[gemrb] 01/03: Imported Upstream version 0.8.0
Beren Minor
berenm-guest at alioth.debian.org
Fri Aug 16 19:13:38 UTC 2013
This is an automated email from the git hooks/post-receive script.
berenm-guest pushed a commit to branch master
in repository gemrb.
commit f2dfd93a44a4c38c434d0607f9ebbfe3ec5ea3be
Author: Beren Minor <beren.minor+git at gmail.com>
Date: Fri Aug 16 20:47:26 2013 +0200
Imported Upstream version 0.8.0
---
.gitattributes | 5 +
.gitignore | 9 +
.mailmap | 5 +
AUTHORS | 1 +
CMakeLists.txt | 173 +-
HACKING | 16 +
INSTALL | 10 +-
NEWS | 103 +
README | 17 +-
TODO | 30 +-
admin/announcement.template | 13 +-
admin/enable-ie-git-diff | 16 +
admin/extend2da.py | 117 +
admin/gource-generator | 16 +
admin/restart_news.sh | 2 -
android/FREETYPEBUILD_Android.mk | 40 +
android/GEMRB_Android.mk | 253 +
android/GEMRB_Application.mk | 5 +
android/GemRB.java | 132 +
android/OGG_Android.mk | 11 +
android/OPENAL_Android.mk | 9 +
android/PNG_Android.mk | 9 +
android/README | 101 +
android/RECURSE_Android.mk | 1 +
android/TODO | 6 +
android/VORBIS_Android.mk | 9 +
android/packaged.GemRB.cfg | 324 +
android/prep_env.sh | 200 +
apple/AppleLogger.h | 40 +
apple/AppleLogger.mm | 75 +
apple/CocoaWrapper/ios/CocoaMain.m | 50 +
apple/CocoaWrapper/ios/GEM_AppDelegate.h | 43 +
apple/CocoaWrapper/ios/GEM_AppDelegate.mm | 154 +
apple/CocoaWrapper/ios/GEM_ConfController.h | 78 +
apple/CocoaWrapper/ios/GEM_ConfController.m | 583 ++
apple/CocoaWrapper/ios/GEM_SDL_Keyboard.m | 202 +
.../ios/nibs/GEM_ConfController-ipad.xib | 455 ++
.../ios/nibs/GEM_ConfController-iphone.xib | 415 ++
apple/CocoaWrapper/mac/CocoaWrapper.mm | 219 +
apple/CocoaWrapper/mac/nibs/GemRB.xib | 2650 +++++++
apple/English.lproj/InfoPlist.strings | Bin 0 -> 258 bytes
apple/GemRB.xcodeproj/.dat08e7.87f | 7366 +++++++++++++++++++
apple/GemRB.xcodeproj/project.pbxproj | 7510 ++++++++++++++++++++
.../project.xcworkspace/contents.xcworkspacedata | 7 +
apple/README | 35 +
apple/config.h | 42 +
apple/defaults.plist | 22 +
apple/ios/GemRB.cfg.newinstall | 101 +
apple/ios/Info.plist | 64 +
apple/ios/README | 20 +
apple/ios/iTunesMetadata.plist.in | 86 +
apple/osx/Info.plist | 35 +
apple/osx/README | 17 +
artwork/gemrb-logo-36px.png | Bin 0 -> 1043 bytes
artwork/gemrb-logo-48px.png | Bin 0 -> 1325 bytes
artwork/gemrb-logo-72px.png | Bin 0 -> 2110 bytes
artwork/gemrb-logo-glow-36px.png | Bin 0 -> 1919 bytes
artwork/gemrb-logo-glow-48px.png | Bin 0 -> 2880 bytes
artwork/gemrb-logo-glow-72px.png | Bin 0 -> 4042 bytes
artwork/gemrb-logo-glow.png | Bin 0 -> 12437 bytes
artwork/gemrb.icns | Bin 0 -> 56828 bytes
artwork/logo-rb_only-light_glow.svg | 117 +
artwork/shirts/README | 6 +
artwork/shirts/detailed-back.svg | 107 +
artwork/shirts/detailed-front.svg | 584 ++
artwork/shirts/minimal-back.pdf | Bin 0 -> 5683 bytes
artwork/shirts/minimal-back.svg | 74 +
artwork/shirts/minimal-front.pdf | Bin 0 -> 3939 bytes
artwork/shirts/minimal-front.svg | 62 +
artwork/shirts/source-detailed-back.svg | 124 +
artwork/shirts/source-detailed-front.svg | 159 +
autogen.sh | 2 +-
cmake/cmake_config.h.in | 15 +
.../cmake_uninstall.cmake.in | 0
cmake/modules/FindICONV.cmake | 102 +
cmake/modules/FindLIBVLC.cmake | 78 +
cmake_config.h.in | 16 -
configure.in | 14 +-
contrib/manhole.py | 33 +
demo/TODO | 23 +
demo/chitin.key | Bin 0 -> 25 bytes
demo/data/AR0100.WED | Bin 0 -> 5608 bytes
demo/data/AR0100HT.BMP | Bin 0 -> 5110 bytes
demo/data/AR0100LM.BMP | Bin 0 -> 10678 bytes
demo/data/AR0100SR.BMP | Bin 0 -> 5110 bytes
demo/data/AR0100TMP.BMP | Bin 0 -> 10678 bytes
demo/data/DejaVuSans.ttf | Bin 0 -> 720012 bytes
demo/data/Eadui.ttf | Bin 0 -> 172460 bytes
demo/data/README | 14 +
demo/data/ZHMW1A1.bam | Bin 0 -> 61836 bytes
demo/data/ZHMW1A2.bam | Bin 0 -> 62823 bytes
demo/data/ZHMW1A3.bam | Bin 0 -> 63794 bytes
demo/data/ZHMW1A4.bam | Bin 0 -> 63467 bytes
demo/data/ZHMW1A5.bam | Bin 0 -> 60578 bytes
demo/data/ZHMW1A6.bam | Bin 0 -> 62541 bytes
demo/data/ZHMW1A7.bam | Bin 0 -> 59156 bytes
demo/data/ZHMW1A8.bam | Bin 0 -> 66865 bytes
demo/data/ZHMW1CA.bam | Bin 0 -> 49908 bytes
demo/data/ZHMW1DE.bam | Bin 0 -> 77131 bytes
demo/data/ZHMW1GH.bam | Bin 0 -> 14919 bytes
demo/data/ZHMW1GU.bam | Bin 0 -> 108646 bytes
demo/data/ZHMW1SC.bam | Bin 0 -> 16741 bytes
demo/data/ZHMW1SD.bam | Bin 0 -> 66424 bytes
demo/data/ZHMW1SL.bam | Bin 0 -> 76832 bytes
demo/data/ZHMW1SP.bam | Bin 0 -> 117948 bytes
demo/data/ZHMW1TW.bam | Bin 0 -> 10903 bytes
demo/data/ZHMW1WK.bam | Bin 0 -> 43455 bytes
demo/data/ar0100.are | Bin 0 -> 388 bytes
demo/data/ar0100.mos | Bin 0 -> 2305824 bytes
demo/data/ar0100.tis | Bin 0 -> 2304024 bytes
demo/data/avatars.2da | 8 +
demo/data/carot.bam | Bin 0 -> 1111 bytes
demo/data/chrmodst.2da | 4 +
demo/data/cursors.bam | Bin 0 -> 6654 bytes
demo/data/defsound.2da | 4 +
demo/data/dexmod.2da | 4 +
demo/data/fist.itm | Bin 0 -> 170 bytes
demo/data/fogowar.bam | Bin 0 -> 306 bytes
demo/data/fonts.2da | 10 +
{gemrb/override/bg1 => demo/data}/gametime.2da | 0
demo/data/gem-demo.gam | Bin 0 -> 2580 bytes
demo/data/gemrb.ini | 126 +
demo/data/guiw.chu | Bin 0 -> 150 bytes
demo/data/hpconbon.2da | 4 +
demo/data/intmod.2da | 4 +
{gemrb/override/bg2 => demo/data}/itemtype.2da | 0
demo/data/lorebon.2da | 4 +
demo/data/mapicon0.bam | Bin 0 -> 1401 bytes
demo/data/mastarea.2da | 4 +
demo/data/numtest.bam | Bin 0 -> 978 bytes
demo/data/palette.png | Bin 0 -> 267 bytes
demo/data/protagon.cre | Bin 0 -> 1076 bytes
demo/data/purple.mos | Bin 0 -> 957 bytes
demo/data/script.2da | 4 +
demo/data/scrlbar1.bam | Bin 0 -> 2878 bytes
demo/data/slottype.2da | 5 +
demo/data/source/ar0100.bmp | Bin 0 -> 5529654 bytes
demo/data/source/carot.bmp | Bin 0 -> 1130 bytes
demo/data/source/glove-pointy.png | Bin 0 -> 8096 bytes
demo/data/source/purple.bmp | Bin 0 -> 161078 bytes
demo/data/source/scroll0.bmp | Bin 0 -> 1478 bytes
demo/data/source/scroll1.bmp | Bin 0 -> 1478 bytes
demo/data/source/scroll2.bmp | Bin 0 -> 1478 bytes
demo/data/source/scroll3.bmp | Bin 0 -> 1478 bytes
demo/data/source/scroll4.bmp | Bin 0 -> 1478 bytes
demo/data/source/scroll5.bmp | Bin 0 -> 1478 bytes
{gemrb/override/bg1 => demo/data}/start.2da | 0
demo/data/startare.2da | 6 +
demo/data/startpos.2da | 5 +
demo/data/strmod.2da | 4 +
demo/data/strmodex.2da | 4 +
demo/data/toolscrl.bam | Bin 0 -> 305 bytes
demo/data/worldmap.wmp | Bin 0 -> 440 bytes
demo/dialog.tlk | Bin 0 -> 19 bytes
demo/gem-demo.ini | 4 +
gemrb.6.in | 357 +-
gemrb/CMakeLists.txt | 86 +-
gemrb/GUIScripts/Actor.py | 25 +-
gemrb/GUIScripts/BGCommon.py | 7 +-
gemrb/GUIScripts/CMakeLists.txt | 11 -
gemrb/GUIScripts/CommonTables.py | 12 +-
gemrb/GUIScripts/CommonWindow.py | 22 +-
gemrb/GUIScripts/DualClass.py | 39 +-
gemrb/GUIScripts/GUIClasses.py | 13 +-
gemrb/GUIScripts/GUICommon.py | 543 +-
gemrb/GUIScripts/GUICommonWindows.py | 1818 +++++
gemrb/GUIScripts/GUIDefines.py | 47 +-
gemrb/GUIScripts/GUILOAD.py | 207 +
gemrb/GUIScripts/GUIOPT.py | 709 ++
gemrb/GUIScripts/GUIOPTControls.py | 145 +
gemrb/GUIScripts/GUIPR.py | 375 +
gemrb/GUIScripts/GUIREC.py | 1056 +++
gemrb/GUIScripts/GUIRECCommon.py | 632 ++
gemrb/GUIScripts/GUISAVE.py | 327 +
gemrb/GUIScripts/GUISTORE.py | 280 +-
gemrb/GUIScripts/GUIWORLD.py | 341 +
gemrb/GUIScripts/InventoryCommon.py | 133 +-
gemrb/GUIScripts/LUCommon.py | 295 +-
gemrb/GUIScripts/LUProfsSelection.py | 56 +-
gemrb/GUIScripts/LUSkillsSelection.py | 31 +-
gemrb/GUIScripts/LUSpellSelection.py | 177 +-
gemrb/GUIScripts/LevelUp.py | 57 +-
gemrb/GUIScripts/Portrait.py | 98 +
gemrb/GUIScripts/Spellbook.py | 527 ++
gemrb/GUIScripts/TextScreen.py | 148 +-
gemrb/GUIScripts/bg1/CMakeLists.txt | 3 -
gemrb/GUIScripts/bg1/CharGenGui.py | 65 +-
gemrb/GUIScripts/bg1/GUICG10.py | 18 +-
gemrb/GUIScripts/bg1/GUICG15.py | 4 +-
gemrb/GUIScripts/bg1/GUICG2.py | 24 +-
gemrb/GUIScripts/bg1/GUICG22.py | 27 +-
gemrb/GUIScripts/bg1/GUICG3.py | 15 +-
gemrb/GUIScripts/bg1/GUICG4.py | 7 +-
gemrb/GUIScripts/bg1/GUICG7.py | 11 +-
gemrb/GUIScripts/bg1/GUICommonWindows.py | 866 ---
gemrb/GUIScripts/bg1/GUIINV.py | 101 +-
gemrb/GUIScripts/bg1/GUILOAD.py | 176 -
gemrb/GUIScripts/bg1/GUIMA.py | 24 +-
gemrb/GUIScripts/bg1/GUIMG.py | 29 +-
gemrb/GUIScripts/bg1/GUIOPT.py | 733 --
gemrb/GUIScripts/bg1/GUIPR.py | 359 -
gemrb/GUIScripts/bg1/GUIREC.py | 1449 ----
gemrb/GUIScripts/bg1/GUISAVE.py | 279 -
gemrb/GUIScripts/bg1/GUIWORLD.py | 336 -
gemrb/GUIScripts/bg1/MessageWindow.py | 13 +
gemrb/GUIScripts/bg1/Start.py | 4 +-
gemrb/GUIScripts/bg2/CMakeLists.txt | 3 -
gemrb/GUIScripts/bg2/CharGen6.py | 19 +-
gemrb/GUIScripts/bg2/CharGenCommon.py | 13 +-
gemrb/GUIScripts/bg2/CharGenEnd.py | 34 +-
gemrb/GUIScripts/bg2/DemoEnd.py | 61 +
gemrb/GUIScripts/bg2/GUICG10.py | 82 +-
gemrb/GUIScripts/bg2/GUICG15.py | 5 +-
gemrb/GUIScripts/bg2/GUICG2.py | 28 +-
gemrb/GUIScripts/bg2/GUICG22.py | 27 +-
gemrb/GUIScripts/bg2/GUICG3.py | 20 +-
gemrb/GUIScripts/bg2/GUICG4.py | 7 +-
gemrb/GUIScripts/bg2/GUICG7.py | 8 +-
gemrb/GUIScripts/bg2/GUICG9.py | 2 +-
gemrb/GUIScripts/bg2/GUICommonWindows.py | 903 ---
gemrb/GUIScripts/bg2/GUIINV.py | 23 +-
gemrb/GUIScripts/bg2/GUILOAD.py | 173 -
gemrb/GUIScripts/bg2/GUIMA.py | 16 +-
gemrb/GUIScripts/bg2/GUIMG.py | 59 +-
gemrb/GUIScripts/bg2/GUIOPT.py | 737 --
gemrb/GUIScripts/bg2/GUIOPT10.py | 188 -
gemrb/GUIScripts/bg2/GUIOPT12.py | 127 -
gemrb/GUIScripts/bg2/GUIOPT6.py | 149 -
gemrb/GUIScripts/bg2/GUIOPT7.py | 125 -
gemrb/GUIScripts/bg2/GUIOPT8.py | 176 -
gemrb/GUIScripts/bg2/GUIOPT9.py | 176 -
gemrb/GUIScripts/bg2/GUIPR.py | 356 -
gemrb/GUIScripts/bg2/GUIREC.py | 1567 ----
gemrb/GUIScripts/bg2/GUISAVE.py | 281 -
gemrb/GUIScripts/bg2/GUIWORLD.py | 335 -
gemrb/GUIScripts/bg2/ImportFile.py | 2 +-
gemrb/GUIScripts/bg2/LUHLASelection.py | 11 +-
gemrb/GUIScripts/bg2/MessageWindow.py | 77 +-
gemrb/GUIScripts/bg2/QuitGame.py | 7 +-
gemrb/GUIScripts/bg2/Start.py | 21 +-
gemrb/GUIScripts/bg2/Start2.py | 2 +-
gemrb/GUIScripts/bg2/StartOpt.py | 25 +-
gemrb/GUIScripts/demo/GUIOPT.py | 5 +
gemrb/GUIScripts/demo/LoadScreen.py | 5 +
gemrb/GUIScripts/demo/MessageWindow.py | 96 +
gemrb/GUIScripts/demo/README | 5 +
gemrb/GUIScripts/demo/SetupGame.py | 7 +
gemrb/GUIScripts/demo/Start.py | 9 +
gemrb/GUIScripts/ie_feats.py | 96 +
gemrb/GUIScripts/ie_sounds.py | 22 +
gemrb/GUIScripts/ie_spells.py | 5 +
gemrb/GUIScripts/ie_stats.py | 7 +-
gemrb/GUIScripts/include.py | 23 +
gemrb/GUIScripts/iwd/CMakeLists.txt | 3 -
gemrb/GUIScripts/iwd/CharGen.py | 208 +-
gemrb/GUIScripts/iwd/GUICommonWindows.py | 843 ---
gemrb/GUIScripts/iwd/GUIINV.py | 17 +-
gemrb/GUIScripts/iwd/GUILOAD.py | 177 -
gemrb/GUIScripts/iwd/GUIMA.py | 9 +-
gemrb/GUIScripts/iwd/GUIMG.py | 33 +-
gemrb/GUIScripts/iwd/GUIOPT.py | 724 --
gemrb/GUIScripts/iwd/GUIPR.py | 349 -
gemrb/GUIScripts/iwd/GUIREC.py | 1468 ----
gemrb/GUIScripts/iwd/GUISAVE.py | 279 -
gemrb/GUIScripts/iwd/GUIWORLD.py | 312 -
gemrb/GUIScripts/iwd/Portrait.py | 95 -
gemrb/GUIScripts/iwd/Start.py | 1 +
gemrb/GUIScripts/iwd2/Alignment.py | 9 +-
gemrb/GUIScripts/iwd2/AutoPause.py | 206 -
gemrb/GUIScripts/iwd2/CGPortrait.py | 230 +
gemrb/GUIScripts/iwd2/CMakeLists.txt | 3 -
gemrb/GUIScripts/iwd2/CharGen4.py | 2 +-
gemrb/GUIScripts/iwd2/CharGen6.py | 12 +-
gemrb/GUIScripts/iwd2/CharGen9.py | 104 +-
gemrb/GUIScripts/iwd2/CharOverview.py | 20 +-
gemrb/GUIScripts/iwd2/CharSound.py | 139 -
gemrb/GUIScripts/iwd2/Class.py | 16 +-
gemrb/GUIScripts/iwd2/Enemy.py | 6 +-
gemrb/GUIScripts/iwd2/Feats.py | 23 +-
gemrb/GUIScripts/iwd2/Feedback.py | 184 -
gemrb/GUIScripts/iwd2/GUICommonWindows.py | 769 --
gemrb/GUIScripts/iwd2/GUIINV.py | 34 +-
gemrb/GUIScripts/iwd2/GUIMA.py | 12 +-
gemrb/GUIScripts/iwd2/GUIOPT.py | 778 --
gemrb/GUIScripts/iwd2/GUIREC.py | 1318 ++--
gemrb/GUIScripts/iwd2/GUISAVE.py | 279 -
gemrb/GUIScripts/iwd2/GUISPL.py | 358 +-
gemrb/GUIScripts/iwd2/GUIWORLD.py | 4 +-
gemrb/GUIScripts/iwd2/GamePlay.py | 189 -
gemrb/GUIScripts/iwd2/Gender.py | 2 +-
gemrb/GUIScripts/iwd2/Graphics.py | 184 -
gemrb/GUIScripts/iwd2/MessageWindow.py | 1 +
gemrb/GUIScripts/iwd2/Movies.py | 79 -
gemrb/GUIScripts/iwd2/Options.py | 39 +-
gemrb/GUIScripts/iwd2/Portrait.py | 225 -
gemrb/GUIScripts/iwd2/Skills.py | 6 +-
gemrb/GUIScripts/iwd2/Sound.py | 132 -
gemrb/GUIScripts/pst/CMakeLists.txt | 3 -
gemrb/GUIScripts/pst/FloatMenuWindow.py | 195 +-
gemrb/GUIScripts/pst/GUICommonWindows.py | 653 --
gemrb/GUIScripts/pst/GUIINV.py | 47 +-
gemrb/GUIScripts/pst/GUIJRNL.py | 8 +
gemrb/GUIScripts/pst/GUIMA.py | 3 +-
gemrb/GUIScripts/pst/GUIMG.py | 10 +-
gemrb/GUIScripts/pst/GUIOPT.py | 551 +-
gemrb/GUIScripts/pst/GUIPR.py | 11 +-
gemrb/GUIScripts/pst/GUIREC.py | 146 +-
gemrb/GUIScripts/pst/GUISAVE.py | 11 +-
gemrb/GUIScripts/pst/GUIWORLD.py | 1 -
gemrb/GUIScripts/pst/MessageWindow.py | 7 +-
gemrb/GUIScripts/pst/NewLife.py | 6 +-
gemrb/GUIScripts/pst/QuitGame.py | 2 +-
gemrb/GemRB.cfg.noinstall.sample | 66 +-
gemrb/GemRB.cfg.sample.in | 79 +-
gemrb/GemRB.cpp | 63 +-
gemrb/Makefile.am | 2 +-
gemrb/core/ActorMgr.cpp | 4 +
gemrb/core/ActorMgr.h | 12 +-
gemrb/core/Ambient.cpp | 4 +
gemrb/core/Ambient.h | 4 +
gemrb/core/AmbientMgr.cpp | 4 +
gemrb/core/AmbientMgr.h | 4 +
gemrb/core/AnimStructures.h | 4 +
gemrb/core/Animation.cpp | 32 +-
gemrb/core/Animation.h | 7 +-
gemrb/core/AnimationFactory.cpp | 7 +-
gemrb/core/AnimationFactory.h | 5 +
gemrb/core/AnimationMgr.cpp | 4 +
gemrb/core/AnimationMgr.h | 11 +-
gemrb/core/ArchiveImporter.cpp | 4 +
gemrb/core/ArchiveImporter.h | 6 +-
gemrb/core/Audio.cpp | 4 +
gemrb/core/Audio.h | 7 +-
gemrb/core/Bitmap.cpp | 4 +
gemrb/core/Bitmap.h | 4 +
gemrb/core/CMakeLists.txt | 116 +-
gemrb/core/Cache.cpp | 5 +
gemrb/core/Cache.h | 4 +
gemrb/core/Calendar.cpp | 3 +
gemrb/core/Calendar.h | 4 +
gemrb/core/Callback.cpp | 4 +
gemrb/core/Callback.h | 4 +
gemrb/core/CharAnimations.cpp | 354 +-
gemrb/core/CharAnimations.h | 24 +-
gemrb/core/Compressor.cpp | 6 +-
gemrb/core/Compressor.h | 8 +-
gemrb/core/ControlAnimation.cpp | 30 +-
gemrb/core/ControlAnimation.h | 16 +-
gemrb/core/Core.cpp | 112 +-
gemrb/core/DataFileMgr.cpp | 4 +
gemrb/core/DataFileMgr.h | 6 +-
gemrb/core/Dialog.cpp | 4 +
gemrb/core/Dialog.h | 4 +
gemrb/core/DialogHandler.cpp | 128 +-
gemrb/core/DialogHandler.h | 6 +-
gemrb/core/DialogMgr.cpp | 4 +
gemrb/core/DialogMgr.h | 6 +-
gemrb/core/DisplayMessage.cpp | 76 +-
gemrb/core/DisplayMessage.h | 21 +-
gemrb/core/Effect.h | 15 +-
gemrb/core/EffectMgr.cpp | 4 +
gemrb/core/EffectMgr.h | 4 +
gemrb/core/EffectQueue.cpp | 715 +-
gemrb/core/EffectQueue.h | 25 +-
gemrb/core/Factory.cpp | 4 +
gemrb/core/Factory.h | 4 +
gemrb/core/FactoryObject.cpp | 4 +
gemrb/core/FactoryObject.h | 4 +
gemrb/core/FileCache.cpp | 57 +
gemrb/core/FileCache.h | 30 +
gemrb/core/Font.cpp | 482 +-
gemrb/core/Font.h | 88 +-
gemrb/core/FontManager.cpp | 37 +
gemrb/core/FontManager.h | 58 +
gemrb/core/GUI/Button.cpp | 180 +-
gemrb/core/GUI/Button.h | 38 +-
gemrb/core/GUI/Console.cpp | 27 +-
gemrb/core/GUI/Console.h | 11 +-
gemrb/core/GUI/Control.cpp | 128 +-
gemrb/core/GUI/Control.h | 45 +-
gemrb/core/GUI/EventMgr.cpp | 113 +-
gemrb/core/GUI/EventMgr.h | 38 +-
gemrb/core/GUI/GameControl.cpp | 1114 +--
gemrb/core/GUI/GameControl.h | 48 +-
gemrb/core/GUI/Label.cpp | 15 +-
gemrb/core/GUI/Label.h | 8 +-
gemrb/core/GUI/MapControl.cpp | 76 +-
gemrb/core/GUI/MapControl.h | 18 +-
gemrb/core/GUI/Progressbar.cpp | 15 +-
gemrb/core/GUI/Progressbar.h | 10 +-
gemrb/core/GUI/ScrollBar.cpp | 274 +-
gemrb/core/GUI/ScrollBar.h | 25 +-
gemrb/core/GUI/Slider.cpp | 15 +-
gemrb/core/GUI/Slider.h | 10 +-
gemrb/core/GUI/TextArea.cpp | 284 +-
gemrb/core/GUI/TextArea.h | 31 +-
gemrb/core/GUI/TextEdit.cpp | 47 +-
gemrb/core/GUI/TextEdit.h | 14 +-
gemrb/core/GUI/Window.cpp | 68 +-
gemrb/core/GUI/Window.h | 47 +-
gemrb/core/GUI/WorldMapControl.cpp | 110 +-
gemrb/core/GUI/WorldMapControl.h | 12 +-
gemrb/core/Game.cpp | 568 +-
gemrb/core/Game.h | 68 +-
gemrb/core/GameData.cpp | 164 +-
gemrb/core/GameData.h | 32 +-
gemrb/core/GameScript/Actions.cpp | 1400 ++--
gemrb/core/GameScript/GSUtils.cpp | 999 ++-
gemrb/core/GameScript/GSUtils.h | 28 +-
gemrb/core/GameScript/GameScript.cpp | 588 +-
gemrb/core/GameScript/GameScript.h | 175 +-
gemrb/core/GameScript/Matching.cpp | 107 +-
gemrb/core/GameScript/Matching.h | 6 +
gemrb/core/GameScript/Objects.cpp | 292 +-
gemrb/core/GameScript/Triggers.cpp | 924 +--
gemrb/core/GlobalTimer.cpp | 51 +-
gemrb/core/GlobalTimer.h | 13 +-
gemrb/core/Holder.h | 5 +
gemrb/core/Image.cpp | 4 +
gemrb/core/Image.h | 4 +
gemrb/core/ImageFactory.cpp | 4 +
gemrb/core/ImageFactory.h | 4 +
gemrb/core/ImageMgr.cpp | 14 +-
gemrb/core/ImageMgr.h | 4 +
gemrb/core/ImageWriter.cpp | 4 +
gemrb/core/ImageWriter.h | 4 +
gemrb/core/IndexedArchive.cpp | 33 +
gemrb/core/IndexedArchive.h | 40 +
gemrb/core/IniSpawn.cpp | 223 +-
gemrb/core/IniSpawn.h | 26 +-
gemrb/core/Interface.cpp | 2220 +++---
gemrb/core/Interface.h | 120 +-
gemrb/core/InterfaceConfig.cpp | 232 +
gemrb/core/InterfaceConfig.h | 66 +
gemrb/core/Inventory.cpp | 406 +-
gemrb/core/Inventory.h | 50 +-
gemrb/core/Item.cpp | 71 +-
gemrb/core/Item.h | 27 +-
gemrb/core/ItemMgr.cpp | 4 +
gemrb/core/ItemMgr.h | 6 +-
gemrb/core/KeyMap.cpp | 162 +
gemrb/core/KeyMap.h | 52 +
gemrb/core/LRUCache.cpp | 4 +
gemrb/core/LRUCache.h | 4 +
gemrb/core/Makefile.am | 16 +-
gemrb/core/Map.cpp | 781 +-
gemrb/core/Map.h | 77 +-
gemrb/core/MapMgr.cpp | 4 +
gemrb/core/MapMgr.h | 12 +-
gemrb/core/MoviePlayer.cpp | 4 +
gemrb/core/MoviePlayer.h | 4 +
gemrb/core/MusicMgr.cpp | 4 +
gemrb/core/MusicMgr.h | 4 +
gemrb/core/Palette.cpp | 14 +
gemrb/core/Palette.h | 5 +
gemrb/core/PalettedImageMgr.cpp | 4 +
gemrb/core/PalettedImageMgr.h | 4 +
gemrb/core/Particles.cpp | 12 +-
gemrb/core/Particles.h | 6 +-
gemrb/core/PathFinder.h | 4 +
gemrb/core/Plugin.cpp | 4 +
gemrb/core/Plugin.h | 18 +-
gemrb/core/PluginLoader.cpp | 235 +
gemrb/core/PluginLoader.h | 36 +
gemrb/core/PluginMgr.cpp | 212 +-
gemrb/core/PluginMgr.h | 38 +-
gemrb/core/Polygon.cpp | 14 +-
gemrb/core/Polygon.h | 4 +
gemrb/core/PolymorphCache.h | 4 +
gemrb/core/Projectile.cpp | 77 +-
gemrb/core/Projectile.h | 11 +-
gemrb/core/ProjectileMgr.cpp | 4 +
gemrb/core/ProjectileMgr.h | 6 +-
gemrb/core/ProjectileServer.cpp | 16 +-
gemrb/core/ProjectileServer.h | 5 +-
gemrb/core/Region.cpp | 44 +-
gemrb/core/Region.h | 10 +-
gemrb/core/Resource.cpp | 4 +
gemrb/core/Resource.h | 4 +
gemrb/core/ResourceDesc.cpp | 4 +
gemrb/core/ResourceDesc.h | 4 +
gemrb/core/ResourceManager.cpp | 50 +-
gemrb/core/ResourceManager.h | 4 +
gemrb/core/ResourceSource.cpp | 4 +
gemrb/core/ResourceSource.h | 4 +
gemrb/core/SaveGame.h | 7 +-
gemrb/core/SaveGameIterator.cpp | 113 +-
gemrb/core/SaveGameIterator.h | 6 +-
gemrb/core/SaveGameMgr.cpp | 4 +
gemrb/core/SaveGameMgr.h | 6 +-
gemrb/core/ScriptEngine.cpp | 4 +
gemrb/core/ScriptEngine.h | 9 +-
gemrb/core/Scriptable/Actor.cpp | 4547 +++++++++---
gemrb/core/Scriptable/Actor.h | 272 +-
gemrb/core/Scriptable/CombatInfo.cpp | 332 +
gemrb/core/Scriptable/CombatInfo.h | 131 +
gemrb/core/Scriptable/Container.cpp | 83 +-
gemrb/core/Scriptable/Container.h | 11 +-
gemrb/core/Scriptable/Door.cpp | 148 +-
gemrb/core/Scriptable/Door.h | 29 +-
gemrb/core/Scriptable/InfoPoint.cpp | 126 +-
gemrb/core/Scriptable/InfoPoint.h | 23 +-
gemrb/core/Scriptable/PCStatStruct.cpp | 101 +-
gemrb/core/Scriptable/PCStatStruct.h | 28 +-
gemrb/core/Scriptable/Scriptable.cpp | 1010 ++-
gemrb/core/Scriptable/Scriptable.h | 239 +-
gemrb/core/ScriptedAnimation.cpp | 42 +-
gemrb/core/ScriptedAnimation.h | 21 +-
gemrb/core/SoundMgr.cpp | 4 +
gemrb/core/SoundMgr.h | 4 +
gemrb/core/Spell.cpp | 122 +-
gemrb/core/Spell.h | 12 +-
gemrb/core/SpellMgr.cpp | 4 +
gemrb/core/SpellMgr.h | 6 +-
gemrb/core/Spellbook.cpp | 360 +-
gemrb/core/Spellbook.h | 56 +-
gemrb/core/Sprite2D.cpp | 11 +-
gemrb/core/Sprite2D.h | 10 +-
gemrb/core/SpriteCover.cpp | 4 +
gemrb/core/SpriteCover.h | 4 +
gemrb/core/Store.cpp | 93 +-
gemrb/core/Store.h | 13 +-
gemrb/core/StoreMgr.cpp | 4 +
gemrb/core/StoreMgr.h | 9 +-
gemrb/core/StringMgr.cpp | 4 +
gemrb/core/StringMgr.h | 6 +-
gemrb/core/SymbolMgr.cpp | 4 +
gemrb/core/SymbolMgr.h | 13 +-
gemrb/core/System/CachedFileStream.cpp | 213 -
gemrb/core/System/CachedFileStream.h | 45 -
gemrb/core/System/DataStream.cpp | 45 +-
gemrb/core/System/DataStream.h | 13 +-
gemrb/core/System/FileStream.cpp | 312 +-
gemrb/core/System/FileStream.h | 31 +-
gemrb/core/System/Logger.cpp | 96 +
gemrb/core/System/Logger.h | 73 +
gemrb/core/System/Logger/Android.cpp | 56 +
gemrb/core/System/Logger/Android.h | 39 +
gemrb/core/System/Logger/File.cpp | 77 +
gemrb/core/System/Logger/File.h | 43 +
gemrb/core/System/Logger/MessageWindowLogger.cpp | 107 +
gemrb/core/System/Logger/MessageWindowLogger.h | 40 +
gemrb/core/System/Logger/Stdio.cpp | 127 +
gemrb/core/System/Logger/Stdio.h | 46 +
gemrb/core/System/Logger/Win32Console.cpp | 79 +
gemrb/core/System/Logger/Win32Console.h | 43 +
gemrb/core/System/Logging.cpp | 129 +
gemrb/core/System/Logging.h | 96 +
gemrb/core/System/MemoryStream.cpp | 94 +-
gemrb/core/System/MemoryStream.h | 36 +-
gemrb/core/System/SlicedStream.cpp | 130 +
gemrb/core/System/SlicedStream.h | 50 +
gemrb/core/System/String.cpp | 191 +
gemrb/core/System/String.h | 67 +
gemrb/core/System/StringBuffer.cpp | 76 +
gemrb/core/System/StringBuffer.h | 66 +
gemrb/core/System/VFS.cpp | 322 +-
gemrb/core/System/VFS.h | 48 +-
gemrb/core/System/android_log_printf.cpp | 35 -
gemrb/core/System/android_log_printf.h | 24 -
gemrb/core/System/snprintf.cpp | 980 ---
gemrb/core/System/snprintf.h | 41 -
gemrb/core/TableMgr.cpp | 12 +-
gemrb/core/TableMgr.h | 12 +-
gemrb/core/Tile.cpp | 20 +-
gemrb/core/Tile.h | 4 +
gemrb/core/TileMap.cpp | 14 +-
gemrb/core/TileMap.h | 6 +-
gemrb/core/TileMapMgr.cpp | 4 +
gemrb/core/TileMapMgr.h | 6 +-
gemrb/core/TileOverlay.cpp | 14 +-
gemrb/core/TileOverlay.h | 6 +-
gemrb/core/TileSetMgr.cpp | 4 +
gemrb/core/TileSetMgr.h | 6 +-
gemrb/core/TypeID.h | 4 +
gemrb/core/Variables.cpp | 49 +-
gemrb/core/Variables.h | 9 +
gemrb/core/Video.cpp | 58 +-
gemrb/core/Video.h | 101 +-
gemrb/core/VideoMode.h | 4 +
gemrb/core/WindowMgr.cpp | 4 +
gemrb/core/WindowMgr.h | 11 +-
gemrb/core/WorldMap.cpp | 150 +-
gemrb/core/WorldMap.h | 15 +-
gemrb/core/WorldMapMgr.cpp | 4 +
gemrb/core/WorldMapMgr.h | 6 +-
gemrb/core/damages.h | 7 +-
gemrb/docs/en/CheatKeys.txt | 7 +-
gemrb/docs/en/GUIScript/AddNewArea.txt | 14 +
gemrb/docs/en/GUIScript/ApplySpell.txt | 3 +-
.../en/GUIScript/Button_CreateLabelOnButton.txt | 18 +
gemrb/docs/en/GUIScript/Button_EnableBorder.txt | 17 +
gemrb/docs/en/GUIScript/Button_SetActionIcon.txt | 18 +
gemrb/docs/en/GUIScript/Button_SetAnchor.txt | 18 +
gemrb/docs/en/GUIScript/Button_SetBAM.txt | 19 +
gemrb/docs/en/GUIScript/Button_SetBorder.txt | 26 +
gemrb/docs/en/GUIScript/Button_SetFlags.txt | 17 +
gemrb/docs/en/GUIScript/Button_SetFont.txt | 16 +
gemrb/docs/en/GUIScript/Button_SetItemIcon.txt | 20 +
gemrb/docs/en/GUIScript/Button_SetMOS.txt | 16 +
gemrb/docs/en/GUIScript/Button_SetOverlay.txt | 19 +
gemrb/docs/en/GUIScript/Button_SetPLT.txt | 25 +
gemrb/docs/en/GUIScript/Button_SetPicture.txt | 17 +
.../en/GUIScript/Button_SetPictureClipping.txt | 16 +
gemrb/docs/en/GUIScript/Button_SetPushOffset.txt | 18 +
gemrb/docs/en/GUIScript/Button_SetSpellIcon.txt | 19 +
gemrb/docs/en/GUIScript/Button_SetSprite2D.txt | 16 +
gemrb/docs/en/GUIScript/Button_SetSprites.txt | 21 +
gemrb/docs/en/GUIScript/Button_SetState.txt | 16 +
gemrb/docs/en/GUIScript/Button_SetTextColor.txt | 19 +
.../docs/en/GUIScript/Control_AttachScrollBar.txt | 16 +
gemrb/docs/en/GUIScript/Control_QueryText.txt | 15 +
gemrb/docs/en/GUIScript/Control_SetAnimation.txt | 18 +
.../en/GUIScript/Control_SetAnimationPalette.txt | 23 +
gemrb/docs/en/GUIScript/Control_SetEvent.txt | 15 +
gemrb/docs/en/GUIScript/Control_SetPos.txt | 17 +
gemrb/docs/en/GUIScript/Control_SetSize.txt | 17 +
gemrb/docs/en/GUIScript/Control_SetStatus.txt | 16 +
gemrb/docs/en/GUIScript/Control_SetText.txt | 16 +
gemrb/docs/en/GUIScript/Control_SetTooltip.txt | 17 +
gemrb/docs/en/GUIScript/Control_SetVarAssoc.txt | 17 +
.../en/GUIScript/Control_TextArea_SetFlags.txt | 17 +
gemrb/docs/en/GUIScript/CreateString.txt | 14 +
gemrb/docs/en/GUIScript/DispelEffect.txt | 16 +
gemrb/docs/en/GUIScript/FindStoreItem.txt | 14 +
gemrb/docs/en/GUIScript/GameGetExpansion.txt | 13 +
.../en/GUIScript/GameGetFirstSelectedActor.txt | 13 +
gemrb/docs/en/GUIScript/GamePause.txt | 15 +-
gemrb/docs/en/GUIScript/GetCombatDetails.txt | 3 +-
gemrb/docs/en/GUIScript/GetDestinationArea.txt | 2 -
gemrb/docs/en/GUIScript/GetGamePortraitPreview.txt | 14 +
gemrb/docs/en/GUIScript/GetGamePreview.txt | 13 +
gemrb/docs/en/GUIScript/GetGameString.txt | 1 +
gemrb/docs/en/GUIScript/GetItem.txt | 2 +-
gemrb/docs/en/GUIScript/GetMazeEntry.txt | 14 +
gemrb/docs/en/GUIScript/GetMazeHeader.txt | 13 +
gemrb/docs/en/GUIScript/GetPlayerSound.txt | 14 +
gemrb/docs/en/GUIScript/GetPlayerStat.txt | 1 +
gemrb/docs/en/GUIScript/GetSaveGames.txt | 13 +
gemrb/docs/en/GUIScript/GetSelectedActors.txt | 13 +
gemrb/docs/en/GUIScript/GetSpell.txt | 2 +
gemrb/docs/en/GUIScript/GetSpellCastOn.txt | 14 +
gemrb/docs/en/GUIScript/GetStoreItem.txt | 1 +
gemrb/docs/en/GUIScript/HasFeat.txt | 14 +
gemrb/docs/en/GUIScript/Label_SetTextColor.txt | 18 +
gemrb/docs/en/GUIScript/Label_SetUseRGB.txt | 16 +
gemrb/docs/en/GUIScript/MemorizeSpell.txt | 3 +-
gemrb/docs/en/GUIScript/MessageWindowDebug.txt | 22 +
gemrb/docs/en/GUIScript/SaveGame_GetDate.txt | 13 +
gemrb/docs/en/GUIScript/SaveGame_GetGameDate.txt | 13 +
gemrb/docs/en/GUIScript/SaveGame_GetName.txt | 13 +
gemrb/docs/en/GUIScript/SaveGame_GetPortrait.txt | 15 +
gemrb/docs/en/GUIScript/SaveGame_GetPreview.txt | 13 +
gemrb/docs/en/GUIScript/SaveGame_GetSaveID.txt | 13 +
.../en/GUIScript/ScrollBar_SetDefaultScrollBar.txt | 15 +
gemrb/docs/en/GUIScript/ScrollBar_SetSprites.txt | 23 +
gemrb/docs/en/GUIScript/SetButtonFlags.txt | 2 +-
gemrb/docs/en/GUIScript/SetButtonState.txt | 4 +-
gemrb/docs/en/GUIScript/SetEvent.txt | 1 -
gemrb/docs/en/GUIScript/SetMapAnimation.txt | 19 +
gemrb/docs/en/GUIScript/SetMapDoor.txt | 15 +
gemrb/docs/en/GUIScript/SetMapExit.txt | 16 +
gemrb/docs/en/GUIScript/SetMapRegion.txt | 15 +
gemrb/docs/en/GUIScript/SetMazeData.txt | 15 +
gemrb/docs/en/GUIScript/SetMazeEntry.txt | 16 +
gemrb/docs/en/GUIScript/SetPlayerStat.txt | 1 +
gemrb/docs/en/GUIScript/SetTickHook.txt | 13 +
gemrb/docs/en/GUIScript/SetupControls.txt | 2 +-
gemrb/docs/en/GUIScript/SetupEquipmentIcons.txt | 2 +-
gemrb/docs/en/GUIScript/SetupMaze.txt | 14 +
gemrb/docs/en/GUIScript/SetupQuickSpell.txt | 17 +
gemrb/docs/en/GUIScript/SetupSpellIcons.txt | 18 -
gemrb/docs/en/GUIScript/SpellCast.txt | 2 +-
gemrb/docs/en/GUIScript/Symbol_GetValue.txt | 15 +
gemrb/docs/en/GUIScript/Symbol_Unload.txt | 14 +
gemrb/docs/en/GUIScript/Table_FindValue.txt | 17 +
gemrb/docs/en/GUIScript/Table_GetColumnCount.txt | 15 +
gemrb/docs/en/GUIScript/Table_GetColumnIndex.txt | 15 +
gemrb/docs/en/GUIScript/Table_GetColumnName.txt | 15 +
gemrb/docs/en/GUIScript/Table_GetRowCount.txt | 14 +
gemrb/docs/en/GUIScript/Table_GetRowIndex.txt | 15 +
gemrb/docs/en/GUIScript/Table_GetRowName.txt | 15 +
gemrb/docs/en/GUIScript/Table_GetValue.txt | 17 +
gemrb/docs/en/GUIScript/Table_Unload.txt | 14 +
gemrb/docs/en/GUIScript/TextArea_Append.txt | 19 +
gemrb/docs/en/GUIScript/TextArea_Clear.txt | 15 +
gemrb/docs/en/GUIScript/TextArea_GetCharSounds.txt | 15 +
gemrb/docs/en/GUIScript/TextArea_GetCharacters.txt | 15 +
gemrb/docs/en/GUIScript/TextArea_GetPortraits.txt | 16 +
gemrb/docs/en/GUIScript/TextArea_MoveText.txt | 17 +
gemrb/docs/en/GUIScript/TextArea_Rewind.txt | 16 +
gemrb/docs/en/GUIScript/TextArea_Scroll.txt | 16 +
gemrb/docs/en/GUIScript/TextArea_SelectText.txt | 16 +
gemrb/docs/en/GUIScript/TextArea_SetHistory.txt | 16 +
gemrb/docs/en/GUIScript/TextEdit_ConvertEdit.txt | 16 +
.../docs/en/GUIScript/TextEdit_SetBufferLength.txt | 16 +
gemrb/docs/en/GUIScript/UnmemorizeSpell.txt | 9 +-
gemrb/docs/en/GUIScript/VerbalConstant.txt | 15 +
gemrb/docs/en/GUIScript/Window_CreateButton.txt | 19 +
gemrb/docs/en/GUIScript/Window_CreateLabel.txt | 22 +
.../docs/en/GUIScript/Window_CreateMapControl.txt | 22 +
gemrb/docs/en/GUIScript/Window_CreateScrollBar.txt | 19 +
gemrb/docs/en/GUIScript/Window_CreateTextEdit.txt | 21 +
.../en/GUIScript/Window_CreateWorldMapControl.txt | 21 +
gemrb/docs/en/GUIScript/Window_DeleteControl.txt | 15 +
gemrb/docs/en/GUIScript/Window_GetControl.txt | 15 +
gemrb/docs/en/GUIScript/Window_HasControl.txt | 16 +
gemrb/docs/en/GUIScript/Window_Invalidate.txt | 14 +
gemrb/docs/en/GUIScript/Window_SetFrame.txt | 14 +
gemrb/docs/en/GUIScript/Window_SetPicture.txt | 15 +
gemrb/docs/en/GUIScript/Window_SetPos.txt | 17 +
gemrb/docs/en/GUIScript/Window_SetSize.txt | 16 +
gemrb/docs/en/GUIScript/Window_SetVisible.txt | 15 +
gemrb/docs/en/GUIScript/Window_SetupControls.txt | 17 +
.../en/GUIScript/Window_SetupEquipmentIcons.txt | 18 +
gemrb/docs/en/GUIScript/Window_ShowModal.txt | 15 +
gemrb/docs/en/GUIScript/Window_Unload.txt | 14 +
.../docs/en/GUIScript/WorldMap_AdjustScrolling.txt | 17 +
.../en/GUIScript/WorldMap_GetDestinationArea.txt | 16 +
gemrb/docs/en/GUIScript/WorldMap_SetTextColor.txt | 19 +
gemrb/docs/en/GUIScript/internal.txt | 15 +
gemrb/docs/en/Release.txt | 30 +-
gemrb/docs/en/Tables/avatars.txt | 6 +-
gemrb/docs/en/Tables/comment.txt | 7 +
gemrb/docs/en/Tables/fonts.txt | 20 +-
gemrb/docs/en/Tables/item_use.txt | 6 +-
gemrb/docs/en/Tables/proftype.txt | 6 +
gemrb/docs/en/Tables/stances.txt | 12 +
gemrb/docs/en/Tables/storespl.txt | 6 +
gemrb/docs/en/Tables/textscrn.txt | 12 +
gemrb/docs/en/default_ini.txt | 50 +
gemrb/docs/en/gemrb_ini.txt | 449 +-
gemrb/includes/CocoaWrapper.h | 65 +
gemrb/includes/HashMap.h | 459 ++
gemrb/includes/RGBAColor.h | 10 +-
gemrb/includes/SClassID.h | 13 +-
gemrb/includes/StringMap.h | 131 +
gemrb/includes/defsounds.h | 14 +
gemrb/includes/errors.h | 4 +
gemrb/includes/exports.h | 41 +-
gemrb/includes/globals.h | 76 +-
gemrb/includes/ie_cursors.h | 42 +
gemrb/includes/ie_feats.h | 155 +-
gemrb/includes/ie_stats.h | 28 +-
gemrb/includes/ie_types.h | 5 +-
gemrb/includes/iless.h | 4 +
gemrb/includes/logging.h | 119 -
gemrb/includes/opcode_params.h | 10 +-
gemrb/includes/overlays.h | 4 +
gemrb/includes/plugindef.h | 11 +-
gemrb/includes/strrefs.h | 44 +-
gemrb/includes/win32def.h | 33 +-
gemrb/override/CMakeLists.txt | 7 -
gemrb/override/bg1/CMakeLists.txt | 3 +-
gemrb/override/bg1/Makefile.am | 4 +-
gemrb/override/bg1/avatars.2da | 322 -
gemrb/override/bg1/bloodclr.2da | 29 -
gemrb/override/bg1/clskills.2da | 24 -
gemrb/override/bg1/damage.2da | 16 -
gemrb/override/bg1/defsound.2da | 29 -
gemrb/override/bg1/effects.ids | 319 -
gemrb/override/bg1/efftext.2da | 10 +
gemrb/override/bg1/fonts.2da | 14 -
gemrb/override/bg1/gemrb.ini | 80 -
gemrb/override/bg1/guibtact.2da | 37 -
gemrb/override/bg1/magesch.2da | 13 -
gemrb/override/bg1/minorglb.vvc | Bin 0 -> 492 bytes
gemrb/override/bg1/overlay.2da | 35 -
gemrb/override/bg1/pdolls.2da | 86 -
gemrb/override/bg1/qslots.2da | 24 -
gemrb/override/bg1/shtable.2da | 42 -
gemrb/override/bg1/strings.2da | 170 -
gemrb/override/bg2/CMakeLists.txt | 1 -
gemrb/override/bg2/Makefile.am | 4 +-
gemrb/override/bg2/avatars.2da | 332 -
gemrb/override/bg2/bloodclr.2da | 29 -
gemrb/override/bg2/clskills.2da | 24 -
gemrb/override/bg2/damage.2da | 16 -
gemrb/override/bg2/defsound.2da | 29 -
gemrb/override/bg2/effects.ids | 320 -
gemrb/override/bg2/fonts.2da | 19 -
gemrb/override/bg2/gametime.2da | 5 -
gemrb/override/bg2/gemrb.ini | 92 -
gemrb/override/bg2/magesch.2da | 13 -
gemrb/override/bg2/overlay.2da | 35 -
gemrb/override/bg2/pathfind.2da | 6 -
gemrb/override/bg2/pdolls.2da | 106 -
gemrb/override/bg2/qslots.2da | 24 -
gemrb/override/bg2/races.2da | 11 -
gemrb/override/bg2/splspec.2da | 8 -
gemrb/override/bg2/strings.2da | 169 -
gemrb/override/how/CMakeLists.txt | 1 -
gemrb/override/how/Makefile.am | 4 +-
gemrb/override/how/avatars.2da | 417 --
gemrb/override/how/bloodclr.2da | 29 -
gemrb/override/how/clskills.2da | 22 -
gemrb/override/how/defsound.2da | 29 -
gemrb/override/how/effects.ids | 301 -
gemrb/override/how/fonts.2da | 19 -
gemrb/override/how/gametime.2da | 5 -
gemrb/override/how/gemrb.ini | 123 -
gemrb/override/how/itemsnd.2da | 80 -
gemrb/override/how/itemtype.2da | 77 -
gemrb/override/how/magesch.2da | 12 -
gemrb/override/how/overlay.2da | 35 -
gemrb/override/how/qslots.2da | 24 -
gemrb/override/how/strings.2da | 170 -
gemrb/override/how/vcremap.2da | 4 -
gemrb/override/iwd/CMakeLists.txt | 1 -
gemrb/override/iwd/Makefile.am | 4 +-
gemrb/override/iwd/avatars.2da | 414 --
gemrb/override/iwd/bloodclr.2da | 29 -
gemrb/override/iwd/clskills.2da | 22 -
gemrb/override/iwd/defsound.2da | 29 -
gemrb/override/iwd/effects.ids | 300 -
gemrb/override/iwd/fonts.2da | 19 -
gemrb/override/iwd/gametime.2da | 5 -
gemrb/override/iwd/gemrb.ini | 121 -
gemrb/override/iwd/itemsnd.2da | 80 -
gemrb/override/iwd/itemtype.2da | 77 -
gemrb/override/iwd/magesch.2da | 12 -
gemrb/override/iwd/overlay.2da | 35 -
gemrb/override/iwd/qslots.2da | 24 -
gemrb/override/iwd/strings.2da | 170 -
gemrb/override/iwd/vcremap.2da | 4 -
gemrb/override/iwd2/CMakeLists.txt | 1 -
gemrb/override/iwd2/Makefile.am | 4 +-
gemrb/override/iwd2/ability.2da | 9 -
gemrb/override/iwd2/avatars.2da | 432 --
gemrb/override/iwd2/bios.2da | 14 -
gemrb/override/iwd2/bloodclr.2da | 29 -
gemrb/override/iwd2/classes.2da | 38 -
gemrb/override/iwd2/clskills.2da | 15 -
gemrb/override/iwd2/damage.2da | 16 -
gemrb/override/iwd2/defsound.2da | 29 -
gemrb/override/iwd2/effects.ids | 356 -
gemrb/override/iwd2/efftext.2da | 2 +-
gemrb/override/iwd2/featreq.2da | 79 -
gemrb/override/iwd2/fireball.pro | Bin 768 -> 0 bytes
gemrb/override/iwd2/fistweap.2da | 4 -
gemrb/override/iwd2/fonts.2da | 19 -
gemrb/override/iwd2/gametime.2da | 5 -
gemrb/override/iwd2/gemrb.ini | 98 -
gemrb/override/iwd2/guibtact.2da | 30 -
gemrb/override/iwd2/itemsnd.2da | 80 -
gemrb/override/iwd2/itemtype.2da | 77 -
gemrb/override/iwd2/races.2da | 19 -
gemrb/override/iwd2/slottype.2da | 54 -
gemrb/override/iwd2/splprot.2da | 105 -
gemrb/override/iwd2/strings.2da | 170 -
gemrb/override/pst/CMakeLists.txt | 1 -
gemrb/override/pst/Makefile.am | 4 +-
gemrb/override/pst/baldur.bcs | 152 +
gemrb/override/pst/cloudkil.pro | Bin 768 -> 0 bytes
gemrb/override/pst/clskills.2da | 13 -
gemrb/override/pst/damage.2da | 16 -
gemrb/override/pst/defsound.2da | 29 -
gemrb/override/pst/fonts.2da | 12 -
gemrb/override/pst/gametime.2da | 5 -
gemrb/override/pst/gemprjtl.ids | 292 -
gemrb/override/pst/gemrb.ini | 121 -
gemrb/override/pst/overlay.2da | 35 -
gemrb/override/pst/pathfind.2da | 5 -
gemrb/override/pst/source/baldur.baf | 157 +
gemrb/override/pst/strings.2da | 170 -
gemrb/override/shared/CMakeLists.txt | 1 -
gemrb/override/shared/Makefile.am | 4 +-
gemrb/override/shared/bardsong.spl | Bin 346 -> 0 bytes
gemrb/override/shared/dmgtypes.2da | 22 -
gemrb/override/shared/gemact.ids | 10 -
gemrb/override/shared/stats.ids | 2 +-
gemrb/plugins/2DAImporter/2DAImporter.cpp | 24 +-
gemrb/plugins/2DAImporter/2DAImporter.h | 21 +-
gemrb/plugins/ACMReader/ACMReader.cpp | 6 +-
gemrb/plugins/ACMReader/ACMReader.h | 4 +
gemrb/plugins/ACMReader/unpacker.h | 6 +-
gemrb/plugins/AREImporter/AREImporter.cpp | 265 +-
gemrb/plugins/AREImporter/AREImporter.h | 10 +-
gemrb/plugins/BAMImporter/BAMFont.cpp | 88 +
gemrb/plugins/BAMImporter/BAMFont.h | 46 +
gemrb/plugins/BAMImporter/BAMFontManager.cpp | 79 +
gemrb/plugins/BAMImporter/BAMFontManager.h | 53 +
gemrb/plugins/BAMImporter/BAMImporter.cpp | 158 +-
gemrb/plugins/BAMImporter/BAMImporter.h | 9 +-
gemrb/plugins/BAMImporter/CMakeLists.txt | 2 +-
gemrb/plugins/BAMImporter/Makefile.am | 2 +-
gemrb/plugins/BIFImporter/BIFImporter.cpp | 294 +-
gemrb/plugins/BIFImporter/BIFImporter.h | 18 +-
gemrb/plugins/BIKPlayer/BIKPlayer.cpp | 25 +-
gemrb/plugins/BIKPlayer/BIKPlayer.h | 6 +-
gemrb/plugins/BIKPlayer/GetBitContext.cpp | 3 +-
gemrb/plugins/BIKPlayer/GetBitContext.h | 8 +-
gemrb/plugins/BMPImporter/BMPImporter.cpp | 109 +-
gemrb/plugins/BMPImporter/BMPImporter.h | 7 +-
gemrb/plugins/BMPWriter/BMPWriter.cpp | 2 +
gemrb/plugins/BMPWriter/BMPWriter.h | 4 +
gemrb/plugins/CHUImporter/CHUImporter.cpp | 31 +-
gemrb/plugins/CHUImporter/CHUImporter.h | 8 +-
gemrb/plugins/CMakeLists.txt | 4 +
gemrb/plugins/CREImporter/CREImporter.cpp | 526 +-
gemrb/plugins/CREImporter/CREImporter.h | 15 +-
gemrb/plugins/DLGImporter/DLGImporter.cpp | 39 +-
gemrb/plugins/DLGImporter/DLGImporter.h | 7 +-
.../DirectoryImporter/DirectoryImporter.cpp | 116 +-
.../plugins/DirectoryImporter/DirectoryImporter.h | 29 +-
gemrb/plugins/EFFImporter/EFFImporter.cpp | 52 +-
gemrb/plugins/EFFImporter/EFFImporter.h | 6 +
gemrb/plugins/FXOpcodes/FXOpcodes.cpp | 2365 +++---
gemrb/plugins/GAMImporter/GAMImporter.cpp | 50 +-
gemrb/plugins/GAMImporter/GAMImporter.h | 7 +-
gemrb/plugins/GUIScript/CMakeLists.txt | 2 -
gemrb/plugins/GUIScript/GUIScript.cpp | 2792 +++++---
gemrb/plugins/GUIScript/GUIScript.h | 9 +-
gemrb/plugins/GUIScript/PythonHelpers.cpp | 2 +
gemrb/plugins/GUIScript/PythonHelpers.h | 8 +-
gemrb/plugins/IDSImporter/IDSImporter.cpp | 18 +-
gemrb/plugins/IDSImporter/IDSImporter.h | 11 +-
gemrb/plugins/IDSImporter/IDSImporterDefs.h | 8 +-
gemrb/plugins/INIImporter/INIImporter.cpp | 21 +-
gemrb/plugins/INIImporter/INIImporter.h | 9 +-
gemrb/plugins/ITMImporter/ITMImporter.cpp | 85 +-
gemrb/plugins/ITMImporter/ITMImporter.h | 7 +-
gemrb/plugins/IWDOpcodes/IWDOpcodes.cpp | 1049 ++-
gemrb/plugins/KEYImporter/CMakeLists.txt | 2 +-
gemrb/plugins/KEYImporter/Dictionary.cpp | 226 -
gemrb/plugins/KEYImporter/Dictionary.h | 84 -
gemrb/plugins/KEYImporter/KEYImporter.cpp | 161 +-
gemrb/plugins/KEYImporter/KEYImporter.h | 99 +-
gemrb/plugins/KEYImporter/Makefile.am | 2 +-
gemrb/plugins/MOSImporter/MOSImporter.cpp | 61 +-
gemrb/plugins/MOSImporter/MOSImporter.h | 4 +
gemrb/plugins/MUSImporter/MUSImporter.cpp | 14 +-
gemrb/plugins/MUSImporter/MUSImporter.h | 4 +
gemrb/plugins/MVEPlayer/MVEPlayer.cpp | 7 +-
gemrb/plugins/MVEPlayer/MVEPlayer.h | 4 +
gemrb/plugins/MVEPlayer/gstmvedemux.h | 6 +-
gemrb/plugins/MVEPlayer/mve_player.cpp | 30 +-
gemrb/plugins/MVEPlayer/mve_player.h | 8 +-
gemrb/plugins/Makefile.am | 2 +
gemrb/plugins/NullSound/NullSound.cpp | 7 +-
gemrb/plugins/NullSound/NullSound.h | 5 +-
gemrb/plugins/NullSource/CMakeLists.txt | 1 +
gemrb/plugins/NullSource/NullSource.cpp | 71 +
gemrb/plugins/NullSource/NullSource.h | 41 +
gemrb/plugins/OGGReader/OGGReader.cpp | 6 +-
gemrb/plugins/OGGReader/OGGReader.h | 4 +
gemrb/plugins/OpenALAudio/AmbientMgrAL.cpp | 36 +-
gemrb/plugins/OpenALAudio/AmbientMgrAL.h | 4 +
gemrb/plugins/OpenALAudio/OpenALAudio.cpp | 392 +-
gemrb/plugins/OpenALAudio/OpenALAudio.h | 14 +-
gemrb/plugins/OpenALAudio/StackLock.cpp | 3 +
gemrb/plugins/OpenALAudio/StackLock.h | 4 +
gemrb/plugins/PLTImporter/PLTImporter.cpp | 34 +-
gemrb/plugins/PLTImporter/PLTImporter.h | 4 +
gemrb/plugins/PNGImporter/PNGImporter.cpp | 6 +-
gemrb/plugins/PNGImporter/PNGImporter.h | 4 +
gemrb/plugins/PROImporter/PROImporter.cpp | 16 +-
gemrb/plugins/PROImporter/PROImporter.h | 7 +-
gemrb/plugins/PSTOpcodes/PSTOpcodes.cpp | 420 +-
gemrb/plugins/SAVImporter/CMakeLists.txt | 1 +
gemrb/plugins/SAVImporter/Makefile.am | 3 +
gemrb/plugins/SAVImporter/SAVImporter.cpp | 124 +
gemrb/plugins/SAVImporter/SAVImporter.h | 43 +
gemrb/plugins/SDLAudio/SDLAudio.cpp | 29 +-
gemrb/plugins/SDLAudio/SDLAudio.h | 9 +-
gemrb/plugins/SDLVideo/CMakeLists.txt | 4 +-
gemrb/plugins/SDLVideo/CocoaWrapper.m | 47 +
gemrb/plugins/SDLVideo/Makefile.am | 2 +-
gemrb/plugins/SDLVideo/SDL12Video.cpp | 343 +
gemrb/plugins/SDLVideo/SDL12Video.h | 67 +
gemrb/plugins/SDLVideo/SDL20Video.cpp | 707 ++
gemrb/plugins/SDLVideo/SDL20Video.h | 87 +
gemrb/plugins/SDLVideo/SDLVideo.cpp | 1551 ++--
gemrb/plugins/SDLVideo/SDLVideo.h | 102 +-
gemrb/plugins/SDLVideo/SDLVideoDriver.inl | 539 --
gemrb/plugins/SDLVideo/SpriteRenderer.inl | 912 +++
gemrb/plugins/SDLVideo/TileRenderer.inl | 51 +-
gemrb/plugins/SPLImporter/SPLImporter.cpp | 29 +-
gemrb/plugins/SPLImporter/SPLImporter.h | 7 +-
gemrb/plugins/STOImporter/STOImporter.cpp | 115 +-
gemrb/plugins/STOImporter/STOImporter.h | 23 +-
gemrb/plugins/TISImporter/TISImporter.cpp | 33 +-
gemrb/plugins/TISImporter/TISImporter.h | 7 +-
gemrb/plugins/TLKImporter/TLKImporter.cpp | 78 +-
gemrb/plugins/TLKImporter/TLKImporter.h | 8 +-
gemrb/plugins/TLKImporter/TlkOverride.cpp | 13 +-
gemrb/plugins/TLKImporter/TlkOverride.h | 4 +
gemrb/plugins/TTFImporter/CMakeLists.txt | 12 +
gemrb/plugins/TTFImporter/Freetype.cpp | 55 +
gemrb/plugins/TTFImporter/Freetype.h | 55 +
gemrb/plugins/TTFImporter/Makefile.am | 9 +
gemrb/plugins/TTFImporter/TTFFont.cpp | 287 +
gemrb/plugins/TTFImporter/TTFFont.h | 62 +
gemrb/plugins/TTFImporter/TTFFontManager.cpp | 135 +
gemrb/plugins/TTFImporter/TTFFontManager.h | 62 +
gemrb/plugins/VLCPlayer/CMakeLists.txt | 5 +
gemrb/plugins/VLCPlayer/VLCPlayer.cpp | 211 +
gemrb/plugins/VLCPlayer/VLCPlayer.h | 73 +
gemrb/plugins/VLCPlayer/VideoContext.cpp | 82 +
gemrb/plugins/VLCPlayer/VideoContext.h | 53 +
gemrb/plugins/WAVReader/WAVReader.cpp | 4 +-
gemrb/plugins/WAVReader/WAVReader.h | 4 +
gemrb/plugins/WEDImporter/WEDImporter.cpp | 29 +-
gemrb/plugins/WEDImporter/WEDImporter.h | 7 +-
gemrb/plugins/WMPImporter/WMPImporter.cpp | 67 +-
gemrb/plugins/WMPImporter/WMPImporter.h | 7 +-
gemrb/plugins/ZLibManager/ZLibManager.cpp | 7 +-
gemrb/plugins/ZLibManager/ZLibManager.h | 6 +-
gemrb/tests/minimal/data/fonts.2da | 4 +-
gemrb/tests/minimal/data/numtest.bam | Bin 0 -> 978 bytes
gemrb/unhardcoded/Makefile.am | 2 +
gemrb/unhardcoded/bg1/Makefile.am | 3 +
gemrb/{override => unhardcoded}/bg1/ability.2da | 0
gemrb/{override => unhardcoded}/bg1/acidblgr.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/acidblmu.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/acidblob.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/acidbloc.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/aligns.2da | 0
gemrb/{override => unhardcoded}/bg1/areapro.2da | 0
gemrb/{override => unhardcoded}/bg1/arrow.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/arrowex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/arrowflb.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/arrowflg.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/arrowfli.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/arrowflm.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/arrowhvy.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/bg1/avatars.2da | 322 +
gemrb/{override => unhardcoded}/bg1/avprefc.2da | 0
gemrb/{override => unhardcoded}/bg1/avprefr.2da | 0
gemrb/{override => unhardcoded}/bg1/axe.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/axeex.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/bg1/bios.2da | 24 +
gemrb/unhardcoded/bg1/bloodclr.2da | 29 +
gemrb/{override => unhardcoded}/bg1/bolt.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/boltex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/bullet.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/bulletex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/cgtable.2da | 0
gemrb/{override => unhardcoded}/bg1/chromorb.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/bg1/clabdrui.2da | 6 +
gemrb/unhardcoded/bg1/clabpala.2da | 6 +
gemrb/unhardcoded/bg1/clabrngr.2da | 4 +
gemrb/{override => unhardcoded}/bg1/classes.2da | 0
gemrb/{override => unhardcoded}/bg1/cloud.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/cloudkil.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/clowncol.2da | 0
gemrb/unhardcoded/bg1/clskills.2da | 25 +
gemrb/{override => unhardcoded}/bg1/dagger.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/daggerex.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/bg1/damage.2da | 16 +
gemrb/{override => unhardcoded}/bg1/dart.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/dartex.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/bg1/defsound.2da | 36 +
gemrb/unhardcoded/bg1/difflvls.2da | 5 +
gemrb/unhardcoded/bg1/dsclass.2da | 24 +
gemrb/unhardcoded/bg1/dsrace.2da | 7 +
gemrb/unhardcoded/bg1/dstable.2da | 6 +
gemrb/{override => unhardcoded}/bg1/dualclas.2da | 0
gemrb/unhardcoded/bg1/effects.ids | 319 +
gemrb/{override => unhardcoded}/bg1/fireball.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/fireblic.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/firebolt.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/firebtbl.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/firestor.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/fistweap.2da | 0
gemrb/unhardcoded/bg1/fonts.2da | 17 +
gemrb/{override => unhardcoded}/bg1/formatio.2da | 0
gemrb/unhardcoded/bg1/gametime.2da | 6 +
gemrb/{override => unhardcoded}/bg1/gaze.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/bg1/gemact.ids | 14 +
gemrb/{override => unhardcoded}/bg1/gemprjtl.ids | 0
gemrb/unhardcoded/bg1/gemrb.ini | 129 +
gemrb/unhardcoded/bg1/gemtrig.ids | 9 +
gemrb/{override => unhardcoded}/bg1/grease.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/bg1/guibtact.2da | 37 +
gemrb/{override => unhardcoded}/bg1/guils.chu | Bin 230 -> 230 bytes
gemrb/{override => unhardcoded}/bg1/haterace.2da | 0
.../{override/bg2 => unhardcoded/bg1}/hlymite.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/icestorm.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/inarea.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/bg1/inareapa.pro | Bin 0 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/inareasm.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/item_use.2da | 0
gemrb/{override => unhardcoded}/bg1/itemsnd.2da | 0
gemrb/{override => unhardcoded}/bg1/itemtype.2da | 0
gemrb/{override => unhardcoded}/bg1/itemuse.2da | 0
gemrb/{override => unhardcoded}/bg1/k_m_e.2da | 0
gemrb/{override => unhardcoded}/bg1/k_m_g.2da | 0
gemrb/{override => unhardcoded}/bg1/k_m_h.2da | 0
gemrb/{override => unhardcoded}/bg1/k_m_he.2da | 0
gemrb/{override => unhardcoded}/bg1/kitlist.2da | 0
gemrb/{override => unhardcoded}/bg1/kittable.2da | 0
gemrb/{override => unhardcoded}/bg1/lightsto.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/bg1/magesch.2da | 13 +
gemrb/{override => unhardcoded}/bg1/magicmis.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/mpal256.bmp | Bin 92214 -> 92214 bytes
gemrb/{override => unhardcoded}/bg1/music.2da | 0
gemrb/unhardcoded/bg1/overlay.2da | 35 +
gemrb/{override => unhardcoded}/bg1/pathfind.2da | 0
gemrb/unhardcoded/bg1/pdolls.2da | 89 +
gemrb/{override => unhardcoded}/bg1/pictures.2da | 0
gemrb/unhardcoded/bg1/polish.ini | 30 +
gemrb/unhardcoded/bg1/proftype.2da | 35 +
gemrb/unhardcoded/bg1/qslots.2da | 23 +
gemrb/{override => unhardcoded}/bg1/races.2da | 0
gemrb/{override => unhardcoded}/bg1/randitem.2da | 0
gemrb/unhardcoded/bg1/restmov.2da | 11 +
gemrb/{override => unhardcoded}/bg1/savegame.2da | 0
gemrb/{override => unhardcoded}/bg1/script.2da | 0
gemrb/unhardcoded/bg1/shtable.2da | 42 +
gemrb/{override => unhardcoded}/bg1/skills.2da | 0
gemrb/{override => unhardcoded}/bg1/sleep.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/slottype.2da | 0
gemrb/{override => unhardcoded}/bg1/sparbknp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/sparbkpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/sparblnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/sparblpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/sparchnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/sparchpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/spargonp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/spargopa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/spargrnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/spargrpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/sparicnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/sparicpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/sparklbk.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/sparklbl.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/sparklch.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/sparklgo.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/sparklgr.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/sparklic.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/sparklma.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/sparklor.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/sparklpu.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/sparklre.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/sparklst.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/sparmanp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/sparmapa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/sparornp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/sparorpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/sparpunp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/sparpupa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/sparrenp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/sparrepa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/sparstnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/sparstpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/spear.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/spearex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/spfirebl.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/spklarbk.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/spklarbl.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/spklarch.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/spklargo.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/spklargr.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/spklaric.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/spklarma.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/spklaror.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/spklarpu.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/spklarre.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/spklarst.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/splspec.2da | 0
gemrb/{override => unhardcoded}/bg1/spscorch.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg1/spscoric.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/bg1/stances.2da | 6 +
gemrb/{override/pst => unhardcoded/bg1}/start.2da | 0
gemrb/{override => unhardcoded}/bg1/stone.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/bg1/strings.2da | 187 +
gemrb/unhardcoded/bg1/textscrn.2da | 22 +
gemrb/{override => unhardcoded}/bg1/trapglyp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/trapskul.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/bg1/vcremap.2da | 11 +
gemrb/{override => unhardcoded}/bg1/walksnd.2da | 0
gemrb/{override => unhardcoded}/bg1/weapprof.2da | 0
gemrb/{override => unhardcoded}/bg1/web.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg1/wssingle.2da | 0
gemrb/{override => unhardcoded}/bg2/HPBARB.2da | 0
gemrb/unhardcoded/bg2/Makefile.am | 3 +
gemrb/{override => unhardcoded}/bg2/ability.2da | 0
gemrb/{override => unhardcoded}/bg2/aligns.2da | 0
gemrb/{override => unhardcoded}/bg2/areapro.2da | 0
gemrb/{override => unhardcoded}/bg2/at2xlvl.spl | Bin 250 -> 250 bytes
gemrb/unhardcoded/bg2/avatars.2da | 332 +
gemrb/{override => unhardcoded}/bg2/avprefc.2da | 0
gemrb/{override => unhardcoded}/bg2/avprefr.2da | 0
gemrb/unhardcoded/bg2/bloodclr.2da | 29 +
gemrb/{override => unhardcoded}/bg2/cgtable.2da | 0
gemrb/{override => unhardcoded}/bg2/classes.2da | 0
gemrb/{override => unhardcoded}/bg2/clowncol.2da | 0
gemrb/unhardcoded/bg2/clskills.2da | 25 +
gemrb/{override => unhardcoded}/bg2/colrspry.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg2/comet.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/bg2/damage.2da | 16 +
gemrb/unhardcoded/bg2/defsound.2da | 36 +
gemrb/{override => unhardcoded}/bg2/denyspl.2da | 0
gemrb/unhardcoded/bg2/dsclass.2da | 24 +
gemrb/unhardcoded/bg2/dsrace.2da | 7 +
gemrb/unhardcoded/bg2/dstable.2da | 6 +
gemrb/unhardcoded/bg2/effects.ids | 321 +
gemrb/{override => unhardcoded}/bg2/findtrap.spl | Bin 298 -> 298 bytes
gemrb/{override => unhardcoded}/bg2/fistweap.2da | 0
gemrb/unhardcoded/bg2/fonts.2da | 21 +
gemrb/{override => unhardcoded}/bg2/formatio.2da | 0
gemrb/unhardcoded/bg2/gametime.2da | 6 +
gemrb/{override => unhardcoded}/bg2/gemprjtl.ids | 0
gemrb/unhardcoded/bg2/gemrb.ini | 132 +
gemrb/{override => unhardcoded}/bg2/gender.2da | 0
gemrb/{override => unhardcoded}/bg2/guibtact.2da | 0
gemrb/{override => unhardcoded}/bg2/guiid.chu | Bin 92 -> 92 bytes
gemrb/{override => unhardcoded}/bg2/guils.chu | Bin 234 -> 234 bytes
gemrb/{override => unhardcoded}/bg2/halvdur.spl | Bin 250 -> 250 bytes
.../{override/pst => unhardcoded/bg2}/hlymite.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg2/item_use.2da | 0
gemrb/{override => unhardcoded}/bg2/itemsnd.2da | 0
gemrb/{override => unhardcoded}/bg2/itemspec.2da | 0
gemrb/{override => unhardcoded}/bg2/itemtype.2da | 0
gemrb/{override => unhardcoded}/bg2/itemuse.2da | 0
gemrb/{override => unhardcoded}/bg2/k_bn_d.2da | 0
gemrb/{override => unhardcoded}/bg2/k_bn_e.2da | 0
gemrb/{override => unhardcoded}/bg2/k_bn_g.2da | 0
gemrb/{override => unhardcoded}/bg2/k_bn_h.2da | 0
gemrb/{override => unhardcoded}/bg2/k_bn_he.2da | 0
gemrb/{override => unhardcoded}/bg2/k_bn_hl.2da | 0
gemrb/{override => unhardcoded}/bg2/k_bn_ho.2da | 0
gemrb/{override => unhardcoded}/bg2/k_m_e.2da | 0
gemrb/{override => unhardcoded}/bg2/k_m_g.2da | 0
gemrb/{override => unhardcoded}/bg2/k_m_h.2da | 0
gemrb/{override => unhardcoded}/bg2/k_m_he.2da | 0
gemrb/{override => unhardcoded}/bg2/lightb.pro | Bin 512 -> 512 bytes
.../shared => unhardcoded/bg2}/lightbnb.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/bg2/magesch.2da | 13 +
gemrb/{override => unhardcoded}/bg2/modal.2da | 0
gemrb/{override => unhardcoded}/bg2/monkbon.2da | 0
gemrb/unhardcoded/bg2/overlay.2da | 35 +
gemrb/unhardcoded/bg2/pathfind.2da | 6 +
gemrb/unhardcoded/bg2/pdolls.2da | 106 +
gemrb/{override => unhardcoded}/bg2/pictures.2da | 0
gemrb/unhardcoded/bg2/proftype.2da | 35 +
gemrb/{override => unhardcoded}/bg2/qslot2.2da | 0
gemrb/unhardcoded/bg2/qslots.2da | 23 +
gemrb/unhardcoded/bg2/races.2da | 12 +
gemrb/{override => unhardcoded}/bg2/randitem.2da | 0
gemrb/{override => unhardcoded}/bg2/rest.spl | Bin 202 -> 202 bytes
gemrb/{override => unhardcoded}/bg2/restmov.2da | 0
gemrb/{override => unhardcoded}/bg2/sanctry.vvc | Bin 492 -> 492 bytes
gemrb/{override => unhardcoded}/bg2/savegame.2da | 0
gemrb/{override => unhardcoded}/bg2/script.2da | 0
gemrb/{override => unhardcoded}/bg2/shtable.2da | 0
gemrb/{override => unhardcoded}/bg2/skills.2da | 0
gemrb/{override => unhardcoded}/bg2/slottype.2da | 0
gemrb/{override => unhardcoded}/bg2/snow.spl | Bin 202 -> 202 bytes
gemrb/{override => unhardcoded}/bg2/spbrnhnd.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg2/spconeco.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg2/spentaci.vvc | Bin 492 -> 492 bytes
gemrb/{override => unhardcoded}/bg2/spfdeath.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg2/spfirewl.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg2/spgenhla.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg2/spholymt.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/bg2/splspec.2da | 9 +
gemrb/{override => unhardcoded}/bg2/spscorch.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/bg2/spscoric.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/bg2/spshield.vvc | Bin 492 -> 492 bytes
gemrb/unhardcoded/bg2/stances.2da | 6 +
gemrb/{override => unhardcoded}/bg2/start.2da | 0
gemrb/unhardcoded/bg2/strings.2da | 187 +
gemrb/{override => unhardcoded}/bg2/walksnd.2da | 0
gemrb/{override => unhardcoded}/bg2/wildmag.2da | 0
gemrb/{override => unhardcoded}/bg2/wishcode.2da | 0
gemrb/{override => unhardcoded}/bg2/wsshield.2da | 0
gemrb/{override => unhardcoded}/bg2/wssingle.2da | 0
gemrb/{override => unhardcoded}/bg2/wstwohnd.2da | 0
gemrb/{override => unhardcoded}/bg2/wstwowpn.2da | 0
gemrb/unhardcoded/how/Makefile.am | 3 +
gemrb/{override => unhardcoded}/how/ability.2da | 0
gemrb/{override => unhardcoded}/how/abjurap.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/abjurh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/abjurt.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/acidblgr.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/acidblmu.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/acidblob.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/acidbloc.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/acidh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/adhwil.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/adhwilh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/alance.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/aligns.2da | 0
gemrb/{override => unhardcoded}/how/altera.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/alteranp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/alterap.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/alteras.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/alterh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/altert.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/area1np.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/area1p.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/area2.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/area2np.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/area3p.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/area4np.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/areapro.2da | 0
gemrb/{override => unhardcoded}/how/armorh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/arrow.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/arrowex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/arrowflb.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/arrowflg.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/arrowfli.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/arrowflm.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/arrowhvy.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/ascorch.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/astorm.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/asumm1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/asumm1h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/asumm1x.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/asumm2h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/asumm3h.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/how/avatars.2da | 417 ++
gemrb/{override => unhardcoded}/how/avprefc.2da | 0
gemrb/{override => unhardcoded}/how/avprefr.2da | 0
gemrb/{override => unhardcoded}/how/axe.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/axeex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/bbarrh1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/bbarrh2.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/bbarrier.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/bdeath.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/blessh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/how/bloodclr.2da | 29 +
gemrb/{override => unhardcoded}/how/bolt.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/boltex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/bscloud.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/bullet.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/bulletex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/calllih.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/ccdamah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/ccommah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/ccwounh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/cdiseah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/ceelem1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/ceelemh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/ceelemx.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/cfelem1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/cfelemh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/cfelemx.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/cfog.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/cgraceh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/cgtable.2da | 0
gemrb/{override => unhardcoded}/how/chant.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/chromorb.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/classes.2da | 0
gemrb/{override => unhardcoded}/how/cldamah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/cloud.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/cloudb.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/cloudbh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/cloudkil.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/cloudks.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/clowncol.2da | 0
gemrb/unhardcoded/how/clskills.2da | 22 +
gemrb/{override => unhardcoded}/how/clssplab.2da | 0
gemrb/{override => unhardcoded}/how/clwounh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/cmdamah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/cmwounh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/cobones.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/cobonh1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/cobonh2.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/cocold.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/cocoldh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/cofire.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/coldh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/colrspry.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/confush.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/confusp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/confusw.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/conjuh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/conjut.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/copest.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/cry150.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/cry200.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/cry225.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/cry250.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/cry500np.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/csdamah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/cstrenh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/cswounh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/curseh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/cwelem1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/cwelemh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/cwelemx.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/cynicism.2da | 0
gemrb/{override => unhardcoded}/how/dagger.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/daggerex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/damage.2da | 0
gemrb/{override => unhardcoded}/how/dart.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/dartex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/dbreath.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/ddeath.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/ddeath2.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/ddoorh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/how/defsound.2da | 36 +
gemrb/{override => unhardcoded}/how/destruh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/dfog.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/how/difflvls.2da | 5 +
gemrb/{override => unhardcoded}/how/disint.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/disinth.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/dispel.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/divinh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/divint.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/how/dsclass.2da | 24 +
gemrb/{override => unhardcoded}/how/dspell.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/dspellh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/how/dsrace.2da | 7 +
gemrb/unhardcoded/how/dstable.2da | 6 +
gemrb/{override => unhardcoded}/how/dualclas.2da | 0
gemrb/unhardcoded/how/effects.ids | 301 +
gemrb/{override => unhardcoded}/how/electrh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/emotion.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/enchah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/enchannp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/enchat.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/entangle.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/equake.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/exaltah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/factioh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/findtrap.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/fireball.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/fireblic.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/firebolt.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/firebtbl.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/fireh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/firestor.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/fistweap.2da | 0
gemrb/{override => unhardcoded}/how/fodeath.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/how/fonts.2da | 22 +
gemrb/{override => unhardcoded}/how/formatio.2da | 0
gemrb/{override => unhardcoded}/how/fseed.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/fstrikh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/how/gametime.2da | 6 +
gemrb/{override => unhardcoded}/how/garmorh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/gaze.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/gemprjtl.ids | 0
gemrb/unhardcoded/how/gemrb.ini | 133 +
gemrb/{override => unhardcoded}/how/gender.2da | 0
gemrb/{override => unhardcoded}/how/golcloud.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/grease.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/gshout.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/guibtact.2da | 0
gemrb/{override => unhardcoded}/how/guils.chu | Bin 230 -> 230 bytes
gemrb/{override => unhardcoded}/how/harmh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/harmony.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/haterace.2da | 0
gemrb/{override => unhardcoded}/how/healh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/hmighth.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/hold.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/hsmite.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/hword.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/icelance.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/icestorm.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/icloud.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/iclouda.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/icloudb.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/illush.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/illust.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/inarea.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/inareanp.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/how/inareapa.pro | Bin 0 -> 768 bytes
gemrb/{override => unhardcoded}/how/inareasm.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/invoch.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/invoct.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/iplague.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/island00.2da | 0
gemrb/unhardcoded/how/itemsnd.2da | 81 +
gemrb/unhardcoded/how/itemtype.2da | 77 +
gemrb/{override => unhardcoded}/how/itemuse.2da | 0
gemrb/{override => unhardcoded}/how/kitlist.2da | 0
gemrb/{override => unhardcoded}/how/lightb.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/how/lightbnb.pro | Bin 0 -> 512 bytes
gemrb/{override => unhardcoded}/how/lightsto.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/lodisr.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/how/magesch.2da | 12 +
gemrb/{override => unhardcoded}/how/magicmis.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/malison.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/mfmiss.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/mfmiss2.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/mfmissh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/mmagich.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/mmissile.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/moelda.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/mrage.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/mrageh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/mspore.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/msumm1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/msumm1h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/msumm1x.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/msumm2h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/msumm3h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/msumm4h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/msumm5h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/msumm6h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/msumm7h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/mswordh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/mtouchh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/necroh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/necrot.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/npoisoh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/ofsphe.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/how/overlay.2da | 35 +
gemrb/{override => unhardcoded}/how/paralh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/pathfind.2da | 0
gemrb/{override => unhardcoded}/how/pdolls.2da | 0
gemrb/{override => unhardcoded}/how/pfire.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/pictures.2da | 0
gemrb/{override => unhardcoded}/how/poisonh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/pomab.2da | 0
gemrb/{override => unhardcoded}/how/portal.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/prayer.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/prayerh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/how/proftype.2da | 61 +
gemrb/{override => unhardcoded}/how/protevil.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/prtl_cl.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/prtl_cl.spl | Bin 202 -> 202 bytes
gemrb/{override => unhardcoded}/how/prtl_op.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/prtl_op.spl | Bin 202 -> 202 bytes
gemrb/{override => unhardcoded}/how/pspray.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/pwkill.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/pwsileh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/pwstun.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/pwstunh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/how/qslots.2da | 23 +
gemrb/{override => unhardcoded}/how/races.2da | 0
gemrb/{override => unhardcoded}/how/rad100.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/rad250.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/randitem.2da | 0
gemrb/{override => unhardcoded}/how/rdeadh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/recitah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/resurrh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/rng450.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/rparalh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/rwotfag.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/rwotfah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/sarmorh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/savegame.2da | 0
gemrb/{override => unhardcoded}/how/scharge.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/scharge.spl | Bin 250 -> 250 bytes
gemrb/{override => unhardcoded}/how/schargh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/script.2da | 0
gemrb/{override => unhardcoded}/how/seater.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/seaterh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/sgrowth.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/shout.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/shroud.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/shtable.2da | 0
gemrb/{override => unhardcoded}/how/skills.2da | 0
gemrb/{override => unhardcoded}/how/sleep.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/slivinh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/slottype.2da | 0
gemrb/{override => unhardcoded}/how/soflamh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/sohope.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/sooneh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/sopain.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/sparbknp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/sparbkpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/sparblnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/sparblpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/sparchnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/sparchpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/spargonp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/spargopa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/spargrnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/spargrpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/sparicnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/sparicpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/sparklbk.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/sparklbl.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/sparklch.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/sparklgo.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/sparklgr.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/sparklic.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/sparklma.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/sparklor.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/sparklpu.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/sparklre.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/sparklst.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/sparmanp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/sparmapa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/sparornp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/sparorpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/sparpunp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/sparpupa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/sparrenp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/sparrepa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/sparstnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/sparstpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/spear.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/spearex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/spfirebl.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/spklarbk.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/spklarbl.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/spklarch.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/spklargo.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/spklargr.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/spklaric.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/spklarma.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/spklaror.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/spklarpu.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/spklarre.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/spklarst.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/splprot.2da | 0
gemrb/{override => unhardcoded}/how/splspec.2da | 0
gemrb/{override => unhardcoded}/how/spoisoh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/spscorch.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/spscoric.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/spwrath.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/ssorbh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/ssswarm.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/sstone.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/sstoneh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/start.2da | 0
gemrb/{override => unhardcoded}/how/stone.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/strengh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/how/strings.2da | 187 +
gemrb/{override => unhardcoded}/how/suffoc.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/suffoch.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/sunfire.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/sunray.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/sunscoh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/swave.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/swaveh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/trapglyp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/trapskul.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/tspray.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/turn.spl | Bin 202 -> 202 bytes
gemrb/{override => unhardcoded}/how/ublight.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/uward.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/uwardh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/how/vcremap.2da | 32 +
gemrb/{override => unhardcoded}/how/vspherh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/wdeath1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/wdeath2.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/weapprof.2da | 0
gemrb/{override => unhardcoded}/how/web.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/whirlw.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/womoon.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/wowisp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/wvdeath.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/wvhith.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/how/wwolf.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/how/zlaura.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/iwd/Makefile.am | 3 +
gemrb/{override => unhardcoded}/iwd/ability.2da | 0
gemrb/{override => unhardcoded}/iwd/abjurap.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/abjurh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/abjurt.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/acidblgr.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/acidblmu.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/acidblob.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/acidbloc.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/acidh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/adhwil.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/adhwilh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/alance.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/aligns.2da | 0
gemrb/{override => unhardcoded}/iwd/altera.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/alteranp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/alterap.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/alteras.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/alterh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/altert.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/area1np.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/area1p.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/area2.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/area2np.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/area3p.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/area4np.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/armorh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/arrow.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/arrowex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/arrowflb.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/arrowflg.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/arrowfli.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/arrowflm.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/arrowhvy.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/ascorch.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/astorm.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/asumm1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/asumm1h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/asumm1x.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/asumm2h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/asumm3h.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd/avatars.2da | 414 ++
gemrb/{override => unhardcoded}/iwd/avprefc.2da | 0
gemrb/{override => unhardcoded}/iwd/avprefr.2da | 0
gemrb/{override => unhardcoded}/iwd/axe.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/axeex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/bbarrh1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/bbarrh2.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/bbarrier.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/bdeath.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/blessh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd/bloodclr.2da | 29 +
gemrb/{override => unhardcoded}/iwd/bolt.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/boltex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/bscloud.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/bullet.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/bulletex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/calllih.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/ccdamah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/ccommah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/ccwounh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/cdiseah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/ceelem1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/ceelemh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/ceelemx.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/cfelem1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/cfelemh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/cfelemx.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/cfog.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/cgraceh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/cgtable.2da | 0
gemrb/{override => unhardcoded}/iwd/chant.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/chromorb.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/classes.2da | 0
gemrb/{override => unhardcoded}/iwd/cldamah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/cloud.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/cloudb.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/cloudbh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/cloudkil.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/cloudks.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/clowncol.2da | 0
gemrb/unhardcoded/iwd/clskills.2da | 22 +
gemrb/{override => unhardcoded}/iwd/clssplab.2da | 0
gemrb/{override => unhardcoded}/iwd/clwounh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/cmdamah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/cmwounh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/cobones.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/cobonh1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/cobonh2.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/cocold.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/cocoldh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/cofire.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/coldh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/colrspry.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/confush.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/confusp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/confusw.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/conjuh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/conjut.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/copest.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/cry150.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/cry200.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/cry225.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/cry250.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/cry500np.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/csdamah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/cstrenh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/cswounh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/curseh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/cwelem1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/cwelemh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/cwelemx.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/cynicism.2da | 0
gemrb/{override => unhardcoded}/iwd/dagger.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/daggerex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/damage.2da | 0
gemrb/{override => unhardcoded}/iwd/dart.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/dartex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/dbreath.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/ddeath.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/ddeath2.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/ddoorh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd/defsound.2da | 36 +
gemrb/{override => unhardcoded}/iwd/destruh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/dfog.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/disint.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/disinth.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/dispel.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/divinh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/divint.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd/dsclass.2da | 24 +
gemrb/{override => unhardcoded}/iwd/dspell.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/dspellh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd/dsrace.2da | 7 +
gemrb/unhardcoded/iwd/dstable.2da | 6 +
gemrb/{override => unhardcoded}/iwd/dualclas.2da | 0
gemrb/unhardcoded/iwd/effects.ids | 300 +
gemrb/{override => unhardcoded}/iwd/electrh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/emotion.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/enchah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/enchannp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/enchat.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/entangle.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/equake.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/exaltah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/factioh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/findtrap.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/fireball.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/fireblic.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/firebolt.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/firebtbl.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/fireh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/firestor.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/fistweap.2da | 0
gemrb/{override => unhardcoded}/iwd/fodeath.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd/fonts.2da | 22 +
gemrb/{override => unhardcoded}/iwd/formatio.2da | 0
gemrb/{override => unhardcoded}/iwd/fseed.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/fstrikh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd/gametime.2da | 6 +
gemrb/{override => unhardcoded}/iwd/garmorh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/gaze.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/gemprjtl.ids | 0
gemrb/unhardcoded/iwd/gemrb.ini | 133 +
gemrb/{override => unhardcoded}/iwd/gender.2da | 0
gemrb/{override => unhardcoded}/iwd/golcloud.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/grease.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/gshout.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/guibtact.2da | 0
gemrb/{override => unhardcoded}/iwd/guils.chu | Bin 230 -> 230 bytes
gemrb/{override => unhardcoded}/iwd/harmh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/harmony.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/haterace.2da | 0
gemrb/{override => unhardcoded}/iwd/healh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/hmighth.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/hold.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/hsmite.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/hword.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/icelance.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/icestorm.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/icloud.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/iclouda.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/icloudb.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/illush.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/illust.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/inarea.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/inareanp.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/iwd/inareapa.pro | Bin 0 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/inareasm.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/invoch.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/invoct.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/iplague.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/iwd/itemsnd.2da | 81 +
gemrb/unhardcoded/iwd/itemtype.2da | 77 +
gemrb/{override => unhardcoded}/iwd/itemuse.2da | 0
gemrb/{override => unhardcoded}/iwd/kitlist.2da | 0
gemrb/{override => unhardcoded}/iwd/lightb.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd/lightbnb.pro | Bin 0 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/lightsto.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/lodisr.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/iwd/magesch.2da | 12 +
gemrb/{override => unhardcoded}/iwd/magicmis.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/malison.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/mfmiss.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/mfmiss2.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/mfmissh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/mmagich.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/mmissile.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/moelda.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/mpal256.bmp | Bin 92214 -> 92214 bytes
gemrb/{override => unhardcoded}/iwd/mrage.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/mrageh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/mspore.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/msumm1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/msumm1h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/msumm1x.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/msumm2h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/msumm3h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/msumm4h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/msumm5h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/msumm6h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/msumm7h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/mswordh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/mtouchh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/necroh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/necrot.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/npoisoh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/ofsphe.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd/overlay.2da | 35 +
gemrb/{override => unhardcoded}/iwd/paralh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/pathfind.2da | 0
gemrb/{override => unhardcoded}/iwd/pdolls.2da | 0
gemrb/{override => unhardcoded}/iwd/pfire.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/pictures.2da | 0
gemrb/{override => unhardcoded}/iwd/poisonh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/pomab.2da | 0
gemrb/{override => unhardcoded}/iwd/portal.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/prayer.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/prayerh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd/proftype.2da | 61 +
gemrb/{override => unhardcoded}/iwd/protevil.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/prtl_cl.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/prtl_cl.spl | Bin 202 -> 202 bytes
gemrb/{override => unhardcoded}/iwd/prtl_op.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/prtl_op.spl | Bin 202 -> 202 bytes
gemrb/{override => unhardcoded}/iwd/pspray.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/pwkill.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/pwsileh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/pwstun.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/pwstunh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd/qslots.2da | 23 +
gemrb/{override => unhardcoded}/iwd/races.2da | 0
gemrb/{override => unhardcoded}/iwd/rad100.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/rad250.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/randitem.2da | 0
gemrb/{override => unhardcoded}/iwd/rdeadh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/recitah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/resurrh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/rng450.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/rparalh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/rwotfag.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/rwotfah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/sarmorh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/savegame.2da | 0
gemrb/{override => unhardcoded}/iwd/scharge.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/scharge.spl | Bin 250 -> 250 bytes
gemrb/{override => unhardcoded}/iwd/schargh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/script.2da | 0
gemrb/{override => unhardcoded}/iwd/seater.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/seaterh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/sgrowth.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/shout.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/shroud.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/shtable.2da | 0
gemrb/{override => unhardcoded}/iwd/skills.2da | 0
gemrb/{override => unhardcoded}/iwd/sleep.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/slivinh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/slottype.2da | 0
gemrb/{override => unhardcoded}/iwd/soflamh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/sohope.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/sooneh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/sopain.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/sparbknp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/sparbkpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/sparblnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/sparblpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/sparchnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/sparchpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/spargonp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/spargopa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/spargrnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/spargrpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/sparicnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/sparicpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/sparklbk.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/sparklbl.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/sparklch.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/sparklgo.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/sparklgr.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/sparklic.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/sparklma.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/sparklor.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/sparklpu.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/sparklre.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/sparklst.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/sparmanp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/sparmapa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/sparornp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/sparorpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/sparpunp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/sparpupa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/sparrenp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/sparrepa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/sparstnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/sparstpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/spear.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/spearex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/spfirebl.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/spklarbk.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/spklarbl.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/spklarch.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/spklargo.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/spklargr.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/spklaric.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/spklarma.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/spklaror.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/spklarpu.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/spklarre.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/spklarst.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/splprot.2da | 0
gemrb/{override => unhardcoded}/iwd/splspec.2da | 0
gemrb/{override => unhardcoded}/iwd/spoisoh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/spscorch.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/spscoric.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/spwrath.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/ssorbh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/ssswarm.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/sstone.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/sstoneh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/start.2da | 0
gemrb/{override => unhardcoded}/iwd/stone.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/strengh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd/strings.2da | 187 +
gemrb/{override => unhardcoded}/iwd/suffoc.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/suffoch.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/sunfire.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/sunray.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/sunscoh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/swave.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/swaveh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/trapglyp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/trapskul.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/tspray.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/ublight.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/uward.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/uwardh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd/vcremap.2da | 32 +
gemrb/{override => unhardcoded}/iwd/vspherh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/wdeath1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/wdeath2.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/weapprof.2da | 0
gemrb/{override => unhardcoded}/iwd/web.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/whirlw.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/womoon.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/wowisp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/wvdeath.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/wvhith.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd/wwolf.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd/zlaura.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/iwd2/Makefile.am | 3 +
gemrb/unhardcoded/iwd2/ability.2da | 9 +
gemrb/{override => unhardcoded}/iwd2/abjura.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/abjurap.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/abjurh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/abjurt.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/abreath.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/acidblgr.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/acidblmu.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/acidblob.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/acidbloc.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/acidh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd2/acidh.vvc | Bin 0 -> 492 bytes
gemrb/{override => unhardcoded}/iwd2/adhwil.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/adhwilh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/alance.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/aligns.2da | 0
gemrb/{override => unhardcoded}/iwd2/altera.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/alteranp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/alterap.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/alteraps.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/alteras.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/alterh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/altert.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/area1np.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/area1npl.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/area1p.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/area1pl.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/area1ps.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/area2.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/area2np.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/area3p.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/area4np.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/armorh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/arrow.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/arrowex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/arrowflb.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/arrowflg.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/arrowfli.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/arrowflm.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/arrowhvy.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd2/artstr.spl | Bin 0 -> 218 bytes
gemrb/{override => unhardcoded}/iwd2/ascorch.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/astorm.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/asumm1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/asumm1h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/asumm1x.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/asumm2h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/asumm3h.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd2/avatars.2da | 433 ++
gemrb/{override => unhardcoded}/iwd2/avprefc.2da | 0
gemrb/{override => unhardcoded}/iwd2/avprefr.2da | 0
gemrb/{override => unhardcoded}/iwd2/axe.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/axeex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/bbarrh1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/bbarrh2.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/bbarrier.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/bdeath.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/bigboldr.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/iwd2/bios.2da | 14 +
gemrb/{override => unhardcoded}/iwd2/blessh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd2/bloodclr.2da | 29 +
gemrb/{override => unhardcoded}/iwd2/bolt.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/boltex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/boulder.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/bscloud.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/bullet.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/bulletex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/calllih.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/ccdamah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/ccommah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/ccwounh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/cdiseah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/ceelem1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/ceelemh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/ceelemx.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/cfelem1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/cfelemh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/cfelemx.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/cfog.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/cgraceh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/cgtable.2da | 0
gemrb/{override => unhardcoded}/iwd2/chant.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/chromorb.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd2/classes.2da | 38 +
gemrb/{override => unhardcoded}/iwd2/cldamah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/cloud.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/cloudb.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/cloudbh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/cloudkil.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/cloudks.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/clowncol.2da | 0
gemrb/unhardcoded/iwd2/clskills.2da | 15 +
gemrb/{override => unhardcoded}/iwd2/clwounh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/cmdamah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/cmwounh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/cobones.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/cobonh1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/cobonh2.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/cocold.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/cocoldh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/cofire.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/coldh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd2/coldh.vvc | Bin 0 -> 492 bytes
gemrb/{override => unhardcoded}/iwd2/colrspry.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/confush.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/confusp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/confusw.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/conjuh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/conjut.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/copest.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/iwd2/cripstr.spl | Bin 0 -> 266 bytes
gemrb/{override => unhardcoded}/iwd2/cry150.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/cry200.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/cry225.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/cry250.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/cry500np.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/csdamah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/cstrenh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/cswounh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/curseh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/cwelem1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/cwelemh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/cwelemx.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/dagger.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/daggerex.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/iwd2/damage.2da | 19 +
gemrb/{override => unhardcoded}/iwd2/dart.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/dartex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/dattach.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/dbreath.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/ddeath.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/ddeath2.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/ddoorh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd2/defsound.2da | 36 +
gemrb/{override => unhardcoded}/iwd2/destruh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd2/detect.spl | Bin 0 -> 346 bytes
gemrb/{override => unhardcoded}/iwd2/dfog.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/iwd2/dirty.spl | Bin 0 -> 410 bytes
gemrb/{override => unhardcoded}/iwd2/disint.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/disinth.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/dispel.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/divinh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/divint.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd2/dsclass.2da | 15 +
gemrb/{override => unhardcoded}/iwd2/dspell.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/dspellh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd2/dsrace.2da | 7 +
gemrb/unhardcoded/iwd2/dstable.2da | 6 +
gemrb/unhardcoded/iwd2/effects.ids | 368 +
gemrb/{override => unhardcoded}/iwd2/electrh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd2/electrh.vvc | Bin 0 -> 492 bytes
gemrb/{override => unhardcoded}/iwd2/emotion.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/enchah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/enchan.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/enchannp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/enchat.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/entangle.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/entropy.2da | 0
gemrb/{override => unhardcoded}/iwd2/equake.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/exaltah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/factioh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/fbreath.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/iwd2/feat00.spl | Bin 0 -> 266 bytes
gemrb/unhardcoded/iwd2/feat02.spl | Bin 0 -> 266 bytes
gemrb/unhardcoded/iwd2/feat07.spl | Bin 0 -> 266 bytes
gemrb/unhardcoded/iwd2/feat09.spl | Bin 0 -> 218 bytes
gemrb/unhardcoded/iwd2/feat0a.spl | Bin 0 -> 266 bytes
gemrb/unhardcoded/iwd2/feat0c.spl | Bin 0 -> 218 bytes
gemrb/unhardcoded/iwd2/feat0d.spl | Bin 0 -> 218 bytes
gemrb/unhardcoded/iwd2/feat0f.spl | Bin 0 -> 266 bytes
gemrb/unhardcoded/iwd2/feat10.spl | Bin 0 -> 218 bytes
gemrb/unhardcoded/iwd2/feat18.spl | Bin 0 -> 746 bytes
gemrb/unhardcoded/iwd2/feat19.spl | Bin 0 -> 218 bytes
gemrb/unhardcoded/iwd2/feat1a.spl | Bin 0 -> 218 bytes
gemrb/unhardcoded/iwd2/feat1c.spl | Bin 0 -> 266 bytes
gemrb/unhardcoded/iwd2/feat1c1.eff | Bin 0 -> 272 bytes
gemrb/unhardcoded/iwd2/feat1c2.eff | Bin 0 -> 272 bytes
gemrb/unhardcoded/iwd2/feat1d.spl | Bin 0 -> 218 bytes
gemrb/unhardcoded/iwd2/feat1e.spl | Bin 0 -> 218 bytes
gemrb/unhardcoded/iwd2/feat20.spl | Bin 0 -> 266 bytes
gemrb/unhardcoded/iwd2/feat22.spl | Bin 0 -> 218 bytes
gemrb/unhardcoded/iwd2/feat23.spl | Bin 0 -> 218 bytes
gemrb/unhardcoded/iwd2/feat25.spl | Bin 0 -> 410 bytes
gemrb/unhardcoded/iwd2/feat32.spl | Bin 0 -> 218 bytes
gemrb/unhardcoded/iwd2/feat33.spl | Bin 0 -> 266 bytes
gemrb/unhardcoded/iwd2/feat3b.spl | Bin 0 -> 266 bytes
gemrb/unhardcoded/iwd2/feat41.spl | Bin 0 -> 266 bytes
gemrb/unhardcoded/iwd2/featreq.2da | 79 +
gemrb/{override => unhardcoded}/iwd2/ffinger.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/findtrap.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/iwd2/fireball.pro | Bin 0 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/fireblic.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/firebolt.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/firebtbl.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/fireh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd2/fireh.vvc | Bin 0 -> 492 bytes
gemrb/{override => unhardcoded}/iwd2/firestor.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/iwd2/fistweap.2da | 4 +
gemrb/{override => unhardcoded}/iwd2/fodeath.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd2/fonts.2da | 22 +
gemrb/{override => unhardcoded}/iwd2/formatio.2da | 0
gemrb/{override => unhardcoded}/iwd2/fseed.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/fstrikh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/gabreath.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/iwd2/gametime.2da | 6 +
gemrb/{override => unhardcoded}/iwd2/garmorh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/gate.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/gaze.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/geloopx.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/gemprjtl.ids | 0
gemrb/unhardcoded/iwd2/gemrb.ini | 131 +
gemrb/{override => unhardcoded}/iwd2/gender.2da | 0
gemrb/{override => unhardcoded}/iwd2/golcloud.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/grease.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/gshout.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/iwd2/guibtact.2da | 93 +
gemrb/{override => unhardcoded}/iwd2/guils.chu | Bin 284 -> 284 bytes
gemrb/unhardcoded/iwd2/hamstr.spl | Bin 0 -> 218 bytes
gemrb/{override => unhardcoded}/iwd2/harmh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/harmony.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/haterace.2da | 0
gemrb/{override => unhardcoded}/iwd2/healh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/hmighth.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/hold.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/hsmite.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/hword.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/icelance.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/icestorm.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/icloud.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/iclouda.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/icloudb.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/illush.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/illust.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/inarea.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/inareanp.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/iwd2/inareapa.pro | Bin 0 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/inareasm.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/invoch.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/invoct.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/iplague.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/island00.2da | 0
gemrb/unhardcoded/iwd2/itemdata.2da | 30 +
gemrb/unhardcoded/iwd2/itemsnd.2da | 81 +
gemrb/unhardcoded/iwd2/itemspec.2da | 4 +
gemrb/unhardcoded/iwd2/itemtype.2da | 77 +
gemrb/{override => unhardcoded}/iwd2/itemuse.2da | 0
gemrb/{override => unhardcoded}/iwd2/iwdshtab.2da | 0
gemrb/{override => unhardcoded}/iwd2/lightb.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd2/lightbnb.pro | Bin 0 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/lightsto.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/lodisr.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/iwd2/magesch.2da | 12 +
gemrb/{override => unhardcoded}/iwd2/magicmis.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/malison.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/iwd2/mdfeats.2da | 11 +
gemrb/{override => unhardcoded}/iwd2/mfmiss.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/mfmiss2.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/mfmissh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/mfog.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/mmagich.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/mmissile.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/modal.2da | 0
gemrb/{override => unhardcoded}/iwd2/moelda.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/mrage.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/mrageh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/mspore.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/msumm1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/msumm1h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/msumm1x.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/msumm2h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/msumm3h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/msumm4h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/msumm5h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/msumm6h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/msumm7h.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/mswordh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/mtouchh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/necroh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/necrot.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/npoisoh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/ofsphe.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/overlay.2da | 0
gemrb/{override => unhardcoded}/iwd2/paralh.pro | Bin 512 -> 512 bytes
.../how => unhardcoded/iwd2}/pathfind.2da | 0
gemrb/{override => unhardcoded}/iwd2/pfire.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/pictures.2da | 0
gemrb/{override => unhardcoded}/iwd2/poisonh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/polystat.2da | 0
gemrb/{override => unhardcoded}/iwd2/portal.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/prayer.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/prayerh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd2/proftype.2da | 73 +
gemrb/{override => unhardcoded}/iwd2/protevil.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/prtl_cl.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/prtl_op.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/pspray.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/pwkill.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/pwsileh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/pwstun.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/pwstunh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd2/raceflag.2da | 10 +
gemrb/unhardcoded/iwd2/races.2da | 19 +
gemrb/{override => unhardcoded}/iwd2/rad100.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/rad250.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/rad300.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/randitem.2da | 0
gemrb/{override => unhardcoded}/iwd2/rdeadh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/recitah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/resurrh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/rng450.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/rparalh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/rwotfag.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/rwotfah.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/sarmorh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/savegame.2da | 0
gemrb/{override => unhardcoded}/iwd2/scharge.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/schargh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/script.2da | 0
gemrb/{override => unhardcoded}/iwd2/seater.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/seaterh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/sgrowth.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/shout.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/shroud.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/shtable.2da | 0
gemrb/{override => unhardcoded}/iwd2/skillsta.2da | 0
gemrb/{override => unhardcoded}/iwd2/sleep.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/slivinh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd2/slottype.2da | 54 +
gemrb/{override => unhardcoded}/iwd2/soflamh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/sohope.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/sooneh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/sopain.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/sparbknp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/sparbkpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/sparblnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/sparblpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/sparchnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/sparchpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/spargonp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/spargopa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/spargrnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/spargrpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/sparicnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/sparicpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/sparklbk.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/sparklbl.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/sparklch.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/sparklgo.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/sparklgr.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/sparklic.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/sparklma.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/sparklor.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/sparklpu.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/sparklre.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/sparklst.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/sparmanp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/sparmapa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/sparornp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/sparorpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/sparpunp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/sparpupa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/sparrenp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/sparrepa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/sparstnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/sparstpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/spbrnhnd.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/spear.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/spearex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/spfdeath.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/spfirebl.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd2/spin231r.spl | Bin 0 -> 362 bytes
gemrb/unhardcoded/iwd2/spin232r.spl | Bin 0 -> 266 bytes
gemrb/unhardcoded/iwd2/spin233r.spl | Bin 0 -> 266 bytes
gemrb/{override => unhardcoded}/iwd2/spklarbk.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/spklarbl.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/spklarch.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/spklargo.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/spklargr.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/spklaric.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/spklarma.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/spklaror.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/spklarpu.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/spklarre.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/spklarst.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/iwd2/splfocus.2da | 12 +
gemrb/unhardcoded/iwd2/splprot.2da | 105 +
gemrb/{override => unhardcoded}/iwd2/splspec.2da | 0
gemrb/{override => unhardcoded}/iwd2/spoisoh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/spscorch.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/spscoric.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/spwrath.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/ssorbh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/ssswarm.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/sstone.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/sstoneh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/start.2da | 0
gemrb/{override => unhardcoded}/iwd2/stone.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/strengh.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/iwd2/strings.2da | 187 +
gemrb/{override => unhardcoded}/iwd2/suffoc.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/suffoch.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/sunfire.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/sunray.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/sunscoh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/swave.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/swaveh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/topics.2da | 0
gemrb/{override => unhardcoded}/iwd2/trap.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/trapglyp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/trapskul.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/tspray.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/turn.spl | Bin 202 -> 202 bytes
gemrb/{override => unhardcoded}/iwd2/ublight.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/uhold.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/uward.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/uwardh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/vspherh.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/wdeath1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/wdeath2.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/web.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/whirlw.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/wofire.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/womoon.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/womoonx.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/wowisp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/wvdeath.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/wvhith.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/iwd2/wwolf.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/iwd2/zlaura.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/MPALETTE.bmp | Bin 7638 -> 7638 bytes
gemrb/unhardcoded/pst/Makefile.am | 3 +
gemrb/{override => unhardcoded}/pst/abcomm.2da | 0
gemrb/{override => unhardcoded}/pst/acidblgr.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/acidblmu.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/acidblob.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/acidbloc.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/pst/adder.spl | Bin 0 -> 906 bytes
gemrb/{override => unhardcoded}/pst/aligns.2da | 0
gemrb/{override => unhardcoded}/pst/amiss.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/amiss2.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/anims.2da | 0
gemrb/{override => unhardcoded}/pst/aotorm.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/areapro.2da | 0
gemrb/{override => unhardcoded}/pst/arrow.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/arrowex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/arrowflb.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/arrowflg.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/arrowfli.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/arrowflm.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/arrowhvy.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/astorm.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/astorm.spl | Bin 298 -> 298 bytes
gemrb/{override => unhardcoded}/pst/avatars.2da | 0
gemrb/{override => unhardcoded}/pst/avprefix.2da | 0
gemrb/{override => unhardcoded}/pst/avslots.2da | 0
gemrb/{override => unhardcoded}/pst/axe.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/axeex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/axoft.spl | Bin 770 -> 770 bytes
gemrb/unhardcoded/pst/ball.spl | Bin 0 -> 202 bytes
gemrb/{override => unhardcoded}/pst/bbridge.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/bbridge.spl | Bin 202 -> 202 bytes
gemrb/{override => unhardcoded}/pst/bios.2da | 0
gemrb/{override => unhardcoded}/pst/blessed.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/pst/blight.pro | Bin 0 -> 512 bytes
gemrb/unhardcoded/pst/blight2.pro | Bin 0 -> 512 bytes
gemrb/{override => unhardcoded}/pst/bluetint.spl | Bin 202 -> 202 bytes
gemrb/{override => unhardcoded}/pst/bolt.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/boltex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/bstorm.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/bstorm.spl | Bin 1066 -> 1066 bytes
gemrb/{override => unhardcoded}/pst/bstorm2.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/bstorm2.spl | Bin 586 -> 586 bytes
gemrb/{override => unhardcoded}/pst/bullet.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/bulletex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/callih.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/chost.2da | 0
gemrb/unhardcoded/pst/chost.pro | Bin 0 -> 768 bytes
gemrb/{override => unhardcoded}/pst/chost.spl | Bin 298 -> 298 bytes
gemrb/{override => unhardcoded}/pst/chromorb.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/classes.2da | 0
gemrb/{override => unhardcoded}/pst/cloud.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/pst/cloudkil.pro | Bin 0 -> 768 bytes
gemrb/unhardcoded/pst/clskills.2da | 13 +
gemrb/{override => unhardcoded}/pst/clssplab.2da | 0
gemrb/{override => unhardcoded}/pst/cocold.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/colrspry.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/pst/comment.2da | 12 +
gemrb/{override => unhardcoded}/pst/conflag.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/conflag.spl | Bin 250 -> 250 bytes
gemrb/{override => unhardcoded}/pst/confus.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/pst/crits.2da | 13 +
gemrb/{override => unhardcoded}/pst/cursed.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/dagger.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/daggerex.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/pst/damage.2da | 16 +
gemrb/{override => unhardcoded}/pst/dart.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/dartex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/dbolt.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/dbolt.spl | Bin 202 -> 202 bytes
gemrb/unhardcoded/pst/defsound.2da | 36 +
gemrb/{override => unhardcoded}/pst/dhell.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/dhell.spl | Bin 490 -> 490 bytes
gemrb/unhardcoded/pst/dstable.2da | 3 +
gemrb/{override => unhardcoded}/pst/easymaze.2da | 0
gemrb/{override => unhardcoded}/pst/ebomb.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/effects.ids | 0
gemrb/{override => unhardcoded}/pst/elyfire.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/elytear.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/embalm.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/estrike.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/factions.2da | 0
gemrb/{override => unhardcoded}/pst/faerie.spl | Bin 250 -> 250 bytes
gemrb/{override => unhardcoded}/pst/fbomb.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/fbyello.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/fearaura.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/ffire.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/fireball.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/firebolt.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/firebtbl.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/fireice.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/fireice.spl | Bin 250 -> 250 bytes
gemrb/{override => unhardcoded}/pst/firestor.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/fistweap.2da | 0
gemrb/{override => unhardcoded}/pst/fizzle.spl | Bin 250 -> 250 bytes
gemrb/{override => unhardcoded}/pst/fmiss.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/pst/fonts.2da | 14 +
gemrb/{override => unhardcoded}/pst/formatio.2da | 0
gemrb/unhardcoded/pst/foundry.2da | 4 +
gemrb/{override => unhardcoded}/pst/frain.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/pst/gametime.2da | 6 +
gemrb/{override => unhardcoded}/pst/gaze.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/pst/gemprjtl.ids | 292 +
gemrb/unhardcoded/pst/gemrb.ini | 126 +
gemrb/{override => unhardcoded}/pst/genders.2da | 0
gemrb/{override => unhardcoded}/pst/goinvul.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/goinvul.spl | Bin 346 -> 346 bytes
gemrb/{override => unhardcoded}/pst/grease.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/guibtact.2da | 0
gemrb/{override => unhardcoded}/pst/guiid.chu | Bin 92 -> 92 bytes
gemrb/{override => unhardcoded}/pst/guils.chu | Bin 146 -> 146 bytes
gemrb/{override => unhardcoded}/pst/guiw08.chu | Bin 5148 -> 5148 bytes
.../{override/bg2 => unhardcoded/pst}/hlymite.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/hold.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/holdund.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/holdund.spl | Bin 818 -> 818 bytes
gemrb/unhardcoded/pst/hopand.pro | Bin 0 -> 768 bytes
gemrb/unhardcoded/pst/hopand2.pro | Bin 0 -> 512 bytes
gemrb/{override => unhardcoded}/pst/horror.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/pst/howl.spl | Bin 0 -> 298 bytes
gemrb/{override => unhardcoded}/pst/ice.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/ice.spl | Bin 250 -> 250 bytes
gemrb/{override => unhardcoded}/pst/icestorm.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/ifury.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/ifury.spl | Bin 994 -> 994 bytes
gemrb/{override => unhardcoded}/pst/ignusorb.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/ignusorb.vvc | Bin 492 -> 492 bytes
gemrb/{override => unhardcoded}/pst/iknife.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/imiss.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/imiss2.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/impstr.spl | Bin 346 -> 346 bytes
gemrb/{override => unhardcoded}/pst/inarea.pro | Bin 768 -> 768 bytes
.../{override/how => unhardcoded/pst}/inareanp.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/pst/inareapa.pro | Bin 0 -> 768 bytes
.../{override/bg1 => unhardcoded/pst}/inareasm.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/istorm.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/istorm.spl | Bin 250 -> 250 bytes
gemrb/{override => unhardcoded}/pst/istr.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/iswarm.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/iswarm.spl | Bin 466 -> 466 bytes
gemrb/{override => unhardcoded}/pst/item_use.2da | 0
gemrb/{override => unhardcoded}/pst/itemsnd.2da | 0
gemrb/{override => unhardcoded}/pst/itemtype.2da | 0
gemrb/{override => unhardcoded}/pst/itemuse.2da | 0
gemrb/{override => unhardcoded}/pst/iterror.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/kiss.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/kitlist.2da | 0
gemrb/{override => unhardcoded}/pst/knock.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/lightb.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/lightnin.spl | Bin 202 -> 202 bytes
gemrb/{override => unhardcoded}/pst/lightsto.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/litany.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/litany.spl | Bin 202 -> 202 bytes
gemrb/{override => unhardcoded}/pst/lmiss.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/lstorm.2da | 0
gemrb/{override => unhardcoded}/pst/lstorm.pro | Bin 768 -> 768 bytes
.../pst/fizzle.spl => unhardcoded/pst/lstorm.spl} | Bin 250 -> 250 bytes
gemrb/{override => unhardcoded}/pst/lstorm2.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/lstorm2.spl | Bin 250 -> 250 bytes
gemrb/{override => unhardcoded}/pst/magicmis.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/mcannon.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/mcannon.spl | Bin 394 -> 394 bytes
gemrb/{override => unhardcoded}/pst/mmiss.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/mmiss2.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/modal.2da | 0
gemrb/{override => unhardcoded}/pst/mpal256.bmp | Bin 92214 -> 92214 bytes
gemrb/{override => unhardcoded}/pst/mswarm.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/mswarm.spl | Bin 250 -> 250 bytes
gemrb/{override => unhardcoded}/pst/music.2da | 0
gemrb/{override => unhardcoded}/pst/nbolt.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/orb.spl | Bin 546 -> 546 bytes
gemrb/{override => unhardcoded}/pst/orngtint.spl | Bin 202 -> 202 bytes
gemrb/unhardcoded/pst/overlay.2da | 35 +
gemrb/{override => unhardcoded}/pst/pacify.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/pacify.spl | Bin 298 -> 298 bytes
.../iwd2 => unhardcoded/pst}/pathfind.2da | 0
gemrb/{override => unhardcoded}/pst/pdolls.2da | 0
gemrb/{override => unhardcoded}/pst/poo.spl | Bin 250 -> 250 bytes
gemrb/{override => unhardcoded}/pst/poone.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/pst/proftype.2da | 45 +
gemrb/{override => unhardcoded}/pst/pwb.spl | Bin 298 -> 298 bytes
gemrb/{override => unhardcoded}/pst/pwblind.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/pwk.spl | Bin 298 -> 298 bytes
gemrb/{override => unhardcoded}/pst/pwkill.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/races.2da | 0
gemrb/{override => unhardcoded}/pst/randitem.2da | 0
gemrb/{override => unhardcoded}/pst/rdead.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/rdead.spl | Bin 250 -> 250 bytes
gemrb/{override => unhardcoded}/pst/rock.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/rotorm.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/rune.2da | 0
gemrb/{override => unhardcoded}/pst/rune.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/rune.spl | Bin 346 -> 346 bytes
gemrb/{override => unhardcoded}/pst/s015hwav.vvc | Bin 492 -> 492 bytes
gemrb/{override => unhardcoded}/pst/s025melt.vvc | Bin 492 -> 492 bytes
gemrb/{override => unhardcoded}/pst/s046ist2.vvc | Bin 492 -> 492 bytes
gemrb/{override => unhardcoded}/pst/s046istm.vvc | Bin 492 -> 492 bytes
gemrb/{override => unhardcoded}/pst/s052cone.vvc | Bin 492 -> 492 bytes
gemrb/{override => unhardcoded}/pst/s056itrl.vvc | Bin 492 -> 492 bytes
gemrb/{override => unhardcoded}/pst/s061beam.vvc | Bin 492 -> 492 bytes
gemrb/unhardcoded/pst/s061glwb.vvc | Bin 0 -> 492 bytes
gemrb/unhardcoded/pst/s061shll.vvc | Bin 0 -> 492 bytes
gemrb/{override => unhardcoded}/pst/s064bglt.vvc | Bin 492 -> 492 bytes
gemrb/{override => unhardcoded}/pst/s064hglt.vvc | Bin 492 -> 492 bytes
gemrb/{override => unhardcoded}/pst/s064lort.vvc | Bin 492 -> 492 bytes
gemrb/{override => unhardcoded}/pst/s064uplt.vvc | Bin 492 -> 492 bytes
gemrb/{override => unhardcoded}/pst/s070boom.vvc | Bin 492 -> 492 bytes
gemrb/{override => unhardcoded}/pst/s075wdsh.vvc | Bin 492 -> 492 bytes
gemrb/{override => unhardcoded}/pst/s914bgbl.vvc | Bin 492 -> 492 bytes
gemrb/{override => unhardcoded}/pst/s914hgbl.vvc | Bin 492 -> 492 bytes
gemrb/{override => unhardcoded}/pst/s914rune.vvc | Bin 492 -> 492 bytes
gemrb/{override => unhardcoded}/pst/savegame.2da | 0
gemrb/{override => unhardcoded}/pst/script.2da | 0
gemrb/{override => unhardcoded}/pst/shammer.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/shammer.spl | Bin 810 -> 810 bytes
gemrb/unhardcoded/pst/sigil.2da | 20 +
gemrb/{override => unhardcoded}/pst/skmob.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/skmob.spl | Bin 250 -> 250 bytes
gemrb/{override => unhardcoded}/pst/skmob2.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/sleep.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/slots.ids | 0
gemrb/{override => unhardcoded}/pst/slottype.2da | 0
gemrb/unhardcoded/pst/source/baldur.baf | 157 +
gemrb/{override => unhardcoded}/pst/sparbknp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/sparbkpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/sparblnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/sparblpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/sparchnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/sparchpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/spargonp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/spargopa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/spargrnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/spargrpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/sparicnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/sparicpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/sparklbk.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/sparklbl.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/sparklch.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/sparklgo.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/sparklgr.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/sparklic.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/sparklma.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/sparklor.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/sparklpu.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/sparklre.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/sparklst.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/sparmanp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/sparmapa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/sparornp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/sparorpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/sparpunp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/sparpupa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/sparrenp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/sparrepa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/sparstnp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/sparstpa.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/speak.eff | Bin 272 -> 272 bytes
gemrb/{override => unhardcoded}/pst/spear.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/spearex.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/spfirebl.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/spklarbk.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/spklarbl.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/spklarch.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/spklargo.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/spklargr.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/spklaric.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/spklarma.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/spklaror.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/spklarpu.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/spklarre.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/spklarst.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/splspec.2da | 0
gemrb/{override => unhardcoded}/pst/spscorch.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/spscoric.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/pst/sshadow.pro | Bin 0 -> 512 bytes
gemrb/unhardcoded/pst/sshadow.spl | Bin 0 -> 346 bytes
gemrb/{override/bg1 => unhardcoded/pst}/start.2da | 0
gemrb/{override => unhardcoded}/pst/states.2da | 0
gemrb/{override => unhardcoded}/pst/stone.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/stories.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/stories.spl | Bin 250 -> 250 bytes
gemrb/{override => unhardcoded}/pst/str.spl | Bin 250 -> 250 bytes
gemrb/{override => unhardcoded}/pst/strength.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/pst/strings.2da | 187 +
gemrb/{override => unhardcoded}/pst/tlaugh.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/trapglyp.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/trapskul.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/vtouch.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/pst/weapprof.2da | 0
gemrb/{override => unhardcoded}/pst/web.pro | Bin 768 -> 768 bytes
gemrb/{override => unhardcoded}/pst/wmmos2b.mos | Bin 36218 -> 36218 bytes
gemrb/unhardcoded/shared/Makefile.am | 3 +
gemrb/{override => unhardcoded}/shared/avprefg.2da | 0
.../{override => unhardcoded}/shared/avprefix.2da | 0
gemrb/{override => unhardcoded}/shared/axeflm.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/shared/bardsong.spl | Bin 0 -> 346 bytes
gemrb/unhardcoded/shared/chinese.ini | 3 +
gemrb/unhardcoded/shared/comment.2da | 8 +
.../{override => unhardcoded}/shared/containr.2da | 0
gemrb/{override => unhardcoded}/shared/cow.pro | Bin 768 -> 768 bytes
gemrb/unhardcoded/shared/czech.ini | 39 +
gemrb/unhardcoded/shared/default.ini | 39 +
gemrb/unhardcoded/shared/defaults.ini | 61 +
gemrb/unhardcoded/shared/demoend.chu | Bin 0 -> 88 bytes
gemrb/{override => unhardcoded}/shared/detect.spl | Bin 202 -> 202 bytes
gemrb/unhardcoded/shared/difflvls.2da | 5 +
gemrb/unhardcoded/shared/dmgtypes.2da | 22 +
gemrb/{override => unhardcoded}/shared/dummy.spl | Bin 202 -> 202 bytes
gemrb/unhardcoded/shared/fatigue.2da | 5 +
.../{override => unhardcoded}/shared/findtrap.spl | Bin 202 -> 202 bytes
gemrb/{override => unhardcoded}/shared/flmstrk.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/shared/gemact.ids | 13 +
gemrb/unhardcoded/shared/gemtrig.ids | 2 +
gemrb/{override => unhardcoded}/shared/invtrav.pro | Bin 512 -> 512 bytes
.../{override => unhardcoded}/shared/itemspec.2da | 0
gemrb/unhardcoded/shared/japanese.ini | 2 +
gemrb/unhardcoded/shared/keymap.2da | 71 +
gemrb/unhardcoded/shared/korean.ini | 2 +
gemrb/{override => unhardcoded}/shared/modal.2da | 0
gemrb/{override => unhardcoded}/shared/panic.spl | Bin 346 -> 346 bytes
.../{override => unhardcoded}/shared/polystat.2da | 0
gemrb/{override => unhardcoded}/shared/redholy.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/shared/sanctuc.vvc | Bin 492 -> 492 bytes
gemrb/{override => unhardcoded}/shared/shair.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/shared/shair1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/shared/shair2.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/shared/shair3.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/shared/shair4.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/shared/shair5.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/shared/shair6.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/shared/shair7.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/shared/sharea.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/shared/sharea1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/shared/sharea2.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/shared/sharea3.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/shared/sharea4.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/shared/sharea5.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/shared/sharea6.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/shared/shearth.pro | Bin 512 -> 512 bytes
.../{override => unhardcoded}/shared/shearth1.pro | Bin 512 -> 512 bytes
.../{override => unhardcoded}/shared/shearth2.pro | Bin 512 -> 512 bytes
.../{override => unhardcoded}/shared/shearth3.pro | Bin 512 -> 512 bytes
.../{override => unhardcoded}/shared/shearth4.pro | Bin 512 -> 512 bytes
.../{override => unhardcoded}/shared/shearth5.pro | Bin 512 -> 512 bytes
.../{override => unhardcoded}/shared/shearth6.pro | Bin 512 -> 512 bytes
.../{override => unhardcoded}/shared/shearth7.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/shared/shwater.pro | Bin 512 -> 512 bytes
.../{override => unhardcoded}/shared/shwater1.pro | Bin 512 -> 512 bytes
.../{override => unhardcoded}/shared/shwater2.pro | Bin 512 -> 512 bytes
.../{override => unhardcoded}/shared/shwater3.pro | Bin 512 -> 512 bytes
.../{override => unhardcoded}/shared/shwater4.pro | Bin 512 -> 512 bytes
.../{override => unhardcoded}/shared/shwater5.pro | Bin 512 -> 512 bytes
.../{override => unhardcoded}/shared/shwater6.pro | Bin 512 -> 512 bytes
.../{override => unhardcoded}/shared/shwater7.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/shared/skybolt.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/shared/sneak.spl | Bin 202 -> 202 bytes
.../{override => unhardcoded}/shared/souleatr.2da | 0
gemrb/{override => unhardcoded}/shared/spboom1.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/shared/spboom2.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/shared/spboom3.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/shared/spdimdr.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/shared/spldisp.2da | 18 +
.../{override => unhardcoded}/shared/spmagmis.pro | Bin 512 -> 512 bytes
.../{override => unhardcoded}/shared/spsmkjet.pro | Bin 512 -> 512 bytes
gemrb/{override => unhardcoded}/shared/spsmold.pro | Bin 512 -> 512 bytes
.../{override => unhardcoded}/shared/spsmpuff.pro | Bin 512 -> 512 bytes
gemrb/unhardcoded/shared/storespl.2da | 13 +
gemrb/{override => unhardcoded}/shared/turn.spl | Bin 202 -> 202 bytes
testing/python.supp | 106 +
2811 files changed, 76447 insertions(+), 44634 deletions(-)
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..ccaa9f3
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,5 @@
+*.bcs diff=ie
+*.chu diff=ie
+*.pro diff=ie
+*.spl diff=ie
+*.vvc diff=ie
diff --git a/.gitignore b/.gitignore
index c158f0b..b6c4b52 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,15 @@ Makefile.in
.libs
.dirstamp
+# Mac/Xcode junk
+DerivedData
+Payload
+apple/build
+apple/ios/lib
+.DS_Store
+xcuserdata
+*.pbxuser
+
/aclocal.m4
/admin/config.guess
/admin/config.sub
diff --git a/.mailmap b/.mailmap
index 3736258..6255064 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1,2 +1,7 @@
Jaka Kranjc <lynxlupodian at users.sourceforge.net> <lynxlynxlynx at sourcemage.org>
Edheldil <edheldil at users.sourceforge.net> Jarda Benkovsky <benkovsk at totoro.(none)>
+Avenger <avenger_teambg at users.sourceforge.net> unknown <Laci at .(none)>
+Thomas Gull <tgull1 at dmail.dixie.edu> Tommy Gunn <olathuss at users.sourceforge.net>
+Brad Allred <bradallred at me.com> Brad <brad at new-mbp.local>
+<avenger_teambg at users.sourceforge.net> <avenger_teambg at sourceforge.net>
+Laurie Chilvers <chilvence at gmail.com> chiv <chilvence at gmail.com>
diff --git a/AUTHORS b/AUTHORS
index 28a7ad9..d7111d3 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -3,6 +3,7 @@ GemRB authors listed in Alphabetical Order
Alyssa Milburn <fuzzie at users.sourceforge.net>
Avenger <avenger_teambg at users.sourceforge.net>
Balrog994 <Balrog994 at yahoo.com>
+Brad Allred <brad-a at users.sourceforge.net>
Brian Tanedo <behteh at users.sourceforge.net>
Dark-Star <doc_wagon at users.sourceforge.net>
Divide <divide at users.sourceforge.net>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a52c538..c45a3bc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,20 +1,19 @@
-cmake_minimum_required(VERSION 2.4.4)
+cmake_minimum_required(VERSION 2.6.0)
if(COMMAND cmake_policy)
cmake_policy(SET CMP0003 NEW)
cmake_policy(SET CMP0005 NEW)
endif(COMMAND cmake_policy)
-# allow empty else and endif constructs (available by default since 2.6.0)
-set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
# prevent in-source builds
-IF(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
+IF(NOT INSOURCEBUILD AND (${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}))
MESSAGE(FATAL_ERROR "
CMake generation for this project is not allowed within the source directory!
- Remove the CMakeCache.txt file and try again from another folder, e.g.:
- rm CMakeCache.txt
+ Remove the CMake cache files and try again from another folder, e.g.:
+ rm -r CMakeCache.txt CMakeFiles/
mkdir build
cd build
- cmake .."
+ cmake ..
+ If you really want an in-source build, pass -DINSOURCEBUILD=1"
)
ENDIF()
@@ -48,7 +47,11 @@ ENDIF(PREFIX)
if (NOT LAYOUT)
if (WIN32)
set(LAYOUT "home")
- else (WIN32)
+ elseif (APPLE)
+ set(LAYOUT "bundle")
+ # favor mac frameworks over unix libraries
+ set(CMAKE_FIND_FRAMEWORK FIRST)
+ else (APPLE)
set(LAYOUT "fhs")
endif (WIN32)
endif (NOT LAYOUT)
@@ -73,6 +76,7 @@ if (${LAYOUT} MATCHES "home")
SET_PATH( ICON_DIR ${CMAKE_INSTALL_PREFIX} )
SET_PATH( SVG_DIR ${CMAKE_INSTALL_PREFIX} )
SET_PATH( MENU_DIR ${CMAKE_INSTALL_PREFIX} )
+ SET_PATH( EXAMPLE_CONF_DIR ${CMAKE_INSTALL_PREFIX} )
elseif (${LAYOUT} MATCHES "fhs")
SET_PATH( LIB_DIR ${CMAKE_INSTALL_PREFIX}/lib/gemrb )
SET_PATH( PLUGIN_DIR ${LIB_DIR}/plugins )
@@ -90,7 +94,8 @@ elseif (${LAYOUT} MATCHES "fhs")
SET_PATH( ICON_DIR ${CMAKE_INSTALL_PREFIX}/share/pixmaps )
SET_PATH( SVG_DIR ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps )
SET_PATH( MENU_DIR ${CMAKE_INSTALL_PREFIX}/share/applications )
-else (${LAYOUT} MATCHES "opt")
+ SET_PATH( EXAMPLE_CONF_DIR ${SYSCONF_DIR} )
+elseif (${LAYOUT} MATCHES "opt")
SET_PATH( LIB_DIR ${CMAKE_INSTALL_PREFIX}/lib )
SET_PATH( PLUGIN_DIR ${LIB_DIR}/plugins )
SET_PATH( DATA_DIR ${CMAKE_INSTALL_PREFIX}/share/ )
@@ -101,6 +106,14 @@ else (${LAYOUT} MATCHES "opt")
SET_PATH( ICON_DIR ${CMAKE_INSTALL_PREFIX}/share/pixmaps )
SET_PATH( SVG_DIR ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps )
SET_PATH( MENU_DIR ${CMAKE_INSTALL_PREFIX}/share/applications )
+ SET_PATH( EXAMPLE_CONF_DIR ${SYSCONF_DIR} )
+else (${LAYOUT} MATCHES "bundle") # Mac or iOS
+ # most paths are irrelevant since the items will be bundled with application
+ SET_PATH( BIN_DIR /Applications )
+ # TODO: these should be copied during build and not install.
+ SET_PATH( LIB_DIR "${BIN_DIR}/${PROJECT_NAME}.app/Contents/Frameworks" )
+ SET_PATH( PLUGIN_DIR "${BIN_DIR}/${PROJECT_NAME}.app/Contents/Plugins" )
+ SET_PATH( DOC_DIR "${BIN_DIR}/${PROJECT_NAME}.app/Contents/Resources" )
endif (${LAYOUT} MATCHES "home")
# check if this is a release version
@@ -116,18 +129,18 @@ else()
set (GIT_VERSION 1)
endif()
-IF(CMAKE_COMPILER_IS_GNUCXX)
+IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
if ((NOT DISABLE_WERROR) AND GIT_VERSION)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wno-error=cast-align")
endif ()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -W -Wpointer-arith -Wcast-align")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic -Wno-format-y2k -Wno-long-long -fno-strict-aliasing")
# only export symbols explicitly marked to be exported.
INCLUDE(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-fvisibility=hidden" VISIBILITY_HIDDEN)
- IF (VISIBILITY_HIDDEN)
+ IF (VISIBILITY_HIDDEN AND NOT WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
- ENDIF (VISIBILITY_HIDDEN)
+ ENDIF ()
if (WIN32)
# GCC 4.5.0+ has shared libstdc++ without dllimport
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--enable-auto-import")
@@ -137,10 +150,16 @@ IF(CMAKE_COMPILER_IS_GNUCXX)
if (NOT APPLE AND NOT UNSAFE_PLUGIN)
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--no-undefined")
endif (NOT APPLE AND NOT UNSAFE_PLUGIN)
-ENDIF(CMAKE_COMPILER_IS_GNUCXX)
+ENDIF()
+
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/")
# Check for all the required and optional dependencies
-INCLUDE(FindPythonLibs)
+IF((CMAKE_MAJOR_VERSION GREATER 1) AND (CMAKE_MINOR_VERSION GREATER 7))
+ FIND_PACKAGE(PythonLibs 2.3 REQUIRED)
+ELSE((CMAKE_MAJOR_VERSION GREATER 1) AND (CMAKE_MINOR_VERSION GREATER 7))
+ INCLUDE(FindPythonLibs)
+ENDIF((CMAKE_MAJOR_VERSION GREATER 1) AND (CMAKE_MINOR_VERSION GREATER 7))
IF(PYTHONLIBS_FOUND)
MESSAGE(STATUS "Looking for Python libraries and headers: found")
ELSE()
@@ -186,6 +205,28 @@ ELSE()
MESSAGE(WARNING "If you want to build the SDL_mixer plugin, install SDL_mixer first.")
ENDIF()
+INCLUDE(FindLIBVLC)
+IF(LIBVLC_FOUND)
+ MESSAGE(STATUS "Looking for VLC: found")
+ELSE()
+ MESSAGE(WARNING "Looking for VLC: not found!")
+ MESSAGE(WARNING "If you want to build the VLC plugin, install VLC first.")
+ENDIF()
+
+INCLUDE(FindFreetype)
+IF(FREETYPE_FOUND)
+ MESSAGE(STATUS "Looking for Freetype: found")
+ INCLUDE(FindICONV)
+ IF(NOT ICONV_FOUND)
+ MESSAGE(WARNING "Iconv not found. TTF plugin will not be able to translate non-unicode compatible TLK encodings.")
+ ELSE()
+ set(HAVE_ICONV)
+ ENDIF()
+ELSE()
+ MESSAGE(WARNING "Looking for Freetype: not found!")
+ MESSAGE(WARNING "If you want to build the TTF plugin, install Freetype first.")
+ENDIF()
+
INCLUDE(FindPNG)
IF(PNG_FOUND)
MESSAGE(STATUS "Looking for libPNG: found")
@@ -213,17 +254,18 @@ ADD_DEFINITIONS("-DHAVE_CONFIG_H")
# On Release builds cmake automatically defines NDEBUG, so we
# explicitly undefine it:
-if(CMAKE_BUILD_TYPE STREQUAL "Release" AND NOT MSVC)
+# This matches stripped (Release) and nonstripped (RelWithDebInfo) builds
+if(CMAKE_BUILD_TYPE MATCHES "Rel.*" AND NOT MSVC)
ADD_DEFINITIONS("-UNDEBUG")
endif()
if (STATIC_LINK)
if (NOT WIN32)
ADD_DEFINITIONS("-DSTATIC_LINK")
- else (NOT WIN32 AND NOT APPLE)
+ else (NOT WIN32)
unset(STATIC_LINK CACHE)
MESSAGE(STATUS "Static linking not (yet) supported on this platform.")
- endif (NOT WIN32 AND NOT APPLE)
+ endif (NOT WIN32)
endif (STATIC_LINK)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} gemrb/includes gemrb/core)
@@ -234,8 +276,12 @@ CHECK_TYPE_SIZE("int" SIZEOF_INT)
CHECK_TYPE_SIZE("long int" SIZEOF_LONG_INT)
INCLUDE (CheckFunctionExists)
-CHECK_FUNCTION_EXISTS("snprintf" HAVE_SNPRINTF)
CHECK_FUNCTION_EXISTS("strndup" HAVE_STRNDUP)
+CHECK_FUNCTION_EXISTS("strlcpy", HAVE_STRLCPY)
+CHECK_FUNCTION_EXISTS("setenv" HAVE_SETENV)
+
+CHECK_INCLUDE_FILES("unistd.h" HAVE_UNISTD_H)
+CHECK_INCLUDE_FILES("malloc.h" HAVE_MALLOC_H)
#Unneeded on windows
IF(NOT WIN32)
@@ -253,23 +299,60 @@ IF(NOT WIN32)
ENDIF(NOT WIN32)
IF(APPLE)
- FIND_LIBRARY(SDL_MAIN_LIBRARY_PATH SDLmain)
+ # Make sure we can find the 'ibtool' program. we need it to compile xibs
+ find_program(IBTOOL ibtool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin")
+ IF (${IBTOOL} STREQUAL "IBTOOL-NOTFOUND")
+ MESSAGE (FATAL_ERROR "ibtool can not be found and is needed to compile the .xib files. It should have been installed with
+ the Apple developer tools. The default system paths were searched in addition to ${OSX_DEVELOPER_ROOT}/usr/bin")
+ ENDIF ()
+
+ ADD_DEFINITIONS("-x objective-c++")
+ INCLUDE_DIRECTORIES(apple)
FIND_LIBRARY(COCOA_LIBRARY_PATH Cocoa)
+ FIND_LIBRARY(COREFOUNDATION_LIBRARY CoreFoundation)
+ # for objective-c++
+ SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DTARGET_OS_MAC")
+ # for pure objective-c
+ SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -x objective-c -DTARGET_OS_MAC")
ENDIF(APPLE)
-CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/cmake_config.h.in
+IF (MINGW)
+ SET (WIN32_USE_STDIO Yes)
+ENDIF ()
+if (WIN32_USE_STDIO)
+ SET (NOCOLOR Yes)
+ENDIF()
+
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_config.h.in
${CMAKE_CURRENT_BINARY_DIR}/config.h ESCAPE_QUOTES)
#Plugin addition macro
MACRO(ADD_GEMRB_PLUGIN plugin_name)
+ SET (PLUGIN_BUILD_FILES ${ARGN})
+ if (${ARGV1} STREQUAL "COCOA")
+ LIST(REMOVE_ITEM PLUGIN_BUILD_FILES "COCOA")
+ #this is an Apple thing
+ if (APPLE)
+ SET_SOURCE_FILES_PROPERTIES(
+ CocoaWrapper.m
+ PROPERTIES LANGUAGE C
+ )
+ message(STATUS "Will link ${plugin_name} plugin to: ${BUNDLE_LOADER}")
+ SET (PLUGIN_BUILD_FILES ${PLUGIN_BUILD_FILES} CocoaWrapper.m)
+ endif (APPLE)
+ endif (${ARGV1} STREQUAL "COCOA")
+
if (STATIC_LINK)
- ADD_LIBRARY(${plugin_name} STATIC ${ARGN})
+ ADD_LIBRARY(${plugin_name} STATIC ${PLUGIN_BUILD_FILES})
set(plugins "${plugins};${plugin_name}" PARENT_SCOPE)
else (STATIC_LINK)
- ADD_LIBRARY(${plugin_name} MODULE ${ARGN})
+ ADD_LIBRARY(${plugin_name} MODULE ${PLUGIN_BUILD_FILES})
if (NOT UNSAFE_PLUGIN)
TARGET_LINK_LIBRARIES(${plugin_name} gemrb_core ${CMAKE_THREAD_LIBS_INIT})
endif (NOT UNSAFE_PLUGIN)
+ if (CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
+ TARGET_LINK_LIBRARIES(${plugin_name} -shared-libgcc)
+ endif (CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
INSTALL(TARGETS ${plugin_name} DESTINATION ${PLUGIN_DIR})
endif (STATIC_LINK)
SET_TARGET_PROPERTIES(${plugin_name} PROPERTIES PREFIX ""
@@ -277,12 +360,6 @@ MACRO(ADD_GEMRB_PLUGIN plugin_name)
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/gemrb/plugins)
ENDMACRO(ADD_GEMRB_PLUGIN)
-#gemrb overrides macro
-MACRO(ADD_GEMRB_OVERRIDE game_name)
- FILE( GLOB FILES_TO_INSTALL *.2da *.bmp *.ini *.chu *.ids *.bcs *.vvc *.mos *.spl *.wav *.pro)
- INSTALL( FILES ${FILES_TO_INSTALL} DESTINATION ${DATA_DIR}/override/${game_name} )
-ENDMACRO(ADD_GEMRB_OVERRIDE )
-
# also put the chosen paths in the man page (Ubuntu)
CONFIGURE_FILE(
"${CMAKE_CURRENT_SOURCE_DIR}/gemrb.6.in"
@@ -291,15 +368,19 @@ CONFIGURE_FILE(
)
ADD_SUBDIRECTORY( gemrb )
-INSTALL( FILES "${CMAKE_CURRENT_BINARY_DIR}/gemrb.6" DESTINATION ${MAN_DIR} )
-INSTALL( FILES artwork/gemrb-logo.png DESTINATION ${ICON_DIR} RENAME gemrb.png )
-INSTALL( FILES artwork/logo04-rb_only.svg DESTINATION ${SVG_DIR} RENAME gemrb.svg )
-INSTALL( FILES gemrb.desktop DESTINATION ${MENU_DIR} )
+IF (NOT APPLE)
+ INSTALL( FILES "${CMAKE_CURRENT_BINARY_DIR}/gemrb.6" DESTINATION ${MAN_DIR} )
+ INSTALL( FILES artwork/gemrb-logo.png DESTINATION ${ICON_DIR} RENAME gemrb.png )
+ INSTALL( FILES artwork/logo04-rb_only.svg DESTINATION ${SVG_DIR} RENAME gemrb.svg )
+ INSTALL( FILES gemrb.desktop DESTINATION ${MENU_DIR} )
+ENDIF()
INSTALL( FILES README INSTALL COPYING NEWS AUTHORS DESTINATION ${DOC_DIR} )
+INSTALL( FILES admin/extend2da.py DESTINATION ${BIN_DIR}
+ PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
CONFIGURE_FILE(
- "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
- "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake"
IMMEDIATE @ONLY
)
@@ -322,6 +403,16 @@ add_custom_target( dist
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
+# pretty-print options macro
+# as of 2.8 cmake does not support anything like EVAL
+MACRO(PRINT_OPTION option)
+if (${option})
+ message(STATUS " ${option}: ${${option}}")
+else()
+ message(STATUS " ${option}: disabled")
+endif()
+ENDMACRO(PRINT_OPTION)
+
message(STATUS "")
message(STATUS "These are the configured paths:")
message(STATUS " PREFIX: ${CMAKE_INSTALL_PREFIX}")
@@ -338,13 +429,11 @@ message(STATUS " MENU_DIR: ${MENU_DIR}")
message(STATUS "")
message(STATUS "Options:")
message(STATUS " LAYOUT: ${LAYOUT}")
-message(STATUS " NOCOLOR: ${NOCOLOR}")
-message(STATUS " TOUCHSCREEN: ${TOUCHSCREEN}")
-if (STATIC_LINK)
- message(STATUS " STATIC_LINK: ${STATIC_LINK}")
-else()
- message(STATUS " STATIC_LINK: disabled")
-endif()
+PRINT_OPTION(NOCOLOR)
+PRINT_OPTION(STATIC_LINK)
+PRINT_OPTION(INSOURCEBUILD)
+PRINT_OPTION(DISABLE_WERROR)
+PRINT_OPTION(WIN32_USE_STDIO)
message(STATUS "")
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
message(STATUS "")
diff --git a/HACKING b/HACKING
new file mode 100644
index 0000000..bb7b3bb
--- /dev/null
+++ b/HACKING
@@ -0,0 +1,16 @@
+Axioms of Style
+
+1. When in doubt, follow the style of the existing function or file.
+1.1. When creating a new file, follow the style of existing files, pe. Game.h/.cpp.
+1.1.1. Do not forget to include the license header.
+2. Code indentation is done with single tabulators.
+3. Try to avoid creating very long lines. There is no set maximum.
+4. Sort includes by type (project, system) and alphabetically.
+
+
+Where to start
+If you don't know what to work on, check out the included TODO file, the FIXMEs
+and TODOs spread throughout the code, the more detailed todo on our wiki at
+http://gemrb.org/wiki/doku.php?id=todo or ask either on the forums or IRC.
+Alternatively, just start playing one of the games and see what annoys you,
+then start fixing it.
diff --git a/INSTALL b/INSTALL
index 2743ebe..0ab8d41 100644
--- a/INSTALL
+++ b/INSTALL
@@ -4,7 +4,9 @@ BUILDING GEMRB WITH CMAKE
Tools you will need to build GemRB:
- cmake
- make
- - g++
+ - g++ or clang (others not tested)
+
+NOTE: g++ 4.3 is known to miscompile gemrb.
Libraries:
- ZLib
@@ -13,6 +15,9 @@ Libraries:
- OpenAL (optional, for sound)
- SDL_mixer (optional, for fast lower-quality sound)
- libpng (optional, for the png importer plugin)
+ - FreeType (optional, for the TTF fonts plugin)
+ - iconv (optional, for the TTF fonts plugin and only needed when using a non unicode compatible TLK)
+ - (lib)VLC 2.0+ (optional, for movies in some mac distributions of the games)
Building GemRB on unix-like systems
-----------------------------------
@@ -38,9 +43,6 @@ If you're on an exotic platform and get a lot of errors trying to build,
also pass -DDISABLE_WERROR=1, so warnings won't impede you. This option is
also suggested if you're making a source package.
-You can also pass -DTOUCHSCREEN=1 on devices that have one. GemRB will disable
-mouse scrolling and use wider visible trigger-area scrolling on borders.
-
Please let us know if you encounter any problems while building.
Building GemRB with mingw
diff --git a/NEWS b/NEWS
index 6b6f31c..7d8e355 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,106 @@
+GemRB v0.8.0 (2013-04-27):
+ New features:
+ - iwd2: Chapter 0+1 completable, full spellbook and ECL support
+ - multibyte font support (chinese, korean, japanese)
+ - favourite weapon/spell tracking, bg1 dreams
+ - most gemrb overrides were moved and are now moddable via game override
+ - initial bundled gemrb demo stubs
+
+ Improved features:
+ - random encounters and spawns (properly difficult)
+ - iwd2 combat, stats, spells, skills, effects and actions
+ - animations, speech, input
+ - looting, worldmap, hotkeys (work everywhere), fatigue
+ - bugfixes
+
+GemRB v0.7.2 (2012-11-20):
+ New features:
+ - configuration changes are now saved to gem-baldur.ini (or equivalent)
+ - GemRB now asks for confirmation when exiting
+ - output can now be shown in the ingame message window (run debug(5))
+ - ToBEx flags for effect damage: bypass mirror image, ignore difficulty
+ - SDL2 software keyboard
+
+ Improved features:
+ - custom dialog.tlk encoding support
+ - fonts, effect icons, initials, chapter text
+ - option windows
+ - actions, triggers, effects, invisibility handling
+ - assorted bugfixes
+
+GemRB V0.7.1 (2012-07-15):
+ New features:
+ - almost all iwd2 feats
+ - encumbrance penalties in movement
+ - configurable xp/damage adjustments per difficulty level
+ - support for logging to file directly
+ - iwd2 armor penalty and critical hit multiplier
+ - beginnings of iwd2 spellbook support
+ - vlc plugin for extra video formats
+
+ Improved features:
+ - (iwd2) effects, actions, combat, action bar, infravision
+ - sdl renderer and an initial sdl2 port
+ - config loading, logging
+ - cocoa wrapper and mac build, cursor handling, touch input
+ - bugfixes
+
+GemRB V0.7.0 (2011-12-30):
+ New features:
+ - one can play through the whole Baldur's Gate saga
+ - custom TTF fonts support
+ - arbitrarily sortable casting list
+ - ios configuration interface, xcode project
+ - more pst spawn ini flags, individual critical hit animations
+
+ Improved features:
+ - resting, comment timing, actions
+ - drop caps, keybindings, sdl 1.3 input
+ - bugfixes, cleanups
+
+GemRB V0.6.6 (2011-10-03):
+ New features:
+ - aura pollution and cleansing, casting interruption
+ - formation rotation
+ - bounty encounters
+ - npclevel.2da support
+ - initial mac bundle support
+ - fatigue
+ - backstab on condition (like in ToBEx)
+
+ Improved features:
+ - effects, triggers, actions
+ - keyboard shortcuts (F1-F12), touchscreen ui, scrolling
+ - hitpoint gain, thieving skill boni
+ - combat, spellcasting, iwd sounds
+ - PST inventory, PST spells
+ - bugfixes
+
+ Applied patches:
+ manpage typo fixes from c-korn #3377098
+ pst spell learning fix from Viktor Novotný
+ touchscreen fix from Beholder
+
+GemRB V0.6.5 (2011-07-24):
+ New features:
+ - quickspell support
+ - keymap.ini handling
+ - yet more unhardcoded PST projectiles
+ - area comments, party npc interactions
+ - ios port and enhanced touchscreen support
+
+ Improved features:
+ - performance
+ - squirrels and other small game don't die instantly
+ - stores and stacking
+ - effects, triggers, actions, dialogs
+ - secret door detection, turning undead
+ - bugfixes and internal cleanups
+
+ Applied patches:
+ ios support patches from Brad Allred
+ android and touchscreen patches from Beholder
+
GemRB V0.6.4 (2011-03-27):
New features:
- PST maze and (un)hardcoded projectiles
diff --git a/README b/README
index 8d3b719..dde0195 100644
--- a/README
+++ b/README
@@ -11,23 +11,24 @@ somewhere on your harddisk, or you can try to use the data from the
Dragonlance Total Conversion project - see the link below.
The original game data has to be installed on a windows
-partition and mounted to your Linux/Unix filesystem, installed on
-windows and then copied to your filesystem, installed with WINE or
-extracted manually from the CDs using the tool `unshield'.
+partition and mounted or copied to your (Linux/Unix) filesystem, installed
+with WINE or extracted manually from the CDs using the tool `unshield'.
What little documentation exists is mostly in gemrb/docs/en/ and
-subdirectories, the gemrb.6 man page and this file.
+subdirectories, the gemrb.6 man page, this file and the website.
Supported platforms
-------------------
Supported (i.e. we got reports about successfully running GemRB) systems:
Linux x86, x86-64, ppc
FreeBSD x86
-MS Windows (98, XP or Vista)
+MS Windows
various Macintosh systems (even pre x86) also should work ...
-some smart phones (Symbian, Android)
+some smart phones (Symbian, Android, other Linux-based, Ios)
some consoles (OpenPandora, Dingoo)
-some exotic OSes (ReactOS, SyllableOS, Haiku)
+some exotic OSes (ReactOS, SyllableOS, Haiku, AmigaOS)
+
+g++ 4.3 is known to miscompile gemrb.
Requirements
------------
@@ -36,7 +37,7 @@ See the INSTALL file.
Contacts
--------
Our homepage:
-http://gemrb.sourceforge.net
+http://gemrb.org
Our project at sourceforge.net:
http://sourceforge.net/projects/gemrb
diff --git a/TODO b/TODO
index f18e8cd..9cb1df8 100644
--- a/TODO
+++ b/TODO
@@ -1,5 +1,4 @@
Scripts:
-1. (DONE?) ToB specific actions/triggers, like pocketplane (so ToB will work)
2. (PARTLY) Properly detect the play mode (sp/mp, normal/extended)
Strings:
@@ -7,31 +6,21 @@ Strings:
2. implement feature: "<GENDER?stref1:strref2>" (or even more ambitious stat specific strref tokens)
Combat:
-1. (PARTLY) fix combat round timings
+1. (DONE?) fix combat round timings
2. implement customisable combat calculation, it should be general enough to
simulate all games, without any hardcoded parts
Items:
-1. (DONE-almost) Break items, count charges
2. (PARTLY) Implement switching weapon abilities
-3. (DONE-almost) Implement item usage (similar to spells)
Effects:
-1. (DONE-almost) Implement common effects
-2. (PARTLY) Implement IWD2 effects
-3. (DONE-almost) Implement TOB effects
-4. (PARTLY) Implement PST effects
-5. (DONE-almost) Implement area/non-living affecting effects
+2. (DONE-mostly) Implement IWD2 effects
+4. (DONE-mostly) Implement PST effects
Area:
1. (PARTLY) Don't load scripts for pile items? (research when a script is unused)
-2. (DONE) Create real streaming ambients (do not preload them, just use them when needed)
-3. (DONE) in pathfinder, calculate with the actor's feet circle size (npc blocking still needed)
4. (DONE-almost) fix overlaid tiles - bug #1623839
-Store:
-1. Store caching (especially bags)
-
Animation:
1. (PARTLY) fix char animation sequences
2. stanceID is still fuzzy. Fix it. (FIXED?)
@@ -51,10 +40,8 @@ Game GUI:
1. (PARTLY) implement class based (but customisable) action button bar. Generally port
the IWD2 system to all engines
2. implement grabbing mouse pointer by a control to fix dragging of PST Float menu window
-3. (PARTLY) Fix drop capitals (initials) Calculate text height/width correctly, display
- it correctly too.
-4. (PARTLY) Fix unwanted screen shake (especially when on bottom of area)
-5. (DONE-almost) Level up code, this should be written mostly in GuiScript!!!
+4. (PARTLY) Fix unwanted screen shake (especially when on bottom of area on actor selection)
+5. (DONE-almost) Level up code, missing for pst wierdness and iwd2
General:
1. The Cache and Variables classes could be rewritten to incorporate the release
@@ -63,14 +50,11 @@ General:
right after loading config files and remain static afterwards. Maybe define
some PATH variable describing all the directories searched for files
3. valgrind reports a big heap of unreleased python objects
-4. Implement at least all the options accessible from the GUI options setup,
- rewrite baldur|torment|icewind.ini
+4. (DONE-mostly) Implement at least all the options accessible from the GUI options setup
Graphics:
1. use scaling in Video::SpriteScaleDown() instead of in Video::GetPreview()
and in BMPImporter
-2. move SDLVideoDriver sprite functions to their own file, rename them to
- SpriteIsPixelTransparent etc.
3. (PARTLY) Add PNG support? (still image done)
4. Fog of war: fully visible squares with one corner neighbour invisible need alpha of the adjacent corner to the invisible square tuned down (uh, i hope it is clear what to do, look for artifacts in the fog of war edge)
@@ -79,7 +63,7 @@ Sound:
them in another thread (openal weirdness?)
2. (PARTLY) sounds get sometimes distorted, might be connected to problem #1
3. (PARTLY) Separate OpenAL interface from ACM loader and MVE player
-5. fix sound settings (currently the volumes get reset on area change, for example)
+5. (FIXED?) fix sound settings (currently the volumes get reset on area change, for example)
6. implement and use as much from EAX (echo, damping, etc) as possible
Release:
diff --git a/admin/announcement.template b/admin/announcement.template
index 4b099a8..10edf81 100644
--- a/admin/announcement.template
+++ b/admin/announcement.template
@@ -1,12 +1,11 @@
******************* FORUM ***************************
GemRB 0.9.0 released!
-The [url=http://gemrb.sf.net]GemRB[/url] team is proud to announce a new (minor) release.
+The [url=http://gemrb.org]GemRB[/url] team is proud to announce a new (minor) release.
(short description of major changes)
-Currently only the sources are available. You can get them [url=http://sourceforge.net/project/showfiles.php?group_id=10122]here[/url].
-http://sourceforge.net/project/showfiles.php?group_id=10122]here[/url].
+Currently only the sources and some packages are available. You can get them from [url=http://gemrb.org/wiki/doku.php?id=download]here[/url].
Full changelog digest:
[code]
@@ -16,7 +15,9 @@ NEWS entry
******************* MODDING RING ********************
For the modding news blurb, just skip the changelog digest and put a link
to the main forum post. Also add a general intro, since this is syndicated:
-[url=http://gemrb.sf.net]GemRB[/url] is a portable open-source implementation of Bioware's Infinity Engine. It was written to support pseudo-3D role playing games based on the Dungeons & Dragons ruleset (Baldur's Gate and Icewind Dale series, Planescape: Torment).
+[url=http://gemrb.org]GemRB[/url] is a portable open-source implementation of Bioware's Infinity Engine. It was written to support pseudo-3D role playing games based on the Dungeons & Dragons ruleset (Baldur's Gate and Icewind Dale series, Planescape: Torment).
+
+For the details, try GemRB yourself or check the [url=]linked changelog[/url] for some highlights.
******************* SOURCEFORGE *********************
For SF, just remove all of the BBCode.
@@ -28,4 +29,6 @@ Visit http://www.happypenguin.org/update?GemRB%3A%20The%20Infinity%20Engine%20Cl
and insert a shortened NEWS summary (3-10 items)
******************** LGDB ******************
-Visit the project page and submit an update (version only).
+http://www.lgdb.org/game/gemrb
+Visit the project page and submit an update (version, changelog). Choose
+"edit current" on the top and scroll through the form to get to the relevant part.
diff --git a/admin/enable-ie-git-diff b/admin/enable-ie-git-diff
new file mode 100755
index 0000000..3aa2951
--- /dev/null
+++ b/admin/enable-ie-git-diff
@@ -0,0 +1,16 @@
+#!/bin/bash
+#If you have ieparse (from ie_shell) or ielister, you can make git diff/log/show
+# output diffs of text dumps of the binary files it supports instead of just skipping
+# them.
+
+#1. Install either tool.
+
+#2. Define the new diff driver and optionally make it cache the results:
+# NOTE: use the correct path if the binary is not in the system path!
+
+cat >> .git/config <<-"IE"
+[diff "ie"]
+ textconv = ielister
+ cachetextconv = true
+IE
+
diff --git a/admin/extend2da.py b/admin/extend2da.py
new file mode 100755
index 0000000..a49481b
--- /dev/null
+++ b/admin/extend2da.py
@@ -0,0 +1,117 @@
+#!/usr/bin/python
+# GemRB - Infinity Engine Emulator
+# Copyright (C) 2011 The GemRB Project
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+#
+import sys
+
+def usage(msg):
+ print("Error:", msg)
+ print("Usage:", sys.argv[0], 'filename APPEND|APPEND_COL "$|value1 [$|value2] ... [$|valueN]"')
+ print("Passing $ will result in an empty cell. Use it for the first two entries when appending columns, so you don't break the 2da signature or default value")
+ print()
+ print("Example:")
+ print("python extend2da.py gemrb/override/bg1/classes.2da APPEND 'HACKER 1 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0'")
+
+# get the longest row for comparison, while caching the reads
+def readAndGetMaxLength(f):
+ global lines
+
+ max = i = 0
+ for line in f:
+ lines.append(line.rstrip())
+ if len(lines[i]) > max:
+ max = len(lines[i])
+ i = i + 1
+ return max
+
+def appendCol(f, max):
+ global lines, data
+
+ f.seek(0)
+ f.truncate()
+ i = 0
+ for cell in data:
+ if cell == "$":
+ f.write(lines[i] + b"\n")
+ i = i + 1
+ continue
+ padding = max - len(lines[i]) + 2 # 2 spaces as field separator
+ f.write(lines[i] + (" "*padding + cell + "\n").encode('ascii'))
+
+ i = i + 1
+
+def CheckCountsMismatch(mode):
+ global data, lines
+
+ if mode == "APPEND_COL":
+ msg = "rows"
+ rc = 13
+ count = len(lines)
+ elif mode == "APPEND":
+ msg = "columns"
+ rc = 14
+ count = len(lines[3].split()) # skip the 2da header
+ else:
+ return
+
+ mismatch = count - len(data)
+ if mismatch:
+ print ("Error: you need to specify the data for all the %s!" % msg)
+ print ("Table has %d, while you provided %d!" % (count, len(data)))
+ sys.exit(rc)
+
+
+#TODO: be fancy and align the columns correctly
+def appendRow(f):
+ global data
+
+ f.seek(0, 2) # seek to the end
+ for cell in data:
+ f.write(("%s " % cell).encode('ascii'))
+ # remove the extraneus ending padding
+ f.seek(f.tell()-2)
+ f.truncate()
+ f.write(b"\n")
+
+################# MAIN ####################################
+if len(sys.argv) < 4:
+ usage("missing parameters")
+ sys.exit(11)
+
+filename = sys.argv[1]
+mode = sys.argv[2].upper() # APPEND / APPEND_COL
+data = sys.argv[3:][0].split()
+
+if mode != "APPEND" and mode != "APPEND_COL":
+ usage("invalid mode parameter")
+ sys.exit(12)
+
+lines = []
+
+with open(filename, 'r+b') as f:
+ max = readAndGetMaxLength(f)
+ CheckCountsMismatch(mode)
+ if mode == "APPEND_COL":
+ appendCol(f, max)
+ elif mode == "APPEND":
+ appendRow(f)
+
+# tests
+# python2 extend2da.py gemrb/override/bg1/classes.2da APPEND_COL "$ $ BOGOSITY 0 0 0 00 0 0 0 0 0 0 0 0 0 0 2 3 4 7"
+# python2 extend2da.py gemrb/override/bg1/classes.2da APPEND "HACKER 1 3 0 0 0 00 0 0 0 0 0 0 0 0 0 0 "
+
diff --git a/admin/gource-generator b/admin/gource-generator
new file mode 100644
index 0000000..ab81b10
--- /dev/null
+++ b/admin/gource-generator
@@ -0,0 +1,16 @@
+Use Q in gource to see the "log position" to be used with --start-position and
+--stop-position .
+
+Use -c with a value greater than 1.0 to speed up the animation even further.
+
+Use -H to see all the possible gource options.
+
+FFMpeg encoding quality and options are practically arbitrary. Now the video is
+720p (-1280x720), but consider increasing the bitrate (-b) or improve quality some
+other way.
+
+gource --logo artwork/gemrb-logo.png --title "GemRB development 2012" \
+ --seconds-per-day 1 --auto-skip-seconds 1 \
+ -p 0.8447 -1280x720 -o - |
+ffmpeg -y -r 60 -f image2pipe -vcodec ppm -i - -vcodec libvpx -b:v 10000K gource.webm
+
diff --git a/admin/restart_news.sh b/admin/restart_news.sh
index 6e4c817..fec01ac 100755
--- a/admin/restart_news.sh
+++ b/admin/restart_news.sh
@@ -38,7 +38,5 @@ GemRB git ($rev):
-
- bugfixes
- Applied patches:
-
LILARCOR
mv NEWSNEWS NEWS
diff --git a/android/FREETYPEBUILD_Android.mk b/android/FREETYPEBUILD_Android.mk
new file mode 100644
index 0000000..f67b596
--- /dev/null
+++ b/android/FREETYPEBUILD_Android.mk
@@ -0,0 +1,40 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := freetype2-static
+
+LOCAL_CFLAGS := -DANDROID_NDK \
+ -DFT2_BUILD_LIBRARY=1
+
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include_all \
+ $(LOCAL_PATH)/../../include/ \
+ $(LOCAL_PATH)/../../src/
+
+LOCAL_SRC_FILES := \
+ ../../src/autofit/autofit.c \
+ ../../src/base/basepic.c \
+ ../../src/base/ftapi.c \
+ ../../src/base/ftbase.c \
+ ../../src/base/ftbbox.c \
+ ../../src/base/ftbitmap.c \
+ ../../src/base/ftdbgmem.c \
+ ../../src/base/ftdebug.c \
+ ../../src/base/ftglyph.c \
+ ../../src/base/ftinit.c \
+ ../../src/base/ftpic.c \
+ ../../src/base/ftstroke.c \
+ ../../src/base/ftsynth.c \
+ ../../src/base/ftsystem.c \
+ ../../src/cff/cff.c \
+ ../../src/pshinter/pshinter.c \
+ ../../src/psnames/psnames.c \
+ ../../src/raster/raster.c \
+ ../../src/sfnt/sfnt.c \
+ ../../src/smooth/smooth.c \
+ ../../src/truetype/truetype.c
+
+LOCAL_LDLIBS := -ldl -llog
+
+include $(BUILD_STATIC_LIBRARY)
+
diff --git a/android/GEMRB_Android.mk b/android/GEMRB_Android.mk
new file mode 100644
index 0000000..73eab06
--- /dev/null
+++ b/android/GEMRB_Android.mk
@@ -0,0 +1,253 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := main
+
+SDL_PATH := ../SDL
+
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include $(LOCAL_PATH)/main/gemrb/includes/ \
+ $(LOCAL_PATH)/main/gemrb/plugins/SAVImporter/ $(LOCAL_PATH)/main/gemrb/plugins/BMPWriter/ \
+ $(LOCAL_PATH)/main/gemrb/plugins/TISImporter/ $(LOCAL_PATH)/main/gemrb/plugins/CHUImporter/ \
+ $(LOCAL_PATH)/main/gemrb/plugins/2DAImporter/ $(LOCAL_PATH)/main/gemrb/plugins/BAMImporter/ \
+ $(LOCAL_PATH)/main/gemrb/plugins/ITMImporter/ $(LOCAL_PATH)/main/gemrb/plugins/BMPImporter/ \
+ $(LOCAL_PATH)/main/gemrb/plugins/WEDImporter/ $(LOCAL_PATH)/main/gemrb/plugins/IDSImporter/ \
+ $(LOCAL_PATH)/main/gemrb/plugins/ZLibManager/ $(LOCAL_PATH)/main/gemrb/plugins/DLGImporter/ \
+ $(LOCAL_PATH)/main/gemrb/plugins/GUIScript/ $(LOCAL_PATH)/main/gemrb/plugins/WAVReader/ \
+ $(LOCAL_PATH)/main/gemrb/plugins/STOImporter/ $(LOCAL_PATH)/main/gemrb/plugins/TTFImporter/ \
+ $(LOCAL_PATH)/main/gemrb/plugins/WMPImporter/ $(LOCAL_PATH)/main/gemrb/plugins/INIImporter/ \
+ $(LOCAL_PATH)/main/gemrb/plugins/MOSImporter/ $(LOCAL_PATH)/main/gemrb/plugins/TLKImporter/ \
+ $(LOCAL_PATH)/main/gemrb/plugins/BIKPlayer/ $(LOCAL_PATH)/main/gemrb/plugins/SPLImporter/ \
+ $(LOCAL_PATH)/main/gemrb/plugins/NullSound/ $(LOCAL_PATH)/main/gemrb/plugins/EFFImporter/ \
+ $(LOCAL_PATH)/main/gemrb/plugins/SDLAudio/ $(LOCAL_PATH)/main/gemrb/plugins/CREImporter/ \
+ $(LOCAL_PATH)/main/gemrb/plugins/OpenALAudio/ $(LOCAL_PATH)/main/gemrb/plugins/PROImporter/ \
+ $(LOCAL_PATH)/main/gemrb/plugins/ACMReader/ $(LOCAL_PATH)/main/gemrb/plugins/GAMImporter/ \
+ $(LOCAL_PATH)/main/gemrb/plugins/SDLVideo/ $(LOCAL_PATH)/main/gemrb/plugins/BIFImporter/ \
+ $(LOCAL_PATH)/main/gemrb/plugins/KEYImporter/ $(LOCAL_PATH)/main/gemrb/plugins/AREImporter/ \
+ $(LOCAL_PATH)/main/gemrb/plugins/DirectoryImporter/ \
+ $(LOCAL_PATH)/main/gemrb/plugins/OGGReader/ $(LOCAL_PATH)/main/gemrb/plugins/MVEPlayer/ \
+ $(LOCAL_PATH)/main/gemrb/plugins/NullSource/ $(LOCAL_PATH)/main/gemrb/plugins/PLTImporter/ \
+ $(LOCAL_PATH)/main/gemrb/plugins/PNGImporter/ $(LOCAL_PATH)/main/gemrb/plugins/MUSImporter/ \
+ $(LOCAL_PATH)/main/gemrb/core/Scriptable/ $(LOCAL_PATH)/main/gemrb/core/System/Logger/ \
+ $(LOCAL_PATH)/main/gemrb/core/System/ $(LOCAL_PATH)/main/gemrb/core/ \
+ $(LOCAL_PATH)/../freetype2-android/include \
+ $(LOCAL_PATH)/../SDL_mixer-1.2.12/ \
+ $(LOCAL_PATH)/../openal/include/ \
+ $(LOCAL_PATH)/../SDL/src/core/android/ \
+ $(LOCAL_PATH)/../libogg/include/ \
+ $(LOCAL_PATH)/../libvorbis/include/ \
+ $(LOCAL_PATH)/../libpython/include/ \
+ $(LOCAL_PATH)/../libpng/include/ \
+
+# Add your application source files here...
+LOCAL_SRC_FILES := main/gemrb/plugins/SAVImporter/SAVImporter.cpp \
+ main/gemrb/plugins/BMPWriter/BMPWriter.cpp \
+ main/gemrb/plugins/TISImporter/TISImporter.cpp \
+ main/gemrb/plugins/CHUImporter/CHUImporter.cpp \
+ main/gemrb/plugins/2DAImporter/2DAImporter.cpp \
+ main/gemrb/plugins/BAMImporter/BAMFontManager.cpp \
+ main/gemrb/plugins/BAMImporter/BAMFont.cpp \
+ main/gemrb/plugins/BAMImporter/BAMImporter.cpp \
+ main/gemrb/plugins/PSTOpcodes/PSTOpcodes.cpp \
+ main/gemrb/plugins/ITMImporter/ITMImporter.cpp \
+ main/gemrb/plugins/BMPImporter/BMPImporter.cpp \
+ main/gemrb/plugins/WEDImporter/WEDImporter.cpp \
+ main/gemrb/plugins/IDSImporter/IDSImporter.cpp \
+ main/gemrb/plugins/ZLibManager/ZLibManager.cpp \
+ main/gemrb/plugins/DLGImporter/DLGImporter.cpp \
+ main/gemrb/plugins/GUIScript/PythonHelpers.cpp \
+ main/gemrb/plugins/GUIScript/GUIScript.cpp \
+ main/gemrb/plugins/WAVReader/WAVReader.cpp \
+ main/gemrb/plugins/STOImporter/STOImporter.cpp \
+ main/gemrb/plugins/TTFImporter/TTFFontManager.cpp \
+ main/gemrb/plugins/TTFImporter/Freetype.cpp \
+ main/gemrb/plugins/TTFImporter/TTFFont.cpp \
+ main/gemrb/plugins/WMPImporter/WMPImporter.cpp \
+ main/gemrb/plugins/INIImporter/INIImporter.cpp \
+ main/gemrb/plugins/MOSImporter/MOSImporter.cpp \
+ main/gemrb/plugins/TLKImporter/TLKImporter.cpp \
+ main/gemrb/plugins/TLKImporter/TlkOverride.cpp \
+ main/gemrb/plugins/BIKPlayer/dct.cpp \
+ main/gemrb/plugins/BIKPlayer/BIKPlayer.cpp \
+ main/gemrb/plugins/BIKPlayer/rational.cpp \
+ main/gemrb/plugins/BIKPlayer/mem.cpp \
+ main/gemrb/plugins/BIKPlayer/GetBitContext.cpp \
+ main/gemrb/plugins/BIKPlayer/fft.cpp \
+ main/gemrb/plugins/BIKPlayer/rdft.cpp \
+ main/gemrb/plugins/SPLImporter/SPLImporter.cpp \
+ main/gemrb/plugins/NullSound/NullSound.cpp \
+ main/gemrb/plugins/EFFImporter/EFFImporter.cpp \
+ main/gemrb/plugins/FXOpcodes/FXOpcodes.cpp \
+ main/gemrb/plugins/CREImporter/CREImporter.cpp \
+ main/gemrb/plugins/OpenALAudio/OpenALAudio.cpp \
+ main/gemrb/plugins/OpenALAudio/StackLock.cpp \
+ main/gemrb/plugins/OpenALAudio/AmbientMgrAL.cpp \
+ main/gemrb/plugins/PROImporter/PROImporter.cpp \
+ main/gemrb/plugins/ACMReader/decoder.cpp \
+ main/gemrb/plugins/ACMReader/ACMReader.cpp \
+ main/gemrb/plugins/ACMReader/unpacker.cpp \
+ main/gemrb/plugins/GAMImporter/GAMImporter.cpp \
+ main/gemrb/plugins/SDLVideo/SDL20Video.cpp \
+ main/gemrb/plugins/SDLVideo/SDLVideo.cpp \
+ main/gemrb/plugins/BIFImporter/BIFImporter.cpp \
+ main/gemrb/plugins/KEYImporter/KEYImporter.cpp \
+ main/gemrb/plugins/AREImporter/AREImporter.cpp \
+ main/gemrb/plugins/DirectoryImporter/DirectoryImporter.cpp \
+ main/gemrb/plugins/IWDOpcodes/IWDOpcodes.cpp \
+ main/gemrb/plugins/OGGReader/OGGReader.cpp \
+ main/gemrb/plugins/MVEPlayer/mveaudiodec.cpp \
+ main/gemrb/plugins/MVEPlayer/mvevideodec8.cpp \
+ main/gemrb/plugins/MVEPlayer/MVEPlayer.cpp \
+ main/gemrb/plugins/MVEPlayer/mve_player.cpp \
+ main/gemrb/plugins/MVEPlayer/mvevideodec16.cpp \
+ main/gemrb/plugins/NullSource/NullSource.cpp \
+ main/gemrb/plugins/PLTImporter/PLTImporter.cpp \
+ main/gemrb/plugins/PNGImporter/PNGImporter.cpp \
+ main/gemrb/plugins/MUSImporter/MUSImporter.cpp \
+ main/gemrb/core/Projectile.cpp \
+ main/gemrb/core/AnimationMgr.cpp \
+ main/gemrb/core/Store.cpp \
+ main/gemrb/core/Ambient.cpp \
+ main/gemrb/core/TableMgr.cpp \
+ main/gemrb/core/ScriptEngine.cpp \
+ main/gemrb/core/WindowMgr.cpp \
+ main/gemrb/core/Tile.cpp \
+ main/gemrb/core/DisplayMessage.cpp \
+ main/gemrb/core/Scriptable/InfoPoint.cpp \
+ main/gemrb/core/Scriptable/CombatInfo.cpp \
+ main/gemrb/core/Scriptable/Container.cpp \
+ main/gemrb/core/Scriptable/PCStatStruct.cpp \
+ main/gemrb/core/Scriptable/Door.cpp \
+ main/gemrb/core/Scriptable/Scriptable.cpp \
+ main/gemrb/core/Scriptable/Actor.cpp \
+ main/gemrb/core/IniSpawn.cpp \
+ main/gemrb/core/CharAnimations.cpp \
+ main/gemrb/core/Plugin.cpp \
+ main/gemrb/core/GameData.cpp \
+ main/gemrb/core/MusicMgr.cpp \
+ main/gemrb/core/PluginLoader.cpp \
+ main/gemrb/core/WorldMap.cpp \
+ main/gemrb/core/ItemMgr.cpp \
+ main/gemrb/core/SoundMgr.cpp \
+ main/gemrb/core/TileMap.cpp \
+ main/gemrb/core/AmbientMgr.cpp \
+ main/gemrb/core/Inventory.cpp \
+ main/gemrb/core/ScriptedAnimation.cpp \
+ main/gemrb/core/WorldMapMgr.cpp \
+ main/gemrb/core/Spellbook.cpp \
+ main/gemrb/core/Factory.cpp \
+ main/gemrb/core/TileSetMgr.cpp \
+ main/gemrb/core/SymbolMgr.cpp \
+ main/gemrb/core/DialogMgr.cpp \
+ main/gemrb/core/ImageMgr.cpp \
+ main/gemrb/core/LRUCache.cpp \
+ main/gemrb/core/Sprite2D.cpp \
+ main/gemrb/core/Dialog.cpp \
+ main/gemrb/core/Calendar.cpp \
+ main/gemrb/core/DialogHandler.cpp \
+ main/gemrb/core/System/Logger.cpp \
+ main/gemrb/core/System/Logger/MessageWindowLogger.cpp \
+ main/gemrb/core/System/Logger/File.cpp \
+ main/gemrb/core/System/Logger/Stdio.cpp \
+ main/gemrb/core/System/Logger/Android.cpp \
+ main/gemrb/core/System/StringBuffer.cpp \
+ main/gemrb/core/System/VFS.cpp \
+ main/gemrb/core/System/String.cpp \
+ main/gemrb/core/System/Logging.cpp \
+ main/gemrb/core/System/FileStream.cpp \
+ main/gemrb/core/System/MemoryStream.cpp \
+ main/gemrb/core/System/DataStream.cpp \
+ main/gemrb/core/System/SlicedStream.cpp \
+ main/gemrb/core/ResourceDesc.cpp \
+ main/gemrb/core/Item.cpp \
+ main/gemrb/core/SaveGameIterator.cpp \
+ main/gemrb/core/Callback.cpp \
+ main/gemrb/core/ArchiveImporter.cpp \
+ main/gemrb/core/StringMgr.cpp \
+ main/gemrb/core/ControlAnimation.cpp \
+ main/gemrb/core/Region.cpp \
+ main/gemrb/core/ProjectileMgr.cpp \
+ main/gemrb/core/ActorMgr.cpp \
+ main/gemrb/core/Resource.cpp \
+ main/gemrb/core/StoreMgr.cpp \
+ main/gemrb/core/Animation.cpp \
+ main/gemrb/core/ResourceSource.cpp \
+ main/gemrb/core/Map.cpp \
+ main/gemrb/core/Variables.cpp \
+ main/gemrb/core/FactoryObject.cpp \
+ main/gemrb/core/DataFileMgr.cpp \
+ main/gemrb/core/ResourceManager.cpp \
+ main/gemrb/core/Video.cpp \
+ main/gemrb/core/SpriteCover.cpp \
+ main/gemrb/core/EffectQueue.cpp \
+ main/gemrb/core/TileOverlay.cpp \
+ main/gemrb/core/KeyMap.cpp \
+ main/gemrb/core/Audio.cpp \
+ main/gemrb/core/AnimationFactory.cpp \
+ main/gemrb/core/SaveGameMgr.cpp \
+ main/gemrb/core/ImageFactory.cpp \
+ main/gemrb/core/Bitmap.cpp \
+ main/gemrb/core/TileMapMgr.cpp \
+ main/gemrb/core/GlobalTimer.cpp \
+ main/gemrb/core/GameScript/GameScript.cpp \
+ main/gemrb/core/GameScript/Triggers.cpp \
+ main/gemrb/core/GameScript/GSUtils.cpp \
+ main/gemrb/core/GameScript/Matching.cpp \
+ main/gemrb/core/GameScript/Actions.cpp \
+ main/gemrb/core/GameScript/Objects.cpp \
+ main/gemrb/core/Polygon.cpp \
+ main/gemrb/core/GUI/MapControl.cpp \
+ main/gemrb/core/GUI/Label.cpp \
+ main/gemrb/core/GUI/ScrollBar.cpp \
+ main/gemrb/core/GUI/Control.cpp \
+ main/gemrb/core/GUI/WorldMapControl.cpp \
+ main/gemrb/core/GUI/TextEdit.cpp \
+ main/gemrb/core/GUI/Window.cpp \
+ main/gemrb/core/GUI/Button.cpp \
+ main/gemrb/core/GUI/GameControl.cpp \
+ main/gemrb/core/GUI/TextArea.cpp \
+ main/gemrb/core/GUI/EventMgr.cpp \
+ main/gemrb/core/GUI/Progressbar.cpp \
+ main/gemrb/core/GUI/Console.cpp \
+ main/gemrb/core/GUI/Slider.cpp \
+ main/gemrb/core/FontManager.cpp \
+ main/gemrb/core/MoviePlayer.cpp \
+ main/gemrb/core/Font.cpp \
+ main/gemrb/core/MapMgr.cpp \
+ main/gemrb/core/Compressor.cpp \
+ main/gemrb/core/PalettedImageMgr.cpp \
+ main/gemrb/core/PluginMgr.cpp \
+ main/gemrb/core/IndexedArchive.cpp \
+ main/gemrb/core/Spell.cpp \
+ main/gemrb/core/Core.cpp \
+ main/gemrb/core/Image.cpp \
+ main/gemrb/core/SpellMgr.cpp \
+ main/gemrb/core/Particles.cpp \
+ main/gemrb/core/ProjectileServer.cpp \
+ main/gemrb/core/EffectMgr.cpp \
+ main/gemrb/core/Game.cpp \
+ main/gemrb/core/ImageWriter.cpp \
+ main/gemrb/core/Interface.cpp \
+ main/gemrb/core/InterfaceConfig.cpp \
+ main/gemrb/core/Cache.cpp \
+ main/gemrb/core/FileCache.cpp \
+ main/gemrb/core/Palette.cpp \
+ main/gemrb/core/System/swab.c \
+ main/gemrb/GemRB.cpp \
+ ../SDL/src/main/android/SDL_android_main.cpp \
+ # main/gemrb/plugins/SDLAudio/SDLAudio.cpp \
+
+LOCAL_SHARED_LIBRARIES := SDL2 openal ogg vorbis python
+LOCAL_STATIC_LIBRARIES := freetype2-static png gnustl_static
+
+LOCAL_CPPFLAGS += -fexceptions -finline-functions -O0 -DSTATIC_LINK=Yes -DHAVE_SNPRINTF
+
+LOCAL_LDLIBS := -lGLESv1_CM -llog -lz -ldl
+# LOCAL_LDLIBS += -L$(LOCAL_PATH)/../../../gemrb/obj/local/armeabi/ -logg -lvorbis -lSDL_mixer -lpython2.7 -l freetype2-static -lpng -lgnustl_static
+
+LOCAL_C_INCLUDES += $(NDK_PATH)/sources/cxx-stl/gnu-libstdc++/include
+LOCAL_LDLIBS += -L$(NDK_PATH)/sources/cxx-stl/gnu-libstdc++/libs/$(TARGET_ARCH_ABI) -lstdc++
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(call all-subdir-makefiles)
diff --git a/android/GEMRB_Application.mk b/android/GEMRB_Application.mk
new file mode 100644
index 0000000..6110cb2
--- /dev/null
+++ b/android/GEMRB_Application.mk
@@ -0,0 +1,5 @@
+# Uncomment this if you're using STL in your project
+# See CPLUSPLUS-SUPPORT.html in the NDK documentation for more information
+# APP_PROJECT_PATH := $(call my-dir)/..
+APP_STL := gnustl_static
+APP_MODULES := SDL2 ogg vorbis openal python freetype2-static png main
diff --git a/android/GemRB.java b/android/GemRB.java
new file mode 100644
index 0000000..212e947
--- /dev/null
+++ b/android/GemRB.java
@@ -0,0 +1,132 @@
+package net.sourceforge.gemrb;
+
+import org.libsdl.app.SDLActivity;
+import android.os.Bundle;
+import android.util.Log;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.BufferedOutputStream;
+import java.io.BufferedInputStream;
+import java.io.InputStream;
+import android.content.res.AssetManager;
+import java.util.Enumeration;
+import java.util.zip.*;
+import java.util.Properties;
+import android.app.AlertDialog;
+import android.widget.EditText;
+import android.content.DialogInterface;
+
+public class GemRB extends SDLActivity {
+
+ public String newPath;
+
+ protected void onCreate(Bundle savedInstanceState) {
+ File gemrbHomeFolder = getApplicationContext().getExternalFilesDir(null); // null for general purpose files
+ String[] foldersToExtract = { "GUIScripts", "override", "unhardcoded" };
+
+ // first clear the directories and their contents
+ Log.d("GemRB Activity", "Cleaning up...");
+ for(String folder : foldersToExtract) {
+ deleteRecursive(new File(gemrbHomeFolder.getAbsolutePath().concat(gemrbHomeFolder.separator).concat(folder)));
+ }
+
+ Log.d("GemRB Activity", "Extracting new files...");
+ try {
+ extractFolder(this.getApplication().getPackageCodePath(), gemrbHomeFolder.getAbsolutePath());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ Log.d("GemRB Activity", "Done.");
+
+ Log.d("GemRB Activity", "Checking GemRB.cfg content.");
+
+ File finalConfFile = new File(gemrbHomeFolder.getAbsolutePath().concat(gemrbHomeFolder.separator).concat("GemRB.cfg"));
+
+ if(!finalConfFile.exists()) {
+ Log.d("GemRB Activity", "GemRB.cfg doesn't exist in the expected location, creating it from the packaged template.");
+
+ // String[] keysToChange = { "GUIScriptsPath", "GemRBOverridePath", "GemRBUnhardcodedPath" };
+ try {
+ File inConfFile = new File(gemrbHomeFolder.getAbsolutePath().concat(gemrbHomeFolder.separator).concat("packaged.GemRB.cfg"));
+ BufferedReader inConf = new BufferedReader(new FileReader(inConfFile));
+ File outConfFile = new File(gemrbHomeFolder.getAbsolutePath().concat(gemrbHomeFolder.separator).concat("new.GemRB.cfg"));
+ BufferedWriter outConf = new BufferedWriter(new FileWriter(outConfFile));
+
+ String line;
+
+ while((line = inConf.readLine()) != null) {
+ outConf.write(line.concat("\n"));
+ outConf.flush();
+ }
+ inConf.close();
+ outConf.flush();
+ outConf.close();
+
+ inConfFile.delete();
+ outConfFile.renameTo(finalConfFile);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ super.onCreate(savedInstanceState);
+ }
+
+ private static void deleteRecursive(File fileOrDirectory) {
+ if (fileOrDirectory.isDirectory())
+ for (File child : fileOrDirectory.listFiles())
+ deleteRecursive(child);
+
+ fileOrDirectory.delete();
+ }
+
+ private static void extractFolder(String zipFile, String newPath) throws ZipException, IOException {
+ int BUFFER = 1024 * 1024;
+ File file = new File(zipFile);
+
+ ZipFile zip = new ZipFile(file);
+
+ new File(newPath).mkdir();
+ Enumeration zipFileEntries = zip.entries();
+
+ // establish buffer for writing file
+ byte data[] = new byte[BUFFER];
+ // Process each entry
+ while (zipFileEntries.hasMoreElements()) {
+ // grab a zip file entry
+ ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
+ String currentEntry = entry.getName();
+ if(!currentEntry.contains("asset")) {
+ continue;
+ }
+ File destFile = new File(newPath, currentEntry.substring(7)); // 6th index should be "/" of "assets/"
+ //destFile = new File(newPath, destFile.getName());
+ File destinationParent = destFile.getParentFile();
+
+ // create the parent directory structure if needed
+ destinationParent.mkdirs();
+
+ if (!entry.isDirectory()) {
+ InputStream is = zip.getInputStream(entry);
+ int currentByte;
+
+ // write the current file to disk
+ FileOutputStream dest = new FileOutputStream(destFile);
+
+ // read and write until last byte is encountered
+ while ((currentByte = is.read(data, 0, BUFFER)) != -1) {
+ dest.write(data, 0, currentByte);
+ }
+ dest.flush();
+ dest.close();
+ is.close();
+ }
+ }
+ }
+}
diff --git a/android/OGG_Android.mk b/android/OGG_Android.mk
new file mode 100644
index 0000000..8f3eb45
--- /dev/null
+++ b/android/OGG_Android.mk
@@ -0,0 +1,11 @@
+LOCAL_PATH := $(call my-dir)
+
+# ogg
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := ogg
+LOCAL_SRC_FILES := libogg.so
+LOCAL_C_EXPORT_INCLUDES := include
+
+include $(PREBUILT_SHARED_LIBRARY)
+
diff --git a/android/OPENAL_Android.mk b/android/OPENAL_Android.mk
new file mode 100644
index 0000000..a27b6f1
--- /dev/null
+++ b/android/OPENAL_Android.mk
@@ -0,0 +1,9 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := openal
+LOCAL_SRC_FILES := libopenal.so
+LOCAL_EXPORT_C_INCLUDES := include/
+
+include $(PREBUILT_SHARED_LIBRARY)
diff --git a/android/PNG_Android.mk b/android/PNG_Android.mk
new file mode 100644
index 0000000..0a8d7fd
--- /dev/null
+++ b/android/PNG_Android.mk
@@ -0,0 +1,9 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := png
+LOCAL_SRC_FILES := libpng.a
+LOCAL_EXPORT_C_INCLUDES := include/
+
+include $(PREBUILT_STATIC_LIBRARY)
diff --git a/android/README b/android/README
new file mode 100644
index 0000000..275a309
--- /dev/null
+++ b/android/README
@@ -0,0 +1,101 @@
+BUILDING GEMRB FOR ANDROID
+--------------------------
+
+Tools you will need to build GemRB for Android:
+
+- android-sdk API-level 10 or greater
+- android-ndk (newer is generally better, tested against r8d)
+- ant
+- java
+- mercurial for building SDL2
+- git for building various other dependencies
+
+--------------------------------------
+Building the apk on a Unix-like System
+--------------------------------------
+
+Running the following commands from the directory this README resides in will
+build an Android 2.2 and later compatible .apk.
+
+First, use the provided script to prepare the build environment:
+
+ bash prep_env.sh $GEMRB_GIT_PATH
+
+where $GEMRB_GIT_PATH is the full path to the directory above the one this
+README resides in. This script will create neccessary folders, check out and
+build a few of the neccessary libraries and copy and modify a few project files.
+
+After the completion of the script, you can change into the build directory
+with:
+
+ cd build/gemrb
+
+and subsequently compile the remaining libraries and GemRB itsself with:
+
+ ndk-build
+
+for a stripped build or
+
+ ndk-build NDK_DEBUG=1
+
+if you want a debuggable build.
+
+When the compilation concluded successfully, you can package the apk with:
+
+ ant debug
+
+You can supply the additional argument "install" to ant to directly install the
+resulting apk to a device connected to the computer which builds it, i.e:
+
+ ant debug install
+
+NOTE: To use this command, you HAVE to have USB-Debugging enabled on your
+Android device.
+
+If everything ran without any errors you should find a file named
+"SDLActivity-debug.apk" in build/gemrb/bin below the folder this README resides
+in. If you ran ant with the "install" argument, you can directly run GemRB from
+your devices' main menu. If you didn't, you can copy the apk file to your device
+with
+
+ adb push bin/SDLActivity-debug.apk /sdcard/
+
+assuming you are still in build/gemrb.
+
+---------------------
+Configuring your game
+---------------------
+
+You will have to install the widescreen mod for your game.
+Depending on the version of Android on your device, you have to adjust the
+height by 48 pixels, seeing as the home bar takes up space on the screen.
+
+NOTE: Due to performance issues, it is recommended to chose a resolution that
+keeps the aspect ratio of your screen but does not equal your native resolution.
+
+-----------------
+Configuring GemRB
+-----------------
+
+The app will most likely not start your game on the first start.
+This is because the supplied config file does not know about the location of
+your game data. You will need to run the following command to retrieve the config
+file:
+
+ adb pull /sdcard/Android/data/net.sourceforge.gemrb/files/.GemRB/GemRB.cfg
+
+and edit it with your preferred text editor. Pay attention to the comments in
+the file, the entries you need to change are:
+
+ - GamePath
+ - CD1 to CD5
+ - CachePath
+
+After you adjust these paths, you have to copy the file back to the correct
+location on your device:
+
+ adb push GemRB.cfg /sdcard/Android/data/net.sourceforge.gemrb/files/.GemRB/GemRB.cfg
+
+Assuming you followed all these steps correctly, you should be able to run the
+app from your device's main menu and the game should start correctly.
+
diff --git a/android/RECURSE_Android.mk b/android/RECURSE_Android.mk
new file mode 100644
index 0000000..5053e7d
--- /dev/null
+++ b/android/RECURSE_Android.mk
@@ -0,0 +1 @@
+include $(call all-subdir-makefiles)
diff --git a/android/TODO b/android/TODO
new file mode 100644
index 0000000..3424918
--- /dev/null
+++ b/android/TODO
@@ -0,0 +1,6 @@
+2013-03-10
+- prep_env.sh should have more error checks
+- add a dialog on first run to prompt for GamePath
+- version checks for override, unhardcoded and GUIScripts
+- mouse cursor seems to get positioned at the corners of the screen touches for some reason, most likely not directly related to the android build though
+- touches have to be rather quick to register as click events, might be related to SDL20Driver::ProcessFirstTouch()
diff --git a/android/VORBIS_Android.mk b/android/VORBIS_Android.mk
new file mode 100644
index 0000000..34674b7
--- /dev/null
+++ b/android/VORBIS_Android.mk
@@ -0,0 +1,9 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := vorbis
+LOCAL_SRC_FILES := libvorbis.so
+LOCAL_C_EXPORT_INCLOUDES := include/
+
+include $(PREBUILT_SHARED_LIBRARY)
diff --git a/android/packaged.GemRB.cfg b/android/packaged.GemRB.cfg
new file mode 100644
index 0000000..e1b7bd5
--- /dev/null
+++ b/android/packaged.GemRB.cfg
@@ -0,0 +1,324 @@
+#####################################################
+# #
+# This is the GemRB Configuration file. #
+# Here are defined some default parameters for #
+# basic configuration and paths definition. #
+# #
+# Parameters are defined as a Name=Value pair #
+# The Value can be of three types: #
+# - String #
+# - Integer #
+# - Boolean #
+# #
+# The String value is represented as follows #
+# i.e. H:\GemRB\plugins #
+# Integers are defined as follows #
+# i.e. 12723 #
+# Booleans are represented as 1 or 0 in this file #
+# #
+# Lines starting with # are ignored #
+# #
+#####################################################
+
+#####################################################
+# #
+# Game Type [String] Use one of the following #
+# values: #
+# #
+# auto Attempt to autodetect game type #
+# #
+# bg1 Baldur's Gate #
+# bg2 Baldur's Gate 2 : SoA or ToB #
+# tob Baldur's Gate 2 : ToB (obsolete) #
+# iwd IceWind Dale (no How or ToTL installed)#
+# how IceWind Dale : HoW or ToTL #
+# iwd2 IceWind Dale 2 #
+# pst Planescape Torment #
+# (More will come) #
+# #
+#####################################################
+
+GameType=bg1
+
+#####################################################
+# Game Name [String] Title for GemRB window, use #
+# anything you wish, e.g. Baldur's Gate 3: RotFL #
+#####################################################
+
+GameName=Baldur's Gate 2
+
+#####################################################
+# Encoding [default|polish|czech] Language used by #
+# game data. Except of polish BG1, leave disabled. #
+#####################################################
+
+# Encoding=default
+
+#####################################################
+# Video Parameters #
+#####################################################
+#NOTE: SCREEN width and height can NOT be ARBITRARY without installing the
+# widescreen mod: http://www.gibberlings3.net/widescreen/
+#Resolutions supported by the original games (gemrb) are:
+# * 640x480 (except in iwd2)
+# * 800x600 (bg2, iwd:how, iwd2)
+# * 1024x768 (bg2, iwd:how, iwd2)
+# * 1280x1024 (bg2, iwd:how, iwd2)
+
+#Screen width
+Width=640
+
+#Screen height
+Height=480
+
+#Bits per pixel [Integer:16,32]
+Bpp=16
+
+#Fullscreen [Boolean]
+Fullscreen=0
+
+# Delay before tooltips appear [milliseconds]
+TooltipDelay=500
+
+#####################################################
+# Audio Parameters #
+#####################################################
+# #
+# All volume options are in percents, with 100 #
+# being the normal and default volume #
+# #
+#####################################################
+
+# Choices: openal (default), sdlaudio (faster, but limited featureset), none
+AudioDriver = openal
+
+# Volume of ambient sounds
+#VolumeAmbients = 100
+
+# Volume during movie playback
+#VolumeMovie = 100
+
+# Volume of background music
+#VolumeMusic = 100
+
+# Volume of sound effects
+#VolumeSFX = 100
+
+# Volume of PC or NPC voices
+#VolumeVoices = 100
+
+#####################################################
+# Case Sensitive Filesystem [Boolean] #
+# #
+# If your installed game files are residing on a #
+# case sensitive filesystem (ext2 on Linux) then #
+# you need to set this value to 1, it has no #
+# effect on Windows #
+#####################################################
+
+#CaseSensitive=1
+
+#####################################################
+# GUI Parameters #
+#####################################################
+# #
+# GemRB may enhance the GUI of the Infinity Engine #
+# games (so far only in bg2) creating functionally #
+# new buttons or scrollbars where they weren't #
+# present in original games. It may improve its #
+# usability, but is not quite compatible with #
+# mods changing graphics and alignment in the *.chu #
+# files (e.g. the buttons will appear in old #
+# coordinates and may stop being clickable). #
+#####################################################
+
+# Enable all gui enhancements ? [Integer]
+GUIEnhancements = 15
+
+
+#####################################################
+# Debug #
+#####################################################
+
+# Do not play intro videos [Boolean], useful for development
+#SkipIntroVideos=1
+
+# Draw Frames per Second info [Boolean]
+# DrawFPS=0
+
+# Hide unexplored parts of a map
+#FogOfWar=1
+
+# Enable debug and cheat keystrokes, see docs/en/CheatKeys.txt
+# full listing
+#EnableCheatKeys=1
+
+#####################################################
+# Paths #
+#####################################################
+
+#####################################################
+# Game Paths [String] #
+# #
+# These are the paths where the Game you want to #
+# play is installed. #
+# Enter the full path to the directory. #
+#####################################################
+
+#GamePath=/storage/emulated/0/Android/data/net.sourceforge.gemrb/files/bg2/
+#CD1=/storage/emulated/0/Android/data/net.sourceforge.gemrb/files/bg2/data
+GamePath=/sdcard/gemrb/bg1
+CD1=/sdcard/gemrb/bg1/data
+# CD2=<CD2_PLACEHOLDER>
+# CD3=<CD3_PLACEHOLDER>
+# CD4=<CD4_PLACEHOLDER>
+# CD5=<CD5_PLACEHOLDER>
+
+#####################################################
+# GemRB Cache Path [String] #
+# #
+# This is the path where GemRB will store the #
+# cached files, enter the full path to the GemRB #
+# Cache directory. #
+#####################################################
+
+CachePath=/sdcard/gemrb/bg1/cache
+
+#####################################################
+# GemRB Save Path [String] #
+# #
+# This is the path where GemRB looks for saved #
+# games. #
+# Enter the full path to the directory containing #
+# e.g. the 'save' subdirectory. #
+# #
+# You do not have to specify this if you use save #
+# subdir in the GamePath directory. #
+#####################################################
+
+# SavePath=/sdcard/gemrb/bg2/
+
+###### HERE BE DRAGONS #############################
+# You shouldn't need to change any paths below this point.
+
+#####################################################
+# GemRB Path [String] #
+# #
+# This is the path where GemRB is stored, just #
+# enter the full path to the GemRB executable #
+#####################################################
+
+# GemRBPath=
+
+#####################################################
+# GemRB GUI Scripts Path [String] #
+# #
+# This is the path where GemRB GUI scripts are #
+# stored, usually these are in the GemRB directory #
+# Enter the full path to the directory containing #
+# the 'GUIScript' subdirectory. #
+#####################################################
+
+#GUIScriptsPath=
+
+#####################################################
+# GemRB Plugins Path [String] #
+# #
+# This is the path containing GemRB plugins #
+# - shared libraries (.so) on Unixes, or #
+# DLLs (.dll) on windows. #
+# Enter the full path to the directory. #
+# #
+# You may need to specify this path if running #
+# GemRB from source directory on Linux. #
+#####################################################
+
+#PluginsPath=@PLUGIN_DIR@
+
+#####################################################
+# Custom Font Path [String] #
+# #
+# This is the path where GemRB looks for non-BAM #
+# fonts (ex TTF) #
+# #
+#####################################################
+
+#CustomFontPath=
+
+#####################################################
+# Game Data Path [String] #
+# #
+# This is the subdirectory under GamePath where #
+# game data files are stored. #
+# #
+# You probably do NOT want to specify this! #
+#####################################################
+
+#GameDataPath=
+
+#####################################################
+# Game Data Override Path [String] #
+# #
+# This is the subdirectory under GamePath where #
+# game data override files are stored. #
+# #
+# You probably do NOT want to specify this! #
+#####################################################
+
+#GameOverridePath=
+
+#####################################################
+# GemRB Data Override Path [String] #
+# #
+# This is the path where GemRB looks for the GemRB #
+# data override directory. #
+# #
+# You probably do NOT want to specify this! #
+#####################################################
+
+#GemRBOverridePath=
+#GemRBUnhardcodedPath=
+
+#####################################################
+# Input Parameters #
+#####################################################
+
+#whether or not to use software keyboard on devices that support one
+UseSoftKeyboard=1
+
+#Adds a gutter around the screen for scrolling
+TouchScrollAreas=0
+
+#####################################################
+# MouseFeedback #
+# Bitfield with reserved bits for disabling #
+# the mouse. Those bits cannot be set via config #
+# #
+# Show mouse+tooltips = 0 #
+# Hide mouse = 1 #
+# Hide tooltips = 2 #
+# Hide mouse+tooltips = 3 #
+#####################################################
+
+# For a strictly touchscreen device we recommend
+# Changing this to 3.
+
+# default is 0
+MouseFeedback=0
+
+#####################################################
+# Touch Gesture Input Parameters #
+# Requires SDL 1.3 or later #
+# All "NumFing" settings must be > 1 and < 5 #
+# NumFingScroll and NumFingKboard cannot be equal #
+#####################################################
+
+#NumFingScroll=2
+
+#NumFingKboard=3
+
+#NumFingInfo=2
+
+#####################################################
+# END #
+#####################################################
diff --git a/android/prep_env.sh b/android/prep_env.sh
new file mode 100644
index 0000000..84d61c3
--- /dev/null
+++ b/android/prep_env.sh
@@ -0,0 +1,200 @@
+#!/bin/bash
+
+# TODO: create the whole dir struct first, i.e. get SDL2.0, get GemRb, create symlinks etc.
+# get rid of everything pelya if possible
+# figure out, what exactly openal needs
+
+ENVROOT=$PWD
+GEMRB_GIT_PATH=$1
+
+function build_vorbis {
+ echo -en "Checking out libogg-vorbis.\n"
+ git clone git://github.com/jcadam/libogg-vorbis-android.git &&
+ echo -en "Building libogg-vorbis...\n" &&
+ pushd "$ENVROOT/libogg-vorbis-android" &&
+ ndk-build &&
+ popd &&
+ echo -en "Done with libogg-vorbis.\n"
+}
+
+function build_openal {
+ # this still only works with a copied android.h from pelya/commandergenius
+ # ifdef SDLVERSION somethingsomething in OpenALAudio solves this
+ echo -en "Checking out openal.\n"
+ git clone git://repo.or.cz/openal-soft/android.git &&
+ mv "$ENVROOT/android" "$ENVROOT/openal" && # why would they name it "android" :(
+ echo -en "Building openal...\n" &&
+ pushd "$ENVROOT/openal/android" &&
+ ndk-build &&
+ popd &&
+ echo -en "Done with openal.\n"
+}
+
+function build_libpng {
+ echo -en "Checking out libpng...\n"
+ git clone git://github.com/julienr/libpng-android.git &&
+ echo -en "Building libpng...\n" &&
+ pushd "$ENVROOT/libpng-android" &&
+ ndk-build &&
+ popd &&
+ echo -en "Done with libpng.\n"
+}
+
+function get_freetype {
+ # can't precompile freetype, at least not as it comes from upstream
+ git clone git://github.com/cdave1/freetype2-android.git
+}
+
+function build_deps {
+ build_openal &&
+ build_vorbis &&
+ build_libpng &&
+ get_freetype
+}
+
+function setup_dir_struct {
+ echo -en "Checking out SDL2...\n"
+ # get SDL2
+ hg clone http://hg.libsdl.org/SDL &&
+ # and do what it says in its README.android
+ echo -en "Creating the directory structure for the project..." &&
+ mkdir build &&
+ cp -r "$ENVROOT/SDL/android-project" build/ &&
+ mv "$ENVROOT/build/android-project" "$ENVROOT/build/gemrb" &&
+ echo -en "Done.\n" &&
+ echo -en "Symlinking the GemRB-git path..." &&
+ ln -s "$GEMRB_GIT_PATH" "$ENVROOT/build/gemrb/jni/src/main" &&
+ ln -s "$ENVROOT/SDL" "$ENVROOT/build/gemrb/jni/SDL"
+}
+
+function move_libraries {
+ echo -en "Creating directories and copying Makefiles for prebuilt libraries...\n"
+
+ # freetype2 is special, it's not supposed to be precompiled according to upstream,
+ # additionally, upstream makefile is actually broken and we need makefiles in every
+ # directory up to where the current one is stored, because ndk-build doesn't see
+ # the right one otherwise
+ # the alternative would probably be to store the makefile at the root of the
+ # freetype directory, but im not sure in how far that messes with library placement
+ cp -r "$ENVROOT/freetype2-android" "$ENVROOT/build/gemrb/jni/" &&
+ cp "$ENVROOT/FREETYPEBUILD_Android.mk" "$ENVROOT/build/gemrb/jni/freetype2-android/Android/jni/Android.mk" &&
+ cp "$ENVROOT/RECURSE_Android.mk" "$ENVROOT/build/gemrb/jni/freetype2-android/Android/Android.mk" &&
+ cp "$ENVROOT/RECURSE_Android.mk" "$ENVROOT/build/gemrb/jni/freetype2-android/Android.mk" &&
+ # im not happy with this, but it's ok for now i guess
+
+ mkdir build/gemrb/jni/{libogg,libvorbis,libpng,openal} &&
+ cp "$ENVROOT/OGG_Android.mk" "$ENVROOT/build/gemrb/jni/libogg/Android.mk" &&
+ cp "$ENVROOT/VORBIS_Android.mk" "$ENVROOT/build/gemrb/jni/libvorbis/Android.mk" &&
+ cp "$ENVROOT/OPENAL_Android.mk" "$ENVROOT/build/gemrb/jni/openal/Android.mk" &&
+ cp "$ENVROOT/PNG_Android.mk" "$ENVROOT/build/gemrb/jni/libpng/Android.mk" &&
+
+ echo -en "Copying prebuilt libraries and linking header directories...\n" &&
+
+ # libogg
+ cp "$ENVROOT/libogg-vorbis-android/libs/armeabi/libogg.so" "$ENVROOT/build/gemrb/jni/libogg/" &&
+ ln -s "$ENVROOT/libogg-vorbis-android/jni/include/" "$ENVROOT/build/gemrb/jni/libogg/include" &&
+
+ # vorbis
+ cp "$ENVROOT/libogg-vorbis-android/libs/armeabi/libvorbis.so" "$ENVROOT/build/gemrb/jni/libvorbis/" &&
+ ln -s "$ENVROOT/libogg-vorbis-android/jni/include/" "$ENVROOT/build/gemrb/jni/libvorbis/include" &&
+ # those two are a little bit messy, because they both need their include directory
+ # this is because they can't both be defined as prebuilt libraries in the same makefile and directory,
+ # because that messes with makefile variables for some reason
+
+ # png
+ cp "$ENVROOT/libpng-android/obj/local/armeabi/libpng.a" "$ENVROOT/build/gemrb/jni/libpng/" &&
+ ln -s "$ENVROOT/libpng-android/jni/" "$ENVROOT/build/gemrb/jni/libpng/include" &&
+
+ # openal
+ cp "$ENVROOT/openal/android/libs/armeabi/libopenal.so" "$ENVROOT/build/gemrb/jni/openal/" &&
+ ln -s "$ENVROOT/openal/include" "$ENVROOT/build/gemrb/jni/openal/include" &&
+
+ # python
+ wget http://sourceforge.net/projects/gemrb/files/Other%20Binaries/android/libpython-2.6.2-pelya.tar.bz2 -O "$ENVROOT/libpython.tar" &&
+ tar -xf "$ENVROOT/libpython.tar" -C "$ENVROOT/build/gemrb/jni/" &&
+
+ echo -en "Done.\n"
+}
+
+function move_and_edit_projectfiles {
+ echo -en "Copying and editing files..."
+ mkdir -p "$ENVROOT/build/gemrb/src/net/sourceforge/gemrb/" &&
+
+ # copy the gemrb activity
+ cp "$ENVROOT/GemRB.java" "$ENVROOT/build/gemrb/src/net/sourceforge/gemrb/" &&
+
+ # copy the packaged config file
+ mkdir -p "$ENVROOT/build/gemrb/assets" &&
+ cp "$ENVROOT/packaged.GemRB.cfg" "$ENVROOT/build/gemrb/assets" &&
+
+ # copy the icons
+ cp "$GEMRB_GIT_PATH/artwork/gemrb-logo-glow-36px.png" "$ENVROOT/build/gemrb/res/drawable-ldpi/icon.png" &&
+ cp "$GEMRB_GIT_PATH/artwork/gemrb-logo-glow-48px.png" "$ENVROOT/build/gemrb/res/drawable-mdpi/icon.png" &&
+ cp "$GEMRB_GIT_PATH/artwork/gemrb-logo-glow-72px.png" "$ENVROOT/build/gemrb/res/drawable-hdpi/icon.png" &&
+
+ # copy the makefile
+ cp "$ENVROOT/GEMRB_Android.mk" "$ENVROOT/build/gemrb/jni/src/Android.mk" &&
+
+ # and the Application.mk
+ cp "$ENVROOT/GEMRB_Application.mk" "$ENVROOT/build/gemrb/jni/Application.mk" &&
+ echo -en "Done.\n" &&
+
+ # add the neccessary libraries to the base activity
+ echo -en "Performing neccessary edits...\n" &&
+ sed -i -e '/System.loadLibrary("SDL2")/ a\
+ System.loadLibrary("ogg"); \
+ System.loadLibrary("vorbis"); \
+ System.loadLibrary("openal"); \
+ System.loadLibrary("python");' "$ENVROOT/build/gemrb/src/org/libsdl/app/SDLActivity.java" &&
+
+ sed -i -e 's,sdlFormat = 0x8,sdlFormat = 0x1,g' "$ENVROOT/build/gemrb/src/org/libsdl/app/SDLActivity.java" &&
+
+ sed -i -e 's,SDL_app,GemRB,' "$ENVROOT/build/gemrb/jni/SDL/src/main/android/SDL_android_main.cpp" &&
+ sed -i -e 's,//exit,exit,' "$ENVROOT/build/gemrb/jni/SDL/src/main/android/SDL_android_main.cpp" &&
+
+ # change activity class and application name, as well as enable debuggable
+ sed -i -e s,org.libsdl.app,net.sourceforge.gemrb, "$ENVROOT/build/gemrb/AndroidManifest.xml" &&
+ sed -i -e s,SDLActivity,GemRB, "$ENVROOT/build/gemrb/AndroidManifest.xml" &&
+ sed -i -e '21 a\
+ android:debuggable="true"' "$ENVROOT/build/gemrb/AndroidManifest.xml" &&
+ sed -i -e s,SDL\ App,GemRB, build/gemrb/res/values/strings.xml &&
+
+ echo -en "Copying GemRB override, unhardcoded and GUIScripts folders..." &&
+ mkdir -p "$ENVROOT/build/gemrb/assets" &&
+ cp -r "$ENVROOT/build/gemrb/jni/src/main/gemrb/override" "$ENVROOT/build/gemrb/assets/" &&
+ cp -r "$ENVROOT/build/gemrb/jni/src/main/gemrb/unhardcoded" "$ENVROOT/build/gemrb/assets/" &&
+ cp -r "$ENVROOT/build/gemrb/jni/src/main/gemrb/GUIScripts" "$ENVROOT/build/gemrb/assets/" &&
+
+ echo -en "Done.\n"
+}
+
+function finished {
+ echo -en "That should be it, provided all the commands ran succesfully.\n\n" # TODO: Error checking beyond $1
+ echo -en "To build:\n"
+ echo -en " cd build/gemrb\n"
+ echo -en " ndk-build && ant debug\n\n"
+ echo -en "alternatively, for ndk-gdb debuggable builds: \n"
+ echo -en " cd build/gemrb\n"
+ echo -en " ndk-build NDK_DEBUG=1 && ant debug\n\n"
+ echo -en "The finished apk will be $ENVROOT/build/gemrb/bin/SDLActivity-debug.apk\n\n"
+}
+
+# Flow control starts here
+
+if [ -z "$1" ]
+then
+ echo -en "Error: No argument supplied.\n
+Usage:
+ $0 /absolute/path/to/gemrb/git\n"
+ exit 1
+fi
+
+setup_dir_struct &&
+move_and_edit_projectfiles &&
+build_deps &&
+move_libraries &&
+android update project -t android-17 -p "$ENVROOT/build/gemrb" &&
+finished || {
+echo 'Building failed!'
+exit 2
+}
diff --git a/apple/AppleLogger.h b/apple/AppleLogger.h
new file mode 100644
index 0000000..9784df2
--- /dev/null
+++ b/apple/AppleLogger.h
@@ -0,0 +1,40 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef LOGGER_APPLE_H
+#define LOGGER_APPLE_H
+
+#include "System/Logger/Stdio.h"
+
+namespace GemRB {
+
+class GEM_EXPORT AppleLogger : public StdioLogger {
+public:
+ AppleLogger();
+ virtual ~AppleLogger();
+
+ void textcolor(log_color);
+protected:
+ void LogInternal(log_level level, const char* owner, const char* message, log_color color);
+};
+
+Logger* createAppleLogger();
+
+}
+
+#endif
diff --git a/apple/AppleLogger.mm b/apple/AppleLogger.mm
new file mode 100644
index 0000000..74ce008
--- /dev/null
+++ b/apple/AppleLogger.mm
@@ -0,0 +1,75 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#if TARGET_OS_IPHONE
+#import <Uikit/UIAlertView.h>
+#elif TARGET_OS_MAC
+#import <Cocoa/Cocoa.h>
+#endif
+
+#include "AppleLogger.h"
+
+#include "System/Logging.h"
+
+namespace GemRB {
+/*
+TODO: override parent so we can use NSLog
+*/
+
+AppleLogger::AppleLogger()
+ : StdioLogger(false)
+{}
+
+AppleLogger::~AppleLogger()
+{}
+
+void AppleLogger::textcolor(log_color /*c*/)
+{}
+
+void AppleLogger::LogInternal(log_level level, const char* owner, const char* message, log_color color)
+{
+ if (level == FATAL) {
+ // display a GUI alert for FATAL errors
+ NSString* alertTitle = [NSString stringWithFormat:@"Fatal Error in %s", owner];
+ NSString* alertMessage = [NSString stringWithCString:message encoding:NSASCIIStringEncoding];
+#if TARGET_OS_IPHONE
+ UIAlertView *alert =
+ [[UIAlertView alloc] initWithTitle: alertTitle
+ message: alertMessage
+ delegate: nil
+ cancelButtonTitle: @"OK"
+ otherButtonTitles: nil];
+ [alert show];
+ while (alert.visible) {
+ [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
+ }
+ [alert release];
+#elif TARGET_OS_MAC
+ NSRunAlertPanel(alertTitle, alertMessage, @"OK", nil, nil);
+#endif
+ }
+
+ StdioLogger::LogInternal(level, owner, message, color);
+}
+
+Logger* createAppleLogger()
+{
+ return new AppleLogger();
+}
+
+}
diff --git a/apple/CocoaWrapper/ios/CocoaMain.m b/apple/CocoaWrapper/ios/CocoaMain.m
new file mode 100644
index 0000000..8574b9c
--- /dev/null
+++ b/apple/CocoaWrapper/ios/CocoaMain.m
@@ -0,0 +1,50 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include <Python.h>
+
+#import "GEM_AppDelegate.h"
+
+extern int SDL_main(int argc, char *argv[]);
+
+// use the SDL 1.3 build in wrapper for iOS
+int SDL_main (int __unused argc, char __unused **argv)
+{
+ /*
+ Consideration: we are currently getting argv and argc from cocoa process info and not using the ones passed here (they of course ought to be the same)
+ */
+
+
+ /*
+ Beware!: This relies on haveing a certain revision of SDL 1.3 or later.
+ Early revisions of 1.3 would call exit() when this method returns instad of leaving the runloop running for us.
+ GemRB used to hack its own runloop to workaround the issue, but that caused problems with the config editor
+ Now that SDL no longer exits and we are creating our own app delegate we can safely use this wrapper without hacks.
+
+ Also note this function never returns. exit is called after GemRB_main returns in the app delegate.
+ */
+
+ //do all the special plugin initializations here
+ Py_NoSiteFlag = 1;
+ //this mostly just supresses a benign console error
+ setenv("PYTHONHOME", "GUIScripts", 0);
+
+ return 0; //never actually returns.
+}
diff --git a/apple/CocoaWrapper/ios/GEM_AppDelegate.h b/apple/CocoaWrapper/ios/GEM_AppDelegate.h
new file mode 100644
index 0000000..f65676a
--- /dev/null
+++ b/apple/CocoaWrapper/ios/GEM_AppDelegate.h
@@ -0,0 +1,43 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2012 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#import <Foundation/Foundation.h>
+#import <SDL/uikit/SDL_uikitappdelegate.h>
+
+#import "GEM_ConfController.h"
+
+// make a category to force SDLUIKitDelegate to return our class name
+ at interface SDLUIKitDelegate (GemDelegate)
++ (NSString *)getAppDelegateClassName; //override this SDL method so an instance of our subclass is used
+ at end
+
+ at interface GEM_AppDelegate : SDLUIKitDelegate <GEM_ConfControllerDelegate>
+{
+ GEM_ConfController* confControl;
+
+ UIWindow* configWin;
+ NSArray* nibObjects;
+}
+ at property(readonly) GEM_ConfController* confControl;
+
+- (void)setupWrapper;
+- (void)runGemRB:(NSString*)configPath;
+- (void)toggleDebug:(id)sender;
+ at end
diff --git a/apple/CocoaWrapper/ios/GEM_AppDelegate.mm b/apple/CocoaWrapper/ios/GEM_AppDelegate.mm
new file mode 100644
index 0000000..f2622f1
--- /dev/null
+++ b/apple/CocoaWrapper/ios/GEM_AppDelegate.mm
@@ -0,0 +1,154 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2012 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#import "AppleLogger.h"
+#import "GEM_AppDelegate.h"
+#import "System/FileStream.h"
+#import "Interface.h"
+#import "System/Logger/File.h"
+
+using namespace GemRB;
+
+ at implementation SDLUIKitDelegate (GemDelegate)
++ (NSString *)getAppDelegateClassName
+{
+ //override this SDL method so an instance of our subclass is used
+ return @"GEM_AppDelegate";
+}
+ at end
+
+ at implementation GEM_AppDelegate
+ at synthesize confControl;
+
+// we MUST setup out wrapper interface here or iOS 5 will bitch about root view controller not being set
+// and our interface will be the wrong orientation and distorted
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
+{
+ // Normally you would call super implemetation first, but don't!
+ AddLogger(createAppleLogger());
+ [self setupWrapper];
+
+ return [super application:application didFinishLaunchingWithOptions:launchOptions];
+}
+
+- (void)setupWrapper
+{
+ configWin = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
+ configWin.backgroundColor = [UIColor blackColor];
+ confControl = [[GEM_ConfController alloc] init];
+ confControl.delegate = self;
+ nibObjects = nil;
+ // now load the config selector nib and display the list modally
+ if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+ nibObjects = [[NSBundle mainBundle] loadNibNamed:@"GEM_ConfController-ipad" owner:confControl options:nil];
+ } else {
+ nibObjects = [[NSBundle mainBundle] loadNibNamed:@"GEM_ConfController-iphone" owner:confControl options:nil];
+ }
+
+ confControl.rootVC.delegate = confControl;
+
+ [nibObjects retain];
+ configWin.rootViewController = confControl.rootVC;
+ configWin.screen = [UIScreen mainScreen];
+ [configWin makeKeyAndVisible]; // Note that this causes the window to be retained!
+}
+
+- (void)setupComplete:(NSString*)configPath
+{
+ [self runGemRB:configPath];
+}
+
+- (void)runGemRB:(NSString*)configPath
+{
+ int ret = GEM_OK;
+ if (configPath) {
+ NSLog(@"Using config file:%@", configPath);
+ // get argv
+ // manipulate argc & argv to have gemrb passed the argument for the config file to use.
+ NSMutableArray* procArguments = [[[NSProcessInfo processInfo] arguments] mutableCopy];
+ [procArguments addObject:@"-c"];
+ [procArguments addObject:configPath];
+
+ int argc = [procArguments count];
+ char** argv = (char**)malloc(argc * sizeof(char*));
+
+ int i = 0;
+ for (NSString* arg in procArguments) {
+ argv[i++] = (char*)[arg cStringUsingEncoding:NSASCIIStringEncoding];
+ }
+
+ [configWin resignKeyWindow];
+ configWin.rootViewController = nil;
+
+ [configWin release];
+ [nibObjects release];
+ [confControl release];
+ [procArguments release];
+
+ core = new Interface();
+ CFGConfig* config = new CFGConfig(argc, argv);
+ free(argv);
+ if ((ret = core->Init(config)) == GEM_ERROR) {
+ delete config;
+ delete( core );
+ Log(MESSAGE, "Cocoa Wrapper", "Unable to initialize core. Relaunching wraper.");
+ // reload the wrapper interface so we can try again instead of dying
+ [self setupWrapper];
+ } else {
+ // pass control to GemRB
+ delete config;
+ core->Main();
+ delete( core );
+ ShutdownLogging();
+ // We must exit since the application runloop never returns.
+ exit(ret);
+ }
+ }
+}
+
+- (void)toggleDebug:(id) __unused sender
+{
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+ NSString* logFile = [NSString stringWithFormat:@"%@/GemRB.log", [paths objectAtIndex:0]];
+ //OpenFile();
+ const char* cLogFile = [logFile cStringUsingEncoding:NSASCIIStringEncoding];
+ FileStream *fs = new FileStream();
+ if (fs->Create(cLogFile)) {
+ AddLogger(createFileLogger(fs));
+ Log(MESSAGE, "Cocoa Wrapper", "Started a log file at %s", cLogFile);
+ } else {
+ delete fs;
+ Log(ERROR, "Cocoa Wrapper", "Unable to start log file at %s", cLogFile);
+ }
+}
+
+- (void)dealloc
+{
+ // This is really just formallity.
+ // these objects would have been deallocated in runGemRB under normal circumstances
+
+ [configWin release];
+ [nibObjects release];
+ [confControl release];
+
+ [super dealloc];
+}
+
+ at end
diff --git a/apple/CocoaWrapper/ios/GEM_ConfController.h b/apple/CocoaWrapper/ios/GEM_ConfController.h
new file mode 100644
index 0000000..c949daa
--- /dev/null
+++ b/apple/CocoaWrapper/ios/GEM_ConfController.h
@@ -0,0 +1,78 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#import <UIKit/UIKit.h>
+
+ at protocol GEM_ConfControllerDelegate
+- (void)setupComplete:(NSString*)configPath;
+ at end
+
+ at interface GEM_NavController : UINavigationController {
+ at private
+}
+ at end
+
+ at interface GEM_ConfController : NSObject <UINavigationControllerDelegate>
+{
+ @private
+
+ NSString* docDir;
+ NSArray* configFiles;
+ NSArray* installFiles;
+ NSArray* installedGames;
+ NSArray* logFiles;
+
+ NSArray* toolBarItems;
+
+ NSIndexPath* configIndexPath;
+
+ UITextView* editor;
+ UITableView* controlTable;
+
+ UINavigationController* rootVC;
+ UIViewController* editorVC;
+
+ UIBarButtonItem* editorButton;
+ UIBarButtonItem* playButton;
+}
+ at property (nonatomic, retain) IBOutlet UITableView* controlTable;
+ at property (nonatomic, retain) NSIndexPath* configIndexPath;
+ at property (nonatomic, retain) IBOutlet UITextView* editor;
+ at property (nonatomic, retain) IBOutlet UINavigationController* rootVC;
+ at property (nonatomic, retain) IBOutlet UIViewController* editorVC;
+ at property (nonatomic, retain) IBOutlet UIBarButtonItem* playButton;
+ at property (nonatomic, retain) id delegate;
+
+- (void)reloadTableData;
+- (NSString*)selectedConfigPath;
+- (BOOL)installGame:(NSIndexPath*)indexPath;
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
+- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;
+- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath;
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
+
+- (IBAction)saveConfig:(id)sender;
+- (IBAction)launchGEM:(id)sender;
+
+- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
+ at end
diff --git a/apple/CocoaWrapper/ios/GEM_ConfController.m b/apple/CocoaWrapper/ios/GEM_ConfController.m
new file mode 100644
index 0000000..894f510
--- /dev/null
+++ b/apple/CocoaWrapper/ios/GEM_ConfController.m
@@ -0,0 +1,583 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#import "GEM_ConfController.h"
+
+#import <SDL/SDL.h>
+
+#include <archive.h>
+#include <archive_entry.h>
+
+#include <sys/stat.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+enum ConfigTableSection {
+ TABLE_SEC_CONFIG = 0,
+ TABLE_SEC_INSTALL = 1,
+ TABLE_SEC_LOG = 2
+ };
+
+ at implementation GEM_NavController
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation
+{
+ if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+ // Don't ask me why, but these need to be reversed to revent the screen from being upsidedown.
+ if (interfaceOrientation == UIDeviceOrientationLandscapeLeft)
+ SDL_SetHintWithPriority(SDL_HINT_ORIENTATIONS, "LandscapeRight", SDL_HINT_OVERRIDE);
+ else if (interfaceOrientation == UIDeviceOrientationLandscapeRight)
+ SDL_SetHintWithPriority(SDL_HINT_ORIENTATIONS, "LandscapeLeft", SDL_HINT_OVERRIDE);
+ return UIInterfaceOrientationIsLandscape(interfaceOrientation);
+ }else{
+ return UIInterfaceOrientationIsPortrait(interfaceOrientation);
+ }
+ return NO;
+}
+
+ at end
+
+ at implementation GEM_ConfController
+ at synthesize configIndexPath;
+ at synthesize editor;
+ at synthesize controlTable;
+ at synthesize rootVC;
+ at synthesize editorVC;
+ at synthesize playButton;
+ at synthesize delegate;
+
+- (id)init
+{
+ self = [super init];
+ if (self) {
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+ docDir = [[paths objectAtIndex:0] copy];
+
+ configFiles = nil;
+ installFiles = nil;
+ logFiles = nil;
+ configIndexPath = nil;
+ rootVC = nil;
+ editorVC = nil;
+
+ editorButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(saveConfig:)];
+ editorButton.style = UIBarButtonItemStyleDone;
+ editorButton.enabled = NO;
+
+ UIBarButtonItem* debugBtn = [[UIBarButtonItem alloc] initWithTitle:@"Debug" style:UIBarButtonItemStyleBordered target:self action:@selector(toggleDebug:)];
+
+ UIBarButtonItem* savesBtn = [[UIBarButtonItem alloc] initWithTitle:@"Saves" style:UIBarButtonItemStyleBordered target:self action:@selector(showSaves:)];
+
+ UIBarButtonItem* space = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
+
+ toolBarItems = [NSArray arrayWithObjects:debugBtn, savesBtn, space, editorButton, nil];
+ [debugBtn release];
+ [savesBtn release];
+ [space release];
+ [toolBarItems retain];
+
+ [self reloadTableData];
+ }
+ return self;
+}
+
+- (void)toggleDebug:(id) __unused sender
+{
+ [delegate toggleDebug:sender];
+}
+
+- (void)reloadTableData
+{
+ if (configFiles) [configFiles release];
+ if (installFiles) [installFiles release];
+ if (logFiles) [logFiles release];
+
+ NSFileManager *manager = [NSFileManager defaultManager];
+ NSArray* files = [manager contentsOfDirectoryAtPath:docDir error:nil];
+
+ NSLog(@"scanning documents: %@", [files description]);
+
+ configFiles = [files filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self ENDSWITH '.cfg'"]];
+ NSArray *installExtensions = [NSArray arrayWithObjects:@"bg1", @"bg2", @"iwd", @"how", @"iwd2", @"pst", nil];
+ installFiles = [files filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"pathExtension IN %@", installExtensions]];
+ logFiles = [files filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self ENDSWITH '.log'"]];
+
+ [configFiles retain];
+ [installFiles retain];
+ [logFiles retain];
+
+ [controlTable reloadData];
+}
+
+- (void)dealloc
+{
+ // cancel any pending requests to install game data
+ [NSObject cancelPreviousPerformRequestsWithTarget:self];
+
+ [docDir release];
+ [editorButton release];
+
+ [configFiles release];
+ [installFiles release];
+ [logFiles release];
+
+ [toolBarItems release];
+
+ [super dealloc];
+}
+
+- (void)navigationController:(UINavigationController *) __unused navigationController willShowViewController:(UIViewController *) __unused viewController animated:(BOOL) __unused animated
+{
+ rootVC.topViewController.toolbarItems = toolBarItems;
+}
+
+- (NSString*)selectedConfigPath
+{
+ if (!configIndexPath) return nil;
+ return [NSString stringWithFormat:@"%@/%@", docDir, [configFiles objectAtIndex:configIndexPath.row]];
+}
+
+- (BOOL)installGame:(NSIndexPath*)indexPath
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSString* archivePath = [installFiles objectAtIndex:indexPath.row];
+ NSString* srcPath = [NSString stringWithFormat:@"%@/%@", docDir, archivePath];
+
+ NSFileManager* fm = [NSFileManager defaultManager];
+
+ NSError* error = nil;
+ unsigned long long totalBytes = [[fm attributesOfItemAtPath:srcPath error:&error] fileSize];
+
+ if (error) {
+ NSLog(@"FM error for %@:\n%@", srcPath, [error localizedDescription]);
+ [pool release];
+ return NO;
+ }
+
+ UITableViewCell* selectedCell = [controlTable cellForRowAtIndexPath:indexPath];
+
+ UIProgressView* pv = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
+ UIView* contentView = selectedCell.contentView;
+ CGRect frame = CGRectMake(0.0, 0.0, contentView.frame.size.width, contentView.frame.size.height);
+ dispatch_async(dispatch_get_main_queue(), ^{
+ pv.frame = frame;
+ });
+ [contentView addSubview:pv];
+
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
+ NSString* libDir = [[paths objectAtIndex:0] copy];
+
+ NSString* dstPath = [NSString stringWithFormat:@"%@/%@/tmp/", libDir, [archivePath pathExtension]];
+ [fm createDirectoryAtPath:dstPath withIntermediateDirectories:YES attributes:nil error:nil];
+ NSLog(@"installing %@ to %@...", srcPath, dstPath);
+
+ struct archive *a;
+ const char* archiveAbsPath = [srcPath cStringUsingEncoding:NSASCIIStringEncoding];
+ a = archive_read_new();
+ archive_read_support_format_all(a);
+
+ struct archive *ext = archive_write_disk_new();
+ archive_write_disk_set_options(ext, 0);
+ archive_write_disk_set_standard_lookup(ext);
+ struct archive_entry *entry;
+
+ @try {
+ int r;
+ if ((r = archive_read_open_file(a, archiveAbsPath, 10240))) {
+ @throw ([NSException exceptionWithName:@"ArchiveException"
+ reason:[NSString stringWithFormat:@"Error opening archive (%i):%s",
+ r, archive_error_string(a)]
+ userInfo:nil]);
+ }
+ NSString* installName = nil;
+ BOOL archiveHasRootDir = YES;
+ unsigned long long progressSize = 0;
+ for (;;) {
+ r = archive_read_next_header(a, &entry);
+ if (r == ARCHIVE_EOF) break;
+ NSString* tmp = [NSString stringWithFormat:@"%s", archive_entry_pathname(entry)];
+ archive_entry_set_pathname(entry, [[dstPath stringByAppendingString:tmp] cStringUsingEncoding:NSASCIIStringEncoding]);
+ // Mac OS X has an annoying thing where it embeds crap in the archive. skip it.
+ if ([tmp rangeOfString:@"__MACOSX/"].location != NSNotFound) continue;
+ if (!installName) {
+ if ([tmp rangeOfString:@"/"].location != NSNotFound) {
+ installName = tmp;
+ } else {
+ archiveHasRootDir = NO;
+ }
+ } else if ([tmp rangeOfString:installName].location != 0) {
+ archiveHasRootDir = NO;
+ }
+
+ if (r != ARCHIVE_OK) {
+ NSLog(@"error reading archive (%i):%s", r, archive_error_string(a));
+ break;
+ }
+
+ r = archive_write_header(ext, entry);
+ if (r != ARCHIVE_OK)
+ NSLog(@"%s", archive_error_string(a));
+ else {
+ int status;
+ const void *buff;
+ size_t size;
+ off_t offset;
+
+ for (;;) {
+ status = archive_read_data_block(a, &buff, &size, &offset);
+ if (status == ARCHIVE_EOF) break;
+ if (status != ARCHIVE_OK) {
+ NSLog(@"%s", archive_error_string(a));
+ break;
+ }
+ progressSize += size;
+ status = archive_write_data_block(ext, buff, size, offset);
+ if (status != ARCHIVE_OK) {
+ NSLog(@"%s", archive_error_string(a));
+ break;
+ }
+ }
+
+ dispatch_async(dispatch_get_main_queue(), ^{
+ pv.progress = (float)((double)progressSize / (double)totalBytes);
+ });
+ }
+ }
+ // result from a break above
+ if (r == ARCHIVE_FATAL) {
+ @throw ([NSException exceptionWithName:@"Archive Error"
+ reason:[NSString stringWithFormat:@"Fatal error reading archive:%s", archive_error_string(a)]
+ userInfo:nil]);
+ }
+
+ installName = [installName lastPathComponent];
+ NSString* gamePath = [NSString stringWithFormat:@"%@/%@/%@/", libDir, [archivePath pathExtension], installName];
+ // delete anything at gamePath. our install overwrites existing data.
+ [fm removeItemAtPath:gamePath error:nil];
+ if (archiveHasRootDir) {
+ [fm moveItemAtPath:[NSString stringWithFormat:@"%@/%@/", dstPath, installName]
+ toPath:gamePath error:nil];
+ [fm removeItemAtPath:dstPath error:nil];
+ } else {
+ // simply rename the tmp dir to archivePath
+ installName = [archivePath stringByDeletingPathExtension];
+ [fm moveItemAtPath:dstPath toPath:gamePath error:nil];
+ }
+
+ NSString* savePath = [NSString stringWithFormat:@"%@/saves/%@/", libDir, [archivePath pathExtension]];
+ NSString* oldSavePath = [NSString stringWithFormat:@"%@save/", gamePath];
+ [fm createDirectoryAtPath:[NSString stringWithFormat:@"%@save/", savePath] withIntermediateDirectories:YES attributes:nil error:nil];
+ [fm createDirectoryAtPath:[NSString stringWithFormat:@"%@mpsave/", savePath] withIntermediateDirectories:YES attributes:nil error:nil];
+ [fm createDirectoryAtPath:[NSString stringWithFormat:@"%@/Caches/%@/", libDir, [archivePath pathExtension]] withIntermediateDirectories:YES attributes:nil error:nil];
+
+ NSLog(@"moving %@ to %@", oldSavePath, savePath);
+ NSArray* saves = [fm contentsOfDirectoryAtPath:oldSavePath error:nil];
+ for (NSString* saveName in saves) {
+ NSString* fullSavePath = [NSString stringWithFormat:@"%@save/%@", savePath, saveName];
+ [fm removeItemAtPath:fullSavePath error:nil];
+ [fm moveItemAtPath:[NSString stringWithFormat:@"%@/%@", oldSavePath, saveName] toPath:fullSavePath error:nil];
+ NSLog(@"Moving save '%@' to %@", saveName, fullSavePath);
+ }
+
+ oldSavePath = [NSString stringWithFormat:@"%@/mpsave/", gamePath];
+ saves = [fm contentsOfDirectoryAtPath:oldSavePath error:nil];
+
+ for (NSString* saveName in saves) {
+ NSString* fullSavePath = [NSString stringWithFormat:@"%@mpsave/%@", savePath, saveName];
+ [fm removeItemAtPath:fullSavePath error:nil];
+ [fm moveItemAtPath:[NSString stringWithFormat:@"%@/%@", oldSavePath, saveName] toPath:fullSavePath error:nil];
+ NSLog(@"Moving mpsave '%@' to %@", saveName, fullSavePath);
+ }
+
+ NSString* newCfgPath = [NSString stringWithFormat:@"%@/%@.%@.cfg", docDir, installName, [archivePath pathExtension]];
+
+ NSLog(@"Automatically creating config for %@ installed at %@ running on %i", [archivePath pathExtension], gamePath, [[UIDevice currentDevice] userInterfaceIdiom]);
+ NSMutableString* newConfig = [NSMutableString stringWithContentsOfFile:@"GemRB.cfg.newinstall" encoding:NSUTF8StringEncoding error:nil];
+ if ([fm fileExistsAtPath:newCfgPath]) {
+ if (configIndexPath) {
+ // close the config file before overwriting it.
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [controlTable deselectRowAtIndexPath:configIndexPath animated:YES];
+ [self tableView:controlTable didDeselectRowAtIndexPath:configIndexPath];
+ });
+ }
+ // new data overwrites old data therefore new config should do the same.
+ [fm removeItemAtPath:newCfgPath error:nil];
+ }
+ if (newConfig) {
+ [newConfig appendFormat:@"\nGameType = %@", [archivePath pathExtension]];
+ [newConfig appendFormat:@"\nGamePath = %@", [gamePath stringByReplacingOccurrencesOfString:libDir withString:@"../Library"]];
+ // No need for CD paths
+ [newConfig appendFormat:@"\nCachePath = ../Library/Caches/%@/", [archivePath pathExtension]];
+ [newConfig appendFormat:@"\nSavePath = %@", [savePath stringByReplacingOccurrencesOfString:libDir withString:@"../Library"]];
+
+ [newConfig appendString:@"\nCustomFontPath = ../Documents/"];
+
+ NSArray* minResGames = [NSArray arrayWithObjects:@"bg1", @"pst", @"iwd", nil];
+ if ([[NSPredicate predicateWithFormat:@"description IN[c] %@", minResGames] evaluateWithObject:[archivePath pathExtension]]) {
+ // PST & BG1 & IWD are 640x480 without mod
+ [newConfig appendString:@"\nWidth = 640"];
+ [newConfig appendString:@"\nHeight = 480"];
+ } else {
+ if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+ [newConfig appendString:@"\nWidth = 1024"];
+ [newConfig appendString:@"\nHeight = 768"];
+ }else{
+ [newConfig appendString:@"\nWidth = 800"];
+ [newConfig appendString:@"\nHeight = 600"];
+ }
+ }
+
+ NSError* err = nil;
+ if (![newConfig writeToFile:newCfgPath atomically:YES encoding:NSUTF8StringEncoding error:&err]){
+ NSLog(@"Unable to write config file:%@\nError:%@", newCfgPath, [err localizedDescription]);
+ }
+ }else{
+ NSLog(@"Unable to open GemRB.cfg.newinstall");
+ }
+ [pv removeFromSuperview];
+ [pv release];
+// dont delete the archive from simulator
+#if TARGET_IPHONE_SIMULATOR == 0
+ [fm removeItemAtPath:srcPath error:nil];
+#endif
+ }
+ @catch (NSException *exception) {
+ // TODO: present an alert box
+ NSLog(@"%@", exception);
+ return NO;
+ }
+ @finally {
+ archive_read_close(a);
+ archive_read_finish(a);
+ [libDir release];
+ [self reloadTableData];
+ [pool release];
+ }
+
+ return YES;
+}
+
+#pragma mark TableViewDatasource
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ static NSString *CellIdentifier = @"Cell";
+
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ if (cell == nil) {
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
+ }
+ switch (indexPath.section) {
+ case TABLE_SEC_CONFIG:
+ cell.textLabel.text = [configFiles count] ?
+ [configFiles objectAtIndex:indexPath.row] :
+ @"No config files found.";
+ break;
+ case TABLE_SEC_INSTALL:
+ cell.textLabel.text = [installFiles count] ?
+ [installFiles objectAtIndex:indexPath.row] :
+ @"No game files found";
+ break;
+ case TABLE_SEC_LOG:
+ cell.textLabel.text = [logFiles objectAtIndex:indexPath.row];
+ break;
+ }
+ return cell;
+}
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *) __unused tableView
+{
+ if (logFiles) return 3;
+ return 2;
+}
+
+- (NSInteger)tableView:(UITableView *) __unused tableView numberOfRowsInSection:(NSInteger)section
+{
+ switch(section)
+ {
+ case TABLE_SEC_CONFIG:
+ return [configFiles count] ?: 1;
+ case TABLE_SEC_INSTALL:
+ return [installFiles count] ?: 1;
+ case TABLE_SEC_LOG:
+ return [logFiles count];
+ }
+ return 0;
+}
+
+- (NSString *)tableView:(UITableView *) __unused tableView titleForHeaderInSection:(NSInteger)section
+{
+ switch(section)
+ {
+ case TABLE_SEC_CONFIG:
+ return @"Select a configuration file.";
+ case TABLE_SEC_INSTALL:
+ return @"Install a game.";
+ case TABLE_SEC_LOG:
+ if ([logFiles count])
+ return @"View a debug run log.";
+ }
+ return nil;
+}
+
+- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ switch (indexPath.section) {
+ case TABLE_SEC_CONFIG:
+ [editor resignFirstResponder];
+ [tableView cellForRowAtIndexPath:configIndexPath].accessoryType = UITableViewCellAccessoryNone;
+ playButton.enabled = NO;
+ editorButton.enabled = NO;
+ editor.editable = NO;
+ editor.text = @"";
+ break;
+ }
+}
+
+- (void)tableView:(UITableView *) tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ UITableViewCell* selectedCell = [tableView cellForRowAtIndexPath:indexPath];
+ [tableView deselectRowAtIndexPath:indexPath animated:YES];
+ [self tableView:tableView didDeselectRowAtIndexPath:indexPath];
+ switch (indexPath.section) {
+ case TABLE_SEC_CONFIG:
+ if ([configFiles count] == 0) return;
+
+ selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
+ selectedCell.highlighted = NO;
+
+ self.configIndexPath = indexPath;
+ self.editor.text = [NSString stringWithContentsOfFile:[self selectedConfigPath] encoding:NSUTF8StringEncoding error:nil];
+ if (![editor becomeFirstResponder]){
+ NSLog(@"cannot set first responder");
+ }
+
+ editor.editable = YES;
+ editorButton.enabled = YES;
+ playButton.enabled = YES;
+ if (editorVC != nil){
+ editorVC.navigationItem.rightBarButtonItem = editorButton;
+ [editorVC setTitle: [configFiles objectAtIndex:configIndexPath.row]];
+ [rootVC pushViewController:editorVC animated:YES];
+ }
+
+ break;
+ case TABLE_SEC_INSTALL:
+ if ([installFiles count] == 0) return;
+ [self performSelectorInBackground:@selector(installGame:) withObject:indexPath];
+ break;
+ case TABLE_SEC_LOG:
+ self.editor.text = [NSString stringWithContentsOfFile:[docDir stringByAppendingFormat:@"/%@", [logFiles objectAtIndex:indexPath.row]] encoding:NSUTF8StringEncoding error:nil];
+ if (editorVC != nil){
+ editorVC.navigationItem.rightBarButtonItem = editorButton;
+ [editorVC setTitle: [configFiles objectAtIndex:configIndexPath.row]];
+ [rootVC pushViewController:editorVC animated:YES];
+ }
+ break;
+ }
+}
+
+- (void)tableView:(UITableView *) tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ if (editingStyle == UITableViewCellEditingStyleInsert) return;
+
+ NSFileManager* fm = [NSFileManager defaultManager];
+ switch (indexPath.section) {
+ case TABLE_SEC_CONFIG:
+ // check if the config file we are deleting is currently selected and deselect it
+ if (tableView.indexPathForSelectedRow.row == indexPath.row) {
+ [tableView deselectRowAtIndexPath:indexPath animated:YES];
+ [self tableView:tableView didDeselectRowAtIndexPath:indexPath];
+ }
+ if (configIndexPath.row == indexPath.row) {
+ [controlTable deselectRowAtIndexPath:configIndexPath animated:YES];
+ [self tableView:controlTable didDeselectRowAtIndexPath:configIndexPath];
+ }
+ [fm removeItemAtPath:[NSString stringWithFormat:@"%@/%@", docDir, [configFiles objectAtIndex:indexPath.row]] error:nil];
+ break;
+ case TABLE_SEC_INSTALL:
+ [fm removeItemAtPath:[NSString stringWithFormat:@"%@/%@", docDir, [installFiles objectAtIndex:indexPath.row]] error:nil];
+ break;
+ case TABLE_SEC_LOG:
+ [fm removeItemAtPath:[NSString stringWithFormat:@"%@/%@", docDir, [logFiles objectAtIndex:indexPath.row]] error:nil];
+ break;
+ }
+ [self reloadTableData];
+}
+
+- (BOOL)tableView:(UITableView *) __unused tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ switch (indexPath.section) {
+ case TABLE_SEC_CONFIG:
+ return (BOOL)[configFiles count];
+ case TABLE_SEC_INSTALL:
+ return (BOOL)[installFiles count];
+ case TABLE_SEC_LOG:
+ return (BOOL)[logFiles count];
+ }
+ return NO;
+}
+
+- (IBAction)saveConfig:(id) __unused sender
+{
+ if (editorVC)[rootVC popViewControllerAnimated:YES];
+ if (editor.editable)
+ [editor.text writeToFile:[self selectedConfigPath] atomically:YES encoding:NSUTF8StringEncoding error:nil];
+}
+
+- (IBAction)launchGEM:(id) __unused sender
+{
+ /*
+ Ensure a few things about starting GemRB:
+ 1. ensure GemRB_main is called from the main thread.
+ 2. ensure we won't return here since this will be deallocated
+ 3. ensure we have dropped back to the main runloop so autoreleased objects are disposed of
+ bonus: the call stack is significantly reduced this way
+ */
+
+ // SDL disables the event pump after SDL_main returns because normally SDL_main houses the application event loop
+ // GemRB is diffrent and our wrapper interface makes that impossible.
+ SDL_iPhoneSetEventPump(SDL_TRUE);
+
+ [[self delegate] performSelectorOnMainThread:@selector(setupComplete:) withObject:[self selectedConfigPath] waitUntilDone:NO];
+}
+
+- (void)textViewDidBeginEditing:(UITextView *)textView
+{
+ [UIApplication sharedApplication].keyWindow.backgroundColor = [UIColor whiteColor];
+ [UIView animateWithDuration:0.5 animations:^{
+ CGRect frame = textView.frame;
+ frame.size.height -= 300;
+ textView.frame = frame;
+ }];
+}
+
+- (void)textViewDidEndEditing:(UITextView *)textView
+{
+ [UIView animateWithDuration:0.25 animations:^{
+ CGRect frame = textView.frame;
+ frame.size.height += 300;
+ textView.frame = frame;
+ }];
+ [UIApplication sharedApplication].keyWindow.backgroundColor = [UIColor blackColor];
+}
+
+ at end
diff --git a/apple/CocoaWrapper/ios/GEM_SDL_Keyboard.m b/apple/CocoaWrapper/ios/GEM_SDL_Keyboard.m
new file mode 100644
index 0000000..b6f91ed
--- /dev/null
+++ b/apple/CocoaWrapper/ios/GEM_SDL_Keyboard.m
@@ -0,0 +1,202 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#import <QuartzCore/QuartzCore.h>
+#import <SDL.h>
+#import <UIKit/UIKit.h>
+
+#include <SDL/SDL_keyboard_c.h>
+
+#pragma mark UIKit button subclasses
+ at interface GEM_UIKit_RoundedButton : UIButton
+{}
+ at end
+
+ at implementation GEM_UIKit_RoundedButton
+
+- (id)initWithFrame:(CGRect)frame
+{
+ self = [super initWithFrame:frame];
+ if (self) {
+ //custom drawing
+ self.backgroundColor = [UIColor colorWithRed:0.196 green:0.3098 blue:0.52 alpha:1.0];
+ self.titleLabel.textColor = [UIColor darkTextColor];
+ self.titleLabel.font = [UIFont systemFontOfSize:24];
+ self.layer.cornerRadius = 10;
+ self.layer.borderWidth = 2;
+ self.layer.borderColor = [UIColor grayColor].CGColor;
+ self.clipsToBounds = YES;
+ }
+ return self;
+}
+
+ at end
+
+ at interface SDL_UIKit_ModifierKeyButton : GEM_UIKit_RoundedButton {
+ at private
+ SDL_Keymod _modifierKey;
+}
+ at property(nonatomic, assign, getter = modifierKey, setter = setModifierKey:) SDL_Keymod _modifierKey;
+
+- (void)toggleModifier;
+ at end
+
+ at implementation SDL_UIKit_ModifierKeyButton
+ at synthesize _modifierKey;
+
+- (id)initWithFrame:(CGRect)frame
+{
+ self = [super initWithFrame:frame];
+ if (self) {
+ _modifierKey = KMOD_NONE;
+ [self setSelected:NO];
+ [self addTarget:self action:@selector(toggleModifier) forControlEvents:UIControlEventTouchDown];
+ }
+ return self;
+}
+
+- (BOOL)selected
+{
+ return (BOOL)(SDL_GetModState() & _modifierKey);
+}
+
+- (void)setSelected:(BOOL)selected
+{
+ [super setSelected:selected];
+ if (selected){
+ SDL_SetModState(SDL_GetModState() | _modifierKey);
+ self.backgroundColor = [UIColor colorWithRed:0.196 green:0.3098 blue:0.52 alpha:1.0];
+ }else{
+ SDL_SetModState(SDL_GetModState() & ~_modifierKey);
+ self.backgroundColor = [UIColor colorWithRed:0.196 green:0.3098 blue:0.52 alpha:0.25];
+ }
+}
+
+- (void)toggleModifier
+{
+ [self setSelected:!self.selected];
+}
+
+ at end
+
+ at interface SDL_UIKit_KeyButton : GEM_UIKit_RoundedButton {
+ at private
+ SDL_Scancode _keyCode;
+}
+ at property(nonatomic, assign, getter = keyCode, setter = setKeyCode:) SDL_Scancode _keyCode;
+
+- (void)sendKey;
+ at end
+
+ at implementation SDL_UIKit_KeyButton
+ at synthesize _keyCode;
+
+- (id)initWithFrame:(CGRect)frame
+{
+ self = [super initWithFrame:frame];
+ if (self) {
+ _keyCode = SDL_SCANCODE_UNKNOWN;
+ [self addTarget:self action:@selector(sendKey) forControlEvents:UIControlEventTouchDown];
+ }
+ return self;
+}
+
+- (void)sendKey
+{
+ //send both press and release
+ SDL_SendKeyboardKey(SDL_PRESSED, _keyCode);
+ SDL_SendKeyboardKey(SDL_RELEASED, _keyCode);
+}
+
+ at end
+
+#pragma mark end button subclasses
+// need a custom accessory view for the keybaord (for ctrl key modifier)
+ at interface SDL_UIKIT_KBoardAccessoryView : UIView
+{}
+- (void)willMoveToWindow:(UIWindow *)newWindow;
+ at end
+
+ at implementation SDL_UIKIT_KBoardAccessoryView
+
+- (id) initWithFrame:(CGRect)frame
+{
+ self = [super initWithFrame:frame];
+ if (self){
+ self.backgroundColor = [UIColor colorWithRed:138.0/255.0 green:139.0/255.0 blue:147.0/255.0 alpha:1.0];
+ }
+ return self;
+}
+
+- (void)willMoveToWindow:(UIWindow *)newWindow
+{
+ // newWindow is the window with the soft keybord
+ [super willMoveToWindow:newWindow];
+ newWindow.alpha = 0.60;
+}
+
+ at end
+
+ at interface UITextField (KeyboardAccesory)
+-(UIView *)inputAccessoryView;// override UIKit and force our own
+ at end
+
+ at implementation UITextField (KeyboardAccesory)
+- (UIView *)inputAccessoryView
+{
+ static SDL_UIKIT_KBoardAccessoryView* accessoryView = nil;
+ if (!accessoryView){
+ CGRect accessFrame = CGRectMake(0.0, 0.0, [UIScreen mainScreen].bounds.size.width, 77.0);
+ accessoryView = [[SDL_UIKIT_KBoardAccessoryView alloc] initWithFrame:accessFrame];
+
+ CGFloat xSpacing = 20.0;
+ CGFloat width = 120.0;
+ CGFloat xPos = xSpacing;
+ //ctrl key
+ SDL_UIKit_ModifierKeyButton *ctrlButton = [[SDL_UIKit_ModifierKeyButton alloc] initWithFrame:CGRectMake(xPos, 20.0, width, 40.0)];
+ ctrlButton.modifierKey = KMOD_CTRL;
+ [ctrlButton setTitle: @"Ctrl" forState:UIControlStateNormal];
+ [accessoryView addSubview:ctrlButton];
+ [ctrlButton release];
+ //alt key
+ xPos += xSpacing + width;
+ SDL_UIKit_ModifierKeyButton *altButton = [[SDL_UIKit_ModifierKeyButton alloc] initWithFrame:CGRectMake(xPos, 20.0, width, 40.0)];
+ altButton.modifierKey = KMOD_ALT;
+ [altButton setTitle: @"Alt" forState:UIControlStateNormal];
+ [accessoryView addSubview:altButton];
+ [altButton release];
+ //pgUp key
+ xPos += xSpacing + width;
+ SDL_UIKit_KeyButton *pgKey = [[SDL_UIKit_KeyButton alloc] initWithFrame:CGRectMake(xPos, 20.0, width, 40.0)];
+ pgKey.keyCode = SDL_SCANCODE_PAGEUP;
+ [pgKey setTitle: @"PgUp" forState:UIControlStateNormal];
+ [accessoryView addSubview:pgKey];
+ [pgKey release];
+ //pgDown key
+ xPos += xSpacing + width;
+ pgKey = [[SDL_UIKit_KeyButton alloc] initWithFrame:CGRectMake(xPos, 20.0, width, 40.0)];
+ pgKey.keyCode = SDL_SCANCODE_PAGEDOWN;
+ [pgKey setTitle: @"PgDown" forState:UIControlStateNormal];
+ [accessoryView addSubview:pgKey];
+ [pgKey release];
+ }
+ return accessoryView;
+}
+ at end
diff --git a/apple/CocoaWrapper/ios/nibs/GEM_ConfController-ipad.xib b/apple/CocoaWrapper/ios/nibs/GEM_ConfController-ipad.xib
new file mode 100644
index 0000000..b58b37b
--- /dev/null
+++ b/apple/CocoaWrapper/ios/nibs/GEM_ConfController-ipad.xib
@@ -0,0 +1,455 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="8.00">
+ <data>
+ <int key="IBDocument.SystemTarget">1280</int>
+ <string key="IBDocument.SystemVersion">11C74</string>
+ <string key="IBDocument.InterfaceBuilderVersion">1938</string>
+ <string key="IBDocument.AppKitVersion">1138.23</string>
+ <string key="IBDocument.HIToolboxVersion">567.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="NS.object.0">933</string>
+ </object>
+ <array key="IBDocument.IntegratedClassDependencies">
+ <string>IBProxyObject</string>
+ <string>IBUINavigationController</string>
+ <string>IBUIViewController</string>
+ <string>IBUIToolbar</string>
+ <string>IBUIBarButtonItem</string>
+ <string>IBUINavigationBar</string>
+ <string>IBUINavigationItem</string>
+ <string>IBUITextView</string>
+ <string>IBUITableView</string>
+ <string>IBUIView</string>
+ </array>
+ <array key="IBDocument.PluginDependencies">
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </array>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+ <integer value="1" key="NS.object.0"/>
+ </object>
+ <array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <object class="IBProxyObject" id="841351856">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBProxyObject" id="606714003">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBUINavigationController" id="532387919">
+ <object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics">
+ <int key="IBUIStatusBarStyle">2</int>
+ </object>
+ <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
+ <int key="IBUIInterfaceOrientation">3</int>
+ <int key="interfaceOrientation">3</int>
+ </object>
+ <object class="IBUIScreenMetrics" key="IBUISimulatedDestinationMetrics">
+ <string key="IBUISimulatedSizeMetricsClass">IBUIScreenMetrics</string>
+ <object class="NSMutableDictionary" key="IBUINormalizedOrientationToSizeMap">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <array key="dict.sortedKeys">
+ <integer value="1"/>
+ <integer value="3"/>
+ </array>
+ <array class="NSMutableArray" key="dict.values">
+ <string>{768, 1024}</string>
+ <string>{1024, 768}</string>
+ </array>
+ </object>
+ <string key="IBUITargetRuntime">IBIPadFramework</string>
+ <string key="IBUIDisplayName">iPad Full Screen</string>
+ </object>
+ <bool key="IBUIDefinesPresentationContext">YES</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <bool key="IBUIHorizontal">YES</bool>
+ <object class="IBUINavigationBar" key="IBUINavigationBar" id="918869189">
+ <nil key="NSNextResponder"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrameSize">{0, 0}</string>
+ <string key="NSReuseIdentifierKey">_NS:453</string>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <bool key="IBUIMultipleTouchEnabled">YES</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBUIToolbar" key="IBUIToolbar" id="710968057">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrame">{{0, 724}, {1024, 44}}</string>
+ <reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <int key="IBUIContentMode">4</int>
+ <bool key="IBUIMultipleTouchEnabled">YES</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <array class="NSMutableArray" key="IBUIViewControllers">
+ <object class="IBUIViewController" id="224149362">
+ <object class="IBUIView" key="IBUIView" id="275569777">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">274</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="IBUITableView" id="18413225">
+ <reference key="NSNextResponder" ref="275569777"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrameSize">{409, 660}</string>
+ <reference key="NSSuperview" ref="275569777"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="174553469"/>
+ <string key="NSReuseIdentifierKey">_NS:408</string>
+ <object class="NSColor" key="IBUIBackgroundColor" id="12459784">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MCAwIDAgMAA</bytes>
+ </object>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <bool key="IBUIBounces">NO</bool>
+ <int key="IBUIStyle">1</int>
+ <int key="IBUISeparatorStyle">2</int>
+ <int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
+ <bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
+ <float key="IBUIRowHeight">44</float>
+ <float key="IBUISectionHeaderHeight">10</float>
+ <float key="IBUISectionFooterHeight">10</float>
+ </object>
+ <object class="IBUITextView" id="174553469">
+ <reference key="NSNextResponder" ref="275569777"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrame">{{409, 0}, {615, 660}}</string>
+ <reference key="NSSuperview" ref="275569777"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="710968057"/>
+ <string key="NSReuseIdentifierKey">_NS:640</string>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MSAxIDEAA</bytes>
+ </object>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <bool key="IBUIMultipleTouchEnabled">YES</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <bool key="IBUIAlwaysBounceVertical">YES</bool>
+ <bool key="IBUIEditable">NO</bool>
+ <object class="NSMutableString" key="IBUIText">
+ <bytes key="NS.bytes">V2VsY29tZSB0byBHZW1SQiBmb3IgaU9TLgoKSG93IHRvIGxvYWQgZ2FtZXM6CnNpbXBseSB6aXAgeW91
+ciBJbmZpbml0eSBFbmdpbmUgZ2FtZShzKSBvZiBjaG9pY2UgYW5kIHJlbmFtZSB0aGUgemlwIGV4dGVu
+c2lvbiB0byB0aGUgIkdhbWVUeXBlIiAoYmcxLCBiZzIsIHBzdCwgZXRjKSBvZiB0aGUgZ2FtZS4gVGhl
+biB1c2UgaVR1bmVzIEZpbGUgU2hhcmluZyB0byBsb2FkIHRoZW0gaW50byBHZW1SQi4gWW91IHdpbGwg
+bmVlZCB0aGUgc2l6ZSBvZiB0aGUgemlwICsgc2l6ZSBvZiB0aGUgdW5jb21wcmVzc2VkIGRhdGEgdG8g
+aW5zdGFsbCwgYnV0IG9uY2UgaW5zdGFsbGVkIHRoZSB6aXAgd2lsbCBiZSByZW1vdmVkLiBPbmNlIHRy
+YW5zZmVyZWQgbGF1bmNoIEdlbVJCIGFuZCB5b3Ugc2hvdWxkIHNlZSB0aGUgemlwIGxpc3RlZCB1bmRl
+ciAiSW5zdGFsbCBHYW1lIEZpbGVzIi4gVGFwIHRoZSBHYW1lKHMpIHlvdSB3aXNoIHRvIGluc3RhbGwg
+YW5kIHdhaXQgZm9yIHRoZW0gdG8gZmluaXNoIGluc3RhbGxpbmcuIE9uY2UgdGhleSBhcmUgZG9uZSBh
+IGNvbmZpZ3VyYXRpb24gZmlsZSBmb3IgZWFjaCBpbnN0YWxsZWQgZ2FtZSB3aWxsIGJlIGF1dG9tYXRp
+Y2FsbHkgY3JlYXRlZCB3aXRoIHRoZSBjb3JyZWN0IHBhdGhzLiBJZiBuZWVkZWQvZGVzaXJlZCwgeW91
+IG1heSBlZGl0IHRoZSBjb29uZmlndXJhdGlvbiBmaWxlIGJ5IHNlbGVjdGluZyBpdCBpbiB0aGUgbGlz
+dCBhbmQgaXQgd2lsbCBiZSBsb2FkZWQgaW50byB0aGlzIHRleHQgZWRpdG9yLiBPbmNlIHlvdSBoYXZl
+IHRoZSBjb25maWd1cmF0aW9uIHNldCB0aGUgd2F5IHlvdSB3YW50IG1ha2Ugc3VyZSBpdCBpcyBzZWxl
+Y3RlZCAoaXQgd2lsIGhhdmUgYSBjaGVja21hcmsgbmV4dCB0byBpdCkgdGhlbiB0YXAgIlBsYXkiLgoK
+RGVidWcgbW9kZSBpcyBsYXJnZWx5IHVudGVzdGVkLiB5b3Ugc2hvdWxkbnQgbmVlZCBpdC4gQWxsIGl0
+IGRvZXMgaXMgcmVkaXJlY3QgdGhlIGNvbnNvbGUgb3V0cHV0IHRvIGEgZmlsZSB0aGF0IHlvdSB3aWxs
+IGJlIGFibGUgdG8gdmlldyB1cG9uIHlvdXIgbmV4dCBydW4gb3IgYnkgZG93bmxvYWRpbmcgZnJvbSBp
+VHVuZXMuCgpTYXZlIGdhbWUgbWFuYWdlbWVudCBET0VTIE5PVCBXT1JLIGF0IHRoaXMgdGltZS4gVHJ5
+aW5nIHRvIHVzZSBpdCBXSUxMIHJlc3VsdCBpbiBhIGNyYXNoIQ</bytes>
+ </object>
+ <object class="IBUITextInputTraits" key="IBUITextInputTraits">
+ <int key="IBUIAutocorrectionType">1</int>
+ <int key="IBUIKeyboardType">1</int>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBUIFontDescription" key="IBUIFontDescription">
+ <int key="type">1</int>
+ <double key="pointSize">14</double>
+ </object>
+ <object class="NSFont" key="IBUIFont">
+ <string key="NSName">Helvetica</string>
+ <double key="NSSize">14</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ </object>
+ </array>
+ <string key="NSFrame">{{0, 64}, {1024, 660}}</string>
+ <reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="18413225"/>
+ <string key="NSReuseIdentifierKey">_NS:212</string>
+ <reference key="IBUIBackgroundColor" ref="12459784"/>
+ <bool key="IBUIAutoresizesSubviews">NO</bool>
+ <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
+ <int key="IBUIInterfaceOrientation">3</int>
+ <int key="interfaceOrientation">3</int>
+ </object>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBUINavigationItem" key="IBUINavigationItem" id="441117407">
+ <reference key="IBUINavigationBar"/>
+ <string key="IBUITitle">GemRB</string>
+ <object class="IBUIBarButtonItem" key="IBUIRightBarButtonItem" id="327708032">
+ <bool key="IBUIEnabled">NO</bool>
+ <string key="IBUITitle">Play</string>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <int key="IBUIStyle">2</int>
+ <reference key="IBUINavigationItem" ref="441117407"/>
+ </object>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <reference key="IBUIParentViewController" ref="532387919"/>
+ <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
+ <int key="IBUIInterfaceOrientation">1</int>
+ <int key="interfaceOrientation">1</int>
+ </object>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <bool key="IBUIHorizontal">NO</bool>
+ </object>
+ </array>
+ <bool key="IBUIToolbarHidden">NO</bool>
+ </object>
+ </array>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <array class="NSMutableArray" key="connectionRecords">
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">rootVC</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="532387919"/>
+ </object>
+ <int key="connectionID">61</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">editor</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="174553469"/>
+ </object>
+ <int key="connectionID">53</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">controlTable</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="18413225"/>
+ </object>
+ <int key="connectionID">54</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">playButton</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="327708032"/>
+ </object>
+ <int key="connectionID">74</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="18413225"/>
+ <reference key="destination" ref="841351856"/>
+ </object>
+ <int key="connectionID">49</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">dataSource</string>
+ <reference key="source" ref="18413225"/>
+ <reference key="destination" ref="841351856"/>
+ </object>
+ <int key="connectionID">50</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="174553469"/>
+ <reference key="destination" ref="841351856"/>
+ </object>
+ <int key="connectionID">73</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">launchGEM:</string>
+ <reference key="source" ref="327708032"/>
+ <reference key="destination" ref="841351856"/>
+ </object>
+ <int key="connectionID">60</int>
+ </object>
+ </array>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <array key="orderedObjects">
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <array key="object" id="0"/>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="841351856"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="606714003"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">55</int>
+ <reference key="object" ref="532387919"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="918869189"/>
+ <reference ref="224149362"/>
+ <reference ref="710968057"/>
+ </array>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">56</int>
+ <reference key="object" ref="918869189"/>
+ <reference key="parent" ref="532387919"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">57</int>
+ <reference key="object" ref="224149362"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="441117407"/>
+ <reference ref="275569777"/>
+ </array>
+ <reference key="parent" ref="532387919"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">58</int>
+ <reference key="object" ref="441117407"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="327708032"/>
+ </array>
+ <reference key="parent" ref="224149362"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">62</int>
+ <reference key="object" ref="710968057"/>
+ <reference key="parent" ref="532387919"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">59</int>
+ <reference key="object" ref="327708032"/>
+ <reference key="parent" ref="441117407"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">37</int>
+ <reference key="object" ref="275569777"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="18413225"/>
+ <reference ref="174553469"/>
+ </array>
+ <reference key="parent" ref="224149362"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">42</int>
+ <reference key="object" ref="174553469"/>
+ <reference key="parent" ref="275569777"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">41</int>
+ <reference key="object" ref="18413225"/>
+ <reference key="parent" ref="275569777"/>
+ </object>
+ </array>
+ </object>
+ <dictionary class="NSMutableDictionary" key="flattenedProperties">
+ <string key="-1.CustomClassName">GEM_ConfController</string>
+ <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="-2.CustomClassName">UIResponder</string>
+ <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="37.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="41.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="42.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="55.CustomClassName">GEM_NavController</string>
+ <string key="55.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="56.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="57.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="58.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="59.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="62.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+ <nil key="activeLocalization"/>
+ <dictionary class="NSMutableDictionary" key="localizations"/>
+ <nil key="sourceID"/>
+ <int key="maxID">74</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <array class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <object class="IBPartialClassDescription">
+ <string key="className">GEM_ConfController</string>
+ <string key="superclassName">NSObject</string>
+ <dictionary class="NSMutableDictionary" key="actions">
+ <string key="launchGEM:">id</string>
+ <string key="saveConfig:">id</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="actionInfosByName">
+ <object class="IBActionInfo" key="launchGEM:">
+ <string key="name">launchGEM:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo" key="saveConfig:">
+ <string key="name">saveConfig:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="outlets">
+ <string key="controlTable">UITableView</string>
+ <string key="editor">UITextView</string>
+ <string key="editorVC">UIViewController</string>
+ <string key="playButton">UIBarButtonItem</string>
+ <string key="rootVC">UINavigationController</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <object class="IBToOneOutletInfo" key="controlTable">
+ <string key="name">controlTable</string>
+ <string key="candidateClassName">UITableView</string>
+ </object>
+ <object class="IBToOneOutletInfo" key="editor">
+ <string key="name">editor</string>
+ <string key="candidateClassName">UITextView</string>
+ </object>
+ <object class="IBToOneOutletInfo" key="editorVC">
+ <string key="name">editorVC</string>
+ <string key="candidateClassName">UIViewController</string>
+ </object>
+ <object class="IBToOneOutletInfo" key="playButton">
+ <string key="name">playButton</string>
+ <string key="candidateClassName">UIBarButtonItem</string>
+ </object>
+ <object class="IBToOneOutletInfo" key="rootVC">
+ <string key="name">rootVC</string>
+ <string key="candidateClassName">UINavigationController</string>
+ </object>
+ </dictionary>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/GEM_ConfController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">GEM_NavController</string>
+ <string key="superclassName">UINavigationController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/GEM_NavController.h</string>
+ </object>
+ </object>
+ </array>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBIPadFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+ <real value="4200" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <string key="IBCocoaTouchPluginVersion">933</string>
+ </data>
+</archive>
diff --git a/apple/CocoaWrapper/ios/nibs/GEM_ConfController-iphone.xib b/apple/CocoaWrapper/ios/nibs/GEM_ConfController-iphone.xib
new file mode 100644
index 0000000..7bf16b7
--- /dev/null
+++ b/apple/CocoaWrapper/ios/nibs/GEM_ConfController-iphone.xib
@@ -0,0 +1,415 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="8.00">
+ <data>
+ <int key="IBDocument.SystemTarget">1280</int>
+ <string key="IBDocument.SystemVersion">11C74</string>
+ <string key="IBDocument.InterfaceBuilderVersion">1938</string>
+ <string key="IBDocument.AppKitVersion">1138.23</string>
+ <string key="IBDocument.HIToolboxVersion">567.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="NS.object.0">933</string>
+ </object>
+ <array key="IBDocument.IntegratedClassDependencies">
+ <string>IBProxyObject</string>
+ <string>IBUINavigationController</string>
+ <string>IBUIViewController</string>
+ <string>IBUIBarButtonItem</string>
+ <string>IBUINavigationBar</string>
+ <string>IBUINavigationItem</string>
+ <string>IBUITableView</string>
+ <string>IBUITextView</string>
+ </array>
+ <array key="IBDocument.PluginDependencies">
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </array>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+ <integer value="1" key="NS.object.0"/>
+ </object>
+ <array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <object class="IBProxyObject" id="841351856">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBProxyObject" id="606714003">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBUIViewController" id="1015082547">
+ <object class="IBUITextView" key="IBUIView" id="1030036642">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrameSize">{768, 960}</string>
+ <reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
+ <string key="NSReuseIdentifierKey">_NS:640</string>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MSAxIDEAA</bytes>
+ </object>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <bool key="IBUIMultipleTouchEnabled">YES</bool>
+ <object class="IBUISimulatedNavigationBarMetrics" key="IBUISimulatedTopBarMetrics">
+ <bool key="IBUIPrompted">NO</bool>
+ </object>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <bool key="IBUIAlwaysBounceVertical">YES</bool>
+ <bool key="IBUIShowsHorizontalScrollIndicator">NO</bool>
+ <bool key="IBUIDelaysContentTouches">NO</bool>
+ <bool key="IBUICanCancelContentTouches">NO</bool>
+ <string key="IBUIText">Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. [...]
+ <object class="IBUITextInputTraits" key="IBUITextInputTraits">
+ <int key="IBUIAutocapitalizationType">2</int>
+ <int key="IBUIAutocorrectionType">1</int>
+ <int key="IBUIKeyboardType">1</int>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBUIFontDescription" key="IBUIFontDescription">
+ <int key="type">1</int>
+ <double key="pointSize">14</double>
+ </object>
+ <object class="NSFont" key="IBUIFont">
+ <string key="NSName">Helvetica</string>
+ <double key="NSSize">14</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ </object>
+ <object class="IBUINavigationItem" key="IBUINavigationItem" id="683530484">
+ <string key="IBUITitle"/>
+ <object class="IBUIBarButtonItem" key="IBUIRightBarButtonItem" id="51747481">
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <int key="IBUIStyle">2</int>
+ <reference key="IBUINavigationItem" ref="683530484"/>
+ <int key="IBUISystemItemIdentifier">3</int>
+ </object>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
+ <int key="IBUIInterfaceOrientation">1</int>
+ <int key="interfaceOrientation">1</int>
+ </object>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <bool key="IBUIHorizontal">NO</bool>
+ </object>
+ <object class="IBUINavigationController" id="89217823">
+ <object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics">
+ <int key="IBUIStatusBarStyle">2</int>
+ </object>
+ <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
+ <int key="IBUIInterfaceOrientation">1</int>
+ <int key="interfaceOrientation">1</int>
+ </object>
+ <bool key="IBUIDefinesPresentationContext">YES</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <bool key="IBUIHorizontal">NO</bool>
+ <object class="IBUINavigationBar" key="IBUINavigationBar" id="392803394">
+ <nil key="NSNextResponder"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrameSize">{0, 0}</string>
+ <string key="NSReuseIdentifierKey">_NS:453</string>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <bool key="IBUIMultipleTouchEnabled">YES</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <array class="NSMutableArray" key="IBUIViewControllers">
+ <object class="IBUIViewController" id="674042113">
+ <object class="IBUITableView" key="IBUIView" id="326066669">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrame">{{0, 64}, {768, 960}}</string>
+ <reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
+ <string key="NSReuseIdentifierKey">_NS:408</string>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MCAwIDAgMAA</bytes>
+ </object>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <bool key="IBUIBounces">NO</bool>
+ <bool key="IBUIScrollEnabled">NO</bool>
+ <int key="IBUIStyle">1</int>
+ <int key="IBUISeparatorStyle">2</int>
+ <int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
+ <bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
+ <float key="IBUIRowHeight">44</float>
+ <float key="IBUISectionHeaderHeight">10</float>
+ <float key="IBUISectionFooterHeight">10</float>
+ </object>
+ <object class="IBUINavigationItem" key="IBUINavigationItem" id="705974131">
+ <reference key="IBUINavigationBar"/>
+ <string key="IBUITitle">GemRB</string>
+ <object class="IBUIBarButtonItem" key="IBUIRightBarButtonItem" id="970039044">
+ <string key="IBUITitle">Play</string>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <int key="IBUIStyle">2</int>
+ <reference key="IBUINavigationItem" ref="705974131"/>
+ </object>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <reference key="IBUIParentViewController" ref="89217823"/>
+ <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
+ <int key="IBUIInterfaceOrientation">1</int>
+ <int key="interfaceOrientation">1</int>
+ </object>
+ <int key="IBUIModalTransitionStyle">1</int>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <bool key="IBUIHorizontal">NO</bool>
+ </object>
+ </array>
+ </object>
+ </array>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <array class="NSMutableArray" key="connectionRecords">
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">rootVC</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="89217823"/>
+ </object>
+ <int key="connectionID">38</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">editorVC</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="1015082547"/>
+ </object>
+ <int key="connectionID">42</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">editor</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="1030036642"/>
+ </object>
+ <int key="connectionID">43</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">controlTable</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="326066669"/>
+ </object>
+ <int key="connectionID">44</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">dataSource</string>
+ <reference key="source" ref="326066669"/>
+ <reference key="destination" ref="841351856"/>
+ </object>
+ <int key="connectionID">16</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="326066669"/>
+ <reference key="destination" ref="841351856"/>
+ </object>
+ <int key="connectionID">17</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">saveConfig:</string>
+ <reference key="source" ref="51747481"/>
+ <reference key="destination" ref="841351856"/>
+ </object>
+ <int key="connectionID">39</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">launchGEM:</string>
+ <reference key="source" ref="970039044"/>
+ <reference key="destination" ref="841351856"/>
+ </object>
+ <int key="connectionID">45</int>
+ </object>
+ </array>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <array key="orderedObjects">
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <array key="object" id="0"/>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="841351856"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="606714003"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">11</int>
+ <reference key="object" ref="89217823"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="392803394"/>
+ <reference ref="674042113"/>
+ </array>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">12</int>
+ <reference key="object" ref="392803394"/>
+ <reference key="parent" ref="89217823"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">13</int>
+ <reference key="object" ref="674042113"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="705974131"/>
+ <reference ref="326066669"/>
+ </array>
+ <reference key="parent" ref="89217823"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">14</int>
+ <reference key="object" ref="705974131"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="970039044"/>
+ </array>
+ <reference key="parent" ref="674042113"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">15</int>
+ <reference key="object" ref="326066669"/>
+ <reference key="parent" ref="674042113"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">40</int>
+ <reference key="object" ref="970039044"/>
+ <reference key="parent" ref="705974131"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">35</int>
+ <reference key="object" ref="1015082547"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="1030036642"/>
+ <reference ref="683530484"/>
+ </array>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">19</int>
+ <reference key="object" ref="1030036642"/>
+ <reference key="parent" ref="1015082547"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">36</int>
+ <reference key="object" ref="683530484"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="51747481"/>
+ </array>
+ <reference key="parent" ref="1015082547"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">37</int>
+ <reference key="object" ref="51747481"/>
+ <reference key="parent" ref="683530484"/>
+ </object>
+ </array>
+ </object>
+ <dictionary class="NSMutableDictionary" key="flattenedProperties">
+ <string key="-1.CustomClassName">GEM_ConfController</string>
+ <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="-2.CustomClassName">UIResponder</string>
+ <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="11.CustomClassName">GEM_NavController</string>
+ <string key="11.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="12.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="13.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="14.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="15.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="19.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="35.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="36.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="37.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="40.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+ <nil key="activeLocalization"/>
+ <dictionary class="NSMutableDictionary" key="localizations"/>
+ <nil key="sourceID"/>
+ <int key="maxID">45</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <array class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <object class="IBPartialClassDescription">
+ <string key="className">GEM_ConfController</string>
+ <string key="superclassName">NSObject</string>
+ <dictionary class="NSMutableDictionary" key="actions">
+ <string key="launchGEM:">id</string>
+ <string key="saveConfig:">id</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="actionInfosByName">
+ <object class="IBActionInfo" key="launchGEM:">
+ <string key="name">launchGEM:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo" key="saveConfig:">
+ <string key="name">saveConfig:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="outlets">
+ <string key="controlTable">UITableView</string>
+ <string key="editor">UITextView</string>
+ <string key="editorVC">UIViewController</string>
+ <string key="playButton">UIBarButtonItem</string>
+ <string key="rootVC">UINavigationController</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <object class="IBToOneOutletInfo" key="controlTable">
+ <string key="name">controlTable</string>
+ <string key="candidateClassName">UITableView</string>
+ </object>
+ <object class="IBToOneOutletInfo" key="editor">
+ <string key="name">editor</string>
+ <string key="candidateClassName">UITextView</string>
+ </object>
+ <object class="IBToOneOutletInfo" key="editorVC">
+ <string key="name">editorVC</string>
+ <string key="candidateClassName">UIViewController</string>
+ </object>
+ <object class="IBToOneOutletInfo" key="playButton">
+ <string key="name">playButton</string>
+ <string key="candidateClassName">UIBarButtonItem</string>
+ </object>
+ <object class="IBToOneOutletInfo" key="rootVC">
+ <string key="name">rootVC</string>
+ <string key="candidateClassName">UINavigationController</string>
+ </object>
+ </dictionary>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/GEM_ConfController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">GEM_NavController</string>
+ <string key="superclassName">UINavigationController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/GEM_NavController.h</string>
+ </object>
+ </object>
+ </array>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBIPadFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+ <real value="4200" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <string key="IBCocoaTouchPluginVersion">933</string>
+ </data>
+</archive>
diff --git a/apple/CocoaWrapper/mac/CocoaWrapper.mm b/apple/CocoaWrapper/mac/CocoaWrapper.mm
new file mode 100644
index 0000000..ef9ec64
--- /dev/null
+++ b/apple/CocoaWrapper/mac/CocoaWrapper.mm
@@ -0,0 +1,219 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#import "CocoaWrapper.h"
+
+#import "AppleLogger.h"
+#import "Interface.h"
+#import "System/FileStream.h"
+#import "System/Logger/File.h"
+
+using namespace GemRB;
+
+/* For some reaon, Apple removed setAppleMenu from the headers in 10.4,
+ but the method still is there and works. To avoid warnings, we declare
+ it ourselves here. */
+ at interface NSApplication(Missing_Methods)
+- (void)setAppleMenu:(NSMenu *)menu;
+ at end
+
+/* The main class of the application, the application's delegate */
+ at implementation CocoaWrapper
+ at synthesize configWindow=_configWindow;
+
+- (id)init
+{
+ self = [super init];
+ if (self) {
+ _configWindow = nil;
+ _showConfigWindow = NO;
+ }
+ return self;
+}
+
+- (BOOL)application:(NSApplication *) __unused theApplication openFile:(NSString *) filename
+{
+ NSFileManager* fm = [NSFileManager defaultManager];
+ // only open if passed a directory
+ BOOL isDir = NO;
+ if ([fm fileExistsAtPath:filename isDirectory:&isDir] && isDir) {
+ NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
+ [defaults setObject:filename forKey:@"GamePath"];
+
+ if (_showConfigWindow == NO) {
+ // opened via means other than config window
+ [self launchGame:nil];
+ }
+
+ return YES;
+ }
+ return NO;
+}
+
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *) __unused sender
+{
+ //override this method using plugin categories.
+ NSLog(@"Application preparing for termination...");
+ return NSTerminateNow;
+}
+
+- (void)applicationWillTerminate:(NSNotification *) __unused aNotification
+{
+ //override this method using plugin categories.
+ NSLog(@"Application terminate");
+}
+
+// always called before openFile when launched via CLI/DragDrop
+- (void)applicationWillFinishLaunching:(NSNotification *) __unused aNotification
+{
+ AddLogger(createAppleLogger());
+
+ // Load default defaults
+ [[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"defaults" ofType:@"plist"]]];
+}
+
+/* Called when the internal event loop has just started running */
+- (void) applicationDidFinishLaunching: (NSNotification *) __unused aNotification
+{
+ // we configure this here so that when GemRB is launched though means such as Drag/Drop we dont show the config window
+
+ _showConfigWindow = YES; //still need to set this to YES in case an error occurs
+ [NSBundle loadNibNamed:@"GemRB" owner:self];
+
+ if (core == NULL) {
+ [_configWindow makeKeyAndOrderFront:nil];
+ }
+}
+
+- (IBAction)openGame:(id) __unused sender
+{
+ // be careful to use only methods available in 10.5!
+ NSOpenPanel* op = [NSOpenPanel openPanel];
+ [op setCanChooseDirectories:YES];
+ [op setCanChooseFiles:NO];
+ [op setAllowsMultipleSelection:NO];
+ [op setMessage:@"Select a folder containing an IE game."];
+ [op setPrompt:@"Select Game"];
+ if ([op runModal] == NSFileHandlingPanelOKButton) { //blocks till user selection
+ [self application:NSApp openFile:[op filename]];
+ }
+}
+
+- (IBAction)launchGame:(id) __unused sender
+{
+ core = new Interface();
+ InterfaceConfig* config = new InterfaceConfig(0, NULL);
+
+ // load NSUserDefaults into config
+ NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
+ NSDictionary* userValues = [defaults persistentDomainForName:@"net.sourceforge.gemrb"];
+ NSDictionary* defaultValues = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"defaults" ofType:@"plist"]];
+
+ NSMutableDictionary* dict = [NSMutableDictionary dictionaryWithDictionary:defaultValues];
+ [dict addEntriesFromDictionary:userValues];
+
+ for ( NSString* key in dict ) {
+ NSString* value = nil;
+ id obj = [dict objectForKey:key];
+ if ([obj isKindOfClass:[NSNumber class]]) {
+ value = [(NSNumber*)obj stringValue];
+ } else if ([obj isKindOfClass:[NSString class]]) {
+ value = (NSString*)obj;
+ }
+ config->SetKeyValuePair([key cStringUsingEncoding:NSASCIIStringEncoding],
+ [value cStringUsingEncoding:NSASCIIStringEncoding]);
+ }
+
+ int status;
+ if ((status = core->Init(config)) == GEM_ERROR) {
+ delete config;
+ delete( core );
+ Log(MESSAGE, "Cocoa Wrapper", "Unable to initialize core. Terminating.");
+ } else {
+ [_configWindow close];
+ // pass control to GemRB
+ delete config;
+ core->Main();
+ delete( core );
+ ShutdownLogging();
+ // We must exit since the application runloop never returns.
+
+ // TODO: we want to be able to use NSApplication terminate method
+ // need fancier logic in shouldTerminate implementation first (in SDL plugin)
+ exit(status);
+ }
+}
+
+- (BOOL)respondsToSelector:(SEL)aSelector
+{
+ if ([NSApp respondsToSelector:aSelector]) {
+ return YES;
+ }
+ return [super respondsToSelector:aSelector];
+}
+
+- (NSMethodSignature*) methodSignatureForSelector:(SEL)selector
+{
+ // Check if car can handle the message
+ NSMethodSignature* signature = [super
+ methodSignatureForSelector:selector];
+
+ // If not, can the car info string handle the message?
+ if (!signature)
+ signature = [NSApp methodSignatureForSelector:selector];
+
+ return signature;
+}
+
+- (void)forwardInvocation:(NSInvocation *)invocation
+{
+ SEL selector = [invocation selector];
+
+ if ([NSApp respondsToSelector:selector])
+ {
+ [invocation invokeWithTarget:NSApp];
+ }
+}
+
+ at end
+
+/* Main entry point to executable - should *not* be GemRB_main! */
+int main (int __unused argc, char ** __unused argv)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ /* Ensure the application object is initialised */
+ NSApplication* app = [NSApplication sharedApplication];
+
+ /* Set up the menubar */
+ [NSApp setMainMenu:[[NSMenu alloc] init]];
+
+ CocoaWrapper* wrapper = [[CocoaWrapper alloc] init];
+ [app setDelegate:wrapper];
+
+ /* Start the main event loop */
+ [pool drain];
+ [NSApp run];
+
+ [wrapper release];
+ [pool release];
+
+ return 0;
+}
diff --git a/apple/CocoaWrapper/mac/nibs/GemRB.xib b/apple/CocoaWrapper/mac/nibs/GemRB.xib
new file mode 100644
index 0000000..6faf393
--- /dev/null
+++ b/apple/CocoaWrapper/mac/nibs/GemRB.xib
@@ -0,0 +1,2650 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00">
+ <data>
+ <int key="IBDocument.SystemTarget">1050</int>
+ <string key="IBDocument.SystemVersion">12D78</string>
+ <string key="IBDocument.InterfaceBuilderVersion">3084</string>
+ <string key="IBDocument.AppKitVersion">1187.37</string>
+ <string key="IBDocument.HIToolboxVersion">626.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="NS.object.0">3084</string>
+ </object>
+ <array key="IBDocument.IntegratedClassDependencies">
+ <string>NSBox</string>
+ <string>NSButton</string>
+ <string>NSButtonCell</string>
+ <string>NSCustomObject</string>
+ <string>NSMenu</string>
+ <string>NSMenuItem</string>
+ <string>NSTextField</string>
+ <string>NSTextFieldCell</string>
+ <string>NSUserDefaultsController</string>
+ <string>NSView</string>
+ <string>NSWindowTemplate</string>
+ </array>
+ <array key="IBDocument.PluginDependencies">
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ </array>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+ <integer value="1" key="NS.object.0"/>
+ </object>
+ <array class="NSMutableArray" key="IBDocument.RootObjects" id="1048">
+ <object class="NSCustomObject" id="1021">
+ <string key="NSClassName">CocoaWrapper</string>
+ </object>
+ <object class="NSCustomObject" id="1014">
+ <string key="NSClassName">FirstResponder</string>
+ </object>
+ <object class="NSCustomObject" id="1050">
+ <string key="NSClassName">NSApplication</string>
+ </object>
+ <object class="NSCustomObject" id="163992474">
+ <string key="NSClassName">NSFontManager</string>
+ </object>
+ <object class="NSMenu" id="649796088">
+ <string key="NSTitle">Main Menu</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="694149608">
+ <reference key="NSMenu" ref="649796088"/>
+ <string key="NSTitle">GemRB</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <object class="NSCustomResource" key="NSOnImage" id="353210768">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">NSMenuCheckmark</string>
+ </object>
+ <object class="NSCustomResource" key="NSMixedImage" id="549394948">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">NSMenuMixedState</string>
+ </object>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="110575045">
+ <string key="NSTitle">GemRB</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="238522557">
+ <reference key="NSMenu" ref="110575045"/>
+ <string key="NSTitle">About GemRB</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="304266470">
+ <reference key="NSMenu" ref="110575045"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="609285721">
+ <reference key="NSMenu" ref="110575045"/>
+ <string key="NSTitle">Preferences…</string>
+ <string key="NSKeyEquiv">,</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="481834944">
+ <reference key="NSMenu" ref="110575045"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="1046388886">
+ <reference key="NSMenu" ref="110575045"/>
+ <string key="NSTitle">Services</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="752062318">
+ <string key="NSTitle">Services</string>
+ <array class="NSMutableArray" key="NSMenuItems"/>
+ <string key="NSName">_NSServicesMenu</string>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="646227648">
+ <reference key="NSMenu" ref="110575045"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="755159360">
+ <reference key="NSMenu" ref="110575045"/>
+ <string key="NSTitle">Hide GemRB</string>
+ <string key="NSKeyEquiv">h</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="342932134">
+ <reference key="NSMenu" ref="110575045"/>
+ <string key="NSTitle">Hide Others</string>
+ <string key="NSKeyEquiv">h</string>
+ <int key="NSKeyEquivModMask">1572864</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="908899353">
+ <reference key="NSMenu" ref="110575045"/>
+ <string key="NSTitle">Show All</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="1056857174">
+ <reference key="NSMenu" ref="110575045"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="632727374">
+ <reference key="NSMenu" ref="110575045"/>
+ <string key="NSTitle">Quit GemRB</string>
+ <string key="NSKeyEquiv">q</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ </array>
+ <string key="NSName">_NSAppleMenu</string>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="379814623">
+ <reference key="NSMenu" ref="649796088"/>
+ <string key="NSTitle">File</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="720053764">
+ <string key="NSTitle">File</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="705341025">
+ <reference key="NSMenu" ref="720053764"/>
+ <string key="NSTitle">New</string>
+ <string key="NSKeyEquiv">n</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="722745758">
+ <reference key="NSMenu" ref="720053764"/>
+ <string key="NSTitle">Open…</string>
+ <string key="NSKeyEquiv">o</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="1025936716">
+ <reference key="NSMenu" ref="720053764"/>
+ <string key="NSTitle">Open Recent</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="1065607017">
+ <string key="NSTitle">Open Recent</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="759406840">
+ <reference key="NSMenu" ref="1065607017"/>
+ <string key="NSTitle">Clear Menu</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ </array>
+ <string key="NSName">_NSRecentDocumentsMenu</string>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="425164168">
+ <reference key="NSMenu" ref="720053764"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="776162233">
+ <reference key="NSMenu" ref="720053764"/>
+ <string key="NSTitle">Close</string>
+ <string key="NSKeyEquiv">w</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="1023925487">
+ <reference key="NSMenu" ref="720053764"/>
+ <string key="NSTitle">Save…</string>
+ <string key="NSKeyEquiv">s</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="579971712">
+ <reference key="NSMenu" ref="720053764"/>
+ <string key="NSTitle">Revert to Saved</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="1010469920">
+ <reference key="NSMenu" ref="720053764"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="294629803">
+ <reference key="NSMenu" ref="720053764"/>
+ <string key="NSTitle">Page Setup...</string>
+ <string key="NSKeyEquiv">P</string>
+ <int key="NSKeyEquivModMask">1179648</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ <string key="NSToolTip"/>
+ </object>
+ <object class="NSMenuItem" id="49223823">
+ <reference key="NSMenu" ref="720053764"/>
+ <string key="NSTitle">Print…</string>
+ <string key="NSKeyEquiv">p</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ </array>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="760709348">
+ <reference key="NSMenu" ref="649796088"/>
+ <string key="NSTitle">Edit</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="874538137">
+ <string key="NSTitle">Edit</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="689132699">
+ <reference key="NSMenu" ref="874538137"/>
+ <string key="NSTitle">Undo</string>
+ <string key="NSKeyEquiv">z</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="588035066">
+ <reference key="NSMenu" ref="874538137"/>
+ <string key="NSTitle">Redo</string>
+ <string key="NSKeyEquiv">Z</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="19281719">
+ <reference key="NSMenu" ref="874538137"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="327226428">
+ <reference key="NSMenu" ref="874538137"/>
+ <string key="NSTitle">Cut</string>
+ <string key="NSKeyEquiv">x</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="499410273">
+ <reference key="NSMenu" ref="874538137"/>
+ <string key="NSTitle">Copy</string>
+ <string key="NSKeyEquiv">c</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="610688774">
+ <reference key="NSMenu" ref="874538137"/>
+ <string key="NSTitle">Paste</string>
+ <string key="NSKeyEquiv">v</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="143408881">
+ <reference key="NSMenu" ref="874538137"/>
+ <string key="NSTitle">Paste and Match Style</string>
+ <string key="NSKeyEquiv">V</string>
+ <int key="NSKeyEquivModMask">1572864</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="972907518">
+ <reference key="NSMenu" ref="874538137"/>
+ <string key="NSTitle">Delete</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="414073690">
+ <reference key="NSMenu" ref="874538137"/>
+ <string key="NSTitle">Select All</string>
+ <string key="NSKeyEquiv">a</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="438589790">
+ <reference key="NSMenu" ref="874538137"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="34073996">
+ <reference key="NSMenu" ref="874538137"/>
+ <string key="NSTitle">Find</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="142787696">
+ <string key="NSTitle">Find</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="748212273">
+ <reference key="NSMenu" ref="142787696"/>
+ <string key="NSTitle">Find…</string>
+ <string key="NSKeyEquiv">f</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ <int key="NSTag">1</int>
+ </object>
+ <object class="NSMenuItem" id="1065735815">
+ <reference key="NSMenu" ref="142787696"/>
+ <string key="NSTitle">Find Next</string>
+ <string key="NSKeyEquiv">g</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ <int key="NSTag">2</int>
+ </object>
+ <object class="NSMenuItem" id="582428080">
+ <reference key="NSMenu" ref="142787696"/>
+ <string key="NSTitle">Find Previous</string>
+ <string key="NSKeyEquiv">G</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ <int key="NSTag">3</int>
+ </object>
+ <object class="NSMenuItem" id="915153746">
+ <reference key="NSMenu" ref="142787696"/>
+ <string key="NSTitle">Use Selection for Find</string>
+ <string key="NSKeyEquiv">e</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ <int key="NSTag">7</int>
+ </object>
+ <object class="NSMenuItem" id="284401815">
+ <reference key="NSMenu" ref="142787696"/>
+ <string key="NSTitle">Jump to Selection</string>
+ <string key="NSKeyEquiv">j</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ </array>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="653847976">
+ <reference key="NSMenu" ref="874538137"/>
+ <string key="NSTitle">Spelling and Grammar</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="961864607">
+ <string key="NSTitle">Spelling</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="1073299659">
+ <reference key="NSMenu" ref="961864607"/>
+ <string key="NSTitle">Show Spelling and Grammar</string>
+ <string key="NSKeyEquiv">:</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="116276200">
+ <reference key="NSMenu" ref="961864607"/>
+ <string key="NSTitle">Check Document Now</string>
+ <string key="NSKeyEquiv">;</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="895226763">
+ <reference key="NSMenu" ref="961864607"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="325876846">
+ <reference key="NSMenu" ref="961864607"/>
+ <string key="NSTitle">Check Spelling While Typing</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="1073614422">
+ <reference key="NSMenu" ref="961864607"/>
+ <string key="NSTitle">Check Grammar With Spelling</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="768164437">
+ <reference key="NSMenu" ref="961864607"/>
+ <string key="NSTitle">Correct Spelling Automatically</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ </array>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="438460389">
+ <reference key="NSMenu" ref="874538137"/>
+ <string key="NSTitle">Substitutions</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="127406826">
+ <string key="NSTitle">Substitutions</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="738094600">
+ <reference key="NSMenu" ref="127406826"/>
+ <string key="NSTitle">Show Substitutions</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="337624084">
+ <reference key="NSMenu" ref="127406826"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="809892461">
+ <reference key="NSMenu" ref="127406826"/>
+ <string key="NSTitle">Smart Copy/Paste</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="861597930">
+ <reference key="NSMenu" ref="127406826"/>
+ <string key="NSTitle">Smart Quotes</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="647578214">
+ <reference key="NSMenu" ref="127406826"/>
+ <string key="NSTitle">Smart Dashes</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="424647815">
+ <reference key="NSMenu" ref="127406826"/>
+ <string key="NSTitle">Smart Links</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="259062896">
+ <reference key="NSMenu" ref="127406826"/>
+ <string key="NSTitle">Data Detectors</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="213997630">
+ <reference key="NSMenu" ref="127406826"/>
+ <string key="NSTitle">Text Replacement</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ </array>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="33629833">
+ <reference key="NSMenu" ref="874538137"/>
+ <string key="NSTitle">Transformations</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="165587917">
+ <string key="NSTitle">Transformations</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="112815381">
+ <reference key="NSMenu" ref="165587917"/>
+ <string key="NSTitle">Make Upper Case</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="634567257">
+ <reference key="NSMenu" ref="165587917"/>
+ <string key="NSTitle">Make Lower Case</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="669637497">
+ <reference key="NSMenu" ref="165587917"/>
+ <string key="NSTitle">Capitalize</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ </array>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="168141218">
+ <reference key="NSMenu" ref="874538137"/>
+ <string key="NSTitle">Speech</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="972561574">
+ <string key="NSTitle">Speech</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="476308533">
+ <reference key="NSMenu" ref="972561574"/>
+ <string key="NSTitle">Start Speaking</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="214803442">
+ <reference key="NSMenu" ref="972561574"/>
+ <string key="NSTitle">Stop Speaking</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ </array>
+ </object>
+ </object>
+ </array>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="391199113">
+ <reference key="NSMenu" ref="649796088"/>
+ <string key="NSTitle">Help</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="374024848">
+ <string key="NSTitle">Help</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="238773614">
+ <reference key="NSMenu" ref="374024848"/>
+ <string key="NSTitle">GemRB Help</string>
+ <string key="NSKeyEquiv">?</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ </array>
+ <string key="NSName">_NSHelpMenu</string>
+ </object>
+ </object>
+ </array>
+ <string key="NSName">_NSMainMenu</string>
+ </object>
+ <object class="NSWindowTemplate" id="513744381">
+ <int key="NSWindowStyleMask">15</int>
+ <int key="NSWindowBacking">2</int>
+ <string key="NSWindowRect">{{196, 240}, {414, 182}}</string>
+ <int key="NSWTFlags">611844096</int>
+ <string key="NSWindowTitle">Prefrences</string>
+ <string key="NSWindowClass">NSWindow</string>
+ <nil key="NSViewClass"/>
+ <nil key="NSUserInterfaceItemIdentifier"/>
+ <object class="NSView" key="NSWindowView" id="414427165">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">256</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="NSTextField" id="1027211632">
+ <reference key="NSNextResponder" ref="414427165"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{83, 146}, {231, 19}}</string>
+ <reference key="NSSuperview" ref="414427165"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="960485278"/>
+ <string key="NSReuseIdentifierKey">_NS:9</string>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="8094530">
+ <int key="NSCellFlags">-1804599231</int>
+ <int key="NSCellFlags2">272761856</int>
+ <string key="NSContents"/>
+ <object class="NSFont" key="NSSupport" id="26">
+ <string key="NSName">LucidaGrande</string>
+ <double key="NSSize">11</double>
+ <int key="NSfFlags">3100</int>
+ </object>
+ <string key="NSCellIdentifier">_NS:9</string>
+ <reference key="NSControlView" ref="1027211632"/>
+ <bool key="NSDrawsBackground">YES</bool>
+ <object class="NSColor" key="NSBackgroundColor" id="604804392">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">textBackgroundColor</string>
+ <object class="NSColor" key="NSColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ </object>
+ <object class="NSColor" key="NSTextColor" id="15837238">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">textColor</string>
+ <object class="NSColor" key="NSColor" id="741016158">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MAA</bytes>
+ </object>
+ </object>
+ </object>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+ </object>
+ <object class="NSBox" id="973036919">
+ <reference key="NSNextResponder" ref="414427165"/>
+ <int key="NSvFlags">12</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="NSView" id="862042093">
+ <reference key="NSNextResponder" ref="973036919"/>
+ <int key="NSvFlags">274</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="NSButton" id="514909995">
+ <reference key="NSNextResponder" ref="862042093"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{15, 83}, {122, 18}}</string>
+ <reference key="NSSuperview" ref="862042093"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="81603430"/>
+ <string key="NSReuseIdentifierKey">_NS:9</string>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="712348702">
+ <int key="NSCellFlags">-2080374784</int>
+ <int key="NSCellFlags2">268566528</int>
+ <string key="NSContents">GUI Enhancements</string>
+ <reference key="NSSupport" ref="26"/>
+ <string key="NSCellIdentifier">_NS:9</string>
+ <reference key="NSControlView" ref="514909995"/>
+ <int key="NSButtonFlags">1211912448</int>
+ <int key="NSButtonFlags2">2</int>
+ <object class="NSCustomResource" key="NSNormalImage" id="19498200">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">NSSwitch</string>
+ </object>
+ <object class="NSButtonImageSource" key="NSAlternateImage" id="233505524">
+ <string key="NSImageName">NSSwitch</string>
+ </object>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent"/>
+ <int key="NSPeriodicDelay">200</int>
+ <int key="NSPeriodicInterval">25</int>
+ </object>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+ </object>
+ <object class="NSButton" id="81603430">
+ <reference key="NSNextResponder" ref="862042093"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{15, 65}, {79, 18}}</string>
+ <reference key="NSSuperview" ref="862042093"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="426949335"/>
+ <string key="NSReuseIdentifierKey">_NS:9</string>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="455129962">
+ <int key="NSCellFlags">-2080374784</int>
+ <int key="NSCellFlags2">268566528</int>
+ <string key="NSContents">Skip Intros</string>
+ <reference key="NSSupport" ref="26"/>
+ <string key="NSCellIdentifier">_NS:9</string>
+ <reference key="NSControlView" ref="81603430"/>
+ <int key="NSButtonFlags">1211912448</int>
+ <int key="NSButtonFlags2">2</int>
+ <reference key="NSNormalImage" ref="19498200"/>
+ <reference key="NSAlternateImage" ref="233505524"/>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent"/>
+ <int key="NSPeriodicDelay">200</int>
+ <int key="NSPeriodicInterval">25</int>
+ </object>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+ </object>
+ <object class="NSButton" id="426949335">
+ <reference key="NSNextResponder" ref="862042093"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{15, 47}, {79, 18}}</string>
+ <reference key="NSSuperview" ref="862042093"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="1002349262"/>
+ <string key="NSReuseIdentifierKey">_NS:9</string>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="817985991">
+ <int key="NSCellFlags">-2080374784</int>
+ <int key="NSCellFlags2">268566528</int>
+ <string key="NSContents">FPS</string>
+ <reference key="NSSupport" ref="26"/>
+ <string key="NSCellIdentifier">_NS:9</string>
+ <reference key="NSControlView" ref="426949335"/>
+ <int key="NSButtonFlags">1211912448</int>
+ <int key="NSButtonFlags2">2</int>
+ <reference key="NSNormalImage" ref="19498200"/>
+ <reference key="NSAlternateImage" ref="233505524"/>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent"/>
+ <int key="NSPeriodicDelay">200</int>
+ <int key="NSPeriodicInterval">25</int>
+ </object>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+ </object>
+ <object class="NSButton" id="1002349262">
+ <reference key="NSNextResponder" ref="862042093"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{15, 29}, {80, 18}}</string>
+ <reference key="NSSuperview" ref="862042093"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="376604116"/>
+ <string key="NSReuseIdentifierKey">_NS:9</string>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="828623902">
+ <int key="NSCellFlags">-2080374784</int>
+ <int key="NSCellFlags2">268566528</int>
+ <string key="NSContents">Fog of War</string>
+ <reference key="NSSupport" ref="26"/>
+ <string key="NSCellIdentifier">_NS:9</string>
+ <reference key="NSControlView" ref="1002349262"/>
+ <int key="NSButtonFlags">1211912448</int>
+ <int key="NSButtonFlags2">2</int>
+ <reference key="NSNormalImage" ref="19498200"/>
+ <reference key="NSAlternateImage" ref="233505524"/>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent"/>
+ <int key="NSPeriodicDelay">200</int>
+ <int key="NSPeriodicInterval">25</int>
+ </object>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+ </object>
+ <object class="NSButton" id="376604116">
+ <reference key="NSNextResponder" ref="862042093"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{15, 11}, {81, 18}}</string>
+ <reference key="NSSuperview" ref="862042093"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="332651215"/>
+ <string key="NSReuseIdentifierKey">_NS:9</string>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="781005808">
+ <int key="NSCellFlags">-2080374784</int>
+ <int key="NSCellFlags2">268566528</int>
+ <string key="NSContents">Cheat Keys</string>
+ <reference key="NSSupport" ref="26"/>
+ <string key="NSCellIdentifier">_NS:9</string>
+ <reference key="NSControlView" ref="376604116"/>
+ <int key="NSButtonFlags">1211912448</int>
+ <int key="NSButtonFlags2">2</int>
+ <reference key="NSNormalImage" ref="19498200"/>
+ <reference key="NSAlternateImage" ref="233505524"/>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent"/>
+ <int key="NSPeriodicDelay">200</int>
+ <int key="NSPeriodicInterval">25</int>
+ </object>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+ </object>
+ </array>
+ <string key="NSFrame">{{1, 1}, {153, 108}}</string>
+ <reference key="NSSuperview" ref="973036919"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="514909995"/>
+ <string key="NSReuseIdentifierKey">_NS:11</string>
+ </object>
+ </array>
+ <string key="NSFrame">{{17, 16}, {155, 124}}</string>
+ <reference key="NSSuperview" ref="414427165"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="862042093"/>
+ <string key="NSReuseIdentifierKey">_NS:9</string>
+ <string key="NSOffsets">{0, 0}</string>
+ <object class="NSTextFieldCell" key="NSTitleCell">
+ <int key="NSCellFlags">67108864</int>
+ <int key="NSCellFlags2">0</int>
+ <string key="NSContents">Game Settings</string>
+ <reference key="NSSupport" ref="26"/>
+ <reference key="NSBackgroundColor" ref="604804392"/>
+ <object class="NSColor" key="NSTextColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MCAwLjgwMDAwMDAxMTkAA</bytes>
+ </object>
+ </object>
+ <reference key="NSContentView" ref="862042093"/>
+ <int key="NSBorderType">1</int>
+ <int key="NSBoxType">0</int>
+ <int key="NSTitlePosition">2</int>
+ <bool key="NSTransparent">NO</bool>
+ </object>
+ <object class="NSTextField" id="292409822">
+ <reference key="NSNextResponder" ref="414427165"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{17, 148}, {61, 14}}</string>
+ <reference key="NSSuperview" ref="414427165"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="1027211632"/>
+ <string key="NSReuseIdentifierKey">_NS:1535</string>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="354930942">
+ <int key="NSCellFlags">68157504</int>
+ <int key="NSCellFlags2">272761856</int>
+ <string key="NSContents">Game Path</string>
+ <reference key="NSSupport" ref="26"/>
+ <string key="NSCellIdentifier">_NS:1535</string>
+ <reference key="NSControlView" ref="292409822"/>
+ <object class="NSColor" key="NSBackgroundColor" id="616357123">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">controlColor</string>
+ <object class="NSColor" key="NSColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
+ </object>
+ </object>
+ <object class="NSColor" key="NSTextColor" id="1067694695">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">controlTextColor</string>
+ <reference key="NSColor" ref="741016158"/>
+ </object>
+ </object>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+ </object>
+ <object class="NSButton" id="960485278">
+ <reference key="NSNextResponder" ref="414427165"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{317, 140}, {82, 28}}</string>
+ <reference key="NSSuperview" ref="414427165"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="973036919"/>
+ <string key="NSReuseIdentifierKey">_NS:9</string>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="13942975">
+ <int key="NSCellFlags">67108864</int>
+ <int key="NSCellFlags2">134348800</int>
+ <string key="NSContents">Open</string>
+ <reference key="NSSupport" ref="26"/>
+ <string key="NSCellIdentifier">_NS:9</string>
+ <reference key="NSControlView" ref="960485278"/>
+ <int key="NSButtonFlags">-2038284288</int>
+ <int key="NSButtonFlags2">129</int>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent"/>
+ <int key="NSPeriodicDelay">200</int>
+ <int key="NSPeriodicInterval">25</int>
+ </object>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+ </object>
+ <object class="NSButton" id="267578530">
+ <reference key="NSNextResponder" ref="414427165"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{317, 14}, {82, 28}}</string>
+ <reference key="NSSuperview" ref="414427165"/>
+ <reference key="NSWindow"/>
+ <string key="NSReuseIdentifierKey">_NS:9</string>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="995000440">
+ <int key="NSCellFlags">67108864</int>
+ <int key="NSCellFlags2">134348800</int>
+ <string key="NSContents">Launch</string>
+ <reference key="NSSupport" ref="26"/>
+ <string key="NSCellIdentifier">_NS:9</string>
+ <reference key="NSControlView" ref="267578530"/>
+ <int key="NSButtonFlags">-2038284288</int>
+ <int key="NSButtonFlags2">129</int>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent"/>
+ <int key="NSPeriodicDelay">200</int>
+ <int key="NSPeriodicInterval">25</int>
+ </object>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+ </object>
+ <object class="NSBox" id="332651215">
+ <reference key="NSNextResponder" ref="414427165"/>
+ <int key="NSvFlags">12</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="NSView" id="570115299">
+ <reference key="NSNextResponder" ref="332651215"/>
+ <int key="NSvFlags">274</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="NSTextField" id="586782438">
+ <reference key="NSNextResponder" ref="570115299"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{58, 62}, {65, 19}}</string>
+ <reference key="NSSuperview" ref="570115299"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="772391111"/>
+ <string key="NSReuseIdentifierKey">_NS:9</string>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="226663740">
+ <int key="NSCellFlags">-1804599231</int>
+ <int key="NSCellFlags2">272761856</int>
+ <string key="NSContents">640</string>
+ <reference key="NSSupport" ref="26"/>
+ <string key="NSCellIdentifier">_NS:9</string>
+ <reference key="NSControlView" ref="586782438"/>
+ <bool key="NSDrawsBackground">YES</bool>
+ <reference key="NSBackgroundColor" ref="604804392"/>
+ <reference key="NSTextColor" ref="15837238"/>
+ </object>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+ </object>
+ <object class="NSTextField" id="177317088">
+ <reference key="NSNextResponder" ref="570115299"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{15, 64}, {38, 14}}</string>
+ <reference key="NSSuperview" ref="570115299"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="586782438"/>
+ <string key="NSReuseIdentifierKey">_NS:1535</string>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="31322398">
+ <int key="NSCellFlags">68157504</int>
+ <int key="NSCellFlags2">272761856</int>
+ <string key="NSContents">Width</string>
+ <reference key="NSSupport" ref="26"/>
+ <string key="NSCellIdentifier">_NS:1535</string>
+ <reference key="NSControlView" ref="177317088"/>
+ <reference key="NSBackgroundColor" ref="616357123"/>
+ <reference key="NSTextColor" ref="1067694695"/>
+ </object>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+ </object>
+ <object class="NSTextField" id="772391111">
+ <reference key="NSNextResponder" ref="570115299"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{13, 37}, {40, 14}}</string>
+ <reference key="NSSuperview" ref="570115299"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="229843470"/>
+ <string key="NSReuseIdentifierKey">_NS:1535</string>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="673338681">
+ <int key="NSCellFlags">68157504</int>
+ <int key="NSCellFlags2">272761856</int>
+ <string key="NSContents">Height</string>
+ <reference key="NSSupport" ref="26"/>
+ <string key="NSCellIdentifier">_NS:1535</string>
+ <reference key="NSControlView" ref="772391111"/>
+ <reference key="NSBackgroundColor" ref="616357123"/>
+ <reference key="NSTextColor" ref="1067694695"/>
+ </object>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+ </object>
+ <object class="NSButton" id="285959694">
+ <reference key="NSNextResponder" ref="570115299"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{15, 83}, {80, 18}}</string>
+ <reference key="NSSuperview" ref="570115299"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="177317088"/>
+ <string key="NSReuseIdentifierKey">_NS:9</string>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="899503579">
+ <int key="NSCellFlags">-2080374784</int>
+ <int key="NSCellFlags2">268566528</int>
+ <string key="NSContents">Full Screen</string>
+ <reference key="NSSupport" ref="26"/>
+ <string key="NSCellIdentifier">_NS:9</string>
+ <reference key="NSControlView" ref="285959694"/>
+ <int key="NSButtonFlags">1211912448</int>
+ <int key="NSButtonFlags2">2</int>
+ <reference key="NSNormalImage" ref="19498200"/>
+ <reference key="NSAlternateImage" ref="233505524"/>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent"/>
+ <int key="NSPeriodicDelay">200</int>
+ <int key="NSPeriodicInterval">25</int>
+ </object>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+ </object>
+ <object class="NSTextField" id="229843470">
+ <reference key="NSNextResponder" ref="570115299"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{58, 35}, {65, 19}}</string>
+ <reference key="NSSuperview" ref="570115299"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="267578530"/>
+ <string key="NSReuseIdentifierKey">_NS:9</string>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="609783267">
+ <int key="NSCellFlags">-1804599231</int>
+ <int key="NSCellFlags2">272761856</int>
+ <string key="NSContents">480</string>
+ <reference key="NSSupport" ref="26"/>
+ <string key="NSCellIdentifier">_NS:9</string>
+ <reference key="NSControlView" ref="229843470"/>
+ <bool key="NSDrawsBackground">YES</bool>
+ <reference key="NSBackgroundColor" ref="604804392"/>
+ <reference key="NSTextColor" ref="15837238"/>
+ </object>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+ </object>
+ </array>
+ <string key="NSFrame">{{1, 1}, {141, 108}}</string>
+ <reference key="NSSuperview" ref="332651215"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="285959694"/>
+ <string key="NSReuseIdentifierKey">_NS:11</string>
+ </object>
+ </array>
+ <string key="NSFrame">{{174, 16}, {143, 124}}</string>
+ <reference key="NSSuperview" ref="414427165"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="570115299"/>
+ <string key="NSReuseIdentifierKey">_NS:9</string>
+ <string key="NSOffsets">{0, 0}</string>
+ <object class="NSTextFieldCell" key="NSTitleCell">
+ <int key="NSCellFlags">67108864</int>
+ <int key="NSCellFlags2">0</int>
+ <string key="NSContents">Game Window</string>
+ <reference key="NSSupport" ref="26"/>
+ <reference key="NSBackgroundColor" ref="604804392"/>
+ <object class="NSColor" key="NSTextColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MCAwLjgwMDAwMDAxMTkAA</bytes>
+ </object>
+ </object>
+ <reference key="NSContentView" ref="570115299"/>
+ <int key="NSBorderType">1</int>
+ <int key="NSBoxType">0</int>
+ <int key="NSTitlePosition">2</int>
+ <bool key="NSTransparent">NO</bool>
+ </object>
+ </array>
+ <string key="NSFrameSize">{414, 182}</string>
+ <reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="292409822"/>
+ </object>
+ <string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
+ <string key="NSMaxSize">{10000000000000, 10000000000000}</string>
+ <bool key="NSWindowIsRestorable">YES</bool>
+ </object>
+ <object class="NSUserDefaultsController" id="385123273">
+ <bool key="NSSharedInstance">YES</bool>
+ </object>
+ </array>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <array class="NSMutableArray" key="connectionRecords">
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">orderFrontStandardAboutPanel:</string>
+ <reference key="source" ref="1021"/>
+ <reference key="destination" ref="238522557"/>
+ </object>
+ <int key="connectionID">142</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">terminate:</string>
+ <reference key="source" ref="1021"/>
+ <reference key="destination" ref="632727374"/>
+ </object>
+ <int key="connectionID">448</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">openGame:</string>
+ <reference key="source" ref="1021"/>
+ <reference key="destination" ref="960485278"/>
+ </object>
+ <int key="connectionID">901</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">launchGame:</string>
+ <reference key="source" ref="1021"/>
+ <reference key="destination" ref="267578530"/>
+ </object>
+ <int key="connectionID">980</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">prefrences</string>
+ <reference key="source" ref="1021"/>
+ <reference key="destination" ref="513744381"/>
+ </object>
+ <int key="connectionID">981</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">openGame:</string>
+ <reference key="source" ref="1021"/>
+ <reference key="destination" ref="722745758"/>
+ </object>
+ <int key="connectionID">996</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">configWindow</string>
+ <reference key="source" ref="1021"/>
+ <reference key="destination" ref="513744381"/>
+ </object>
+ <int key="connectionID">997</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">print:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="49223823"/>
+ </object>
+ <int key="connectionID">86</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">runPageLayout:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="294629803"/>
+ </object>
+ <int key="connectionID">87</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">clearRecentDocuments:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="759406840"/>
+ </object>
+ <int key="connectionID">127</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">performClose:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="776162233"/>
+ </object>
+ <int key="connectionID">193</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">showHelp:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="238773614"/>
+ </object>
+ <int key="connectionID">360</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">saveDocument:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="1023925487"/>
+ </object>
+ <int key="connectionID">362</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">revertDocumentToSaved:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="579971712"/>
+ </object>
+ <int key="connectionID">364</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">hide:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="755159360"/>
+ </object>
+ <int key="connectionID">369</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">hideOtherApplications:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="342932134"/>
+ </object>
+ <int key="connectionID">370</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">unhideAllApplications:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="908899353"/>
+ </object>
+ <int key="connectionID">372</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">startSpeaking:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="476308533"/>
+ </object>
+ <int key="connectionID">950</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">copy:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="499410273"/>
+ </object>
+ <int key="connectionID">951</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">cut:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="327226428"/>
+ </object>
+ <int key="connectionID">952</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">toggleAutomaticSpellingCorrection:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="768164437"/>
+ </object>
+ <int key="connectionID">953</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">toggleSmartInsertDelete:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="809892461"/>
+ </object>
+ <int key="connectionID">954</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">checkSpelling:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="116276200"/>
+ </object>
+ <int key="connectionID">955</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">toggleContinuousSpellChecking:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="325876846"/>
+ </object>
+ <int key="connectionID">956</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">paste:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="610688774"/>
+ </object>
+ <int key="connectionID">957</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">toggleAutomaticDataDetection:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="259062896"/>
+ </object>
+ <int key="connectionID">958</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">toggleAutomaticTextReplacement:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="213997630"/>
+ </object>
+ <int key="connectionID">959</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">orderFrontSubstitutionsPanel:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="738094600"/>
+ </object>
+ <int key="connectionID">960</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">toggleAutomaticLinkDetection:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="424647815"/>
+ </object>
+ <int key="connectionID">961</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">uppercaseWord:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="112815381"/>
+ </object>
+ <int key="connectionID">962</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">lowercaseWord:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="634567257"/>
+ </object>
+ <int key="connectionID">963</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">toggleGrammarChecking:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="1073614422"/>
+ </object>
+ <int key="connectionID">964</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">showGuessPanel:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="1073299659"/>
+ </object>
+ <int key="connectionID">965</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">redo:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="588035066"/>
+ </object>
+ <int key="connectionID">966</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">delete:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="972907518"/>
+ </object>
+ <int key="connectionID">967</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">toggleAutomaticQuoteSubstitution:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="861597930"/>
+ </object>
+ <int key="connectionID">968</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">capitalizeWord:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="669637497"/>
+ </object>
+ <int key="connectionID">969</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">selectAll:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="414073690"/>
+ </object>
+ <int key="connectionID">970</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">stopSpeaking:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="214803442"/>
+ </object>
+ <int key="connectionID">971</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">undo:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="689132699"/>
+ </object>
+ <int key="connectionID">972</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">toggleAutomaticDashSubstitution:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="647578214"/>
+ </object>
+ <int key="connectionID">973</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">pasteAsPlainText:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="143408881"/>
+ </object>
+ <int key="connectionID">974</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">performFindPanelAction:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="1065735815"/>
+ </object>
+ <int key="connectionID">975</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">performFindPanelAction:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="915153746"/>
+ </object>
+ <int key="connectionID">976</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">performFindPanelAction:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="748212273"/>
+ </object>
+ <int key="connectionID">977</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">centerSelectionInVisibleArea:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="284401815"/>
+ </object>
+ <int key="connectionID">978</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">performFindPanelAction:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="582428080"/>
+ </object>
+ <int key="connectionID">979</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: values.GUIEnhancements</string>
+ <reference key="source" ref="514909995"/>
+ <reference key="destination" ref="385123273"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="514909995"/>
+ <reference key="NSDestination" ref="385123273"/>
+ <string key="NSLabel">value: values.GUIEnhancements</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">values.GUIEnhancements</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">883</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: values.SkipIntros</string>
+ <reference key="source" ref="81603430"/>
+ <reference key="destination" ref="385123273"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="81603430"/>
+ <reference key="NSDestination" ref="385123273"/>
+ <string key="NSLabel">value: values.SkipIntros</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">values.SkipIntros</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">885</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: values.DrawFPS</string>
+ <reference key="source" ref="426949335"/>
+ <reference key="destination" ref="385123273"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="426949335"/>
+ <reference key="NSDestination" ref="385123273"/>
+ <string key="NSLabel">value: values.DrawFPS</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">values.DrawFPS</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">887</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: values.FogOfWar</string>
+ <reference key="source" ref="1002349262"/>
+ <reference key="destination" ref="385123273"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="1002349262"/>
+ <reference key="NSDestination" ref="385123273"/>
+ <string key="NSLabel">value: values.FogOfWar</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">values.FogOfWar</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">888</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: values.EnableCheatKeys</string>
+ <reference key="source" ref="376604116"/>
+ <reference key="destination" ref="385123273"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="376604116"/>
+ <reference key="NSDestination" ref="385123273"/>
+ <string key="NSLabel">value: values.EnableCheatKeys</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">values.EnableCheatKeys</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">889</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: values.GamePath</string>
+ <reference key="source" ref="1027211632"/>
+ <reference key="destination" ref="385123273"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="1027211632"/>
+ <reference key="NSDestination" ref="385123273"/>
+ <string key="NSLabel">value: values.GamePath</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">values.GamePath</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">898</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: values.Width</string>
+ <reference key="source" ref="586782438"/>
+ <reference key="destination" ref="385123273"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="586782438"/>
+ <reference key="NSDestination" ref="385123273"/>
+ <string key="NSLabel">value: values.Width</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">values.Width</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">994</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: values.Height</string>
+ <reference key="source" ref="229843470"/>
+ <reference key="destination" ref="385123273"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="229843470"/>
+ <reference key="NSDestination" ref="385123273"/>
+ <string key="NSLabel">value: values.Height</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">values.Height</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">995</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: values.Fullscreen</string>
+ <reference key="source" ref="285959694"/>
+ <reference key="destination" ref="385123273"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="285959694"/>
+ <reference key="NSDestination" ref="385123273"/>
+ <string key="NSLabel">value: values.Fullscreen</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">values.Fullscreen</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">993</int>
+ </object>
+ </array>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <array key="orderedObjects">
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <array key="object" id="0"/>
+ <reference key="children" ref="1048"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="1021"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="1014"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">First Responder</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-3</int>
+ <reference key="object" ref="1050"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">Application</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">29</int>
+ <reference key="object" ref="649796088"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="694149608"/>
+ <reference ref="391199113"/>
+ <reference ref="379814623"/>
+ <reference ref="760709348"/>
+ </array>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">Main Menu</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">56</int>
+ <reference key="object" ref="694149608"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="110575045"/>
+ </array>
+ <reference key="parent" ref="649796088"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">103</int>
+ <reference key="object" ref="391199113"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="374024848"/>
+ </array>
+ <reference key="parent" ref="649796088"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">83</int>
+ <reference key="object" ref="379814623"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="720053764"/>
+ </array>
+ <reference key="parent" ref="649796088"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">81</int>
+ <reference key="object" ref="720053764"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="1023925487"/>
+ <reference ref="49223823"/>
+ <reference ref="722745758"/>
+ <reference ref="705341025"/>
+ <reference ref="1025936716"/>
+ <reference ref="294629803"/>
+ <reference ref="776162233"/>
+ <reference ref="425164168"/>
+ <reference ref="579971712"/>
+ <reference ref="1010469920"/>
+ </array>
+ <reference key="parent" ref="379814623"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">75</int>
+ <reference key="object" ref="1023925487"/>
+ <reference key="parent" ref="720053764"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">78</int>
+ <reference key="object" ref="49223823"/>
+ <reference key="parent" ref="720053764"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">72</int>
+ <reference key="object" ref="722745758"/>
+ <reference key="parent" ref="720053764"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">82</int>
+ <reference key="object" ref="705341025"/>
+ <reference key="parent" ref="720053764"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">124</int>
+ <reference key="object" ref="1025936716"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="1065607017"/>
+ </array>
+ <reference key="parent" ref="720053764"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">77</int>
+ <reference key="object" ref="294629803"/>
+ <reference key="parent" ref="720053764"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">73</int>
+ <reference key="object" ref="776162233"/>
+ <reference key="parent" ref="720053764"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">79</int>
+ <reference key="object" ref="425164168"/>
+ <reference key="parent" ref="720053764"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">112</int>
+ <reference key="object" ref="579971712"/>
+ <reference key="parent" ref="720053764"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">74</int>
+ <reference key="object" ref="1010469920"/>
+ <reference key="parent" ref="720053764"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">125</int>
+ <reference key="object" ref="1065607017"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="759406840"/>
+ </array>
+ <reference key="parent" ref="1025936716"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">126</int>
+ <reference key="object" ref="759406840"/>
+ <reference key="parent" ref="1065607017"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">106</int>
+ <reference key="object" ref="374024848"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="238773614"/>
+ </array>
+ <reference key="parent" ref="391199113"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">111</int>
+ <reference key="object" ref="238773614"/>
+ <reference key="parent" ref="374024848"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">57</int>
+ <reference key="object" ref="110575045"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="238522557"/>
+ <reference ref="755159360"/>
+ <reference ref="908899353"/>
+ <reference ref="632727374"/>
+ <reference ref="646227648"/>
+ <reference ref="609285721"/>
+ <reference ref="481834944"/>
+ <reference ref="304266470"/>
+ <reference ref="1046388886"/>
+ <reference ref="1056857174"/>
+ <reference ref="342932134"/>
+ </array>
+ <reference key="parent" ref="694149608"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">58</int>
+ <reference key="object" ref="238522557"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">134</int>
+ <reference key="object" ref="755159360"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">150</int>
+ <reference key="object" ref="908899353"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">136</int>
+ <reference key="object" ref="632727374"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">144</int>
+ <reference key="object" ref="646227648"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">129</int>
+ <reference key="object" ref="609285721"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">143</int>
+ <reference key="object" ref="481834944"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">236</int>
+ <reference key="object" ref="304266470"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">131</int>
+ <reference key="object" ref="1046388886"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="752062318"/>
+ </array>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">149</int>
+ <reference key="object" ref="1056857174"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">145</int>
+ <reference key="object" ref="342932134"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">130</int>
+ <reference key="object" ref="752062318"/>
+ <reference key="parent" ref="1046388886"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">367</int>
+ <reference key="object" ref="513744381"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="414427165"/>
+ </array>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">368</int>
+ <reference key="object" ref="414427165"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="973036919"/>
+ <reference ref="292409822"/>
+ <reference ref="1027211632"/>
+ <reference ref="960485278"/>
+ <reference ref="267578530"/>
+ <reference ref="332651215"/>
+ </array>
+ <reference key="parent" ref="513744381"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">373</int>
+ <reference key="object" ref="163992474"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">882</int>
+ <reference key="object" ref="385123273"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">891</int>
+ <reference key="object" ref="1027211632"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="8094530"/>
+ </array>
+ <reference key="parent" ref="414427165"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">892</int>
+ <reference key="object" ref="8094530"/>
+ <reference key="parent" ref="1027211632"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">893</int>
+ <reference key="object" ref="973036919"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="376604116"/>
+ <reference ref="1002349262"/>
+ <reference ref="426949335"/>
+ <reference ref="81603430"/>
+ <reference ref="514909995"/>
+ </array>
+ <reference key="parent" ref="414427165"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">839</int>
+ <reference key="object" ref="514909995"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="712348702"/>
+ </array>
+ <reference key="parent" ref="973036919"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">840</int>
+ <reference key="object" ref="712348702"/>
+ <reference key="parent" ref="514909995"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">844</int>
+ <reference key="object" ref="81603430"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="455129962"/>
+ </array>
+ <reference key="parent" ref="973036919"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">845</int>
+ <reference key="object" ref="455129962"/>
+ <reference key="parent" ref="81603430"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">849</int>
+ <reference key="object" ref="426949335"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="817985991"/>
+ </array>
+ <reference key="parent" ref="973036919"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">850</int>
+ <reference key="object" ref="817985991"/>
+ <reference key="parent" ref="426949335"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">854</int>
+ <reference key="object" ref="1002349262"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="828623902"/>
+ </array>
+ <reference key="parent" ref="973036919"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">855</int>
+ <reference key="object" ref="828623902"/>
+ <reference key="parent" ref="1002349262"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">859</int>
+ <reference key="object" ref="376604116"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="781005808"/>
+ </array>
+ <reference key="parent" ref="973036919"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">860</int>
+ <reference key="object" ref="781005808"/>
+ <reference key="parent" ref="376604116"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">894</int>
+ <reference key="object" ref="292409822"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="354930942"/>
+ </array>
+ <reference key="parent" ref="414427165"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">895</int>
+ <reference key="object" ref="354930942"/>
+ <reference key="parent" ref="292409822"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">899</int>
+ <reference key="object" ref="960485278"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="13942975"/>
+ </array>
+ <reference key="parent" ref="414427165"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">900</int>
+ <reference key="object" ref="13942975"/>
+ <reference key="parent" ref="960485278"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">902</int>
+ <reference key="object" ref="267578530"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="995000440"/>
+ </array>
+ <reference key="parent" ref="414427165"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">903</int>
+ <reference key="object" ref="995000440"/>
+ <reference key="parent" ref="267578530"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">904</int>
+ <reference key="object" ref="760709348"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="874538137"/>
+ </array>
+ <reference key="parent" ref="649796088"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">905</int>
+ <reference key="object" ref="874538137"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="689132699"/>
+ <reference ref="588035066"/>
+ <reference ref="19281719"/>
+ <reference ref="327226428"/>
+ <reference ref="499410273"/>
+ <reference ref="610688774"/>
+ <reference ref="143408881"/>
+ <reference ref="972907518"/>
+ <reference ref="414073690"/>
+ <reference ref="438589790"/>
+ <reference ref="34073996"/>
+ <reference ref="653847976"/>
+ <reference ref="438460389"/>
+ <reference ref="33629833"/>
+ <reference ref="168141218"/>
+ </array>
+ <reference key="parent" ref="760709348"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">906</int>
+ <reference key="object" ref="689132699"/>
+ <reference key="parent" ref="874538137"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">907</int>
+ <reference key="object" ref="588035066"/>
+ <reference key="parent" ref="874538137"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">908</int>
+ <reference key="object" ref="19281719"/>
+ <reference key="parent" ref="874538137"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">909</int>
+ <reference key="object" ref="327226428"/>
+ <reference key="parent" ref="874538137"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">910</int>
+ <reference key="object" ref="499410273"/>
+ <reference key="parent" ref="874538137"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">911</int>
+ <reference key="object" ref="610688774"/>
+ <reference key="parent" ref="874538137"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">912</int>
+ <reference key="object" ref="143408881"/>
+ <reference key="parent" ref="874538137"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">913</int>
+ <reference key="object" ref="972907518"/>
+ <reference key="parent" ref="874538137"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">914</int>
+ <reference key="object" ref="414073690"/>
+ <reference key="parent" ref="874538137"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">915</int>
+ <reference key="object" ref="438589790"/>
+ <reference key="parent" ref="874538137"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">916</int>
+ <reference key="object" ref="34073996"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="142787696"/>
+ </array>
+ <reference key="parent" ref="874538137"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">917</int>
+ <reference key="object" ref="653847976"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="961864607"/>
+ </array>
+ <reference key="parent" ref="874538137"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">918</int>
+ <reference key="object" ref="438460389"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="127406826"/>
+ </array>
+ <reference key="parent" ref="874538137"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">919</int>
+ <reference key="object" ref="33629833"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="165587917"/>
+ </array>
+ <reference key="parent" ref="874538137"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">920</int>
+ <reference key="object" ref="168141218"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="972561574"/>
+ </array>
+ <reference key="parent" ref="874538137"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">921</int>
+ <reference key="object" ref="972561574"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="476308533"/>
+ <reference ref="214803442"/>
+ </array>
+ <reference key="parent" ref="168141218"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">922</int>
+ <reference key="object" ref="476308533"/>
+ <reference key="parent" ref="972561574"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">923</int>
+ <reference key="object" ref="214803442"/>
+ <reference key="parent" ref="972561574"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">924</int>
+ <reference key="object" ref="165587917"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="112815381"/>
+ <reference ref="634567257"/>
+ <reference ref="669637497"/>
+ </array>
+ <reference key="parent" ref="33629833"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">925</int>
+ <reference key="object" ref="112815381"/>
+ <reference key="parent" ref="165587917"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">926</int>
+ <reference key="object" ref="634567257"/>
+ <reference key="parent" ref="165587917"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">927</int>
+ <reference key="object" ref="669637497"/>
+ <reference key="parent" ref="165587917"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">928</int>
+ <reference key="object" ref="127406826"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="738094600"/>
+ <reference ref="337624084"/>
+ <reference ref="809892461"/>
+ <reference ref="861597930"/>
+ <reference ref="647578214"/>
+ <reference ref="424647815"/>
+ <reference ref="259062896"/>
+ <reference ref="213997630"/>
+ </array>
+ <reference key="parent" ref="438460389"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">929</int>
+ <reference key="object" ref="738094600"/>
+ <reference key="parent" ref="127406826"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">930</int>
+ <reference key="object" ref="337624084"/>
+ <reference key="parent" ref="127406826"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">931</int>
+ <reference key="object" ref="809892461"/>
+ <reference key="parent" ref="127406826"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">932</int>
+ <reference key="object" ref="861597930"/>
+ <reference key="parent" ref="127406826"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">933</int>
+ <reference key="object" ref="647578214"/>
+ <reference key="parent" ref="127406826"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">934</int>
+ <reference key="object" ref="424647815"/>
+ <reference key="parent" ref="127406826"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">935</int>
+ <reference key="object" ref="259062896"/>
+ <reference key="parent" ref="127406826"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">936</int>
+ <reference key="object" ref="213997630"/>
+ <reference key="parent" ref="127406826"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">937</int>
+ <reference key="object" ref="961864607"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="1073299659"/>
+ <reference ref="116276200"/>
+ <reference ref="895226763"/>
+ <reference ref="325876846"/>
+ <reference ref="1073614422"/>
+ <reference ref="768164437"/>
+ </array>
+ <reference key="parent" ref="653847976"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">938</int>
+ <reference key="object" ref="1073299659"/>
+ <reference key="parent" ref="961864607"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">939</int>
+ <reference key="object" ref="116276200"/>
+ <reference key="parent" ref="961864607"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">940</int>
+ <reference key="object" ref="895226763"/>
+ <reference key="parent" ref="961864607"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">941</int>
+ <reference key="object" ref="325876846"/>
+ <reference key="parent" ref="961864607"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">942</int>
+ <reference key="object" ref="1073614422"/>
+ <reference key="parent" ref="961864607"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">943</int>
+ <reference key="object" ref="768164437"/>
+ <reference key="parent" ref="961864607"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">944</int>
+ <reference key="object" ref="142787696"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="748212273"/>
+ <reference ref="1065735815"/>
+ <reference ref="582428080"/>
+ <reference ref="915153746"/>
+ <reference ref="284401815"/>
+ </array>
+ <reference key="parent" ref="34073996"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">945</int>
+ <reference key="object" ref="748212273"/>
+ <reference key="parent" ref="142787696"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">946</int>
+ <reference key="object" ref="1065735815"/>
+ <reference key="parent" ref="142787696"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">947</int>
+ <reference key="object" ref="582428080"/>
+ <reference key="parent" ref="142787696"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">948</int>
+ <reference key="object" ref="915153746"/>
+ <reference key="parent" ref="142787696"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">949</int>
+ <reference key="object" ref="284401815"/>
+ <reference key="parent" ref="142787696"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">992</int>
+ <reference key="object" ref="332651215"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="285959694"/>
+ <reference ref="177317088"/>
+ <reference ref="586782438"/>
+ <reference ref="229843470"/>
+ <reference ref="772391111"/>
+ </array>
+ <reference key="parent" ref="414427165"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">982</int>
+ <reference key="object" ref="586782438"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="226663740"/>
+ </array>
+ <reference key="parent" ref="332651215"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">983</int>
+ <reference key="object" ref="226663740"/>
+ <reference key="parent" ref="586782438"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">984</int>
+ <reference key="object" ref="177317088"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="31322398"/>
+ </array>
+ <reference key="parent" ref="332651215"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">985</int>
+ <reference key="object" ref="31322398"/>
+ <reference key="parent" ref="177317088"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">986</int>
+ <reference key="object" ref="772391111"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="673338681"/>
+ </array>
+ <reference key="parent" ref="332651215"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">987</int>
+ <reference key="object" ref="673338681"/>
+ <reference key="parent" ref="772391111"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">990</int>
+ <reference key="object" ref="285959694"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="899503579"/>
+ </array>
+ <reference key="parent" ref="332651215"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">991</int>
+ <reference key="object" ref="899503579"/>
+ <reference key="parent" ref="285959694"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">988</int>
+ <reference key="object" ref="229843470"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="609783267"/>
+ </array>
+ <reference key="parent" ref="332651215"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">989</int>
+ <reference key="object" ref="609783267"/>
+ <reference key="parent" ref="229843470"/>
+ </object>
+ </array>
+ </object>
+ <dictionary class="NSMutableDictionary" key="flattenedProperties">
+ <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="-3.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="103.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="106.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="111.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="112.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="124.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="125.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="126.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="129.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="130.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="131.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="134.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="136.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="143.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="144.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="145.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="149.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="150.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="236.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="29.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="367.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="367.IBWindowTemplateEditedContentRect">{{307, 836}, {480, 270}}</string>
+ <boolean value="NO" key="367.NSWindowTemplate.visibleAtLaunch"/>
+ <string key="368.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="373.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="56.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="57.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="58.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="72.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="73.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="74.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="75.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="77.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="78.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="79.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="81.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="82.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="83.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="839.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="840.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="844.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="845.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="849.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="850.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="854.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="855.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="859.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="860.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="882.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="891.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="892.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="893.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="894.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="895.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="899.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="900.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="902.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="903.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="904.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="905.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="906.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="907.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="908.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="909.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="910.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="911.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="912.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="913.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="914.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="915.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="916.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="917.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="918.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="919.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="920.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="921.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="922.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="923.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="924.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="925.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="926.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="927.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="928.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="929.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="930.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="931.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="932.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="933.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="934.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="935.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="936.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="937.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="938.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="939.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="940.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="941.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="942.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="943.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="944.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="945.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="946.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="947.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="948.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="949.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="982.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="983.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="984.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="985.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="986.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="987.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="988.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="989.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="990.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="991.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="992.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+ <nil key="activeLocalization"/>
+ <dictionary class="NSMutableDictionary" key="localizations"/>
+ <nil key="sourceID"/>
+ <int key="maxID">997</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <array class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <object class="IBPartialClassDescription">
+ <string key="className">CocoaWrapper</string>
+ <string key="superclassName">NSObject</string>
+ <object class="NSMutableDictionary" key="actions">
+ <string key="NS.key.0">openGame:</string>
+ <string key="NS.object.0">id</string>
+ </object>
+ <object class="NSMutableDictionary" key="actionInfosByName">
+ <string key="NS.key.0">openGame:</string>
+ <object class="IBActionInfo" key="NS.object.0">
+ <string key="name">openGame:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/CocoaWrapper.h</string>
+ </object>
+ </object>
+ </array>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
+ <real value="1050" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <dictionary class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
+ <string key="NSMenuCheckmark">{11, 11}</string>
+ <string key="NSMenuMixedState">{10, 3}</string>
+ <string key="NSSwitch">{15, 15}</string>
+ </dictionary>
+ </data>
+</archive>
diff --git a/apple/English.lproj/InfoPlist.strings b/apple/English.lproj/InfoPlist.strings
new file mode 100644
index 0000000..626e832
Binary files /dev/null and b/apple/English.lproj/InfoPlist.strings differ
diff --git a/apple/GemRB.xcodeproj/.dat08e7.87f b/apple/GemRB.xcodeproj/.dat08e7.87f
new file mode 100644
index 0000000..87c0b47
--- /dev/null
+++ b/apple/GemRB.xcodeproj/.dat08e7.87f
@@ -0,0 +1,7366 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
+ 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+ A208210D1419712F002CD244 /* String.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECEC13A8669700C6DF12 /* String.cpp */; };
+ A208210E1419712F002CD244 /* IndexedArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECD913A8661600C6DF12 /* IndexedArchive.cpp */; };
+ A20821101419712F002CD244 /* PluginLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECDB13A8661600C6DF12 /* PluginLoader.cpp */; };
+ A20821111419712F002CD244 /* MemoryStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0601395FF62006ADC12 /* MemoryStream.cpp */; };
+ A20C698013B0FA430082EEBA /* AmbientMgrAL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8737139F0A7D0002DC13 /* AmbientMgrAL.cpp */; };
+ A20C698113B0FA430082EEBA /* OpenALAudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B873B139F0A7D0002DC13 /* OpenALAudio.cpp */; };
+ A20C698213B0FA430082EEBA /* StackLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B873D139F0A7D0002DC13 /* StackLock.cpp */; };
+ A22693791422934E004468E8 /* CocoaWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = A249187B141075A60038B170 /* CocoaWrapper.m */; settings = {COMPILER_FLAGS = "-DTARGET_OS_MAC"; }; };
+ A226F41013A119D8009CE75E /* 2DAImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8699139F0A7D0002DC13 /* 2DAImporter.cpp */; };
+ A226F41113A119E2009CE75E /* ACMReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B869E139F0A7D0002DC13 /* ACMReader.cpp */; };
+ A226F41213A119E2009CE75E /* decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86A1139F0A7D0002DC13 /* decoder.cpp */; };
+ A226F41313A119E2009CE75E /* unpacker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86A5139F0A7D0002DC13 /* unpacker.cpp */; };
+ A226F41413A119E5009CE75E /* ACMReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B869E139F0A7D0002DC13 /* ACMReader.cpp */; };
+ A226F41513A119E5009CE75E /* decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86A1139F0A7D0002DC13 /* decoder.cpp */; };
+ A226F41613A119E5009CE75E /* unpacker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86A5139F0A7D0002DC13 /* unpacker.cpp */; };
+ A226F41713A119EA009CE75E /* AREImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86A8139F0A7D0002DC13 /* AREImporter.cpp */; };
+ A226F41813A119F1009CE75E /* BAMImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86AD139F0A7D0002DC13 /* BAMImporter.cpp */; };
+ A226F41913A119F6009CE75E /* BIFImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86B2139F0A7D0002DC13 /* BIFImporter.cpp */; };
+ A226F41A13A11A00009CE75E /* BIKPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86B7139F0A7D0002DC13 /* BIKPlayer.cpp */; };
+ A226F41B13A11A00009CE75E /* dct.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86BC139F0A7D0002DC13 /* dct.cpp */; };
+ A226F41C13A11A00009CE75E /* fft.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86BE139F0A7D0002DC13 /* fft.cpp */; };
+ A226F41D13A11A00009CE75E /* GetBitContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86BF139F0A7D0002DC13 /* GetBitContext.cpp */; };
+ A226F41E13A11A00009CE75E /* mem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86C2139F0A7D0002DC13 /* mem.cpp */; };
+ A226F41F13A11A00009CE75E /* rational.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86C3139F0A7D0002DC13 /* rational.cpp */; };
+ A226F42013A11A00009CE75E /* rdft.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86C5139F0A7D0002DC13 /* rdft.cpp */; };
+ A226F42113A11A07009CE75E /* BMPImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86C7139F0A7D0002DC13 /* BMPImporter.cpp */; };
+ A226F42213A11A0C009CE75E /* BMPWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86CC139F0A7D0002DC13 /* BMPWriter.cpp */; };
+ A226F42313A11A11009CE75E /* CHUImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86D1139F0A7D0002DC13 /* CHUImporter.cpp */; };
+ A226F42413A11A17009CE75E /* CREImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86D8139F0A7D0002DC13 /* CREImporter.cpp */; };
+ A226F42513A11A1C009CE75E /* DirectoryImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86DD139F0A7D0002DC13 /* DirectoryImporter.cpp */; };
+ A226F42613A11A22009CE75E /* DLGImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86E2139F0A7D0002DC13 /* DLGImporter.cpp */; };
+ A226F42713A11A27009CE75E /* EFFImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86E7139F0A7D0002DC13 /* EFFImporter.cpp */; };
+ A226F42813A11A2C009CE75E /* FXOpcodes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86EC139F0A7D0002DC13 /* FXOpcodes.cpp */; };
+ A226F42913A11A31009CE75E /* GAMImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86F0139F0A7D0002DC13 /* GAMImporter.cpp */; };
+ A226F42A13A11A39009CE75E /* GUIScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86F5139F0A7D0002DC13 /* GUIScript.cpp */; };
+ A226F42B13A11A39009CE75E /* PythonHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86F8139F0A7D0002DC13 /* PythonHelpers.cpp */; };
+ A226F42C13A11A3F009CE75E /* IDSImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86FC139F0A7D0002DC13 /* IDSImporter.cpp */; };
+ A226F42D13A11A44009CE75E /* INIImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8702139F0A7D0002DC13 /* INIImporter.cpp */; };
+ A226F42E13A11A49009CE75E /* ITMImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8707139F0A7D0002DC13 /* ITMImporter.cpp */; };
+ A226F42F13A11A4E009CE75E /* IWDOpcodes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B870C139F0A7D0002DC13 /* IWDOpcodes.cpp */; };
+ A226F43113A11A53009CE75E /* KEYImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8712139F0A7D0002DC13 /* KEYImporter.cpp */; };
+ A226F43213A11A58009CE75E /* MOSImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8719139F0A7D0002DC13 /* MOSImporter.cpp */; };
+ A226F43313A11A5E009CE75E /* MUSImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B871E139F0A7D0002DC13 /* MUSImporter.cpp */; };
+ A226F43413A11A66009CE75E /* mve_player.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8725139F0A7D0002DC13 /* mve_player.cpp */; };
+ A226F43513A11A66009CE75E /* mveaudiodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8727139F0A7D0002DC13 /* mveaudiodec.cpp */; };
+ A226F43613A11A66009CE75E /* MVEPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8728139F0A7D0002DC13 /* MVEPlayer.cpp */; };
+ A226F43713A11A66009CE75E /* mvevideodec16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B872A139F0A7D0002DC13 /* mvevideodec16.cpp */; };
+ A226F43813A11A66009CE75E /* mvevideodec8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B872B139F0A7D0002DC13 /* mvevideodec8.cpp */; };
+ A226F43E13A11A7E009CE75E /* PLTImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8742139F0A7D0002DC13 /* PLTImporter.cpp */; };
+ A226F44013A11A8D009CE75E /* PROImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B874C139F0A7D0002DC13 /* PROImporter.cpp */; };
+ A226F44113A11A94009CE75E /* PSTOpcodes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8751139F0A7D0002DC13 /* PSTOpcodes.cpp */; };
+ A226F44413A11AA3009CE75E /* SPLImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8761139F0A7D0002DC13 /* SPLImporter.cpp */; };
+ A226F44513A11AA8009CE75E /* STOImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8766139F0A7D0002DC13 /* STOImporter.cpp */; };
+ A226F44613A11AAC009CE75E /* TISImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B876B139F0A7D0002DC13 /* TISImporter.cpp */; };
+ A226F44713A11AB4009CE75E /* TLKImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8770139F0A7D0002DC13 /* TLKImporter.cpp */; };
+ A226F44813A11AB4009CE75E /* TlkOverride.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8772139F0A7D0002DC13 /* TlkOverride.cpp */; };
+ A226F44913A11AB9009CE75E /* WAVReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8777139F0A7D0002DC13 /* WAVReader.cpp */; };
+ A226F44A13A11ABE009CE75E /* WEDImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B877C139F0A7D0002DC13 /* WEDImporter.cpp */; };
+ A226F44B13A11AC3009CE75E /* WMPImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8781139F0A7D0002DC13 /* WMPImporter.cpp */; };
+ A226F44C13A11AC8009CE75E /* ZLibManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8786139F0A7D0002DC13 /* ZLibManager.cpp */; };
+ A239390B145F8677007895B3 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A239390A145F8677007895B3 /* UIKit.framework */; };
+ A23EBFFA141979D500CC049E /* KeyMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECDA13A8661600C6DF12 /* KeyMap.cpp */; };
+ A2491881141092F20038B170 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2491880141092F20038B170 /* Cocoa.framework */; };
+ A24E8BAD1405AAB200FD17D1 /* GemRB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BD82721396B886007E9C63 /* GemRB.cpp */; };
+ A259F3F7142BFBCD00D49124 /* SDL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A259F3F5142BFBCD00D49124 /* SDL.framework */; };
+ A259F3F8142BFBCD00D49124 /* SDL_ttf.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A259F3F6142BFBCD00D49124 /* SDL_ttf.framework */; };
+ A265ECDC13A8661600C6DF12 /* FileCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECD813A8661600C6DF12 /* FileCache.cpp */; };
+ A265ECDD13A8661600C6DF12 /* IndexedArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECD913A8661600C6DF12 /* IndexedArchive.cpp */; };
+ A265ECDE13A8661600C6DF12 /* KeyMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECDA13A8661600C6DF12 /* KeyMap.cpp */; };
+ A265ECDF13A8661600C6DF12 /* PluginLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECDB13A8661600C6DF12 /* PluginLoader.cpp */; };
+ A265ECE013A8661600C6DF12 /* FileCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECD813A8661600C6DF12 /* FileCache.cpp */; };
+ A265ECED13A8669700C6DF12 /* Logging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECEA13A8669700C6DF12 /* Logging.cpp */; };
+ A265ECEE13A8669700C6DF12 /* SlicedStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECEB13A8669700C6DF12 /* SlicedStream.cpp */; };
+ A265ECEF13A8669700C6DF12 /* String.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECEC13A8669700C6DF12 /* String.cpp */; };
+ A265ECF013A8669700C6DF12 /* Logging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECEA13A8669700C6DF12 /* Logging.cpp */; };
+ A265ECF113A8669700C6DF12 /* SlicedStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECEB13A8669700C6DF12 /* SlicedStream.cpp */; };
+ A2690313142BEE2F003E8BCC /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B4C513A28B0000D41A8A /* BIFImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86B2139F0A7D0002DC13 /* BIFImporter.cpp */; };
+ A276B4C613A28B0D00D41A8A /* BIKPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86B7139F0A7D0002DC13 /* BIKPlayer.cpp */; };
+ A276B4C713A28B0D00D41A8A /* dct.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86BC139F0A7D0002DC13 /* dct.cpp */; };
+ A276B4C813A28B0D00D41A8A /* fft.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86BE139F0A7D0002DC13 /* fft.cpp */; };
+ A276B4C913A28B0D00D41A8A /* GetBitContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86BF139F0A7D0002DC13 /* GetBitContext.cpp */; };
+ A276B4CA13A28B0D00D41A8A /* mem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86C2139F0A7D0002DC13 /* mem.cpp */; };
+ A276B4CB13A28B0D00D41A8A /* rational.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86C3139F0A7D0002DC13 /* rational.cpp */; };
+ A276B4CC13A28B0D00D41A8A /* rdft.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86C5139F0A7D0002DC13 /* rdft.cpp */; };
+ A276B4CD13A28B2000D41A8A /* BMPImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86C7139F0A7D0002DC13 /* BMPImporter.cpp */; };
+ A276B4CE13A28B2900D41A8A /* BMPWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86CC139F0A7D0002DC13 /* BMPWriter.cpp */; };
+ A276B4CF13A28B2F00D41A8A /* CHUImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86D1139F0A7D0002DC13 /* CHUImporter.cpp */; };
+ A276B4D013A28B3500D41A8A /* CREImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86D8139F0A7D0002DC13 /* CREImporter.cpp */; };
+ A276B4D113A28B3B00D41A8A /* DirectoryImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86DD139F0A7D0002DC13 /* DirectoryImporter.cpp */; };
+ A276B4D213A28B4300D41A8A /* DLGImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86E2139F0A7D0002DC13 /* DLGImporter.cpp */; };
+ A276B4D313A28B4B00D41A8A /* EFFImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86E7139F0A7D0002DC13 /* EFFImporter.cpp */; };
+ A276B4D413A28B5000D41A8A /* FXOpcodes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86EC139F0A7D0002DC13 /* FXOpcodes.cpp */; };
+ A276B4D513A28B5600D41A8A /* GAMImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86F0139F0A7D0002DC13 /* GAMImporter.cpp */; };
+ A276B4D613A28B5E00D41A8A /* GUIScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86F5139F0A7D0002DC13 /* GUIScript.cpp */; };
+ A276B4D713A28B5E00D41A8A /* PythonHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86F8139F0A7D0002DC13 /* PythonHelpers.cpp */; };
+ A276B4D813A28B6600D41A8A /* IDSImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86FC139F0A7D0002DC13 /* IDSImporter.cpp */; };
+ A276B4D913A28B6B00D41A8A /* INIImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8702139F0A7D0002DC13 /* INIImporter.cpp */; };
+ A276B4DA13A28B7200D41A8A /* ITMImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8707139F0A7D0002DC13 /* ITMImporter.cpp */; };
+ A276B4DB13A28B7D00D41A8A /* IWDOpcodes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B870C139F0A7D0002DC13 /* IWDOpcodes.cpp */; };
+ A276B4DD13A28B8500D41A8A /* KEYImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8712139F0A7D0002DC13 /* KEYImporter.cpp */; };
+ A276B4DE13A28B8D00D41A8A /* MOSImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8719139F0A7D0002DC13 /* MOSImporter.cpp */; };
+ A276B4DF13A28B9400D41A8A /* MUSImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B871E139F0A7D0002DC13 /* MUSImporter.cpp */; };
+ A276B4E013A28B9F00D41A8A /* mve_player.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8725139F0A7D0002DC13 /* mve_player.cpp */; };
+ A276B4E113A28B9F00D41A8A /* mveaudiodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8727139F0A7D0002DC13 /* mveaudiodec.cpp */; };
+ A276B4E213A28B9F00D41A8A /* MVEPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8728139F0A7D0002DC13 /* MVEPlayer.cpp */; };
+ A276B4E313A28B9F00D41A8A /* mvevideodec16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B872A139F0A7D0002DC13 /* mvevideodec16.cpp */; };
+ A276B4E413A28B9F00D41A8A /* mvevideodec8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B872B139F0A7D0002DC13 /* mvevideodec8.cpp */; };
+ A276B4E513A28BA500D41A8A /* NullSound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B872F139F0A7D0002DC13 /* NullSound.cpp */; };
+ A276B4E613A28BAC00D41A8A /* OGGReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8734139F0A7D0002DC13 /* OGGReader.cpp */; };
+ A276B4E713A28BB400D41A8A /* AmbientMgrAL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8737139F0A7D0002DC13 /* AmbientMgrAL.cpp */; };
+ A276B4E813A28BB400D41A8A /* OpenALAudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B873B139F0A7D0002DC13 /* OpenALAudio.cpp */; };
+ A276B4E913A28BB400D41A8A /* StackLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B873D139F0A7D0002DC13 /* StackLock.cpp */; };
+ A276B4EA13A28BBC00D41A8A /* PLTImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8742139F0A7D0002DC13 /* PLTImporter.cpp */; };
+ A276B4EB13A28BC500D41A8A /* PNGImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8747139F0A7D0002DC13 /* PNGImporter.cpp */; };
+ A276B4EC13A28BCC00D41A8A /* PROImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B874C139F0A7D0002DC13 /* PROImporter.cpp */; };
+ A276B4ED13A28BD400D41A8A /* PSTOpcodes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8751139F0A7D0002DC13 /* PSTOpcodes.cpp */; };
+ A276B4EE13A28BDB00D41A8A /* SDLAudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8755139F0A7D0002DC13 /* SDLAudio.cpp */; };
+ A276B4EF13A28BE100D41A8A /* SDLVideo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B875A139F0A7D0002DC13 /* SDLVideo.cpp */; };
+ A276B4F013A28BE800D41A8A /* SPLImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8761139F0A7D0002DC13 /* SPLImporter.cpp */; };
+ A276B4F713A28C1300D41A8A /* STOImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8766139F0A7D0002DC13 /* STOImporter.cpp */; };
+ A276B4F813A28C2200D41A8A /* TISImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B876B139F0A7D0002DC13 /* TISImporter.cpp */; };
+ A276B4F913A28C2900D41A8A /* TLKImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8770139F0A7D0002DC13 /* TLKImporter.cpp */; };
+ A276B4FA13A28C2900D41A8A /* TlkOverride.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8772139F0A7D0002DC13 /* TlkOverride.cpp */; };
+ A276B4FB13A28C3000D41A8A /* WAVReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8777139F0A7D0002DC13 /* WAVReader.cpp */; };
+ A276B4FC13A28C3500D41A8A /* WEDImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B877C139F0A7D0002DC13 /* WEDImporter.cpp */; };
+ A276B4FD13A28C3B00D41A8A /* WMPImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8781139F0A7D0002DC13 /* WMPImporter.cpp */; };
+ A276B4FE13A28C4100D41A8A /* ZLibManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8786139F0A7D0002DC13 /* ZLibManager.cpp */; };
+ A276B52513A28CC900D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B52613A28CD300D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B52713A28CD800D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B52813A28CDD00D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B52913A28CE000D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B52A13A28CE400D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B52B13A28CEA00D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B52C13A28CF000D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B52D13A28CF400D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B52E13A28CF700D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B52F13A28CFA00D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53013A28D0000D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53113A28D0600D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53213A28D0900D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53313A28D0C00D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53413A28D0F00D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53513A28D1200D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53613A28D1500D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53713A28D1800D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53813A28D1B00D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53913A28D1F00D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53A13A28D2300D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53B13A28D2500D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53C13A28D2800D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53D13A28D2A00D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53E13A28D2D00D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53F13A28D3000D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B54013A28D3500D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B54113A28D3D00D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B54213A28D4000D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B54313A28D4300D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B54413A28D4600D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B54513A28D4900D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B54613A28D4C00D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B54713A28D5500D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B54813A28D5900D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B54913A28D5D00D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A27979AF13ABA509009A6FEF /* SAVImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27979AC13ABA4F7009A6FEF /* SAVImporter.cpp */; };
+ A27A81C4145F12CE00883469 /* CocoaWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = A27A81C2145F12CD00883469 /* CocoaWrapper.m */; };
+ A27E831313A035C600B41410 /* 2DAImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8699139F0A7D0002DC13 /* 2DAImporter.cpp */; };
+ A28D2499143BEA4200A27897 /* FontManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A28D2498143BEA4200A27897 /* FontManager.cpp */; };
+ A28D249A143BEA4200A27897 /* FontManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A28D2498143BEA4200A27897 /* FontManager.cpp */; };
+ A28D249C143BEA5800A27897 /* FontManager.h in Headers */ = {isa = PBXBuildFile; fileRef = A28D249B143BEA5800A27897 /* FontManager.h */; };
+ A29BF81313A03C2600C812DD /* AREImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86A8139F0A7D0002DC13 /* AREImporter.cpp */; };
+ A29BF82B13A03DFC00C812DD /* BAMImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86AD139F0A7D0002DC13 /* BAMImporter.cpp */; };
+ A29BF85213A0420300C812DD /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A29BF85513A0420A00C812DD /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A29BF85613A0420F00C812DD /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A29BF85713A0421200C812DD /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A29BF86613A0431300C812DD /* GemRB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BD82721396B886007E9C63 /* GemRB.cpp */; };
+ A29BF8A213A04A6F00C812DD /* ActorMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F8D1395FF61006ADC12 /* ActorMgr.cpp */; };
+ A29BF8A313A04A6F00C812DD /* Ambient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F8F1395FF61006ADC12 /* Ambient.cpp */; };
+ A29BF8A413A04A6F00C812DD /* AmbientMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F911395FF61006ADC12 /* AmbientMgr.cpp */; };
+ A29BF8A513A04A6F00C812DD /* Animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F931395FF61006ADC12 /* Animation.cpp */; };
+ A29BF8A613A04A6F00C812DD /* AnimationFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F951395FF61006ADC12 /* AnimationFactory.cpp */; };
+ A29BF8A713A04A6F00C812DD /* AnimationMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F971395FF61006ADC12 /* AnimationMgr.cpp */; };
+ A29BF8A813A04A6F00C812DD /* ArchiveImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F9A1395FF61006ADC12 /* ArchiveImporter.cpp */; };
+ A29BF8A913A04A6F00C812DD /* Audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F9C1395FF61006ADC12 /* Audio.cpp */; };
+ A29BF8AA13A04A6F00C812DD /* Bitmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F9E1395FF61006ADC12 /* Bitmap.cpp */; };
+ A29BF8AB13A04A6F00C812DD /* Cache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FA01395FF61006ADC12 /* Cache.cpp */; };
+ A29BF8AC13A04A6F00C812DD /* Calendar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FA21395FF61006ADC12 /* Calendar.cpp */; };
+ A29BF8AD13A04A6F00C812DD /* Callback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FA41395FF61006ADC12 /* Callback.cpp */; };
+ A29BF8AE13A04A6F00C812DD /* CharAnimations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FA61395FF61006ADC12 /* CharAnimations.cpp */; };
+ A29BF8AF13A04A6F00C812DD /* Compressor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FA91395FF61006ADC12 /* Compressor.cpp */; };
+ A29BF8B013A04A6F00C812DD /* ControlAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FAB1395FF61006ADC12 /* ControlAnimation.cpp */; };
+ A29BF8B113A04A6F00C812DD /* Core.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FAD1395FF61006ADC12 /* Core.cpp */; };
+ A29BF8B213A04A6F00C812DD /* DataFileMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FAF1395FF61006ADC12 /* DataFileMgr.cpp */; };
+ A29BF8B313A04A6F00C812DD /* Dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FB11395FF61006ADC12 /* Dialog.cpp */; };
+ A29BF8B413A04A6F00C812DD /* DialogHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FB31395FF61006ADC12 /* DialogHandler.cpp */; };
+ A29BF8B513A04A6F00C812DD /* DialogMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FB51395FF61006ADC12 /* DialogMgr.cpp */; };
+ A29BF8B613A04A6F00C812DD /* DisplayMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FB71395FF61006ADC12 /* DisplayMessage.cpp */; };
+ A29BF8B713A04A6F00C812DD /* EffectMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FBA1395FF61006ADC12 /* EffectMgr.cpp */; };
+ A29BF8B813A04A6F00C812DD /* EffectQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FBC1395FF61006ADC12 /* EffectQueue.cpp */; };
+ A29BF8B913A04A6F00C812DD /* Factory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FBE1395FF61006ADC12 /* Factory.cpp */; };
+ A29BF8BA13A04A6F00C812DD /* FactoryObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FC01395FF61006ADC12 /* FactoryObject.cpp */; };
+ A29BF8BB13A04A6F00C812DD /* Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FC21395FF61006ADC12 /* Font.cpp */; };
+ A29BF8BC13A04A6F00C812DD /* Game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FC41395FF61006ADC12 /* Game.cpp */; };
+ A29BF8BD13A04A6F00C812DD /* GameData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FC61395FF62006ADC12 /* GameData.cpp */; };
+ A29BF8BE13A04A6F00C812DD /* GlobalTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FD21395FF62006ADC12 /* GlobalTimer.cpp */; };
+ A29BF8BF13A04A6F00C812DD /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FF21395FF62006ADC12 /* Image.cpp */; };
+ A29BF8C013A04A6F00C812DD /* ImageFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FF41395FF62006ADC12 /* ImageFactory.cpp */; };
+ A29BF8C113A04A6F00C812DD /* ImageMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FF61395FF62006ADC12 /* ImageMgr.cpp */; };
+ A29BF8C213A04A6F00C812DD /* ImageWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FF81395FF62006ADC12 /* ImageWriter.cpp */; };
+ A29BF8C313A04A6F00C812DD /* IniSpawn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FFA1395FF62006ADC12 /* IniSpawn.cpp */; };
+ A29BF8C413A04A6F00C812DD /* Interface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FFC1395FF62006ADC12 /* Interface.cpp */; };
+ A29BF8C513A04A6F00C812DD /* Inventory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FFE1395FF62006ADC12 /* Inventory.cpp */; };
+ A29BF8C613A04A6F00C812DD /* Item.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0001395FF62006ADC12 /* Item.cpp */; };
+ A29BF8C713A04A6F00C812DD /* ItemMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0021395FF62006ADC12 /* ItemMgr.cpp */; };
+ A29BF8C813A04A6F00C812DD /* LRUCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0041395FF62006ADC12 /* LRUCache.cpp */; };
+ A29BF8C913A04A6F00C812DD /* Map.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0071395FF62006ADC12 /* Map.cpp */; };
+ A29BF8CA13A04A6F00C812DD /* MapMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0091395FF62006ADC12 /* MapMgr.cpp */; };
+ A29BF8CB13A04A6F00C812DD /* MoviePlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA00B1395FF62006ADC12 /* MoviePlayer.cpp */; };
+ A29BF8CC13A04A6F00C812DD /* MusicMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA00D1395FF62006ADC12 /* MusicMgr.cpp */; };
+ A29BF8CD13A04A6F00C812DD /* Palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA00F1395FF62006ADC12 /* Palette.cpp */; };
+ A29BF8CE13A04A6F00C812DD /* PalettedImageMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0111395FF62006ADC12 /* PalettedImageMgr.cpp */; };
+ A29BF8CF13A04A6F00C812DD /* Particles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0131395FF62006ADC12 /* Particles.cpp */; };
+ A29BF8D013A04A6F00C812DD /* Plugin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0161395FF62006ADC12 /* Plugin.cpp */; };
+ A29BF8D113A04A6F00C812DD /* PluginMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0181395FF62006ADC12 /* PluginMgr.cpp */; };
+ A29BF8D213A04A6F00C812DD /* Polygon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA01A1395FF62006ADC12 /* Polygon.cpp */; };
+ A29BF8D313A04A6F00C812DD /* Projectile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA01D1395FF62006ADC12 /* Projectile.cpp */; };
+ A29BF8D413A04A6F00C812DD /* ProjectileMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA01F1395FF62006ADC12 /* ProjectileMgr.cpp */; };
+ A29BF8D513A04A6F00C812DD /* ProjectileServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0211395FF62006ADC12 /* ProjectileServer.cpp */; };
+ A29BF8D613A04A6F00C812DD /* Region.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0231395FF62006ADC12 /* Region.cpp */; };
+ A29BF8D713A04A6F00C812DD /* Resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0251395FF62006ADC12 /* Resource.cpp */; };
+ A29BF8D813A04A6F00C812DD /* ResourceDesc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0271395FF62006ADC12 /* ResourceDesc.cpp */; };
+ A29BF8D913A04A6F00C812DD /* ResourceManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0291395FF62006ADC12 /* ResourceManager.cpp */; };
+ A29BF8DA13A04A6F00C812DD /* ResourceSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA02B1395FF62006ADC12 /* ResourceSource.cpp */; };
+ A29BF8DB13A04A6F00C812DD /* SaveGameIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA02E1395FF62006ADC12 /* SaveGameIterator.cpp */; };
+ A29BF8DC13A04A6F00C812DD /* SaveGameMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0301395FF62006ADC12 /* SaveGameMgr.cpp */; };
+ A29BF8DD13A04A6F00C812DD /* ScriptedAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA03F1395FF62006ADC12 /* ScriptedAnimation.cpp */; };
+ A29BF8DE13A04A6F00C812DD /* ScriptEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0411395FF62006ADC12 /* ScriptEngine.cpp */; };
+ A29BF8DF13A04A6F00C812DD /* SoundMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0431395FF62006ADC12 /* SoundMgr.cpp */; };
+ A29BF8E013A04A6F00C812DD /* Spell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0451395FF62006ADC12 /* Spell.cpp */; };
+ A29BF8E113A04A6F00C812DD /* Spellbook.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0471395FF62006ADC12 /* Spellbook.cpp */; };
+ A29BF8E213A04A6F00C812DD /* SpellMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0491395FF62006ADC12 /* SpellMgr.cpp */; };
+ A29BF8E313A04A6F00C812DD /* Sprite2D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA04B1395FF62006ADC12 /* Sprite2D.cpp */; };
+ A29BF8E413A04A6F00C812DD /* SpriteCover.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA04D1395FF62006ADC12 /* SpriteCover.cpp */; };
+ A29BF8E513A04A6F00C812DD /* Store.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA04F1395FF62006ADC12 /* Store.cpp */; };
+ A29BF8E613A04A6F00C812DD /* StoreMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0511395FF62006ADC12 /* StoreMgr.cpp */; };
+ A29BF8E713A04A6F00C812DD /* StringMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0531395FF62006ADC12 /* StringMgr.cpp */; };
+ A29BF8E813A04A6F00C812DD /* SymbolMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0551395FF62006ADC12 /* SymbolMgr.cpp */; };
+ A29BF8E913A04A6F00C812DD /* TableMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0681395FF62006ADC12 /* TableMgr.cpp */; };
+ A29BF8EA13A04A6F00C812DD /* Tile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA06A1395FF62006ADC12 /* Tile.cpp */; };
+ A29BF8EB13A04A6F00C812DD /* TileMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA06C1395FF62006ADC12 /* TileMap.cpp */; };
+ A29BF8EC13A04A6F00C812DD /* TileMapMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA06E1395FF62006ADC12 /* TileMapMgr.cpp */; };
+ A29BF8ED13A04A6F00C812DD /* TileOverlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0701395FF62006ADC12 /* TileOverlay.cpp */; };
+ A29BF8EE13A04A6F00C812DD /* TileSetMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0721395FF62006ADC12 /* TileSetMgr.cpp */; };
+ A29BF8EF13A04A6F00C812DD /* Variables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0751395FF62006ADC12 /* Variables.cpp */; };
+ A29BF8F013A04A6F00C812DD /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0771395FF62006ADC12 /* Video.cpp */; };
+ A29BF8F113A04A6F00C812DD /* WindowMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA07A1395FF62006ADC12 /* WindowMgr.cpp */; };
+ A29BF8F213A04A6F00C812DD /* WorldMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA07C1395FF62006ADC12 /* WorldMap.cpp */; };
+ A29BF8F313A04A6F00C812DD /* WorldMapMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA07E1395FF62006ADC12 /* WorldMapMgr.cpp */; };
+ A29BF8F513A04A6F00C812DD /* DataStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA05C1395FF62006ADC12 /* DataStream.cpp */; };
+ A29BF8F613A04A6F00C812DD /* FileStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA05E1395FF62006ADC12 /* FileStream.cpp */; };
+ A29BF8F713A04A6F00C812DD /* MemoryStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0601395FF62006ADC12 /* MemoryStream.cpp */; };
+ A29BF8F913A04A6F00C812DD /* swab.c in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0641395FF62006ADC12 /* swab.c */; };
+ A29BF8FA13A04A6F00C812DD /* VFS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0661395FF62006ADC12 /* VFS.cpp */; };
+ A29BF8FB13A04A6F00C812DD /* Actor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0331395FF62006ADC12 /* Actor.cpp */; };
+ A29BF8FC13A04A6F00C812DD /* Container.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0351395FF62006ADC12 /* Container.cpp */; };
+ A29BF8FD13A04A6F00C812DD /* Door.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0371395FF62006ADC12 /* Door.cpp */; };
+ A29BF8FE13A04A6F00C812DD /* InfoPoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0391395FF62006ADC12 /* InfoPoint.cpp */; };
+ A29BF8FF13A04A6F00C812DD /* PCStatStruct.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA03B1395FF62006ADC12 /* PCStatStruct.cpp */; };
+ A29BF90013A04A6F00C812DD /* Scriptable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA03D1395FF62006ADC12 /* Scriptable.cpp */; };
+ A29BF90113A04A6F00C812DD /* Button.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FD51395FF62006ADC12 /* Button.cpp */; };
+ A29BF90213A04A6F00C812DD /* Console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FD71395FF62006ADC12 /* Console.cpp */; };
+ A29BF90313A04A6F00C812DD /* Control.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FD91395FF62006ADC12 /* Control.cpp */; };
+ A29BF90413A04A6F00C812DD /* EventMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FDB1395FF62006ADC12 /* EventMgr.cpp */; };
+ A29BF90513A04A6F00C812DD /* GameControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FDD1395FF62006ADC12 /* GameControl.cpp */; };
+ A29BF90613A04A6F00C812DD /* Label.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FDF1395FF62006ADC12 /* Label.cpp */; };
+ A29BF90713A04A6F00C812DD /* MapControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FE11395FF62006ADC12 /* MapControl.cpp */; };
+ A29BF90813A04A6F00C812DD /* Progressbar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FE31395FF62006ADC12 /* Progressbar.cpp */; };
+ A29BF90913A04A6F00C812DD /* ScrollBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FE51395FF62006ADC12 /* ScrollBar.cpp */; };
+ A29BF90A13A04A6F00C812DD /* Slider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FE71395FF62006ADC12 /* Slider.cpp */; };
+ A29BF90B13A04A6F00C812DD /* TextArea.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FE91395FF62006ADC12 /* TextArea.cpp */; };
+ A29BF90C13A04A6F00C812DD /* TextEdit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FEB1395FF62006ADC12 /* TextEdit.cpp */; };
+ A29BF90D13A04A6F00C812DD /* Window.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FED1395FF62006ADC12 /* Window.cpp */; };
+ A29BF90E13A04A6F00C812DD /* WorldMapControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FEF1395FF62006ADC12 /* WorldMapControl.cpp */; };
+ A29BF90F13A04A6F00C812DD /* Actions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FC91395FF62006ADC12 /* Actions.cpp */; };
+ A29BF91013A04A6F00C812DD /* GameScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FCA1395FF62006ADC12 /* GameScript.cpp */; };
+ A29BF91113A04A6F00C812DD /* GSUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FCC1395FF62006ADC12 /* GSUtils.cpp */; };
+ A29BF91213A04A6F00C812DD /* Matching.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FCE1395FF62006ADC12 /* Matching.cpp */; };
+ A29BF91313A04A6F00C812DD /* Objects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FD01395FF62006ADC12 /* Objects.cpp */; };
+ A29BF91413A04A6F00C812DD /* Triggers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FD11395FF62006ADC12 /* Triggers.cpp */; };
+ A2A6A45214687E55000F1688 /* GEM_ConfController.m in Sources */ = {isa = PBXBuildFile; fileRef = A2A6A45014687E55000F1688 /* GEM_ConfController.m */; };
+ A2A6A45314687E55000F1688 /* GEM_ConfController-iphone.xib in Resources */ = {isa = PBXBuildFile; fileRef = A2A6A45114687E55000F1688 /* GEM_ConfController-iphone.xib */; };
+ A2A6A455146880C1000F1688 /* CocoaWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = A2A6A454146880C1000F1688 /* CocoaWrapper.m */; };
+ A2A6A456146880C1000F1688 /* CocoaWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = A2A6A454146880C1000F1688 /* CocoaWrapper.m */; };
+ A2A6A45C146893CC000F1688 /* TTFFontManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2A6A459146893CC000F1688 /* TTFFontManager.cpp */; };
+ A2A6A45D146893CC000F1688 /* TTFFontManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2A6A459146893CC000F1688 /* TTFFontManager.cpp */; };
+ A2AAF33A13A14A4500AE8402 /* SDLVideo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B875A139F0A7D0002DC13 /* SDLVideo.cpp */; };
+ A2C66D6F13A2950300C0AA8E /* SDL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A29BF7FC13A039DD00C812DD /* SDL.framework */; };
+ A2C66D9913A2950700C0AA8E /* SDL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A29BF7FC13A039DD00C812DD /* SDL.framework */; };
+ A2C66D9D13A2953D00C0AA8E /* Python.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2C66D9C13A2953D00C0AA8E /* Python.framework */; };
+ A2C66DB513A295DC00C0AA8E /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2830A0F13A05A64000A63FE /* OpenAL.framework */; };
+ A2C66DBC13A2961700C0AA8E /* SDL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A29BF7FC13A039DD00C812DD /* SDL.framework */; };
+ A2E57ADD1475EB45005C0A29 /* GEM_ConfController-ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = A2E57ADC1475EB45005C0A29 /* GEM_ConfController-ipad.xib */; };
+ A2E6634E139E882900310FC8 /* ActorMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F8D1395FF61006ADC12 /* ActorMgr.cpp */; };
+ A2E6634F139E882900310FC8 /* ActorMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9F8E1395FF61006ADC12 /* ActorMgr.h */; };
+ A2E66350139E882900310FC8 /* Ambient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F8F1395FF61006ADC12 /* Ambient.cpp */; };
+ A2E66351139E882900310FC8 /* Ambient.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9F901395FF61006ADC12 /* Ambient.h */; };
+ A2E66352139E882900310FC8 /* AmbientMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F911395FF61006ADC12 /* AmbientMgr.cpp */; };
+ A2E66353139E882900310FC8 /* AmbientMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9F921395FF61006ADC12 /* AmbientMgr.h */; };
+ A2E66354139E882900310FC8 /* Animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F931395FF61006ADC12 /* Animation.cpp */; };
+ A2E66355139E882900310FC8 /* Animation.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9F941395FF61006ADC12 /* Animation.h */; };
+ A2E66356139E882900310FC8 /* AnimationFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F951395FF61006ADC12 /* AnimationFactory.cpp */; };
+ A2E66357139E883100310FC8 /* AnimationFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9F961395FF61006ADC12 /* AnimationFactory.h */; };
+ A2E66358139E883100310FC8 /* AnimationMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F971395FF61006ADC12 /* AnimationMgr.cpp */; };
+ A2E66359139E883100310FC8 /* AnimationMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9F981395FF61006ADC12 /* AnimationMgr.h */; };
+ A2E6635A139E883100310FC8 /* AnimStructures.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9F991395FF61006ADC12 /* AnimStructures.h */; };
+ A2E6635B139E883100310FC8 /* ArchiveImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F9A1395FF61006ADC12 /* ArchiveImporter.cpp */; };
+ A2E6635C139E883100310FC8 /* ArchiveImporter.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9F9B1395FF61006ADC12 /* ArchiveImporter.h */; };
+ A2E6635D139E883100310FC8 /* Audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F9C1395FF61006ADC12 /* Audio.cpp */; };
+ A2E6635E139E883100310FC8 /* Audio.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9F9D1395FF61006ADC12 /* Audio.h */; };
+ A2E6635F139E883100310FC8 /* Bitmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F9E1395FF61006ADC12 /* Bitmap.cpp */; };
+ A2E66360139E883100310FC8 /* Bitmap.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9F9F1395FF61006ADC12 /* Bitmap.h */; };
+ A2E66361139E883100310FC8 /* Cache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FA01395FF61006ADC12 /* Cache.cpp */; };
+ A2E66362139E883100310FC8 /* Cache.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FA11395FF61006ADC12 /* Cache.h */; };
+ A2E66363139E883100310FC8 /* Calendar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FA21395FF61006ADC12 /* Calendar.cpp */; };
+ A2E66364139E883100310FC8 /* Calendar.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FA31395FF61006ADC12 /* Calendar.h */; };
+ A2E66365139E883100310FC8 /* Callback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FA41395FF61006ADC12 /* Callback.cpp */; };
+ A2E66366139E883100310FC8 /* Callback.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FA51395FF61006ADC12 /* Callback.h */; };
+ A2E66367139E883100310FC8 /* CharAnimations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FA61395FF61006ADC12 /* CharAnimations.cpp */; };
+ A2E66368139E883100310FC8 /* CharAnimations.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FA71395FF61006ADC12 /* CharAnimations.h */; };
+ A2E66369139E883100310FC8 /* Compressor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FA91395FF61006ADC12 /* Compressor.cpp */; };
+ A2E6636A139E883100310FC8 /* Compressor.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FAA1395FF61006ADC12 /* Compressor.h */; };
+ A2E6636B139E883100310FC8 /* ControlAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FAB1395FF61006ADC12 /* ControlAnimation.cpp */; };
+ A2E6636C139E883100310FC8 /* ControlAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FAC1395FF61006ADC12 /* ControlAnimation.h */; };
+ A2E6636D139E883100310FC8 /* Core.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FAD1395FF61006ADC12 /* Core.cpp */; };
+ A2E6636E139E883100310FC8 /* damages.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FAE1395FF61006ADC12 /* damages.h */; };
+ A2E6636F139E883100310FC8 /* DataFileMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FAF1395FF61006ADC12 /* DataFileMgr.cpp */; };
+ A2E66370139E883100310FC8 /* DataFileMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FB01395FF61006ADC12 /* DataFileMgr.h */; };
+ A2E66371139E883100310FC8 /* Dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FB11395FF61006ADC12 /* Dialog.cpp */; };
+ A2E66372139E883100310FC8 /* Dialog.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FB21395FF61006ADC12 /* Dialog.h */; };
+ A2E66373139E883100310FC8 /* DialogHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FB31395FF61006ADC12 /* DialogHandler.cpp */; };
+ A2E66374139E883100310FC8 /* DialogHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FB41395FF61006ADC12 /* DialogHandler.h */; };
+ A2E66375139E883100310FC8 /* DialogMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FB51395FF61006ADC12 /* DialogMgr.cpp */; };
+ A2E66376139E883100310FC8 /* DialogMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FB61395FF61006ADC12 /* DialogMgr.h */; };
+ A2E66377139E883100310FC8 /* DisplayMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FB71395FF61006ADC12 /* DisplayMessage.cpp */; };
+ A2E66378139E883100310FC8 /* DisplayMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FB81395FF61006ADC12 /* DisplayMessage.h */; };
+ A2E66379139E883100310FC8 /* Effect.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FB91395FF61006ADC12 /* Effect.h */; };
+ A2E6637A139E883100310FC8 /* EffectMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FBA1395FF61006ADC12 /* EffectMgr.cpp */; };
+ A2E6637B139E883100310FC8 /* EffectMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FBB1395FF61006ADC12 /* EffectMgr.h */; };
+ A2E6637C139E883100310FC8 /* EffectQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FBC1395FF61006ADC12 /* EffectQueue.cpp */; };
+ A2E6637D139E883100310FC8 /* EffectQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FBD1395FF61006ADC12 /* EffectQueue.h */; };
+ A2E6637E139E883100310FC8 /* Factory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FBE1395FF61006ADC12 /* Factory.cpp */; };
+ A2E6637F139E883100310FC8 /* Factory.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FBF1395FF61006ADC12 /* Factory.h */; };
+ A2E66380139E883100310FC8 /* FactoryObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FC01395FF61006ADC12 /* FactoryObject.cpp */; };
+ A2E66381139E883100310FC8 /* FactoryObject.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FC11395FF61006ADC12 /* FactoryObject.h */; };
+ A2E66382139E883100310FC8 /* Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FC21395FF61006ADC12 /* Font.cpp */; };
+ A2E66383139E883100310FC8 /* Font.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FC31395FF61006ADC12 /* Font.h */; };
+ A2E66384139E883100310FC8 /* Game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FC41395FF61006ADC12 /* Game.cpp */; };
+ A2E66385139E883100310FC8 /* Game.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FC51395FF62006ADC12 /* Game.h */; };
+ A2E66386139E883100310FC8 /* GameData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FC61395FF62006ADC12 /* GameData.cpp */; };
+ A2E66387139E883100310FC8 /* GameData.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FC71395FF62006ADC12 /* GameData.h */; };
+ A2E66388139E883700310FC8 /* GlobalTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FD21395FF62006ADC12 /* GlobalTimer.cpp */; };
+ A2E66389139E883700310FC8 /* GlobalTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FD31395FF62006ADC12 /* GlobalTimer.h */; };
+ A2E6638A139E883E00310FC8 /* Holder.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FF11395FF62006ADC12 /* Holder.h */; };
+ A2E6638B139E883E00310FC8 /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FF21395FF62006ADC12 /* Image.cpp */; };
+ A2E6638C139E883E00310FC8 /* Image.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FF31395FF62006ADC12 /* Image.h */; };
+ A2E6638D139E883E00310FC8 /* ImageFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FF41395FF62006ADC12 /* ImageFactory.cpp */; };
+ A2E6638E139E883E00310FC8 /* ImageFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FF51395FF62006ADC12 /* ImageFactory.h */; };
+ A2E6638F139E883E00310FC8 /* ImageMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FF61395FF62006ADC12 /* ImageMgr.cpp */; };
+ A2E66390139E883E00310FC8 /* ImageMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FF71395FF62006ADC12 /* ImageMgr.h */; };
+ A2E66391139E883E00310FC8 /* ImageWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FF81395FF62006ADC12 /* ImageWriter.cpp */; };
+ A2E66392139E883E00310FC8 /* ImageWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FF91395FF62006ADC12 /* ImageWriter.h */; };
+ A2E66393139E883E00310FC8 /* IniSpawn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FFA1395FF62006ADC12 /* IniSpawn.cpp */; };
+ A2E66394139E883E00310FC8 /* IniSpawn.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FFB1395FF62006ADC12 /* IniSpawn.h */; };
+ A2E66395139E883E00310FC8 /* Interface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FFC1395FF62006ADC12 /* Interface.cpp */; };
+ A2E66396139E883E00310FC8 /* Interface.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FFD1395FF62006ADC12 /* Interface.h */; };
+ A2E66397139E883E00310FC8 /* Inventory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FFE1395FF62006ADC12 /* Inventory.cpp */; };
+ A2E66398139E883E00310FC8 /* Inventory.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FFF1395FF62006ADC12 /* Inventory.h */; };
+ A2E66399139E883E00310FC8 /* Item.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0001395FF62006ADC12 /* Item.cpp */; };
+ A2E6639A139E883E00310FC8 /* Item.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0011395FF62006ADC12 /* Item.h */; };
+ A2E6639B139E883E00310FC8 /* ItemMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0021395FF62006ADC12 /* ItemMgr.cpp */; };
+ A2E6639C139E883E00310FC8 /* ItemMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0031395FF62006ADC12 /* ItemMgr.h */; };
+ A2E6639D139E883E00310FC8 /* LRUCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0041395FF62006ADC12 /* LRUCache.cpp */; };
+ A2E6639E139E883E00310FC8 /* LRUCache.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0051395FF62006ADC12 /* LRUCache.h */; };
+ A2E6639F139E883E00310FC8 /* Map.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0071395FF62006ADC12 /* Map.cpp */; };
+ A2E663A0139E883E00310FC8 /* Map.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0081395FF62006ADC12 /* Map.h */; };
+ A2E663A1139E883E00310FC8 /* MapMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0091395FF62006ADC12 /* MapMgr.cpp */; };
+ A2E663A2139E883E00310FC8 /* MapMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA00A1395FF62006ADC12 /* MapMgr.h */; };
+ A2E663A3139E883E00310FC8 /* MoviePlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA00B1395FF62006ADC12 /* MoviePlayer.cpp */; };
+ A2E663A4139E883E00310FC8 /* MoviePlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA00C1395FF62006ADC12 /* MoviePlayer.h */; };
+ A2E663A5139E883E00310FC8 /* MusicMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA00D1395FF62006ADC12 /* MusicMgr.cpp */; };
+ A2E663A6139E883E00310FC8 /* MusicMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA00E1395FF62006ADC12 /* MusicMgr.h */; };
+ A2E663A7139E883E00310FC8 /* Palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA00F1395FF62006ADC12 /* Palette.cpp */; };
+ A2E663A8139E883E00310FC8 /* Palette.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0101395FF62006ADC12 /* Palette.h */; };
+ A2E663A9139E883E00310FC8 /* PalettedImageMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0111395FF62006ADC12 /* PalettedImageMgr.cpp */; };
+ A2E663AA139E883E00310FC8 /* PalettedImageMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0121395FF62006ADC12 /* PalettedImageMgr.h */; };
+ A2E663AB139E883E00310FC8 /* Particles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0131395FF62006ADC12 /* Particles.cpp */; };
+ A2E663AC139E883E00310FC8 /* Particles.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0141395FF62006ADC12 /* Particles.h */; };
+ A2E663AD139E883E00310FC8 /* PathFinder.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0151395FF62006ADC12 /* PathFinder.h */; };
+ A2E663AE139E883E00310FC8 /* Plugin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0161395FF62006ADC12 /* Plugin.cpp */; };
+ A2E663AF139E883E00310FC8 /* Plugin.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0171395FF62006ADC12 /* Plugin.h */; };
+ A2E663B0139E883E00310FC8 /* PluginMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0181395FF62006ADC12 /* PluginMgr.cpp */; };
+ A2E663B1139E883E00310FC8 /* PluginMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0191395FF62006ADC12 /* PluginMgr.h */; };
+ A2E663B2139E883E00310FC8 /* Polygon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA01A1395FF62006ADC12 /* Polygon.cpp */; };
+ A2E663B3139E883E00310FC8 /* Polygon.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA01B1395FF62006ADC12 /* Polygon.h */; };
+ A2E663B4139E883E00310FC8 /* PolymorphCache.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA01C1395FF62006ADC12 /* PolymorphCache.h */; };
+ A2E663B5139E883E00310FC8 /* Projectile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA01D1395FF62006ADC12 /* Projectile.cpp */; };
+ A2E663B6139E883E00310FC8 /* Projectile.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA01E1395FF62006ADC12 /* Projectile.h */; };
+ A2E663B7139E883E00310FC8 /* ProjectileMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA01F1395FF62006ADC12 /* ProjectileMgr.cpp */; };
+ A2E663B8139E883E00310FC8 /* ProjectileMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0201395FF62006ADC12 /* ProjectileMgr.h */; };
+ A2E663B9139E883E00310FC8 /* ProjectileServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0211395FF62006ADC12 /* ProjectileServer.cpp */; };
+ A2E663BA139E883E00310FC8 /* ProjectileServer.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0221395FF62006ADC12 /* ProjectileServer.h */; };
+ A2E663BB139E883E00310FC8 /* Region.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0231395FF62006ADC12 /* Region.cpp */; };
+ A2E663BC139E883E00310FC8 /* Region.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0241395FF62006ADC12 /* Region.h */; };
+ A2E663BD139E883E00310FC8 /* Resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0251395FF62006ADC12 /* Resource.cpp */; };
+ A2E663BE139E883E00310FC8 /* Resource.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0261395FF62006ADC12 /* Resource.h */; };
+ A2E663BF139E883E00310FC8 /* ResourceDesc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0271395FF62006ADC12 /* ResourceDesc.cpp */; };
+ A2E663C0139E883E00310FC8 /* ResourceDesc.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0281395FF62006ADC12 /* ResourceDesc.h */; };
+ A2E663C1139E883E00310FC8 /* ResourceManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0291395FF62006ADC12 /* ResourceManager.cpp */; };
+ A2E663C2139E883E00310FC8 /* ResourceManager.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA02A1395FF62006ADC12 /* ResourceManager.h */; };
+ A2E663C3139E883E00310FC8 /* ResourceSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA02B1395FF62006ADC12 /* ResourceSource.cpp */; };
+ A2E663C4139E883E00310FC8 /* ResourceSource.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA02C1395FF62006ADC12 /* ResourceSource.h */; };
+ A2E663C5139E883E00310FC8 /* SaveGame.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA02D1395FF62006ADC12 /* SaveGame.h */; };
+ A2E663C6139E883E00310FC8 /* SaveGameIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA02E1395FF62006ADC12 /* SaveGameIterator.cpp */; };
+ A2E663C7139E883E00310FC8 /* SaveGameIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA02F1395FF62006ADC12 /* SaveGameIterator.h */; };
+ A2E663C8139E883E00310FC8 /* SaveGameMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0301395FF62006ADC12 /* SaveGameMgr.cpp */; };
+ A2E663C9139E883E00310FC8 /* SaveGameMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0311395FF62006ADC12 /* SaveGameMgr.h */; };
+ A2E663CA139E884500310FC8 /* ScriptedAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA03F1395FF62006ADC12 /* ScriptedAnimation.cpp */; };
+ A2E663CB139E884500310FC8 /* ScriptedAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0401395FF62006ADC12 /* ScriptedAnimation.h */; };
+ A2E663CC139E884500310FC8 /* ScriptEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0411395FF62006ADC12 /* ScriptEngine.cpp */; };
+ A2E663CD139E884500310FC8 /* ScriptEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0421395FF62006ADC12 /* ScriptEngine.h */; };
+ A2E663CE139E884500310FC8 /* SoundMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0431395FF62006ADC12 /* SoundMgr.cpp */; };
+ A2E663CF139E884500310FC8 /* SoundMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0441395FF62006ADC12 /* SoundMgr.h */; };
+ A2E663D0139E884500310FC8 /* Spell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0451395FF62006ADC12 /* Spell.cpp */; };
+ A2E663D1139E884500310FC8 /* Spell.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0461395FF62006ADC12 /* Spell.h */; };
+ A2E663D2139E884500310FC8 /* Spellbook.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0471395FF62006ADC12 /* Spellbook.cpp */; };
+ A2E663D3139E884500310FC8 /* Spellbook.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0481395FF62006ADC12 /* Spellbook.h */; };
+ A2E663D4139E884500310FC8 /* SpellMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0491395FF62006ADC12 /* SpellMgr.cpp */; };
+ A2E663D5139E884500310FC8 /* SpellMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA04A1395FF62006ADC12 /* SpellMgr.h */; };
+ A2E663D6139E884500310FC8 /* Sprite2D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA04B1395FF62006ADC12 /* Sprite2D.cpp */; };
+ A2E663D7139E884500310FC8 /* Sprite2D.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA04C1395FF62006ADC12 /* Sprite2D.h */; };
+ A2E663D8139E884500310FC8 /* SpriteCover.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA04D1395FF62006ADC12 /* SpriteCover.cpp */; };
+ A2E663D9139E884500310FC8 /* SpriteCover.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA04E1395FF62006ADC12 /* SpriteCover.h */; };
+ A2E663DA139E884500310FC8 /* Store.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA04F1395FF62006ADC12 /* Store.cpp */; };
+ A2E663DB139E884500310FC8 /* Store.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0501395FF62006ADC12 /* Store.h */; };
+ A2E663DC139E884500310FC8 /* StoreMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0511395FF62006ADC12 /* StoreMgr.cpp */; };
+ A2E663DD139E884500310FC8 /* StoreMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0521395FF62006ADC12 /* StoreMgr.h */; };
+ A2E663DE139E884500310FC8 /* StringMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0531395FF62006ADC12 /* StringMgr.cpp */; };
+ A2E663DF139E884500310FC8 /* StringMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0541395FF62006ADC12 /* StringMgr.h */; };
+ A2E663E0139E884500310FC8 /* SymbolMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0551395FF62006ADC12 /* SymbolMgr.cpp */; };
+ A2E663E1139E884500310FC8 /* SymbolMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0561395FF62006ADC12 /* SymbolMgr.h */; };
+ A2E663E2139E884B00310FC8 /* TableMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0681395FF62006ADC12 /* TableMgr.cpp */; };
+ A2E663E3139E884B00310FC8 /* TableMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0691395FF62006ADC12 /* TableMgr.h */; };
+ A2E663E4139E884B00310FC8 /* Tile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA06A1395FF62006ADC12 /* Tile.cpp */; };
+ A2E663E5139E884B00310FC8 /* Tile.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA06B1395FF62006ADC12 /* Tile.h */; };
+ A2E663E6139E884B00310FC8 /* TileMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA06C1395FF62006ADC12 /* TileMap.cpp */; };
+ A2E663E7139E884B00310FC8 /* TileMap.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA06D1395FF62006ADC12 /* TileMap.h */; };
+ A2E663E8139E884B00310FC8 /* TileMapMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA06E1395FF62006ADC12 /* TileMapMgr.cpp */; };
+ A2E663E9139E884B00310FC8 /* TileMapMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA06F1395FF62006ADC12 /* TileMapMgr.h */; };
+ A2E663EA139E884B00310FC8 /* TileOverlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0701395FF62006ADC12 /* TileOverlay.cpp */; };
+ A2E663EB139E884B00310FC8 /* TileOverlay.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0711395FF62006ADC12 /* TileOverlay.h */; };
+ A2E663EC139E884B00310FC8 /* TileSetMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0721395FF62006ADC12 /* TileSetMgr.cpp */; };
+ A2E663ED139E884B00310FC8 /* TileSetMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0731395FF62006ADC12 /* TileSetMgr.h */; };
+ A2E663EE139E884B00310FC8 /* TypeID.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0741395FF62006ADC12 /* TypeID.h */; };
+ A2E663EF139E884B00310FC8 /* Variables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0751395FF62006ADC12 /* Variables.cpp */; };
+ A2E663F0139E884B00310FC8 /* Variables.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0761395FF62006ADC12 /* Variables.h */; };
+ A2E663F1139E884B00310FC8 /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0771395FF62006ADC12 /* Video.cpp */; };
+ A2E663F2139E884B00310FC8 /* Video.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0781395FF62006ADC12 /* Video.h */; };
+ A2E663F3139E884B00310FC8 /* VideoMode.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0791395FF62006ADC12 /* VideoMode.h */; };
+ A2E663F4139E884B00310FC8 /* WindowMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA07A1395FF62006ADC12 /* WindowMgr.cpp */; };
+ A2E663F5139E884B00310FC8 /* WindowMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA07B1395FF62006ADC12 /* WindowMgr.h */; };
+ A2E663F6139E884B00310FC8 /* WorldMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA07C1395FF62006ADC12 /* WorldMap.cpp */; };
+ A2E663F7139E884B00310FC8 /* WorldMap.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA07D1395FF62006ADC12 /* WorldMap.h */; };
+ A2E663F8139E884B00310FC8 /* WorldMapMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA07E1395FF62006ADC12 /* WorldMapMgr.cpp */; };
+ A2E663F9139E884B00310FC8 /* WorldMapMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA07F1395FF62006ADC12 /* WorldMapMgr.h */; };
+ A2E663FC139E885300310FC8 /* DataStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA05C1395FF62006ADC12 /* DataStream.cpp */; };
+ A2E663FD139E885300310FC8 /* DataStream.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA05D1395FF62006ADC12 /* DataStream.h */; };
+ A2E663FE139E885300310FC8 /* FileStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA05E1395FF62006ADC12 /* FileStream.cpp */; };
+ A2E663FF139E885300310FC8 /* FileStream.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA05F1395FF62006ADC12 /* FileStream.h */; };
+ A2E66401139E885300310FC8 /* MemoryStream.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0611395FF62006ADC12 /* MemoryStream.h */; };
+ A2E66404139E885300310FC8 /* swab.c in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0641395FF62006ADC12 /* swab.c */; };
+ A2E66405139E885300310FC8 /* swab.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0651395FF62006ADC12 /* swab.h */; };
+ A2E66406139E885300310FC8 /* VFS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0661395FF62006ADC12 /* VFS.cpp */; };
+ A2E66407139E885300310FC8 /* VFS.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0671395FF62006ADC12 /* VFS.h */; };
+ A2E66408139E885A00310FC8 /* Actor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0331395FF62006ADC12 /* Actor.cpp */; };
+ A2E66409139E885A00310FC8 /* Actor.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0341395FF62006ADC12 /* Actor.h */; };
+ A2E6640A139E885A00310FC8 /* Container.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0351395FF62006ADC12 /* Container.cpp */; };
+ A2E6640B139E885A00310FC8 /* Container.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0361395FF62006ADC12 /* Container.h */; };
+ A2E6640C139E885A00310FC8 /* Door.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0371395FF62006ADC12 /* Door.cpp */; };
+ A2E6640D139E885A00310FC8 /* Door.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0381395FF62006ADC12 /* Door.h */; };
+ A2E6640E139E885A00310FC8 /* InfoPoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0391395FF62006ADC12 /* InfoPoint.cpp */; };
+ A2E6640F139E885A00310FC8 /* InfoPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA03A1395FF62006ADC12 /* InfoPoint.h */; };
+ A2E66410139E885A00310FC8 /* PCStatStruct.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA03B1395FF62006ADC12 /* PCStatStruct.cpp */; };
+ A2E66411139E885A00310FC8 /* PCStatStruct.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA03C1395FF62006ADC12 /* PCStatStruct.h */; };
+ A2E66412139E885A00310FC8 /* Scriptable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA03D1395FF62006ADC12 /* Scriptable.cpp */; };
+ A2E66413139E885A00310FC8 /* Scriptable.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA03E1395FF62006ADC12 /* Scriptable.h */; };
+ A2E66414139E886100310FC8 /* Button.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FD51395FF62006ADC12 /* Button.cpp */; };
+ A2E66415139E886100310FC8 /* Button.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FD61395FF62006ADC12 /* Button.h */; };
+ A2E66416139E886100310FC8 /* Console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FD71395FF62006ADC12 /* Console.cpp */; };
+ A2E66417139E886100310FC8 /* Console.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FD81395FF62006ADC12 /* Console.h */; };
+ A2E66418139E886100310FC8 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = A2FE553A13982BA6006AB962 /* config.h */; };
+ A2E66419139E886100310FC8 /* Control.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FD91395FF62006ADC12 /* Control.cpp */; };
+ A2E6641A139E886100310FC8 /* Control.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FDA1395FF62006ADC12 /* Control.h */; };
+ A2E6641B139E886100310FC8 /* EventMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FDB1395FF62006ADC12 /* EventMgr.cpp */; };
+ A2E6641C139E886100310FC8 /* EventMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FDC1395FF62006ADC12 /* EventMgr.h */; };
+ A2E6641D139E886100310FC8 /* GameControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FDD1395FF62006ADC12 /* GameControl.cpp */; };
+ A2E6641E139E886100310FC8 /* GameControl.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FDE1395FF62006ADC12 /* GameControl.h */; };
+ A2E6641F139E886100310FC8 /* Label.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FDF1395FF62006ADC12 /* Label.cpp */; };
+ A2E66420139E886100310FC8 /* Label.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FE01395FF62006ADC12 /* Label.h */; };
+ A2E66421139E886100310FC8 /* MapControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FE11395FF62006ADC12 /* MapControl.cpp */; };
+ A2E66422139E886100310FC8 /* MapControl.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FE21395FF62006ADC12 /* MapControl.h */; };
+ A2E66423139E886100310FC8 /* Progressbar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FE31395FF62006ADC12 /* Progressbar.cpp */; };
+ A2E66424139E886100310FC8 /* Progressbar.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FE41395FF62006ADC12 /* Progressbar.h */; };
+ A2E66425139E886100310FC8 /* ScrollBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FE51395FF62006ADC12 /* ScrollBar.cpp */; };
+ A2E66426139E886100310FC8 /* ScrollBar.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FE61395FF62006ADC12 /* ScrollBar.h */; };
+ A2E66427139E886100310FC8 /* Slider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FE71395FF62006ADC12 /* Slider.cpp */; };
+ A2E66428139E886100310FC8 /* Slider.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FE81395FF62006ADC12 /* Slider.h */; };
+ A2E66429139E886100310FC8 /* TextArea.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FE91395FF62006ADC12 /* TextArea.cpp */; };
+ A2E6642A139E886100310FC8 /* TextArea.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FEA1395FF62006ADC12 /* TextArea.h */; };
+ A2E6642B139E886100310FC8 /* TextEdit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FEB1395FF62006ADC12 /* TextEdit.cpp */; };
+ A2E6642C139E886100310FC8 /* TextEdit.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FEC1395FF62006ADC12 /* TextEdit.h */; };
+ A2E6642D139E886100310FC8 /* Window.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FED1395FF62006ADC12 /* Window.cpp */; };
+ A2E6642E139E886100310FC8 /* Window.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FEE1395FF62006ADC12 /* Window.h */; };
+ A2E6642F139E886100310FC8 /* WorldMapControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FEF1395FF62006ADC12 /* WorldMapControl.cpp */; };
+ A2E66430139E886100310FC8 /* WorldMapControl.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FF01395FF62006ADC12 /* WorldMapControl.h */; };
+ A2E66431139E886700310FC8 /* Actions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FC91395FF62006ADC12 /* Actions.cpp */; };
+ A2E66432139E886700310FC8 /* GameScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FCA1395FF62006ADC12 /* GameScript.cpp */; };
+ A2E66433139E886700310FC8 /* GameScript.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FCB1395FF62006ADC12 /* GameScript.h */; };
+ A2E66434139E886700310FC8 /* GSUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FCC1395FF62006ADC12 /* GSUtils.cpp */; };
+ A2E66435139E886700310FC8 /* GSUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FCD1395FF62006ADC12 /* GSUtils.h */; };
+ A2E66436139E886700310FC8 /* Matching.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FCE1395FF62006ADC12 /* Matching.cpp */; };
+ A2E66437139E886700310FC8 /* Matching.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FCF1395FF62006ADC12 /* Matching.h */; };
+ A2E66438139E886700310FC8 /* Objects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FD01395FF62006ADC12 /* Objects.cpp */; };
+ A2E66439139E886700310FC8 /* Triggers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FD11395FF62006ADC12 /* Triggers.cpp */; };
+ A2E66448139E8CAA00310FC8 /* ie_types.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BD81A913960965007E9C63 /* ie_types.h */; };
+ A2E6647C139E8FAB00310FC8 /* core.pch in Headers */ = {isa = PBXBuildFile; fileRef = A2E6647B139E8FAB00310FC8 /* core.pch */; };
+ A2E66486139E907000310FC8 /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A2E66487139E908E00310FC8 /* libgemrb_core.dylib in Copy Frameworks into .app bundle */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A2EC8059145F9E6E0033754A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2EC8058145F9E6E0033754A /* Foundation.framework */; };
+ A2EC805B1460556B0033754A /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2EC805A1460556B0033754A /* OpenAL.framework */; };
+ A2EC805D1460559C0033754A /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2EC805C1460559C0033754A /* CoreAudio.framework */; };
+ A2EC8061146055D80033754A /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2EC805F146055D80033754A /* OpenGLES.framework */; };
+ A2EC8063146056490033754A /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2EC8062146056490033754A /* QuartzCore.framework */; };
+ A2EC8065146056900033754A /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2EC8064146056900033754A /* AudioToolbox.framework */; };
+ A2EC8067146056B40033754A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2EC8066146056B40033754A /* CoreGraphics.framework */; };
+ A2EC807214605F4B0033754A /* CocoaWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = A249187B141075A60038B170 /* CocoaWrapper.m */; };
+ A2F0505613ABB82D0023B7EB /* SAVImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27979AC13ABA4F7009A6FEF /* SAVImporter.cpp */; };
+ A2F0505B13ABB84C0023B7EB /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ A2375BA013AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A27E830913A0358200B41410;
+ remoteInfo = 2DAImporter;
+ };
+ A2375BA213AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A2FCD5FA13A0366100271997;
+ remoteInfo = ACMReader;
+ };
+ A2375BA413AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A2462F1013A036B1002D1F02;
+ remoteInfo = AREImporter;
+ };
+ A2375BA613AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A29BF7B113A0380F00C812DD;
+ remoteInfo = BAMImporter;
+ };
+ A2375BA813AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B3C913A2867900D41A8A;
+ remoteInfo = BIFImporter;
+ };
+ A2375BAA13AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B3D013A286A800D41A8A;
+ remoteInfo = BIKPlayer;
+ };
+ A2375BAC13AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B3D613A286BC00D41A8A;
+ remoteInfo = BMPImporter;
+ };
+ A2375BAE13AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B3DC13A286CD00D41A8A;
+ remoteInfo = BMPWriter;
+ };
+ A2375BB013AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B3E213A286DE00D41A8A;
+ remoteInfo = CHUImporter;
+ };
+ A2375BB213AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B3E813A286EC00D41A8A;
+ remoteInfo = CREImporter;
+ };
+ A2375BB413AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B3EE13A286FB00D41A8A;
+ remoteInfo = DirectoryImporter;
+ };
+ A2375BB613AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B3F413A2871300D41A8A;
+ remoteInfo = DLGImporter;
+ };
+ A2375BB813AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B3FA13A2872500D41A8A;
+ remoteInfo = EFFImporter;
+ };
+ A2375BBA13AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B40013A2873700D41A8A;
+ remoteInfo = FXOpcodes;
+ };
+ A2375BBC13AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B40613A2874700D41A8A;
+ remoteInfo = GAMImporter;
+ };
+ A2375BBE13AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B40C13A2875400D41A8A;
+ remoteInfo = GUIScript;
+ };
+ A2375BC013AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B41213A2876300D41A8A;
+ remoteInfo = IDSImporter;
+ };
+ A2375BC213AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B41813A2877100D41A8A;
+ remoteInfo = INIImporter;
+ };
+ A2375BC413AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B41E13A2878400D41A8A;
+ remoteInfo = ITMImporter;
+ };
+ A2375BC613AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B42413A2879900D41A8A;
+ remoteInfo = IWDOpcodes;
+ };
+ A2375BC813AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B42A13A287AB00D41A8A;
+ remoteInfo = KEYImporter;
+ };
+ A2375BCA13AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B43013A287BC00D41A8A;
+ remoteInfo = MOSImporter;
+ };
+ A2375BCC13AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B44813A289E000D41A8A;
+ remoteInfo = MUSImporter;
+ };
+ A2375BCE13AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B44E13A28A0000D41A8A;
+ remoteInfo = MVEPlayer;
+ };
+ A2375BD013AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B45413A28A0E00D41A8A;
+ remoteInfo = NullSound;
+ };
+ A2375BD213AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B46013A28A3100D41A8A;
+ remoteInfo = OpenALAudio;
+ };
+ A2375BD413AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B46613A28A3F00D41A8A;
+ remoteInfo = PLTImporter;
+ };
+ A2375BD613AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B47213A28A5D00D41A8A;
+ remoteInfo = PROImporter;
+ };
+ A2375BD813AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B47813A28A7600D41A8A;
+ remoteInfo = PSTOpcodes;
+ };
+ A2375BDC13AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B48A13A28A9E00D41A8A;
+ remoteInfo = SPLImporter;
+ };
+ A2375BDE13AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B4F313A28C0400D41A8A;
+ remoteInfo = STOImporter;
+ };
+ A2375BE013AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B49013A28AA800D41A8A;
+ remoteInfo = TISImporter;
+ };
+ A2375BE213AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B49613A28AB800D41A8A;
+ remoteInfo = TLKImporter;
+ };
+ A2375BE413AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B49C13A28AC800D41A8A;
+ remoteInfo = WAVReader;
+ };
+ A2375BE613AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B4A213A28AD300D41A8A;
+ remoteInfo = WEDImporter;
+ };
+ A2375BE813AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B4A813A28AE100D41A8A;
+ remoteInfo = WMPImporter;
+ };
+ A2375BEA13AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B4AE13A28AEE00D41A8A;
+ remoteInfo = ZLibManager;
+ };
+ A23EBFFB1419A81500CC049E /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A2F0505013ABB80B0023B7EB;
+ remoteInfo = SAVImporter;
+ };
+ A259F3F9142BFC4100D49124 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A269030F142BEE2F003E8BCC;
+ remoteInfo = SDLTTFFont;
+ };
+ A2E6633B139E876900310FC8 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A2E66337139E875400310FC8;
+ remoteInfo = libgemrb_core.dylib;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 002F39FD09D0883400EBEB88 /* Copy Frameworks into .app bundle */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ A2E66487139E908E00310FC8 /* libgemrb_core.dylib in Copy Frameworks into .app bundle */,
+ );
+ name = "Copy Frameworks into .app bundle";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+ 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+ 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
+ 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
+ 32CA4F630368D1EE00C91783 /* GemRB_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GemRB_Prefix.pch; sourceTree = "<group>"; };
+ 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = osx/Info.plist; sourceTree = "<group>"; };
+ 8D1107320486CEB800E47090 /* GemRB.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GemRB.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ A208210A14191A03002CD244 /* SDL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL.framework; path = /Library/Frameworks/SDL.framework; sourceTree = "<absolute>"; };
+ A22693781422931B004468E8 /* CocoaWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CocoaWrapper.h; path = ../gemrb/includes/CocoaWrapper.h; sourceTree = "<group>"; };
+ A239390A145F8677007895B3 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
+ A2462F1113A036B1002D1F02 /* AREImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = AREImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A249187B141075A60038B170 /* CocoaWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CocoaWrapper.m; sourceTree = "<group>"; };
+ A2491880141092F20038B170 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+ A259F3F5142BFBCD00D49124 /* SDL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL.framework; path = /Library/Frameworks/SDL.framework; sourceTree = "<absolute>"; };
+ A259F3F6142BFBCD00D49124 /* SDL_ttf.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL_ttf.framework; path = /Library/Frameworks/SDL_ttf.framework; sourceTree = "<absolute>"; };
+ A265ECD813A8661600C6DF12 /* FileCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FileCache.cpp; path = ../gemrb/core/FileCache.cpp; sourceTree = SOURCE_ROOT; };
+ A265ECD913A8661600C6DF12 /* IndexedArchive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IndexedArchive.cpp; path = ../gemrb/core/IndexedArchive.cpp; sourceTree = SOURCE_ROOT; };
+ A265ECDA13A8661600C6DF12 /* KeyMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KeyMap.cpp; path = ../gemrb/core/KeyMap.cpp; sourceTree = SOURCE_ROOT; };
+ A265ECDB13A8661600C6DF12 /* PluginLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PluginLoader.cpp; path = ../gemrb/core/PluginLoader.cpp; sourceTree = SOURCE_ROOT; };
+ A265ECEA13A8669700C6DF12 /* Logging.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Logging.cpp; path = ../gemrb/core/System/Logging.cpp; sourceTree = SOURCE_ROOT; };
+ A265ECEB13A8669700C6DF12 /* SlicedStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SlicedStream.cpp; path = ../gemrb/core/System/SlicedStream.cpp; sourceTree = SOURCE_ROOT; };
+ A265ECEC13A8669700C6DF12 /* String.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = String.cpp; path = ../gemrb/core/System/String.cpp; sourceTree = SOURCE_ROOT; };
+ A276B3CA13A2867900D41A8A /* BIFImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = BIFImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B3D113A286A800D41A8A /* BIKPlayer.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = BIKPlayer.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B3D713A286BC00D41A8A /* BMPImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = BMPImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B3DD13A286CD00D41A8A /* BMPWriter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = BMPWriter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B3E313A286DE00D41A8A /* CHUImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = CHUImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B3E913A286EC00D41A8A /* CREImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = CREImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B3EF13A286FB00D41A8A /* DirectoryImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = DirectoryImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B3F513A2871300D41A8A /* DLGImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = DLGImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B3FB13A2872500D41A8A /* EFFImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = EFFImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B40113A2873700D41A8A /* FXOpcodes.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = FXOpcodes.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B40713A2874700D41A8A /* GAMImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = GAMImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B40D13A2875400D41A8A /* GUIScript.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = GUIScript.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B41313A2876300D41A8A /* IDSImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = IDSImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B41913A2877100D41A8A /* INIImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = INIImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B41F13A2878400D41A8A /* ITMImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = ITMImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B42513A2879900D41A8A /* IWDOpcodes.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = IWDOpcodes.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B42B13A287AB00D41A8A /* KEYImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = KEYImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B43113A287BD00D41A8A /* MOSImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = MOSImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B44913A289E000D41A8A /* MUSImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = MUSImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B44F13A28A0000D41A8A /* MVEPlayer.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = MVEPlayer.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B45513A28A0E00D41A8A /* NullSound.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = NullSound.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B45B13A28A1C00D41A8A /* OGGReader.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = OGGReader.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B46113A28A3100D41A8A /* OpenALAudio.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = OpenALAudio.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B46713A28A3F00D41A8A /* PLTImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = PLTImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B46D13A28A5000D41A8A /* PNGImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = PNGImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B47313A28A5D00D41A8A /* PROImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = PROImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B47913A28A7600D41A8A /* PSTOpcodes.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = PSTOpcodes.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B47F13A28A8500D41A8A /* SDLAudio.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = SDLAudio.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B48513A28A9000D41A8A /* SDLVideo.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = SDLVideo.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B48B13A28A9E00D41A8A /* SPLImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = SPLImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B49113A28AA900D41A8A /* TISImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = TISImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B49713A28AB800D41A8A /* TLKImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = TLKImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B49D13A28AC800D41A8A /* WAVReader.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = WAVReader.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B4A313A28AD300D41A8A /* WEDImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = WEDImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B4A913A28AE100D41A8A /* WMPImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = WMPImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B4AF13A28AEE00D41A8A /* ZLibManager.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = ZLibManager.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B4F413A28C0400D41A8A /* STOImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = STOImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A27979AC13ABA4F7009A6FEF /* SAVImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SAVImporter.cpp; sourceTree = "<group>"; };
+ A27979AD13ABA4F7009A6FEF /* SAVImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SAVImporter.h; sourceTree = "<group>"; };
+ A27A81C2145F12CD00883469 /* CocoaWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CocoaWrapper.m; sourceTree = "<group>"; };
+ A27B8699139F0A7D0002DC13 /* 2DAImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = 2DAImporter.cpp; sourceTree = "<group>"; };
+ A27B869A139F0A7D0002DC13 /* 2DAImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 2DAImporter.h; sourceTree = "<group>"; };
+ A27B869E139F0A7D0002DC13 /* ACMReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ACMReader.cpp; sourceTree = "<group>"; };
+ A27B869F139F0A7D0002DC13 /* ACMReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ACMReader.h; sourceTree = "<group>"; };
+ A27B86A1139F0A7D0002DC13 /* decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = decoder.cpp; sourceTree = "<group>"; };
+ A27B86A2139F0A7D0002DC13 /* decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = decoder.h; sourceTree = "<group>"; };
+ A27B86A3139F0A7D0002DC13 /* general.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = general.h; sourceTree = "<group>"; };
+ A27B86A5139F0A7D0002DC13 /* unpacker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unpacker.cpp; sourceTree = "<group>"; };
+ A27B86A6139F0A7D0002DC13 /* unpacker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unpacker.h; sourceTree = "<group>"; };
+ A27B86A8139F0A7D0002DC13 /* AREImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AREImporter.cpp; sourceTree = "<group>"; };
+ A27B86A9139F0A7D0002DC13 /* AREImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AREImporter.h; sourceTree = "<group>"; };
+ A27B86AD139F0A7D0002DC13 /* BAMImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BAMImporter.cpp; sourceTree = "<group>"; };
+ A27B86AE139F0A7D0002DC13 /* BAMImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BAMImporter.h; sourceTree = "<group>"; };
+ A27B86B2139F0A7D0002DC13 /* BIFImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BIFImporter.cpp; sourceTree = "<group>"; };
+ A27B86B3139F0A7D0002DC13 /* BIFImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BIFImporter.h; sourceTree = "<group>"; };
+ A27B86B7139F0A7D0002DC13 /* BIKPlayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BIKPlayer.cpp; sourceTree = "<group>"; };
+ A27B86B8139F0A7D0002DC13 /* BIKPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BIKPlayer.h; sourceTree = "<group>"; };
+ A27B86B9139F0A7D0002DC13 /* binkdata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = binkdata.h; sourceTree = "<group>"; };
+ A27B86BB139F0A7D0002DC13 /* common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = "<group>"; };
+ A27B86BC139F0A7D0002DC13 /* dct.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dct.cpp; sourceTree = "<group>"; };
+ A27B86BD139F0A7D0002DC13 /* dsputil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dsputil.h; sourceTree = "<group>"; };
+ A27B86BE139F0A7D0002DC13 /* fft.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fft.cpp; sourceTree = "<group>"; };
+ A27B86BF139F0A7D0002DC13 /* GetBitContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GetBitContext.cpp; sourceTree = "<group>"; };
+ A27B86C0139F0A7D0002DC13 /* GetBitContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GetBitContext.h; sourceTree = "<group>"; };
+ A27B86C2139F0A7D0002DC13 /* mem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mem.cpp; sourceTree = "<group>"; };
+ A27B86C3139F0A7D0002DC13 /* rational.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rational.cpp; sourceTree = "<group>"; };
+ A27B86C4139F0A7D0002DC13 /* rational.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rational.h; sourceTree = "<group>"; };
+ A27B86C5139F0A7D0002DC13 /* rdft.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rdft.cpp; sourceTree = "<group>"; };
+ A27B86C7139F0A7D0002DC13 /* BMPImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BMPImporter.cpp; sourceTree = "<group>"; };
+ A27B86C8139F0A7D0002DC13 /* BMPImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BMPImporter.h; sourceTree = "<group>"; };
+ A27B86CC139F0A7D0002DC13 /* BMPWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BMPWriter.cpp; sourceTree = "<group>"; };
+ A27B86CD139F0A7D0002DC13 /* BMPWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BMPWriter.h; sourceTree = "<group>"; };
+ A27B86D1139F0A7D0002DC13 /* CHUImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CHUImporter.cpp; sourceTree = "<group>"; };
+ A27B86D2139F0A7D0002DC13 /* CHUImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CHUImporter.h; sourceTree = "<group>"; };
+ A27B86D8139F0A7D0002DC13 /* CREImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CREImporter.cpp; sourceTree = "<group>"; };
+ A27B86D9139F0A7D0002DC13 /* CREImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CREImporter.h; sourceTree = "<group>"; };
+ A27B86DD139F0A7D0002DC13 /* DirectoryImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectoryImporter.cpp; sourceTree = "<group>"; };
+ A27B86DE139F0A7D0002DC13 /* DirectoryImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryImporter.h; sourceTree = "<group>"; };
+ A27B86E2139F0A7D0002DC13 /* DLGImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DLGImporter.cpp; sourceTree = "<group>"; };
+ A27B86E3139F0A7D0002DC13 /* DLGImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DLGImporter.h; sourceTree = "<group>"; };
+ A27B86E7139F0A7D0002DC13 /* EFFImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EFFImporter.cpp; sourceTree = "<group>"; };
+ A27B86E8139F0A7D0002DC13 /* EFFImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EFFImporter.h; sourceTree = "<group>"; };
+ A27B86EC139F0A7D0002DC13 /* FXOpcodes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FXOpcodes.cpp; sourceTree = "<group>"; };
+ A27B86F0139F0A7D0002DC13 /* GAMImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GAMImporter.cpp; sourceTree = "<group>"; };
+ A27B86F1139F0A7D0002DC13 /* GAMImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GAMImporter.h; sourceTree = "<group>"; };
+ A27B86F5139F0A7D0002DC13 /* GUIScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIScript.cpp; sourceTree = "<group>"; };
+ A27B86F6139F0A7D0002DC13 /* GUIScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIScript.h; sourceTree = "<group>"; };
+ A27B86F8139F0A7D0002DC13 /* PythonHelpers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PythonHelpers.cpp; sourceTree = "<group>"; };
+ A27B86F9139F0A7D0002DC13 /* PythonHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PythonHelpers.h; sourceTree = "<group>"; };
+ A27B86FC139F0A7D0002DC13 /* IDSImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDSImporter.cpp; sourceTree = "<group>"; };
+ A27B86FD139F0A7D0002DC13 /* IDSImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDSImporter.h; sourceTree = "<group>"; };
+ A27B86FE139F0A7D0002DC13 /* IDSImporterDefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDSImporterDefs.h; sourceTree = "<group>"; };
+ A27B8702139F0A7D0002DC13 /* INIImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = INIImporter.cpp; sourceTree = "<group>"; };
+ A27B8703139F0A7D0002DC13 /* INIImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = INIImporter.h; sourceTree = "<group>"; };
+ A27B8707139F0A7D0002DC13 /* ITMImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ITMImporter.cpp; sourceTree = "<group>"; };
+ A27B8708139F0A7D0002DC13 /* ITMImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ITMImporter.h; sourceTree = "<group>"; };
+ A27B870C139F0A7D0002DC13 /* IWDOpcodes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IWDOpcodes.cpp; sourceTree = "<group>"; };
+ A27B8710139F0A7D0002DC13 /* Dictionary.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Dictionary.cpp; sourceTree = "<group>"; };
+ A27B8711139F0A7D0002DC13 /* Dictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Dictionary.h; sourceTree = "<group>"; };
+ A27B8712139F0A7D0002DC13 /* KEYImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KEYImporter.cpp; sourceTree = "<group>"; };
+ A27B8713139F0A7D0002DC13 /* KEYImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KEYImporter.h; sourceTree = "<group>"; };
+ A27B8719139F0A7D0002DC13 /* MOSImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MOSImporter.cpp; sourceTree = "<group>"; };
+ A27B871A139F0A7D0002DC13 /* MOSImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MOSImporter.h; sourceTree = "<group>"; };
+ A27B871E139F0A7D0002DC13 /* MUSImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MUSImporter.cpp; sourceTree = "<group>"; };
+ A27B871F139F0A7D0002DC13 /* MUSImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MUSImporter.h; sourceTree = "<group>"; };
+ A27B8722139F0A7D0002DC13 /* gstmvedemux.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gstmvedemux.h; sourceTree = "<group>"; };
+ A27B8724139F0A7D0002DC13 /* mve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mve.h; sourceTree = "<group>"; };
+ A27B8725139F0A7D0002DC13 /* mve_player.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mve_player.cpp; sourceTree = "<group>"; };
+ A27B8726139F0A7D0002DC13 /* mve_player.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mve_player.h; sourceTree = "<group>"; };
+ A27B8727139F0A7D0002DC13 /* mveaudiodec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mveaudiodec.cpp; sourceTree = "<group>"; };
+ A27B8728139F0A7D0002DC13 /* MVEPlayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MVEPlayer.cpp; sourceTree = "<group>"; };
+ A27B8729139F0A7D0002DC13 /* MVEPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVEPlayer.h; sourceTree = "<group>"; };
+ A27B872A139F0A7D0002DC13 /* mvevideodec16.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mvevideodec16.cpp; sourceTree = "<group>"; };
+ A27B872B139F0A7D0002DC13 /* mvevideodec8.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mvevideodec8.cpp; sourceTree = "<group>"; };
+ A27B872F139F0A7D0002DC13 /* NullSound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NullSound.cpp; sourceTree = "<group>"; };
+ A27B8730139F0A7D0002DC13 /* NullSound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NullSound.h; sourceTree = "<group>"; };
+ A27B8734139F0A7D0002DC13 /* OGGReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OGGReader.cpp; sourceTree = "<group>"; };
+ A27B8735139F0A7D0002DC13 /* OGGReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OGGReader.h; sourceTree = "<group>"; };
+ A27B8737139F0A7D0002DC13 /* AmbientMgrAL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AmbientMgrAL.cpp; sourceTree = "<group>"; };
+ A27B8738139F0A7D0002DC13 /* AmbientMgrAL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AmbientMgrAL.h; sourceTree = "<group>"; };
+ A27B873B139F0A7D0002DC13 /* OpenALAudio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenALAudio.cpp; sourceTree = "<group>"; };
+ A27B873C139F0A7D0002DC13 /* OpenALAudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenALAudio.h; sourceTree = "<group>"; };
+ A27B873D139F0A7D0002DC13 /* StackLock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StackLock.cpp; sourceTree = "<group>"; };
+ A27B873E139F0A7D0002DC13 /* StackLock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StackLock.h; sourceTree = "<group>"; };
+ A27B8742139F0A7D0002DC13 /* PLTImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PLTImporter.cpp; sourceTree = "<group>"; };
+ A27B8743139F0A7D0002DC13 /* PLTImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PLTImporter.h; sourceTree = "<group>"; };
+ A27B8747139F0A7D0002DC13 /* PNGImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PNGImporter.cpp; sourceTree = "<group>"; };
+ A27B8748139F0A7D0002DC13 /* PNGImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PNGImporter.h; sourceTree = "<group>"; };
+ A27B874C139F0A7D0002DC13 /* PROImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PROImporter.cpp; sourceTree = "<group>"; };
+ A27B874D139F0A7D0002DC13 /* PROImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PROImporter.h; sourceTree = "<group>"; };
+ A27B8751139F0A7D0002DC13 /* PSTOpcodes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PSTOpcodes.cpp; sourceTree = "<group>"; };
+ A27B8755139F0A7D0002DC13 /* SDLAudio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SDLAudio.cpp; sourceTree = "<group>"; };
+ A27B8756139F0A7D0002DC13 /* SDLAudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLAudio.h; sourceTree = "<group>"; };
+ A27B875A139F0A7D0002DC13 /* SDLVideo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SDLVideo.cpp; sourceTree = "<group>"; };
+ A27B875B139F0A7D0002DC13 /* SDLVideo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLVideo.h; sourceTree = "<group>"; };
+ A27B8761139F0A7D0002DC13 /* SPLImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SPLImporter.cpp; sourceTree = "<group>"; };
+ A27B8762139F0A7D0002DC13 /* SPLImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPLImporter.h; sourceTree = "<group>"; };
+ A27B8766139F0A7D0002DC13 /* STOImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = STOImporter.cpp; sourceTree = "<group>"; };
+ A27B8767139F0A7D0002DC13 /* STOImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STOImporter.h; sourceTree = "<group>"; };
+ A27B876B139F0A7D0002DC13 /* TISImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TISImporter.cpp; sourceTree = "<group>"; };
+ A27B876C139F0A7D0002DC13 /* TISImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TISImporter.h; sourceTree = "<group>"; };
+ A27B8770139F0A7D0002DC13 /* TLKImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TLKImporter.cpp; sourceTree = "<group>"; };
+ A27B8771139F0A7D0002DC13 /* TLKImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TLKImporter.h; sourceTree = "<group>"; };
+ A27B8772139F0A7D0002DC13 /* TlkOverride.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TlkOverride.cpp; sourceTree = "<group>"; };
+ A27B8773139F0A7D0002DC13 /* TlkOverride.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TlkOverride.h; sourceTree = "<group>"; };
+ A27B8777139F0A7D0002DC13 /* WAVReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WAVReader.cpp; sourceTree = "<group>"; };
+ A27B8778139F0A7D0002DC13 /* WAVReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WAVReader.h; sourceTree = "<group>"; };
+ A27B877C139F0A7D0002DC13 /* WEDImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WEDImporter.cpp; sourceTree = "<group>"; };
+ A27B877D139F0A7D0002DC13 /* WEDImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WEDImporter.h; sourceTree = "<group>"; };
+ A27B8781139F0A7D0002DC13 /* WMPImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WMPImporter.cpp; sourceTree = "<group>"; };
+ A27B8782139F0A7D0002DC13 /* WMPImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMPImporter.h; sourceTree = "<group>"; };
+ A27B8786139F0A7D0002DC13 /* ZLibManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ZLibManager.cpp; sourceTree = "<group>"; };
+ A27B8787139F0A7D0002DC13 /* ZLibManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZLibManager.h; sourceTree = "<group>"; };
+ A27B87B5139F0E120002DC13 /* plugins.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = plugins.pch; path = ../../apple/osx/plugins.pch; sourceTree = "<group>"; };
+ A27E830A13A0358200B41410 /* 2DAImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = 2DAImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A2830A0F13A05A64000A63FE /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = System/Library/Frameworks/OpenAL.framework; sourceTree = SDKROOT; };
+ A2830A3913A05B5F000A63FE /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
+ A2830A3F13A05B81000A63FE /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
+ A2830ABA13A0624D000A63FE /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = ios/Info.plist; sourceTree = "<group>"; };
+ A28D2498143BEA4200A27897 /* FontManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FontManager.cpp; sourceTree = "<group>"; };
+ A28D249B143BEA5800A27897 /* FontManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontManager.h; sourceTree = "<group>"; };
+ A28D24A0143C24C100A27897 /* BAMFontManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BAMFontManager.cpp; sourceTree = "<group>"; };
+ A28D24A3143C24E500A27897 /* BAMFontManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BAMFontManager.h; sourceTree = "<group>"; };
+ A29BF7B213A0380F00C812DD /* BAMImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = BAMImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A29BF7FC13A039DD00C812DD /* SDL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL.framework; path = /Library/Frameworks/SDL.framework; sourceTree = "<absolute>"; };
+ A29BF85C13A0427900C812DD /* GemRB.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GemRB.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ A2A6A44F14687E55000F1688 /* GEM_ConfController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GEM_ConfController.h; path = ../gemrb/CocoaWrapper/ios/GEM_ConfController.h; sourceTree = "<group>"; };
+ A2A6A45014687E55000F1688 /* GEM_ConfController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GEM_ConfController.m; path = ../gemrb/CocoaWrapper/ios/GEM_ConfController.m; sourceTree = "<group>"; };
+ A2A6A45114687E55000F1688 /* GEM_ConfController-iphone.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = "GEM_ConfController-iphone.xib"; path = "../gemrb/CocoaWrapper/ios/GEM_ConfController-iphone.xib"; sourceTree = "<group>"; };
+ A2A6A454146880C1000F1688 /* CocoaWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CocoaWrapper.m; path = ../gemrb/CocoaWrapper/CocoaWrapper.m; sourceTree = "<group>"; };
+ A2A6A459146893CC000F1688 /* TTFFontManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TTFFontManager.cpp; sourceTree = "<group>"; };
+ A2A6A45A146893CC000F1688 /* TTFFontManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TTFFontManager.h; sourceTree = "<group>"; };
+ A2AAF36713A1507100AE8402 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
+ A2AAF38D13A150D700AE8402 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
+ A2AAF39313A150F900AE8402 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
+ A2AC3E561462F7C2000E1E2C /* compiler_macros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = compiler_macros.h; sourceTree = "<group>"; };
+ A2BD81A313960965007E9C63 /* defsounds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = defsounds.h; sourceTree = "<group>"; };
+ A2BD81A413960965007E9C63 /* errors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = errors.h; sourceTree = "<group>"; };
+ A2BD81A513960965007E9C63 /* exports.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = exports.h; sourceTree = "<group>"; };
+ A2BD81A613960965007E9C63 /* globals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = globals.h; sourceTree = "<group>"; };
+ A2BD81A713960965007E9C63 /* ie_feats.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ie_feats.h; sourceTree = "<group>"; };
+ A2BD81A813960965007E9C63 /* ie_stats.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ie_stats.h; sourceTree = "<group>"; };
+ A2BD81A913960965007E9C63 /* ie_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ie_types.h; sourceTree = "<group>"; };
+ A2BD81AA13960965007E9C63 /* iless.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iless.h; sourceTree = "<group>"; };
+ A2BD81AB13960965007E9C63 /* logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = logging.h; sourceTree = "<group>"; };
+ A2BD81AD13960965007E9C63 /* opcode_params.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opcode_params.h; sourceTree = "<group>"; };
+ A2BD81AE13960965007E9C63 /* operatorbool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = operatorbool.h; sourceTree = "<group>"; };
+ A2BD81AF13960965007E9C63 /* overlays.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = overlays.h; sourceTree = "<group>"; };
+ A2BD81B013960965007E9C63 /* plugindef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = plugindef.h; sourceTree = "<group>"; };
+ A2BD81B113960965007E9C63 /* RGBAColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RGBAColor.h; sourceTree = "<group>"; };
+ A2BD81B213960965007E9C63 /* SClassID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SClassID.h; sourceTree = "<group>"; };
+ A2BD81B313960965007E9C63 /* strrefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = strrefs.h; sourceTree = "<group>"; };
+ A2BD82721396B886007E9C63 /* GemRB.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = GemRB.cpp; path = ../gemrb/GemRB.cpp; sourceTree = SOURCE_ROOT; };
+ A2BD83111396FD5F007E9C63 /* Python.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Python.framework; path = /System/Library/Frameworks/Python.framework; sourceTree = "<absolute>"; };
+ A2BD831D1396FE16007E9C63 /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = /System/Library/Frameworks/OpenAL.framework; sourceTree = "<absolute>"; };
+ A2BD83F4139713A8007E9C63 /* win32def.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = win32def.h; sourceTree = "<group>"; };
+ A2BF9F8D1395FF61006ADC12 /* ActorMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActorMgr.cpp; sourceTree = "<group>"; };
+ A2BF9F8E1395FF61006ADC12 /* ActorMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActorMgr.h; sourceTree = "<group>"; };
+ A2BF9F8F1395FF61006ADC12 /* Ambient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Ambient.cpp; sourceTree = "<group>"; };
+ A2BF9F901395FF61006ADC12 /* Ambient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Ambient.h; sourceTree = "<group>"; };
+ A2BF9F911395FF61006ADC12 /* AmbientMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AmbientMgr.cpp; sourceTree = "<group>"; };
+ A2BF9F921395FF61006ADC12 /* AmbientMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AmbientMgr.h; sourceTree = "<group>"; };
+ A2BF9F931395FF61006ADC12 /* Animation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Animation.cpp; sourceTree = "<group>"; };
+ A2BF9F941395FF61006ADC12 /* Animation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Animation.h; sourceTree = "<group>"; };
+ A2BF9F951395FF61006ADC12 /* AnimationFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AnimationFactory.cpp; sourceTree = "<group>"; };
+ A2BF9F961395FF61006ADC12 /* AnimationFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnimationFactory.h; sourceTree = "<group>"; };
+ A2BF9F971395FF61006ADC12 /* AnimationMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AnimationMgr.cpp; sourceTree = "<group>"; };
+ A2BF9F981395FF61006ADC12 /* AnimationMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnimationMgr.h; sourceTree = "<group>"; };
+ A2BF9F991395FF61006ADC12 /* AnimStructures.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnimStructures.h; sourceTree = "<group>"; };
+ A2BF9F9A1395FF61006ADC12 /* ArchiveImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArchiveImporter.cpp; sourceTree = "<group>"; };
+ A2BF9F9B1395FF61006ADC12 /* ArchiveImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArchiveImporter.h; sourceTree = "<group>"; };
+ A2BF9F9C1395FF61006ADC12 /* Audio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Audio.cpp; sourceTree = "<group>"; };
+ A2BF9F9D1395FF61006ADC12 /* Audio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Audio.h; sourceTree = "<group>"; };
+ A2BF9F9E1395FF61006ADC12 /* Bitmap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Bitmap.cpp; sourceTree = "<group>"; };
+ A2BF9F9F1395FF61006ADC12 /* Bitmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Bitmap.h; sourceTree = "<group>"; };
+ A2BF9FA01395FF61006ADC12 /* Cache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Cache.cpp; sourceTree = "<group>"; };
+ A2BF9FA11395FF61006ADC12 /* Cache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cache.h; sourceTree = "<group>"; };
+ A2BF9FA21395FF61006ADC12 /* Calendar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Calendar.cpp; sourceTree = "<group>"; };
+ A2BF9FA31395FF61006ADC12 /* Calendar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Calendar.h; sourceTree = "<group>"; };
+ A2BF9FA41395FF61006ADC12 /* Callback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Callback.cpp; sourceTree = "<group>"; };
+ A2BF9FA51395FF61006ADC12 /* Callback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Callback.h; sourceTree = "<group>"; };
+ A2BF9FA61395FF61006ADC12 /* CharAnimations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CharAnimations.cpp; sourceTree = "<group>"; };
+ A2BF9FA71395FF61006ADC12 /* CharAnimations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CharAnimations.h; sourceTree = "<group>"; };
+ A2BF9FA91395FF61006ADC12 /* Compressor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Compressor.cpp; sourceTree = "<group>"; };
+ A2BF9FAA1395FF61006ADC12 /* Compressor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Compressor.h; sourceTree = "<group>"; };
+ A2BF9FAB1395FF61006ADC12 /* ControlAnimation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ControlAnimation.cpp; sourceTree = "<group>"; };
+ A2BF9FAC1395FF61006ADC12 /* ControlAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ControlAnimation.h; sourceTree = "<group>"; };
+ A2BF9FAD1395FF61006ADC12 /* Core.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Core.cpp; sourceTree = "<group>"; };
+ A2BF9FAE1395FF61006ADC12 /* damages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = damages.h; sourceTree = "<group>"; };
+ A2BF9FAF1395FF61006ADC12 /* DataFileMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DataFileMgr.cpp; sourceTree = "<group>"; };
+ A2BF9FB01395FF61006ADC12 /* DataFileMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataFileMgr.h; sourceTree = "<group>"; };
+ A2BF9FB11395FF61006ADC12 /* Dialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Dialog.cpp; sourceTree = "<group>"; };
+ A2BF9FB21395FF61006ADC12 /* Dialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Dialog.h; sourceTree = "<group>"; };
+ A2BF9FB31395FF61006ADC12 /* DialogHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DialogHandler.cpp; sourceTree = "<group>"; };
+ A2BF9FB41395FF61006ADC12 /* DialogHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DialogHandler.h; sourceTree = "<group>"; };
+ A2BF9FB51395FF61006ADC12 /* DialogMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DialogMgr.cpp; sourceTree = "<group>"; };
+ A2BF9FB61395FF61006ADC12 /* DialogMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DialogMgr.h; sourceTree = "<group>"; };
+ A2BF9FB71395FF61006ADC12 /* DisplayMessage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DisplayMessage.cpp; sourceTree = "<group>"; };
+ A2BF9FB81395FF61006ADC12 /* DisplayMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DisplayMessage.h; sourceTree = "<group>"; };
+ A2BF9FB91395FF61006ADC12 /* Effect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Effect.h; sourceTree = "<group>"; };
+ A2BF9FBA1395FF61006ADC12 /* EffectMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EffectMgr.cpp; sourceTree = "<group>"; };
+ A2BF9FBB1395FF61006ADC12 /* EffectMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EffectMgr.h; sourceTree = "<group>"; };
+ A2BF9FBC1395FF61006ADC12 /* EffectQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EffectQueue.cpp; sourceTree = "<group>"; };
+ A2BF9FBD1395FF61006ADC12 /* EffectQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EffectQueue.h; sourceTree = "<group>"; };
+ A2BF9FBE1395FF61006ADC12 /* Factory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Factory.cpp; sourceTree = "<group>"; };
+ A2BF9FBF1395FF61006ADC12 /* Factory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Factory.h; sourceTree = "<group>"; };
+ A2BF9FC01395FF61006ADC12 /* FactoryObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FactoryObject.cpp; sourceTree = "<group>"; };
+ A2BF9FC11395FF61006ADC12 /* FactoryObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FactoryObject.h; sourceTree = "<group>"; };
+ A2BF9FC21395FF61006ADC12 /* Font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Font.cpp; sourceTree = "<group>"; };
+ A2BF9FC31395FF61006ADC12 /* Font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Font.h; sourceTree = "<group>"; };
+ A2BF9FC41395FF61006ADC12 /* Game.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Game.cpp; sourceTree = "<group>"; };
+ A2BF9FC51395FF62006ADC12 /* Game.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Game.h; sourceTree = "<group>"; };
+ A2BF9FC61395FF62006ADC12 /* GameData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GameData.cpp; sourceTree = "<group>"; };
+ A2BF9FC71395FF62006ADC12 /* GameData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GameData.h; sourceTree = "<group>"; };
+ A2BF9FC91395FF62006ADC12 /* Actions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Actions.cpp; sourceTree = "<group>"; };
+ A2BF9FCA1395FF62006ADC12 /* GameScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GameScript.cpp; sourceTree = "<group>"; };
+ A2BF9FCB1395FF62006ADC12 /* GameScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GameScript.h; sourceTree = "<group>"; };
+ A2BF9FCC1395FF62006ADC12 /* GSUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GSUtils.cpp; sourceTree = "<group>"; };
+ A2BF9FCD1395FF62006ADC12 /* GSUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GSUtils.h; sourceTree = "<group>"; };
+ A2BF9FCE1395FF62006ADC12 /* Matching.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Matching.cpp; sourceTree = "<group>"; };
+ A2BF9FCF1395FF62006ADC12 /* Matching.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Matching.h; sourceTree = "<group>"; };
+ A2BF9FD01395FF62006ADC12 /* Objects.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Objects.cpp; sourceTree = "<group>"; };
+ A2BF9FD11395FF62006ADC12 /* Triggers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Triggers.cpp; sourceTree = "<group>"; };
+ A2BF9FD21395FF62006ADC12 /* GlobalTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GlobalTimer.cpp; sourceTree = "<group>"; };
+ A2BF9FD31395FF62006ADC12 /* GlobalTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GlobalTimer.h; sourceTree = "<group>"; };
+ A2BF9FD51395FF62006ADC12 /* Button.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Button.cpp; sourceTree = "<group>"; };
+ A2BF9FD61395FF62006ADC12 /* Button.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Button.h; sourceTree = "<group>"; };
+ A2BF9FD71395FF62006ADC12 /* Console.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Console.cpp; sourceTree = "<group>"; };
+ A2BF9FD81395FF62006ADC12 /* Console.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Console.h; sourceTree = "<group>"; };
+ A2BF9FD91395FF62006ADC12 /* Control.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Control.cpp; sourceTree = "<group>"; };
+ A2BF9FDA1395FF62006ADC12 /* Control.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Control.h; sourceTree = "<group>"; };
+ A2BF9FDB1395FF62006ADC12 /* EventMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventMgr.cpp; sourceTree = "<group>"; };
+ A2BF9FDC1395FF62006ADC12 /* EventMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventMgr.h; sourceTree = "<group>"; };
+ A2BF9FDD1395FF62006ADC12 /* GameControl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GameControl.cpp; sourceTree = "<group>"; };
+ A2BF9FDE1395FF62006ADC12 /* GameControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GameControl.h; sourceTree = "<group>"; };
+ A2BF9FDF1395FF62006ADC12 /* Label.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Label.cpp; sourceTree = "<group>"; };
+ A2BF9FE01395FF62006ADC12 /* Label.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Label.h; sourceTree = "<group>"; };
+ A2BF9FE11395FF62006ADC12 /* MapControl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MapControl.cpp; sourceTree = "<group>"; };
+ A2BF9FE21395FF62006ADC12 /* MapControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapControl.h; sourceTree = "<group>"; };
+ A2BF9FE31395FF62006ADC12 /* Progressbar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Progressbar.cpp; sourceTree = "<group>"; };
+ A2BF9FE41395FF62006ADC12 /* Progressbar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Progressbar.h; sourceTree = "<group>"; };
+ A2BF9FE51395FF62006ADC12 /* ScrollBar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollBar.cpp; sourceTree = "<group>"; };
+ A2BF9FE61395FF62006ADC12 /* ScrollBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollBar.h; sourceTree = "<group>"; };
+ A2BF9FE71395FF62006ADC12 /* Slider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Slider.cpp; sourceTree = "<group>"; };
+ A2BF9FE81395FF62006ADC12 /* Slider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Slider.h; sourceTree = "<group>"; };
+ A2BF9FE91395FF62006ADC12 /* TextArea.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextArea.cpp; sourceTree = "<group>"; };
+ A2BF9FEA1395FF62006ADC12 /* TextArea.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextArea.h; sourceTree = "<group>"; };
+ A2BF9FEB1395FF62006ADC12 /* TextEdit.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; path = TextEdit.cpp; sourceTree = "<group>"; };
+ A2BF9FEC1395FF62006ADC12 /* TextEdit.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = TextEdit.h; sourceTree = "<group>"; };
+ A2BF9FED1395FF62006ADC12 /* Window.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Window.cpp; sourceTree = "<group>"; };
+ A2BF9FEE1395FF62006ADC12 /* Window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Window.h; sourceTree = "<group>"; };
+ A2BF9FEF1395FF62006ADC12 /* WorldMapControl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorldMapControl.cpp; sourceTree = "<group>"; };
+ A2BF9FF01395FF62006ADC12 /* WorldMapControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorldMapControl.h; sourceTree = "<group>"; };
+ A2BF9FF11395FF62006ADC12 /* Holder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Holder.h; sourceTree = "<group>"; };
+ A2BF9FF21395FF62006ADC12 /* Image.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Image.cpp; sourceTree = "<group>"; };
+ A2BF9FF31395FF62006ADC12 /* Image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = "<group>"; };
+ A2BF9FF41395FF62006ADC12 /* ImageFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageFactory.cpp; sourceTree = "<group>"; };
+ A2BF9FF51395FF62006ADC12 /* ImageFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageFactory.h; sourceTree = "<group>"; };
+ A2BF9FF61395FF62006ADC12 /* ImageMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageMgr.cpp; sourceTree = "<group>"; };
+ A2BF9FF71395FF62006ADC12 /* ImageMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageMgr.h; sourceTree = "<group>"; };
+ A2BF9FF81395FF62006ADC12 /* ImageWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageWriter.cpp; sourceTree = "<group>"; };
+ A2BF9FF91395FF62006ADC12 /* ImageWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageWriter.h; sourceTree = "<group>"; };
+ A2BF9FFA1395FF62006ADC12 /* IniSpawn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IniSpawn.cpp; sourceTree = "<group>"; };
+ A2BF9FFB1395FF62006ADC12 /* IniSpawn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IniSpawn.h; sourceTree = "<group>"; };
+ A2BF9FFC1395FF62006ADC12 /* Interface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Interface.cpp; sourceTree = "<group>"; };
+ A2BF9FFD1395FF62006ADC12 /* Interface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Interface.h; sourceTree = "<group>"; };
+ A2BF9FFE1395FF62006ADC12 /* Inventory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Inventory.cpp; sourceTree = "<group>"; };
+ A2BF9FFF1395FF62006ADC12 /* Inventory.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = Inventory.h; sourceTree = "<group>"; };
+ A2BFA0001395FF62006ADC12 /* Item.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Item.cpp; sourceTree = "<group>"; };
+ A2BFA0011395FF62006ADC12 /* Item.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Item.h; sourceTree = "<group>"; };
+ A2BFA0021395FF62006ADC12 /* ItemMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ItemMgr.cpp; sourceTree = "<group>"; };
+ A2BFA0031395FF62006ADC12 /* ItemMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ItemMgr.h; sourceTree = "<group>"; };
+ A2BFA0041395FF62006ADC12 /* LRUCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LRUCache.cpp; sourceTree = "<group>"; };
+ A2BFA0051395FF62006ADC12 /* LRUCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LRUCache.h; sourceTree = "<group>"; };
+ A2BFA0071395FF62006ADC12 /* Map.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Map.cpp; sourceTree = "<group>"; };
+ A2BFA0081395FF62006ADC12 /* Map.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Map.h; sourceTree = "<group>"; };
+ A2BFA0091395FF62006ADC12 /* MapMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MapMgr.cpp; sourceTree = "<group>"; };
+ A2BFA00A1395FF62006ADC12 /* MapMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapMgr.h; sourceTree = "<group>"; };
+ A2BFA00B1395FF62006ADC12 /* MoviePlayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MoviePlayer.cpp; sourceTree = "<group>"; };
+ A2BFA00C1395FF62006ADC12 /* MoviePlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MoviePlayer.h; sourceTree = "<group>"; };
+ A2BFA00D1395FF62006ADC12 /* MusicMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MusicMgr.cpp; sourceTree = "<group>"; };
+ A2BFA00E1395FF62006ADC12 /* MusicMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicMgr.h; sourceTree = "<group>"; };
+ A2BFA00F1395FF62006ADC12 /* Palette.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Palette.cpp; sourceTree = "<group>"; };
+ A2BFA0101395FF62006ADC12 /* Palette.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Palette.h; sourceTree = "<group>"; };
+ A2BFA0111395FF62006ADC12 /* PalettedImageMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PalettedImageMgr.cpp; sourceTree = "<group>"; };
+ A2BFA0121395FF62006ADC12 /* PalettedImageMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PalettedImageMgr.h; sourceTree = "<group>"; };
+ A2BFA0131395FF62006ADC12 /* Particles.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Particles.cpp; sourceTree = "<group>"; };
+ A2BFA0141395FF62006ADC12 /* Particles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Particles.h; sourceTree = "<group>"; };
+ A2BFA0151395FF62006ADC12 /* PathFinder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathFinder.h; sourceTree = "<group>"; };
+ A2BFA0161395FF62006ADC12 /* Plugin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Plugin.cpp; sourceTree = "<group>"; };
+ A2BFA0171395FF62006ADC12 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Plugin.h; sourceTree = "<group>"; };
+ A2BFA0181395FF62006ADC12 /* PluginMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PluginMgr.cpp; sourceTree = "<group>"; };
+ A2BFA0191395FF62006ADC12 /* PluginMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PluginMgr.h; sourceTree = "<group>"; };
+ A2BFA01A1395FF62006ADC12 /* Polygon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Polygon.cpp; sourceTree = "<group>"; };
+ A2BFA01B1395FF62006ADC12 /* Polygon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Polygon.h; sourceTree = "<group>"; };
+ A2BFA01C1395FF62006ADC12 /* PolymorphCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolymorphCache.h; sourceTree = "<group>"; };
+ A2BFA01D1395FF62006ADC12 /* Projectile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Projectile.cpp; sourceTree = "<group>"; };
+ A2BFA01E1395FF62006ADC12 /* Projectile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Projectile.h; sourceTree = "<group>"; };
+ A2BFA01F1395FF62006ADC12 /* ProjectileMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProjectileMgr.cpp; sourceTree = "<group>"; };
+ A2BFA0201395FF62006ADC12 /* ProjectileMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProjectileMgr.h; sourceTree = "<group>"; };
+ A2BFA0211395FF62006ADC12 /* ProjectileServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProjectileServer.cpp; sourceTree = "<group>"; };
+ A2BFA0221395FF62006ADC12 /* ProjectileServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProjectileServer.h; sourceTree = "<group>"; };
+ A2BFA0231395FF62006ADC12 /* Region.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Region.cpp; sourceTree = "<group>"; };
+ A2BFA0241395FF62006ADC12 /* Region.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Region.h; sourceTree = "<group>"; };
+ A2BFA0251395FF62006ADC12 /* Resource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Resource.cpp; sourceTree = "<group>"; };
+ A2BFA0261395FF62006ADC12 /* Resource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Resource.h; sourceTree = "<group>"; };
+ A2BFA0271395FF62006ADC12 /* ResourceDesc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResourceDesc.cpp; sourceTree = "<group>"; };
+ A2BFA0281395FF62006ADC12 /* ResourceDesc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResourceDesc.h; sourceTree = "<group>"; };
+ A2BFA0291395FF62006ADC12 /* ResourceManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResourceManager.cpp; sourceTree = "<group>"; };
+ A2BFA02A1395FF62006ADC12 /* ResourceManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResourceManager.h; sourceTree = "<group>"; };
+ A2BFA02B1395FF62006ADC12 /* ResourceSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResourceSource.cpp; sourceTree = "<group>"; };
+ A2BFA02C1395FF62006ADC12 /* ResourceSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResourceSource.h; sourceTree = "<group>"; };
+ A2BFA02D1395FF62006ADC12 /* SaveGame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SaveGame.h; sourceTree = "<group>"; };
+ A2BFA02E1395FF62006ADC12 /* SaveGameIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SaveGameIterator.cpp; sourceTree = "<group>"; };
+ A2BFA02F1395FF62006ADC12 /* SaveGameIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SaveGameIterator.h; sourceTree = "<group>"; };
+ A2BFA0301395FF62006ADC12 /* SaveGameMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SaveGameMgr.cpp; sourceTree = "<group>"; };
+ A2BFA0311395FF62006ADC12 /* SaveGameMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SaveGameMgr.h; sourceTree = "<group>"; };
+ A2BFA0331395FF62006ADC12 /* Actor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Actor.cpp; sourceTree = "<group>"; };
+ A2BFA0341395FF62006ADC12 /* Actor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Actor.h; sourceTree = "<group>"; };
+ A2BFA0351395FF62006ADC12 /* Container.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Container.cpp; sourceTree = "<group>"; };
+ A2BFA0361395FF62006ADC12 /* Container.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Container.h; sourceTree = "<group>"; };
+ A2BFA0371395FF62006ADC12 /* Door.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Door.cpp; sourceTree = "<group>"; };
+ A2BFA0381395FF62006ADC12 /* Door.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Door.h; sourceTree = "<group>"; };
+ A2BFA0391395FF62006ADC12 /* InfoPoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InfoPoint.cpp; sourceTree = "<group>"; };
+ A2BFA03A1395FF62006ADC12 /* InfoPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InfoPoint.h; sourceTree = "<group>"; };
+ A2BFA03B1395FF62006ADC12 /* PCStatStruct.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PCStatStruct.cpp; sourceTree = "<group>"; };
+ A2BFA03C1395FF62006ADC12 /* PCStatStruct.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PCStatStruct.h; sourceTree = "<group>"; };
+ A2BFA03D1395FF62006ADC12 /* Scriptable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Scriptable.cpp; sourceTree = "<group>"; };
+ A2BFA03E1395FF62006ADC12 /* Scriptable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Scriptable.h; sourceTree = "<group>"; };
+ A2BFA03F1395FF62006ADC12 /* ScriptedAnimation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptedAnimation.cpp; sourceTree = "<group>"; };
+ A2BFA0401395FF62006ADC12 /* ScriptedAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptedAnimation.h; sourceTree = "<group>"; };
+ A2BFA0411395FF62006ADC12 /* ScriptEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptEngine.cpp; sourceTree = "<group>"; };
+ A2BFA0421395FF62006ADC12 /* ScriptEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptEngine.h; sourceTree = "<group>"; };
+ A2BFA0431395FF62006ADC12 /* SoundMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SoundMgr.cpp; sourceTree = "<group>"; };
+ A2BFA0441395FF62006ADC12 /* SoundMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SoundMgr.h; sourceTree = "<group>"; };
+ A2BFA0451395FF62006ADC12 /* Spell.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Spell.cpp; sourceTree = "<group>"; };
+ A2BFA0461395FF62006ADC12 /* Spell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Spell.h; sourceTree = "<group>"; };
+ A2BFA0471395FF62006ADC12 /* Spellbook.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Spellbook.cpp; sourceTree = "<group>"; };
+ A2BFA0481395FF62006ADC12 /* Spellbook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Spellbook.h; sourceTree = "<group>"; };
+ A2BFA0491395FF62006ADC12 /* SpellMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpellMgr.cpp; sourceTree = "<group>"; };
+ A2BFA04A1395FF62006ADC12 /* SpellMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpellMgr.h; sourceTree = "<group>"; };
+ A2BFA04B1395FF62006ADC12 /* Sprite2D.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Sprite2D.cpp; sourceTree = "<group>"; };
+ A2BFA04C1395FF62006ADC12 /* Sprite2D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Sprite2D.h; sourceTree = "<group>"; };
+ A2BFA04D1395FF62006ADC12 /* SpriteCover.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpriteCover.cpp; sourceTree = "<group>"; };
+ A2BFA04E1395FF62006ADC12 /* SpriteCover.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpriteCover.h; sourceTree = "<group>"; };
+ A2BFA04F1395FF62006ADC12 /* Store.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Store.cpp; sourceTree = "<group>"; };
+ A2BFA0501395FF62006ADC12 /* Store.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Store.h; sourceTree = "<group>"; };
+ A2BFA0511395FF62006ADC12 /* StoreMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StoreMgr.cpp; sourceTree = "<group>"; };
+ A2BFA0521395FF62006ADC12 /* StoreMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StoreMgr.h; sourceTree = "<group>"; };
+ A2BFA0531395FF62006ADC12 /* StringMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringMgr.cpp; sourceTree = "<group>"; };
+ A2BFA0541395FF62006ADC12 /* StringMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringMgr.h; sourceTree = "<group>"; };
+ A2BFA0551395FF62006ADC12 /* SymbolMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SymbolMgr.cpp; sourceTree = "<group>"; };
+ A2BFA0561395FF62006ADC12 /* SymbolMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolMgr.h; sourceTree = "<group>"; };
+ A2BFA05C1395FF62006ADC12 /* DataStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DataStream.cpp; sourceTree = "<group>"; };
+ A2BFA05D1395FF62006ADC12 /* DataStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataStream.h; sourceTree = "<group>"; };
+ A2BFA05E1395FF62006ADC12 /* FileStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileStream.cpp; sourceTree = "<group>"; };
+ A2BFA05F1395FF62006ADC12 /* FileStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileStream.h; sourceTree = "<group>"; };
+ A2BFA0601395FF62006ADC12 /* MemoryStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MemoryStream.cpp; sourceTree = "<group>"; };
+ A2BFA0611395FF62006ADC12 /* MemoryStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryStream.h; sourceTree = "<group>"; };
+ A2BFA0641395FF62006ADC12 /* swab.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = swab.c; sourceTree = "<group>"; };
+ A2BFA0651395FF62006ADC12 /* swab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = swab.h; sourceTree = "<group>"; };
+ A2BFA0661395FF62006ADC12 /* VFS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VFS.cpp; sourceTree = "<group>"; };
+ A2BFA0671395FF62006ADC12 /* VFS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VFS.h; sourceTree = "<group>"; };
+ A2BFA0681395FF62006ADC12 /* TableMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TableMgr.cpp; sourceTree = "<group>"; };
+ A2BFA0691395FF62006ADC12 /* TableMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TableMgr.h; sourceTree = "<group>"; };
+ A2BFA06A1395FF62006ADC12 /* Tile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Tile.cpp; sourceTree = "<group>"; };
+ A2BFA06B1395FF62006ADC12 /* Tile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Tile.h; sourceTree = "<group>"; };
+ A2BFA06C1395FF62006ADC12 /* TileMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TileMap.cpp; sourceTree = "<group>"; };
+ A2BFA06D1395FF62006ADC12 /* TileMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TileMap.h; sourceTree = "<group>"; };
+ A2BFA06E1395FF62006ADC12 /* TileMapMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TileMapMgr.cpp; sourceTree = "<group>"; };
+ A2BFA06F1395FF62006ADC12 /* TileMapMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TileMapMgr.h; sourceTree = "<group>"; };
+ A2BFA0701395FF62006ADC12 /* TileOverlay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TileOverlay.cpp; sourceTree = "<group>"; };
+ A2BFA0711395FF62006ADC12 /* TileOverlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TileOverlay.h; sourceTree = "<group>"; };
+ A2BFA0721395FF62006ADC12 /* TileSetMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TileSetMgr.cpp; sourceTree = "<group>"; };
+ A2BFA0731395FF62006ADC12 /* TileSetMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TileSetMgr.h; sourceTree = "<group>"; };
+ A2BFA0741395FF62006ADC12 /* TypeID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeID.h; sourceTree = "<group>"; };
+ A2BFA0751395FF62006ADC12 /* Variables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Variables.cpp; sourceTree = "<group>"; };
+ A2BFA0761395FF62006ADC12 /* Variables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Variables.h; sourceTree = "<group>"; };
+ A2BFA0771395FF62006ADC12 /* Video.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Video.cpp; sourceTree = "<group>"; };
+ A2BFA0781395FF62006ADC12 /* Video.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Video.h; sourceTree = "<group>"; };
+ A2BFA0791395FF62006ADC12 /* VideoMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoMode.h; sourceTree = "<group>"; };
+ A2BFA07A1395FF62006ADC12 /* WindowMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WindowMgr.cpp; sourceTree = "<group>"; };
+ A2BFA07B1395FF62006ADC12 /* WindowMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WindowMgr.h; sourceTree = "<group>"; };
+ A2BFA07C1395FF62006ADC12 /* WorldMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorldMap.cpp; sourceTree = "<group>"; };
+ A2BFA07D1395FF62006ADC12 /* WorldMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorldMap.h; sourceTree = "<group>"; };
+ A2BFA07E1395FF62006ADC12 /* WorldMapMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorldMapMgr.cpp; sourceTree = "<group>"; };
+ A2BFA07F1395FF62006ADC12 /* WorldMapMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorldMapMgr.h; sourceTree = "<group>"; };
+ A2C66D9C13A2953D00C0AA8E /* Python.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Python.framework; path = System/Library/Frameworks/Python.framework; sourceTree = SDKROOT; };
+ A2D4C51E13A978110086BCC4 /* defsounds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = defsounds.h; sourceTree = "<group>"; };
+ A2D4C51F13A978110086BCC4 /* errors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = errors.h; sourceTree = "<group>"; };
+ A2D4C52013A978110086BCC4 /* exports.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = exports.h; sourceTree = "<group>"; };
+ A2D4C52113A978110086BCC4 /* globals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = globals.h; sourceTree = "<group>"; };
+ A2D4C52213A978110086BCC4 /* HashMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HashMap.h; sourceTree = "<group>"; };
+ A2D4C52313A978110086BCC4 /* ie_feats.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ie_feats.h; sourceTree = "<group>"; };
+ A2D4C52413A978110086BCC4 /* ie_stats.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ie_stats.h; sourceTree = "<group>"; };
+ A2D4C52513A978110086BCC4 /* ie_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ie_types.h; sourceTree = "<group>"; };
+ A2D4C52613A978110086BCC4 /* iless.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iless.h; sourceTree = "<group>"; };
+ A2D4C52813A978110086BCC4 /* opcode_params.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opcode_params.h; sourceTree = "<group>"; };
+ A2D4C52913A978110086BCC4 /* operatorbool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = operatorbool.h; sourceTree = "<group>"; };
+ A2D4C52A13A978110086BCC4 /* overlays.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = overlays.h; sourceTree = "<group>"; };
+ A2D4C52B13A978110086BCC4 /* plugindef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = plugindef.h; sourceTree = "<group>"; };
+ A2D4C52C13A978110086BCC4 /* RGBAColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RGBAColor.h; sourceTree = "<group>"; };
+ A2D4C52D13A978110086BCC4 /* SClassID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SClassID.h; sourceTree = "<group>"; };
+ A2D4C52E13A978110086BCC4 /* StringMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringMap.h; sourceTree = "<group>"; };
+ A2D4C52F13A978110086BCC4 /* strrefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = strrefs.h; sourceTree = "<group>"; };
+ A2D4C53013A978110086BCC4 /* win32def.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = win32def.h; sourceTree = "<group>"; };
+ A2E57ADC1475EB45005C0A29 /* GEM_ConfController-ipad.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = "GEM_ConfController-ipad.xib"; path = "../gemrb/CocoaWrapper/ios/GEM_ConfController-ipad.xib"; sourceTree = "<group>"; };
+ A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libgemrb_core.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
+ A2E6647B139E8FAB00310FC8 /* core.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = core.pch; sourceTree = SOURCE_ROOT; };
+ A2EC8058145F9E6E0033754A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
+ A2EC805A1460556B0033754A /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/OpenAL.framework; sourceTree = DEVELOPER_DIR; };
+ A2EC805C1460559C0033754A /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/CoreAudio.framework; sourceTree = DEVELOPER_DIR; };
+ A2EC805E146055D80033754A /* GLKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/GLKit.framework; sourceTree = DEVELOPER_DIR; };
+ A2EC805F146055D80033754A /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/OpenGLES.framework; sourceTree = DEVELOPER_DIR; };
+ A2EC8062146056490033754A /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; };
+ A2EC8064146056900033754A /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/AudioToolbox.framework; sourceTree = DEVELOPER_DIR; };
+ A2EC8066146056B40033754A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; };
+ A2F0505113ABB80B0023B7EB /* SAVImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = SAVImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A2FCD5FB13A0366100271997 /* ACMReader.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = ACMReader.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A2FE553A13982BA6006AB962 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = SOURCE_ROOT; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 8D11072E0486CEB800E47090 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2E66486139E907000310FC8 /* libgemrb_core.dylib in Frameworks */,
+ 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A2462F0F13A036B1002D1F02 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A29BF85613A0420F00C812DD /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A2690312142BEE2F003E8BCC /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A259F3F7142BFBCD00D49124 /* SDL.framework in Frameworks */,
+ A259F3F8142BFBCD00D49124 /* SDL_ttf.framework in Frameworks */,
+ A2690313142BEE2F003E8BCC /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3C813A2867900D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B52513A28CC900D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3CF13A286A800D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B52613A28CD300D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3D513A286BC00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B52713A28CD800D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3DB13A286CD00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B52813A28CDD00D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3E113A286DE00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B52913A28CE000D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3E713A286EC00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B52A13A28CE400D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3ED13A286FB00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B52B13A28CEA00D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3F313A2871300D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B52C13A28CF000D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3F913A2872500D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B52D13A28CF400D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3FF13A2873700D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B52E13A28CF700D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B40513A2874700D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B52F13A28CFA00D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B40B13A2875400D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53013A28D0000D41A8A /* libgemrb_core.dylib in Frameworks */,
+ A2C66D9D13A2953D00C0AA8E /* Python.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B41113A2876300D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53113A28D0600D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B41713A2877100D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53213A28D0900D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B41D13A2878400D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53313A28D0C00D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B42313A2879900D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53413A28D0F00D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B42913A287AB00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53513A28D1200D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B42F13A287BC00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53613A28D1500D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B44713A289E000D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53713A28D1800D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B44D13A28A0000D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53813A28D1B00D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B45313A28A0E00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53913A28D1F00D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B45913A28A1C00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53A13A28D2300D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B45F13A28A3100D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53B13A28D2500D41A8A /* libgemrb_core.dylib in Frameworks */,
+ A2C66DBC13A2961700C0AA8E /* SDL.framework in Frameworks */,
+ A2C66DB513A295DC00C0AA8E /* OpenAL.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B46513A28A3F00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53C13A28D2800D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B46B13A28A5000D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53D13A28D2A00D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B47113A28A5D00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53E13A28D2D00D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B47713A28A7600D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53F13A28D3000D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B47D13A28A8500D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2C66D6F13A2950300C0AA8E /* SDL.framework in Frameworks */,
+ A276B54013A28D3500D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B48313A28A9000D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2491881141092F20038B170 /* Cocoa.framework in Frameworks */,
+ A2C66D9913A2950700C0AA8E /* SDL.framework in Frameworks */,
+ A276B54113A28D3D00D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B48913A28A9E00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B54213A28D4000D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B48F13A28AA800D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B54413A28D4600D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B49513A28AB800D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B54513A28D4900D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B49B13A28AC800D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B54613A28D4C00D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B4A113A28AD300D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B54713A28D5500D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B4A713A28AE100D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B54813A28D5900D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B4AD13A28AEE00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B54913A28D5D00D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B4F213A28C0400D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B54313A28D4300D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A27E830813A0358200B41410 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A29BF85213A0420300C812DD /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A29BF7B013A0380F00C812DD /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A29BF85713A0421200C812DD /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A29BF85A13A0427900C812DD /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2EC8067146056B40033754A /* CoreGraphics.framework in Frameworks */,
+ A2EC8065146056900033754A /* AudioToolbox.framework in Frameworks */,
+ A2EC8063146056490033754A /* QuartzCore.framework in Frameworks */,
+ A2EC8061146055D80033754A /* OpenGLES.framework in Frameworks */,
+ A2EC805D1460559C0033754A /* CoreAudio.framework in Frameworks */,
+ A2EC805B1460556B0033754A /* OpenAL.framework in Frameworks */,
+ A2EC8059145F9E6E0033754A /* Foundation.framework in Frameworks */,
+ A239390B145F8677007895B3 /* UIKit.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A2E66336139E875400310FC8 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A2F0504F13ABB80B0023B7EB /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2F0505B13ABB84C0023B7EB /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A2FCD5F913A0366100271997 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A29BF85513A0420A00C812DD /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 080E96DDFE201D6D7F000001 /* Classes */ = {
+ isa = PBXGroup;
+ children = (
+ );
+ name = Classes;
+ sourceTree = "<group>";
+ };
+ 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ A2BD83111396FD5F007E9C63 /* Python.framework */,
+ A2BD831D1396FE16007E9C63 /* OpenAL.framework */,
+ 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
+ );
+ name = "Linked Frameworks";
+ sourceTree = "<group>";
+ };
+ 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 29B97324FDCFA39411CA2CEA /* AppKit.framework */,
+ 29B97325FDCFA39411CA2CEA /* Foundation.framework */,
+ );
+ name = "Other Frameworks";
+ sourceTree = "<group>";
+ };
+ 19C28FACFE9D520D11CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 8D1107320486CEB800E47090 /* GemRB.app */,
+ A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */,
+ A27E830A13A0358200B41410 /* 2DAImporter.so */,
+ A2FCD5FB13A0366100271997 /* ACMReader.so */,
+ A2462F1113A036B1002D1F02 /* AREImporter.so */,
+ A29BF7B213A0380F00C812DD /* BAMImporter.so */,
+ A29BF85C13A0427900C812DD /* GemRB.app */,
+ A276B3CA13A2867900D41A8A /* BIFImporter.so */,
+ A276B3D113A286A800D41A8A /* BIKPlayer.so */,
+ A276B3D713A286BC00D41A8A /* BMPImporter.so */,
+ A276B3DD13A286CD00D41A8A /* BMPWriter.so */,
+ A276B3E313A286DE00D41A8A /* CHUImporter.so */,
+ A276B3E913A286EC00D41A8A /* CREImporter.so */,
+ A276B3EF13A286FB00D41A8A /* DirectoryImporter.so */,
+ A276B3F513A2871300D41A8A /* DLGImporter.so */,
+ A276B3FB13A2872500D41A8A /* EFFImporter.so */,
+ A276B40113A2873700D41A8A /* FXOpcodes.so */,
+ A276B40713A2874700D41A8A /* GAMImporter.so */,
+ A276B40D13A2875400D41A8A /* GUIScript.so */,
+ A276B41313A2876300D41A8A /* IDSImporter.so */,
+ A276B41913A2877100D41A8A /* INIImporter.so */,
+ A276B41F13A2878400D41A8A /* ITMImporter.so */,
+ A276B42513A2879900D41A8A /* IWDOpcodes.so */,
+ A276B42B13A287AB00D41A8A /* KEYImporter.so */,
+ A276B43113A287BD00D41A8A /* MOSImporter.so */,
+ A276B44913A289E000D41A8A /* MUSImporter.so */,
+ A276B44F13A28A0000D41A8A /* MVEPlayer.so */,
+ A276B45513A28A0E00D41A8A /* NullSound.so */,
+ A276B45B13A28A1C00D41A8A /* OGGReader.so */,
+ A276B46113A28A3100D41A8A /* OpenALAudio.so */,
+ A276B46713A28A3F00D41A8A /* PLTImporter.so */,
+ A276B46D13A28A5000D41A8A /* PNGImporter.so */,
+ A276B47313A28A5D00D41A8A /* PROImporter.so */,
+ A276B47913A28A7600D41A8A /* PSTOpcodes.so */,
+ A276B47F13A28A8500D41A8A /* SDLAudio.so */,
+ A276B48513A28A9000D41A8A /* SDLVideo.so */,
+ A276B48B13A28A9E00D41A8A /* SPLImporter.so */,
+ A276B49113A28AA900D41A8A /* TISImporter.so */,
+ A276B49713A28AB800D41A8A /* TLKImporter.so */,
+ A276B49D13A28AC800D41A8A /* WAVReader.so */,
+ A276B4A313A28AD300D41A8A /* WEDImporter.so */,
+ A276B4A913A28AE100D41A8A /* WMPImporter.so */,
+ A276B4AF13A28AEE00D41A8A /* ZLibManager.so */,
+ A276B4F413A28C0400D41A8A /* STOImporter.so */,
+ A2F0505113ABB80B0023B7EB /* SAVImporter.so */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 29B97314FDCFA39411CA2CEA /* GemRB_OSX */ = {
+ isa = PBXGroup;
+ children = (
+ A2E7985C14845B3F00B15DF4 /* Cocoa Wrappers */,
+ A2D4C51D13A978110086BCC4 /* includes */,
+ A27B8697139F0A7D0002DC13 /* plugins */,
+ A2BF9F8C1395FF61006ADC12 /* core */,
+ A2BD81A213960965007E9C63 /* includes */,
+ 080E96DDFE201D6D7F000001 /* Classes */,
+ 29B97315FDCFA39411CA2CEA /* Other Sources */,
+ 29B97317FDCFA39411CA2CEA /* Resources */,
+ A29BF91C13A04B3900C812DD /* Resources-iOS */,
+ 29B97323FDCFA39411CA2CEA /* Frameworks */,
+ A2E7985B14845AFB00B15DF4 /* iOS static libs */,
+ 19C28FACFE9D520D11CA2CBB /* Products */,
+ );
+ name = GemRB_OSX;
+ sourceTree = "<group>";
+ };
+ 29B97315FDCFA39411CA2CEA /* Other Sources */ = {
+ isa = PBXGroup;
+ children = (
+ A2A6A44E14687CC2000F1688 /* ios */,
+ A22693781422931B004468E8 /* CocoaWrapper.h */,
+ A2BD82721396B886007E9C63 /* GemRB.cpp */,
+ A2A6A454146880C1000F1688 /* CocoaWrapper.m */,
+ 32CA4F630368D1EE00C91783 /* GemRB_Prefix.pch */,
+ );
+ name = "Other Sources";
+ sourceTree = "<group>";
+ };
+ 29B97317FDCFA39411CA2CEA /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 8D1107310486CEB800E47090 /* Info.plist */,
+ 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ };
+ 29B97323FDCFA39411CA2CEA /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ A2EC8066146056B40033754A /* CoreGraphics.framework */,
+ A2EC8064146056900033754A /* AudioToolbox.framework */,
+ A2EC8062146056490033754A /* QuartzCore.framework */,
+ A2EC805E146055D80033754A /* GLKit.framework */,
+ A2EC805F146055D80033754A /* OpenGLES.framework */,
+ A2EC805C1460559C0033754A /* CoreAudio.framework */,
+ A2EC805A1460556B0033754A /* OpenAL.framework */,
+ A2EC8058145F9E6E0033754A /* Foundation.framework */,
+ A239390A145F8677007895B3 /* UIKit.framework */,
+ A259F3F5142BFBCD00D49124 /* SDL.framework */,
+ A259F3F6142BFBCD00D49124 /* SDL_ttf.framework */,
+ A208210A14191A03002CD244 /* SDL.framework */,
+ A2491880141092F20038B170 /* Cocoa.framework */,
+ A29BF7FC13A039DD00C812DD /* SDL.framework */,
+ A2830A0F13A05A64000A63FE /* OpenAL.framework */,
+ A2830A3913A05B5F000A63FE /* CoreAudio.framework */,
+ A2830A3F13A05B81000A63FE /* QuartzCore.framework */,
+ A2AAF36713A1507100AE8402 /* CoreAudio.framework */,
+ A2AAF38D13A150D700AE8402 /* AudioToolbox.framework */,
+ A2AAF39313A150F900AE8402 /* AudioToolbox.framework */,
+ A2C66D9C13A2953D00C0AA8E /* Python.framework */,
+ 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
+ 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ A27979A913ABA4F7009A6FEF /* SAVImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27979AC13ABA4F7009A6FEF /* SAVImporter.cpp */,
+ A27979AD13ABA4F7009A6FEF /* SAVImporter.h */,
+ );
+ path = SAVImporter;
+ sourceTree = "<group>";
+ };
+ A27B8697139F0A7D0002DC13 /* plugins */ = {
+ isa = PBXGroup;
+ children = (
+ A2A6A457146893CC000F1688 /* TTFImporter */,
+ A27979A913ABA4F7009A6FEF /* SAVImporter */,
+ A27B8698139F0A7D0002DC13 /* 2DAImporter */,
+ A27B869D139F0A7D0002DC13 /* ACMReader */,
+ A27B86A7139F0A7D0002DC13 /* AREImporter */,
+ A27B86AC139F0A7D0002DC13 /* BAMImporter */,
+ A27B86B1139F0A7D0002DC13 /* BIFImporter */,
+ A27B86B6139F0A7D0002DC13 /* BIKPlayer */,
+ A27B86C6139F0A7D0002DC13 /* BMPImporter */,
+ A27B86CB139F0A7D0002DC13 /* BMPWriter */,
+ A27B86D0139F0A7D0002DC13 /* CHUImporter */,
+ A27B86D6139F0A7D0002DC13 /* CREImporter */,
+ A27B86DB139F0A7D0002DC13 /* DirectoryImporter */,
+ A27B86E0139F0A7D0002DC13 /* DLGImporter */,
+ A27B86E5139F0A7D0002DC13 /* EFFImporter */,
+ A27B86EA139F0A7D0002DC13 /* FXOpcodes */,
+ A27B86EE139F0A7D0002DC13 /* GAMImporter */,
+ A27B86F3139F0A7D0002DC13 /* GUIScript */,
+ A27B86FA139F0A7D0002DC13 /* IDSImporter */,
+ A27B8700139F0A7D0002DC13 /* INIImporter */,
+ A27B8705139F0A7D0002DC13 /* ITMImporter */,
+ A27B870A139F0A7D0002DC13 /* IWDOpcodes */,
+ A27B870E139F0A7D0002DC13 /* KEYImporter */,
+ A27B8716139F0A7D0002DC13 /* MOSImporter */,
+ A27B871B139F0A7D0002DC13 /* MUSImporter */,
+ A27B8720139F0A7D0002DC13 /* MVEPlayer */,
+ A27B872C139F0A7D0002DC13 /* NullSound */,
+ A27B8731139F0A7D0002DC13 /* OGGReader */,
+ A27B8736139F0A7D0002DC13 /* OpenALAudio */,
+ A27B873F139F0A7D0002DC13 /* PLTImporter */,
+ A27B8744139F0A7D0002DC13 /* PNGImporter */,
+ A27B8749139F0A7D0002DC13 /* PROImporter */,
+ A27B874E139F0A7D0002DC13 /* PSTOpcodes */,
+ A27B8752139F0A7D0002DC13 /* SDLAudio */,
+ A27B8757139F0A7D0002DC13 /* SDLVideo */,
+ A27B875E139F0A7D0002DC13 /* SPLImporter */,
+ A27B8763139F0A7D0002DC13 /* STOImporter */,
+ A27B8768139F0A7D0002DC13 /* TISImporter */,
+ A27B876D139F0A7D0002DC13 /* TLKImporter */,
+ A27B8774139F0A7D0002DC13 /* WAVReader */,
+ A27B8779139F0A7D0002DC13 /* WEDImporter */,
+ A27B877E139F0A7D0002DC13 /* WMPImporter */,
+ A27B8783139F0A7D0002DC13 /* ZLibManager */,
+ );
+ name = plugins;
+ path = ../gemrb/plugins;
+ sourceTree = SOURCE_ROOT;
+ };
+ A27B8698139F0A7D0002DC13 /* 2DAImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8699139F0A7D0002DC13 /* 2DAImporter.cpp */,
+ A27B869A139F0A7D0002DC13 /* 2DAImporter.h */,
+ );
+ path = 2DAImporter;
+ sourceTree = "<group>";
+ };
+ A27B869D139F0A7D0002DC13 /* ACMReader */ = {
+ isa = PBXGroup;
+ children = (
+ A27B869E139F0A7D0002DC13 /* ACMReader.cpp */,
+ A27B869F139F0A7D0002DC13 /* ACMReader.h */,
+ A27B86A1139F0A7D0002DC13 /* decoder.cpp */,
+ A27B86A2139F0A7D0002DC13 /* decoder.h */,
+ A27B86A3139F0A7D0002DC13 /* general.h */,
+ A27B86A5139F0A7D0002DC13 /* unpacker.cpp */,
+ A27B86A6139F0A7D0002DC13 /* unpacker.h */,
+ );
+ path = ACMReader;
+ sourceTree = "<group>";
+ };
+ A27B86A7139F0A7D0002DC13 /* AREImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86A8139F0A7D0002DC13 /* AREImporter.cpp */,
+ A27B86A9139F0A7D0002DC13 /* AREImporter.h */,
+ );
+ path = AREImporter;
+ sourceTree = "<group>";
+ };
+ A27B86AC139F0A7D0002DC13 /* BAMImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86AD139F0A7D0002DC13 /* BAMImporter.cpp */,
+ A27B86AE139F0A7D0002DC13 /* BAMImporter.h */,
+ A28D24A0143C24C100A27897 /* BAMFontManager.cpp */,
+ A28D24A3143C24E500A27897 /* BAMFontManager.h */,
+ );
+ path = BAMImporter;
+ sourceTree = "<group>";
+ };
+ A27B86B1139F0A7D0002DC13 /* BIFImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86B2139F0A7D0002DC13 /* BIFImporter.cpp */,
+ A27B86B3139F0A7D0002DC13 /* BIFImporter.h */,
+ );
+ path = BIFImporter;
+ sourceTree = "<group>";
+ };
+ A27B86B6139F0A7D0002DC13 /* BIKPlayer */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86B7139F0A7D0002DC13 /* BIKPlayer.cpp */,
+ A27B86B8139F0A7D0002DC13 /* BIKPlayer.h */,
+ A27B86B9139F0A7D0002DC13 /* binkdata.h */,
+ A27B86BB139F0A7D0002DC13 /* common.h */,
+ A27B86BC139F0A7D0002DC13 /* dct.cpp */,
+ A27B86BD139F0A7D0002DC13 /* dsputil.h */,
+ A27B86BE139F0A7D0002DC13 /* fft.cpp */,
+ A27B86BF139F0A7D0002DC13 /* GetBitContext.cpp */,
+ A27B86C0139F0A7D0002DC13 /* GetBitContext.h */,
+ A27B86C2139F0A7D0002DC13 /* mem.cpp */,
+ A27B86C3139F0A7D0002DC13 /* rational.cpp */,
+ A27B86C4139F0A7D0002DC13 /* rational.h */,
+ A27B86C5139F0A7D0002DC13 /* rdft.cpp */,
+ );
+ path = BIKPlayer;
+ sourceTree = "<group>";
+ };
+ A27B86C6139F0A7D0002DC13 /* BMPImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86C7139F0A7D0002DC13 /* BMPImporter.cpp */,
+ A27B86C8139F0A7D0002DC13 /* BMPImporter.h */,
+ );
+ path = BMPImporter;
+ sourceTree = "<group>";
+ };
+ A27B86CB139F0A7D0002DC13 /* BMPWriter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86CC139F0A7D0002DC13 /* BMPWriter.cpp */,
+ A27B86CD139F0A7D0002DC13 /* BMPWriter.h */,
+ );
+ path = BMPWriter;
+ sourceTree = "<group>";
+ };
+ A27B86D0139F0A7D0002DC13 /* CHUImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86D1139F0A7D0002DC13 /* CHUImporter.cpp */,
+ A27B86D2139F0A7D0002DC13 /* CHUImporter.h */,
+ );
+ path = CHUImporter;
+ sourceTree = "<group>";
+ };
+ A27B86D6139F0A7D0002DC13 /* CREImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86D8139F0A7D0002DC13 /* CREImporter.cpp */,
+ A27B86D9139F0A7D0002DC13 /* CREImporter.h */,
+ );
+ path = CREImporter;
+ sourceTree = "<group>";
+ };
+ A27B86DB139F0A7D0002DC13 /* DirectoryImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86DD139F0A7D0002DC13 /* DirectoryImporter.cpp */,
+ A27B86DE139F0A7D0002DC13 /* DirectoryImporter.h */,
+ );
+ path = DirectoryImporter;
+ sourceTree = "<group>";
+ };
+ A27B86E0139F0A7D0002DC13 /* DLGImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86E2139F0A7D0002DC13 /* DLGImporter.cpp */,
+ A27B86E3139F0A7D0002DC13 /* DLGImporter.h */,
+ );
+ path = DLGImporter;
+ sourceTree = "<group>";
+ };
+ A27B86E5139F0A7D0002DC13 /* EFFImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86E7139F0A7D0002DC13 /* EFFImporter.cpp */,
+ A27B86E8139F0A7D0002DC13 /* EFFImporter.h */,
+ );
+ path = EFFImporter;
+ sourceTree = "<group>";
+ };
+ A27B86EA139F0A7D0002DC13 /* FXOpcodes */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86EC139F0A7D0002DC13 /* FXOpcodes.cpp */,
+ );
+ path = FXOpcodes;
+ sourceTree = "<group>";
+ };
+ A27B86EE139F0A7D0002DC13 /* GAMImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86F0139F0A7D0002DC13 /* GAMImporter.cpp */,
+ A27B86F1139F0A7D0002DC13 /* GAMImporter.h */,
+ );
+ path = GAMImporter;
+ sourceTree = "<group>";
+ };
+ A27B86F3139F0A7D0002DC13 /* GUIScript */ = {
+ isa = PBXGroup;
+ children = (
+ A27A81C2145F12CD00883469 /* CocoaWrapper.m */,
+ A27B86F5139F0A7D0002DC13 /* GUIScript.cpp */,
+ A27B86F6139F0A7D0002DC13 /* GUIScript.h */,
+ A27B86F8139F0A7D0002DC13 /* PythonHelpers.cpp */,
+ A27B86F9139F0A7D0002DC13 /* PythonHelpers.h */,
+ );
+ path = GUIScript;
+ sourceTree = "<group>";
+ };
+ A27B86FA139F0A7D0002DC13 /* IDSImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86FC139F0A7D0002DC13 /* IDSImporter.cpp */,
+ A27B86FD139F0A7D0002DC13 /* IDSImporter.h */,
+ A27B86FE139F0A7D0002DC13 /* IDSImporterDefs.h */,
+ );
+ path = IDSImporter;
+ sourceTree = "<group>";
+ };
+ A27B8700139F0A7D0002DC13 /* INIImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8702139F0A7D0002DC13 /* INIImporter.cpp */,
+ A27B8703139F0A7D0002DC13 /* INIImporter.h */,
+ );
+ path = INIImporter;
+ sourceTree = "<group>";
+ };
+ A27B8705139F0A7D0002DC13 /* ITMImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8707139F0A7D0002DC13 /* ITMImporter.cpp */,
+ A27B8708139F0A7D0002DC13 /* ITMImporter.h */,
+ );
+ path = ITMImporter;
+ sourceTree = "<group>";
+ };
+ A27B870A139F0A7D0002DC13 /* IWDOpcodes */ = {
+ isa = PBXGroup;
+ children = (
+ A27B870C139F0A7D0002DC13 /* IWDOpcodes.cpp */,
+ );
+ path = IWDOpcodes;
+ sourceTree = "<group>";
+ };
+ A27B870E139F0A7D0002DC13 /* KEYImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8710139F0A7D0002DC13 /* Dictionary.cpp */,
+ A27B8711139F0A7D0002DC13 /* Dictionary.h */,
+ A27B8712139F0A7D0002DC13 /* KEYImporter.cpp */,
+ A27B8713139F0A7D0002DC13 /* KEYImporter.h */,
+ );
+ path = KEYImporter;
+ sourceTree = "<group>";
+ };
+ A27B8716139F0A7D0002DC13 /* MOSImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8719139F0A7D0002DC13 /* MOSImporter.cpp */,
+ A27B871A139F0A7D0002DC13 /* MOSImporter.h */,
+ );
+ path = MOSImporter;
+ sourceTree = "<group>";
+ };
+ A27B871B139F0A7D0002DC13 /* MUSImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B871E139F0A7D0002DC13 /* MUSImporter.cpp */,
+ A27B871F139F0A7D0002DC13 /* MUSImporter.h */,
+ );
+ path = MUSImporter;
+ sourceTree = "<group>";
+ };
+ A27B8720139F0A7D0002DC13 /* MVEPlayer */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8722139F0A7D0002DC13 /* gstmvedemux.h */,
+ A27B8724139F0A7D0002DC13 /* mve.h */,
+ A27B8725139F0A7D0002DC13 /* mve_player.cpp */,
+ A27B8726139F0A7D0002DC13 /* mve_player.h */,
+ A27B8727139F0A7D0002DC13 /* mveaudiodec.cpp */,
+ A27B8728139F0A7D0002DC13 /* MVEPlayer.cpp */,
+ A27B8729139F0A7D0002DC13 /* MVEPlayer.h */,
+ A27B872A139F0A7D0002DC13 /* mvevideodec16.cpp */,
+ A27B872B139F0A7D0002DC13 /* mvevideodec8.cpp */,
+ );
+ path = MVEPlayer;
+ sourceTree = "<group>";
+ };
+ A27B872C139F0A7D0002DC13 /* NullSound */ = {
+ isa = PBXGroup;
+ children = (
+ A27B872F139F0A7D0002DC13 /* NullSound.cpp */,
+ A27B8730139F0A7D0002DC13 /* NullSound.h */,
+ );
+ path = NullSound;
+ sourceTree = "<group>";
+ };
+ A27B8731139F0A7D0002DC13 /* OGGReader */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8734139F0A7D0002DC13 /* OGGReader.cpp */,
+ A27B8735139F0A7D0002DC13 /* OGGReader.h */,
+ );
+ path = OGGReader;
+ sourceTree = "<group>";
+ };
+ A27B8736139F0A7D0002DC13 /* OpenALAudio */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8737139F0A7D0002DC13 /* AmbientMgrAL.cpp */,
+ A27B8738139F0A7D0002DC13 /* AmbientMgrAL.h */,
+ A27B873B139F0A7D0002DC13 /* OpenALAudio.cpp */,
+ A27B873C139F0A7D0002DC13 /* OpenALAudio.h */,
+ A27B873D139F0A7D0002DC13 /* StackLock.cpp */,
+ A27B873E139F0A7D0002DC13 /* StackLock.h */,
+ );
+ path = OpenALAudio;
+ sourceTree = "<group>";
+ };
+ A27B873F139F0A7D0002DC13 /* PLTImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8742139F0A7D0002DC13 /* PLTImporter.cpp */,
+ A27B8743139F0A7D0002DC13 /* PLTImporter.h */,
+ );
+ path = PLTImporter;
+ sourceTree = "<group>";
+ };
+ A27B8744139F0A7D0002DC13 /* PNGImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8747139F0A7D0002DC13 /* PNGImporter.cpp */,
+ A27B8748139F0A7D0002DC13 /* PNGImporter.h */,
+ );
+ path = PNGImporter;
+ sourceTree = "<group>";
+ };
+ A27B8749139F0A7D0002DC13 /* PROImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B874C139F0A7D0002DC13 /* PROImporter.cpp */,
+ A27B874D139F0A7D0002DC13 /* PROImporter.h */,
+ );
+ path = PROImporter;
+ sourceTree = "<group>";
+ };
+ A27B874E139F0A7D0002DC13 /* PSTOpcodes */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8751139F0A7D0002DC13 /* PSTOpcodes.cpp */,
+ );
+ path = PSTOpcodes;
+ sourceTree = "<group>";
+ };
+ A27B8752139F0A7D0002DC13 /* SDLAudio */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8755139F0A7D0002DC13 /* SDLAudio.cpp */,
+ A27B8756139F0A7D0002DC13 /* SDLAudio.h */,
+ );
+ path = SDLAudio;
+ sourceTree = "<group>";
+ };
+ A27B8757139F0A7D0002DC13 /* SDLVideo */ = {
+ isa = PBXGroup;
+ children = (
+ A249187B141075A60038B170 /* CocoaWrapper.m */,
+ A27B875A139F0A7D0002DC13 /* SDLVideo.cpp */,
+ A27B875B139F0A7D0002DC13 /* SDLVideo.h */,
+ );
+ path = SDLVideo;
+ sourceTree = "<group>";
+ };
+ A27B875E139F0A7D0002DC13 /* SPLImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8761139F0A7D0002DC13 /* SPLImporter.cpp */,
+ A27B8762139F0A7D0002DC13 /* SPLImporter.h */,
+ );
+ path = SPLImporter;
+ sourceTree = "<group>";
+ };
+ A27B8763139F0A7D0002DC13 /* STOImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8766139F0A7D0002DC13 /* STOImporter.cpp */,
+ A27B8767139F0A7D0002DC13 /* STOImporter.h */,
+ );
+ path = STOImporter;
+ sourceTree = "<group>";
+ };
+ A27B8768139F0A7D0002DC13 /* TISImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B876B139F0A7D0002DC13 /* TISImporter.cpp */,
+ A27B876C139F0A7D0002DC13 /* TISImporter.h */,
+ );
+ path = TISImporter;
+ sourceTree = "<group>";
+ };
+ A27B876D139F0A7D0002DC13 /* TLKImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8770139F0A7D0002DC13 /* TLKImporter.cpp */,
+ A27B8771139F0A7D0002DC13 /* TLKImporter.h */,
+ A27B8772139F0A7D0002DC13 /* TlkOverride.cpp */,
+ A27B8773139F0A7D0002DC13 /* TlkOverride.h */,
+ );
+ path = TLKImporter;
+ sourceTree = "<group>";
+ };
+ A27B8774139F0A7D0002DC13 /* WAVReader */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8777139F0A7D0002DC13 /* WAVReader.cpp */,
+ A27B8778139F0A7D0002DC13 /* WAVReader.h */,
+ );
+ path = WAVReader;
+ sourceTree = "<group>";
+ };
+ A27B8779139F0A7D0002DC13 /* WEDImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B877C139F0A7D0002DC13 /* WEDImporter.cpp */,
+ A27B877D139F0A7D0002DC13 /* WEDImporter.h */,
+ );
+ path = WEDImporter;
+ sourceTree = "<group>";
+ };
+ A27B877E139F0A7D0002DC13 /* WMPImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8781139F0A7D0002DC13 /* WMPImporter.cpp */,
+ A27B8782139F0A7D0002DC13 /* WMPImporter.h */,
+ );
+ path = WMPImporter;
+ sourceTree = "<group>";
+ };
+ A27B8783139F0A7D0002DC13 /* ZLibManager */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8786139F0A7D0002DC13 /* ZLibManager.cpp */,
+ A27B8787139F0A7D0002DC13 /* ZLibManager.h */,
+ );
+ path = ZLibManager;
+ sourceTree = "<group>";
+ };
+ A29BF91C13A04B3900C812DD /* Resources-iOS */ = {
+ isa = PBXGroup;
+ children = (
+ A2830ABA13A0624D000A63FE /* Info.plist */,
+ );
+ name = "Resources-iOS";
+ sourceTree = "<group>";
+ };
+ A2A6A44E14687CC2000F1688 /* ios */ = {
+ isa = PBXGroup;
+ children = (
+ A2E57ADC1475EB45005C0A29 /* GEM_ConfController-ipad.xib */,
+ A2A6A44F14687E55000F1688 /* GEM_ConfController.h */,
+ A2A6A45014687E55000F1688 /* GEM_ConfController.m */,
+ A2A6A45114687E55000F1688 /* GEM_ConfController-iphone.xib */,
+ );
+ name = ios;
+ sourceTree = "<group>";
+ };
+ A2A6A457146893CC000F1688 /* TTFImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A2A6A459146893CC000F1688 /* TTFFontManager.cpp */,
+ A2A6A45A146893CC000F1688 /* TTFFontManager.h */,
+ );
+ path = TTFImporter;
+ sourceTree = "<group>";
+ };
+ A2BD81A213960965007E9C63 /* includes */ = {
+ isa = PBXGroup;
+ children = (
+ A2BD83F4139713A8007E9C63 /* win32def.h */,
+ A2BD81A313960965007E9C63 /* defsounds.h */,
+ A2BD81A413960965007E9C63 /* errors.h */,
+ A2BD81A513960965007E9C63 /* exports.h */,
+ A2BD81A613960965007E9C63 /* globals.h */,
+ A2BD81A713960965007E9C63 /* ie_feats.h */,
+ A2BD81A813960965007E9C63 /* ie_stats.h */,
+ A2BD81A913960965007E9C63 /* ie_types.h */,
+ A2BD81AA13960965007E9C63 /* iless.h */,
+ A2BD81AB13960965007E9C63 /* logging.h */,
+ A2BD81AD13960965007E9C63 /* opcode_params.h */,
+ A2BD81AE13960965007E9C63 /* operatorbool.h */,
+ A2BD81AF13960965007E9C63 /* overlays.h */,
+ A2BD81B013960965007E9C63 /* plugindef.h */,
+ A2BD81B113960965007E9C63 /* RGBAColor.h */,
+ A2BD81B213960965007E9C63 /* SClassID.h */,
+ A2BD81B313960965007E9C63 /* strrefs.h */,
+ );
+ name = includes;
+ path = ../gemrb/includes;
+ sourceTree = SOURCE_ROOT;
+ };
+ A2BF9F8C1395FF61006ADC12 /* core */ = {
+ isa = PBXGroup;
+ children = (
+ A27B87B5139F0E120002DC13 /* plugins.pch */,
+ A2BF9F8D1395FF61006ADC12 /* ActorMgr.cpp */,
+ A2BF9F8E1395FF61006ADC12 /* ActorMgr.h */,
+ A2BF9F8F1395FF61006ADC12 /* Ambient.cpp */,
+ A2BF9F901395FF61006ADC12 /* Ambient.h */,
+ A2BF9F911395FF61006ADC12 /* AmbientMgr.cpp */,
+ A2BF9F921395FF61006ADC12 /* AmbientMgr.h */,
+ A2BF9F931395FF61006ADC12 /* Animation.cpp */,
+ A2BF9F941395FF61006ADC12 /* Animation.h */,
+ A2BF9F951395FF61006ADC12 /* AnimationFactory.cpp */,
+ A2BF9F961395FF61006ADC12 /* AnimationFactory.h */,
+ A2BF9F971395FF61006ADC12 /* AnimationMgr.cpp */,
+ A2BF9F981395FF61006ADC12 /* AnimationMgr.h */,
+ A2BF9F991395FF61006ADC12 /* AnimStructures.h */,
+ A2BF9F9A1395FF61006ADC12 /* ArchiveImporter.cpp */,
+ A2BF9F9B1395FF61006ADC12 /* ArchiveImporter.h */,
+ A2BF9F9C1395FF61006ADC12 /* Audio.cpp */,
+ A2BF9F9D1395FF61006ADC12 /* Audio.h */,
+ A2BF9F9E1395FF61006ADC12 /* Bitmap.cpp */,
+ A2BF9F9F1395FF61006ADC12 /* Bitmap.h */,
+ A2BF9FA01395FF61006ADC12 /* Cache.cpp */,
+ A2BF9FA11395FF61006ADC12 /* Cache.h */,
+ A2BF9FA21395FF61006ADC12 /* Calendar.cpp */,
+ A2BF9FA31395FF61006ADC12 /* Calendar.h */,
+ A2BF9FA41395FF61006ADC12 /* Callback.cpp */,
+ A2BF9FA51395FF61006ADC12 /* Callback.h */,
+ A2BF9FA61395FF61006ADC12 /* CharAnimations.cpp */,
+ A2BF9FA71395FF61006ADC12 /* CharAnimations.h */,
+ A2BF9FA91395FF61006ADC12 /* Compressor.cpp */,
+ A2BF9FAA1395FF61006ADC12 /* Compressor.h */,
+ A2BF9FAB1395FF61006ADC12 /* ControlAnimation.cpp */,
+ A2BF9FAC1395FF61006ADC12 /* ControlAnimation.h */,
+ A2BF9FAD1395FF61006ADC12 /* Core.cpp */,
+ A2E6647B139E8FAB00310FC8 /* core.pch */,
+ A2BF9FAE1395FF61006ADC12 /* damages.h */,
+ A2BF9FAF1395FF61006ADC12 /* DataFileMgr.cpp */,
+ A2BF9FB01395FF61006ADC12 /* DataFileMgr.h */,
+ A2BF9FB11395FF61006ADC12 /* Dialog.cpp */,
+ A2BF9FB21395FF61006ADC12 /* Dialog.h */,
+ A2BF9FB31395FF61006ADC12 /* DialogHandler.cpp */,
+ A2BF9FB41395FF61006ADC12 /* DialogHandler.h */,
+ A2BF9FB51395FF61006ADC12 /* DialogMgr.cpp */,
+ A2BF9FB61395FF61006ADC12 /* DialogMgr.h */,
+ A2BF9FB71395FF61006ADC12 /* DisplayMessage.cpp */,
+ A2BF9FB81395FF61006ADC12 /* DisplayMessage.h */,
+ A2BF9FB91395FF61006ADC12 /* Effect.h */,
+ A2BF9FBA1395FF61006ADC12 /* EffectMgr.cpp */,
+ A2BF9FBB1395FF61006ADC12 /* EffectMgr.h */,
+ A2BF9FBC1395FF61006ADC12 /* EffectQueue.cpp */,
+ A2BF9FBD1395FF61006ADC12 /* EffectQueue.h */,
+ A2BF9FBE1395FF61006ADC12 /* Factory.cpp */,
+ A2BF9FBF1395FF61006ADC12 /* Factory.h */,
+ A2BF9FC01395FF61006ADC12 /* FactoryObject.cpp */,
+ A2BF9FC11395FF61006ADC12 /* FactoryObject.h */,
+ A2BF9FC21395FF61006ADC12 /* Font.cpp */,
+ A2BF9FC31395FF61006ADC12 /* Font.h */,
+ A2BF9FC41395FF61006ADC12 /* Game.cpp */,
+ A2BF9FC51395FF62006ADC12 /* Game.h */,
+ A2BF9FC61395FF62006ADC12 /* GameData.cpp */,
+ A2BF9FC71395FF62006ADC12 /* GameData.h */,
+ A2BF9FC81395FF62006ADC12 /* GameScript */,
+ A2BF9FD21395FF62006ADC12 /* GlobalTimer.cpp */,
+ A2BF9FD31395FF62006ADC12 /* GlobalTimer.h */,
+ A2BF9FD41395FF62006ADC12 /* GUI */,
+ A2BF9FF11395FF62006ADC12 /* Holder.h */,
+ A2BF9FF21395FF62006ADC12 /* Image.cpp */,
+ A2BF9FF31395FF62006ADC12 /* Image.h */,
+ A2BF9FF41395FF62006ADC12 /* ImageFactory.cpp */,
+ A2BF9FF51395FF62006ADC12 /* ImageFactory.h */,
+ A2BF9FF61395FF62006ADC12 /* ImageMgr.cpp */,
+ A2BF9FF71395FF62006ADC12 /* ImageMgr.h */,
+ A2BF9FF81395FF62006ADC12 /* ImageWriter.cpp */,
+ A2BF9FF91395FF62006ADC12 /* ImageWriter.h */,
+ A2BF9FFA1395FF62006ADC12 /* IniSpawn.cpp */,
+ A2BF9FFB1395FF62006ADC12 /* IniSpawn.h */,
+ A2BF9FFC1395FF62006ADC12 /* Interface.cpp */,
+ A2BF9FFD1395FF62006ADC12 /* Interface.h */,
+ A2BF9FFE1395FF62006ADC12 /* Inventory.cpp */,
+ A2BF9FFF1395FF62006ADC12 /* Inventory.h */,
+ A2BFA0001395FF62006ADC12 /* Item.cpp */,
+ A2BFA0011395FF62006ADC12 /* Item.h */,
+ A2BFA0021395FF62006ADC12 /* ItemMgr.cpp */,
+ A2BFA0031395FF62006ADC12 /* ItemMgr.h */,
+ A2BFA0041395FF62006ADC12 /* LRUCache.cpp */,
+ A2BFA0051395FF62006ADC12 /* LRUCache.h */,
+ A2BFA0071395FF62006ADC12 /* Map.cpp */,
+ A2BFA0081395FF62006ADC12 /* Map.h */,
+ A2BFA0091395FF62006ADC12 /* MapMgr.cpp */,
+ A2BFA00A1395FF62006ADC12 /* MapMgr.h */,
+ A2BFA00B1395FF62006ADC12 /* MoviePlayer.cpp */,
+ A2BFA00C1395FF62006ADC12 /* MoviePlayer.h */,
+ A2BFA00D1395FF62006ADC12 /* MusicMgr.cpp */,
+ A2BFA00E1395FF62006ADC12 /* MusicMgr.h */,
+ A2BFA00F1395FF62006ADC12 /* Palette.cpp */,
+ A2BFA0101395FF62006ADC12 /* Palette.h */,
+ A2BFA0111395FF62006ADC12 /* PalettedImageMgr.cpp */,
+ A2BFA0121395FF62006ADC12 /* PalettedImageMgr.h */,
+ A2BFA0131395FF62006ADC12 /* Particles.cpp */,
+ A2BFA0141395FF62006ADC12 /* Particles.h */,
+ A2BFA0151395FF62006ADC12 /* PathFinder.h */,
+ A2BFA0161395FF62006ADC12 /* Plugin.cpp */,
+ A2BFA0171395FF62006ADC12 /* Plugin.h */,
+ A2BFA0181395FF62006ADC12 /* PluginMgr.cpp */,
+ A2BFA0191395FF62006ADC12 /* PluginMgr.h */,
+ A2BFA01A1395FF62006ADC12 /* Polygon.cpp */,
+ A2BFA01B1395FF62006ADC12 /* Polygon.h */,
+ A2BFA01C1395FF62006ADC12 /* PolymorphCache.h */,
+ A2BFA01D1395FF62006ADC12 /* Projectile.cpp */,
+ A2BFA01E1395FF62006ADC12 /* Projectile.h */,
+ A2BFA01F1395FF62006ADC12 /* ProjectileMgr.cpp */,
+ A2BFA0201395FF62006ADC12 /* ProjectileMgr.h */,
+ A2BFA0211395FF62006ADC12 /* ProjectileServer.cpp */,
+ A2BFA0221395FF62006ADC12 /* ProjectileServer.h */,
+ A2BFA0231395FF62006ADC12 /* Region.cpp */,
+ A2BFA0241395FF62006ADC12 /* Region.h */,
+ A2BFA0251395FF62006ADC12 /* Resource.cpp */,
+ A2BFA0261395FF62006ADC12 /* Resource.h */,
+ A2BFA0271395FF62006ADC12 /* ResourceDesc.cpp */,
+ A2BFA0281395FF62006ADC12 /* ResourceDesc.h */,
+ A2BFA0291395FF62006ADC12 /* ResourceManager.cpp */,
+ A2BFA02A1395FF62006ADC12 /* ResourceManager.h */,
+ A2BFA02B1395FF62006ADC12 /* ResourceSource.cpp */,
+ A2BFA02C1395FF62006ADC12 /* ResourceSource.h */,
+ A2BFA02D1395FF62006ADC12 /* SaveGame.h */,
+ A2BFA02E1395FF62006ADC12 /* SaveGameIterator.cpp */,
+ A2BFA02F1395FF62006ADC12 /* SaveGameIterator.h */,
+ A2BFA0301395FF62006ADC12 /* SaveGameMgr.cpp */,
+ A2BFA0311395FF62006ADC12 /* SaveGameMgr.h */,
+ A2BFA0321395FF62006ADC12 /* Scriptable */,
+ A2BFA03F1395FF62006ADC12 /* ScriptedAnimation.cpp */,
+ A2BFA0401395FF62006ADC12 /* ScriptedAnimation.h */,
+ A2BFA0411395FF62006ADC12 /* ScriptEngine.cpp */,
+ A2BFA0421395FF62006ADC12 /* ScriptEngine.h */,
+ A2BFA0431395FF62006ADC12 /* SoundMgr.cpp */,
+ A2BFA0441395FF62006ADC12 /* SoundMgr.h */,
+ A2BFA0451395FF62006ADC12 /* Spell.cpp */,
+ A2BFA0461395FF62006ADC12 /* Spell.h */,
+ A2BFA0471395FF62006ADC12 /* Spellbook.cpp */,
+ A2BFA0481395FF62006ADC12 /* Spellbook.h */,
+ A2BFA0491395FF62006ADC12 /* SpellMgr.cpp */,
+ A2BFA04A1395FF62006ADC12 /* SpellMgr.h */,
+ A2BFA04B1395FF62006ADC12 /* Sprite2D.cpp */,
+ A2BFA04C1395FF62006ADC12 /* Sprite2D.h */,
+ A2BFA04D1395FF62006ADC12 /* SpriteCover.cpp */,
+ A2BFA04E1395FF62006ADC12 /* SpriteCover.h */,
+ A2BFA04F1395FF62006ADC12 /* Store.cpp */,
+ A2BFA0501395FF62006ADC12 /* Store.h */,
+ A2BFA0511395FF62006ADC12 /* StoreMgr.cpp */,
+ A2BFA0521395FF62006ADC12 /* StoreMgr.h */,
+ A2BFA0531395FF62006ADC12 /* StringMgr.cpp */,
+ A2BFA0541395FF62006ADC12 /* StringMgr.h */,
+ A2BFA0551395FF62006ADC12 /* SymbolMgr.cpp */,
+ A2BFA0561395FF62006ADC12 /* SymbolMgr.h */,
+ A2BFA0571395FF62006ADC12 /* System */,
+ A2BFA0681395FF62006ADC12 /* TableMgr.cpp */,
+ A2BFA0691395FF62006ADC12 /* TableMgr.h */,
+ A2BFA06A1395FF62006ADC12 /* Tile.cpp */,
+ A2BFA06B1395FF62006ADC12 /* Tile.h */,
+ A2BFA06C1395FF62006ADC12 /* TileMap.cpp */,
+ A2BFA06D1395FF62006ADC12 /* TileMap.h */,
+ A2BFA06E1395FF62006ADC12 /* TileMapMgr.cpp */,
+ A2BFA06F1395FF62006ADC12 /* TileMapMgr.h */,
+ A2BFA0701395FF62006ADC12 /* TileOverlay.cpp */,
+ A2BFA0711395FF62006ADC12 /* TileOverlay.h */,
+ A2BFA0721395FF62006ADC12 /* TileSetMgr.cpp */,
+ A2BFA0731395FF62006ADC12 /* TileSetMgr.h */,
+ A2BFA0741395FF62006ADC12 /* TypeID.h */,
+ A2BFA0751395FF62006ADC12 /* Variables.cpp */,
+ A2BFA0761395FF62006ADC12 /* Variables.h */,
+ A2BFA0771395FF62006ADC12 /* Video.cpp */,
+ A2BFA0781395FF62006ADC12 /* Video.h */,
+ A2BFA0791395FF62006ADC12 /* VideoMode.h */,
+ A2BFA07A1395FF62006ADC12 /* WindowMgr.cpp */,
+ A2BFA07B1395FF62006ADC12 /* WindowMgr.h */,
+ A2BFA07C1395FF62006ADC12 /* WorldMap.cpp */,
+ A2BFA07D1395FF62006ADC12 /* WorldMap.h */,
+ A2BFA07E1395FF62006ADC12 /* WorldMapMgr.cpp */,
+ A2BFA07F1395FF62006ADC12 /* WorldMapMgr.h */,
+ A28D2498143BEA4200A27897 /* FontManager.cpp */,
+ A28D249B143BEA5800A27897 /* FontManager.h */,
+ );
+ name = core;
+ path = ../gemrb/core;
+ sourceTree = SOURCE_ROOT;
+ };
+ A2BF9FC81395FF62006ADC12 /* GameScript */ = {
+ isa = PBXGroup;
+ children = (
+ A2BF9FC91395FF62006ADC12 /* Actions.cpp */,
+ A2BF9FCA1395FF62006ADC12 /* GameScript.cpp */,
+ A2BF9FCB1395FF62006ADC12 /* GameScript.h */,
+ A2BF9FCC1395FF62006ADC12 /* GSUtils.cpp */,
+ A2BF9FCD1395FF62006ADC12 /* GSUtils.h */,
+ A2BF9FCE1395FF62006ADC12 /* Matching.cpp */,
+ A2BF9FCF1395FF62006ADC12 /* Matching.h */,
+ A2BF9FD01395FF62006ADC12 /* Objects.cpp */,
+ A2BF9FD11395FF62006ADC12 /* Triggers.cpp */,
+ );
+ path = GameScript;
+ sourceTree = "<group>";
+ };
+ A2BF9FD41395FF62006ADC12 /* GUI */ = {
+ isa = PBXGroup;
+ children = (
+ A2BF9FD51395FF62006ADC12 /* Button.cpp */,
+ A2BF9FD61395FF62006ADC12 /* Button.h */,
+ A2BF9FD71395FF62006ADC12 /* Console.cpp */,
+ A2BF9FD81395FF62006ADC12 /* Console.h */,
+ A2FE553A13982BA6006AB962 /* config.h */,
+ A2BF9FD91395FF62006ADC12 /* Control.cpp */,
+ A2BF9FDA1395FF62006ADC12 /* Control.h */,
+ A2BF9FDB1395FF62006ADC12 /* EventMgr.cpp */,
+ A2BF9FDC1395FF62006ADC12 /* EventMgr.h */,
+ A2BF9FDE1395FF62006ADC12 /* GameControl.h */,
+ A2BF9FDD1395FF62006ADC12 /* GameControl.cpp */,
+ A265ECEA13A8669700C6DF12 /* Logging.cpp */,
+ A265ECEB13A8669700C6DF12 /* SlicedStream.cpp */,
+ A265ECEC13A8669700C6DF12 /* String.cpp */,
+ A265ECD813A8661600C6DF12 /* FileCache.cpp */,
+ A265ECD913A8661600C6DF12 /* IndexedArchive.cpp */,
+ A265ECDA13A8661600C6DF12 /* KeyMap.cpp */,
+ A265ECDB13A8661600C6DF12 /* PluginLoader.cpp */,
+ A2BF9FDF1395FF62006ADC12 /* Label.cpp */,
+ A2BF9FE01395FF62006ADC12 /* Label.h */,
+ A2BF9FE11395FF62006ADC12 /* MapControl.cpp */,
+ A2BF9FE21395FF62006ADC12 /* MapControl.h */,
+ A2BF9FE31395FF62006ADC12 /* Progressbar.cpp */,
+ A2BF9FE41395FF62006ADC12 /* Progressbar.h */,
+ A2BF9FE51395FF62006ADC12 /* ScrollBar.cpp */,
+ A2BF9FE61395FF62006ADC12 /* ScrollBar.h */,
+ A2BF9FE71395FF62006ADC12 /* Slider.cpp */,
+ A2BF9FE81395FF62006ADC12 /* Slider.h */,
+ A2BF9FE91395FF62006ADC12 /* TextArea.cpp */,
+ A2BF9FEA1395FF62006ADC12 /* TextArea.h */,
+ A2BF9FEB1395FF62006ADC12 /* TextEdit.cpp */,
+ A2BF9FEC1395FF62006ADC12 /* TextEdit.h */,
+ A2BF9FED1395FF62006ADC12 /* Window.cpp */,
+ A2BF9FEE1395FF62006ADC12 /* Window.h */,
+ A2BF9FEF1395FF62006ADC12 /* WorldMapControl.cpp */,
+ A2BF9FF01395FF62006ADC12 /* WorldMapControl.h */,
+ );
+ path = GUI;
+ sourceTree = "<group>";
+ };
+ A2BFA0321395FF62006ADC12 /* Scriptable */ = {
+ isa = PBXGroup;
+ children = (
+ A2BFA0331395FF62006ADC12 /* Actor.cpp */,
+ A2BFA0341395FF62006ADC12 /* Actor.h */,
+ A2BFA0351395FF62006ADC12 /* Container.cpp */,
+ A2BFA0361395FF62006ADC12 /* Container.h */,
+ A2BFA0371395FF62006ADC12 /* Door.cpp */,
+ A2BFA0381395FF62006ADC12 /* Door.h */,
+ A2BFA0391395FF62006ADC12 /* InfoPoint.cpp */,
+ A2BFA03A1395FF62006ADC12 /* InfoPoint.h */,
+ A2BFA03B1395FF62006ADC12 /* PCStatStruct.cpp */,
+ A2BFA03C1395FF62006ADC12 /* PCStatStruct.h */,
+ A2BFA03D1395FF62006ADC12 /* Scriptable.cpp */,
+ A2BFA03E1395FF62006ADC12 /* Scriptable.h */,
+ );
+ path = Scriptable;
+ sourceTree = "<group>";
+ };
+ A2BFA0571395FF62006ADC12 /* System */ = {
+ isa = PBXGroup;
+ children = (
+ A2BFA05C1395FF62006ADC12 /* DataStream.cpp */,
+ A2BFA05D1395FF62006ADC12 /* DataStream.h */,
+ A2BFA05E1395FF62006ADC12 /* FileStream.cpp */,
+ A2BFA05F1395FF62006ADC12 /* FileStream.h */,
+ A2BFA0601395FF62006ADC12 /* MemoryStream.cpp */,
+ A2BFA0611395FF62006ADC12 /* MemoryStream.h */,
+ A2BFA0641395FF62006ADC12 /* swab.c */,
+ A2BFA0651395FF62006ADC12 /* swab.h */,
+ A2BFA0661395FF62006ADC12 /* VFS.cpp */,
+ A2BFA0671395FF62006ADC12 /* VFS.h */,
+ );
+ path = System;
+ sourceTree = "<group>";
+ };
+ A2D4C51D13A978110086BCC4 /* includes */ = {
+ isa = PBXGroup;
+ children = (
+ A2AC3E561462F7C2000E1E2C /* compiler_macros.h */,
+ A2D4C51E13A978110086BCC4 /* defsounds.h */,
+ A2D4C51F13A978110086BCC4 /* errors.h */,
+ A2D4C52013A978110086BCC4 /* exports.h */,
+ A2D4C52113A978110086BCC4 /* globals.h */,
+ A2D4C52213A978110086BCC4 /* HashMap.h */,
+ A2D4C52313A978110086BCC4 /* ie_feats.h */,
+ A2D4C52413A978110086BCC4 /* ie_stats.h */,
+ A2D4C52513A978110086BCC4 /* ie_types.h */,
+ A2D4C52613A978110086BCC4 /* iless.h */,
+ A2D4C52813A978110086BCC4 /* opcode_params.h */,
+ A2D4C52913A978110086BCC4 /* operatorbool.h */,
+ A2D4C52A13A978110086BCC4 /* overlays.h */,
+ A2D4C52B13A978110086BCC4 /* plugindef.h */,
+ A2D4C52C13A978110086BCC4 /* RGBAColor.h */,
+ A2D4C52D13A978110086BCC4 /* SClassID.h */,
+ A2D4C52E13A978110086BCC4 /* StringMap.h */,
+ A2D4C52F13A978110086BCC4 /* strrefs.h */,
+ A2D4C53013A978110086BCC4 /* win32def.h */,
+ );
+ name = includes;
+ path = ../gemrb/includes;
+ sourceTree = SOURCE_ROOT;
+ };
+ A2E7985B14845AFB00B15DF4 /* iOS static libs */ = {
+ isa = PBXGroup;
+ children = (
+ );
+ name = "iOS static libs";
+ sourceTree = "<group>";
+ };
+ A2E7985C14845B3F00B15DF4 /* Cocoa Wrappers */ = {
+ isa = PBXGroup;
+ children = (
+ A2E7985D14845B4E00B15DF4 /* New Group */,
+ );
+ name = "Cocoa Wrappers";
+ sourceTree = "<group>";
+ };
+ A2E7985D14845B4E00B15DF4 /* New Group */ = {
+ isa = PBXGroup;
+ children = (
+ );
+ name = "New Group";
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ A2E66334139E875400310FC8 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2E66448139E8CAA00310FC8 /* ie_types.h in Headers */,
+ A2E6634F139E882900310FC8 /* ActorMgr.h in Headers */,
+ A2E66351139E882900310FC8 /* Ambient.h in Headers */,
+ A2E66353139E882900310FC8 /* AmbientMgr.h in Headers */,
+ A2E66355139E882900310FC8 /* Animation.h in Headers */,
+ A2E66357139E883100310FC8 /* AnimationFactory.h in Headers */,
+ A2E66359139E883100310FC8 /* AnimationMgr.h in Headers */,
+ A2E6635A139E883100310FC8 /* AnimStructures.h in Headers */,
+ A2E6635C139E883100310FC8 /* ArchiveImporter.h in Headers */,
+ A2E6635E139E883100310FC8 /* Audio.h in Headers */,
+ A2E66360139E883100310FC8 /* Bitmap.h in Headers */,
+ A2E66362139E883100310FC8 /* Cache.h in Headers */,
+ A2E66364139E883100310FC8 /* Calendar.h in Headers */,
+ A2E66366139E883100310FC8 /* Callback.h in Headers */,
+ A2E66368139E883100310FC8 /* CharAnimations.h in Headers */,
+ A2E6636A139E883100310FC8 /* Compressor.h in Headers */,
+ A2E6636C139E883100310FC8 /* ControlAnimation.h in Headers */,
+ A2E6636E139E883100310FC8 /* damages.h in Headers */,
+ A2E66370139E883100310FC8 /* DataFileMgr.h in Headers */,
+ A2E66372139E883100310FC8 /* Dialog.h in Headers */,
+ A2E66374139E883100310FC8 /* DialogHandler.h in Headers */,
+ A2E66376139E883100310FC8 /* DialogMgr.h in Headers */,
+ A2E66378139E883100310FC8 /* DisplayMessage.h in Headers */,
+ A2E66379139E883100310FC8 /* Effect.h in Headers */,
+ A2E6637B139E883100310FC8 /* EffectMgr.h in Headers */,
+ A2E6637D139E883100310FC8 /* EffectQueue.h in Headers */,
+ A2E6637F139E883100310FC8 /* Factory.h in Headers */,
+ A2E66381139E883100310FC8 /* FactoryObject.h in Headers */,
+ A2E66383139E883100310FC8 /* Font.h in Headers */,
+ A2E66385139E883100310FC8 /* Game.h in Headers */,
+ A2E66387139E883100310FC8 /* GameData.h in Headers */,
+ A2E66389139E883700310FC8 /* GlobalTimer.h in Headers */,
+ A2E6638A139E883E00310FC8 /* Holder.h in Headers */,
+ A2E6638C139E883E00310FC8 /* Image.h in Headers */,
+ A2E6638E139E883E00310FC8 /* ImageFactory.h in Headers */,
+ A2E66390139E883E00310FC8 /* ImageMgr.h in Headers */,
+ A2E66392139E883E00310FC8 /* ImageWriter.h in Headers */,
+ A2E66394139E883E00310FC8 /* IniSpawn.h in Headers */,
+ A2E66396139E883E00310FC8 /* Interface.h in Headers */,
+ A2E66398139E883E00310FC8 /* Inventory.h in Headers */,
+ A2E6639A139E883E00310FC8 /* Item.h in Headers */,
+ A2E6639C139E883E00310FC8 /* ItemMgr.h in Headers */,
+ A2E6639E139E883E00310FC8 /* LRUCache.h in Headers */,
+ A2E663A0139E883E00310FC8 /* Map.h in Headers */,
+ A2E663A2139E883E00310FC8 /* MapMgr.h in Headers */,
+ A2E663A4139E883E00310FC8 /* MoviePlayer.h in Headers */,
+ A2E663A6139E883E00310FC8 /* MusicMgr.h in Headers */,
+ A2E663A8139E883E00310FC8 /* Palette.h in Headers */,
+ A2E663AA139E883E00310FC8 /* PalettedImageMgr.h in Headers */,
+ A2E663AC139E883E00310FC8 /* Particles.h in Headers */,
+ A2E663AD139E883E00310FC8 /* PathFinder.h in Headers */,
+ A2E663AF139E883E00310FC8 /* Plugin.h in Headers */,
+ A2E663B1139E883E00310FC8 /* PluginMgr.h in Headers */,
+ A2E663B3139E883E00310FC8 /* Polygon.h in Headers */,
+ A2E663B4139E883E00310FC8 /* PolymorphCache.h in Headers */,
+ A2E663B6139E883E00310FC8 /* Projectile.h in Headers */,
+ A2E663B8139E883E00310FC8 /* ProjectileMgr.h in Headers */,
+ A2E663BA139E883E00310FC8 /* ProjectileServer.h in Headers */,
+ A2E663BC139E883E00310FC8 /* Region.h in Headers */,
+ A2E663BE139E883E00310FC8 /* Resource.h in Headers */,
+ A2E663C0139E883E00310FC8 /* ResourceDesc.h in Headers */,
+ A2E663C2139E883E00310FC8 /* ResourceManager.h in Headers */,
+ A2E663C4139E883E00310FC8 /* ResourceSource.h in Headers */,
+ A2E663C5139E883E00310FC8 /* SaveGame.h in Headers */,
+ A2E663C7139E883E00310FC8 /* SaveGameIterator.h in Headers */,
+ A2E663C9139E883E00310FC8 /* SaveGameMgr.h in Headers */,
+ A2E663CB139E884500310FC8 /* ScriptedAnimation.h in Headers */,
+ A2E663CD139E884500310FC8 /* ScriptEngine.h in Headers */,
+ A2E663CF139E884500310FC8 /* SoundMgr.h in Headers */,
+ A2E663D1139E884500310FC8 /* Spell.h in Headers */,
+ A2E663D3139E884500310FC8 /* Spellbook.h in Headers */,
+ A2E663D5139E884500310FC8 /* SpellMgr.h in Headers */,
+ A2E663D7139E884500310FC8 /* Sprite2D.h in Headers */,
+ A2E663D9139E884500310FC8 /* SpriteCover.h in Headers */,
+ A2E663DB139E884500310FC8 /* Store.h in Headers */,
+ A2E663DD139E884500310FC8 /* StoreMgr.h in Headers */,
+ A2E663DF139E884500310FC8 /* StringMgr.h in Headers */,
+ A2E663E1139E884500310FC8 /* SymbolMgr.h in Headers */,
+ A2E663E3139E884B00310FC8 /* TableMgr.h in Headers */,
+ A2E663E5139E884B00310FC8 /* Tile.h in Headers */,
+ A2E663E7139E884B00310FC8 /* TileMap.h in Headers */,
+ A2E663E9139E884B00310FC8 /* TileMapMgr.h in Headers */,
+ A2E663EB139E884B00310FC8 /* TileOverlay.h in Headers */,
+ A2E663ED139E884B00310FC8 /* TileSetMgr.h in Headers */,
+ A2E663EE139E884B00310FC8 /* TypeID.h in Headers */,
+ A2E663F0139E884B00310FC8 /* Variables.h in Headers */,
+ A2E663F2139E884B00310FC8 /* Video.h in Headers */,
+ A2E663F3139E884B00310FC8 /* VideoMode.h in Headers */,
+ A2E663F5139E884B00310FC8 /* WindowMgr.h in Headers */,
+ A2E663F7139E884B00310FC8 /* WorldMap.h in Headers */,
+ A2E663F9139E884B00310FC8 /* WorldMapMgr.h in Headers */,
+ A2E663FD139E885300310FC8 /* DataStream.h in Headers */,
+ A2E663FF139E885300310FC8 /* FileStream.h in Headers */,
+ A2E66401139E885300310FC8 /* MemoryStream.h in Headers */,
+ A2E66405139E885300310FC8 /* swab.h in Headers */,
+ A2E66407139E885300310FC8 /* VFS.h in Headers */,
+ A2E66409139E885A00310FC8 /* Actor.h in Headers */,
+ A2E6640B139E885A00310FC8 /* Container.h in Headers */,
+ A2E6640D139E885A00310FC8 /* Door.h in Headers */,
+ A2E6640F139E885A00310FC8 /* InfoPoint.h in Headers */,
+ A2E66411139E885A00310FC8 /* PCStatStruct.h in Headers */,
+ A2E66413139E885A00310FC8 /* Scriptable.h in Headers */,
+ A2E66415139E886100310FC8 /* Button.h in Headers */,
+ A2E66417139E886100310FC8 /* Console.h in Headers */,
+ A2E66418139E886100310FC8 /* config.h in Headers */,
+ A2E6641A139E886100310FC8 /* Control.h in Headers */,
+ A2E6641C139E886100310FC8 /* EventMgr.h in Headers */,
+ A2E6641E139E886100310FC8 /* GameControl.h in Headers */,
+ A2E66420139E886100310FC8 /* Label.h in Headers */,
+ A2E66422139E886100310FC8 /* MapControl.h in Headers */,
+ A2E66424139E886100310FC8 /* Progressbar.h in Headers */,
+ A2E66426139E886100310FC8 /* ScrollBar.h in Headers */,
+ A2E66428139E886100310FC8 /* Slider.h in Headers */,
+ A2E6642A139E886100310FC8 /* TextArea.h in Headers */,
+ A2E6642C139E886100310FC8 /* TextEdit.h in Headers */,
+ A2E6642E139E886100310FC8 /* Window.h in Headers */,
+ A2E66430139E886100310FC8 /* WorldMapControl.h in Headers */,
+ A2E66433139E886700310FC8 /* GameScript.h in Headers */,
+ A2E66435139E886700310FC8 /* GSUtils.h in Headers */,
+ A2E66437139E886700310FC8 /* Matching.h in Headers */,
+ A2E6647C139E8FAB00310FC8 /* core.pch in Headers */,
+ A28D249C143BEA5800A27897 /* FontManager.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ 8D1107260486CEB800E47090 /* GemRB OS X */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "GemRB OS X" */;
+ buildPhases = (
+ 8D1107290486CEB800E47090 /* Resources */,
+ 8D11072C0486CEB800E47090 /* Sources */,
+ 002F39FD09D0883400EBEB88 /* Copy Frameworks into .app bundle */,
+ 8D11072E0486CEB800E47090 /* Frameworks */,
+ A249187F141079510038B170 /* ShellScript */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ A259F3FA142BFC4100D49124 /* PBXTargetDependency */,
+ A23EBFFC1419A81500CC049E /* PBXTargetDependency */,
+ A2E6633C139E876900310FC8 /* PBXTargetDependency */,
+ A2375BA113AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BA313AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BA513AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BA713AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BA913AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BAB13AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BAD13AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BAF13AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BB113AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BB313AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BB513AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BB713AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BB913AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BBB13AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BBD13AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BBF13AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BC113AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BC313AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BC513AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BC713AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BC913AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BCB13AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BCD13AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BCF13AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BD113AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BD313AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BD513AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BD713AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BD913AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BDD13AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BDF13AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BE113AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BE313AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BE513AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BE713AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BE913AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BEB13AAF58E00E7EF9B /* PBXTargetDependency */,
+ );
+ name = "GemRB OS X";
+ productInstallPath = "$(HOME)/Applications";
+ productName = GemRB_OSX;
+ productReference = 8D1107320486CEB800E47090 /* GemRB.app */;
+ productType = "com.apple.product-type.application";
+ };
+ A2462F1013A036B1002D1F02 /* AREImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A2462F1813A036C8002D1F02 /* Build configuration list for PBXNativeTarget "AREImporter" */;
+ buildPhases = (
+ A2462F0E13A036B1002D1F02 /* Sources */,
+ A2462F0F13A036B1002D1F02 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = AREImporter;
+ productName = AREImporter;
+ productReference = A2462F1113A036B1002D1F02 /* AREImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A269030F142BEE2F003E8BCC /* SDLTTFFont */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A2690314142BEE2F003E8BCC /* Build configuration list for PBXNativeTarget "SDLTTFFont" */;
+ buildPhases = (
+ A2690310142BEE2F003E8BCC /* Sources */,
+ A2690312142BEE2F003E8BCC /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = SDLTTFFont;
+ productName = SAVImporter;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B3C913A2867900D41A8A /* BIFImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B3CD13A2869700D41A8A /* Build configuration list for PBXNativeTarget "BIFImporter" */;
+ buildPhases = (
+ A276B3C713A2867900D41A8A /* Sources */,
+ A276B3C813A2867900D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = BIFImporter;
+ productName = BIFImporter;
+ productReference = A276B3CA13A2867900D41A8A /* BIFImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B3D013A286A800D41A8A /* BIKPlayer */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B43513A287CC00D41A8A /* Build configuration list for PBXNativeTarget "BIKPlayer" */;
+ buildPhases = (
+ A276B3CE13A286A800D41A8A /* Sources */,
+ A276B3CF13A286A800D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = BIKPlayer;
+ productName = BIKPlayer;
+ productReference = A276B3D113A286A800D41A8A /* BIKPlayer.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B3D613A286BC00D41A8A /* BMPImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B43613A287CC00D41A8A /* Build configuration list for PBXNativeTarget "BMPImporter" */;
+ buildPhases = (
+ A276B3D413A286BC00D41A8A /* Sources */,
+ A276B3D513A286BC00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = BMPImporter;
+ productName = BMPImporter;
+ productReference = A276B3D713A286BC00D41A8A /* BMPImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B3DC13A286CD00D41A8A /* BMPWriter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B43713A287CC00D41A8A /* Build configuration list for PBXNativeTarget "BMPWriter" */;
+ buildPhases = (
+ A276B3DA13A286CD00D41A8A /* Sources */,
+ A276B3DB13A286CD00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = BMPWriter;
+ productName = BMPWriter;
+ productReference = A276B3DD13A286CD00D41A8A /* BMPWriter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B3E213A286DE00D41A8A /* CHUImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B43813A287CC00D41A8A /* Build configuration list for PBXNativeTarget "CHUImporter" */;
+ buildPhases = (
+ A276B3E013A286DE00D41A8A /* Sources */,
+ A276B3E113A286DE00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = CHUImporter;
+ productName = CHUImporter;
+ productReference = A276B3E313A286DE00D41A8A /* CHUImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B3E813A286EC00D41A8A /* CREImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B43913A287CC00D41A8A /* Build configuration list for PBXNativeTarget "CREImporter" */;
+ buildPhases = (
+ A276B3E613A286EC00D41A8A /* Sources */,
+ A276B3E713A286EC00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = CREImporter;
+ productName = CREImporter;
+ productReference = A276B3E913A286EC00D41A8A /* CREImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B3EE13A286FB00D41A8A /* DirectoryImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B43A13A287CC00D41A8A /* Build configuration list for PBXNativeTarget "DirectoryImporter" */;
+ buildPhases = (
+ A276B3EC13A286FB00D41A8A /* Sources */,
+ A276B3ED13A286FB00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = DirectoryImporter;
+ productName = DirectoryImporter;
+ productReference = A276B3EF13A286FB00D41A8A /* DirectoryImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B3F413A2871300D41A8A /* DLGImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B43B13A287CC00D41A8A /* Build configuration list for PBXNativeTarget "DLGImporter" */;
+ buildPhases = (
+ A276B3F213A2871300D41A8A /* Sources */,
+ A276B3F313A2871300D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = DLGImporter;
+ productName = DLGImporter;
+ productReference = A276B3F513A2871300D41A8A /* DLGImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B3FA13A2872500D41A8A /* EFFImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B43C13A287CC00D41A8A /* Build configuration list for PBXNativeTarget "EFFImporter" */;
+ buildPhases = (
+ A276B3F813A2872500D41A8A /* Sources */,
+ A276B3F913A2872500D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = EFFImporter;
+ productName = EFFImporter;
+ productReference = A276B3FB13A2872500D41A8A /* EFFImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B40013A2873700D41A8A /* FXOpcodes */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B43D13A287CC00D41A8A /* Build configuration list for PBXNativeTarget "FXOpcodes" */;
+ buildPhases = (
+ A276B3FE13A2873700D41A8A /* Sources */,
+ A276B3FF13A2873700D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = FXOpcodes;
+ productName = FXOpcodes;
+ productReference = A276B40113A2873700D41A8A /* FXOpcodes.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B40613A2874700D41A8A /* GAMImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B43E13A287CC00D41A8A /* Build configuration list for PBXNativeTarget "GAMImporter" */;
+ buildPhases = (
+ A276B40413A2874700D41A8A /* Sources */,
+ A276B40513A2874700D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = GAMImporter;
+ productName = GAMImporter;
+ productReference = A276B40713A2874700D41A8A /* GAMImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B40C13A2875400D41A8A /* GUIScript */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B43F13A287CC00D41A8A /* Build configuration list for PBXNativeTarget "GUIScript" */;
+ buildPhases = (
+ A276B40A13A2875400D41A8A /* Sources */,
+ A276B40B13A2875400D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = GUIScript;
+ productName = GUIScript;
+ productReference = A276B40D13A2875400D41A8A /* GUIScript.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B41213A2876300D41A8A /* IDSImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B44013A287CC00D41A8A /* Build configuration list for PBXNativeTarget "IDSImporter" */;
+ buildPhases = (
+ A276B41013A2876300D41A8A /* Sources */,
+ A276B41113A2876300D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = IDSImporter;
+ productName = IDSImporter;
+ productReference = A276B41313A2876300D41A8A /* IDSImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B41813A2877100D41A8A /* INIImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B44113A287CC00D41A8A /* Build configuration list for PBXNativeTarget "INIImporter" */;
+ buildPhases = (
+ A276B41613A2877100D41A8A /* Sources */,
+ A276B41713A2877100D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = INIImporter;
+ productName = INIImporter;
+ productReference = A276B41913A2877100D41A8A /* INIImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B41E13A2878400D41A8A /* ITMImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B44213A287CC00D41A8A /* Build configuration list for PBXNativeTarget "ITMImporter" */;
+ buildPhases = (
+ A276B41C13A2878400D41A8A /* Sources */,
+ A276B41D13A2878400D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = ITMImporter;
+ productName = ITMImporter;
+ productReference = A276B41F13A2878400D41A8A /* ITMImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B42413A2879900D41A8A /* IWDOpcodes */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B44313A287CC00D41A8A /* Build configuration list for PBXNativeTarget "IWDOpcodes" */;
+ buildPhases = (
+ A276B42213A2879900D41A8A /* Sources */,
+ A276B42313A2879900D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = IWDOpcodes;
+ productName = IWDOpcodes;
+ productReference = A276B42513A2879900D41A8A /* IWDOpcodes.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B42A13A287AB00D41A8A /* KEYImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B44413A287CC00D41A8A /* Build configuration list for PBXNativeTarget "KEYImporter" */;
+ buildPhases = (
+ A276B42813A287AB00D41A8A /* Sources */,
+ A276B42913A287AB00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = KEYImporter;
+ productName = KEYImporter;
+ productReference = A276B42B13A287AB00D41A8A /* KEYImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B43013A287BC00D41A8A /* MOSImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B44513A287CC00D41A8A /* Build configuration list for PBXNativeTarget "MOSImporter" */;
+ buildPhases = (
+ A276B42E13A287BC00D41A8A /* Sources */,
+ A276B42F13A287BC00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = MOSImporter;
+ productName = MOSImporter;
+ productReference = A276B43113A287BD00D41A8A /* MOSImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B44813A289E000D41A8A /* MUSImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4B313A28AF400D41A8A /* Build configuration list for PBXNativeTarget "MUSImporter" */;
+ buildPhases = (
+ A276B44613A289E000D41A8A /* Sources */,
+ A276B44713A289E000D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = MUSImporter;
+ productName = MUSImporter;
+ productReference = A276B44913A289E000D41A8A /* MUSImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B44E13A28A0000D41A8A /* MVEPlayer */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4B413A28AF400D41A8A /* Build configuration list for PBXNativeTarget "MVEPlayer" */;
+ buildPhases = (
+ A276B44C13A28A0000D41A8A /* Sources */,
+ A276B44D13A28A0000D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = MVEPlayer;
+ productName = MVEPlayer;
+ productReference = A276B44F13A28A0000D41A8A /* MVEPlayer.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B45413A28A0E00D41A8A /* NullSound */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4B513A28AF400D41A8A /* Build configuration list for PBXNativeTarget "NullSound" */;
+ buildPhases = (
+ A276B45213A28A0E00D41A8A /* Sources */,
+ A276B45313A28A0E00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = NullSound;
+ productName = NullSound;
+ productReference = A276B45513A28A0E00D41A8A /* NullSound.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B45A13A28A1C00D41A8A /* OGGReader */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4B613A28AF400D41A8A /* Build configuration list for PBXNativeTarget "OGGReader" */;
+ buildPhases = (
+ A276B45813A28A1C00D41A8A /* Sources */,
+ A276B45913A28A1C00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = OGGReader;
+ productName = OGGReader;
+ productReference = A276B45B13A28A1C00D41A8A /* OGGReader.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B46013A28A3100D41A8A /* OpenALAudio */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4B713A28AF400D41A8A /* Build configuration list for PBXNativeTarget "OpenALAudio" */;
+ buildPhases = (
+ A276B45E13A28A3100D41A8A /* Sources */,
+ A276B45F13A28A3100D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = OpenALAudio;
+ productName = OpenALAudio;
+ productReference = A276B46113A28A3100D41A8A /* OpenALAudio.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B46613A28A3F00D41A8A /* PLTImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4B813A28AF400D41A8A /* Build configuration list for PBXNativeTarget "PLTImporter" */;
+ buildPhases = (
+ A276B46413A28A3F00D41A8A /* Sources */,
+ A276B46513A28A3F00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = PLTImporter;
+ productName = PLTImporter;
+ productReference = A276B46713A28A3F00D41A8A /* PLTImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B46C13A28A5000D41A8A /* PNGImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4B913A28AF400D41A8A /* Build configuration list for PBXNativeTarget "PNGImporter" */;
+ buildPhases = (
+ A276B46A13A28A5000D41A8A /* Sources */,
+ A276B46B13A28A5000D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = PNGImporter;
+ productName = PNGImporter;
+ productReference = A276B46D13A28A5000D41A8A /* PNGImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B47213A28A5D00D41A8A /* PROImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4BA13A28AF400D41A8A /* Build configuration list for PBXNativeTarget "PROImporter" */;
+ buildPhases = (
+ A276B47013A28A5D00D41A8A /* Sources */,
+ A276B47113A28A5D00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = PROImporter;
+ productName = PROImporter;
+ productReference = A276B47313A28A5D00D41A8A /* PROImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B47813A28A7600D41A8A /* PSTOpcodes */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4BB13A28AF400D41A8A /* Build configuration list for PBXNativeTarget "PSTOpcodes" */;
+ buildPhases = (
+ A276B47613A28A7600D41A8A /* Sources */,
+ A276B47713A28A7600D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = PSTOpcodes;
+ productName = PSTOpcodes;
+ productReference = A276B47913A28A7600D41A8A /* PSTOpcodes.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B47E13A28A8500D41A8A /* SDLAudio */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4BC13A28AF400D41A8A /* Build configuration list for PBXNativeTarget "SDLAudio" */;
+ buildPhases = (
+ A276B47C13A28A8500D41A8A /* Sources */,
+ A276B47D13A28A8500D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = SDLAudio;
+ productName = SDLAudio;
+ productReference = A276B47F13A28A8500D41A8A /* SDLAudio.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B48413A28A9000D41A8A /* SDLVideo */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4BD13A28AF400D41A8A /* Build configuration list for PBXNativeTarget "SDLVideo" */;
+ buildPhases = (
+ A276B48213A28A9000D41A8A /* Sources */,
+ A276B48313A28A9000D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = SDLVideo;
+ productName = SDLVideo;
+ productReference = A276B48513A28A9000D41A8A /* SDLVideo.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B48A13A28A9E00D41A8A /* SPLImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4BE13A28AF400D41A8A /* Build configuration list for PBXNativeTarget "SPLImporter" */;
+ buildPhases = (
+ A276B48813A28A9E00D41A8A /* Sources */,
+ A276B48913A28A9E00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = SPLImporter;
+ productName = SPLImporter;
+ productReference = A276B48B13A28A9E00D41A8A /* SPLImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B49013A28AA800D41A8A /* TISImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4BF13A28AF400D41A8A /* Build configuration list for PBXNativeTarget "TISImporter" */;
+ buildPhases = (
+ A276B48E13A28AA800D41A8A /* Sources */,
+ A276B48F13A28AA800D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = TISImporter;
+ productName = TISImporter;
+ productReference = A276B49113A28AA900D41A8A /* TISImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B49613A28AB800D41A8A /* TLKImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4C013A28AF400D41A8A /* Build configuration list for PBXNativeTarget "TLKImporter" */;
+ buildPhases = (
+ A276B49413A28AB800D41A8A /* Sources */,
+ A276B49513A28AB800D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = TLKImporter;
+ productName = TLKImporter;
+ productReference = A276B49713A28AB800D41A8A /* TLKImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B49C13A28AC800D41A8A /* WAVReader */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4C113A28AF400D41A8A /* Build configuration list for PBXNativeTarget "WAVReader" */;
+ buildPhases = (
+ A276B49A13A28AC800D41A8A /* Sources */,
+ A276B49B13A28AC800D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = WAVReader;
+ productName = WAVReader;
+ productReference = A276B49D13A28AC800D41A8A /* WAVReader.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B4A213A28AD300D41A8A /* WEDImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4C213A28AF400D41A8A /* Build configuration list for PBXNativeTarget "WEDImporter" */;
+ buildPhases = (
+ A276B4A013A28AD300D41A8A /* Sources */,
+ A276B4A113A28AD300D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = WEDImporter;
+ productName = WEDImporter;
+ productReference = A276B4A313A28AD300D41A8A /* WEDImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B4A813A28AE100D41A8A /* WMPImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4C313A28AF400D41A8A /* Build configuration list for PBXNativeTarget "WMPImporter" */;
+ buildPhases = (
+ A276B4A613A28AE100D41A8A /* Sources */,
+ A276B4A713A28AE100D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = WMPImporter;
+ productName = WMPImporter;
+ productReference = A276B4A913A28AE100D41A8A /* WMPImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B4AE13A28AEE00D41A8A /* ZLibManager */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4C413A28AF400D41A8A /* Build configuration list for PBXNativeTarget "ZLibManager" */;
+ buildPhases = (
+ A276B4AC13A28AEE00D41A8A /* Sources */,
+ A276B4AD13A28AEE00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = ZLibManager;
+ productName = ZLibManager;
+ productReference = A276B4AF13A28AEE00D41A8A /* ZLibManager.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B4F313A28C0400D41A8A /* STOImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B52413A28C4400D41A8A /* Build configuration list for PBXNativeTarget "STOImporter" */;
+ buildPhases = (
+ A276B4F113A28C0400D41A8A /* Sources */,
+ A276B4F213A28C0400D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = STOImporter;
+ productName = STOImporter;
+ productReference = A276B4F413A28C0400D41A8A /* STOImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A27E830913A0358200B41410 /* 2DAImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A27E831213A035B800B41410 /* Build configuration list for PBXNativeTarget "2DAImporter" */;
+ buildPhases = (
+ A27E830713A0358200B41410 /* Sources */,
+ A27E830813A0358200B41410 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = 2DAImporter;
+ productName = 2DAImporter;
+ productReference = A27E830A13A0358200B41410 /* 2DAImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A29BF7B113A0380F00C812DD /* BAMImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A29BF7B913A0381D00C812DD /* Build configuration list for PBXNativeTarget "BAMImporter" */;
+ buildPhases = (
+ A29BF7AF13A0380F00C812DD /* Sources */,
+ A29BF7B013A0380F00C812DD /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = BAMImporter;
+ productName = BAMImporter;
+ productReference = A29BF7B213A0380F00C812DD /* BAMImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A29BF85B13A0427900C812DD /* GemRB iOS */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A29BF86313A042B600C812DD /* Build configuration list for PBXNativeTarget "GemRB iOS" */;
+ buildPhases = (
+ A29BF85813A0427900C812DD /* Resources */,
+ A29BF85913A0427900C812DD /* Sources */,
+ A29BF85A13A0427900C812DD /* Frameworks */,
+ A2D4C61613A978520086BCC4 /* ShellScript */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "GemRB iOS";
+ productName = "GemRB iOS";
+ productReference = A29BF85C13A0427900C812DD /* GemRB.app */;
+ productType = "com.apple.product-type.application";
+ };
+ A2E66337139E875400310FC8 /* gemrb_core */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A2E6633D139E87A400310FC8 /* Build configuration list for PBXNativeTarget "gemrb_core" */;
+ buildPhases = (
+ A2E66334139E875400310FC8 /* Headers */,
+ A2E66335139E875400310FC8 /* Sources */,
+ A2E66336139E875400310FC8 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = gemrb_core;
+ productName = libgemrb_core.dylib;
+ productReference = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A2F0505013ABB80B0023B7EB /* SAVImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A2F0505713ABB8320023B7EB /* Build configuration list for PBXNativeTarget "SAVImporter" */;
+ buildPhases = (
+ A2F0504E13ABB80B0023B7EB /* Sources */,
+ A2F0504F13ABB80B0023B7EB /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = SAVImporter;
+ productName = SAVImporter;
+ productReference = A2F0505113ABB80B0023B7EB /* SAVImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A2FCD5FA13A0366100271997 /* ACMReader */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A2FCD60213A0366F00271997 /* Build configuration list for PBXNativeTarget "ACMReader" */;
+ buildPhases = (
+ A2FCD5F813A0366100271997 /* Sources */,
+ A2FCD5F913A0366100271997 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = ACMReader;
+ productName = ACMReader;
+ productReference = A2FCD5FB13A0366100271997 /* ACMReader.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 29B97313FDCFA39411CA2CEA /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ BuildIndependentTargetsInParallel = YES;
+ LastUpgradeCheck = 0420;
+ };
+ buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "GemRB" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 1;
+ knownRegions = (
+ English,
+ Japanese,
+ French,
+ German,
+ );
+ mainGroup = 29B97314FDCFA39411CA2CEA /* GemRB_OSX */;
+ projectDirPath = "";
+ projectRoots = (
+ "",
+ ../gemrb,
+ );
+ targets = (
+ A2E66337139E875400310FC8 /* gemrb_core */,
+ 8D1107260486CEB800E47090 /* GemRB OS X */,
+ A29BF85B13A0427900C812DD /* GemRB iOS */,
+ A27E830913A0358200B41410 /* 2DAImporter */,
+ A2FCD5FA13A0366100271997 /* ACMReader */,
+ A2462F1013A036B1002D1F02 /* AREImporter */,
+ A29BF7B113A0380F00C812DD /* BAMImporter */,
+ A276B3C913A2867900D41A8A /* BIFImporter */,
+ A276B3D013A286A800D41A8A /* BIKPlayer */,
+ A276B3D613A286BC00D41A8A /* BMPImporter */,
+ A276B3DC13A286CD00D41A8A /* BMPWriter */,
+ A276B3E213A286DE00D41A8A /* CHUImporter */,
+ A276B3E813A286EC00D41A8A /* CREImporter */,
+ A276B3EE13A286FB00D41A8A /* DirectoryImporter */,
+ A276B3F413A2871300D41A8A /* DLGImporter */,
+ A276B3FA13A2872500D41A8A /* EFFImporter */,
+ A276B40013A2873700D41A8A /* FXOpcodes */,
+ A276B40613A2874700D41A8A /* GAMImporter */,
+ A276B40C13A2875400D41A8A /* GUIScript */,
+ A276B41213A2876300D41A8A /* IDSImporter */,
+ A276B41813A2877100D41A8A /* INIImporter */,
+ A276B41E13A2878400D41A8A /* ITMImporter */,
+ A276B42413A2879900D41A8A /* IWDOpcodes */,
+ A276B42A13A287AB00D41A8A /* KEYImporter */,
+ A276B43013A287BC00D41A8A /* MOSImporter */,
+ A276B44813A289E000D41A8A /* MUSImporter */,
+ A276B44E13A28A0000D41A8A /* MVEPlayer */,
+ A276B45413A28A0E00D41A8A /* NullSound */,
+ A276B45A13A28A1C00D41A8A /* OGGReader */,
+ A276B46013A28A3100D41A8A /* OpenALAudio */,
+ A276B46613A28A3F00D41A8A /* PLTImporter */,
+ A276B46C13A28A5000D41A8A /* PNGImporter */,
+ A276B47213A28A5D00D41A8A /* PROImporter */,
+ A276B47813A28A7600D41A8A /* PSTOpcodes */,
+ A276B47E13A28A8500D41A8A /* SDLAudio */,
+ A276B48413A28A9000D41A8A /* SDLVideo */,
+ A276B48A13A28A9E00D41A8A /* SPLImporter */,
+ A276B4F313A28C0400D41A8A /* STOImporter */,
+ A276B49013A28AA800D41A8A /* TISImporter */,
+ A276B49613A28AB800D41A8A /* TLKImporter */,
+ A276B49C13A28AC800D41A8A /* WAVReader */,
+ A276B4A213A28AD300D41A8A /* WEDImporter */,
+ A276B4A813A28AE100D41A8A /* WMPImporter */,
+ A276B4AE13A28AEE00D41A8A /* ZLibManager */,
+ A2F0505013ABB80B0023B7EB /* SAVImporter */,
+ A269030F142BEE2F003E8BCC /* SDLTTFFont */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 8D1107290486CEB800E47090 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A29BF85813A0427900C812DD /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2A6A45314687E55000F1688 /* GEM_ConfController-iphone.xib in Resources */,
+ A2E57ADD1475EB45005C0A29 /* GEM_ConfController-ipad.xib in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ A249187F141079510038B170 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/bash;
+ shellScript = "#xcodebuild -project GemRB.xcodeproj -target SDLVideo -configuration $CONFIGURATION";
+ };
+ A2D4C61613A978520086BCC4 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ ../gemrb/GUIScripts/,
+ ../gemrb/override/,
+ ios/GemRB.cfg,
+ ios/iTunesArtWork,
+ ios/iTunesMetadata.plist,
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "cp ios/GemRB.cfg $BUILT_PRODUCTS_DIR/\"$CONTENTS_FOLDER_PATH\"/GemRB.cfg\ncp ios/GemRB.cfg.newinstall $BUILT_PRODUCTS_DIR/\"$CONTENTS_FOLDER_PATH\"/GemRB.cfg.newinstall\ncp -r ../gemrb/GUIScripts/ $BUILT_PRODUCTS_DIR/\"$CONTENTS_FOLDER_PATH\"/GUIScripts\ncp -r ../gemrb/override/ $BUILT_PRODUCTS_DIR/\"$CONTENTS_FOLDER_PATH\"/override\n\n#make ipa\n#purge payload of everything\nrm -r ios/Payload\nmkdir ios/Payload\ncp -r $BUILT_PRODUCTS_DIR/GemRB.app ios/Payload/GemRB.app [...]
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 8D11072C0486CEB800E47090 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A24E8BAD1405AAB200FD17D1 /* GemRB.cpp in Sources */,
+ A2A6A455146880C1000F1688 /* CocoaWrapper.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A2462F0E13A036B1002D1F02 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A29BF81313A03C2600C812DD /* AREImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A2690310142BEE2F003E8BCC /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2A6A45D146893CC000F1688 /* TTFFontManager.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3C713A2867900D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4C513A28B0000D41A8A /* BIFImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3CE13A286A800D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4C613A28B0D00D41A8A /* BIKPlayer.cpp in Sources */,
+ A276B4C713A28B0D00D41A8A /* dct.cpp in Sources */,
+ A276B4C813A28B0D00D41A8A /* fft.cpp in Sources */,
+ A276B4C913A28B0D00D41A8A /* GetBitContext.cpp in Sources */,
+ A276B4CA13A28B0D00D41A8A /* mem.cpp in Sources */,
+ A276B4CB13A28B0D00D41A8A /* rational.cpp in Sources */,
+ A276B4CC13A28B0D00D41A8A /* rdft.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3D413A286BC00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4CD13A28B2000D41A8A /* BMPImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3DA13A286CD00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4CE13A28B2900D41A8A /* BMPWriter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3E013A286DE00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4CF13A28B2F00D41A8A /* CHUImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3E613A286EC00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4D013A28B3500D41A8A /* CREImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3EC13A286FB00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4D113A28B3B00D41A8A /* DirectoryImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3F213A2871300D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4D213A28B4300D41A8A /* DLGImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3F813A2872500D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4D313A28B4B00D41A8A /* EFFImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3FE13A2873700D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4D413A28B5000D41A8A /* FXOpcodes.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B40413A2874700D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4D513A28B5600D41A8A /* GAMImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B40A13A2875400D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4D613A28B5E00D41A8A /* GUIScript.cpp in Sources */,
+ A276B4D713A28B5E00D41A8A /* PythonHelpers.cpp in Sources */,
+ A27A81C4145F12CE00883469 /* CocoaWrapper.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B41013A2876300D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4D813A28B6600D41A8A /* IDSImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B41613A2877100D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4D913A28B6B00D41A8A /* INIImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B41C13A2878400D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4DA13A28B7200D41A8A /* ITMImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B42213A2879900D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4DB13A28B7D00D41A8A /* IWDOpcodes.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B42813A287AB00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4DD13A28B8500D41A8A /* KEYImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B42E13A287BC00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4DE13A28B8D00D41A8A /* MOSImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B44613A289E000D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4DF13A28B9400D41A8A /* MUSImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B44C13A28A0000D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4E013A28B9F00D41A8A /* mve_player.cpp in Sources */,
+ A276B4E113A28B9F00D41A8A /* mveaudiodec.cpp in Sources */,
+ A276B4E213A28B9F00D41A8A /* MVEPlayer.cpp in Sources */,
+ A276B4E313A28B9F00D41A8A /* mvevideodec16.cpp in Sources */,
+ A276B4E413A28B9F00D41A8A /* mvevideodec8.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B45213A28A0E00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4E513A28BA500D41A8A /* NullSound.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B45813A28A1C00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4E613A28BAC00D41A8A /* OGGReader.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B45E13A28A3100D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4E713A28BB400D41A8A /* AmbientMgrAL.cpp in Sources */,
+ A276B4E813A28BB400D41A8A /* OpenALAudio.cpp in Sources */,
+ A276B4E913A28BB400D41A8A /* StackLock.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B46413A28A3F00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4EA13A28BBC00D41A8A /* PLTImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B46A13A28A5000D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4EB13A28BC500D41A8A /* PNGImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B47013A28A5D00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4EC13A28BCC00D41A8A /* PROImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B47613A28A7600D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4ED13A28BD400D41A8A /* PSTOpcodes.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B47C13A28A8500D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4EE13A28BDB00D41A8A /* SDLAudio.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B48213A28A9000D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A22693791422934E004468E8 /* CocoaWrapper.m in Sources */,
+ A276B4EF13A28BE100D41A8A /* SDLVideo.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B48813A28A9E00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4F013A28BE800D41A8A /* SPLImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B48E13A28AA800D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4F813A28C2200D41A8A /* TISImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B49413A28AB800D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4F913A28C2900D41A8A /* TLKImporter.cpp in Sources */,
+ A276B4FA13A28C2900D41A8A /* TlkOverride.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B49A13A28AC800D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4FB13A28C3000D41A8A /* WAVReader.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B4A013A28AD300D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4FC13A28C3500D41A8A /* WEDImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B4A613A28AE100D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4FD13A28C3B00D41A8A /* WMPImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B4AC13A28AEE00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4FE13A28C4100D41A8A /* ZLibManager.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B4F113A28C0400D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4F713A28C1300D41A8A /* STOImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A27E830713A0358200B41410 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A27E831313A035C600B41410 /* 2DAImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A29BF7AF13A0380F00C812DD /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A29BF82B13A03DFC00C812DD /* BAMImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A29BF85913A0427900C812DD /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2EC807214605F4B0033754A /* CocoaWrapper.m in Sources */,
+ A29BF86613A0431300C812DD /* GemRB.cpp in Sources */,
+ A29BF8A213A04A6F00C812DD /* ActorMgr.cpp in Sources */,
+ A29BF8A313A04A6F00C812DD /* Ambient.cpp in Sources */,
+ A29BF8A413A04A6F00C812DD /* AmbientMgr.cpp in Sources */,
+ A29BF8A513A04A6F00C812DD /* Animation.cpp in Sources */,
+ A29BF8A613A04A6F00C812DD /* AnimationFactory.cpp in Sources */,
+ A29BF8A713A04A6F00C812DD /* AnimationMgr.cpp in Sources */,
+ A29BF8A813A04A6F00C812DD /* ArchiveImporter.cpp in Sources */,
+ A29BF8A913A04A6F00C812DD /* Audio.cpp in Sources */,
+ A29BF8AA13A04A6F00C812DD /* Bitmap.cpp in Sources */,
+ A29BF8AB13A04A6F00C812DD /* Cache.cpp in Sources */,
+ A29BF8AC13A04A6F00C812DD /* Calendar.cpp in Sources */,
+ A29BF8AD13A04A6F00C812DD /* Callback.cpp in Sources */,
+ A29BF8AE13A04A6F00C812DD /* CharAnimations.cpp in Sources */,
+ A29BF8AF13A04A6F00C812DD /* Compressor.cpp in Sources */,
+ A29BF8B013A04A6F00C812DD /* ControlAnimation.cpp in Sources */,
+ A29BF8B113A04A6F00C812DD /* Core.cpp in Sources */,
+ A29BF8B213A04A6F00C812DD /* DataFileMgr.cpp in Sources */,
+ A29BF8B313A04A6F00C812DD /* Dialog.cpp in Sources */,
+ A29BF8B413A04A6F00C812DD /* DialogHandler.cpp in Sources */,
+ A29BF8B513A04A6F00C812DD /* DialogMgr.cpp in Sources */,
+ A29BF8B613A04A6F00C812DD /* DisplayMessage.cpp in Sources */,
+ A29BF8B713A04A6F00C812DD /* EffectMgr.cpp in Sources */,
+ A29BF8B813A04A6F00C812DD /* EffectQueue.cpp in Sources */,
+ A29BF8B913A04A6F00C812DD /* Factory.cpp in Sources */,
+ A29BF8BA13A04A6F00C812DD /* FactoryObject.cpp in Sources */,
+ A29BF8BB13A04A6F00C812DD /* Font.cpp in Sources */,
+ A29BF8BC13A04A6F00C812DD /* Game.cpp in Sources */,
+ A29BF8BD13A04A6F00C812DD /* GameData.cpp in Sources */,
+ A29BF8BE13A04A6F00C812DD /* GlobalTimer.cpp in Sources */,
+ A29BF8BF13A04A6F00C812DD /* Image.cpp in Sources */,
+ A29BF8C013A04A6F00C812DD /* ImageFactory.cpp in Sources */,
+ A29BF8C113A04A6F00C812DD /* ImageMgr.cpp in Sources */,
+ A29BF8C213A04A6F00C812DD /* ImageWriter.cpp in Sources */,
+ A29BF8C313A04A6F00C812DD /* IniSpawn.cpp in Sources */,
+ A29BF8C413A04A6F00C812DD /* Interface.cpp in Sources */,
+ A29BF8C513A04A6F00C812DD /* Inventory.cpp in Sources */,
+ A29BF8C613A04A6F00C812DD /* Item.cpp in Sources */,
+ A29BF8C713A04A6F00C812DD /* ItemMgr.cpp in Sources */,
+ A29BF8C813A04A6F00C812DD /* LRUCache.cpp in Sources */,
+ A29BF8C913A04A6F00C812DD /* Map.cpp in Sources */,
+ A29BF8CA13A04A6F00C812DD /* MapMgr.cpp in Sources */,
+ A29BF8CB13A04A6F00C812DD /* MoviePlayer.cpp in Sources */,
+ A29BF8CC13A04A6F00C812DD /* MusicMgr.cpp in Sources */,
+ A29BF8CD13A04A6F00C812DD /* Palette.cpp in Sources */,
+ A29BF8CE13A04A6F00C812DD /* PalettedImageMgr.cpp in Sources */,
+ A29BF8CF13A04A6F00C812DD /* Particles.cpp in Sources */,
+ A29BF8D013A04A6F00C812DD /* Plugin.cpp in Sources */,
+ A29BF8D113A04A6F00C812DD /* PluginMgr.cpp in Sources */,
+ A29BF8D213A04A6F00C812DD /* Polygon.cpp in Sources */,
+ A29BF8D313A04A6F00C812DD /* Projectile.cpp in Sources */,
+ A29BF8D413A04A6F00C812DD /* ProjectileMgr.cpp in Sources */,
+ A29BF8D513A04A6F00C812DD /* ProjectileServer.cpp in Sources */,
+ A29BF8D613A04A6F00C812DD /* Region.cpp in Sources */,
+ A29BF8D713A04A6F00C812DD /* Resource.cpp in Sources */,
+ A29BF8D813A04A6F00C812DD /* ResourceDesc.cpp in Sources */,
+ A29BF8D913A04A6F00C812DD /* ResourceManager.cpp in Sources */,
+ A29BF8DA13A04A6F00C812DD /* ResourceSource.cpp in Sources */,
+ A29BF8DB13A04A6F00C812DD /* SaveGameIterator.cpp in Sources */,
+ A29BF8DC13A04A6F00C812DD /* SaveGameMgr.cpp in Sources */,
+ A29BF8DD13A04A6F00C812DD /* ScriptedAnimation.cpp in Sources */,
+ A29BF8DE13A04A6F00C812DD /* ScriptEngine.cpp in Sources */,
+ A29BF8DF13A04A6F00C812DD /* SoundMgr.cpp in Sources */,
+ A29BF8E013A04A6F00C812DD /* Spell.cpp in Sources */,
+ A29BF8E113A04A6F00C812DD /* Spellbook.cpp in Sources */,
+ A29BF8E213A04A6F00C812DD /* SpellMgr.cpp in Sources */,
+ A29BF8E313A04A6F00C812DD /* Sprite2D.cpp in Sources */,
+ A29BF8E413A04A6F00C812DD /* SpriteCover.cpp in Sources */,
+ A29BF8E513A04A6F00C812DD /* Store.cpp in Sources */,
+ A29BF8E613A04A6F00C812DD /* StoreMgr.cpp in Sources */,
+ A29BF8E713A04A6F00C812DD /* StringMgr.cpp in Sources */,
+ A29BF8E813A04A6F00C812DD /* SymbolMgr.cpp in Sources */,
+ A29BF8E913A04A6F00C812DD /* TableMgr.cpp in Sources */,
+ A29BF8EA13A04A6F00C812DD /* Tile.cpp in Sources */,
+ A29BF8EB13A04A6F00C812DD /* TileMap.cpp in Sources */,
+ A29BF8EC13A04A6F00C812DD /* TileMapMgr.cpp in Sources */,
+ A29BF8ED13A04A6F00C812DD /* TileOverlay.cpp in Sources */,
+ A29BF8EE13A04A6F00C812DD /* TileSetMgr.cpp in Sources */,
+ A29BF8EF13A04A6F00C812DD /* Variables.cpp in Sources */,
+ A29BF8F013A04A6F00C812DD /* Video.cpp in Sources */,
+ A29BF8F113A04A6F00C812DD /* WindowMgr.cpp in Sources */,
+ A29BF8F213A04A6F00C812DD /* WorldMap.cpp in Sources */,
+ A29BF8F313A04A6F00C812DD /* WorldMapMgr.cpp in Sources */,
+ A29BF8F513A04A6F00C812DD /* DataStream.cpp in Sources */,
+ A29BF8F613A04A6F00C812DD /* FileStream.cpp in Sources */,
+ A29BF8F713A04A6F00C812DD /* MemoryStream.cpp in Sources */,
+ A29BF8F913A04A6F00C812DD /* swab.c in Sources */,
+ A29BF8FA13A04A6F00C812DD /* VFS.cpp in Sources */,
+ A29BF8FB13A04A6F00C812DD /* Actor.cpp in Sources */,
+ A29BF8FC13A04A6F00C812DD /* Container.cpp in Sources */,
+ A29BF8FD13A04A6F00C812DD /* Door.cpp in Sources */,
+ A29BF8FE13A04A6F00C812DD /* InfoPoint.cpp in Sources */,
+ A29BF8FF13A04A6F00C812DD /* PCStatStruct.cpp in Sources */,
+ A29BF90013A04A6F00C812DD /* Scriptable.cpp in Sources */,
+ A29BF90113A04A6F00C812DD /* Button.cpp in Sources */,
+ A29BF90213A04A6F00C812DD /* Console.cpp in Sources */,
+ A29BF90313A04A6F00C812DD /* Control.cpp in Sources */,
+ A29BF90413A04A6F00C812DD /* EventMgr.cpp in Sources */,
+ A29BF90513A04A6F00C812DD /* GameControl.cpp in Sources */,
+ A29BF90613A04A6F00C812DD /* Label.cpp in Sources */,
+ A29BF90713A04A6F00C812DD /* MapControl.cpp in Sources */,
+ A29BF90813A04A6F00C812DD /* Progressbar.cpp in Sources */,
+ A29BF90913A04A6F00C812DD /* ScrollBar.cpp in Sources */,
+ A29BF90A13A04A6F00C812DD /* Slider.cpp in Sources */,
+ A29BF90B13A04A6F00C812DD /* TextArea.cpp in Sources */,
+ A29BF90C13A04A6F00C812DD /* TextEdit.cpp in Sources */,
+ A29BF90D13A04A6F00C812DD /* Window.cpp in Sources */,
+ A29BF90E13A04A6F00C812DD /* WorldMapControl.cpp in Sources */,
+ A29BF90F13A04A6F00C812DD /* Actions.cpp in Sources */,
+ A29BF91013A04A6F00C812DD /* GameScript.cpp in Sources */,
+ A29BF91113A04A6F00C812DD /* GSUtils.cpp in Sources */,
+ A29BF91213A04A6F00C812DD /* Matching.cpp in Sources */,
+ A29BF91313A04A6F00C812DD /* Objects.cpp in Sources */,
+ A29BF91413A04A6F00C812DD /* Triggers.cpp in Sources */,
+ A226F41013A119D8009CE75E /* 2DAImporter.cpp in Sources */,
+ A226F41113A119E2009CE75E /* ACMReader.cpp in Sources */,
+ A226F41213A119E2009CE75E /* decoder.cpp in Sources */,
+ A226F41313A119E2009CE75E /* unpacker.cpp in Sources */,
+ A226F41713A119EA009CE75E /* AREImporter.cpp in Sources */,
+ A226F41813A119F1009CE75E /* BAMImporter.cpp in Sources */,
+ A226F41913A119F6009CE75E /* BIFImporter.cpp in Sources */,
+ A226F41A13A11A00009CE75E /* BIKPlayer.cpp in Sources */,
+ A226F41B13A11A00009CE75E /* dct.cpp in Sources */,
+ A226F41C13A11A00009CE75E /* fft.cpp in Sources */,
+ A226F41D13A11A00009CE75E /* GetBitContext.cpp in Sources */,
+ A226F41E13A11A00009CE75E /* mem.cpp in Sources */,
+ A226F41F13A11A00009CE75E /* rational.cpp in Sources */,
+ A226F42013A11A00009CE75E /* rdft.cpp in Sources */,
+ A226F42113A11A07009CE75E /* BMPImporter.cpp in Sources */,
+ A226F42213A11A0C009CE75E /* BMPWriter.cpp in Sources */,
+ A226F42313A11A11009CE75E /* CHUImporter.cpp in Sources */,
+ A226F42413A11A17009CE75E /* CREImporter.cpp in Sources */,
+ A226F42513A11A1C009CE75E /* DirectoryImporter.cpp in Sources */,
+ A226F42613A11A22009CE75E /* DLGImporter.cpp in Sources */,
+ A226F42713A11A27009CE75E /* EFFImporter.cpp in Sources */,
+ A226F42813A11A2C009CE75E /* FXOpcodes.cpp in Sources */,
+ A226F42913A11A31009CE75E /* GAMImporter.cpp in Sources */,
+ A226F42A13A11A39009CE75E /* GUIScript.cpp in Sources */,
+ A226F42B13A11A39009CE75E /* PythonHelpers.cpp in Sources */,
+ A226F42C13A11A3F009CE75E /* IDSImporter.cpp in Sources */,
+ A226F42D13A11A44009CE75E /* INIImporter.cpp in Sources */,
+ A226F42E13A11A49009CE75E /* ITMImporter.cpp in Sources */,
+ A226F42F13A11A4E009CE75E /* IWDOpcodes.cpp in Sources */,
+ A226F43113A11A53009CE75E /* KEYImporter.cpp in Sources */,
+ A226F43213A11A58009CE75E /* MOSImporter.cpp in Sources */,
+ A226F43313A11A5E009CE75E /* MUSImporter.cpp in Sources */,
+ A226F43413A11A66009CE75E /* mve_player.cpp in Sources */,
+ A226F43513A11A66009CE75E /* mveaudiodec.cpp in Sources */,
+ A226F43613A11A66009CE75E /* MVEPlayer.cpp in Sources */,
+ A226F43713A11A66009CE75E /* mvevideodec16.cpp in Sources */,
+ A226F43813A11A66009CE75E /* mvevideodec8.cpp in Sources */,
+ A226F43E13A11A7E009CE75E /* PLTImporter.cpp in Sources */,
+ A226F44013A11A8D009CE75E /* PROImporter.cpp in Sources */,
+ A226F44113A11A94009CE75E /* PSTOpcodes.cpp in Sources */,
+ A226F44413A11AA3009CE75E /* SPLImporter.cpp in Sources */,
+ A226F44513A11AA8009CE75E /* STOImporter.cpp in Sources */,
+ A226F44613A11AAC009CE75E /* TISImporter.cpp in Sources */,
+ A226F44713A11AB4009CE75E /* TLKImporter.cpp in Sources */,
+ A226F44813A11AB4009CE75E /* TlkOverride.cpp in Sources */,
+ A226F44913A11AB9009CE75E /* WAVReader.cpp in Sources */,
+ A226F44A13A11ABE009CE75E /* WEDImporter.cpp in Sources */,
+ A226F44B13A11AC3009CE75E /* WMPImporter.cpp in Sources */,
+ A226F44C13A11AC8009CE75E /* ZLibManager.cpp in Sources */,
+ A2AAF33A13A14A4500AE8402 /* SDLVideo.cpp in Sources */,
+ A265ECDC13A8661600C6DF12 /* FileCache.cpp in Sources */,
+ A265ECDD13A8661600C6DF12 /* IndexedArchive.cpp in Sources */,
+ A265ECDE13A8661600C6DF12 /* KeyMap.cpp in Sources */,
+ A265ECDF13A8661600C6DF12 /* PluginLoader.cpp in Sources */,
+ A265ECED13A8669700C6DF12 /* Logging.cpp in Sources */,
+ A265ECEE13A8669700C6DF12 /* SlicedStream.cpp in Sources */,
+ A265ECEF13A8669700C6DF12 /* String.cpp in Sources */,
+ A27979AF13ABA509009A6FEF /* SAVImporter.cpp in Sources */,
+ A20C698013B0FA430082EEBA /* AmbientMgrAL.cpp in Sources */,
+ A20C698113B0FA430082EEBA /* OpenALAudio.cpp in Sources */,
+ A20C698213B0FA430082EEBA /* StackLock.cpp in Sources */,
+ A28D249A143BEA4200A27897 /* FontManager.cpp in Sources */,
+ A2A6A45214687E55000F1688 /* GEM_ConfController.m in Sources */,
+ A2A6A456146880C1000F1688 /* CocoaWrapper.m in Sources */,
+ A2A6A45C146893CC000F1688 /* TTFFontManager.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A2E66335139E875400310FC8 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A23EBFFA141979D500CC049E /* KeyMap.cpp in Sources */,
+ A208210D1419712F002CD244 /* String.cpp in Sources */,
+ A208210E1419712F002CD244 /* IndexedArchive.cpp in Sources */,
+ A20821101419712F002CD244 /* PluginLoader.cpp in Sources */,
+ A20821111419712F002CD244 /* MemoryStream.cpp in Sources */,
+ A2E6634E139E882900310FC8 /* ActorMgr.cpp in Sources */,
+ A2E66350139E882900310FC8 /* Ambient.cpp in Sources */,
+ A2E66352139E882900310FC8 /* AmbientMgr.cpp in Sources */,
+ A2E66354139E882900310FC8 /* Animation.cpp in Sources */,
+ A2E66356139E882900310FC8 /* AnimationFactory.cpp in Sources */,
+ A2E66358139E883100310FC8 /* AnimationMgr.cpp in Sources */,
+ A2E6635B139E883100310FC8 /* ArchiveImporter.cpp in Sources */,
+ A2E6635D139E883100310FC8 /* Audio.cpp in Sources */,
+ A2E6635F139E883100310FC8 /* Bitmap.cpp in Sources */,
+ A2E66361139E883100310FC8 /* Cache.cpp in Sources */,
+ A2E66363139E883100310FC8 /* Calendar.cpp in Sources */,
+ A2E66365139E883100310FC8 /* Callback.cpp in Sources */,
+ A2E66367139E883100310FC8 /* CharAnimations.cpp in Sources */,
+ A2E66369139E883100310FC8 /* Compressor.cpp in Sources */,
+ A2E6636B139E883100310FC8 /* ControlAnimation.cpp in Sources */,
+ A2E6636D139E883100310FC8 /* Core.cpp in Sources */,
+ A2E6636F139E883100310FC8 /* DataFileMgr.cpp in Sources */,
+ A2E66371139E883100310FC8 /* Dialog.cpp in Sources */,
+ A2E66373139E883100310FC8 /* DialogHandler.cpp in Sources */,
+ A2E66375139E883100310FC8 /* DialogMgr.cpp in Sources */,
+ A2E66377139E883100310FC8 /* DisplayMessage.cpp in Sources */,
+ A2E6637A139E883100310FC8 /* EffectMgr.cpp in Sources */,
+ A2E6637C139E883100310FC8 /* EffectQueue.cpp in Sources */,
+ A2E6637E139E883100310FC8 /* Factory.cpp in Sources */,
+ A2E66380139E883100310FC8 /* FactoryObject.cpp in Sources */,
+ A2E66382139E883100310FC8 /* Font.cpp in Sources */,
+ A2E66384139E883100310FC8 /* Game.cpp in Sources */,
+ A2E66386139E883100310FC8 /* GameData.cpp in Sources */,
+ A2E66388139E883700310FC8 /* GlobalTimer.cpp in Sources */,
+ A2E6638B139E883E00310FC8 /* Image.cpp in Sources */,
+ A2E6638D139E883E00310FC8 /* ImageFactory.cpp in Sources */,
+ A2E6638F139E883E00310FC8 /* ImageMgr.cpp in Sources */,
+ A2E66391139E883E00310FC8 /* ImageWriter.cpp in Sources */,
+ A2E66393139E883E00310FC8 /* IniSpawn.cpp in Sources */,
+ A2E66395139E883E00310FC8 /* Interface.cpp in Sources */,
+ A2E66397139E883E00310FC8 /* Inventory.cpp in Sources */,
+ A2E66399139E883E00310FC8 /* Item.cpp in Sources */,
+ A2E6639B139E883E00310FC8 /* ItemMgr.cpp in Sources */,
+ A2E6639D139E883E00310FC8 /* LRUCache.cpp in Sources */,
+ A2E6639F139E883E00310FC8 /* Map.cpp in Sources */,
+ A2E663A1139E883E00310FC8 /* MapMgr.cpp in Sources */,
+ A2E663A3139E883E00310FC8 /* MoviePlayer.cpp in Sources */,
+ A2E663A5139E883E00310FC8 /* MusicMgr.cpp in Sources */,
+ A2E663A7139E883E00310FC8 /* Palette.cpp in Sources */,
+ A2E663A9139E883E00310FC8 /* PalettedImageMgr.cpp in Sources */,
+ A2E663AB139E883E00310FC8 /* Particles.cpp in Sources */,
+ A2E663AE139E883E00310FC8 /* Plugin.cpp in Sources */,
+ A2E663B0139E883E00310FC8 /* PluginMgr.cpp in Sources */,
+ A2E663B2139E883E00310FC8 /* Polygon.cpp in Sources */,
+ A2E663B5139E883E00310FC8 /* Projectile.cpp in Sources */,
+ A2E663B7139E883E00310FC8 /* ProjectileMgr.cpp in Sources */,
+ A2E663B9139E883E00310FC8 /* ProjectileServer.cpp in Sources */,
+ A2E663BB139E883E00310FC8 /* Region.cpp in Sources */,
+ A2E663BD139E883E00310FC8 /* Resource.cpp in Sources */,
+ A2E663BF139E883E00310FC8 /* ResourceDesc.cpp in Sources */,
+ A2E663C1139E883E00310FC8 /* ResourceManager.cpp in Sources */,
+ A2E663C3139E883E00310FC8 /* ResourceSource.cpp in Sources */,
+ A2E663C6139E883E00310FC8 /* SaveGameIterator.cpp in Sources */,
+ A2E663C8139E883E00310FC8 /* SaveGameMgr.cpp in Sources */,
+ A2E663CA139E884500310FC8 /* ScriptedAnimation.cpp in Sources */,
+ A2E663CC139E884500310FC8 /* ScriptEngine.cpp in Sources */,
+ A2E663CE139E884500310FC8 /* SoundMgr.cpp in Sources */,
+ A2E663D0139E884500310FC8 /* Spell.cpp in Sources */,
+ A2E663D2139E884500310FC8 /* Spellbook.cpp in Sources */,
+ A2E663D4139E884500310FC8 /* SpellMgr.cpp in Sources */,
+ A2E663D6139E884500310FC8 /* Sprite2D.cpp in Sources */,
+ A2E663D8139E884500310FC8 /* SpriteCover.cpp in Sources */,
+ A2E663DA139E884500310FC8 /* Store.cpp in Sources */,
+ A2E663DC139E884500310FC8 /* StoreMgr.cpp in Sources */,
+ A2E663DE139E884500310FC8 /* StringMgr.cpp in Sources */,
+ A2E663E0139E884500310FC8 /* SymbolMgr.cpp in Sources */,
+ A2E663E2139E884B00310FC8 /* TableMgr.cpp in Sources */,
+ A2E663E4139E884B00310FC8 /* Tile.cpp in Sources */,
+ A2E663E6139E884B00310FC8 /* TileMap.cpp in Sources */,
+ A2E663E8139E884B00310FC8 /* TileMapMgr.cpp in Sources */,
+ A2E663EA139E884B00310FC8 /* TileOverlay.cpp in Sources */,
+ A2E663EC139E884B00310FC8 /* TileSetMgr.cpp in Sources */,
+ A2E663EF139E884B00310FC8 /* Variables.cpp in Sources */,
+ A2E663F1139E884B00310FC8 /* Video.cpp in Sources */,
+ A2E663F4139E884B00310FC8 /* WindowMgr.cpp in Sources */,
+ A2E663F6139E884B00310FC8 /* WorldMap.cpp in Sources */,
+ A2E663F8139E884B00310FC8 /* WorldMapMgr.cpp in Sources */,
+ A2E663FC139E885300310FC8 /* DataStream.cpp in Sources */,
+ A2E663FE139E885300310FC8 /* FileStream.cpp in Sources */,
+ A2E66404139E885300310FC8 /* swab.c in Sources */,
+ A2E66406139E885300310FC8 /* VFS.cpp in Sources */,
+ A2E66408139E885A00310FC8 /* Actor.cpp in Sources */,
+ A2E6640A139E885A00310FC8 /* Container.cpp in Sources */,
+ A2E6640C139E885A00310FC8 /* Door.cpp in Sources */,
+ A2E6640E139E885A00310FC8 /* InfoPoint.cpp in Sources */,
+ A2E66410139E885A00310FC8 /* PCStatStruct.cpp in Sources */,
+ A2E66412139E885A00310FC8 /* Scriptable.cpp in Sources */,
+ A2E66414139E886100310FC8 /* Button.cpp in Sources */,
+ A2E66416139E886100310FC8 /* Console.cpp in Sources */,
+ A2E66419139E886100310FC8 /* Control.cpp in Sources */,
+ A2E6641B139E886100310FC8 /* EventMgr.cpp in Sources */,
+ A2E6641D139E886100310FC8 /* GameControl.cpp in Sources */,
+ A2E6641F139E886100310FC8 /* Label.cpp in Sources */,
+ A2E66421139E886100310FC8 /* MapControl.cpp in Sources */,
+ A2E66423139E886100310FC8 /* Progressbar.cpp in Sources */,
+ A2E66425139E886100310FC8 /* ScrollBar.cpp in Sources */,
+ A2E66427139E886100310FC8 /* Slider.cpp in Sources */,
+ A2E66429139E886100310FC8 /* TextArea.cpp in Sources */,
+ A2E6642B139E886100310FC8 /* TextEdit.cpp in Sources */,
+ A2E6642D139E886100310FC8 /* Window.cpp in Sources */,
+ A2E6642F139E886100310FC8 /* WorldMapControl.cpp in Sources */,
+ A2E66431139E886700310FC8 /* Actions.cpp in Sources */,
+ A2E66432139E886700310FC8 /* GameScript.cpp in Sources */,
+ A2E66434139E886700310FC8 /* GSUtils.cpp in Sources */,
+ A2E66436139E886700310FC8 /* Matching.cpp in Sources */,
+ A2E66438139E886700310FC8 /* Objects.cpp in Sources */,
+ A2E66439139E886700310FC8 /* Triggers.cpp in Sources */,
+ A265ECE013A8661600C6DF12 /* FileCache.cpp in Sources */,
+ A265ECF013A8669700C6DF12 /* Logging.cpp in Sources */,
+ A265ECF113A8669700C6DF12 /* SlicedStream.cpp in Sources */,
+ A28D2499143BEA4200A27897 /* FontManager.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A2F0504E13ABB80B0023B7EB /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2F0505613ABB82D0023B7EB /* SAVImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A2FCD5F813A0366100271997 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A226F41413A119E5009CE75E /* ACMReader.cpp in Sources */,
+ A226F41513A119E5009CE75E /* decoder.cpp in Sources */,
+ A226F41613A119E5009CE75E /* unpacker.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ A2375BA113AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A27E830913A0358200B41410 /* 2DAImporter */;
+ targetProxy = A2375BA013AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BA313AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A2FCD5FA13A0366100271997 /* ACMReader */;
+ targetProxy = A2375BA213AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BA513AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A2462F1013A036B1002D1F02 /* AREImporter */;
+ targetProxy = A2375BA413AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BA713AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A29BF7B113A0380F00C812DD /* BAMImporter */;
+ targetProxy = A2375BA613AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BA913AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B3C913A2867900D41A8A /* BIFImporter */;
+ targetProxy = A2375BA813AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BAB13AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B3D013A286A800D41A8A /* BIKPlayer */;
+ targetProxy = A2375BAA13AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BAD13AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B3D613A286BC00D41A8A /* BMPImporter */;
+ targetProxy = A2375BAC13AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BAF13AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B3DC13A286CD00D41A8A /* BMPWriter */;
+ targetProxy = A2375BAE13AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BB113AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B3E213A286DE00D41A8A /* CHUImporter */;
+ targetProxy = A2375BB013AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BB313AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B3E813A286EC00D41A8A /* CREImporter */;
+ targetProxy = A2375BB213AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BB513AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B3EE13A286FB00D41A8A /* DirectoryImporter */;
+ targetProxy = A2375BB413AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BB713AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B3F413A2871300D41A8A /* DLGImporter */;
+ targetProxy = A2375BB613AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BB913AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B3FA13A2872500D41A8A /* EFFImporter */;
+ targetProxy = A2375BB813AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BBB13AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B40013A2873700D41A8A /* FXOpcodes */;
+ targetProxy = A2375BBA13AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BBD13AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B40613A2874700D41A8A /* GAMImporter */;
+ targetProxy = A2375BBC13AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BBF13AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B40C13A2875400D41A8A /* GUIScript */;
+ targetProxy = A2375BBE13AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BC113AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B41213A2876300D41A8A /* IDSImporter */;
+ targetProxy = A2375BC013AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BC313AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B41813A2877100D41A8A /* INIImporter */;
+ targetProxy = A2375BC213AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BC513AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B41E13A2878400D41A8A /* ITMImporter */;
+ targetProxy = A2375BC413AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BC713AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B42413A2879900D41A8A /* IWDOpcodes */;
+ targetProxy = A2375BC613AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BC913AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B42A13A287AB00D41A8A /* KEYImporter */;
+ targetProxy = A2375BC813AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BCB13AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B43013A287BC00D41A8A /* MOSImporter */;
+ targetProxy = A2375BCA13AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BCD13AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B44813A289E000D41A8A /* MUSImporter */;
+ targetProxy = A2375BCC13AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BCF13AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B44E13A28A0000D41A8A /* MVEPlayer */;
+ targetProxy = A2375BCE13AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BD113AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B45413A28A0E00D41A8A /* NullSound */;
+ targetProxy = A2375BD013AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BD313AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B46013A28A3100D41A8A /* OpenALAudio */;
+ targetProxy = A2375BD213AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BD513AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B46613A28A3F00D41A8A /* PLTImporter */;
+ targetProxy = A2375BD413AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BD713AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B47213A28A5D00D41A8A /* PROImporter */;
+ targetProxy = A2375BD613AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BD913AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B47813A28A7600D41A8A /* PSTOpcodes */;
+ targetProxy = A2375BD813AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BDD13AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B48A13A28A9E00D41A8A /* SPLImporter */;
+ targetProxy = A2375BDC13AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BDF13AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B4F313A28C0400D41A8A /* STOImporter */;
+ targetProxy = A2375BDE13AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BE113AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B49013A28AA800D41A8A /* TISImporter */;
+ targetProxy = A2375BE013AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BE313AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B49613A28AB800D41A8A /* TLKImporter */;
+ targetProxy = A2375BE213AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BE513AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B49C13A28AC800D41A8A /* WAVReader */;
+ targetProxy = A2375BE413AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BE713AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B4A213A28AD300D41A8A /* WEDImporter */;
+ targetProxy = A2375BE613AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BE913AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B4A813A28AE100D41A8A /* WMPImporter */;
+ targetProxy = A2375BE813AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BEB13AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B4AE13A28AEE00D41A8A /* ZLibManager */;
+ targetProxy = A2375BEA13AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A23EBFFC1419A81500CC049E /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A2F0505013ABB80B0023B7EB /* SAVImporter */;
+ targetProxy = A23EBFFB1419A81500CC049E /* PBXContainerItemProxy */;
+ };
+ A259F3FA142BFC4100D49124 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A269030F142BEE2F003E8BCC /* SDLTTFFont */;
+ targetProxy = A259F3F9142BFC4100D49124 /* PBXContainerItemProxy */;
+ };
+ A2E6633C139E876900310FC8 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A2E66337139E875400310FC8 /* gemrb_core */;
+ targetProxy = A2E6633B139E876900310FC8 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 089C165DFE840E0CC02AAC07 /* English */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ A2462F1213A036B2002D1F02 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = AREImporter;
+ SDKROOT = macosx;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A2462F1313A036B2002D1F02 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = AREImporter;
+ SDKROOT = macosx;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A2690315142BEE2F003E8BCC /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ HEADER_SEARCH_PATHS = (
+ /Library/Frameworks/SDL_ttf.framework/Headers,
+ /Library/Frameworks/SDL.framework/Headers,
+ "$(HEADER_SEARCH_PATHS)",
+ ../gemrb/includes,
+ );
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = TTFImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A2690316142BEE2F003E8BCC /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ HEADER_SEARCH_PATHS = (
+ /Library/Frameworks/SDL_ttf.framework/Headers,
+ /Library/Frameworks/SDL.framework/Headers,
+ "$(HEADER_SEARCH_PATHS)",
+ ../gemrb/includes,
+ );
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = TTFImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Release;
+ };
+ A276B3CB13A2867900D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = BIFImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B3CC13A2867900D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = BIFImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B3D213A286A800D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = BIKPlayer;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B3D313A286A800D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = BIKPlayer;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B3D813A286BD00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = BMPImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B3D913A286BD00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = BMPImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B3DE13A286CD00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = BMPWriter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B3DF13A286CD00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = BMPWriter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B3E413A286DE00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = CHUImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B3E513A286DE00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = CHUImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B3EA13A286ED00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = CREImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B3EB13A286ED00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = CREImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B3F013A286FB00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = DirectoryImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B3F113A286FB00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = DirectoryImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B3F613A2871400D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = DLGImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B3F713A2871400D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = DLGImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B3FC13A2872600D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = EFFImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B3FD13A2872600D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = EFFImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B40213A2873700D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = FXOpcodes;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B40313A2873700D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = FXOpcodes;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B40813A2874800D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = GAMImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B40913A2874800D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = GAMImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B40E13A2875500D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ HEADER_SEARCH_PATHS = (
+ /System/Library/Frameworks/Python.framework/Headers,
+ "$(HEADER_SEARCH_PATHS)",
+ );
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = GUIScript;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B40F13A2875500D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ HEADER_SEARCH_PATHS = (
+ /System/Library/Frameworks/Python.framework/Headers,
+ "$(HEADER_SEARCH_PATHS)",
+ );
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = GUIScript;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B41413A2876400D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = IDSImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B41513A2876400D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = IDSImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B41A13A2877100D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = INIImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B41B13A2877100D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = INIImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B42013A2878400D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = ITMImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B42113A2878400D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = ITMImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B42613A2879A00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = IWDOpcodes;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B42713A2879A00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = IWDOpcodes;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B42C13A287AB00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = KEYImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B42D13A287AB00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = KEYImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B43213A287BD00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = MOSImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B43313A287BD00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = MOSImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B44A13A289E100D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = MUSImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B44B13A289E100D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = MUSImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B45013A28A0100D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = MVEPlayer;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B45113A28A0100D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = MVEPlayer;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B45613A28A0F00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = NullSound;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B45713A28A0F00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = NullSound;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B45C13A28A1C00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = OGGReader;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B45D13A28A1C00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = OGGReader;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B46213A28A3100D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = YES;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(FRAMEWORK_SEARCH_PATHS)",
+ /Library/Frameworks/,
+ );
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ "GCC_VERSION[arch=x86_64]" = "";
+ HEADER_SEARCH_PATHS = /Library/Frameworks/SDL.framework/Headers;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = OpenALAudio;
+ USER_HEADER_SEARCH_PATHS = "./ ../gemrb/ ../gemrb/core/";
+ };
+ name = Debug;
+ };
+ A276B46313A28A3100D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = YES;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(FRAMEWORK_SEARCH_PATHS)",
+ /Library/Frameworks/,
+ );
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ "GCC_VERSION[arch=x86_64]" = "";
+ HEADER_SEARCH_PATHS = /Library/Frameworks/SDL.framework/Headers;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ OTHER_CFLAGS = "";
+ PRODUCT_NAME = OpenALAudio;
+ USER_HEADER_SEARCH_PATHS = "./ ../gemrb/ ../gemrb/core/";
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B46813A28A3F00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = PLTImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B46913A28A3F00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = PLTImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B46E13A28A5000D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = PNGImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B46F13A28A5000D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = PNGImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B47413A28A5D00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = PROImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B47513A28A5D00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = PROImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B47A13A28A7600D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = PSTOpcodes;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B47B13A28A7600D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = PSTOpcodes;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B48013A28A8500D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ HEADER_SEARCH_PATHS = (
+ /Library/Frameworks/SDL.framework/Headers,
+ "$(HEADER_SEARCH_PATHS)",
+ );
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = SDLAudio;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B48113A28A8500D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ HEADER_SEARCH_PATHS = (
+ /Library/Frameworks/SDL.framework/Headers,
+ "$(HEADER_SEARCH_PATHS)",
+ );
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = SDLAudio;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B48613A28A9000D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = YES;
+ BUNDLE_LOADER = "/Users/brada/Library/Developer/Xcode/DerivedData/GemRB-gjmmnczugayburckvrfrsukvyxvk/Build/Products/Debug/GemRB.app/Contents/MacOS/GemRB";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ HEADER_SEARCH_PATHS = (
+ /Library/Frameworks/SDL.framework/Headers,
+ "$(HEADER_SEARCH_PATHS)",
+ );
+ INSTALL_PATH = "$(HOME)/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ OTHER_CFLAGS = (
+ "-isystem",
+ ./,
+ );
+ PRODUCT_NAME = SDLVideo;
+ UNEXPORTED_SYMBOLS_FILE = "";
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ VALID_ARCHS = "i386 x86_64";
+ };
+ name = Debug;
+ };
+ A276B48713A28A9000D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = YES;
+ BUNDLE_LOADER = "/Users/brada/Library/Developer/Xcode/DerivedData/GemRB-gjmmnczugayburckvrfrsukvyxvk/Build/Products/Debug/GemRB.app/Contents/MacOS/GemRB";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ HEADER_SEARCH_PATHS = (
+ /Library/Frameworks/SDL.framework/Headers,
+ "$(HEADER_SEARCH_PATHS)",
+ );
+ INSTALL_PATH = "$(HOME)/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ OTHER_CFLAGS = (
+ "-isystem",
+ ./,
+ );
+ PRODUCT_NAME = SDLVideo;
+ UNEXPORTED_SYMBOLS_FILE = "";
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ VALID_ARCHS = "i386 x86_64";
+ };
+ name = Release;
+ };
+ A276B48C13A28A9E00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = SPLImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B48D13A28A9E00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = SPLImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B49213A28AA900D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = TISImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B49313A28AA900D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = TISImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B49813A28AB800D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = TLKImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B49913A28AB800D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = TLKImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B49E13A28AC800D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = WAVReader;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B49F13A28AC800D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = WAVReader;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B4A413A28AD300D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = WEDImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B4A513A28AD300D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = WEDImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B4AA13A28AE100D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = WMPImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B4AB13A28AE100D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = WMPImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B4B013A28AEE00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = ZLibManager;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B4B113A28AEE00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = ZLibManager;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A276B4F513A28C0500D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = STOImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A276B4F613A28C0500D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = STOImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A27E830B13A0358300B41410 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = 2DAImporter;
+ SDKROOT = macosx;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ VALID_ARCHS = "i386 x86_64";
+ };
+ name = Debug;
+ };
+ A27E830C13A0358300B41410 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = 2DAImporter;
+ SDKROOT = macosx;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ VALID_ARCHS = "i386 x86_64";
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A29BF7B313A0380F00C812DD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = BAMImporter;
+ SDKROOT = macosx;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A29BF7B413A0380F00C812DD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = BAMImporter;
+ SDKROOT = macosx;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A29BF85E13A0427A00C812DD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEPLOYMENT_POSTPROCESSING = YES;
+ FRAMEWORK_SEARCH_PATHS = "";
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = GemRB_Prefix.pch;
+ GCC_VERSION = "";
+ "GCC_VERSION[arch=x86_64]" = "";
+ GCC_WARN_ABOUT_MISSING_NEWLINE = NO;
+ GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
+ GCC_WARN_UNUSED_PARAMETER = NO;
+ HEADER_SEARCH_PATHS = (
+ ./,
+ ios/Python/Include,
+ ios/SDL/include,
+ ../gemrb/includes,
+ );
+ INFOPLIST_FILE = ios/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 4.3;
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"$(SRCROOT)/ios/SDL\"",
+ "\"$(SRCROOT)/ios/Python\"",
+ "\"$(SRCROOT)/ios\"",
+ );
+ OTHER_CFLAGS = (
+ "-DTARGET_OS_IPHONE",
+ "-isystem",
+ ./ios/Python/Include/,
+ "-isystem",
+ ./ios/SDL/Include/,
+ "-DSTATIC_LINK",
+ "$(OTHER_CFLAGS)",
+ );
+ PRODUCT_NAME = GemRB;
+ PROVISIONING_PROFILE = "";
+ SDKROOT = iphoneos;
+ "SDKROOT[arch=*]" = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ USER_HEADER_SEARCH_PATHS = "./ ../gemrb/includes/ ../gemrb/core/";
+ VALID_ARCHS = armv7;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Debug;
+ };
+ A29BF85F13A0427A00C812DD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEPLOYMENT_POSTPROCESSING = YES;
+ FRAMEWORK_SEARCH_PATHS = "";
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = GemRB_Prefix.pch;
+ GCC_VERSION = "";
+ "GCC_VERSION[arch=x86_64]" = "";
+ GCC_WARN_ABOUT_MISSING_NEWLINE = NO;
+ GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
+ GCC_WARN_UNUSED_PARAMETER = NO;
+ HEADER_SEARCH_PATHS = (
+ ./,
+ ios/Python/Include,
+ ios/SDL/include,
+ ../gemrb/includes,
+ );
+ INFOPLIST_FILE = ios/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 4.3;
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"$(SRCROOT)/ios/SDL\"",
+ "\"$(SRCROOT)/ios/Python\"",
+ "\"$(SRCROOT)/ios\"",
+ );
+ OTHER_CFLAGS = (
+ "-isystem",
+ ./ios/SDL/Include/,
+ "-isystem",
+ ./ios/Python/Include/,
+ "-DSTATIC_LINK",
+ "$(OTHER_CFLAGS)",
+ "-DTARGET_OS_IPHONE",
+ );
+ PRODUCT_NAME = GemRB;
+ PROVISIONING_PROFILE = "";
+ SDKROOT = iphoneos;
+ "SDKROOT[arch=*]" = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ USER_HEADER_SEARCH_PATHS = "./ ../gemrb/includes/ ../gemrb/core/";
+ VALID_ARCHS = armv7;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Release;
+ };
+ A2E66339139E875500310FC8 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ COPY_PHASE_STRIP = NO;
+ EXECUTABLE_PREFIX = lib;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = core.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
+ HEADER_SEARCH_PATHS = (
+ ../gemrb/core,
+ "$(HOME)/Library/Frameworks/SDL.framework/Headers",
+ /Library/Frameworks/SDL.framework/Headers,
+ "$(HEADER_SEARCH_PATHS)",
+ );
+ INSTALL_PATH = /usr/local/lib;
+ PRODUCT_NAME = gemrb_core;
+ SDKROOT = macosx;
+ VALID_ARCHS = "i386 x86_64";
+ };
+ name = Debug;
+ };
+ A2E6633A139E875500310FC8 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ EXECUTABLE_PREFIX = lib;
+ GCC_MODEL_TUNING = G5;
+ GCC_PREFIX_HEADER = core.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
+ HEADER_SEARCH_PATHS = (
+ ../gemrb/core,
+ "$(HOME)/Library/Frameworks/SDL.framework/Headers",
+ /Library/Frameworks/SDL.framework/Headers,
+ "$(HEADER_SEARCH_PATHS)",
+ );
+ INSTALL_PATH = /usr/local/lib;
+ PRODUCT_NAME = gemrb_core;
+ SDKROOT = macosx;
+ VALID_ARCHS = "i386 x86_64";
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A2F0505213ABB80C0023B7EB /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = osx/plugins.pch;
+ PRODUCT_NAME = SAVImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A2F0505313ABB80C0023B7EB /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = osx/plugins.pch;
+ PRODUCT_NAME = SAVImporter;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A2FCD5FC13A0366100271997 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = ACMReader;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ };
+ name = Debug;
+ };
+ A2FCD5FD13A0366100271997 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUNDLE_LOADER = "";
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_PREFIX_HEADER = osx/plugins.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PREFIX_HEADER = plugins.pch;
+ PRODUCT_NAME = ACMReader;
+ USER_HEADER_SEARCH_PATHS = ../gemrb/core;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ C01FCF4B08A954540054247B /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = YES;
+ CODE_SIGN_IDENTITY = "";
+ COPY_PHASE_STRIP = NO;
+ EXPORTED_SYMBOLS_FILE = "";
+ FRAMEWORK_SEARCH_PATHS = (
+ /Library/Frameworks,
+ /System/Library/Frameworks,
+ "$(FRAMEWORK_SEARCH_PATHS)",
+ );
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_INPUT_FILETYPE = automatic;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "";
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ "GCC_VERSION[arch=i386]" = "";
+ "GCC_VERSION[arch=x86_64]" = "";
+ GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
+ GENERATE_MASTER_OBJECT_FILE = NO;
+ HEADER_SEARCH_PATHS = (
+ /Library/Frameworks/SDL.framework/Headers,
+ "$(HEADER_SEARCH_PATHS)",
+ ../gemrb/core,
+ osx/,
+ ./,
+ );
+ INFOPLIST_FILE = osx/Info.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ LINKER_DISPLAYS_MANGLED_NAMES = NO;
+ ONLY_ACTIVE_ARCH = NO;
+ OTHER_CFLAGS = (
+ "-D_DEBUG",
+ "-DTARGET_OS_MAC",
+ "-g",
+ );
+ OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
+ OTHER_LDFLAGS = "";
+ PRODUCT_NAME = GemRB;
+ SDKROOT = "";
+ "SDKROOT[arch=x86_64]" = "";
+ VALID_ARCHS = "i386 x86_64";
+ WRAPPER_EXTENSION = app;
+ };
+ name = Debug;
+ };
+ C01FCF4C08A954540054247B /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = YES;
+ CODE_SIGN_IDENTITY = "";
+ COPY_PHASE_STRIP = NO;
+ EXPORTED_SYMBOLS_FILE = "";
+ FRAMEWORK_SEARCH_PATHS = (
+ /System/Library/Frameworks,
+ "$(FRAMEWORK_SEARCH_PATHS)",
+ );
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ GCC_INPUT_FILETYPE = automatic;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "";
+ GCC_SYMBOLS_PRIVATE_EXTERN = YES;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ "GCC_VERSION[arch=i386]" = "";
+ "GCC_VERSION[arch=x86_64]" = "";
+ GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
+ GENERATE_MASTER_OBJECT_FILE = NO;
+ HEADER_SEARCH_PATHS = (
+ /Library/Frameworks/SDL.framework/Headers,
+ "$(HEADER_SEARCH_PATHS)",
+ ../gemrb/core,
+ osx/,
+ ./,
+ );
+ INFOPLIST_FILE = osx/Info.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ LINKER_DISPLAYS_MANGLED_NAMES = NO;
+ ONLY_ACTIVE_ARCH = NO;
+ OTHER_CFLAGS = "-DTARGET_OS_MAC";
+ OTHER_CPLUSPLUSFLAGS = "-DTARGET_OS_MAC";
+ OTHER_LDFLAGS = "";
+ PRODUCT_NAME = GemRB;
+ SDKROOT = "";
+ "SDKROOT[arch=x86_64]" = "";
+ VALID_ARCHS = "i386 x86_64";
+ WRAPPER_EXTENSION = app;
+ };
+ name = Release;
+ };
+ C01FCF4F08A954540054247B /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = YES;
+ ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(FRAMEWORK_SEARCH_PATHS)",
+ /Library/Frameworks/,
+ );
+ GCC_PREFIX_HEADER = GemRB_Prefix.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ "GCC_VERSION[arch=x86_64]" = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_PEDANTIC = NO;
+ GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_LABEL = YES;
+ GCC_WARN_UNUSED_PARAMETER = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = (
+ "$(HEADER_SEARCH_PATHS)",
+ ../gemrb/includes,
+ );
+ OTHER_CFLAGS = (
+ "-g",
+ "-D_DEBUG",
+ "-isystem",
+ ./,
+ "-W",
+ "-Wextra",
+ );
+ SDKROOT = "";
+ "SDKROOT[arch=*]" = "";
+ STRIP_INSTALLED_PRODUCT = NO;
+ USER_HEADER_SEARCH_PATHS = "./ ../gemrb/ ../gemrb/core/";
+ VALID_ARCHS = "i386 x86_64";
+ };
+ name = Debug;
+ };
+ C01FCF5008A954540054247B /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = YES;
+ ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(FRAMEWORK_SEARCH_PATHS)",
+ /Library/Frameworks/,
+ );
+ GCC_PREFIX_HEADER = GemRB_Prefix.pch;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ "GCC_VERSION[arch=x86_64]" = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_PEDANTIC = NO;
+ GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_LABEL = YES;
+ GCC_WARN_UNUSED_PARAMETER = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = (
+ "$(HEADER_SEARCH_PATHS)",
+ ../gemrb/includes,
+ );
+ OTHER_CFLAGS = (
+ "-isystem",
+ ./,
+ "-W",
+ "-Wextra",
+ );
+ SDKROOT = "";
+ "SDKROOT[arch=*]" = "";
+ USER_HEADER_SEARCH_PATHS = "./ ../gemrb/ ../gemrb/core/";
+ VALID_ARCHS = "i386 x86_64";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ A2462F1813A036C8002D1F02 /* Build configuration list for PBXNativeTarget "AREImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A2462F1213A036B2002D1F02 /* Debug */,
+ A2462F1313A036B2002D1F02 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A2690314142BEE2F003E8BCC /* Build configuration list for PBXNativeTarget "SDLTTFFont" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A2690315142BEE2F003E8BCC /* Debug */,
+ A2690316142BEE2F003E8BCC /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B3CD13A2869700D41A8A /* Build configuration list for PBXNativeTarget "BIFImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B3CB13A2867900D41A8A /* Debug */,
+ A276B3CC13A2867900D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B43513A287CC00D41A8A /* Build configuration list for PBXNativeTarget "BIKPlayer" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B3D213A286A800D41A8A /* Debug */,
+ A276B3D313A286A800D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B43613A287CC00D41A8A /* Build configuration list for PBXNativeTarget "BMPImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B3D813A286BD00D41A8A /* Debug */,
+ A276B3D913A286BD00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B43713A287CC00D41A8A /* Build configuration list for PBXNativeTarget "BMPWriter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B3DE13A286CD00D41A8A /* Debug */,
+ A276B3DF13A286CD00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B43813A287CC00D41A8A /* Build configuration list for PBXNativeTarget "CHUImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B3E413A286DE00D41A8A /* Debug */,
+ A276B3E513A286DE00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B43913A287CC00D41A8A /* Build configuration list for PBXNativeTarget "CREImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B3EA13A286ED00D41A8A /* Debug */,
+ A276B3EB13A286ED00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B43A13A287CC00D41A8A /* Build configuration list for PBXNativeTarget "DirectoryImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B3F013A286FB00D41A8A /* Debug */,
+ A276B3F113A286FB00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B43B13A287CC00D41A8A /* Build configuration list for PBXNativeTarget "DLGImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B3F613A2871400D41A8A /* Debug */,
+ A276B3F713A2871400D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B43C13A287CC00D41A8A /* Build configuration list for PBXNativeTarget "EFFImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B3FC13A2872600D41A8A /* Debug */,
+ A276B3FD13A2872600D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B43D13A287CC00D41A8A /* Build configuration list for PBXNativeTarget "FXOpcodes" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B40213A2873700D41A8A /* Debug */,
+ A276B40313A2873700D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B43E13A287CC00D41A8A /* Build configuration list for PBXNativeTarget "GAMImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B40813A2874800D41A8A /* Debug */,
+ A276B40913A2874800D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B43F13A287CC00D41A8A /* Build configuration list for PBXNativeTarget "GUIScript" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B40E13A2875500D41A8A /* Debug */,
+ A276B40F13A2875500D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B44013A287CC00D41A8A /* Build configuration list for PBXNativeTarget "IDSImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B41413A2876400D41A8A /* Debug */,
+ A276B41513A2876400D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B44113A287CC00D41A8A /* Build configuration list for PBXNativeTarget "INIImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B41A13A2877100D41A8A /* Debug */,
+ A276B41B13A2877100D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B44213A287CC00D41A8A /* Build configuration list for PBXNativeTarget "ITMImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B42013A2878400D41A8A /* Debug */,
+ A276B42113A2878400D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B44313A287CC00D41A8A /* Build configuration list for PBXNativeTarget "IWDOpcodes" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B42613A2879A00D41A8A /* Debug */,
+ A276B42713A2879A00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B44413A287CC00D41A8A /* Build configuration list for PBXNativeTarget "KEYImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B42C13A287AB00D41A8A /* Debug */,
+ A276B42D13A287AB00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B44513A287CC00D41A8A /* Build configuration list for PBXNativeTarget "MOSImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B43213A287BD00D41A8A /* Debug */,
+ A276B43313A287BD00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4B313A28AF400D41A8A /* Build configuration list for PBXNativeTarget "MUSImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B44A13A289E100D41A8A /* Debug */,
+ A276B44B13A289E100D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4B413A28AF400D41A8A /* Build configuration list for PBXNativeTarget "MVEPlayer" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B45013A28A0100D41A8A /* Debug */,
+ A276B45113A28A0100D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4B513A28AF400D41A8A /* Build configuration list for PBXNativeTarget "NullSound" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B45613A28A0F00D41A8A /* Debug */,
+ A276B45713A28A0F00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4B613A28AF400D41A8A /* Build configuration list for PBXNativeTarget "OGGReader" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B45C13A28A1C00D41A8A /* Debug */,
+ A276B45D13A28A1C00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4B713A28AF400D41A8A /* Build configuration list for PBXNativeTarget "OpenALAudio" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B46213A28A3100D41A8A /* Debug */,
+ A276B46313A28A3100D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4B813A28AF400D41A8A /* Build configuration list for PBXNativeTarget "PLTImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B46813A28A3F00D41A8A /* Debug */,
+ A276B46913A28A3F00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4B913A28AF400D41A8A /* Build configuration list for PBXNativeTarget "PNGImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B46E13A28A5000D41A8A /* Debug */,
+ A276B46F13A28A5000D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4BA13A28AF400D41A8A /* Build configuration list for PBXNativeTarget "PROImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B47413A28A5D00D41A8A /* Debug */,
+ A276B47513A28A5D00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4BB13A28AF400D41A8A /* Build configuration list for PBXNativeTarget "PSTOpcodes" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B47A13A28A7600D41A8A /* Debug */,
+ A276B47B13A28A7600D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4BC13A28AF400D41A8A /* Build configuration list for PBXNativeTarget "SDLAudio" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B48013A28A8500D41A8A /* Debug */,
+ A276B48113A28A8500D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4BD13A28AF400D41A8A /* Build configuration list for PBXNativeTarget "SDLVideo" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B48613A28A9000D41A8A /* Debug */,
+ A276B48713A28A9000D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4BE13A28AF400D41A8A /* Build configuration list for PBXNativeTarget "SPLImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B48C13A28A9E00D41A8A /* Debug */,
+ A276B48D13A28A9E00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4BF13A28AF400D41A8A /* Build configuration list for PBXNativeTarget "TISImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B49213A28AA900D41A8A /* Debug */,
+ A276B49313A28AA900D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4C013A28AF400D41A8A /* Build configuration list for PBXNativeTarget "TLKImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B49813A28AB800D41A8A /* Debug */,
+ A276B49913A28AB800D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4C113A28AF400D41A8A /* Build configuration list for PBXNativeTarget "WAVReader" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B49E13A28AC800D41A8A /* Debug */,
+ A276B49F13A28AC800D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4C213A28AF400D41A8A /* Build configuration list for PBXNativeTarget "WEDImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B4A413A28AD300D41A8A /* Debug */,
+ A276B4A513A28AD300D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4C313A28AF400D41A8A /* Build configuration list for PBXNativeTarget "WMPImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B4AA13A28AE100D41A8A /* Debug */,
+ A276B4AB13A28AE100D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4C413A28AF400D41A8A /* Build configuration list for PBXNativeTarget "ZLibManager" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B4B013A28AEE00D41A8A /* Debug */,
+ A276B4B113A28AEE00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B52413A28C4400D41A8A /* Build configuration list for PBXNativeTarget "STOImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B4F513A28C0500D41A8A /* Debug */,
+ A276B4F613A28C0500D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A27E831213A035B800B41410 /* Build configuration list for PBXNativeTarget "2DAImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A27E830B13A0358300B41410 /* Debug */,
+ A27E830C13A0358300B41410 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A29BF7B913A0381D00C812DD /* Build configuration list for PBXNativeTarget "BAMImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A29BF7B313A0380F00C812DD /* Debug */,
+ A29BF7B413A0380F00C812DD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A29BF86313A042B600C812DD /* Build configuration list for PBXNativeTarget "GemRB iOS" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A29BF85E13A0427A00C812DD /* Debug */,
+ A29BF85F13A0427A00C812DD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A2E6633D139E87A400310FC8 /* Build configuration list for PBXNativeTarget "gemrb_core" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A2E66339139E875500310FC8 /* Debug */,
+ A2E6633A139E875500310FC8 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A2F0505713ABB8320023B7EB /* Build configuration list for PBXNativeTarget "SAVImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A2F0505213ABB80C0023B7EB /* Debug */,
+ A2F0505313ABB80C0023B7EB /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A2FCD60213A0366F00271997 /* Build configuration list for PBXNativeTarget "ACMReader" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A2FCD5FC13A0366100271997 /* Debug */,
+ A2FCD5FD13A0366100271997 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "GemRB OS X" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C01FCF4B08A954540054247B /* Debug */,
+ C01FCF4C08A954540054247B /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C01FCF4E08A954540054247B /* Build configuration list for PBXProject "GemRB" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C01FCF4F08A954540054247B /* Debug */,
+ C01FCF5008A954540054247B /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
+}
diff --git a/apple/GemRB.xcodeproj/project.pbxproj b/apple/GemRB.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..0dcbeaa
--- /dev/null
+++ b/apple/GemRB.xcodeproj/project.pbxproj
@@ -0,0 +1,7510 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXAggregateTarget section */
+ A2F8708C14AE439000F9CC1F /* ReleasePackage */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = A2F8708D14AE439000F9CC1F /* Build configuration list for PBXAggregateTarget "ReleasePackage" */;
+ buildPhases = (
+ A2F8709214AE448500F9CC1F /* ShellScript */,
+ );
+ dependencies = (
+ A295049116097F9D00BB22AA /* PBXTargetDependency */,
+ A295048716097E3700BB22AA /* PBXTargetDependency */,
+ A2F8709114AE43BB00F9CC1F /* PBXTargetDependency */,
+ A2F8709414AE4A8F00F9CC1F /* PBXTargetDependency */,
+ );
+ name = ReleasePackage;
+ productName = ReleasePackage;
+ };
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+ 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
+ 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+ A208210D1419712F002CD244 /* String.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECEC13A8669700C6DF12 /* String.cpp */; };
+ A208210E1419712F002CD244 /* IndexedArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECD913A8661600C6DF12 /* IndexedArchive.cpp */; };
+ A20821101419712F002CD244 /* PluginLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECDB13A8661600C6DF12 /* PluginLoader.cpp */; };
+ A20821111419712F002CD244 /* MemoryStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0601395FF62006ADC12 /* MemoryStream.cpp */; };
+ A20C698013B0FA430082EEBA /* AmbientMgrAL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8737139F0A7D0002DC13 /* AmbientMgrAL.cpp */; };
+ A20C698113B0FA430082EEBA /* OpenALAudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B873B139F0A7D0002DC13 /* OpenALAudio.cpp */; };
+ A20C698213B0FA430082EEBA /* StackLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B873D139F0A7D0002DC13 /* StackLock.cpp */; };
+ A218A75214A8F3DB001142CF /* ../artwork/gemrb.icns in Resources */ = {isa = PBXBuildFile; fileRef = A218A75114A8F3DB001142CF /* ../artwork/gemrb.icns */; };
+ A22693791422934E004468E8 /* CocoaWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = A249187B141075A60038B170 /* CocoaWrapper.m */; settings = {COMPILER_FLAGS = "-DTARGET_OS_MAC"; }; };
+ A226F41013A119D8009CE75E /* 2DAImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8699139F0A7D0002DC13 /* 2DAImporter.cpp */; };
+ A226F41113A119E2009CE75E /* ACMReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B869E139F0A7D0002DC13 /* ACMReader.cpp */; };
+ A226F41213A119E2009CE75E /* decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86A1139F0A7D0002DC13 /* decoder.cpp */; };
+ A226F41313A119E2009CE75E /* unpacker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86A5139F0A7D0002DC13 /* unpacker.cpp */; };
+ A226F41413A119E5009CE75E /* ACMReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B869E139F0A7D0002DC13 /* ACMReader.cpp */; };
+ A226F41513A119E5009CE75E /* decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86A1139F0A7D0002DC13 /* decoder.cpp */; };
+ A226F41613A119E5009CE75E /* unpacker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86A5139F0A7D0002DC13 /* unpacker.cpp */; };
+ A226F41713A119EA009CE75E /* AREImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86A8139F0A7D0002DC13 /* AREImporter.cpp */; };
+ A226F41813A119F1009CE75E /* BAMImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86AD139F0A7D0002DC13 /* BAMImporter.cpp */; };
+ A226F41913A119F6009CE75E /* BIFImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86B2139F0A7D0002DC13 /* BIFImporter.cpp */; };
+ A226F41A13A11A00009CE75E /* BIKPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86B7139F0A7D0002DC13 /* BIKPlayer.cpp */; };
+ A226F41B13A11A00009CE75E /* dct.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86BC139F0A7D0002DC13 /* dct.cpp */; };
+ A226F41C13A11A00009CE75E /* fft.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86BE139F0A7D0002DC13 /* fft.cpp */; };
+ A226F41D13A11A00009CE75E /* GetBitContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86BF139F0A7D0002DC13 /* GetBitContext.cpp */; };
+ A226F41E13A11A00009CE75E /* mem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86C2139F0A7D0002DC13 /* mem.cpp */; };
+ A226F41F13A11A00009CE75E /* rational.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86C3139F0A7D0002DC13 /* rational.cpp */; };
+ A226F42013A11A00009CE75E /* rdft.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86C5139F0A7D0002DC13 /* rdft.cpp */; };
+ A226F42113A11A07009CE75E /* BMPImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86C7139F0A7D0002DC13 /* BMPImporter.cpp */; };
+ A226F42213A11A0C009CE75E /* BMPWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86CC139F0A7D0002DC13 /* BMPWriter.cpp */; };
+ A226F42313A11A11009CE75E /* CHUImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86D1139F0A7D0002DC13 /* CHUImporter.cpp */; };
+ A226F42413A11A17009CE75E /* CREImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86D8139F0A7D0002DC13 /* CREImporter.cpp */; };
+ A226F42513A11A1C009CE75E /* DirectoryImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86DD139F0A7D0002DC13 /* DirectoryImporter.cpp */; };
+ A226F42613A11A22009CE75E /* DLGImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86E2139F0A7D0002DC13 /* DLGImporter.cpp */; };
+ A226F42713A11A27009CE75E /* EFFImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86E7139F0A7D0002DC13 /* EFFImporter.cpp */; };
+ A226F42813A11A2C009CE75E /* FXOpcodes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86EC139F0A7D0002DC13 /* FXOpcodes.cpp */; };
+ A226F42913A11A31009CE75E /* GAMImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86F0139F0A7D0002DC13 /* GAMImporter.cpp */; };
+ A226F42A13A11A39009CE75E /* GUIScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86F5139F0A7D0002DC13 /* GUIScript.cpp */; };
+ A226F42B13A11A39009CE75E /* PythonHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86F8139F0A7D0002DC13 /* PythonHelpers.cpp */; };
+ A226F42C13A11A3F009CE75E /* IDSImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86FC139F0A7D0002DC13 /* IDSImporter.cpp */; };
+ A226F42D13A11A44009CE75E /* INIImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8702139F0A7D0002DC13 /* INIImporter.cpp */; };
+ A226F42E13A11A49009CE75E /* ITMImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8707139F0A7D0002DC13 /* ITMImporter.cpp */; };
+ A226F42F13A11A4E009CE75E /* IWDOpcodes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B870C139F0A7D0002DC13 /* IWDOpcodes.cpp */; };
+ A226F43113A11A53009CE75E /* KEYImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8712139F0A7D0002DC13 /* KEYImporter.cpp */; };
+ A226F43213A11A58009CE75E /* MOSImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8719139F0A7D0002DC13 /* MOSImporter.cpp */; };
+ A226F43313A11A5E009CE75E /* MUSImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B871E139F0A7D0002DC13 /* MUSImporter.cpp */; };
+ A226F43413A11A66009CE75E /* mve_player.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8725139F0A7D0002DC13 /* mve_player.cpp */; };
+ A226F43513A11A66009CE75E /* mveaudiodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8727139F0A7D0002DC13 /* mveaudiodec.cpp */; };
+ A226F43613A11A66009CE75E /* MVEPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8728139F0A7D0002DC13 /* MVEPlayer.cpp */; };
+ A226F43713A11A66009CE75E /* mvevideodec16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B872A139F0A7D0002DC13 /* mvevideodec16.cpp */; };
+ A226F43813A11A66009CE75E /* mvevideodec8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B872B139F0A7D0002DC13 /* mvevideodec8.cpp */; };
+ A226F43E13A11A7E009CE75E /* PLTImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8742139F0A7D0002DC13 /* PLTImporter.cpp */; };
+ A226F44013A11A8D009CE75E /* PROImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B874C139F0A7D0002DC13 /* PROImporter.cpp */; };
+ A226F44113A11A94009CE75E /* PSTOpcodes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8751139F0A7D0002DC13 /* PSTOpcodes.cpp */; };
+ A226F44413A11AA3009CE75E /* SPLImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8761139F0A7D0002DC13 /* SPLImporter.cpp */; };
+ A226F44513A11AA8009CE75E /* STOImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8766139F0A7D0002DC13 /* STOImporter.cpp */; };
+ A226F44613A11AAC009CE75E /* TISImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B876B139F0A7D0002DC13 /* TISImporter.cpp */; };
+ A226F44713A11AB4009CE75E /* TLKImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8770139F0A7D0002DC13 /* TLKImporter.cpp */; };
+ A226F44813A11AB4009CE75E /* TlkOverride.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8772139F0A7D0002DC13 /* TlkOverride.cpp */; };
+ A226F44913A11AB9009CE75E /* WAVReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8777139F0A7D0002DC13 /* WAVReader.cpp */; };
+ A226F44A13A11ABE009CE75E /* WEDImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B877C139F0A7D0002DC13 /* WEDImporter.cpp */; };
+ A226F44B13A11AC3009CE75E /* WMPImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8781139F0A7D0002DC13 /* WMPImporter.cpp */; };
+ A226F44C13A11AC8009CE75E /* ZLibManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8786139F0A7D0002DC13 /* ZLibManager.cpp */; };
+ A228D24916A86FA00053375D /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A228D24816A86FA00053375D /* libiconv.dylib */; };
+ A22B5D611583D816007B4AA4 /* libFreetype2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A22B5D5D1583D816007B4AA4 /* libFreetype2.a */; };
+ A22B5D621583D816007B4AA4 /* libPython.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A22B5D5E1583D816007B4AA4 /* libPython.a */; };
+ A22B5D641583D816007B4AA4 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A22B5D601583D816007B4AA4 /* libSDL2.a */; };
+ A22DCCDF14A8FE0F0067D6D1 /* ios/Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = A22DCCDE14A8FE0F0067D6D1 /* ios/Icon.png */; };
+ A22DCCE114A8FE120067D6D1 /* ios/Icon at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = A22DCCE014A8FE120067D6D1 /* ios/Icon at 2x.png */; };
+ A22DCCE314A8FE870067D6D1 /* ios/Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = A22DCCE214A8FE870067D6D1 /* ios/Icon-72.png */; };
+ A22EBDCE14FF18030029C9C1 /* AppleLogger.mm in Sources */ = {isa = PBXBuildFile; fileRef = A22EBDCD14FF18030029C9C1 /* AppleLogger.mm */; };
+ A230584915D5BBCC00BDF69C /* MessageWindowLogger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A230584715D5BBCC00BDF69C /* MessageWindowLogger.cpp */; };
+ A230584A15D5BBCC00BDF69C /* MessageWindowLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = A230584815D5BBCC00BDF69C /* MessageWindowLogger.h */; };
+ A2374CA215F1486E002A1C8C /* libbz2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2374CA115F1486E002A1C8C /* libbz2.dylib */; };
+ A238174B14B781F00058BFF4 /* GemRB.cfg.newinstall in Resources */ = {isa = PBXBuildFile; fileRef = A238174914B781CC0058BFF4 /* GemRB.cfg.newinstall */; };
+ A239390B145F8677007895B3 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A239390A145F8677007895B3 /* UIKit.framework */; };
+ A23EBFFA141979D500CC049E /* KeyMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECDA13A8661600C6DF12 /* KeyMap.cpp */; };
+ A2491881141092F20038B170 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2491880141092F20038B170 /* Cocoa.framework */; };
+ A265ECDC13A8661600C6DF12 /* FileCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECD813A8661600C6DF12 /* FileCache.cpp */; };
+ A265ECDD13A8661600C6DF12 /* IndexedArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECD913A8661600C6DF12 /* IndexedArchive.cpp */; };
+ A265ECDE13A8661600C6DF12 /* KeyMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECDA13A8661600C6DF12 /* KeyMap.cpp */; };
+ A265ECDF13A8661600C6DF12 /* PluginLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECDB13A8661600C6DF12 /* PluginLoader.cpp */; };
+ A265ECE013A8661600C6DF12 /* FileCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECD813A8661600C6DF12 /* FileCache.cpp */; };
+ A265ECED13A8669700C6DF12 /* Logging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECEA13A8669700C6DF12 /* Logging.cpp */; };
+ A265ECEE13A8669700C6DF12 /* SlicedStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECEB13A8669700C6DF12 /* SlicedStream.cpp */; };
+ A265ECEF13A8669700C6DF12 /* String.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECEC13A8669700C6DF12 /* String.cpp */; };
+ A265ECF013A8669700C6DF12 /* Logging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECEA13A8669700C6DF12 /* Logging.cpp */; };
+ A265ECF113A8669700C6DF12 /* SlicedStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265ECEB13A8669700C6DF12 /* SlicedStream.cpp */; };
+ A273DC7C14856756000DA299 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A273DC7B14856755000DA299 /* libz.dylib */; };
+ A276B4C513A28B0000D41A8A /* BIFImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86B2139F0A7D0002DC13 /* BIFImporter.cpp */; };
+ A276B4C613A28B0D00D41A8A /* BIKPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86B7139F0A7D0002DC13 /* BIKPlayer.cpp */; };
+ A276B4C713A28B0D00D41A8A /* dct.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86BC139F0A7D0002DC13 /* dct.cpp */; };
+ A276B4C813A28B0D00D41A8A /* fft.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86BE139F0A7D0002DC13 /* fft.cpp */; };
+ A276B4C913A28B0D00D41A8A /* GetBitContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86BF139F0A7D0002DC13 /* GetBitContext.cpp */; };
+ A276B4CA13A28B0D00D41A8A /* mem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86C2139F0A7D0002DC13 /* mem.cpp */; };
+ A276B4CB13A28B0D00D41A8A /* rational.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86C3139F0A7D0002DC13 /* rational.cpp */; };
+ A276B4CC13A28B0D00D41A8A /* rdft.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86C5139F0A7D0002DC13 /* rdft.cpp */; };
+ A276B4CD13A28B2000D41A8A /* BMPImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86C7139F0A7D0002DC13 /* BMPImporter.cpp */; };
+ A276B4CE13A28B2900D41A8A /* BMPWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86CC139F0A7D0002DC13 /* BMPWriter.cpp */; };
+ A276B4CF13A28B2F00D41A8A /* CHUImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86D1139F0A7D0002DC13 /* CHUImporter.cpp */; };
+ A276B4D013A28B3500D41A8A /* CREImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86D8139F0A7D0002DC13 /* CREImporter.cpp */; };
+ A276B4D113A28B3B00D41A8A /* DirectoryImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86DD139F0A7D0002DC13 /* DirectoryImporter.cpp */; };
+ A276B4D213A28B4300D41A8A /* DLGImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86E2139F0A7D0002DC13 /* DLGImporter.cpp */; };
+ A276B4D313A28B4B00D41A8A /* EFFImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86E7139F0A7D0002DC13 /* EFFImporter.cpp */; };
+ A276B4D413A28B5000D41A8A /* FXOpcodes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86EC139F0A7D0002DC13 /* FXOpcodes.cpp */; };
+ A276B4D513A28B5600D41A8A /* GAMImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86F0139F0A7D0002DC13 /* GAMImporter.cpp */; };
+ A276B4D613A28B5E00D41A8A /* GUIScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86F5139F0A7D0002DC13 /* GUIScript.cpp */; };
+ A276B4D713A28B5E00D41A8A /* PythonHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86F8139F0A7D0002DC13 /* PythonHelpers.cpp */; };
+ A276B4D813A28B6600D41A8A /* IDSImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86FC139F0A7D0002DC13 /* IDSImporter.cpp */; };
+ A276B4D913A28B6B00D41A8A /* INIImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8702139F0A7D0002DC13 /* INIImporter.cpp */; };
+ A276B4DA13A28B7200D41A8A /* ITMImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8707139F0A7D0002DC13 /* ITMImporter.cpp */; };
+ A276B4DB13A28B7D00D41A8A /* IWDOpcodes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B870C139F0A7D0002DC13 /* IWDOpcodes.cpp */; };
+ A276B4DD13A28B8500D41A8A /* KEYImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8712139F0A7D0002DC13 /* KEYImporter.cpp */; };
+ A276B4DE13A28B8D00D41A8A /* MOSImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8719139F0A7D0002DC13 /* MOSImporter.cpp */; };
+ A276B4DF13A28B9400D41A8A /* MUSImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B871E139F0A7D0002DC13 /* MUSImporter.cpp */; };
+ A276B4E013A28B9F00D41A8A /* mve_player.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8725139F0A7D0002DC13 /* mve_player.cpp */; };
+ A276B4E113A28B9F00D41A8A /* mveaudiodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8727139F0A7D0002DC13 /* mveaudiodec.cpp */; };
+ A276B4E213A28B9F00D41A8A /* MVEPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8728139F0A7D0002DC13 /* MVEPlayer.cpp */; };
+ A276B4E313A28B9F00D41A8A /* mvevideodec16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B872A139F0A7D0002DC13 /* mvevideodec16.cpp */; };
+ A276B4E413A28B9F00D41A8A /* mvevideodec8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B872B139F0A7D0002DC13 /* mvevideodec8.cpp */; };
+ A276B4E513A28BA500D41A8A /* NullSound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B872F139F0A7D0002DC13 /* NullSound.cpp */; };
+ A276B4E613A28BAC00D41A8A /* OGGReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8734139F0A7D0002DC13 /* OGGReader.cpp */; };
+ A276B4E713A28BB400D41A8A /* AmbientMgrAL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8737139F0A7D0002DC13 /* AmbientMgrAL.cpp */; };
+ A276B4E813A28BB400D41A8A /* OpenALAudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B873B139F0A7D0002DC13 /* OpenALAudio.cpp */; };
+ A276B4E913A28BB400D41A8A /* StackLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B873D139F0A7D0002DC13 /* StackLock.cpp */; };
+ A276B4EA13A28BBC00D41A8A /* PLTImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8742139F0A7D0002DC13 /* PLTImporter.cpp */; };
+ A276B4EB13A28BC500D41A8A /* PNGImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8747139F0A7D0002DC13 /* PNGImporter.cpp */; };
+ A276B4EC13A28BCC00D41A8A /* PROImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B874C139F0A7D0002DC13 /* PROImporter.cpp */; };
+ A276B4ED13A28BD400D41A8A /* PSTOpcodes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8751139F0A7D0002DC13 /* PSTOpcodes.cpp */; };
+ A276B4EE13A28BDB00D41A8A /* SDLAudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8755139F0A7D0002DC13 /* SDLAudio.cpp */; };
+ A276B4EF13A28BE100D41A8A /* SDLVideo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B875A139F0A7D0002DC13 /* SDLVideo.cpp */; };
+ A276B4F013A28BE800D41A8A /* SPLImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8761139F0A7D0002DC13 /* SPLImporter.cpp */; };
+ A276B4F713A28C1300D41A8A /* STOImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8766139F0A7D0002DC13 /* STOImporter.cpp */; };
+ A276B4F813A28C2200D41A8A /* TISImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B876B139F0A7D0002DC13 /* TISImporter.cpp */; };
+ A276B4F913A28C2900D41A8A /* TLKImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8770139F0A7D0002DC13 /* TLKImporter.cpp */; };
+ A276B4FA13A28C2900D41A8A /* TlkOverride.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8772139F0A7D0002DC13 /* TlkOverride.cpp */; };
+ A276B4FB13A28C3000D41A8A /* WAVReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8777139F0A7D0002DC13 /* WAVReader.cpp */; };
+ A276B4FC13A28C3500D41A8A /* WEDImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B877C139F0A7D0002DC13 /* WEDImporter.cpp */; };
+ A276B4FD13A28C3B00D41A8A /* WMPImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8781139F0A7D0002DC13 /* WMPImporter.cpp */; };
+ A276B4FE13A28C4100D41A8A /* ZLibManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8786139F0A7D0002DC13 /* ZLibManager.cpp */; };
+ A276B52513A28CC900D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B52613A28CD300D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B52713A28CD800D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B52813A28CDD00D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B52913A28CE000D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B52A13A28CE400D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B52B13A28CEA00D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B52C13A28CF000D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B52D13A28CF400D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B52E13A28CF700D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B52F13A28CFA00D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53013A28D0000D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53113A28D0600D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53213A28D0900D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53313A28D0C00D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53413A28D0F00D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53513A28D1200D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53613A28D1500D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53713A28D1800D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53813A28D1B00D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53913A28D1F00D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53A13A28D2300D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53B13A28D2500D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53C13A28D2800D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53D13A28D2A00D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53E13A28D2D00D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B53F13A28D3000D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B54013A28D3500D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B54113A28D3D00D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B54213A28D4000D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B54313A28D4300D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B54413A28D4600D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B54513A28D4900D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B54613A28D4C00D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B54713A28D5500D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B54813A28D5900D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A276B54913A28D5D00D41A8A /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A27979AF13ABA509009A6FEF /* SAVImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27979AC13ABA4F7009A6FEF /* SAVImporter.cpp */; };
+ A27ABCD016F2396C00FE11EF /* NullSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2FE2C7716F2313400DDC6C7 /* NullSource.cpp */; };
+ A27E831313A035C600B41410 /* 2DAImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B8699139F0A7D0002DC13 /* 2DAImporter.cpp */; };
+ A288622014A54FFD009AC280 /* libarchive.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A288621F14A54FFD009AC280 /* libarchive.dylib */; };
+ A288622214A5501F009AC280 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A288622114A5501F009AC280 /* libz.dylib */; };
+ A288622314A550BF009AC280 /* BAMFontManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A28D24A0143C24C100A27897 /* BAMFontManager.cpp */; };
+ A28D249A143BEA4200A27897 /* FontManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A28D2498143BEA4200A27897 /* FontManager.cpp */; };
+ A29504701609721300BB22AA /* TTFFontManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2A6A459146893CC000F1688 /* TTFFontManager.cpp */; };
+ A29504721609721300BB22AA /* FreeType.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2AAC14615C1C2F500D27766 /* FreeType.framework */; };
+ A29504731609721300BB22AA /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A29504781609724F00BB22AA /* TTFImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A29504771609721300BB22AA /* TTFImporter.so */; };
+ A2969F0F168CDC0D00D9C6FC /* CombatInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2969F0D168CDC0D00D9C6FC /* CombatInfo.cpp */; };
+ A2969F10168CDC0D00D9C6FC /* CombatInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2969F0D168CDC0D00D9C6FC /* CombatInfo.cpp */; };
+ A2969F11168CDC0D00D9C6FC /* CombatInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = A2969F0E168CDC0D00D9C6FC /* CombatInfo.h */; };
+ A298DD0814EB4E8C00F59F56 /* CocoaWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = A249187B141075A60038B170 /* CocoaWrapper.m */; settings = {COMPILER_FLAGS = "-DTARGET_OS_MAC"; }; };
+ A298DD0914EB4E8C00F59F56 /* SDLVideo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B875A139F0A7D0002DC13 /* SDLVideo.cpp */; };
+ A298DD0B14EB4E8C00F59F56 /* SDL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2D0505014D0B06C00D8CD77 /* SDL.framework */; };
+ A298DD0C14EB4E8C00F59F56 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2491880141092F20038B170 /* Cocoa.framework */; };
+ A298DD0D14EB4E8C00F59F56 /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A298DD1614EB4EDE00F59F56 /* SDL12Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A298DD1314EB4EDE00F59F56 /* SDL12Video.cpp */; };
+ A298DD1914EB4EEB00F59F56 /* SDL20Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A298DD1714EB4EEB00F59F56 /* SDL20Video.cpp */; };
+ A298DD1A14EB4EEB00F59F56 /* SDL20Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A298DD1714EB4EEB00F59F56 /* SDL20Video.cpp */; };
+ A298DD1D14EB61C100F59F56 /* Stdio.h in Headers */ = {isa = PBXBuildFile; fileRef = A298DD1B14EB61C100F59F56 /* Stdio.h */; };
+ A298DD2214EB61D300F59F56 /* Stdio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A298DD2114EB61D300F59F56 /* Stdio.cpp */; };
+ A298DD2314EB61D300F59F56 /* Stdio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A298DD2114EB61D300F59F56 /* Stdio.cpp */; };
+ A29BF81313A03C2600C812DD /* AREImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86A8139F0A7D0002DC13 /* AREImporter.cpp */; };
+ A29BF82B13A03DFC00C812DD /* BAMImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B86AD139F0A7D0002DC13 /* BAMImporter.cpp */; };
+ A29BF85213A0420300C812DD /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A29BF85513A0420A00C812DD /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A29BF85613A0420F00C812DD /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A29BF85713A0421200C812DD /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A29BF8A213A04A6F00C812DD /* ActorMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F8D1395FF61006ADC12 /* ActorMgr.cpp */; };
+ A29BF8A313A04A6F00C812DD /* Ambient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F8F1395FF61006ADC12 /* Ambient.cpp */; };
+ A29BF8A413A04A6F00C812DD /* AmbientMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F911395FF61006ADC12 /* AmbientMgr.cpp */; };
+ A29BF8A513A04A6F00C812DD /* Animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F931395FF61006ADC12 /* Animation.cpp */; };
+ A29BF8A613A04A6F00C812DD /* AnimationFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F951395FF61006ADC12 /* AnimationFactory.cpp */; };
+ A29BF8A713A04A6F00C812DD /* AnimationMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F971395FF61006ADC12 /* AnimationMgr.cpp */; };
+ A29BF8A813A04A6F00C812DD /* ArchiveImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F9A1395FF61006ADC12 /* ArchiveImporter.cpp */; };
+ A29BF8A913A04A6F00C812DD /* Audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F9C1395FF61006ADC12 /* Audio.cpp */; };
+ A29BF8AA13A04A6F00C812DD /* Bitmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F9E1395FF61006ADC12 /* Bitmap.cpp */; };
+ A29BF8AB13A04A6F00C812DD /* Cache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FA01395FF61006ADC12 /* Cache.cpp */; };
+ A29BF8AC13A04A6F00C812DD /* Calendar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FA21395FF61006ADC12 /* Calendar.cpp */; };
+ A29BF8AD13A04A6F00C812DD /* Callback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FA41395FF61006ADC12 /* Callback.cpp */; };
+ A29BF8AE13A04A6F00C812DD /* CharAnimations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FA61395FF61006ADC12 /* CharAnimations.cpp */; };
+ A29BF8AF13A04A6F00C812DD /* Compressor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FA91395FF61006ADC12 /* Compressor.cpp */; };
+ A29BF8B013A04A6F00C812DD /* ControlAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FAB1395FF61006ADC12 /* ControlAnimation.cpp */; };
+ A29BF8B113A04A6F00C812DD /* Core.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FAD1395FF61006ADC12 /* Core.cpp */; };
+ A29BF8B213A04A6F00C812DD /* DataFileMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FAF1395FF61006ADC12 /* DataFileMgr.cpp */; };
+ A29BF8B313A04A6F00C812DD /* Dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FB11395FF61006ADC12 /* Dialog.cpp */; };
+ A29BF8B413A04A6F00C812DD /* DialogHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FB31395FF61006ADC12 /* DialogHandler.cpp */; };
+ A29BF8B513A04A6F00C812DD /* DialogMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FB51395FF61006ADC12 /* DialogMgr.cpp */; };
+ A29BF8B613A04A6F00C812DD /* DisplayMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FB71395FF61006ADC12 /* DisplayMessage.cpp */; };
+ A29BF8B713A04A6F00C812DD /* EffectMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FBA1395FF61006ADC12 /* EffectMgr.cpp */; };
+ A29BF8B813A04A6F00C812DD /* EffectQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FBC1395FF61006ADC12 /* EffectQueue.cpp */; };
+ A29BF8B913A04A6F00C812DD /* Factory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FBE1395FF61006ADC12 /* Factory.cpp */; };
+ A29BF8BA13A04A6F00C812DD /* FactoryObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FC01395FF61006ADC12 /* FactoryObject.cpp */; };
+ A29BF8BB13A04A6F00C812DD /* Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FC21395FF61006ADC12 /* Font.cpp */; };
+ A29BF8BC13A04A6F00C812DD /* Game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FC41395FF61006ADC12 /* Game.cpp */; };
+ A29BF8BD13A04A6F00C812DD /* GameData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FC61395FF62006ADC12 /* GameData.cpp */; };
+ A29BF8BE13A04A6F00C812DD /* GlobalTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FD21395FF62006ADC12 /* GlobalTimer.cpp */; };
+ A29BF8BF13A04A6F00C812DD /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FF21395FF62006ADC12 /* Image.cpp */; };
+ A29BF8C013A04A6F00C812DD /* ImageFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FF41395FF62006ADC12 /* ImageFactory.cpp */; };
+ A29BF8C113A04A6F00C812DD /* ImageMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FF61395FF62006ADC12 /* ImageMgr.cpp */; };
+ A29BF8C213A04A6F00C812DD /* ImageWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FF81395FF62006ADC12 /* ImageWriter.cpp */; };
+ A29BF8C313A04A6F00C812DD /* IniSpawn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FFA1395FF62006ADC12 /* IniSpawn.cpp */; };
+ A29BF8C413A04A6F00C812DD /* Interface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FFC1395FF62006ADC12 /* Interface.cpp */; };
+ A29BF8C513A04A6F00C812DD /* Inventory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FFE1395FF62006ADC12 /* Inventory.cpp */; };
+ A29BF8C613A04A6F00C812DD /* Item.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0001395FF62006ADC12 /* Item.cpp */; };
+ A29BF8C713A04A6F00C812DD /* ItemMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0021395FF62006ADC12 /* ItemMgr.cpp */; };
+ A29BF8C813A04A6F00C812DD /* LRUCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0041395FF62006ADC12 /* LRUCache.cpp */; };
+ A29BF8C913A04A6F00C812DD /* Map.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0071395FF62006ADC12 /* Map.cpp */; };
+ A29BF8CA13A04A6F00C812DD /* MapMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0091395FF62006ADC12 /* MapMgr.cpp */; };
+ A29BF8CB13A04A6F00C812DD /* MoviePlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA00B1395FF62006ADC12 /* MoviePlayer.cpp */; };
+ A29BF8CC13A04A6F00C812DD /* MusicMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA00D1395FF62006ADC12 /* MusicMgr.cpp */; };
+ A29BF8CD13A04A6F00C812DD /* Palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA00F1395FF62006ADC12 /* Palette.cpp */; };
+ A29BF8CE13A04A6F00C812DD /* PalettedImageMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0111395FF62006ADC12 /* PalettedImageMgr.cpp */; };
+ A29BF8CF13A04A6F00C812DD /* Particles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0131395FF62006ADC12 /* Particles.cpp */; };
+ A29BF8D013A04A6F00C812DD /* Plugin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0161395FF62006ADC12 /* Plugin.cpp */; };
+ A29BF8D113A04A6F00C812DD /* PluginMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0181395FF62006ADC12 /* PluginMgr.cpp */; };
+ A29BF8D213A04A6F00C812DD /* Polygon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA01A1395FF62006ADC12 /* Polygon.cpp */; };
+ A29BF8D313A04A6F00C812DD /* Projectile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA01D1395FF62006ADC12 /* Projectile.cpp */; };
+ A29BF8D413A04A6F00C812DD /* ProjectileMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA01F1395FF62006ADC12 /* ProjectileMgr.cpp */; };
+ A29BF8D513A04A6F00C812DD /* ProjectileServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0211395FF62006ADC12 /* ProjectileServer.cpp */; };
+ A29BF8D613A04A6F00C812DD /* Region.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0231395FF62006ADC12 /* Region.cpp */; };
+ A29BF8D713A04A6F00C812DD /* Resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0251395FF62006ADC12 /* Resource.cpp */; };
+ A29BF8D813A04A6F00C812DD /* ResourceDesc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0271395FF62006ADC12 /* ResourceDesc.cpp */; };
+ A29BF8D913A04A6F00C812DD /* ResourceManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0291395FF62006ADC12 /* ResourceManager.cpp */; };
+ A29BF8DA13A04A6F00C812DD /* ResourceSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA02B1395FF62006ADC12 /* ResourceSource.cpp */; };
+ A29BF8DB13A04A6F00C812DD /* SaveGameIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA02E1395FF62006ADC12 /* SaveGameIterator.cpp */; };
+ A29BF8DC13A04A6F00C812DD /* SaveGameMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0301395FF62006ADC12 /* SaveGameMgr.cpp */; };
+ A29BF8DD13A04A6F00C812DD /* ScriptedAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA03F1395FF62006ADC12 /* ScriptedAnimation.cpp */; };
+ A29BF8DE13A04A6F00C812DD /* ScriptEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0411395FF62006ADC12 /* ScriptEngine.cpp */; };
+ A29BF8DF13A04A6F00C812DD /* SoundMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0431395FF62006ADC12 /* SoundMgr.cpp */; };
+ A29BF8E013A04A6F00C812DD /* Spell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0451395FF62006ADC12 /* Spell.cpp */; };
+ A29BF8E113A04A6F00C812DD /* Spellbook.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0471395FF62006ADC12 /* Spellbook.cpp */; };
+ A29BF8E213A04A6F00C812DD /* SpellMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0491395FF62006ADC12 /* SpellMgr.cpp */; };
+ A29BF8E313A04A6F00C812DD /* Sprite2D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA04B1395FF62006ADC12 /* Sprite2D.cpp */; };
+ A29BF8E413A04A6F00C812DD /* SpriteCover.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA04D1395FF62006ADC12 /* SpriteCover.cpp */; };
+ A29BF8E513A04A6F00C812DD /* Store.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA04F1395FF62006ADC12 /* Store.cpp */; };
+ A29BF8E613A04A6F00C812DD /* StoreMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0511395FF62006ADC12 /* StoreMgr.cpp */; };
+ A29BF8E713A04A6F00C812DD /* StringMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0531395FF62006ADC12 /* StringMgr.cpp */; };
+ A29BF8E813A04A6F00C812DD /* SymbolMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0551395FF62006ADC12 /* SymbolMgr.cpp */; };
+ A29BF8E913A04A6F00C812DD /* TableMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0681395FF62006ADC12 /* TableMgr.cpp */; };
+ A29BF8EA13A04A6F00C812DD /* Tile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA06A1395FF62006ADC12 /* Tile.cpp */; };
+ A29BF8EB13A04A6F00C812DD /* TileMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA06C1395FF62006ADC12 /* TileMap.cpp */; };
+ A29BF8EC13A04A6F00C812DD /* TileMapMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA06E1395FF62006ADC12 /* TileMapMgr.cpp */; };
+ A29BF8ED13A04A6F00C812DD /* TileOverlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0701395FF62006ADC12 /* TileOverlay.cpp */; };
+ A29BF8EE13A04A6F00C812DD /* TileSetMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0721395FF62006ADC12 /* TileSetMgr.cpp */; };
+ A29BF8EF13A04A6F00C812DD /* Variables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0751395FF62006ADC12 /* Variables.cpp */; };
+ A29BF8F013A04A6F00C812DD /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0771395FF62006ADC12 /* Video.cpp */; };
+ A29BF8F113A04A6F00C812DD /* WindowMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA07A1395FF62006ADC12 /* WindowMgr.cpp */; };
+ A29BF8F213A04A6F00C812DD /* WorldMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA07C1395FF62006ADC12 /* WorldMap.cpp */; };
+ A29BF8F313A04A6F00C812DD /* WorldMapMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA07E1395FF62006ADC12 /* WorldMapMgr.cpp */; };
+ A29BF8F513A04A6F00C812DD /* DataStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA05C1395FF62006ADC12 /* DataStream.cpp */; };
+ A29BF8F613A04A6F00C812DD /* FileStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA05E1395FF62006ADC12 /* FileStream.cpp */; };
+ A29BF8F713A04A6F00C812DD /* MemoryStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0601395FF62006ADC12 /* MemoryStream.cpp */; };
+ A29BF8F913A04A6F00C812DD /* swab.c in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0641395FF62006ADC12 /* swab.c */; };
+ A29BF8FA13A04A6F00C812DD /* VFS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0661395FF62006ADC12 /* VFS.cpp */; };
+ A29BF8FB13A04A6F00C812DD /* Actor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0331395FF62006ADC12 /* Actor.cpp */; };
+ A29BF8FC13A04A6F00C812DD /* Container.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0351395FF62006ADC12 /* Container.cpp */; };
+ A29BF8FD13A04A6F00C812DD /* Door.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0371395FF62006ADC12 /* Door.cpp */; };
+ A29BF8FE13A04A6F00C812DD /* InfoPoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0391395FF62006ADC12 /* InfoPoint.cpp */; };
+ A29BF8FF13A04A6F00C812DD /* PCStatStruct.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA03B1395FF62006ADC12 /* PCStatStruct.cpp */; };
+ A29BF90013A04A6F00C812DD /* Scriptable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA03D1395FF62006ADC12 /* Scriptable.cpp */; };
+ A29BF90113A04A6F00C812DD /* Button.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FD51395FF62006ADC12 /* Button.cpp */; };
+ A29BF90213A04A6F00C812DD /* Console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FD71395FF62006ADC12 /* Console.cpp */; };
+ A29BF90313A04A6F00C812DD /* Control.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FD91395FF62006ADC12 /* Control.cpp */; };
+ A29BF90413A04A6F00C812DD /* EventMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FDB1395FF62006ADC12 /* EventMgr.cpp */; };
+ A29BF90513A04A6F00C812DD /* GameControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FDD1395FF62006ADC12 /* GameControl.cpp */; };
+ A29BF90613A04A6F00C812DD /* Label.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FDF1395FF62006ADC12 /* Label.cpp */; };
+ A29BF90713A04A6F00C812DD /* MapControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FE11395FF62006ADC12 /* MapControl.cpp */; };
+ A29BF90813A04A6F00C812DD /* Progressbar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FE31395FF62006ADC12 /* Progressbar.cpp */; };
+ A29BF90913A04A6F00C812DD /* ScrollBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FE51395FF62006ADC12 /* ScrollBar.cpp */; };
+ A29BF90A13A04A6F00C812DD /* Slider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FE71395FF62006ADC12 /* Slider.cpp */; };
+ A29BF90B13A04A6F00C812DD /* TextArea.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FE91395FF62006ADC12 /* TextArea.cpp */; };
+ A29BF90C13A04A6F00C812DD /* TextEdit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FEB1395FF62006ADC12 /* TextEdit.cpp */; };
+ A29BF90D13A04A6F00C812DD /* Window.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FED1395FF62006ADC12 /* Window.cpp */; };
+ A29BF90E13A04A6F00C812DD /* WorldMapControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FEF1395FF62006ADC12 /* WorldMapControl.cpp */; };
+ A29BF90F13A04A6F00C812DD /* Actions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FC91395FF62006ADC12 /* Actions.cpp */; };
+ A29BF91013A04A6F00C812DD /* GameScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FCA1395FF62006ADC12 /* GameScript.cpp */; };
+ A29BF91113A04A6F00C812DD /* GSUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FCC1395FF62006ADC12 /* GSUtils.cpp */; };
+ A29BF91213A04A6F00C812DD /* Matching.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FCE1395FF62006ADC12 /* Matching.cpp */; };
+ A29BF91313A04A6F00C812DD /* Objects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FD01395FF62006ADC12 /* Objects.cpp */; };
+ A29BF91413A04A6F00C812DD /* Triggers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FD11395FF62006ADC12 /* Triggers.cpp */; };
+ A2A26ADD15AA729800A8E25D /* VideoContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2A26ADB15AA729800A8E25D /* VideoContext.cpp */; };
+ A2A2EA2F16A5EB4C0092B903 /* BAMFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2A2EA2D16A5EB4C0092B903 /* BAMFont.cpp */; };
+ A2A2EA3016A5EB4C0092B903 /* BAMFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2A2EA2D16A5EB4C0092B903 /* BAMFont.cpp */; };
+ A2A2EA3416A5EB630092B903 /* TTFFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2A2EA3216A5EB630092B903 /* TTFFont.cpp */; };
+ A2A2EA3516A5EB630092B903 /* TTFFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2A2EA3216A5EB630092B903 /* TTFFont.cpp */; };
+ A2A2EA3816A5FC860092B903 /* Freetype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2A2EA3616A5FC860092B903 /* Freetype.cpp */; };
+ A2A2EA3916A5FC860092B903 /* Freetype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2A2EA3616A5FC860092B903 /* Freetype.cpp */; };
+ A2A2EA4716A76AE90092B903 /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2A2EA4516A76ACC0092B903 /* libiconv.dylib */; };
+ A2A3A7D914A505FD00F705CF /* CocoaWrapper.mm in Sources */ = {isa = PBXBuildFile; fileRef = A2A3A7D814A505FD00F705CF /* CocoaWrapper.mm */; };
+ A2A3A7E514A5130F00F705CF /* CocoaMain.m in Sources */ = {isa = PBXBuildFile; fileRef = A2A3A7DF14A5130F00F705CF /* CocoaMain.m */; };
+ A2A3A7E614A5130F00F705CF /* GEM_ConfController.m in Sources */ = {isa = PBXBuildFile; fileRef = A2A3A7E114A5130F00F705CF /* GEM_ConfController.m */; };
+ A2A3A7E714A5130F00F705CF /* GEM_ConfController-ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = A2A3A7E314A5130F00F705CF /* GEM_ConfController-ipad.xib */; };
+ A2A3A7E814A5130F00F705CF /* GEM_ConfController-iphone.xib in Resources */ = {isa = PBXBuildFile; fileRef = A2A3A7E414A5130F00F705CF /* GEM_ConfController-iphone.xib */; };
+ A2A3A7EF14A51B1800F705CF /* GEM_SDL_Keyboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A2A3A7EE14A51B1800F705CF /* GEM_SDL_Keyboard.m */; };
+ A2A6A45C146893CC000F1688 /* TTFFontManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2A6A459146893CC000F1688 /* TTFFontManager.cpp */; };
+ A2AAF33A13A14A4500AE8402 /* SDLVideo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B875A139F0A7D0002DC13 /* SDLVideo.cpp */; };
+ A2AF8FC714DDCE47005CAC5D /* Vorbis.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2AF8FC614DDCE47005CAC5D /* Vorbis.framework */; };
+ A2B0CCD51486FF710074E54B /* FontManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A28D2498143BEA4200A27897 /* FontManager.cpp */; };
+ A2B0CCD61486FF780074E54B /* BAMFontManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A28D24A0143C24C100A27897 /* BAMFontManager.cpp */; };
+ A2B67A6B16B1DFC100577415 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2B67A6816B1DF6500577415 /* CoreFoundation.framework */; };
+ A2BD125215A7EDFE000FAB95 /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A2BD125A15A7EE61000FAB95 /* VLCPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BD125815A7EE61000FAB95 /* VLCPlayer.cpp */; };
+ A2BD125E15A8E63B000FAB95 /* VLCPlayer.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A2BD125615A7EDFE000FAB95 /* VLCPlayer.so */; };
+ A2C229C2150D89F300A0E3BE /* AppleLogger.mm in Sources */ = {isa = PBXBuildFile; fileRef = A22EBDCD14FF18030029C9C1 /* AppleLogger.mm */; };
+ A2C66D9D13A2953D00C0AA8E /* Python.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2C66D9C13A2953D00C0AA8E /* Python.framework */; };
+ A2C66DB513A295DC00C0AA8E /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2830A0F13A05A64000A63FE /* OpenAL.framework */; };
+ A2C76D2A14F196E900961680 /* StringBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2C76D2814F196E900961680 /* StringBuffer.cpp */; };
+ A2C76D2B14F196E900961680 /* StringBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2C76D2814F196E900961680 /* StringBuffer.cpp */; };
+ A2C76D2C14F196E900961680 /* StringBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A2C76D2914F196E900961680 /* StringBuffer.h */; };
+ A2CB5AC315000A0D00B5C154 /* File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2CB5AC115000A0D00B5C154 /* File.cpp */; };
+ A2CB5AC415000A0D00B5C154 /* File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2CB5AC115000A0D00B5C154 /* File.cpp */; };
+ A2CB5AC515000A0D00B5C154 /* File.h in Headers */ = {isa = PBXBuildFile; fileRef = A2CB5AC215000A0D00B5C154 /* File.h */; };
+ A2D0504F14D0AFCA00D8CD77 /* libgemrb_core.dylib in Copy Frameworks into .app bundle */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A2D0505114D0B06C00D8CD77 /* SDL.framework in Copy Frameworks into .app bundle */ = {isa = PBXBuildFile; fileRef = A2D0505014D0B06C00D8CD77 /* SDL.framework */; };
+ A2D0505214D0B09F00D8CD77 /* SDL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2D0505014D0B06C00D8CD77 /* SDL.framework */; };
+ A2D0505414D0C17500D8CD77 /* SDL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2D0505014D0B06C00D8CD77 /* SDL.framework */; };
+ A2DB6D5A15D9EE8C00D70E88 /* MessageWindowLogger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A230584715D5BBCC00BDF69C /* MessageWindowLogger.cpp */; };
+ A2DE329914EB071200117503 /* Logger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2DE329714EB071200117503 /* Logger.cpp */; };
+ A2DE329A14EB071200117503 /* Logger.h in Headers */ = {isa = PBXBuildFile; fileRef = A2DE329814EB071200117503 /* Logger.h */; };
+ A2DE32AD14EB0C6900117503 /* Logger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2DE329714EB071200117503 /* Logger.cpp */; };
+ A2E1583114D1D8DA0044F3C5 /* GEM_AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = A2E1583014D1D8DA0044F3C5 /* GEM_AppDelegate.mm */; };
+ A2E27EF716EEA7B00079E104 /* InterfaceConfig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2E27EF516EEA7B00079E104 /* InterfaceConfig.cpp */; };
+ A2E27EF916EEA7B00079E104 /* InterfaceConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = A2E27EF616EEA7B00079E104 /* InterfaceConfig.h */; };
+ A2E27EFA16F109090079E104 /* InterfaceConfig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2E27EF516EEA7B00079E104 /* InterfaceConfig.cpp */; };
+ A2E27EFC16F12B5A0079E104 /* GemRB.xib in Resources */ = {isa = PBXBuildFile; fileRef = A2E27EFB16F12B5A0079E104 /* GemRB.xib */; };
+ A2E6634E139E882900310FC8 /* ActorMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F8D1395FF61006ADC12 /* ActorMgr.cpp */; };
+ A2E6634F139E882900310FC8 /* ActorMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9F8E1395FF61006ADC12 /* ActorMgr.h */; };
+ A2E66350139E882900310FC8 /* Ambient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F8F1395FF61006ADC12 /* Ambient.cpp */; };
+ A2E66351139E882900310FC8 /* Ambient.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9F901395FF61006ADC12 /* Ambient.h */; };
+ A2E66352139E882900310FC8 /* AmbientMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F911395FF61006ADC12 /* AmbientMgr.cpp */; };
+ A2E66353139E882900310FC8 /* AmbientMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9F921395FF61006ADC12 /* AmbientMgr.h */; };
+ A2E66354139E882900310FC8 /* Animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F931395FF61006ADC12 /* Animation.cpp */; };
+ A2E66355139E882900310FC8 /* Animation.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9F941395FF61006ADC12 /* Animation.h */; };
+ A2E66356139E882900310FC8 /* AnimationFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F951395FF61006ADC12 /* AnimationFactory.cpp */; };
+ A2E66357139E883100310FC8 /* AnimationFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9F961395FF61006ADC12 /* AnimationFactory.h */; };
+ A2E66358139E883100310FC8 /* AnimationMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F971395FF61006ADC12 /* AnimationMgr.cpp */; };
+ A2E66359139E883100310FC8 /* AnimationMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9F981395FF61006ADC12 /* AnimationMgr.h */; };
+ A2E6635A139E883100310FC8 /* AnimStructures.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9F991395FF61006ADC12 /* AnimStructures.h */; };
+ A2E6635B139E883100310FC8 /* ArchiveImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F9A1395FF61006ADC12 /* ArchiveImporter.cpp */; };
+ A2E6635C139E883100310FC8 /* ArchiveImporter.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9F9B1395FF61006ADC12 /* ArchiveImporter.h */; };
+ A2E6635D139E883100310FC8 /* Audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F9C1395FF61006ADC12 /* Audio.cpp */; };
+ A2E6635E139E883100310FC8 /* Audio.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9F9D1395FF61006ADC12 /* Audio.h */; };
+ A2E6635F139E883100310FC8 /* Bitmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9F9E1395FF61006ADC12 /* Bitmap.cpp */; };
+ A2E66360139E883100310FC8 /* Bitmap.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9F9F1395FF61006ADC12 /* Bitmap.h */; };
+ A2E66361139E883100310FC8 /* Cache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FA01395FF61006ADC12 /* Cache.cpp */; };
+ A2E66362139E883100310FC8 /* Cache.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FA11395FF61006ADC12 /* Cache.h */; };
+ A2E66363139E883100310FC8 /* Calendar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FA21395FF61006ADC12 /* Calendar.cpp */; };
+ A2E66364139E883100310FC8 /* Calendar.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FA31395FF61006ADC12 /* Calendar.h */; };
+ A2E66365139E883100310FC8 /* Callback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FA41395FF61006ADC12 /* Callback.cpp */; };
+ A2E66366139E883100310FC8 /* Callback.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FA51395FF61006ADC12 /* Callback.h */; };
+ A2E66367139E883100310FC8 /* CharAnimations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FA61395FF61006ADC12 /* CharAnimations.cpp */; };
+ A2E66368139E883100310FC8 /* CharAnimations.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FA71395FF61006ADC12 /* CharAnimations.h */; };
+ A2E66369139E883100310FC8 /* Compressor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FA91395FF61006ADC12 /* Compressor.cpp */; };
+ A2E6636A139E883100310FC8 /* Compressor.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FAA1395FF61006ADC12 /* Compressor.h */; };
+ A2E6636B139E883100310FC8 /* ControlAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FAB1395FF61006ADC12 /* ControlAnimation.cpp */; };
+ A2E6636C139E883100310FC8 /* ControlAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FAC1395FF61006ADC12 /* ControlAnimation.h */; };
+ A2E6636D139E883100310FC8 /* Core.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FAD1395FF61006ADC12 /* Core.cpp */; };
+ A2E6636E139E883100310FC8 /* damages.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FAE1395FF61006ADC12 /* damages.h */; };
+ A2E6636F139E883100310FC8 /* DataFileMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FAF1395FF61006ADC12 /* DataFileMgr.cpp */; };
+ A2E66370139E883100310FC8 /* DataFileMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FB01395FF61006ADC12 /* DataFileMgr.h */; };
+ A2E66371139E883100310FC8 /* Dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FB11395FF61006ADC12 /* Dialog.cpp */; };
+ A2E66372139E883100310FC8 /* Dialog.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FB21395FF61006ADC12 /* Dialog.h */; };
+ A2E66373139E883100310FC8 /* DialogHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FB31395FF61006ADC12 /* DialogHandler.cpp */; };
+ A2E66374139E883100310FC8 /* DialogHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FB41395FF61006ADC12 /* DialogHandler.h */; };
+ A2E66375139E883100310FC8 /* DialogMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FB51395FF61006ADC12 /* DialogMgr.cpp */; };
+ A2E66376139E883100310FC8 /* DialogMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FB61395FF61006ADC12 /* DialogMgr.h */; };
+ A2E66377139E883100310FC8 /* DisplayMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FB71395FF61006ADC12 /* DisplayMessage.cpp */; };
+ A2E66378139E883100310FC8 /* DisplayMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FB81395FF61006ADC12 /* DisplayMessage.h */; };
+ A2E66379139E883100310FC8 /* Effect.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FB91395FF61006ADC12 /* Effect.h */; };
+ A2E6637A139E883100310FC8 /* EffectMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FBA1395FF61006ADC12 /* EffectMgr.cpp */; };
+ A2E6637B139E883100310FC8 /* EffectMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FBB1395FF61006ADC12 /* EffectMgr.h */; };
+ A2E6637C139E883100310FC8 /* EffectQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FBC1395FF61006ADC12 /* EffectQueue.cpp */; };
+ A2E6637D139E883100310FC8 /* EffectQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FBD1395FF61006ADC12 /* EffectQueue.h */; };
+ A2E6637E139E883100310FC8 /* Factory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FBE1395FF61006ADC12 /* Factory.cpp */; };
+ A2E6637F139E883100310FC8 /* Factory.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FBF1395FF61006ADC12 /* Factory.h */; };
+ A2E66380139E883100310FC8 /* FactoryObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FC01395FF61006ADC12 /* FactoryObject.cpp */; };
+ A2E66381139E883100310FC8 /* FactoryObject.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FC11395FF61006ADC12 /* FactoryObject.h */; };
+ A2E66382139E883100310FC8 /* Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FC21395FF61006ADC12 /* Font.cpp */; };
+ A2E66383139E883100310FC8 /* Font.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FC31395FF61006ADC12 /* Font.h */; };
+ A2E66384139E883100310FC8 /* Game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FC41395FF61006ADC12 /* Game.cpp */; };
+ A2E66385139E883100310FC8 /* Game.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FC51395FF62006ADC12 /* Game.h */; };
+ A2E66386139E883100310FC8 /* GameData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FC61395FF62006ADC12 /* GameData.cpp */; };
+ A2E66387139E883100310FC8 /* GameData.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FC71395FF62006ADC12 /* GameData.h */; };
+ A2E66388139E883700310FC8 /* GlobalTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FD21395FF62006ADC12 /* GlobalTimer.cpp */; };
+ A2E66389139E883700310FC8 /* GlobalTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FD31395FF62006ADC12 /* GlobalTimer.h */; };
+ A2E6638A139E883E00310FC8 /* Holder.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FF11395FF62006ADC12 /* Holder.h */; };
+ A2E6638B139E883E00310FC8 /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FF21395FF62006ADC12 /* Image.cpp */; };
+ A2E6638C139E883E00310FC8 /* Image.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FF31395FF62006ADC12 /* Image.h */; };
+ A2E6638D139E883E00310FC8 /* ImageFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FF41395FF62006ADC12 /* ImageFactory.cpp */; };
+ A2E6638E139E883E00310FC8 /* ImageFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FF51395FF62006ADC12 /* ImageFactory.h */; };
+ A2E6638F139E883E00310FC8 /* ImageMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FF61395FF62006ADC12 /* ImageMgr.cpp */; };
+ A2E66390139E883E00310FC8 /* ImageMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FF71395FF62006ADC12 /* ImageMgr.h */; };
+ A2E66391139E883E00310FC8 /* ImageWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FF81395FF62006ADC12 /* ImageWriter.cpp */; };
+ A2E66392139E883E00310FC8 /* ImageWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FF91395FF62006ADC12 /* ImageWriter.h */; };
+ A2E66393139E883E00310FC8 /* IniSpawn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FFA1395FF62006ADC12 /* IniSpawn.cpp */; };
+ A2E66394139E883E00310FC8 /* IniSpawn.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FFB1395FF62006ADC12 /* IniSpawn.h */; };
+ A2E66395139E883E00310FC8 /* Interface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FFC1395FF62006ADC12 /* Interface.cpp */; };
+ A2E66396139E883E00310FC8 /* Interface.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FFD1395FF62006ADC12 /* Interface.h */; };
+ A2E66397139E883E00310FC8 /* Inventory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FFE1395FF62006ADC12 /* Inventory.cpp */; };
+ A2E66398139E883E00310FC8 /* Inventory.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FFF1395FF62006ADC12 /* Inventory.h */; };
+ A2E66399139E883E00310FC8 /* Item.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0001395FF62006ADC12 /* Item.cpp */; };
+ A2E6639A139E883E00310FC8 /* Item.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0011395FF62006ADC12 /* Item.h */; };
+ A2E6639B139E883E00310FC8 /* ItemMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0021395FF62006ADC12 /* ItemMgr.cpp */; };
+ A2E6639C139E883E00310FC8 /* ItemMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0031395FF62006ADC12 /* ItemMgr.h */; };
+ A2E6639D139E883E00310FC8 /* LRUCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0041395FF62006ADC12 /* LRUCache.cpp */; };
+ A2E6639E139E883E00310FC8 /* LRUCache.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0051395FF62006ADC12 /* LRUCache.h */; };
+ A2E6639F139E883E00310FC8 /* Map.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0071395FF62006ADC12 /* Map.cpp */; };
+ A2E663A0139E883E00310FC8 /* Map.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0081395FF62006ADC12 /* Map.h */; };
+ A2E663A1139E883E00310FC8 /* MapMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0091395FF62006ADC12 /* MapMgr.cpp */; };
+ A2E663A2139E883E00310FC8 /* MapMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA00A1395FF62006ADC12 /* MapMgr.h */; };
+ A2E663A3139E883E00310FC8 /* MoviePlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA00B1395FF62006ADC12 /* MoviePlayer.cpp */; };
+ A2E663A4139E883E00310FC8 /* MoviePlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA00C1395FF62006ADC12 /* MoviePlayer.h */; };
+ A2E663A5139E883E00310FC8 /* MusicMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA00D1395FF62006ADC12 /* MusicMgr.cpp */; };
+ A2E663A6139E883E00310FC8 /* MusicMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA00E1395FF62006ADC12 /* MusicMgr.h */; };
+ A2E663A7139E883E00310FC8 /* Palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA00F1395FF62006ADC12 /* Palette.cpp */; };
+ A2E663A8139E883E00310FC8 /* Palette.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0101395FF62006ADC12 /* Palette.h */; };
+ A2E663A9139E883E00310FC8 /* PalettedImageMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0111395FF62006ADC12 /* PalettedImageMgr.cpp */; };
+ A2E663AA139E883E00310FC8 /* PalettedImageMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0121395FF62006ADC12 /* PalettedImageMgr.h */; };
+ A2E663AB139E883E00310FC8 /* Particles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0131395FF62006ADC12 /* Particles.cpp */; };
+ A2E663AC139E883E00310FC8 /* Particles.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0141395FF62006ADC12 /* Particles.h */; };
+ A2E663AD139E883E00310FC8 /* PathFinder.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0151395FF62006ADC12 /* PathFinder.h */; };
+ A2E663AE139E883E00310FC8 /* Plugin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0161395FF62006ADC12 /* Plugin.cpp */; };
+ A2E663AF139E883E00310FC8 /* Plugin.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0171395FF62006ADC12 /* Plugin.h */; };
+ A2E663B0139E883E00310FC8 /* PluginMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0181395FF62006ADC12 /* PluginMgr.cpp */; };
+ A2E663B1139E883E00310FC8 /* PluginMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0191395FF62006ADC12 /* PluginMgr.h */; };
+ A2E663B2139E883E00310FC8 /* Polygon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA01A1395FF62006ADC12 /* Polygon.cpp */; };
+ A2E663B3139E883E00310FC8 /* Polygon.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA01B1395FF62006ADC12 /* Polygon.h */; };
+ A2E663B4139E883E00310FC8 /* PolymorphCache.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA01C1395FF62006ADC12 /* PolymorphCache.h */; };
+ A2E663B5139E883E00310FC8 /* Projectile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA01D1395FF62006ADC12 /* Projectile.cpp */; };
+ A2E663B6139E883E00310FC8 /* Projectile.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA01E1395FF62006ADC12 /* Projectile.h */; };
+ A2E663B7139E883E00310FC8 /* ProjectileMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA01F1395FF62006ADC12 /* ProjectileMgr.cpp */; };
+ A2E663B8139E883E00310FC8 /* ProjectileMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0201395FF62006ADC12 /* ProjectileMgr.h */; };
+ A2E663B9139E883E00310FC8 /* ProjectileServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0211395FF62006ADC12 /* ProjectileServer.cpp */; };
+ A2E663BA139E883E00310FC8 /* ProjectileServer.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0221395FF62006ADC12 /* ProjectileServer.h */; };
+ A2E663BB139E883E00310FC8 /* Region.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0231395FF62006ADC12 /* Region.cpp */; };
+ A2E663BC139E883E00310FC8 /* Region.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0241395FF62006ADC12 /* Region.h */; };
+ A2E663BD139E883E00310FC8 /* Resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0251395FF62006ADC12 /* Resource.cpp */; };
+ A2E663BE139E883E00310FC8 /* Resource.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0261395FF62006ADC12 /* Resource.h */; };
+ A2E663BF139E883E00310FC8 /* ResourceDesc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0271395FF62006ADC12 /* ResourceDesc.cpp */; };
+ A2E663C0139E883E00310FC8 /* ResourceDesc.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0281395FF62006ADC12 /* ResourceDesc.h */; };
+ A2E663C1139E883E00310FC8 /* ResourceManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0291395FF62006ADC12 /* ResourceManager.cpp */; };
+ A2E663C2139E883E00310FC8 /* ResourceManager.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA02A1395FF62006ADC12 /* ResourceManager.h */; };
+ A2E663C3139E883E00310FC8 /* ResourceSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA02B1395FF62006ADC12 /* ResourceSource.cpp */; };
+ A2E663C4139E883E00310FC8 /* ResourceSource.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA02C1395FF62006ADC12 /* ResourceSource.h */; };
+ A2E663C5139E883E00310FC8 /* SaveGame.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA02D1395FF62006ADC12 /* SaveGame.h */; };
+ A2E663C6139E883E00310FC8 /* SaveGameIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA02E1395FF62006ADC12 /* SaveGameIterator.cpp */; };
+ A2E663C7139E883E00310FC8 /* SaveGameIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA02F1395FF62006ADC12 /* SaveGameIterator.h */; };
+ A2E663C8139E883E00310FC8 /* SaveGameMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0301395FF62006ADC12 /* SaveGameMgr.cpp */; };
+ A2E663C9139E883E00310FC8 /* SaveGameMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0311395FF62006ADC12 /* SaveGameMgr.h */; };
+ A2E663CA139E884500310FC8 /* ScriptedAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA03F1395FF62006ADC12 /* ScriptedAnimation.cpp */; };
+ A2E663CB139E884500310FC8 /* ScriptedAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0401395FF62006ADC12 /* ScriptedAnimation.h */; };
+ A2E663CC139E884500310FC8 /* ScriptEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0411395FF62006ADC12 /* ScriptEngine.cpp */; };
+ A2E663CD139E884500310FC8 /* ScriptEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0421395FF62006ADC12 /* ScriptEngine.h */; };
+ A2E663CE139E884500310FC8 /* SoundMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0431395FF62006ADC12 /* SoundMgr.cpp */; };
+ A2E663CF139E884500310FC8 /* SoundMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0441395FF62006ADC12 /* SoundMgr.h */; };
+ A2E663D0139E884500310FC8 /* Spell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0451395FF62006ADC12 /* Spell.cpp */; };
+ A2E663D1139E884500310FC8 /* Spell.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0461395FF62006ADC12 /* Spell.h */; };
+ A2E663D2139E884500310FC8 /* Spellbook.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0471395FF62006ADC12 /* Spellbook.cpp */; };
+ A2E663D3139E884500310FC8 /* Spellbook.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0481395FF62006ADC12 /* Spellbook.h */; };
+ A2E663D4139E884500310FC8 /* SpellMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0491395FF62006ADC12 /* SpellMgr.cpp */; };
+ A2E663D5139E884500310FC8 /* SpellMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA04A1395FF62006ADC12 /* SpellMgr.h */; };
+ A2E663D6139E884500310FC8 /* Sprite2D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA04B1395FF62006ADC12 /* Sprite2D.cpp */; };
+ A2E663D7139E884500310FC8 /* Sprite2D.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA04C1395FF62006ADC12 /* Sprite2D.h */; };
+ A2E663D8139E884500310FC8 /* SpriteCover.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA04D1395FF62006ADC12 /* SpriteCover.cpp */; };
+ A2E663D9139E884500310FC8 /* SpriteCover.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA04E1395FF62006ADC12 /* SpriteCover.h */; };
+ A2E663DA139E884500310FC8 /* Store.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA04F1395FF62006ADC12 /* Store.cpp */; };
+ A2E663DB139E884500310FC8 /* Store.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0501395FF62006ADC12 /* Store.h */; };
+ A2E663DC139E884500310FC8 /* StoreMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0511395FF62006ADC12 /* StoreMgr.cpp */; };
+ A2E663DD139E884500310FC8 /* StoreMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0521395FF62006ADC12 /* StoreMgr.h */; };
+ A2E663DE139E884500310FC8 /* StringMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0531395FF62006ADC12 /* StringMgr.cpp */; };
+ A2E663DF139E884500310FC8 /* StringMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0541395FF62006ADC12 /* StringMgr.h */; };
+ A2E663E0139E884500310FC8 /* SymbolMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0551395FF62006ADC12 /* SymbolMgr.cpp */; };
+ A2E663E1139E884500310FC8 /* SymbolMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0561395FF62006ADC12 /* SymbolMgr.h */; };
+ A2E663E2139E884B00310FC8 /* TableMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0681395FF62006ADC12 /* TableMgr.cpp */; };
+ A2E663E3139E884B00310FC8 /* TableMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0691395FF62006ADC12 /* TableMgr.h */; };
+ A2E663E4139E884B00310FC8 /* Tile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA06A1395FF62006ADC12 /* Tile.cpp */; };
+ A2E663E5139E884B00310FC8 /* Tile.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA06B1395FF62006ADC12 /* Tile.h */; };
+ A2E663E6139E884B00310FC8 /* TileMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA06C1395FF62006ADC12 /* TileMap.cpp */; };
+ A2E663E7139E884B00310FC8 /* TileMap.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA06D1395FF62006ADC12 /* TileMap.h */; };
+ A2E663E8139E884B00310FC8 /* TileMapMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA06E1395FF62006ADC12 /* TileMapMgr.cpp */; };
+ A2E663E9139E884B00310FC8 /* TileMapMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA06F1395FF62006ADC12 /* TileMapMgr.h */; };
+ A2E663EA139E884B00310FC8 /* TileOverlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0701395FF62006ADC12 /* TileOverlay.cpp */; };
+ A2E663EB139E884B00310FC8 /* TileOverlay.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0711395FF62006ADC12 /* TileOverlay.h */; };
+ A2E663EC139E884B00310FC8 /* TileSetMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0721395FF62006ADC12 /* TileSetMgr.cpp */; };
+ A2E663ED139E884B00310FC8 /* TileSetMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0731395FF62006ADC12 /* TileSetMgr.h */; };
+ A2E663EE139E884B00310FC8 /* TypeID.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0741395FF62006ADC12 /* TypeID.h */; };
+ A2E663EF139E884B00310FC8 /* Variables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0751395FF62006ADC12 /* Variables.cpp */; };
+ A2E663F0139E884B00310FC8 /* Variables.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0761395FF62006ADC12 /* Variables.h */; };
+ A2E663F1139E884B00310FC8 /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0771395FF62006ADC12 /* Video.cpp */; };
+ A2E663F2139E884B00310FC8 /* Video.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0781395FF62006ADC12 /* Video.h */; };
+ A2E663F3139E884B00310FC8 /* VideoMode.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0791395FF62006ADC12 /* VideoMode.h */; };
+ A2E663F4139E884B00310FC8 /* WindowMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA07A1395FF62006ADC12 /* WindowMgr.cpp */; };
+ A2E663F5139E884B00310FC8 /* WindowMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA07B1395FF62006ADC12 /* WindowMgr.h */; };
+ A2E663F6139E884B00310FC8 /* WorldMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA07C1395FF62006ADC12 /* WorldMap.cpp */; };
+ A2E663F7139E884B00310FC8 /* WorldMap.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA07D1395FF62006ADC12 /* WorldMap.h */; };
+ A2E663F8139E884B00310FC8 /* WorldMapMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA07E1395FF62006ADC12 /* WorldMapMgr.cpp */; };
+ A2E663F9139E884B00310FC8 /* WorldMapMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA07F1395FF62006ADC12 /* WorldMapMgr.h */; };
+ A2E663FC139E885300310FC8 /* DataStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA05C1395FF62006ADC12 /* DataStream.cpp */; };
+ A2E663FD139E885300310FC8 /* DataStream.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA05D1395FF62006ADC12 /* DataStream.h */; };
+ A2E663FE139E885300310FC8 /* FileStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA05E1395FF62006ADC12 /* FileStream.cpp */; };
+ A2E663FF139E885300310FC8 /* FileStream.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA05F1395FF62006ADC12 /* FileStream.h */; };
+ A2E66401139E885300310FC8 /* MemoryStream.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0611395FF62006ADC12 /* MemoryStream.h */; };
+ A2E66404139E885300310FC8 /* swab.c in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0641395FF62006ADC12 /* swab.c */; };
+ A2E66405139E885300310FC8 /* swab.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0651395FF62006ADC12 /* swab.h */; };
+ A2E66406139E885300310FC8 /* VFS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0661395FF62006ADC12 /* VFS.cpp */; };
+ A2E66407139E885300310FC8 /* VFS.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0671395FF62006ADC12 /* VFS.h */; };
+ A2E66408139E885A00310FC8 /* Actor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0331395FF62006ADC12 /* Actor.cpp */; };
+ A2E66409139E885A00310FC8 /* Actor.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0341395FF62006ADC12 /* Actor.h */; };
+ A2E6640A139E885A00310FC8 /* Container.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0351395FF62006ADC12 /* Container.cpp */; };
+ A2E6640B139E885A00310FC8 /* Container.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0361395FF62006ADC12 /* Container.h */; };
+ A2E6640C139E885A00310FC8 /* Door.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0371395FF62006ADC12 /* Door.cpp */; };
+ A2E6640D139E885A00310FC8 /* Door.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA0381395FF62006ADC12 /* Door.h */; };
+ A2E6640E139E885A00310FC8 /* InfoPoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA0391395FF62006ADC12 /* InfoPoint.cpp */; };
+ A2E6640F139E885A00310FC8 /* InfoPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA03A1395FF62006ADC12 /* InfoPoint.h */; };
+ A2E66410139E885A00310FC8 /* PCStatStruct.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA03B1395FF62006ADC12 /* PCStatStruct.cpp */; };
+ A2E66411139E885A00310FC8 /* PCStatStruct.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA03C1395FF62006ADC12 /* PCStatStruct.h */; };
+ A2E66412139E885A00310FC8 /* Scriptable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BFA03D1395FF62006ADC12 /* Scriptable.cpp */; };
+ A2E66413139E885A00310FC8 /* Scriptable.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BFA03E1395FF62006ADC12 /* Scriptable.h */; };
+ A2E66414139E886100310FC8 /* Button.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FD51395FF62006ADC12 /* Button.cpp */; };
+ A2E66415139E886100310FC8 /* Button.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FD61395FF62006ADC12 /* Button.h */; };
+ A2E66416139E886100310FC8 /* Console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FD71395FF62006ADC12 /* Console.cpp */; };
+ A2E66417139E886100310FC8 /* Console.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FD81395FF62006ADC12 /* Console.h */; };
+ A2E66418139E886100310FC8 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = A2FE553A13982BA6006AB962 /* config.h */; };
+ A2E66419139E886100310FC8 /* Control.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FD91395FF62006ADC12 /* Control.cpp */; };
+ A2E6641A139E886100310FC8 /* Control.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FDA1395FF62006ADC12 /* Control.h */; };
+ A2E6641B139E886100310FC8 /* EventMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FDB1395FF62006ADC12 /* EventMgr.cpp */; };
+ A2E6641C139E886100310FC8 /* EventMgr.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FDC1395FF62006ADC12 /* EventMgr.h */; };
+ A2E6641D139E886100310FC8 /* GameControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FDD1395FF62006ADC12 /* GameControl.cpp */; };
+ A2E6641E139E886100310FC8 /* GameControl.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FDE1395FF62006ADC12 /* GameControl.h */; };
+ A2E6641F139E886100310FC8 /* Label.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FDF1395FF62006ADC12 /* Label.cpp */; };
+ A2E66420139E886100310FC8 /* Label.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FE01395FF62006ADC12 /* Label.h */; };
+ A2E66421139E886100310FC8 /* MapControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FE11395FF62006ADC12 /* MapControl.cpp */; };
+ A2E66422139E886100310FC8 /* MapControl.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FE21395FF62006ADC12 /* MapControl.h */; };
+ A2E66423139E886100310FC8 /* Progressbar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FE31395FF62006ADC12 /* Progressbar.cpp */; };
+ A2E66424139E886100310FC8 /* Progressbar.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FE41395FF62006ADC12 /* Progressbar.h */; };
+ A2E66425139E886100310FC8 /* ScrollBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FE51395FF62006ADC12 /* ScrollBar.cpp */; };
+ A2E66426139E886100310FC8 /* ScrollBar.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FE61395FF62006ADC12 /* ScrollBar.h */; };
+ A2E66427139E886100310FC8 /* Slider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FE71395FF62006ADC12 /* Slider.cpp */; };
+ A2E66428139E886100310FC8 /* Slider.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FE81395FF62006ADC12 /* Slider.h */; };
+ A2E66429139E886100310FC8 /* TextArea.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FE91395FF62006ADC12 /* TextArea.cpp */; };
+ A2E6642A139E886100310FC8 /* TextArea.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FEA1395FF62006ADC12 /* TextArea.h */; };
+ A2E6642B139E886100310FC8 /* TextEdit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FEB1395FF62006ADC12 /* TextEdit.cpp */; };
+ A2E6642C139E886100310FC8 /* TextEdit.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FEC1395FF62006ADC12 /* TextEdit.h */; };
+ A2E6642D139E886100310FC8 /* Window.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FED1395FF62006ADC12 /* Window.cpp */; };
+ A2E6642E139E886100310FC8 /* Window.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FEE1395FF62006ADC12 /* Window.h */; };
+ A2E6642F139E886100310FC8 /* WorldMapControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FEF1395FF62006ADC12 /* WorldMapControl.cpp */; };
+ A2E66430139E886100310FC8 /* WorldMapControl.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FF01395FF62006ADC12 /* WorldMapControl.h */; };
+ A2E66431139E886700310FC8 /* Actions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FC91395FF62006ADC12 /* Actions.cpp */; };
+ A2E66432139E886700310FC8 /* GameScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FCA1395FF62006ADC12 /* GameScript.cpp */; };
+ A2E66433139E886700310FC8 /* GameScript.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FCB1395FF62006ADC12 /* GameScript.h */; };
+ A2E66434139E886700310FC8 /* GSUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FCC1395FF62006ADC12 /* GSUtils.cpp */; };
+ A2E66435139E886700310FC8 /* GSUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FCD1395FF62006ADC12 /* GSUtils.h */; };
+ A2E66436139E886700310FC8 /* Matching.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FCE1395FF62006ADC12 /* Matching.cpp */; };
+ A2E66437139E886700310FC8 /* Matching.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BF9FCF1395FF62006ADC12 /* Matching.h */; };
+ A2E66438139E886700310FC8 /* Objects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FD01395FF62006ADC12 /* Objects.cpp */; };
+ A2E66439139E886700310FC8 /* Triggers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2BF9FD11395FF62006ADC12 /* Triggers.cpp */; };
+ A2E66486139E907000310FC8 /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A2E9965314DE05590052BABE /* 2DAImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A27E830A13A0358200B41410 /* 2DAImporter.so */; };
+ A2E9965414DE05590052BABE /* ACMReader.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A2FCD5FB13A0366100271997 /* ACMReader.so */; };
+ A2E9965514DE05590052BABE /* AREImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A2462F1113A036B1002D1F02 /* AREImporter.so */; };
+ A2E9965614DE05590052BABE /* BAMImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A29BF7B213A0380F00C812DD /* BAMImporter.so */; };
+ A2E9965714DE05590052BABE /* BIFImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B3CA13A2867900D41A8A /* BIFImporter.so */; };
+ A2E9965814DE05590052BABE /* BIKPlayer.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B3D113A286A800D41A8A /* BIKPlayer.so */; };
+ A2E9965914DE05590052BABE /* BMPImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B3D713A286BC00D41A8A /* BMPImporter.so */; };
+ A2E9965A14DE05590052BABE /* BMPWriter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B3DD13A286CD00D41A8A /* BMPWriter.so */; };
+ A2E9965B14DE05590052BABE /* CHUImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B3E313A286DE00D41A8A /* CHUImporter.so */; };
+ A2E9965C14DE05590052BABE /* CREImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B3E913A286EC00D41A8A /* CREImporter.so */; };
+ A2E9965D14DE05590052BABE /* DirectoryImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B3EF13A286FB00D41A8A /* DirectoryImporter.so */; };
+ A2E9965E14DE05590052BABE /* DLGImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B3F513A2871300D41A8A /* DLGImporter.so */; };
+ A2E9965F14DE05590052BABE /* EFFImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B3FB13A2872500D41A8A /* EFFImporter.so */; };
+ A2E9966014DE05590052BABE /* FXOpcodes.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B40113A2873700D41A8A /* FXOpcodes.so */; };
+ A2E9966114DE05590052BABE /* GAMImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B40713A2874700D41A8A /* GAMImporter.so */; };
+ A2E9966214DE05590052BABE /* GUIScript.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B40D13A2875400D41A8A /* GUIScript.so */; };
+ A2E9966314DE05590052BABE /* IDSImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B41313A2876300D41A8A /* IDSImporter.so */; };
+ A2E9966414DE05590052BABE /* INIImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B41913A2877100D41A8A /* INIImporter.so */; };
+ A2E9966514DE05590052BABE /* ITMImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B41F13A2878400D41A8A /* ITMImporter.so */; };
+ A2E9966614DE05590052BABE /* IWDOpcodes.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B42513A2879900D41A8A /* IWDOpcodes.so */; };
+ A2E9966714DE05590052BABE /* KEYImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B42B13A287AB00D41A8A /* KEYImporter.so */; };
+ A2E9966814DE05590052BABE /* MOSImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B43113A287BD00D41A8A /* MOSImporter.so */; };
+ A2E9966914DE05590052BABE /* MUSImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B44913A289E000D41A8A /* MUSImporter.so */; };
+ A2E9966A14DE05590052BABE /* MVEPlayer.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B44F13A28A0000D41A8A /* MVEPlayer.so */; };
+ A2E9966B14DE05590052BABE /* NullSound.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B45513A28A0E00D41A8A /* NullSound.so */; };
+ A2E9966C14DE05590052BABE /* OpenALAudio.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B46113A28A3100D41A8A /* OpenALAudio.so */; };
+ A2E9966D14DE05590052BABE /* PLTImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B46713A28A3F00D41A8A /* PLTImporter.so */; };
+ A2E9966E14DE05590052BABE /* PROImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B47313A28A5D00D41A8A /* PROImporter.so */; };
+ A2E9966F14DE05590052BABE /* PSTOpcodes.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B47913A28A7600D41A8A /* PSTOpcodes.so */; };
+ A2E9967214DE05590052BABE /* SPLImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B48B13A28A9E00D41A8A /* SPLImporter.so */; };
+ A2E9967314DE05590052BABE /* TISImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B49113A28AA900D41A8A /* TISImporter.so */; };
+ A2E9967414DE05590052BABE /* TLKImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B49713A28AB800D41A8A /* TLKImporter.so */; };
+ A2E9967514DE05590052BABE /* WAVReader.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B49D13A28AC800D41A8A /* WAVReader.so */; };
+ A2E9967614DE05590052BABE /* WEDImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B4A313A28AD300D41A8A /* WEDImporter.so */; };
+ A2E9967714DE05590052BABE /* WMPImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B4A913A28AE100D41A8A /* WMPImporter.so */; };
+ A2E9967814DE05590052BABE /* ZLibManager.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B4AF13A28AEE00D41A8A /* ZLibManager.so */; };
+ A2E9967914DE05590052BABE /* STOImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A276B4F413A28C0400D41A8A /* STOImporter.so */; };
+ A2E9967A14DE05590052BABE /* SAVImporter.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A2F0505113ABB80B0023B7EB /* SAVImporter.so */; };
+ A2EC8059145F9E6E0033754A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2EC8058145F9E6E0033754A /* Foundation.framework */; };
+ A2EC805B1460556B0033754A /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2EC805A1460556B0033754A /* OpenAL.framework */; };
+ A2EC805D1460559C0033754A /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2EC805C1460559C0033754A /* CoreAudio.framework */; };
+ A2EC8061146055D80033754A /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2EC805F146055D80033754A /* OpenGLES.framework */; };
+ A2EC8063146056490033754A /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2EC8062146056490033754A /* QuartzCore.framework */; };
+ A2EC8065146056900033754A /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2EC8064146056900033754A /* AudioToolbox.framework */; };
+ A2EC8067146056B40033754A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2EC8066146056B40033754A /* CoreGraphics.framework */; };
+ A2F0505613ABB82D0023B7EB /* SAVImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27979AC13ABA4F7009A6FEF /* SAVImporter.cpp */; };
+ A2F0505B13ABB84C0023B7EB /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A2FE2C7316F21CBF00DDC6C7 /* defaults.plist in Resources */ = {isa = PBXBuildFile; fileRef = A2FE2C7216F21CBF00DDC6C7 /* defaults.plist */; };
+ A2FE2C7416F21CBF00DDC6C7 /* defaults.plist in Resources */ = {isa = PBXBuildFile; fileRef = A2FE2C7216F21CBF00DDC6C7 /* defaults.plist */; };
+ A2FE2C7D16F2316400DDC6C7 /* libgemrb_core.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */; };
+ A2FE2C8416F231ED00DDC6C7 /* NullSound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A27B872F139F0A7D0002DC13 /* NullSound.cpp */; };
+ A2FE2C8516F231ED00DDC6C7 /* NullSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2FE2C7716F2313400DDC6C7 /* NullSource.cpp */; };
+ A2FE2C8616F2320300DDC6C7 /* NullSource.so in CopyFiles */ = {isa = PBXBuildFile; fileRef = A2FE2C8116F2316400DDC6C7 /* NullSource.so */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ A2375BA013AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A27E830913A0358200B41410;
+ remoteInfo = 2DAImporter;
+ };
+ A2375BA213AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A2FCD5FA13A0366100271997;
+ remoteInfo = ACMReader;
+ };
+ A2375BA413AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A2462F1013A036B1002D1F02;
+ remoteInfo = AREImporter;
+ };
+ A2375BA613AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A29BF7B113A0380F00C812DD;
+ remoteInfo = BAMImporter;
+ };
+ A2375BA813AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B3C913A2867900D41A8A;
+ remoteInfo = BIFImporter;
+ };
+ A2375BAA13AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B3D013A286A800D41A8A;
+ remoteInfo = BIKPlayer;
+ };
+ A2375BAC13AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B3D613A286BC00D41A8A;
+ remoteInfo = BMPImporter;
+ };
+ A2375BAE13AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B3DC13A286CD00D41A8A;
+ remoteInfo = BMPWriter;
+ };
+ A2375BB013AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B3E213A286DE00D41A8A;
+ remoteInfo = CHUImporter;
+ };
+ A2375BB213AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B3E813A286EC00D41A8A;
+ remoteInfo = CREImporter;
+ };
+ A2375BB413AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B3EE13A286FB00D41A8A;
+ remoteInfo = DirectoryImporter;
+ };
+ A2375BB613AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B3F413A2871300D41A8A;
+ remoteInfo = DLGImporter;
+ };
+ A2375BB813AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B3FA13A2872500D41A8A;
+ remoteInfo = EFFImporter;
+ };
+ A2375BBA13AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B40013A2873700D41A8A;
+ remoteInfo = FXOpcodes;
+ };
+ A2375BBC13AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B40613A2874700D41A8A;
+ remoteInfo = GAMImporter;
+ };
+ A2375BBE13AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B40C13A2875400D41A8A;
+ remoteInfo = GUIScript;
+ };
+ A2375BC013AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B41213A2876300D41A8A;
+ remoteInfo = IDSImporter;
+ };
+ A2375BC213AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B41813A2877100D41A8A;
+ remoteInfo = INIImporter;
+ };
+ A2375BC413AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B41E13A2878400D41A8A;
+ remoteInfo = ITMImporter;
+ };
+ A2375BC613AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B42413A2879900D41A8A;
+ remoteInfo = IWDOpcodes;
+ };
+ A2375BC813AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B42A13A287AB00D41A8A;
+ remoteInfo = KEYImporter;
+ };
+ A2375BCA13AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B43013A287BC00D41A8A;
+ remoteInfo = MOSImporter;
+ };
+ A2375BCC13AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B44813A289E000D41A8A;
+ remoteInfo = MUSImporter;
+ };
+ A2375BCE13AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B44E13A28A0000D41A8A;
+ remoteInfo = MVEPlayer;
+ };
+ A2375BD213AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B46013A28A3100D41A8A;
+ remoteInfo = OpenALAudio;
+ };
+ A2375BD413AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B46613A28A3F00D41A8A;
+ remoteInfo = PLTImporter;
+ };
+ A2375BD613AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B47213A28A5D00D41A8A;
+ remoteInfo = PROImporter;
+ };
+ A2375BD813AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B47813A28A7600D41A8A;
+ remoteInfo = PSTOpcodes;
+ };
+ A2375BDC13AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B48A13A28A9E00D41A8A;
+ remoteInfo = SPLImporter;
+ };
+ A2375BDE13AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B4F313A28C0400D41A8A;
+ remoteInfo = STOImporter;
+ };
+ A2375BE013AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B49013A28AA800D41A8A;
+ remoteInfo = TISImporter;
+ };
+ A2375BE213AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B49613A28AB800D41A8A;
+ remoteInfo = TLKImporter;
+ };
+ A2375BE413AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B49C13A28AC800D41A8A;
+ remoteInfo = WAVReader;
+ };
+ A2375BE613AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B4A213A28AD300D41A8A;
+ remoteInfo = WEDImporter;
+ };
+ A2375BE813AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B4A813A28AE100D41A8A;
+ remoteInfo = WMPImporter;
+ };
+ A2375BEA13AAF58E00E7EF9B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B4AE13A28AEE00D41A8A;
+ remoteInfo = ZLibManager;
+ };
+ A23EBFFB1419A81500CC049E /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A2F0505013ABB80B0023B7EB;
+ remoteInfo = SAVImporter;
+ };
+ A295046E1609721300BB22AA /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A2E66337139E875400310FC8;
+ remoteInfo = gemrb_core;
+ };
+ A29504791609725F00BB22AA /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A295046C1609721300BB22AA;
+ remoteInfo = TTFImporter;
+ };
+ A295048616097E3700BB22AA /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B45A13A28A1C00D41A8A;
+ remoteInfo = OGGReader;
+ };
+ A295049016097F9D00BB22AA /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B46C13A28A5000D41A8A;
+ remoteInfo = PNGImporter;
+ };
+ A29F3EE315A8E6DE00C85084 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A2BD124A15A7EDFE000FAB95;
+ remoteInfo = VLCPlayer;
+ };
+ A2AF8FCC14DDCEBD005CAC5D /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A276B45413A28A0E00D41A8A;
+ remoteInfo = NullSound;
+ };
+ A2BD124C15A7EDFE000FAB95 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A2E66337139E875400310FC8;
+ remoteInfo = gemrb_core;
+ };
+ A2C48CEA14A3FEF600575FE5 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A2E66337139E875400310FC8;
+ remoteInfo = gemrb_core;
+ };
+ A2C48CEC14A3FEFA00575FE5 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A2E66337139E875400310FC8;
+ remoteInfo = gemrb_core;
+ };
+ A2C48CEE14A3FEFD00575FE5 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A2E66337139E875400310FC8;
+ remoteInfo = gemrb_core;
+ };
+ A2C48CF014A3FF0000575FE5 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A2E66337139E875400310FC8;
+ remoteInfo = gemrb_core;
+ };
+ A2C48CF214A3FF0300575FE5 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A2E66337139E875400310FC8;
+ remoteInfo = gemrb_core;
+ };
+ A2C48CF414A3FF0600575FE5 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A2E66337139E875400310FC8;
+ remoteInfo = gemrb_core;
+ };
+ A2C48CF614A3FF0900575FE5 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A2E66337139E875400310FC8;
+ remoteInfo = gemrb_core;
+ };
+ A2C48CF814A3FF0D00575FE5 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A2E66337139E875400310FC8;
+ remoteInfo = gemrb_core;
+ };
+ A2E6633B139E876900310FC8 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A2E66337139E875400310FC8;
+ remoteInfo = libgemrb_core.dylib;
+ };
+ A2E9967D14DE12970052BABE /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A2E66337139E875400310FC8;
+ remoteInfo = gemrb_core;
+ };
+ A2E9967F14DE12A90052BABE /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A2E66337139E875400310FC8;
+ remoteInfo = gemrb_core;
+ };
+ A2F8709014AE43BB00F9CC1F /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 8D1107260486CEB800E47090;
+ remoteInfo = "GemRB OS X";
+ };
+ A2F8709314AE4A8F00F9CC1F /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A29BF85B13A0427900C812DD;
+ remoteInfo = "GemRB iOS";
+ };
+ A2FE2C8216F231CB00DDC6C7 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A2FE2C7916F2316400DDC6C7;
+ remoteInfo = NullSource;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 002F39FD09D0883400EBEB88 /* Copy Frameworks into .app bundle */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ A2D0505114D0B06C00D8CD77 /* SDL.framework in Copy Frameworks into .app bundle */,
+ A2D0504F14D0AFCA00D8CD77 /* libgemrb_core.dylib in Copy Frameworks into .app bundle */,
+ );
+ name = "Copy Frameworks into .app bundle";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A2E9965214DE051F0052BABE /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 13;
+ files = (
+ A2FE2C8616F2320300DDC6C7 /* NullSource.so in CopyFiles */,
+ A29504781609724F00BB22AA /* TTFImporter.so in CopyFiles */,
+ A2BD125E15A8E63B000FAB95 /* VLCPlayer.so in CopyFiles */,
+ A2E9965314DE05590052BABE /* 2DAImporter.so in CopyFiles */,
+ A2E9965414DE05590052BABE /* ACMReader.so in CopyFiles */,
+ A2E9965514DE05590052BABE /* AREImporter.so in CopyFiles */,
+ A2E9965614DE05590052BABE /* BAMImporter.so in CopyFiles */,
+ A2E9965714DE05590052BABE /* BIFImporter.so in CopyFiles */,
+ A2E9965814DE05590052BABE /* BIKPlayer.so in CopyFiles */,
+ A2E9965914DE05590052BABE /* BMPImporter.so in CopyFiles */,
+ A2E9965A14DE05590052BABE /* BMPWriter.so in CopyFiles */,
+ A2E9965B14DE05590052BABE /* CHUImporter.so in CopyFiles */,
+ A2E9965C14DE05590052BABE /* CREImporter.so in CopyFiles */,
+ A2E9965D14DE05590052BABE /* DirectoryImporter.so in CopyFiles */,
+ A2E9965E14DE05590052BABE /* DLGImporter.so in CopyFiles */,
+ A2E9965F14DE05590052BABE /* EFFImporter.so in CopyFiles */,
+ A2E9966014DE05590052BABE /* FXOpcodes.so in CopyFiles */,
+ A2E9966114DE05590052BABE /* GAMImporter.so in CopyFiles */,
+ A2E9966214DE05590052BABE /* GUIScript.so in CopyFiles */,
+ A2E9966314DE05590052BABE /* IDSImporter.so in CopyFiles */,
+ A2E9966414DE05590052BABE /* INIImporter.so in CopyFiles */,
+ A2E9966514DE05590052BABE /* ITMImporter.so in CopyFiles */,
+ A2E9966614DE05590052BABE /* IWDOpcodes.so in CopyFiles */,
+ A2E9966714DE05590052BABE /* KEYImporter.so in CopyFiles */,
+ A2E9966814DE05590052BABE /* MOSImporter.so in CopyFiles */,
+ A2E9966914DE05590052BABE /* MUSImporter.so in CopyFiles */,
+ A2E9966A14DE05590052BABE /* MVEPlayer.so in CopyFiles */,
+ A2E9966B14DE05590052BABE /* NullSound.so in CopyFiles */,
+ A2E9966C14DE05590052BABE /* OpenALAudio.so in CopyFiles */,
+ A2E9966D14DE05590052BABE /* PLTImporter.so in CopyFiles */,
+ A2E9966E14DE05590052BABE /* PROImporter.so in CopyFiles */,
+ A2E9966F14DE05590052BABE /* PSTOpcodes.so in CopyFiles */,
+ A2E9967214DE05590052BABE /* SPLImporter.so in CopyFiles */,
+ A2E9967314DE05590052BABE /* TISImporter.so in CopyFiles */,
+ A2E9967414DE05590052BABE /* TLKImporter.so in CopyFiles */,
+ A2E9967514DE05590052BABE /* WAVReader.so in CopyFiles */,
+ A2E9967614DE05590052BABE /* WEDImporter.so in CopyFiles */,
+ A2E9967714DE05590052BABE /* WMPImporter.so in CopyFiles */,
+ A2E9967814DE05590052BABE /* ZLibManager.so in CopyFiles */,
+ A2E9967914DE05590052BABE /* STOImporter.so in CopyFiles */,
+ A2E9967A14DE05590052BABE /* SAVImporter.so in CopyFiles */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+ 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+ 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
+ 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
+ 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = osx/Info.plist; sourceTree = "<group>"; };
+ 8D1107320486CEB800E47090 /* GemRB.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GemRB.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ A218A75114A8F3DB001142CF /* ../artwork/gemrb.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = ../artwork/gemrb.icns; sourceTree = "<group>"; };
+ A22693781422931B004468E8 /* CocoaWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CocoaWrapper.h; path = ../gemrb/includes/CocoaWrapper.h; sourceTree = "<group>"; };
+ A228D24816A86FA00053375D /* libiconv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libiconv.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/usr/lib/libiconv.dylib; sourceTree = DEVELOPER_DIR; };
+ A22B5D5D1583D816007B4AA4 /* libFreetype2.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libFreetype2.a; path = ios/lib/iphonesimulator/libFreetype2.a; sourceTree = "<group>"; };
+ A22B5D5E1583D816007B4AA4 /* libPython.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libPython.a; path = ios/lib/iphonesimulator/libPython.a; sourceTree = "<group>"; };
+ A22B5D601583D816007B4AA4 /* libSDL2.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libSDL2.a; path = ios/lib/iphonesimulator/libSDL2.a; sourceTree = "<group>"; };
+ A22DCCDE14A8FE0F0067D6D1 /* ios/Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ios/Icon.png; sourceTree = "<group>"; };
+ A22DCCE014A8FE120067D6D1 /* ios/Icon at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "ios/Icon at 2x.png"; sourceTree = "<group>"; };
+ A22DCCE214A8FE870067D6D1 /* ios/Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "ios/Icon-72.png"; sourceTree = "<group>"; };
+ A22EBDCC14FF18030029C9C1 /* AppleLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppleLogger.h; sourceTree = "<group>"; };
+ A22EBDCD14FF18030029C9C1 /* AppleLogger.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AppleLogger.mm; sourceTree = "<group>"; };
+ A230584715D5BBCC00BDF69C /* MessageWindowLogger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MessageWindowLogger.cpp; sourceTree = "<group>"; };
+ A230584815D5BBCC00BDF69C /* MessageWindowLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageWindowLogger.h; sourceTree = "<group>"; };
+ A2374CA115F1486E002A1C8C /* libbz2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbz2.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/usr/lib/libbz2.dylib; sourceTree = DEVELOPER_DIR; };
+ A238174914B781CC0058BFF4 /* GemRB.cfg.newinstall */ = {isa = PBXFileReference; lastKnownFileType = text; name = GemRB.cfg.newinstall; path = ios/GemRB.cfg.newinstall; sourceTree = "<group>"; };
+ A239390A145F8677007895B3 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
+ A2462F1113A036B1002D1F02 /* AREImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = AREImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A249187B141075A60038B170 /* CocoaWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CocoaWrapper.m; sourceTree = "<group>"; };
+ A2491880141092F20038B170 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+ A265ECD813A8661600C6DF12 /* FileCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FileCache.cpp; path = ../gemrb/core/FileCache.cpp; sourceTree = SOURCE_ROOT; };
+ A265ECD913A8661600C6DF12 /* IndexedArchive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IndexedArchive.cpp; path = ../gemrb/core/IndexedArchive.cpp; sourceTree = SOURCE_ROOT; };
+ A265ECDA13A8661600C6DF12 /* KeyMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KeyMap.cpp; path = ../gemrb/core/KeyMap.cpp; sourceTree = SOURCE_ROOT; };
+ A265ECDB13A8661600C6DF12 /* PluginLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PluginLoader.cpp; path = ../gemrb/core/PluginLoader.cpp; sourceTree = SOURCE_ROOT; };
+ A265ECEA13A8669700C6DF12 /* Logging.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Logging.cpp; path = ../gemrb/core/System/Logging.cpp; sourceTree = SOURCE_ROOT; };
+ A265ECEB13A8669700C6DF12 /* SlicedStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SlicedStream.cpp; path = ../gemrb/core/System/SlicedStream.cpp; sourceTree = SOURCE_ROOT; };
+ A265ECEC13A8669700C6DF12 /* String.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = String.cpp; path = ../gemrb/core/System/String.cpp; sourceTree = SOURCE_ROOT; };
+ A273DC7B14856755000DA299 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = "<absolute>"; };
+ A276B3CA13A2867900D41A8A /* BIFImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = BIFImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B3D113A286A800D41A8A /* BIKPlayer.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = BIKPlayer.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B3D713A286BC00D41A8A /* BMPImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = BMPImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B3DD13A286CD00D41A8A /* BMPWriter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = BMPWriter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B3E313A286DE00D41A8A /* CHUImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = CHUImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B3E913A286EC00D41A8A /* CREImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = CREImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B3EF13A286FB00D41A8A /* DirectoryImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = DirectoryImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B3F513A2871300D41A8A /* DLGImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = DLGImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B3FB13A2872500D41A8A /* EFFImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = EFFImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B40113A2873700D41A8A /* FXOpcodes.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = FXOpcodes.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B40713A2874700D41A8A /* GAMImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = GAMImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B40D13A2875400D41A8A /* GUIScript.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = GUIScript.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B41313A2876300D41A8A /* IDSImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = IDSImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B41913A2877100D41A8A /* INIImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = INIImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B41F13A2878400D41A8A /* ITMImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = ITMImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B42513A2879900D41A8A /* IWDOpcodes.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = IWDOpcodes.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B42B13A287AB00D41A8A /* KEYImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = KEYImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B43113A287BD00D41A8A /* MOSImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = MOSImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B44913A289E000D41A8A /* MUSImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = MUSImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B44F13A28A0000D41A8A /* MVEPlayer.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = MVEPlayer.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B45513A28A0E00D41A8A /* NullSound.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = NullSound.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B45B13A28A1C00D41A8A /* OGGReader.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = OGGReader.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B46113A28A3100D41A8A /* OpenALAudio.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = OpenALAudio.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B46713A28A3F00D41A8A /* PLTImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = PLTImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B46D13A28A5000D41A8A /* PNGImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = PNGImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B47313A28A5D00D41A8A /* PROImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = PROImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B47913A28A7600D41A8A /* PSTOpcodes.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = PSTOpcodes.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B47F13A28A8500D41A8A /* SDLAudio.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = SDLAudio.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B48513A28A9000D41A8A /* SDLVideo.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = SDLVideo.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B48B13A28A9E00D41A8A /* SPLImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = SPLImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B49113A28AA900D41A8A /* TISImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = TISImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B49713A28AB800D41A8A /* TLKImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = TLKImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B49D13A28AC800D41A8A /* WAVReader.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = WAVReader.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B4A313A28AD300D41A8A /* WEDImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = WEDImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B4A913A28AE100D41A8A /* WMPImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = WMPImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B4AF13A28AEE00D41A8A /* ZLibManager.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = ZLibManager.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A276B4F413A28C0400D41A8A /* STOImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = STOImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A27979AC13ABA4F7009A6FEF /* SAVImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SAVImporter.cpp; sourceTree = "<group>"; };
+ A27979AD13ABA4F7009A6FEF /* SAVImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SAVImporter.h; sourceTree = "<group>"; };
+ A27B8699139F0A7D0002DC13 /* 2DAImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = 2DAImporter.cpp; sourceTree = "<group>"; };
+ A27B869A139F0A7D0002DC13 /* 2DAImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 2DAImporter.h; sourceTree = "<group>"; };
+ A27B869E139F0A7D0002DC13 /* ACMReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ACMReader.cpp; sourceTree = "<group>"; };
+ A27B869F139F0A7D0002DC13 /* ACMReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ACMReader.h; sourceTree = "<group>"; };
+ A27B86A1139F0A7D0002DC13 /* decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = decoder.cpp; sourceTree = "<group>"; };
+ A27B86A2139F0A7D0002DC13 /* decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = decoder.h; sourceTree = "<group>"; };
+ A27B86A3139F0A7D0002DC13 /* general.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = general.h; sourceTree = "<group>"; };
+ A27B86A5139F0A7D0002DC13 /* unpacker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unpacker.cpp; sourceTree = "<group>"; };
+ A27B86A6139F0A7D0002DC13 /* unpacker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unpacker.h; sourceTree = "<group>"; };
+ A27B86A8139F0A7D0002DC13 /* AREImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AREImporter.cpp; sourceTree = "<group>"; };
+ A27B86A9139F0A7D0002DC13 /* AREImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AREImporter.h; sourceTree = "<group>"; };
+ A27B86AD139F0A7D0002DC13 /* BAMImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BAMImporter.cpp; sourceTree = "<group>"; };
+ A27B86AE139F0A7D0002DC13 /* BAMImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BAMImporter.h; sourceTree = "<group>"; };
+ A27B86B2139F0A7D0002DC13 /* BIFImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BIFImporter.cpp; sourceTree = "<group>"; };
+ A27B86B3139F0A7D0002DC13 /* BIFImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BIFImporter.h; sourceTree = "<group>"; };
+ A27B86B7139F0A7D0002DC13 /* BIKPlayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BIKPlayer.cpp; sourceTree = "<group>"; };
+ A27B86B8139F0A7D0002DC13 /* BIKPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BIKPlayer.h; sourceTree = "<group>"; };
+ A27B86B9139F0A7D0002DC13 /* binkdata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = binkdata.h; sourceTree = "<group>"; };
+ A27B86BB139F0A7D0002DC13 /* common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = "<group>"; };
+ A27B86BC139F0A7D0002DC13 /* dct.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dct.cpp; sourceTree = "<group>"; };
+ A27B86BD139F0A7D0002DC13 /* dsputil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dsputil.h; sourceTree = "<group>"; };
+ A27B86BE139F0A7D0002DC13 /* fft.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fft.cpp; sourceTree = "<group>"; };
+ A27B86BF139F0A7D0002DC13 /* GetBitContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GetBitContext.cpp; sourceTree = "<group>"; };
+ A27B86C0139F0A7D0002DC13 /* GetBitContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GetBitContext.h; sourceTree = "<group>"; };
+ A27B86C2139F0A7D0002DC13 /* mem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mem.cpp; sourceTree = "<group>"; };
+ A27B86C3139F0A7D0002DC13 /* rational.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rational.cpp; sourceTree = "<group>"; };
+ A27B86C4139F0A7D0002DC13 /* rational.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rational.h; sourceTree = "<group>"; };
+ A27B86C5139F0A7D0002DC13 /* rdft.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rdft.cpp; sourceTree = "<group>"; };
+ A27B86C7139F0A7D0002DC13 /* BMPImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BMPImporter.cpp; sourceTree = "<group>"; };
+ A27B86C8139F0A7D0002DC13 /* BMPImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BMPImporter.h; sourceTree = "<group>"; };
+ A27B86CC139F0A7D0002DC13 /* BMPWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BMPWriter.cpp; sourceTree = "<group>"; };
+ A27B86CD139F0A7D0002DC13 /* BMPWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BMPWriter.h; sourceTree = "<group>"; };
+ A27B86D1139F0A7D0002DC13 /* CHUImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CHUImporter.cpp; sourceTree = "<group>"; };
+ A27B86D2139F0A7D0002DC13 /* CHUImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CHUImporter.h; sourceTree = "<group>"; };
+ A27B86D8139F0A7D0002DC13 /* CREImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CREImporter.cpp; sourceTree = "<group>"; };
+ A27B86D9139F0A7D0002DC13 /* CREImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CREImporter.h; sourceTree = "<group>"; };
+ A27B86DD139F0A7D0002DC13 /* DirectoryImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectoryImporter.cpp; sourceTree = "<group>"; };
+ A27B86DE139F0A7D0002DC13 /* DirectoryImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryImporter.h; sourceTree = "<group>"; };
+ A27B86E2139F0A7D0002DC13 /* DLGImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DLGImporter.cpp; sourceTree = "<group>"; };
+ A27B86E3139F0A7D0002DC13 /* DLGImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DLGImporter.h; sourceTree = "<group>"; };
+ A27B86E7139F0A7D0002DC13 /* EFFImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EFFImporter.cpp; sourceTree = "<group>"; };
+ A27B86E8139F0A7D0002DC13 /* EFFImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EFFImporter.h; sourceTree = "<group>"; };
+ A27B86EC139F0A7D0002DC13 /* FXOpcodes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FXOpcodes.cpp; sourceTree = "<group>"; };
+ A27B86F0139F0A7D0002DC13 /* GAMImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GAMImporter.cpp; sourceTree = "<group>"; };
+ A27B86F1139F0A7D0002DC13 /* GAMImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GAMImporter.h; sourceTree = "<group>"; };
+ A27B86F5139F0A7D0002DC13 /* GUIScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIScript.cpp; sourceTree = "<group>"; };
+ A27B86F6139F0A7D0002DC13 /* GUIScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIScript.h; sourceTree = "<group>"; };
+ A27B86F8139F0A7D0002DC13 /* PythonHelpers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PythonHelpers.cpp; sourceTree = "<group>"; };
+ A27B86F9139F0A7D0002DC13 /* PythonHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PythonHelpers.h; sourceTree = "<group>"; };
+ A27B86FC139F0A7D0002DC13 /* IDSImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDSImporter.cpp; sourceTree = "<group>"; };
+ A27B86FD139F0A7D0002DC13 /* IDSImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDSImporter.h; sourceTree = "<group>"; };
+ A27B86FE139F0A7D0002DC13 /* IDSImporterDefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDSImporterDefs.h; sourceTree = "<group>"; };
+ A27B8702139F0A7D0002DC13 /* INIImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = INIImporter.cpp; sourceTree = "<group>"; };
+ A27B8703139F0A7D0002DC13 /* INIImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = INIImporter.h; sourceTree = "<group>"; };
+ A27B8707139F0A7D0002DC13 /* ITMImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ITMImporter.cpp; sourceTree = "<group>"; };
+ A27B8708139F0A7D0002DC13 /* ITMImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ITMImporter.h; sourceTree = "<group>"; };
+ A27B870C139F0A7D0002DC13 /* IWDOpcodes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IWDOpcodes.cpp; sourceTree = "<group>"; };
+ A27B8710139F0A7D0002DC13 /* Dictionary.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Dictionary.cpp; sourceTree = "<group>"; };
+ A27B8711139F0A7D0002DC13 /* Dictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Dictionary.h; sourceTree = "<group>"; };
+ A27B8712139F0A7D0002DC13 /* KEYImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KEYImporter.cpp; sourceTree = "<group>"; };
+ A27B8713139F0A7D0002DC13 /* KEYImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KEYImporter.h; sourceTree = "<group>"; };
+ A27B8719139F0A7D0002DC13 /* MOSImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MOSImporter.cpp; sourceTree = "<group>"; };
+ A27B871A139F0A7D0002DC13 /* MOSImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MOSImporter.h; sourceTree = "<group>"; };
+ A27B871E139F0A7D0002DC13 /* MUSImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MUSImporter.cpp; sourceTree = "<group>"; };
+ A27B871F139F0A7D0002DC13 /* MUSImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MUSImporter.h; sourceTree = "<group>"; };
+ A27B8722139F0A7D0002DC13 /* gstmvedemux.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gstmvedemux.h; sourceTree = "<group>"; };
+ A27B8724139F0A7D0002DC13 /* mve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mve.h; sourceTree = "<group>"; };
+ A27B8725139F0A7D0002DC13 /* mve_player.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mve_player.cpp; sourceTree = "<group>"; };
+ A27B8726139F0A7D0002DC13 /* mve_player.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mve_player.h; sourceTree = "<group>"; };
+ A27B8727139F0A7D0002DC13 /* mveaudiodec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mveaudiodec.cpp; sourceTree = "<group>"; };
+ A27B8728139F0A7D0002DC13 /* MVEPlayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MVEPlayer.cpp; sourceTree = "<group>"; };
+ A27B8729139F0A7D0002DC13 /* MVEPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVEPlayer.h; sourceTree = "<group>"; };
+ A27B872A139F0A7D0002DC13 /* mvevideodec16.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mvevideodec16.cpp; sourceTree = "<group>"; };
+ A27B872B139F0A7D0002DC13 /* mvevideodec8.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mvevideodec8.cpp; sourceTree = "<group>"; };
+ A27B872F139F0A7D0002DC13 /* NullSound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NullSound.cpp; sourceTree = "<group>"; };
+ A27B8730139F0A7D0002DC13 /* NullSound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NullSound.h; sourceTree = "<group>"; };
+ A27B8734139F0A7D0002DC13 /* OGGReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OGGReader.cpp; sourceTree = "<group>"; };
+ A27B8735139F0A7D0002DC13 /* OGGReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OGGReader.h; sourceTree = "<group>"; };
+ A27B8737139F0A7D0002DC13 /* AmbientMgrAL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AmbientMgrAL.cpp; sourceTree = "<group>"; };
+ A27B8738139F0A7D0002DC13 /* AmbientMgrAL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AmbientMgrAL.h; sourceTree = "<group>"; };
+ A27B873B139F0A7D0002DC13 /* OpenALAudio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenALAudio.cpp; sourceTree = "<group>"; };
+ A27B873C139F0A7D0002DC13 /* OpenALAudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenALAudio.h; sourceTree = "<group>"; };
+ A27B873D139F0A7D0002DC13 /* StackLock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StackLock.cpp; sourceTree = "<group>"; };
+ A27B873E139F0A7D0002DC13 /* StackLock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StackLock.h; sourceTree = "<group>"; };
+ A27B8742139F0A7D0002DC13 /* PLTImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PLTImporter.cpp; sourceTree = "<group>"; };
+ A27B8743139F0A7D0002DC13 /* PLTImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PLTImporter.h; sourceTree = "<group>"; };
+ A27B8747139F0A7D0002DC13 /* PNGImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PNGImporter.cpp; sourceTree = "<group>"; };
+ A27B8748139F0A7D0002DC13 /* PNGImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PNGImporter.h; sourceTree = "<group>"; };
+ A27B874C139F0A7D0002DC13 /* PROImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PROImporter.cpp; sourceTree = "<group>"; };
+ A27B874D139F0A7D0002DC13 /* PROImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PROImporter.h; sourceTree = "<group>"; };
+ A27B8751139F0A7D0002DC13 /* PSTOpcodes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PSTOpcodes.cpp; sourceTree = "<group>"; };
+ A27B8755139F0A7D0002DC13 /* SDLAudio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SDLAudio.cpp; sourceTree = "<group>"; };
+ A27B8756139F0A7D0002DC13 /* SDLAudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLAudio.h; sourceTree = "<group>"; };
+ A27B875A139F0A7D0002DC13 /* SDLVideo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SDLVideo.cpp; sourceTree = "<group>"; };
+ A27B875B139F0A7D0002DC13 /* SDLVideo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLVideo.h; sourceTree = "<group>"; };
+ A27B8761139F0A7D0002DC13 /* SPLImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SPLImporter.cpp; sourceTree = "<group>"; };
+ A27B8762139F0A7D0002DC13 /* SPLImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPLImporter.h; sourceTree = "<group>"; };
+ A27B8766139F0A7D0002DC13 /* STOImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = STOImporter.cpp; sourceTree = "<group>"; };
+ A27B8767139F0A7D0002DC13 /* STOImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STOImporter.h; sourceTree = "<group>"; };
+ A27B876B139F0A7D0002DC13 /* TISImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TISImporter.cpp; sourceTree = "<group>"; };
+ A27B876C139F0A7D0002DC13 /* TISImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TISImporter.h; sourceTree = "<group>"; };
+ A27B8770139F0A7D0002DC13 /* TLKImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TLKImporter.cpp; sourceTree = "<group>"; };
+ A27B8771139F0A7D0002DC13 /* TLKImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TLKImporter.h; sourceTree = "<group>"; };
+ A27B8772139F0A7D0002DC13 /* TlkOverride.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TlkOverride.cpp; sourceTree = "<group>"; };
+ A27B8773139F0A7D0002DC13 /* TlkOverride.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TlkOverride.h; sourceTree = "<group>"; };
+ A27B8777139F0A7D0002DC13 /* WAVReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WAVReader.cpp; sourceTree = "<group>"; };
+ A27B8778139F0A7D0002DC13 /* WAVReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WAVReader.h; sourceTree = "<group>"; };
+ A27B877C139F0A7D0002DC13 /* WEDImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WEDImporter.cpp; sourceTree = "<group>"; };
+ A27B877D139F0A7D0002DC13 /* WEDImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WEDImporter.h; sourceTree = "<group>"; };
+ A27B8781139F0A7D0002DC13 /* WMPImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WMPImporter.cpp; sourceTree = "<group>"; };
+ A27B8782139F0A7D0002DC13 /* WMPImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMPImporter.h; sourceTree = "<group>"; };
+ A27B8786139F0A7D0002DC13 /* ZLibManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ZLibManager.cpp; sourceTree = "<group>"; };
+ A27B8787139F0A7D0002DC13 /* ZLibManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZLibManager.h; sourceTree = "<group>"; };
+ A27E830A13A0358200B41410 /* 2DAImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = 2DAImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A2830A0F13A05A64000A63FE /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = System/Library/Frameworks/OpenAL.framework; sourceTree = SDKROOT; };
+ A2830A3913A05B5F000A63FE /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
+ A2830A3F13A05B81000A63FE /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
+ A2830ABA13A0624D000A63FE /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = ios/Info.plist; sourceTree = "<group>"; };
+ A288621F14A54FFD009AC280 /* libarchive.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libarchive.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/usr/lib/libarchive.dylib; sourceTree = DEVELOPER_DIR; };
+ A288622114A5501F009AC280 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/usr/lib/libz.dylib; sourceTree = DEVELOPER_DIR; };
+ A28D2498143BEA4200A27897 /* FontManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FontManager.cpp; sourceTree = "<group>"; };
+ A28D249B143BEA5800A27897 /* FontManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontManager.h; sourceTree = "<group>"; };
+ A28D24A0143C24C100A27897 /* BAMFontManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BAMFontManager.cpp; sourceTree = "<group>"; };
+ A28D24A3143C24E500A27897 /* BAMFontManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BAMFontManager.h; sourceTree = "<group>"; };
+ A29504771609721300BB22AA /* TTFImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = TTFImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A2969F0D168CDC0D00D9C6FC /* CombatInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CombatInfo.cpp; sourceTree = "<group>"; };
+ A2969F0E168CDC0D00D9C6FC /* CombatInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CombatInfo.h; sourceTree = "<group>"; };
+ A298DD1114EB4E8C00F59F56 /* SDL2Video.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = SDL2Video.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A298DD1314EB4EDE00F59F56 /* SDL12Video.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SDL12Video.cpp; sourceTree = "<group>"; };
+ A298DD1414EB4EDE00F59F56 /* SDL12Video.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL12Video.h; sourceTree = "<group>"; };
+ A298DD1714EB4EEB00F59F56 /* SDL20Video.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SDL20Video.cpp; sourceTree = "<group>"; };
+ A298DD1814EB4EEB00F59F56 /* SDL20Video.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL20Video.h; sourceTree = "<group>"; };
+ A298DD1B14EB61C100F59F56 /* Stdio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Stdio.h; sourceTree = "<group>"; };
+ A298DD2114EB61D300F59F56 /* Stdio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Stdio.cpp; sourceTree = "<group>"; };
+ A29BF7B213A0380F00C812DD /* BAMImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = BAMImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A29BF85C13A0427900C812DD /* GemRB.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GemRB.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ A2A26ADB15AA729800A8E25D /* VideoContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VideoContext.cpp; path = ../VLCPlayer/VideoContext.cpp; sourceTree = "<group>"; };
+ A2A26ADC15AA729800A8E25D /* VideoContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VideoContext.h; path = ../VLCPlayer/VideoContext.h; sourceTree = "<group>"; };
+ A2A2EA2D16A5EB4C0092B903 /* BAMFont.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BAMFont.cpp; sourceTree = "<group>"; };
+ A2A2EA2E16A5EB4C0092B903 /* BAMFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BAMFont.h; sourceTree = "<group>"; };
+ A2A2EA3216A5EB630092B903 /* TTFFont.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TTFFont.cpp; sourceTree = "<group>"; };
+ A2A2EA3316A5EB630092B903 /* TTFFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TTFFont.h; sourceTree = "<group>"; };
+ A2A2EA3616A5FC860092B903 /* Freetype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Freetype.cpp; sourceTree = "<group>"; };
+ A2A2EA3716A5FC860092B903 /* Freetype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Freetype.h; sourceTree = "<group>"; };
+ A2A2EA4516A76ACC0092B903 /* libiconv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libiconv.dylib; path = /usr/lib/libiconv.dylib; sourceTree = "<absolute>"; };
+ A2A3A7D814A505FD00F705CF /* CocoaWrapper.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = CocoaWrapper.mm; path = CocoaWrapper/mac/CocoaWrapper.mm; sourceTree = "<group>"; };
+ A2A3A7DF14A5130F00F705CF /* CocoaMain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CocoaMain.m; sourceTree = "<group>"; };
+ A2A3A7E014A5130F00F705CF /* GEM_ConfController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GEM_ConfController.h; sourceTree = "<group>"; };
+ A2A3A7E114A5130F00F705CF /* GEM_ConfController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GEM_ConfController.m; sourceTree = "<group>"; };
+ A2A3A7E314A5130F00F705CF /* GEM_ConfController-ipad.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = "GEM_ConfController-ipad.xib"; sourceTree = "<group>"; };
+ A2A3A7E414A5130F00F705CF /* GEM_ConfController-iphone.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = "GEM_ConfController-iphone.xib"; sourceTree = "<group>"; };
+ A2A3A7EE14A51B1800F705CF /* GEM_SDL_Keyboard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GEM_SDL_Keyboard.m; sourceTree = "<group>"; };
+ A2A6A459146893CC000F1688 /* TTFFontManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TTFFontManager.cpp; sourceTree = "<group>"; };
+ A2A6A45A146893CC000F1688 /* TTFFontManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TTFFontManager.h; sourceTree = "<group>"; };
+ A2AAC14615C1C2F500D27766 /* FreeType.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FreeType.framework; path = ../../../../../../Library/Frameworks/FreeType.framework; sourceTree = "<group>"; };
+ A2AAF36713A1507100AE8402 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
+ A2AAF38D13A150D700AE8402 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
+ A2AAF39313A150F900AE8402 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
+ A2AF8FC614DDCE47005CAC5D /* Vorbis.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Vorbis.framework; path = /Library/Frameworks/Vorbis.framework; sourceTree = "<absolute>"; };
+ A2B67A6816B1DF6500577415 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = ../../../../../System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<group>"; };
+ A2BD125615A7EDFE000FAB95 /* VLCPlayer.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = VLCPlayer.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A2BD125815A7EE61000FAB95 /* VLCPlayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VLCPlayer.cpp; path = ../VLCPlayer/VLCPlayer.cpp; sourceTree = "<group>"; };
+ A2BD125915A7EE61000FAB95 /* VLCPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCPlayer.h; path = ../VLCPlayer/VLCPlayer.h; sourceTree = "<group>"; };
+ A2BD82721396B886007E9C63 /* GemRB.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = GemRB.cpp; path = ../gemrb/GemRB.cpp; sourceTree = SOURCE_ROOT; };
+ A2BD83111396FD5F007E9C63 /* Python.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Python.framework; path = /System/Library/Frameworks/Python.framework; sourceTree = "<absolute>"; };
+ A2BD831D1396FE16007E9C63 /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = /System/Library/Frameworks/OpenAL.framework; sourceTree = "<absolute>"; };
+ A2BF9F8D1395FF61006ADC12 /* ActorMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActorMgr.cpp; sourceTree = "<group>"; };
+ A2BF9F8E1395FF61006ADC12 /* ActorMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActorMgr.h; sourceTree = "<group>"; };
+ A2BF9F8F1395FF61006ADC12 /* Ambient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Ambient.cpp; sourceTree = "<group>"; };
+ A2BF9F901395FF61006ADC12 /* Ambient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Ambient.h; sourceTree = "<group>"; };
+ A2BF9F911395FF61006ADC12 /* AmbientMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AmbientMgr.cpp; sourceTree = "<group>"; };
+ A2BF9F921395FF61006ADC12 /* AmbientMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AmbientMgr.h; sourceTree = "<group>"; };
+ A2BF9F931395FF61006ADC12 /* Animation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Animation.cpp; sourceTree = "<group>"; };
+ A2BF9F941395FF61006ADC12 /* Animation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Animation.h; sourceTree = "<group>"; };
+ A2BF9F951395FF61006ADC12 /* AnimationFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AnimationFactory.cpp; sourceTree = "<group>"; };
+ A2BF9F961395FF61006ADC12 /* AnimationFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnimationFactory.h; sourceTree = "<group>"; };
+ A2BF9F971395FF61006ADC12 /* AnimationMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AnimationMgr.cpp; sourceTree = "<group>"; };
+ A2BF9F981395FF61006ADC12 /* AnimationMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnimationMgr.h; sourceTree = "<group>"; };
+ A2BF9F991395FF61006ADC12 /* AnimStructures.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnimStructures.h; sourceTree = "<group>"; };
+ A2BF9F9A1395FF61006ADC12 /* ArchiveImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArchiveImporter.cpp; sourceTree = "<group>"; };
+ A2BF9F9B1395FF61006ADC12 /* ArchiveImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArchiveImporter.h; sourceTree = "<group>"; };
+ A2BF9F9C1395FF61006ADC12 /* Audio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Audio.cpp; sourceTree = "<group>"; };
+ A2BF9F9D1395FF61006ADC12 /* Audio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Audio.h; sourceTree = "<group>"; };
+ A2BF9F9E1395FF61006ADC12 /* Bitmap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Bitmap.cpp; sourceTree = "<group>"; };
+ A2BF9F9F1395FF61006ADC12 /* Bitmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Bitmap.h; sourceTree = "<group>"; };
+ A2BF9FA01395FF61006ADC12 /* Cache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Cache.cpp; sourceTree = "<group>"; };
+ A2BF9FA11395FF61006ADC12 /* Cache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cache.h; sourceTree = "<group>"; };
+ A2BF9FA21395FF61006ADC12 /* Calendar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Calendar.cpp; sourceTree = "<group>"; };
+ A2BF9FA31395FF61006ADC12 /* Calendar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Calendar.h; sourceTree = "<group>"; };
+ A2BF9FA41395FF61006ADC12 /* Callback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Callback.cpp; sourceTree = "<group>"; };
+ A2BF9FA51395FF61006ADC12 /* Callback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Callback.h; sourceTree = "<group>"; };
+ A2BF9FA61395FF61006ADC12 /* CharAnimations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CharAnimations.cpp; sourceTree = "<group>"; };
+ A2BF9FA71395FF61006ADC12 /* CharAnimations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CharAnimations.h; sourceTree = "<group>"; };
+ A2BF9FA91395FF61006ADC12 /* Compressor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Compressor.cpp; sourceTree = "<group>"; };
+ A2BF9FAA1395FF61006ADC12 /* Compressor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Compressor.h; sourceTree = "<group>"; };
+ A2BF9FAB1395FF61006ADC12 /* ControlAnimation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ControlAnimation.cpp; sourceTree = "<group>"; };
+ A2BF9FAC1395FF61006ADC12 /* ControlAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ControlAnimation.h; sourceTree = "<group>"; };
+ A2BF9FAD1395FF61006ADC12 /* Core.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Core.cpp; sourceTree = "<group>"; };
+ A2BF9FAE1395FF61006ADC12 /* damages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = damages.h; sourceTree = "<group>"; };
+ A2BF9FAF1395FF61006ADC12 /* DataFileMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DataFileMgr.cpp; sourceTree = "<group>"; };
+ A2BF9FB01395FF61006ADC12 /* DataFileMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataFileMgr.h; sourceTree = "<group>"; };
+ A2BF9FB11395FF61006ADC12 /* Dialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Dialog.cpp; sourceTree = "<group>"; };
+ A2BF9FB21395FF61006ADC12 /* Dialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Dialog.h; sourceTree = "<group>"; };
+ A2BF9FB31395FF61006ADC12 /* DialogHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DialogHandler.cpp; sourceTree = "<group>"; };
+ A2BF9FB41395FF61006ADC12 /* DialogHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DialogHandler.h; sourceTree = "<group>"; };
+ A2BF9FB51395FF61006ADC12 /* DialogMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DialogMgr.cpp; sourceTree = "<group>"; };
+ A2BF9FB61395FF61006ADC12 /* DialogMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DialogMgr.h; sourceTree = "<group>"; };
+ A2BF9FB71395FF61006ADC12 /* DisplayMessage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DisplayMessage.cpp; sourceTree = "<group>"; };
+ A2BF9FB81395FF61006ADC12 /* DisplayMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DisplayMessage.h; sourceTree = "<group>"; };
+ A2BF9FB91395FF61006ADC12 /* Effect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Effect.h; sourceTree = "<group>"; };
+ A2BF9FBA1395FF61006ADC12 /* EffectMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EffectMgr.cpp; sourceTree = "<group>"; };
+ A2BF9FBB1395FF61006ADC12 /* EffectMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EffectMgr.h; sourceTree = "<group>"; };
+ A2BF9FBC1395FF61006ADC12 /* EffectQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EffectQueue.cpp; sourceTree = "<group>"; };
+ A2BF9FBD1395FF61006ADC12 /* EffectQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EffectQueue.h; sourceTree = "<group>"; };
+ A2BF9FBE1395FF61006ADC12 /* Factory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Factory.cpp; sourceTree = "<group>"; };
+ A2BF9FBF1395FF61006ADC12 /* Factory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Factory.h; sourceTree = "<group>"; };
+ A2BF9FC01395FF61006ADC12 /* FactoryObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FactoryObject.cpp; sourceTree = "<group>"; };
+ A2BF9FC11395FF61006ADC12 /* FactoryObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FactoryObject.h; sourceTree = "<group>"; };
+ A2BF9FC21395FF61006ADC12 /* Font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Font.cpp; sourceTree = "<group>"; };
+ A2BF9FC31395FF61006ADC12 /* Font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Font.h; sourceTree = "<group>"; };
+ A2BF9FC41395FF61006ADC12 /* Game.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Game.cpp; sourceTree = "<group>"; };
+ A2BF9FC51395FF62006ADC12 /* Game.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Game.h; sourceTree = "<group>"; };
+ A2BF9FC61395FF62006ADC12 /* GameData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GameData.cpp; sourceTree = "<group>"; };
+ A2BF9FC71395FF62006ADC12 /* GameData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GameData.h; sourceTree = "<group>"; };
+ A2BF9FC91395FF62006ADC12 /* Actions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Actions.cpp; sourceTree = "<group>"; };
+ A2BF9FCA1395FF62006ADC12 /* GameScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GameScript.cpp; sourceTree = "<group>"; };
+ A2BF9FCB1395FF62006ADC12 /* GameScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GameScript.h; sourceTree = "<group>"; };
+ A2BF9FCC1395FF62006ADC12 /* GSUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GSUtils.cpp; sourceTree = "<group>"; };
+ A2BF9FCD1395FF62006ADC12 /* GSUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GSUtils.h; sourceTree = "<group>"; };
+ A2BF9FCE1395FF62006ADC12 /* Matching.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Matching.cpp; sourceTree = "<group>"; };
+ A2BF9FCF1395FF62006ADC12 /* Matching.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Matching.h; sourceTree = "<group>"; };
+ A2BF9FD01395FF62006ADC12 /* Objects.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Objects.cpp; sourceTree = "<group>"; };
+ A2BF9FD11395FF62006ADC12 /* Triggers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Triggers.cpp; sourceTree = "<group>"; };
+ A2BF9FD21395FF62006ADC12 /* GlobalTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GlobalTimer.cpp; sourceTree = "<group>"; };
+ A2BF9FD31395FF62006ADC12 /* GlobalTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GlobalTimer.h; sourceTree = "<group>"; };
+ A2BF9FD51395FF62006ADC12 /* Button.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Button.cpp; sourceTree = "<group>"; };
+ A2BF9FD61395FF62006ADC12 /* Button.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Button.h; sourceTree = "<group>"; };
+ A2BF9FD71395FF62006ADC12 /* Console.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Console.cpp; sourceTree = "<group>"; };
+ A2BF9FD81395FF62006ADC12 /* Console.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Console.h; sourceTree = "<group>"; };
+ A2BF9FD91395FF62006ADC12 /* Control.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Control.cpp; sourceTree = "<group>"; };
+ A2BF9FDA1395FF62006ADC12 /* Control.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Control.h; sourceTree = "<group>"; };
+ A2BF9FDB1395FF62006ADC12 /* EventMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventMgr.cpp; sourceTree = "<group>"; };
+ A2BF9FDC1395FF62006ADC12 /* EventMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventMgr.h; sourceTree = "<group>"; };
+ A2BF9FDD1395FF62006ADC12 /* GameControl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GameControl.cpp; sourceTree = "<group>"; };
+ A2BF9FDE1395FF62006ADC12 /* GameControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GameControl.h; sourceTree = "<group>"; };
+ A2BF9FDF1395FF62006ADC12 /* Label.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Label.cpp; sourceTree = "<group>"; };
+ A2BF9FE01395FF62006ADC12 /* Label.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Label.h; sourceTree = "<group>"; };
+ A2BF9FE11395FF62006ADC12 /* MapControl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MapControl.cpp; sourceTree = "<group>"; };
+ A2BF9FE21395FF62006ADC12 /* MapControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapControl.h; sourceTree = "<group>"; };
+ A2BF9FE31395FF62006ADC12 /* Progressbar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Progressbar.cpp; sourceTree = "<group>"; };
+ A2BF9FE41395FF62006ADC12 /* Progressbar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Progressbar.h; sourceTree = "<group>"; };
+ A2BF9FE51395FF62006ADC12 /* ScrollBar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollBar.cpp; sourceTree = "<group>"; };
+ A2BF9FE61395FF62006ADC12 /* ScrollBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollBar.h; sourceTree = "<group>"; };
+ A2BF9FE71395FF62006ADC12 /* Slider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Slider.cpp; sourceTree = "<group>"; };
+ A2BF9FE81395FF62006ADC12 /* Slider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Slider.h; sourceTree = "<group>"; };
+ A2BF9FE91395FF62006ADC12 /* TextArea.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextArea.cpp; sourceTree = "<group>"; };
+ A2BF9FEA1395FF62006ADC12 /* TextArea.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextArea.h; sourceTree = "<group>"; };
+ A2BF9FEB1395FF62006ADC12 /* TextEdit.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; path = TextEdit.cpp; sourceTree = "<group>"; };
+ A2BF9FEC1395FF62006ADC12 /* TextEdit.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = TextEdit.h; sourceTree = "<group>"; };
+ A2BF9FED1395FF62006ADC12 /* Window.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Window.cpp; sourceTree = "<group>"; };
+ A2BF9FEE1395FF62006ADC12 /* Window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Window.h; sourceTree = "<group>"; };
+ A2BF9FEF1395FF62006ADC12 /* WorldMapControl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorldMapControl.cpp; sourceTree = "<group>"; };
+ A2BF9FF01395FF62006ADC12 /* WorldMapControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorldMapControl.h; sourceTree = "<group>"; };
+ A2BF9FF11395FF62006ADC12 /* Holder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Holder.h; sourceTree = "<group>"; };
+ A2BF9FF21395FF62006ADC12 /* Image.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Image.cpp; sourceTree = "<group>"; };
+ A2BF9FF31395FF62006ADC12 /* Image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = "<group>"; };
+ A2BF9FF41395FF62006ADC12 /* ImageFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageFactory.cpp; sourceTree = "<group>"; };
+ A2BF9FF51395FF62006ADC12 /* ImageFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageFactory.h; sourceTree = "<group>"; };
+ A2BF9FF61395FF62006ADC12 /* ImageMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageMgr.cpp; sourceTree = "<group>"; };
+ A2BF9FF71395FF62006ADC12 /* ImageMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageMgr.h; sourceTree = "<group>"; };
+ A2BF9FF81395FF62006ADC12 /* ImageWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageWriter.cpp; sourceTree = "<group>"; };
+ A2BF9FF91395FF62006ADC12 /* ImageWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageWriter.h; sourceTree = "<group>"; };
+ A2BF9FFA1395FF62006ADC12 /* IniSpawn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IniSpawn.cpp; sourceTree = "<group>"; };
+ A2BF9FFB1395FF62006ADC12 /* IniSpawn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IniSpawn.h; sourceTree = "<group>"; };
+ A2BF9FFC1395FF62006ADC12 /* Interface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Interface.cpp; sourceTree = "<group>"; };
+ A2BF9FFD1395FF62006ADC12 /* Interface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Interface.h; sourceTree = "<group>"; };
+ A2BF9FFE1395FF62006ADC12 /* Inventory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Inventory.cpp; sourceTree = "<group>"; };
+ A2BF9FFF1395FF62006ADC12 /* Inventory.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = Inventory.h; sourceTree = "<group>"; };
+ A2BFA0001395FF62006ADC12 /* Item.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Item.cpp; sourceTree = "<group>"; };
+ A2BFA0011395FF62006ADC12 /* Item.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Item.h; sourceTree = "<group>"; };
+ A2BFA0021395FF62006ADC12 /* ItemMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ItemMgr.cpp; sourceTree = "<group>"; };
+ A2BFA0031395FF62006ADC12 /* ItemMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ItemMgr.h; sourceTree = "<group>"; };
+ A2BFA0041395FF62006ADC12 /* LRUCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LRUCache.cpp; sourceTree = "<group>"; };
+ A2BFA0051395FF62006ADC12 /* LRUCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LRUCache.h; sourceTree = "<group>"; };
+ A2BFA0071395FF62006ADC12 /* Map.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Map.cpp; sourceTree = "<group>"; };
+ A2BFA0081395FF62006ADC12 /* Map.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Map.h; sourceTree = "<group>"; };
+ A2BFA0091395FF62006ADC12 /* MapMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MapMgr.cpp; sourceTree = "<group>"; };
+ A2BFA00A1395FF62006ADC12 /* MapMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapMgr.h; sourceTree = "<group>"; };
+ A2BFA00B1395FF62006ADC12 /* MoviePlayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MoviePlayer.cpp; sourceTree = "<group>"; };
+ A2BFA00C1395FF62006ADC12 /* MoviePlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MoviePlayer.h; sourceTree = "<group>"; };
+ A2BFA00D1395FF62006ADC12 /* MusicMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MusicMgr.cpp; sourceTree = "<group>"; };
+ A2BFA00E1395FF62006ADC12 /* MusicMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicMgr.h; sourceTree = "<group>"; };
+ A2BFA00F1395FF62006ADC12 /* Palette.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Palette.cpp; sourceTree = "<group>"; };
+ A2BFA0101395FF62006ADC12 /* Palette.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Palette.h; sourceTree = "<group>"; };
+ A2BFA0111395FF62006ADC12 /* PalettedImageMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PalettedImageMgr.cpp; sourceTree = "<group>"; };
+ A2BFA0121395FF62006ADC12 /* PalettedImageMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PalettedImageMgr.h; sourceTree = "<group>"; };
+ A2BFA0131395FF62006ADC12 /* Particles.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Particles.cpp; sourceTree = "<group>"; };
+ A2BFA0141395FF62006ADC12 /* Particles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Particles.h; sourceTree = "<group>"; };
+ A2BFA0151395FF62006ADC12 /* PathFinder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathFinder.h; sourceTree = "<group>"; };
+ A2BFA0161395FF62006ADC12 /* Plugin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Plugin.cpp; sourceTree = "<group>"; };
+ A2BFA0171395FF62006ADC12 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Plugin.h; sourceTree = "<group>"; };
+ A2BFA0181395FF62006ADC12 /* PluginMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PluginMgr.cpp; sourceTree = "<group>"; };
+ A2BFA0191395FF62006ADC12 /* PluginMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PluginMgr.h; sourceTree = "<group>"; };
+ A2BFA01A1395FF62006ADC12 /* Polygon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Polygon.cpp; sourceTree = "<group>"; };
+ A2BFA01B1395FF62006ADC12 /* Polygon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Polygon.h; sourceTree = "<group>"; };
+ A2BFA01C1395FF62006ADC12 /* PolymorphCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolymorphCache.h; sourceTree = "<group>"; };
+ A2BFA01D1395FF62006ADC12 /* Projectile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Projectile.cpp; sourceTree = "<group>"; };
+ A2BFA01E1395FF62006ADC12 /* Projectile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Projectile.h; sourceTree = "<group>"; };
+ A2BFA01F1395FF62006ADC12 /* ProjectileMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProjectileMgr.cpp; sourceTree = "<group>"; };
+ A2BFA0201395FF62006ADC12 /* ProjectileMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProjectileMgr.h; sourceTree = "<group>"; };
+ A2BFA0211395FF62006ADC12 /* ProjectileServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProjectileServer.cpp; sourceTree = "<group>"; };
+ A2BFA0221395FF62006ADC12 /* ProjectileServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProjectileServer.h; sourceTree = "<group>"; };
+ A2BFA0231395FF62006ADC12 /* Region.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Region.cpp; sourceTree = "<group>"; };
+ A2BFA0241395FF62006ADC12 /* Region.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Region.h; sourceTree = "<group>"; };
+ A2BFA0251395FF62006ADC12 /* Resource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Resource.cpp; sourceTree = "<group>"; };
+ A2BFA0261395FF62006ADC12 /* Resource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Resource.h; sourceTree = "<group>"; };
+ A2BFA0271395FF62006ADC12 /* ResourceDesc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResourceDesc.cpp; sourceTree = "<group>"; };
+ A2BFA0281395FF62006ADC12 /* ResourceDesc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResourceDesc.h; sourceTree = "<group>"; };
+ A2BFA0291395FF62006ADC12 /* ResourceManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResourceManager.cpp; sourceTree = "<group>"; };
+ A2BFA02A1395FF62006ADC12 /* ResourceManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResourceManager.h; sourceTree = "<group>"; };
+ A2BFA02B1395FF62006ADC12 /* ResourceSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResourceSource.cpp; sourceTree = "<group>"; };
+ A2BFA02C1395FF62006ADC12 /* ResourceSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResourceSource.h; sourceTree = "<group>"; };
+ A2BFA02D1395FF62006ADC12 /* SaveGame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SaveGame.h; sourceTree = "<group>"; };
+ A2BFA02E1395FF62006ADC12 /* SaveGameIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SaveGameIterator.cpp; sourceTree = "<group>"; };
+ A2BFA02F1395FF62006ADC12 /* SaveGameIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SaveGameIterator.h; sourceTree = "<group>"; };
+ A2BFA0301395FF62006ADC12 /* SaveGameMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SaveGameMgr.cpp; sourceTree = "<group>"; };
+ A2BFA0311395FF62006ADC12 /* SaveGameMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SaveGameMgr.h; sourceTree = "<group>"; };
+ A2BFA0331395FF62006ADC12 /* Actor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Actor.cpp; sourceTree = "<group>"; };
+ A2BFA0341395FF62006ADC12 /* Actor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Actor.h; sourceTree = "<group>"; };
+ A2BFA0351395FF62006ADC12 /* Container.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Container.cpp; sourceTree = "<group>"; };
+ A2BFA0361395FF62006ADC12 /* Container.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Container.h; sourceTree = "<group>"; };
+ A2BFA0371395FF62006ADC12 /* Door.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Door.cpp; sourceTree = "<group>"; };
+ A2BFA0381395FF62006ADC12 /* Door.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Door.h; sourceTree = "<group>"; };
+ A2BFA0391395FF62006ADC12 /* InfoPoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InfoPoint.cpp; sourceTree = "<group>"; };
+ A2BFA03A1395FF62006ADC12 /* InfoPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InfoPoint.h; sourceTree = "<group>"; };
+ A2BFA03B1395FF62006ADC12 /* PCStatStruct.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PCStatStruct.cpp; sourceTree = "<group>"; };
+ A2BFA03C1395FF62006ADC12 /* PCStatStruct.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PCStatStruct.h; sourceTree = "<group>"; };
+ A2BFA03D1395FF62006ADC12 /* Scriptable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Scriptable.cpp; sourceTree = "<group>"; };
+ A2BFA03E1395FF62006ADC12 /* Scriptable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Scriptable.h; sourceTree = "<group>"; };
+ A2BFA03F1395FF62006ADC12 /* ScriptedAnimation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptedAnimation.cpp; sourceTree = "<group>"; };
+ A2BFA0401395FF62006ADC12 /* ScriptedAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptedAnimation.h; sourceTree = "<group>"; };
+ A2BFA0411395FF62006ADC12 /* ScriptEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptEngine.cpp; sourceTree = "<group>"; };
+ A2BFA0421395FF62006ADC12 /* ScriptEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptEngine.h; sourceTree = "<group>"; };
+ A2BFA0431395FF62006ADC12 /* SoundMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SoundMgr.cpp; sourceTree = "<group>"; };
+ A2BFA0441395FF62006ADC12 /* SoundMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SoundMgr.h; sourceTree = "<group>"; };
+ A2BFA0451395FF62006ADC12 /* Spell.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Spell.cpp; sourceTree = "<group>"; };
+ A2BFA0461395FF62006ADC12 /* Spell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Spell.h; sourceTree = "<group>"; };
+ A2BFA0471395FF62006ADC12 /* Spellbook.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Spellbook.cpp; sourceTree = "<group>"; };
+ A2BFA0481395FF62006ADC12 /* Spellbook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Spellbook.h; sourceTree = "<group>"; };
+ A2BFA0491395FF62006ADC12 /* SpellMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpellMgr.cpp; sourceTree = "<group>"; };
+ A2BFA04A1395FF62006ADC12 /* SpellMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpellMgr.h; sourceTree = "<group>"; };
+ A2BFA04B1395FF62006ADC12 /* Sprite2D.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Sprite2D.cpp; sourceTree = "<group>"; };
+ A2BFA04C1395FF62006ADC12 /* Sprite2D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Sprite2D.h; sourceTree = "<group>"; };
+ A2BFA04D1395FF62006ADC12 /* SpriteCover.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpriteCover.cpp; sourceTree = "<group>"; };
+ A2BFA04E1395FF62006ADC12 /* SpriteCover.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpriteCover.h; sourceTree = "<group>"; };
+ A2BFA04F1395FF62006ADC12 /* Store.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Store.cpp; sourceTree = "<group>"; };
+ A2BFA0501395FF62006ADC12 /* Store.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Store.h; sourceTree = "<group>"; };
+ A2BFA0511395FF62006ADC12 /* StoreMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StoreMgr.cpp; sourceTree = "<group>"; };
+ A2BFA0521395FF62006ADC12 /* StoreMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StoreMgr.h; sourceTree = "<group>"; };
+ A2BFA0531395FF62006ADC12 /* StringMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringMgr.cpp; sourceTree = "<group>"; };
+ A2BFA0541395FF62006ADC12 /* StringMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringMgr.h; sourceTree = "<group>"; };
+ A2BFA0551395FF62006ADC12 /* SymbolMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SymbolMgr.cpp; sourceTree = "<group>"; };
+ A2BFA0561395FF62006ADC12 /* SymbolMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolMgr.h; sourceTree = "<group>"; };
+ A2BFA05C1395FF62006ADC12 /* DataStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DataStream.cpp; sourceTree = "<group>"; };
+ A2BFA05D1395FF62006ADC12 /* DataStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataStream.h; sourceTree = "<group>"; };
+ A2BFA05E1395FF62006ADC12 /* FileStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileStream.cpp; sourceTree = "<group>"; };
+ A2BFA05F1395FF62006ADC12 /* FileStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileStream.h; sourceTree = "<group>"; };
+ A2BFA0601395FF62006ADC12 /* MemoryStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MemoryStream.cpp; sourceTree = "<group>"; };
+ A2BFA0611395FF62006ADC12 /* MemoryStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryStream.h; sourceTree = "<group>"; };
+ A2BFA0641395FF62006ADC12 /* swab.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = swab.c; sourceTree = "<group>"; };
+ A2BFA0651395FF62006ADC12 /* swab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = swab.h; sourceTree = "<group>"; };
+ A2BFA0661395FF62006ADC12 /* VFS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VFS.cpp; sourceTree = "<group>"; };
+ A2BFA0671395FF62006ADC12 /* VFS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VFS.h; sourceTree = "<group>"; };
+ A2BFA0681395FF62006ADC12 /* TableMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TableMgr.cpp; sourceTree = "<group>"; };
+ A2BFA0691395FF62006ADC12 /* TableMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TableMgr.h; sourceTree = "<group>"; };
+ A2BFA06A1395FF62006ADC12 /* Tile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Tile.cpp; sourceTree = "<group>"; };
+ A2BFA06B1395FF62006ADC12 /* Tile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Tile.h; sourceTree = "<group>"; };
+ A2BFA06C1395FF62006ADC12 /* TileMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TileMap.cpp; sourceTree = "<group>"; };
+ A2BFA06D1395FF62006ADC12 /* TileMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TileMap.h; sourceTree = "<group>"; };
+ A2BFA06E1395FF62006ADC12 /* TileMapMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TileMapMgr.cpp; sourceTree = "<group>"; };
+ A2BFA06F1395FF62006ADC12 /* TileMapMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TileMapMgr.h; sourceTree = "<group>"; };
+ A2BFA0701395FF62006ADC12 /* TileOverlay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TileOverlay.cpp; sourceTree = "<group>"; };
+ A2BFA0711395FF62006ADC12 /* TileOverlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TileOverlay.h; sourceTree = "<group>"; };
+ A2BFA0721395FF62006ADC12 /* TileSetMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TileSetMgr.cpp; sourceTree = "<group>"; };
+ A2BFA0731395FF62006ADC12 /* TileSetMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TileSetMgr.h; sourceTree = "<group>"; };
+ A2BFA0741395FF62006ADC12 /* TypeID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeID.h; sourceTree = "<group>"; };
+ A2BFA0751395FF62006ADC12 /* Variables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Variables.cpp; sourceTree = "<group>"; };
+ A2BFA0761395FF62006ADC12 /* Variables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Variables.h; sourceTree = "<group>"; };
+ A2BFA0771395FF62006ADC12 /* Video.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Video.cpp; sourceTree = "<group>"; };
+ A2BFA0781395FF62006ADC12 /* Video.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Video.h; sourceTree = "<group>"; };
+ A2BFA0791395FF62006ADC12 /* VideoMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoMode.h; sourceTree = "<group>"; };
+ A2BFA07A1395FF62006ADC12 /* WindowMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WindowMgr.cpp; sourceTree = "<group>"; };
+ A2BFA07B1395FF62006ADC12 /* WindowMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WindowMgr.h; sourceTree = "<group>"; };
+ A2BFA07C1395FF62006ADC12 /* WorldMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorldMap.cpp; sourceTree = "<group>"; };
+ A2BFA07D1395FF62006ADC12 /* WorldMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorldMap.h; sourceTree = "<group>"; };
+ A2BFA07E1395FF62006ADC12 /* WorldMapMgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorldMapMgr.cpp; sourceTree = "<group>"; };
+ A2BFA07F1395FF62006ADC12 /* WorldMapMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorldMapMgr.h; sourceTree = "<group>"; };
+ A2C66D9C13A2953D00C0AA8E /* Python.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Python.framework; path = System/Library/Frameworks/Python.framework; sourceTree = SDKROOT; };
+ A2C76D2814F196E900961680 /* StringBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringBuffer.cpp; sourceTree = "<group>"; };
+ A2C76D2914F196E900961680 /* StringBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringBuffer.h; sourceTree = "<group>"; };
+ A2CB5AC115000A0D00B5C154 /* File.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = File.cpp; sourceTree = "<group>"; };
+ A2CB5AC215000A0D00B5C154 /* File.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = File.h; sourceTree = "<group>"; };
+ A2D0505014D0B06C00D8CD77 /* SDL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL.framework; path = /Library/Frameworks/SDL.framework; sourceTree = "<absolute>"; };
+ A2D4C51E13A978110086BCC4 /* defsounds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = defsounds.h; sourceTree = "<group>"; };
+ A2D4C51F13A978110086BCC4 /* errors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = errors.h; sourceTree = "<group>"; };
+ A2D4C52013A978110086BCC4 /* exports.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = exports.h; sourceTree = "<group>"; };
+ A2D4C52113A978110086BCC4 /* globals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = globals.h; sourceTree = "<group>"; };
+ A2D4C52213A978110086BCC4 /* HashMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HashMap.h; sourceTree = "<group>"; };
+ A2D4C52313A978110086BCC4 /* ie_feats.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ie_feats.h; sourceTree = "<group>"; };
+ A2D4C52413A978110086BCC4 /* ie_stats.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ie_stats.h; sourceTree = "<group>"; };
+ A2D4C52513A978110086BCC4 /* ie_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ie_types.h; sourceTree = "<group>"; };
+ A2D4C52613A978110086BCC4 /* iless.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iless.h; sourceTree = "<group>"; };
+ A2D4C52813A978110086BCC4 /* opcode_params.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opcode_params.h; sourceTree = "<group>"; };
+ A2D4C52913A978110086BCC4 /* operatorbool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = operatorbool.h; sourceTree = "<group>"; };
+ A2D4C52A13A978110086BCC4 /* overlays.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = overlays.h; sourceTree = "<group>"; };
+ A2D4C52B13A978110086BCC4 /* plugindef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = plugindef.h; sourceTree = "<group>"; };
+ A2D4C52C13A978110086BCC4 /* RGBAColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RGBAColor.h; sourceTree = "<group>"; };
+ A2D4C52D13A978110086BCC4 /* SClassID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SClassID.h; sourceTree = "<group>"; };
+ A2D4C52E13A978110086BCC4 /* StringMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringMap.h; sourceTree = "<group>"; };
+ A2D4C52F13A978110086BCC4 /* strrefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = strrefs.h; sourceTree = "<group>"; };
+ A2D4C53013A978110086BCC4 /* win32def.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = win32def.h; sourceTree = "<group>"; };
+ A2DB6D5715D9ECB300D70E88 /* SpriteRenderer.inl */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; path = SpriteRenderer.inl; sourceTree = "<group>"; };
+ A2DB6D5815D9ECB300D70E88 /* TileRenderer.inl */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; path = TileRenderer.inl; sourceTree = "<group>"; };
+ A2DE329714EB071200117503 /* Logger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Logger.cpp; sourceTree = "<group>"; };
+ A2DE329814EB071200117503 /* Logger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Logger.h; sourceTree = "<group>"; };
+ A2E1582F14D1D8DA0044F3C5 /* GEM_AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GEM_AppDelegate.h; sourceTree = "<group>"; };
+ A2E1583014D1D8DA0044F3C5 /* GEM_AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GEM_AppDelegate.mm; sourceTree = "<group>"; };
+ A2E27EF516EEA7B00079E104 /* InterfaceConfig.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InterfaceConfig.cpp; sourceTree = "<group>"; };
+ A2E27EF616EEA7B00079E104 /* InterfaceConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InterfaceConfig.h; sourceTree = "<group>"; };
+ A2E27EFB16F12B5A0079E104 /* GemRB.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = GemRB.xib; path = CocoaWrapper/mac/nibs/GemRB.xib; sourceTree = "<group>"; };
+ A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libgemrb_core.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
+ A2EC8058145F9E6E0033754A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
+ A2EC805A1460556B0033754A /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/OpenAL.framework; sourceTree = DEVELOPER_DIR; };
+ A2EC805C1460559C0033754A /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/CoreAudio.framework; sourceTree = DEVELOPER_DIR; };
+ A2EC805E146055D80033754A /* GLKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/GLKit.framework; sourceTree = DEVELOPER_DIR; };
+ A2EC805F146055D80033754A /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/OpenGLES.framework; sourceTree = DEVELOPER_DIR; };
+ A2EC8062146056490033754A /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; };
+ A2EC8064146056900033754A /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/AudioToolbox.framework; sourceTree = DEVELOPER_DIR; };
+ A2EC8066146056B40033754A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; };
+ A2F0505113ABB80B0023B7EB /* SAVImporter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = SAVImporter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A2FCD5FB13A0366100271997 /* ACMReader.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = ACMReader.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A2FE2C7216F21CBF00DDC6C7 /* defaults.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = defaults.plist; sourceTree = "<group>"; };
+ A2FE2C7716F2313400DDC6C7 /* NullSource.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = NullSource.cpp; sourceTree = "<group>"; };
+ A2FE2C7816F2313400DDC6C7 /* NullSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NullSource.h; sourceTree = "<group>"; };
+ A2FE2C8116F2316400DDC6C7 /* NullSource.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = NullSource.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ A2FE553A13982BA6006AB962 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = SOURCE_ROOT; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 8D11072E0486CEB800E47090 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2E66486139E907000310FC8 /* libgemrb_core.dylib in Frameworks */,
+ 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A2462F0F13A036B1002D1F02 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A29BF85613A0420F00C812DD /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3C813A2867900D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B52513A28CC900D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3CF13A286A800D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B52613A28CD300D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3D513A286BC00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B52713A28CD800D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3DB13A286CD00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B52813A28CDD00D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3E113A286DE00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B52913A28CE000D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3E713A286EC00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B52A13A28CE400D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3ED13A286FB00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B52B13A28CEA00D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3F313A2871300D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B52C13A28CF000D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3F913A2872500D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B52D13A28CF400D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3FF13A2873700D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B52E13A28CF700D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B40513A2874700D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B52F13A28CFA00D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B40B13A2875400D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53013A28D0000D41A8A /* libgemrb_core.dylib in Frameworks */,
+ A2C66D9D13A2953D00C0AA8E /* Python.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B41113A2876300D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53113A28D0600D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B41713A2877100D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53213A28D0900D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B41D13A2878400D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53313A28D0C00D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B42313A2879900D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53413A28D0F00D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B42913A287AB00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53513A28D1200D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B42F13A287BC00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53613A28D1500D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B44713A289E000D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53713A28D1800D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B44D13A28A0000D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53813A28D1B00D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B45313A28A0E00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53913A28D1F00D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B45913A28A1C00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2AF8FC714DDCE47005CAC5D /* Vorbis.framework in Frameworks */,
+ A276B53A13A28D2300D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B45F13A28A3100D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2D0505414D0C17500D8CD77 /* SDL.framework in Frameworks */,
+ A276B53B13A28D2500D41A8A /* libgemrb_core.dylib in Frameworks */,
+ A2C66DB513A295DC00C0AA8E /* OpenAL.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B46513A28A3F00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53C13A28D2800D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B46B13A28A5000D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53D13A28D2A00D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B47113A28A5D00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53E13A28D2D00D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B47713A28A7600D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B53F13A28D3000D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B47D13A28A8500D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B54013A28D3500D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B48313A28A9000D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2D0505214D0B09F00D8CD77 /* SDL.framework in Frameworks */,
+ A2491881141092F20038B170 /* Cocoa.framework in Frameworks */,
+ A276B54113A28D3D00D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B48913A28A9E00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B54213A28D4000D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B48F13A28AA800D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B54413A28D4600D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B49513A28AB800D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B54513A28D4900D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B49B13A28AC800D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B54613A28D4C00D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B4A113A28AD300D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B54713A28D5500D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B4A713A28AE100D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B54813A28D5900D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B4AD13A28AEE00D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A273DC7C14856756000DA299 /* libz.dylib in Frameworks */,
+ A276B54913A28D5D00D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B4F213A28C0400D41A8A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B54313A28D4300D41A8A /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A27E830813A0358200B41410 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A29BF85213A0420300C812DD /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A29504711609721300BB22AA /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2A2EA4716A76AE90092B903 /* libiconv.dylib in Frameworks */,
+ A29504721609721300BB22AA /* FreeType.framework in Frameworks */,
+ A29504731609721300BB22AA /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A298DD0A14EB4E8C00F59F56 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A298DD0B14EB4E8C00F59F56 /* SDL.framework in Frameworks */,
+ A298DD0C14EB4E8C00F59F56 /* Cocoa.framework in Frameworks */,
+ A298DD0D14EB4E8C00F59F56 /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A29BF7B013A0380F00C812DD /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A29BF85713A0421200C812DD /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A29BF85A13A0427900C812DD /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A228D24916A86FA00053375D /* libiconv.dylib in Frameworks */,
+ A2374CA215F1486E002A1C8C /* libbz2.dylib in Frameworks */,
+ A288622214A5501F009AC280 /* libz.dylib in Frameworks */,
+ A288622014A54FFD009AC280 /* libarchive.dylib in Frameworks */,
+ A2EC8067146056B40033754A /* CoreGraphics.framework in Frameworks */,
+ A2EC8065146056900033754A /* AudioToolbox.framework in Frameworks */,
+ A2EC8063146056490033754A /* QuartzCore.framework in Frameworks */,
+ A2EC8061146055D80033754A /* OpenGLES.framework in Frameworks */,
+ A2EC805D1460559C0033754A /* CoreAudio.framework in Frameworks */,
+ A2EC805B1460556B0033754A /* OpenAL.framework in Frameworks */,
+ A2EC8059145F9E6E0033754A /* Foundation.framework in Frameworks */,
+ A239390B145F8677007895B3 /* UIKit.framework in Frameworks */,
+ A22B5D611583D816007B4AA4 /* libFreetype2.a in Frameworks */,
+ A22B5D621583D816007B4AA4 /* libPython.a in Frameworks */,
+ A22B5D641583D816007B4AA4 /* libSDL2.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A2BD124F15A7EDFE000FAB95 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2BD125215A7EDFE000FAB95 /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A2E66336139E875400310FC8 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2B67A6B16B1DFC100577415 /* CoreFoundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A2F0504F13ABB80B0023B7EB /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2F0505B13ABB84C0023B7EB /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A2FCD5F913A0366100271997 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A29BF85513A0420A00C812DD /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A2FE2C7C16F2316400DDC6C7 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2FE2C7D16F2316400DDC6C7 /* libgemrb_core.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 080E96DDFE201D6D7F000001 /* Libraries */ = {
+ isa = PBXGroup;
+ children = (
+ A2E7985B14845AFB00B15DF4 /* iOS static libs */,
+ 29B97323FDCFA39411CA2CEA /* Frameworks */,
+ A2E7985C14845B3F00B15DF4 /* dylibs */,
+ );
+ name = Libraries;
+ sourceTree = "<group>";
+ };
+ 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ A2BD83111396FD5F007E9C63 /* Python.framework */,
+ A2BD831D1396FE16007E9C63 /* OpenAL.framework */,
+ 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
+ );
+ name = "Linked Frameworks";
+ sourceTree = "<group>";
+ };
+ 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 29B97324FDCFA39411CA2CEA /* AppKit.framework */,
+ 29B97325FDCFA39411CA2CEA /* Foundation.framework */,
+ );
+ name = "Other Frameworks";
+ sourceTree = "<group>";
+ };
+ 19C28FACFE9D520D11CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 8D1107320486CEB800E47090 /* GemRB.app */,
+ A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */,
+ A27E830A13A0358200B41410 /* 2DAImporter.so */,
+ A2FCD5FB13A0366100271997 /* ACMReader.so */,
+ A2462F1113A036B1002D1F02 /* AREImporter.so */,
+ A29BF7B213A0380F00C812DD /* BAMImporter.so */,
+ A29BF85C13A0427900C812DD /* GemRB.app */,
+ A276B3CA13A2867900D41A8A /* BIFImporter.so */,
+ A276B3D113A286A800D41A8A /* BIKPlayer.so */,
+ A276B3D713A286BC00D41A8A /* BMPImporter.so */,
+ A276B3DD13A286CD00D41A8A /* BMPWriter.so */,
+ A276B3E313A286DE00D41A8A /* CHUImporter.so */,
+ A276B3E913A286EC00D41A8A /* CREImporter.so */,
+ A276B3EF13A286FB00D41A8A /* DirectoryImporter.so */,
+ A276B3F513A2871300D41A8A /* DLGImporter.so */,
+ A276B3FB13A2872500D41A8A /* EFFImporter.so */,
+ A276B40113A2873700D41A8A /* FXOpcodes.so */,
+ A276B40713A2874700D41A8A /* GAMImporter.so */,
+ A276B40D13A2875400D41A8A /* GUIScript.so */,
+ A276B41313A2876300D41A8A /* IDSImporter.so */,
+ A276B41913A2877100D41A8A /* INIImporter.so */,
+ A276B41F13A2878400D41A8A /* ITMImporter.so */,
+ A276B42513A2879900D41A8A /* IWDOpcodes.so */,
+ A276B42B13A287AB00D41A8A /* KEYImporter.so */,
+ A276B43113A287BD00D41A8A /* MOSImporter.so */,
+ A276B44913A289E000D41A8A /* MUSImporter.so */,
+ A276B44F13A28A0000D41A8A /* MVEPlayer.so */,
+ A276B45513A28A0E00D41A8A /* NullSound.so */,
+ A276B45B13A28A1C00D41A8A /* OGGReader.so */,
+ A276B46113A28A3100D41A8A /* OpenALAudio.so */,
+ A276B46713A28A3F00D41A8A /* PLTImporter.so */,
+ A276B46D13A28A5000D41A8A /* PNGImporter.so */,
+ A276B47313A28A5D00D41A8A /* PROImporter.so */,
+ A276B47913A28A7600D41A8A /* PSTOpcodes.so */,
+ A276B47F13A28A8500D41A8A /* SDLAudio.so */,
+ A276B48513A28A9000D41A8A /* SDLVideo.so */,
+ A276B48B13A28A9E00D41A8A /* SPLImporter.so */,
+ A276B49113A28AA900D41A8A /* TISImporter.so */,
+ A276B49713A28AB800D41A8A /* TLKImporter.so */,
+ A276B49D13A28AC800D41A8A /* WAVReader.so */,
+ A276B4A313A28AD300D41A8A /* WEDImporter.so */,
+ A276B4A913A28AE100D41A8A /* WMPImporter.so */,
+ A276B4AF13A28AEE00D41A8A /* ZLibManager.so */,
+ A276B4F413A28C0400D41A8A /* STOImporter.so */,
+ A2F0505113ABB80B0023B7EB /* SAVImporter.so */,
+ A298DD1114EB4E8C00F59F56 /* SDL2Video.so */,
+ A2BD125615A7EDFE000FAB95 /* VLCPlayer.so */,
+ A29504771609721300BB22AA /* TTFImporter.so */,
+ A2FE2C8116F2316400DDC6C7 /* NullSource.so */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 29B97314FDCFA39411CA2CEA /* GemRB_OSX */ = {
+ isa = PBXGroup;
+ children = (
+ A2B67A6816B1DF6500577415 /* CoreFoundation.framework */,
+ A2374CA115F1486E002A1C8C /* libbz2.dylib */,
+ A2AAC14615C1C2F500D27766 /* FreeType.framework */,
+ A2FE553A13982BA6006AB962 /* config.h */,
+ A2D4C51D13A978110086BCC4 /* includes */,
+ A27B8697139F0A7D0002DC13 /* plugins */,
+ A2BF9F8C1395FF61006ADC12 /* core */,
+ 080E96DDFE201D6D7F000001 /* Libraries */,
+ 29B97315FDCFA39411CA2CEA /* Cocoa Wrappers */,
+ 29B97317FDCFA39411CA2CEA /* Resources */,
+ A29BF91C13A04B3900C812DD /* Resources-iOS */,
+ 19C28FACFE9D520D11CA2CBB /* Products */,
+ );
+ name = GemRB_OSX;
+ sourceTree = "<group>";
+ };
+ 29B97315FDCFA39411CA2CEA /* Cocoa Wrappers */ = {
+ isa = PBXGroup;
+ children = (
+ A2FE2C7216F21CBF00DDC6C7 /* defaults.plist */,
+ A22EBDCC14FF18030029C9C1 /* AppleLogger.h */,
+ A22EBDCD14FF18030029C9C1 /* AppleLogger.mm */,
+ A2A3A7DE14A5130F00F705CF /* ios */,
+ A2BD82721396B886007E9C63 /* GemRB.cpp */,
+ A2A3A7D614A5030600F705CF /* mac */,
+ );
+ name = "Cocoa Wrappers";
+ sourceTree = "<group>";
+ };
+ 29B97317FDCFA39411CA2CEA /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ A218A75114A8F3DB001142CF /* ../artwork/gemrb.icns */,
+ 8D1107310486CEB800E47090 /* Info.plist */,
+ 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ };
+ 29B97323FDCFA39411CA2CEA /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ A2EC8064146056900033754A /* AudioToolbox.framework */,
+ A2AAF38D13A150D700AE8402 /* AudioToolbox.framework */,
+ A2491880141092F20038B170 /* Cocoa.framework */,
+ A2EC805C1460559C0033754A /* CoreAudio.framework */,
+ A2830A3913A05B5F000A63FE /* CoreAudio.framework */,
+ A2EC8066146056B40033754A /* CoreGraphics.framework */,
+ A2EC8058145F9E6E0033754A /* Foundation.framework */,
+ A2EC805E146055D80033754A /* GLKit.framework */,
+ 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
+ A2EC805A1460556B0033754A /* OpenAL.framework */,
+ A2830A0F13A05A64000A63FE /* OpenAL.framework */,
+ A2EC805F146055D80033754A /* OpenGLES.framework */,
+ 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
+ A2C66D9C13A2953D00C0AA8E /* Python.framework */,
+ A2EC8062146056490033754A /* QuartzCore.framework */,
+ A2830A3F13A05B81000A63FE /* QuartzCore.framework */,
+ A2D0505014D0B06C00D8CD77 /* SDL.framework */,
+ A239390A145F8677007895B3 /* UIKit.framework */,
+ A2AF8FC614DDCE47005CAC5D /* Vorbis.framework */,
+ A2AAF36713A1507100AE8402 /* CoreAudio.framework */,
+ A2AAF39313A150F900AE8402 /* AudioToolbox.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ A27979A913ABA4F7009A6FEF /* SAVImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27979AC13ABA4F7009A6FEF /* SAVImporter.cpp */,
+ A27979AD13ABA4F7009A6FEF /* SAVImporter.h */,
+ );
+ path = SAVImporter;
+ sourceTree = "<group>";
+ };
+ A27B8697139F0A7D0002DC13 /* plugins */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8698139F0A7D0002DC13 /* 2DAImporter */,
+ A27B869D139F0A7D0002DC13 /* ACMReader */,
+ A27B86A7139F0A7D0002DC13 /* AREImporter */,
+ A27B86AC139F0A7D0002DC13 /* BAMImporter */,
+ A27B86B1139F0A7D0002DC13 /* BIFImporter */,
+ A27B86B6139F0A7D0002DC13 /* BIKPlayer */,
+ A27B86C6139F0A7D0002DC13 /* BMPImporter */,
+ A27B86CB139F0A7D0002DC13 /* BMPWriter */,
+ A27B86D0139F0A7D0002DC13 /* CHUImporter */,
+ A27B86D6139F0A7D0002DC13 /* CREImporter */,
+ A27B86DB139F0A7D0002DC13 /* DirectoryImporter */,
+ A27B86E0139F0A7D0002DC13 /* DLGImporter */,
+ A27B86E5139F0A7D0002DC13 /* EFFImporter */,
+ A27B86EA139F0A7D0002DC13 /* FXOpcodes */,
+ A27B86EE139F0A7D0002DC13 /* GAMImporter */,
+ A27B86F3139F0A7D0002DC13 /* GUIScript */,
+ A27B86FA139F0A7D0002DC13 /* IDSImporter */,
+ A27B8700139F0A7D0002DC13 /* INIImporter */,
+ A27B8705139F0A7D0002DC13 /* ITMImporter */,
+ A27B870A139F0A7D0002DC13 /* IWDOpcodes */,
+ A27B870E139F0A7D0002DC13 /* KEYImporter */,
+ A27B8716139F0A7D0002DC13 /* MOSImporter */,
+ A27B871B139F0A7D0002DC13 /* MUSImporter */,
+ A27B8720139F0A7D0002DC13 /* MVEPlayer */,
+ A27B872C139F0A7D0002DC13 /* NullSound */,
+ A2FE2C7516F2313400DDC6C7 /* NullSource */,
+ A27B8731139F0A7D0002DC13 /* OGGReader */,
+ A27B8736139F0A7D0002DC13 /* OpenALAudio */,
+ A27B873F139F0A7D0002DC13 /* PLTImporter */,
+ A27B8744139F0A7D0002DC13 /* PNGImporter */,
+ A27B8749139F0A7D0002DC13 /* PROImporter */,
+ A27B874E139F0A7D0002DC13 /* PSTOpcodes */,
+ A27979A913ABA4F7009A6FEF /* SAVImporter */,
+ A27B8752139F0A7D0002DC13 /* SDLAudio */,
+ A27B8757139F0A7D0002DC13 /* SDLVideo */,
+ A27B875E139F0A7D0002DC13 /* SPLImporter */,
+ A27B8763139F0A7D0002DC13 /* STOImporter */,
+ A27B8768139F0A7D0002DC13 /* TISImporter */,
+ A27B876D139F0A7D0002DC13 /* TLKImporter */,
+ A2A6A457146893CC000F1688 /* TTFImporter */,
+ A2BD125715A7EE35000FAB95 /* VLCPlayer */,
+ A27B8774139F0A7D0002DC13 /* WAVReader */,
+ A27B8779139F0A7D0002DC13 /* WEDImporter */,
+ A27B877E139F0A7D0002DC13 /* WMPImporter */,
+ A27B8783139F0A7D0002DC13 /* ZLibManager */,
+ );
+ name = plugins;
+ path = ../gemrb/plugins;
+ sourceTree = SOURCE_ROOT;
+ };
+ A27B8698139F0A7D0002DC13 /* 2DAImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8699139F0A7D0002DC13 /* 2DAImporter.cpp */,
+ A27B869A139F0A7D0002DC13 /* 2DAImporter.h */,
+ );
+ path = 2DAImporter;
+ sourceTree = "<group>";
+ };
+ A27B869D139F0A7D0002DC13 /* ACMReader */ = {
+ isa = PBXGroup;
+ children = (
+ A27B869E139F0A7D0002DC13 /* ACMReader.cpp */,
+ A27B869F139F0A7D0002DC13 /* ACMReader.h */,
+ A27B86A1139F0A7D0002DC13 /* decoder.cpp */,
+ A27B86A2139F0A7D0002DC13 /* decoder.h */,
+ A27B86A3139F0A7D0002DC13 /* general.h */,
+ A27B86A5139F0A7D0002DC13 /* unpacker.cpp */,
+ A27B86A6139F0A7D0002DC13 /* unpacker.h */,
+ );
+ path = ACMReader;
+ sourceTree = "<group>";
+ };
+ A27B86A7139F0A7D0002DC13 /* AREImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86A8139F0A7D0002DC13 /* AREImporter.cpp */,
+ A27B86A9139F0A7D0002DC13 /* AREImporter.h */,
+ );
+ path = AREImporter;
+ sourceTree = "<group>";
+ };
+ A27B86AC139F0A7D0002DC13 /* BAMImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A2A2EA2D16A5EB4C0092B903 /* BAMFont.cpp */,
+ A2A2EA2E16A5EB4C0092B903 /* BAMFont.h */,
+ A28D24A0143C24C100A27897 /* BAMFontManager.cpp */,
+ A28D24A3143C24E500A27897 /* BAMFontManager.h */,
+ A27B86AD139F0A7D0002DC13 /* BAMImporter.cpp */,
+ A27B86AE139F0A7D0002DC13 /* BAMImporter.h */,
+ );
+ path = BAMImporter;
+ sourceTree = "<group>";
+ };
+ A27B86B1139F0A7D0002DC13 /* BIFImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86B2139F0A7D0002DC13 /* BIFImporter.cpp */,
+ A27B86B3139F0A7D0002DC13 /* BIFImporter.h */,
+ );
+ path = BIFImporter;
+ sourceTree = "<group>";
+ };
+ A27B86B6139F0A7D0002DC13 /* BIKPlayer */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86B7139F0A7D0002DC13 /* BIKPlayer.cpp */,
+ A27B86B8139F0A7D0002DC13 /* BIKPlayer.h */,
+ A27B86B9139F0A7D0002DC13 /* binkdata.h */,
+ A27B86BB139F0A7D0002DC13 /* common.h */,
+ A27B86BC139F0A7D0002DC13 /* dct.cpp */,
+ A27B86BD139F0A7D0002DC13 /* dsputil.h */,
+ A27B86BE139F0A7D0002DC13 /* fft.cpp */,
+ A27B86BF139F0A7D0002DC13 /* GetBitContext.cpp */,
+ A27B86C0139F0A7D0002DC13 /* GetBitContext.h */,
+ A27B86C2139F0A7D0002DC13 /* mem.cpp */,
+ A27B86C3139F0A7D0002DC13 /* rational.cpp */,
+ A27B86C4139F0A7D0002DC13 /* rational.h */,
+ A27B86C5139F0A7D0002DC13 /* rdft.cpp */,
+ );
+ path = BIKPlayer;
+ sourceTree = "<group>";
+ };
+ A27B86C6139F0A7D0002DC13 /* BMPImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86C7139F0A7D0002DC13 /* BMPImporter.cpp */,
+ A27B86C8139F0A7D0002DC13 /* BMPImporter.h */,
+ );
+ path = BMPImporter;
+ sourceTree = "<group>";
+ };
+ A27B86CB139F0A7D0002DC13 /* BMPWriter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86CC139F0A7D0002DC13 /* BMPWriter.cpp */,
+ A27B86CD139F0A7D0002DC13 /* BMPWriter.h */,
+ );
+ path = BMPWriter;
+ sourceTree = "<group>";
+ };
+ A27B86D0139F0A7D0002DC13 /* CHUImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86D1139F0A7D0002DC13 /* CHUImporter.cpp */,
+ A27B86D2139F0A7D0002DC13 /* CHUImporter.h */,
+ );
+ path = CHUImporter;
+ sourceTree = "<group>";
+ };
+ A27B86D6139F0A7D0002DC13 /* CREImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86D8139F0A7D0002DC13 /* CREImporter.cpp */,
+ A27B86D9139F0A7D0002DC13 /* CREImporter.h */,
+ );
+ path = CREImporter;
+ sourceTree = "<group>";
+ };
+ A27B86DB139F0A7D0002DC13 /* DirectoryImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86DD139F0A7D0002DC13 /* DirectoryImporter.cpp */,
+ A27B86DE139F0A7D0002DC13 /* DirectoryImporter.h */,
+ );
+ path = DirectoryImporter;
+ sourceTree = "<group>";
+ };
+ A27B86E0139F0A7D0002DC13 /* DLGImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86E2139F0A7D0002DC13 /* DLGImporter.cpp */,
+ A27B86E3139F0A7D0002DC13 /* DLGImporter.h */,
+ );
+ path = DLGImporter;
+ sourceTree = "<group>";
+ };
+ A27B86E5139F0A7D0002DC13 /* EFFImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86E7139F0A7D0002DC13 /* EFFImporter.cpp */,
+ A27B86E8139F0A7D0002DC13 /* EFFImporter.h */,
+ );
+ path = EFFImporter;
+ sourceTree = "<group>";
+ };
+ A27B86EA139F0A7D0002DC13 /* FXOpcodes */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86EC139F0A7D0002DC13 /* FXOpcodes.cpp */,
+ );
+ path = FXOpcodes;
+ sourceTree = "<group>";
+ };
+ A27B86EE139F0A7D0002DC13 /* GAMImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86F0139F0A7D0002DC13 /* GAMImporter.cpp */,
+ A27B86F1139F0A7D0002DC13 /* GAMImporter.h */,
+ );
+ path = GAMImporter;
+ sourceTree = "<group>";
+ };
+ A27B86F3139F0A7D0002DC13 /* GUIScript */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86F5139F0A7D0002DC13 /* GUIScript.cpp */,
+ A27B86F6139F0A7D0002DC13 /* GUIScript.h */,
+ A27B86F8139F0A7D0002DC13 /* PythonHelpers.cpp */,
+ A27B86F9139F0A7D0002DC13 /* PythonHelpers.h */,
+ );
+ path = GUIScript;
+ sourceTree = "<group>";
+ };
+ A27B86FA139F0A7D0002DC13 /* IDSImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B86FC139F0A7D0002DC13 /* IDSImporter.cpp */,
+ A27B86FD139F0A7D0002DC13 /* IDSImporter.h */,
+ A27B86FE139F0A7D0002DC13 /* IDSImporterDefs.h */,
+ );
+ path = IDSImporter;
+ sourceTree = "<group>";
+ };
+ A27B8700139F0A7D0002DC13 /* INIImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8702139F0A7D0002DC13 /* INIImporter.cpp */,
+ A27B8703139F0A7D0002DC13 /* INIImporter.h */,
+ );
+ path = INIImporter;
+ sourceTree = "<group>";
+ };
+ A27B8705139F0A7D0002DC13 /* ITMImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8707139F0A7D0002DC13 /* ITMImporter.cpp */,
+ A27B8708139F0A7D0002DC13 /* ITMImporter.h */,
+ );
+ path = ITMImporter;
+ sourceTree = "<group>";
+ };
+ A27B870A139F0A7D0002DC13 /* IWDOpcodes */ = {
+ isa = PBXGroup;
+ children = (
+ A27B870C139F0A7D0002DC13 /* IWDOpcodes.cpp */,
+ );
+ path = IWDOpcodes;
+ sourceTree = "<group>";
+ };
+ A27B870E139F0A7D0002DC13 /* KEYImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8710139F0A7D0002DC13 /* Dictionary.cpp */,
+ A27B8711139F0A7D0002DC13 /* Dictionary.h */,
+ A27B8712139F0A7D0002DC13 /* KEYImporter.cpp */,
+ A27B8713139F0A7D0002DC13 /* KEYImporter.h */,
+ );
+ path = KEYImporter;
+ sourceTree = "<group>";
+ };
+ A27B8716139F0A7D0002DC13 /* MOSImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8719139F0A7D0002DC13 /* MOSImporter.cpp */,
+ A27B871A139F0A7D0002DC13 /* MOSImporter.h */,
+ );
+ path = MOSImporter;
+ sourceTree = "<group>";
+ };
+ A27B871B139F0A7D0002DC13 /* MUSImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B871E139F0A7D0002DC13 /* MUSImporter.cpp */,
+ A27B871F139F0A7D0002DC13 /* MUSImporter.h */,
+ );
+ path = MUSImporter;
+ sourceTree = "<group>";
+ };
+ A27B8720139F0A7D0002DC13 /* MVEPlayer */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8722139F0A7D0002DC13 /* gstmvedemux.h */,
+ A27B8724139F0A7D0002DC13 /* mve.h */,
+ A27B8725139F0A7D0002DC13 /* mve_player.cpp */,
+ A27B8726139F0A7D0002DC13 /* mve_player.h */,
+ A27B8727139F0A7D0002DC13 /* mveaudiodec.cpp */,
+ A27B8728139F0A7D0002DC13 /* MVEPlayer.cpp */,
+ A27B8729139F0A7D0002DC13 /* MVEPlayer.h */,
+ A27B872A139F0A7D0002DC13 /* mvevideodec16.cpp */,
+ A27B872B139F0A7D0002DC13 /* mvevideodec8.cpp */,
+ );
+ path = MVEPlayer;
+ sourceTree = "<group>";
+ };
+ A27B872C139F0A7D0002DC13 /* NullSound */ = {
+ isa = PBXGroup;
+ children = (
+ A27B872F139F0A7D0002DC13 /* NullSound.cpp */,
+ A27B8730139F0A7D0002DC13 /* NullSound.h */,
+ );
+ path = NullSound;
+ sourceTree = "<group>";
+ };
+ A27B8731139F0A7D0002DC13 /* OGGReader */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8734139F0A7D0002DC13 /* OGGReader.cpp */,
+ A27B8735139F0A7D0002DC13 /* OGGReader.h */,
+ );
+ path = OGGReader;
+ sourceTree = "<group>";
+ };
+ A27B8736139F0A7D0002DC13 /* OpenALAudio */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8737139F0A7D0002DC13 /* AmbientMgrAL.cpp */,
+ A27B8738139F0A7D0002DC13 /* AmbientMgrAL.h */,
+ A27B873B139F0A7D0002DC13 /* OpenALAudio.cpp */,
+ A27B873C139F0A7D0002DC13 /* OpenALAudio.h */,
+ A27B873D139F0A7D0002DC13 /* StackLock.cpp */,
+ A27B873E139F0A7D0002DC13 /* StackLock.h */,
+ );
+ path = OpenALAudio;
+ sourceTree = "<group>";
+ };
+ A27B873F139F0A7D0002DC13 /* PLTImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8742139F0A7D0002DC13 /* PLTImporter.cpp */,
+ A27B8743139F0A7D0002DC13 /* PLTImporter.h */,
+ );
+ path = PLTImporter;
+ sourceTree = "<group>";
+ };
+ A27B8744139F0A7D0002DC13 /* PNGImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8747139F0A7D0002DC13 /* PNGImporter.cpp */,
+ A27B8748139F0A7D0002DC13 /* PNGImporter.h */,
+ );
+ path = PNGImporter;
+ sourceTree = "<group>";
+ };
+ A27B8749139F0A7D0002DC13 /* PROImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B874C139F0A7D0002DC13 /* PROImporter.cpp */,
+ A27B874D139F0A7D0002DC13 /* PROImporter.h */,
+ );
+ path = PROImporter;
+ sourceTree = "<group>";
+ };
+ A27B874E139F0A7D0002DC13 /* PSTOpcodes */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8751139F0A7D0002DC13 /* PSTOpcodes.cpp */,
+ );
+ path = PSTOpcodes;
+ sourceTree = "<group>";
+ };
+ A27B8752139F0A7D0002DC13 /* SDLAudio */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8755139F0A7D0002DC13 /* SDLAudio.cpp */,
+ A27B8756139F0A7D0002DC13 /* SDLAudio.h */,
+ );
+ path = SDLAudio;
+ sourceTree = "<group>";
+ };
+ A27B8757139F0A7D0002DC13 /* SDLVideo */ = {
+ isa = PBXGroup;
+ children = (
+ A2DB6D5715D9ECB300D70E88 /* SpriteRenderer.inl */,
+ A2DB6D5815D9ECB300D70E88 /* TileRenderer.inl */,
+ A298DD1714EB4EEB00F59F56 /* SDL20Video.cpp */,
+ A298DD1814EB4EEB00F59F56 /* SDL20Video.h */,
+ A298DD1314EB4EDE00F59F56 /* SDL12Video.cpp */,
+ A298DD1414EB4EDE00F59F56 /* SDL12Video.h */,
+ A249187B141075A60038B170 /* CocoaWrapper.m */,
+ A27B875A139F0A7D0002DC13 /* SDLVideo.cpp */,
+ A27B875B139F0A7D0002DC13 /* SDLVideo.h */,
+ );
+ path = SDLVideo;
+ sourceTree = "<group>";
+ };
+ A27B875E139F0A7D0002DC13 /* SPLImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8761139F0A7D0002DC13 /* SPLImporter.cpp */,
+ A27B8762139F0A7D0002DC13 /* SPLImporter.h */,
+ );
+ path = SPLImporter;
+ sourceTree = "<group>";
+ };
+ A27B8763139F0A7D0002DC13 /* STOImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8766139F0A7D0002DC13 /* STOImporter.cpp */,
+ A27B8767139F0A7D0002DC13 /* STOImporter.h */,
+ );
+ path = STOImporter;
+ sourceTree = "<group>";
+ };
+ A27B8768139F0A7D0002DC13 /* TISImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B876B139F0A7D0002DC13 /* TISImporter.cpp */,
+ A27B876C139F0A7D0002DC13 /* TISImporter.h */,
+ );
+ path = TISImporter;
+ sourceTree = "<group>";
+ };
+ A27B876D139F0A7D0002DC13 /* TLKImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8770139F0A7D0002DC13 /* TLKImporter.cpp */,
+ A27B8771139F0A7D0002DC13 /* TLKImporter.h */,
+ A27B8772139F0A7D0002DC13 /* TlkOverride.cpp */,
+ A27B8773139F0A7D0002DC13 /* TlkOverride.h */,
+ );
+ path = TLKImporter;
+ sourceTree = "<group>";
+ };
+ A27B8774139F0A7D0002DC13 /* WAVReader */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8777139F0A7D0002DC13 /* WAVReader.cpp */,
+ A27B8778139F0A7D0002DC13 /* WAVReader.h */,
+ );
+ path = WAVReader;
+ sourceTree = "<group>";
+ };
+ A27B8779139F0A7D0002DC13 /* WEDImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B877C139F0A7D0002DC13 /* WEDImporter.cpp */,
+ A27B877D139F0A7D0002DC13 /* WEDImporter.h */,
+ );
+ path = WEDImporter;
+ sourceTree = "<group>";
+ };
+ A27B877E139F0A7D0002DC13 /* WMPImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8781139F0A7D0002DC13 /* WMPImporter.cpp */,
+ A27B8782139F0A7D0002DC13 /* WMPImporter.h */,
+ );
+ path = WMPImporter;
+ sourceTree = "<group>";
+ };
+ A27B8783139F0A7D0002DC13 /* ZLibManager */ = {
+ isa = PBXGroup;
+ children = (
+ A27B8786139F0A7D0002DC13 /* ZLibManager.cpp */,
+ A27B8787139F0A7D0002DC13 /* ZLibManager.h */,
+ );
+ path = ZLibManager;
+ sourceTree = "<group>";
+ };
+ A29BF91C13A04B3900C812DD /* Resources-iOS */ = {
+ isa = PBXGroup;
+ children = (
+ A22DCCE214A8FE870067D6D1 /* ios/Icon-72.png */,
+ A22DCCE014A8FE120067D6D1 /* ios/Icon at 2x.png */,
+ A22DCCDE14A8FE0F0067D6D1 /* ios/Icon.png */,
+ A2830ABA13A0624D000A63FE /* Info.plist */,
+ A238174914B781CC0058BFF4 /* GemRB.cfg.newinstall */,
+ );
+ name = "Resources-iOS";
+ sourceTree = "<group>";
+ };
+ A2A3A7D614A5030600F705CF /* mac */ = {
+ isa = PBXGroup;
+ children = (
+ A22693781422931B004468E8 /* CocoaWrapper.h */,
+ A2A3A7D814A505FD00F705CF /* CocoaWrapper.mm */,
+ A2E27EFD16F12B6C0079E104 /* nibs */,
+ );
+ name = mac;
+ sourceTree = "<group>";
+ };
+ A2A3A7DE14A5130F00F705CF /* ios */ = {
+ isa = PBXGroup;
+ children = (
+ A2A3A7DF14A5130F00F705CF /* CocoaMain.m */,
+ A2E1582F14D1D8DA0044F3C5 /* GEM_AppDelegate.h */,
+ A2E1583014D1D8DA0044F3C5 /* GEM_AppDelegate.mm */,
+ A2A3A7E014A5130F00F705CF /* GEM_ConfController.h */,
+ A2A3A7E114A5130F00F705CF /* GEM_ConfController.m */,
+ A2A3A7EE14A51B1800F705CF /* GEM_SDL_Keyboard.m */,
+ A2A3A7E214A5130F00F705CF /* nibs */,
+ );
+ name = ios;
+ path = CocoaWrapper/ios;
+ sourceTree = "<group>";
+ };
+ A2A3A7E214A5130F00F705CF /* nibs */ = {
+ isa = PBXGroup;
+ children = (
+ A2A3A7E314A5130F00F705CF /* GEM_ConfController-ipad.xib */,
+ A2A3A7E414A5130F00F705CF /* GEM_ConfController-iphone.xib */,
+ );
+ path = nibs;
+ sourceTree = "<group>";
+ };
+ A2A6A457146893CC000F1688 /* TTFImporter */ = {
+ isa = PBXGroup;
+ children = (
+ A2A2EA3216A5EB630092B903 /* TTFFont.cpp */,
+ A2A2EA3316A5EB630092B903 /* TTFFont.h */,
+ A2A6A459146893CC000F1688 /* TTFFontManager.cpp */,
+ A2A6A45A146893CC000F1688 /* TTFFontManager.h */,
+ A2A2EA3616A5FC860092B903 /* Freetype.cpp */,
+ A2A2EA3716A5FC860092B903 /* Freetype.h */,
+ );
+ path = TTFImporter;
+ sourceTree = "<group>";
+ };
+ A2BD125715A7EE35000FAB95 /* VLCPlayer */ = {
+ isa = PBXGroup;
+ children = (
+ A2A26ADB15AA729800A8E25D /* VideoContext.cpp */,
+ A2A26ADC15AA729800A8E25D /* VideoContext.h */,
+ A2BD125815A7EE61000FAB95 /* VLCPlayer.cpp */,
+ A2BD125915A7EE61000FAB95 /* VLCPlayer.h */,
+ );
+ name = VLCPlayer;
+ path = WAVReader;
+ sourceTree = "<group>";
+ };
+ A2BF9F8C1395FF61006ADC12 /* core */ = {
+ isa = PBXGroup;
+ children = (
+ A2BF9F8D1395FF61006ADC12 /* ActorMgr.cpp */,
+ A2BF9F8E1395FF61006ADC12 /* ActorMgr.h */,
+ A2BF9F8F1395FF61006ADC12 /* Ambient.cpp */,
+ A2BF9F901395FF61006ADC12 /* Ambient.h */,
+ A2BF9F911395FF61006ADC12 /* AmbientMgr.cpp */,
+ A2BF9F921395FF61006ADC12 /* AmbientMgr.h */,
+ A2BF9F931395FF61006ADC12 /* Animation.cpp */,
+ A2BF9F941395FF61006ADC12 /* Animation.h */,
+ A2BF9F951395FF61006ADC12 /* AnimationFactory.cpp */,
+ A2BF9F961395FF61006ADC12 /* AnimationFactory.h */,
+ A2BF9F971395FF61006ADC12 /* AnimationMgr.cpp */,
+ A2BF9F981395FF61006ADC12 /* AnimationMgr.h */,
+ A2BF9F991395FF61006ADC12 /* AnimStructures.h */,
+ A2BF9F9A1395FF61006ADC12 /* ArchiveImporter.cpp */,
+ A2BF9F9B1395FF61006ADC12 /* ArchiveImporter.h */,
+ A2BF9F9C1395FF61006ADC12 /* Audio.cpp */,
+ A2BF9F9D1395FF61006ADC12 /* Audio.h */,
+ A2BF9F9E1395FF61006ADC12 /* Bitmap.cpp */,
+ A2BF9F9F1395FF61006ADC12 /* Bitmap.h */,
+ A2BF9FA01395FF61006ADC12 /* Cache.cpp */,
+ A2BF9FA11395FF61006ADC12 /* Cache.h */,
+ A2BF9FA21395FF61006ADC12 /* Calendar.cpp */,
+ A2BF9FA31395FF61006ADC12 /* Calendar.h */,
+ A2BF9FA41395FF61006ADC12 /* Callback.cpp */,
+ A2BF9FA51395FF61006ADC12 /* Callback.h */,
+ A2BF9FA61395FF61006ADC12 /* CharAnimations.cpp */,
+ A2BF9FA71395FF61006ADC12 /* CharAnimations.h */,
+ A2BF9FA91395FF61006ADC12 /* Compressor.cpp */,
+ A2BF9FAA1395FF61006ADC12 /* Compressor.h */,
+ A2BF9FAB1395FF61006ADC12 /* ControlAnimation.cpp */,
+ A2BF9FAC1395FF61006ADC12 /* ControlAnimation.h */,
+ A2BF9FAD1395FF61006ADC12 /* Core.cpp */,
+ A2BF9FAE1395FF61006ADC12 /* damages.h */,
+ A2BF9FAF1395FF61006ADC12 /* DataFileMgr.cpp */,
+ A2BF9FB01395FF61006ADC12 /* DataFileMgr.h */,
+ A2BF9FB11395FF61006ADC12 /* Dialog.cpp */,
+ A2BF9FB21395FF61006ADC12 /* Dialog.h */,
+ A2BF9FB31395FF61006ADC12 /* DialogHandler.cpp */,
+ A2BF9FB41395FF61006ADC12 /* DialogHandler.h */,
+ A2BF9FB51395FF61006ADC12 /* DialogMgr.cpp */,
+ A2BF9FB61395FF61006ADC12 /* DialogMgr.h */,
+ A2BF9FB71395FF61006ADC12 /* DisplayMessage.cpp */,
+ A2BF9FB81395FF61006ADC12 /* DisplayMessage.h */,
+ A2BF9FB91395FF61006ADC12 /* Effect.h */,
+ A2BF9FBA1395FF61006ADC12 /* EffectMgr.cpp */,
+ A2BF9FBB1395FF61006ADC12 /* EffectMgr.h */,
+ A2BF9FBC1395FF61006ADC12 /* EffectQueue.cpp */,
+ A2BF9FBD1395FF61006ADC12 /* EffectQueue.h */,
+ A2BF9FBE1395FF61006ADC12 /* Factory.cpp */,
+ A2BF9FBF1395FF61006ADC12 /* Factory.h */,
+ A2BF9FC01395FF61006ADC12 /* FactoryObject.cpp */,
+ A2BF9FC11395FF61006ADC12 /* FactoryObject.h */,
+ A2BF9FC21395FF61006ADC12 /* Font.cpp */,
+ A2BF9FC31395FF61006ADC12 /* Font.h */,
+ A28D2498143BEA4200A27897 /* FontManager.cpp */,
+ A28D249B143BEA5800A27897 /* FontManager.h */,
+ A2BF9FC41395FF61006ADC12 /* Game.cpp */,
+ A2BF9FC51395FF62006ADC12 /* Game.h */,
+ A2BF9FC61395FF62006ADC12 /* GameData.cpp */,
+ A2BF9FC71395FF62006ADC12 /* GameData.h */,
+ A2BF9FC81395FF62006ADC12 /* GameScript */,
+ A2BF9FD21395FF62006ADC12 /* GlobalTimer.cpp */,
+ A2BF9FD31395FF62006ADC12 /* GlobalTimer.h */,
+ A2BF9FD41395FF62006ADC12 /* GUI */,
+ A2BF9FF11395FF62006ADC12 /* Holder.h */,
+ A2BF9FF21395FF62006ADC12 /* Image.cpp */,
+ A2BF9FF31395FF62006ADC12 /* Image.h */,
+ A2BF9FF41395FF62006ADC12 /* ImageFactory.cpp */,
+ A2BF9FF51395FF62006ADC12 /* ImageFactory.h */,
+ A2BF9FF61395FF62006ADC12 /* ImageMgr.cpp */,
+ A2BF9FF71395FF62006ADC12 /* ImageMgr.h */,
+ A2BF9FF81395FF62006ADC12 /* ImageWriter.cpp */,
+ A2BF9FF91395FF62006ADC12 /* ImageWriter.h */,
+ A2BF9FFA1395FF62006ADC12 /* IniSpawn.cpp */,
+ A2BF9FFB1395FF62006ADC12 /* IniSpawn.h */,
+ A2BF9FFC1395FF62006ADC12 /* Interface.cpp */,
+ A2BF9FFD1395FF62006ADC12 /* Interface.h */,
+ A2E27EF516EEA7B00079E104 /* InterfaceConfig.cpp */,
+ A2E27EF616EEA7B00079E104 /* InterfaceConfig.h */,
+ A2BF9FFE1395FF62006ADC12 /* Inventory.cpp */,
+ A2BF9FFF1395FF62006ADC12 /* Inventory.h */,
+ A2BFA0001395FF62006ADC12 /* Item.cpp */,
+ A2BFA0011395FF62006ADC12 /* Item.h */,
+ A2BFA0021395FF62006ADC12 /* ItemMgr.cpp */,
+ A2BFA0031395FF62006ADC12 /* ItemMgr.h */,
+ A2BFA0041395FF62006ADC12 /* LRUCache.cpp */,
+ A2BFA0051395FF62006ADC12 /* LRUCache.h */,
+ A2BFA0071395FF62006ADC12 /* Map.cpp */,
+ A2BFA0081395FF62006ADC12 /* Map.h */,
+ A2BFA0091395FF62006ADC12 /* MapMgr.cpp */,
+ A2BFA00A1395FF62006ADC12 /* MapMgr.h */,
+ A2BFA00B1395FF62006ADC12 /* MoviePlayer.cpp */,
+ A2BFA00C1395FF62006ADC12 /* MoviePlayer.h */,
+ A2BFA00D1395FF62006ADC12 /* MusicMgr.cpp */,
+ A2BFA00E1395FF62006ADC12 /* MusicMgr.h */,
+ A2BFA00F1395FF62006ADC12 /* Palette.cpp */,
+ A2BFA0101395FF62006ADC12 /* Palette.h */,
+ A2BFA0111395FF62006ADC12 /* PalettedImageMgr.cpp */,
+ A2BFA0121395FF62006ADC12 /* PalettedImageMgr.h */,
+ A2BFA0131395FF62006ADC12 /* Particles.cpp */,
+ A2BFA0141395FF62006ADC12 /* Particles.h */,
+ A2BFA0151395FF62006ADC12 /* PathFinder.h */,
+ A2BFA0161395FF62006ADC12 /* Plugin.cpp */,
+ A2BFA0171395FF62006ADC12 /* Plugin.h */,
+ A2BFA0181395FF62006ADC12 /* PluginMgr.cpp */,
+ A2BFA0191395FF62006ADC12 /* PluginMgr.h */,
+ A2BFA01A1395FF62006ADC12 /* Polygon.cpp */,
+ A2BFA01B1395FF62006ADC12 /* Polygon.h */,
+ A2BFA01C1395FF62006ADC12 /* PolymorphCache.h */,
+ A2BFA01D1395FF62006ADC12 /* Projectile.cpp */,
+ A2BFA01E1395FF62006ADC12 /* Projectile.h */,
+ A2BFA01F1395FF62006ADC12 /* ProjectileMgr.cpp */,
+ A2BFA0201395FF62006ADC12 /* ProjectileMgr.h */,
+ A2BFA0211395FF62006ADC12 /* ProjectileServer.cpp */,
+ A2BFA0221395FF62006ADC12 /* ProjectileServer.h */,
+ A2BFA0231395FF62006ADC12 /* Region.cpp */,
+ A2BFA0241395FF62006ADC12 /* Region.h */,
+ A2BFA0251395FF62006ADC12 /* Resource.cpp */,
+ A2BFA0261395FF62006ADC12 /* Resource.h */,
+ A2BFA0271395FF62006ADC12 /* ResourceDesc.cpp */,
+ A2BFA0281395FF62006ADC12 /* ResourceDesc.h */,
+ A2BFA0291395FF62006ADC12 /* ResourceManager.cpp */,
+ A2BFA02A1395FF62006ADC12 /* ResourceManager.h */,
+ A2BFA02B1395FF62006ADC12 /* ResourceSource.cpp */,
+ A2BFA02C1395FF62006ADC12 /* ResourceSource.h */,
+ A2BFA02D1395FF62006ADC12 /* SaveGame.h */,
+ A2BFA02E1395FF62006ADC12 /* SaveGameIterator.cpp */,
+ A2BFA02F1395FF62006ADC12 /* SaveGameIterator.h */,
+ A2BFA0301395FF62006ADC12 /* SaveGameMgr.cpp */,
+ A2BFA0311395FF62006ADC12 /* SaveGameMgr.h */,
+ A2BFA0321395FF62006ADC12 /* Scriptable */,
+ A2BFA03F1395FF62006ADC12 /* ScriptedAnimation.cpp */,
+ A2BFA0401395FF62006ADC12 /* ScriptedAnimation.h */,
+ A2BFA0411395FF62006ADC12 /* ScriptEngine.cpp */,
+ A2BFA0421395FF62006ADC12 /* ScriptEngine.h */,
+ A2BFA0431395FF62006ADC12 /* SoundMgr.cpp */,
+ A2BFA0441395FF62006ADC12 /* SoundMgr.h */,
+ A2BFA0451395FF62006ADC12 /* Spell.cpp */,
+ A2BFA0461395FF62006ADC12 /* Spell.h */,
+ A2BFA0471395FF62006ADC12 /* Spellbook.cpp */,
+ A2BFA0481395FF62006ADC12 /* Spellbook.h */,
+ A2BFA0491395FF62006ADC12 /* SpellMgr.cpp */,
+ A2BFA04A1395FF62006ADC12 /* SpellMgr.h */,
+ A2BFA04B1395FF62006ADC12 /* Sprite2D.cpp */,
+ A2BFA04C1395FF62006ADC12 /* Sprite2D.h */,
+ A2BFA04D1395FF62006ADC12 /* SpriteCover.cpp */,
+ A2BFA04E1395FF62006ADC12 /* SpriteCover.h */,
+ A2BFA04F1395FF62006ADC12 /* Store.cpp */,
+ A2BFA0501395FF62006ADC12 /* Store.h */,
+ A2BFA0511395FF62006ADC12 /* StoreMgr.cpp */,
+ A2BFA0521395FF62006ADC12 /* StoreMgr.h */,
+ A2BFA0531395FF62006ADC12 /* StringMgr.cpp */,
+ A2BFA0541395FF62006ADC12 /* StringMgr.h */,
+ A2BFA0551395FF62006ADC12 /* SymbolMgr.cpp */,
+ A2BFA0561395FF62006ADC12 /* SymbolMgr.h */,
+ A2BFA0571395FF62006ADC12 /* System */,
+ A2BFA0681395FF62006ADC12 /* TableMgr.cpp */,
+ A2BFA0691395FF62006ADC12 /* TableMgr.h */,
+ A2BFA06A1395FF62006ADC12 /* Tile.cpp */,
+ A2BFA06B1395FF62006ADC12 /* Tile.h */,
+ A2BFA06C1395FF62006ADC12 /* TileMap.cpp */,
+ A2BFA06D1395FF62006ADC12 /* TileMap.h */,
+ A2BFA06E1395FF62006ADC12 /* TileMapMgr.cpp */,
+ A2BFA06F1395FF62006ADC12 /* TileMapMgr.h */,
+ A2BFA0701395FF62006ADC12 /* TileOverlay.cpp */,
+ A2BFA0711395FF62006ADC12 /* TileOverlay.h */,
+ A2BFA0721395FF62006ADC12 /* TileSetMgr.cpp */,
+ A2BFA0731395FF62006ADC12 /* TileSetMgr.h */,
+ A2BFA0741395FF62006ADC12 /* TypeID.h */,
+ A2BFA0751395FF62006ADC12 /* Variables.cpp */,
+ A2BFA0761395FF62006ADC12 /* Variables.h */,
+ A2BFA0771395FF62006ADC12 /* Video.cpp */,
+ A2BFA0781395FF62006ADC12 /* Video.h */,
+ A2BFA0791395FF62006ADC12 /* VideoMode.h */,
+ A2BFA07A1395FF62006ADC12 /* WindowMgr.cpp */,
+ A2BFA07B1395FF62006ADC12 /* WindowMgr.h */,
+ A2BFA07C1395FF62006ADC12 /* WorldMap.cpp */,
+ A2BFA07D1395FF62006ADC12 /* WorldMap.h */,
+ A2BFA07E1395FF62006ADC12 /* WorldMapMgr.cpp */,
+ A2BFA07F1395FF62006ADC12 /* WorldMapMgr.h */,
+ );
+ name = core;
+ path = ../gemrb/core;
+ sourceTree = SOURCE_ROOT;
+ };
+ A2BF9FC81395FF62006ADC12 /* GameScript */ = {
+ isa = PBXGroup;
+ children = (
+ A2BF9FC91395FF62006ADC12 /* Actions.cpp */,
+ A2BF9FCA1395FF62006ADC12 /* GameScript.cpp */,
+ A2BF9FCB1395FF62006ADC12 /* GameScript.h */,
+ A2BF9FCC1395FF62006ADC12 /* GSUtils.cpp */,
+ A2BF9FCD1395FF62006ADC12 /* GSUtils.h */,
+ A2BF9FCE1395FF62006ADC12 /* Matching.cpp */,
+ A2BF9FCF1395FF62006ADC12 /* Matching.h */,
+ A2BF9FD01395FF62006ADC12 /* Objects.cpp */,
+ A2BF9FD11395FF62006ADC12 /* Triggers.cpp */,
+ );
+ path = GameScript;
+ sourceTree = "<group>";
+ };
+ A2BF9FD41395FF62006ADC12 /* GUI */ = {
+ isa = PBXGroup;
+ children = (
+ A2BF9FD51395FF62006ADC12 /* Button.cpp */,
+ A2BF9FD61395FF62006ADC12 /* Button.h */,
+ A2BF9FD71395FF62006ADC12 /* Console.cpp */,
+ A2BF9FD81395FF62006ADC12 /* Console.h */,
+ A2BF9FD91395FF62006ADC12 /* Control.cpp */,
+ A2BF9FDA1395FF62006ADC12 /* Control.h */,
+ A2BF9FDB1395FF62006ADC12 /* EventMgr.cpp */,
+ A2BF9FDC1395FF62006ADC12 /* EventMgr.h */,
+ A265ECD813A8661600C6DF12 /* FileCache.cpp */,
+ A2BF9FDD1395FF62006ADC12 /* GameControl.cpp */,
+ A2BF9FDE1395FF62006ADC12 /* GameControl.h */,
+ A265ECD913A8661600C6DF12 /* IndexedArchive.cpp */,
+ A265ECDA13A8661600C6DF12 /* KeyMap.cpp */,
+ A2BF9FDF1395FF62006ADC12 /* Label.cpp */,
+ A2BF9FE01395FF62006ADC12 /* Label.h */,
+ A2BF9FE11395FF62006ADC12 /* MapControl.cpp */,
+ A2BF9FE21395FF62006ADC12 /* MapControl.h */,
+ A265ECDB13A8661600C6DF12 /* PluginLoader.cpp */,
+ A2BF9FE31395FF62006ADC12 /* Progressbar.cpp */,
+ A2BF9FE41395FF62006ADC12 /* Progressbar.h */,
+ A2BF9FE51395FF62006ADC12 /* ScrollBar.cpp */,
+ A2BF9FE61395FF62006ADC12 /* ScrollBar.h */,
+ A265ECEB13A8669700C6DF12 /* SlicedStream.cpp */,
+ A2BF9FE71395FF62006ADC12 /* Slider.cpp */,
+ A2BF9FE81395FF62006ADC12 /* Slider.h */,
+ A265ECEC13A8669700C6DF12 /* String.cpp */,
+ A2BF9FE91395FF62006ADC12 /* TextArea.cpp */,
+ A2BF9FEA1395FF62006ADC12 /* TextArea.h */,
+ A2BF9FEB1395FF62006ADC12 /* TextEdit.cpp */,
+ A2BF9FEC1395FF62006ADC12 /* TextEdit.h */,
+ A2BF9FED1395FF62006ADC12 /* Window.cpp */,
+ A2BF9FEE1395FF62006ADC12 /* Window.h */,
+ A2BF9FEF1395FF62006ADC12 /* WorldMapControl.cpp */,
+ A2BF9FF01395FF62006ADC12 /* WorldMapControl.h */,
+ );
+ path = GUI;
+ sourceTree = "<group>";
+ };
+ A2BFA0321395FF62006ADC12 /* Scriptable */ = {
+ isa = PBXGroup;
+ children = (
+ A2BFA0331395FF62006ADC12 /* Actor.cpp */,
+ A2BFA0341395FF62006ADC12 /* Actor.h */,
+ A2969F0D168CDC0D00D9C6FC /* CombatInfo.cpp */,
+ A2969F0E168CDC0D00D9C6FC /* CombatInfo.h */,
+ A2BFA0351395FF62006ADC12 /* Container.cpp */,
+ A2BFA0361395FF62006ADC12 /* Container.h */,
+ A2BFA0371395FF62006ADC12 /* Door.cpp */,
+ A2BFA0381395FF62006ADC12 /* Door.h */,
+ A2BFA0391395FF62006ADC12 /* InfoPoint.cpp */,
+ A2BFA03A1395FF62006ADC12 /* InfoPoint.h */,
+ A2BFA03B1395FF62006ADC12 /* PCStatStruct.cpp */,
+ A2BFA03C1395FF62006ADC12 /* PCStatStruct.h */,
+ A2BFA03D1395FF62006ADC12 /* Scriptable.cpp */,
+ A2BFA03E1395FF62006ADC12 /* Scriptable.h */,
+ );
+ path = Scriptable;
+ sourceTree = "<group>";
+ };
+ A2BFA0571395FF62006ADC12 /* System */ = {
+ isa = PBXGroup;
+ children = (
+ A2BFA05C1395FF62006ADC12 /* DataStream.cpp */,
+ A2BFA05D1395FF62006ADC12 /* DataStream.h */,
+ A2BFA05E1395FF62006ADC12 /* FileStream.cpp */,
+ A2BFA05F1395FF62006ADC12 /* FileStream.h */,
+ A2DE329B14EB078200117503 /* Logger */,
+ A2DE329714EB071200117503 /* Logger.cpp */,
+ A2DE329814EB071200117503 /* Logger.h */,
+ A265ECEA13A8669700C6DF12 /* Logging.cpp */,
+ A2BFA0601395FF62006ADC12 /* MemoryStream.cpp */,
+ A2BFA0611395FF62006ADC12 /* MemoryStream.h */,
+ A2C76D2814F196E900961680 /* StringBuffer.cpp */,
+ A2C76D2914F196E900961680 /* StringBuffer.h */,
+ A2BFA0641395FF62006ADC12 /* swab.c */,
+ A2BFA0651395FF62006ADC12 /* swab.h */,
+ A2BFA0661395FF62006ADC12 /* VFS.cpp */,
+ A2BFA0671395FF62006ADC12 /* VFS.h */,
+ );
+ path = System;
+ sourceTree = "<group>";
+ };
+ A2D4C51D13A978110086BCC4 /* includes */ = {
+ isa = PBXGroup;
+ children = (
+ A2D4C51E13A978110086BCC4 /* defsounds.h */,
+ A2D4C51F13A978110086BCC4 /* errors.h */,
+ A2D4C52013A978110086BCC4 /* exports.h */,
+ A2D4C52113A978110086BCC4 /* globals.h */,
+ A2D4C52213A978110086BCC4 /* HashMap.h */,
+ A2D4C52313A978110086BCC4 /* ie_feats.h */,
+ A2D4C52413A978110086BCC4 /* ie_stats.h */,
+ A2D4C52513A978110086BCC4 /* ie_types.h */,
+ A2D4C52613A978110086BCC4 /* iless.h */,
+ A2D4C52813A978110086BCC4 /* opcode_params.h */,
+ A2D4C52913A978110086BCC4 /* operatorbool.h */,
+ A2D4C52A13A978110086BCC4 /* overlays.h */,
+ A2D4C52B13A978110086BCC4 /* plugindef.h */,
+ A2D4C52C13A978110086BCC4 /* RGBAColor.h */,
+ A2D4C52D13A978110086BCC4 /* SClassID.h */,
+ A2D4C52E13A978110086BCC4 /* StringMap.h */,
+ A2D4C52F13A978110086BCC4 /* strrefs.h */,
+ A2D4C53013A978110086BCC4 /* win32def.h */,
+ );
+ name = includes;
+ path = ../gemrb/includes;
+ sourceTree = SOURCE_ROOT;
+ };
+ A2DE329B14EB078200117503 /* Logger */ = {
+ isa = PBXGroup;
+ children = (
+ A2CB5AC115000A0D00B5C154 /* File.cpp */,
+ A2CB5AC215000A0D00B5C154 /* File.h */,
+ A298DD2114EB61D300F59F56 /* Stdio.cpp */,
+ A298DD1B14EB61C100F59F56 /* Stdio.h */,
+ A230584715D5BBCC00BDF69C /* MessageWindowLogger.cpp */,
+ A230584815D5BBCC00BDF69C /* MessageWindowLogger.h */,
+ );
+ path = Logger;
+ sourceTree = "<group>";
+ };
+ A2E27EFD16F12B6C0079E104 /* nibs */ = {
+ isa = PBXGroup;
+ children = (
+ A2E27EFB16F12B5A0079E104 /* GemRB.xib */,
+ );
+ name = nibs;
+ sourceTree = "<group>";
+ };
+ A2E7985B14845AFB00B15DF4 /* iOS static libs */ = {
+ isa = PBXGroup;
+ children = (
+ A22B5D5D1583D816007B4AA4 /* libFreetype2.a */,
+ A22B5D5E1583D816007B4AA4 /* libPython.a */,
+ A22B5D601583D816007B4AA4 /* libSDL2.a */,
+ );
+ name = "iOS static libs";
+ sourceTree = "<group>";
+ };
+ A2E7985C14845B3F00B15DF4 /* dylibs */ = {
+ isa = PBXGroup;
+ children = (
+ A228D24816A86FA00053375D /* libiconv.dylib */,
+ A2A2EA4516A76ACC0092B903 /* libiconv.dylib */,
+ A288621F14A54FFD009AC280 /* libarchive.dylib */,
+ A288622114A5501F009AC280 /* libz.dylib */,
+ A273DC7B14856755000DA299 /* libz.dylib */,
+ );
+ name = dylibs;
+ sourceTree = "<group>";
+ };
+ A2FE2C7516F2313400DDC6C7 /* NullSource */ = {
+ isa = PBXGroup;
+ children = (
+ A2FE2C7716F2313400DDC6C7 /* NullSource.cpp */,
+ A2FE2C7816F2313400DDC6C7 /* NullSource.h */,
+ );
+ path = NullSource;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ A2E66334139E875400310FC8 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2E6634F139E882900310FC8 /* ActorMgr.h in Headers */,
+ A2E66351139E882900310FC8 /* Ambient.h in Headers */,
+ A2E66353139E882900310FC8 /* AmbientMgr.h in Headers */,
+ A2E66355139E882900310FC8 /* Animation.h in Headers */,
+ A2E66357139E883100310FC8 /* AnimationFactory.h in Headers */,
+ A2E66359139E883100310FC8 /* AnimationMgr.h in Headers */,
+ A2E6635A139E883100310FC8 /* AnimStructures.h in Headers */,
+ A2E6635C139E883100310FC8 /* ArchiveImporter.h in Headers */,
+ A2E6635E139E883100310FC8 /* Audio.h in Headers */,
+ A2E66360139E883100310FC8 /* Bitmap.h in Headers */,
+ A2E66362139E883100310FC8 /* Cache.h in Headers */,
+ A2E66364139E883100310FC8 /* Calendar.h in Headers */,
+ A2E66366139E883100310FC8 /* Callback.h in Headers */,
+ A2E66368139E883100310FC8 /* CharAnimations.h in Headers */,
+ A2E6636A139E883100310FC8 /* Compressor.h in Headers */,
+ A2E6636C139E883100310FC8 /* ControlAnimation.h in Headers */,
+ A2E6636E139E883100310FC8 /* damages.h in Headers */,
+ A2E66370139E883100310FC8 /* DataFileMgr.h in Headers */,
+ A2E66372139E883100310FC8 /* Dialog.h in Headers */,
+ A2E66374139E883100310FC8 /* DialogHandler.h in Headers */,
+ A2E66376139E883100310FC8 /* DialogMgr.h in Headers */,
+ A2E66378139E883100310FC8 /* DisplayMessage.h in Headers */,
+ A2E66379139E883100310FC8 /* Effect.h in Headers */,
+ A2E6637B139E883100310FC8 /* EffectMgr.h in Headers */,
+ A2E6637D139E883100310FC8 /* EffectQueue.h in Headers */,
+ A2E6637F139E883100310FC8 /* Factory.h in Headers */,
+ A2E66381139E883100310FC8 /* FactoryObject.h in Headers */,
+ A2E66383139E883100310FC8 /* Font.h in Headers */,
+ A2E66385139E883100310FC8 /* Game.h in Headers */,
+ A2E66387139E883100310FC8 /* GameData.h in Headers */,
+ A2E66389139E883700310FC8 /* GlobalTimer.h in Headers */,
+ A2E6638A139E883E00310FC8 /* Holder.h in Headers */,
+ A2E6638C139E883E00310FC8 /* Image.h in Headers */,
+ A2E6638E139E883E00310FC8 /* ImageFactory.h in Headers */,
+ A2E66390139E883E00310FC8 /* ImageMgr.h in Headers */,
+ A2E66392139E883E00310FC8 /* ImageWriter.h in Headers */,
+ A2E66394139E883E00310FC8 /* IniSpawn.h in Headers */,
+ A2E66396139E883E00310FC8 /* Interface.h in Headers */,
+ A2E66398139E883E00310FC8 /* Inventory.h in Headers */,
+ A2E6639A139E883E00310FC8 /* Item.h in Headers */,
+ A2E6639C139E883E00310FC8 /* ItemMgr.h in Headers */,
+ A2E6639E139E883E00310FC8 /* LRUCache.h in Headers */,
+ A2E663A0139E883E00310FC8 /* Map.h in Headers */,
+ A2E663A2139E883E00310FC8 /* MapMgr.h in Headers */,
+ A2E663A4139E883E00310FC8 /* MoviePlayer.h in Headers */,
+ A2E663A6139E883E00310FC8 /* MusicMgr.h in Headers */,
+ A2E663A8139E883E00310FC8 /* Palette.h in Headers */,
+ A2E663AA139E883E00310FC8 /* PalettedImageMgr.h in Headers */,
+ A2E663AC139E883E00310FC8 /* Particles.h in Headers */,
+ A2E663AD139E883E00310FC8 /* PathFinder.h in Headers */,
+ A2E663AF139E883E00310FC8 /* Plugin.h in Headers */,
+ A2E663B1139E883E00310FC8 /* PluginMgr.h in Headers */,
+ A2E663B3139E883E00310FC8 /* Polygon.h in Headers */,
+ A2E663B4139E883E00310FC8 /* PolymorphCache.h in Headers */,
+ A2E663B6139E883E00310FC8 /* Projectile.h in Headers */,
+ A2E663B8139E883E00310FC8 /* ProjectileMgr.h in Headers */,
+ A2E663BA139E883E00310FC8 /* ProjectileServer.h in Headers */,
+ A2E663BC139E883E00310FC8 /* Region.h in Headers */,
+ A2E663BE139E883E00310FC8 /* Resource.h in Headers */,
+ A2E663C0139E883E00310FC8 /* ResourceDesc.h in Headers */,
+ A2E663C2139E883E00310FC8 /* ResourceManager.h in Headers */,
+ A2E663C4139E883E00310FC8 /* ResourceSource.h in Headers */,
+ A2E663C5139E883E00310FC8 /* SaveGame.h in Headers */,
+ A2E663C7139E883E00310FC8 /* SaveGameIterator.h in Headers */,
+ A2E663C9139E883E00310FC8 /* SaveGameMgr.h in Headers */,
+ A2E663CB139E884500310FC8 /* ScriptedAnimation.h in Headers */,
+ A2E663CD139E884500310FC8 /* ScriptEngine.h in Headers */,
+ A2E663CF139E884500310FC8 /* SoundMgr.h in Headers */,
+ A2E663D1139E884500310FC8 /* Spell.h in Headers */,
+ A2E663D3139E884500310FC8 /* Spellbook.h in Headers */,
+ A2E663D5139E884500310FC8 /* SpellMgr.h in Headers */,
+ A2E663D7139E884500310FC8 /* Sprite2D.h in Headers */,
+ A2E663D9139E884500310FC8 /* SpriteCover.h in Headers */,
+ A2E663DB139E884500310FC8 /* Store.h in Headers */,
+ A2E663DD139E884500310FC8 /* StoreMgr.h in Headers */,
+ A2E663DF139E884500310FC8 /* StringMgr.h in Headers */,
+ A2E663E1139E884500310FC8 /* SymbolMgr.h in Headers */,
+ A2E663E3139E884B00310FC8 /* TableMgr.h in Headers */,
+ A2E663E5139E884B00310FC8 /* Tile.h in Headers */,
+ A2E663E7139E884B00310FC8 /* TileMap.h in Headers */,
+ A2E663E9139E884B00310FC8 /* TileMapMgr.h in Headers */,
+ A2E663EB139E884B00310FC8 /* TileOverlay.h in Headers */,
+ A2E663ED139E884B00310FC8 /* TileSetMgr.h in Headers */,
+ A2E663EE139E884B00310FC8 /* TypeID.h in Headers */,
+ A2E663F0139E884B00310FC8 /* Variables.h in Headers */,
+ A2E663F2139E884B00310FC8 /* Video.h in Headers */,
+ A2E663F3139E884B00310FC8 /* VideoMode.h in Headers */,
+ A2E663F5139E884B00310FC8 /* WindowMgr.h in Headers */,
+ A2E663F7139E884B00310FC8 /* WorldMap.h in Headers */,
+ A2E663F9139E884B00310FC8 /* WorldMapMgr.h in Headers */,
+ A2E663FD139E885300310FC8 /* DataStream.h in Headers */,
+ A2E663FF139E885300310FC8 /* FileStream.h in Headers */,
+ A2E66401139E885300310FC8 /* MemoryStream.h in Headers */,
+ A2E66405139E885300310FC8 /* swab.h in Headers */,
+ A2E66407139E885300310FC8 /* VFS.h in Headers */,
+ A2E66409139E885A00310FC8 /* Actor.h in Headers */,
+ A2E6640B139E885A00310FC8 /* Container.h in Headers */,
+ A2E6640D139E885A00310FC8 /* Door.h in Headers */,
+ A2E6640F139E885A00310FC8 /* InfoPoint.h in Headers */,
+ A2E66411139E885A00310FC8 /* PCStatStruct.h in Headers */,
+ A2E66413139E885A00310FC8 /* Scriptable.h in Headers */,
+ A2E66415139E886100310FC8 /* Button.h in Headers */,
+ A2E66417139E886100310FC8 /* Console.h in Headers */,
+ A2E66418139E886100310FC8 /* config.h in Headers */,
+ A2E6641A139E886100310FC8 /* Control.h in Headers */,
+ A2E6641C139E886100310FC8 /* EventMgr.h in Headers */,
+ A2E6641E139E886100310FC8 /* GameControl.h in Headers */,
+ A2E66420139E886100310FC8 /* Label.h in Headers */,
+ A2E66422139E886100310FC8 /* MapControl.h in Headers */,
+ A2E66424139E886100310FC8 /* Progressbar.h in Headers */,
+ A2E66426139E886100310FC8 /* ScrollBar.h in Headers */,
+ A2E66428139E886100310FC8 /* Slider.h in Headers */,
+ A2E6642A139E886100310FC8 /* TextArea.h in Headers */,
+ A2E6642C139E886100310FC8 /* TextEdit.h in Headers */,
+ A2E6642E139E886100310FC8 /* Window.h in Headers */,
+ A2E66430139E886100310FC8 /* WorldMapControl.h in Headers */,
+ A2E66433139E886700310FC8 /* GameScript.h in Headers */,
+ A2E66435139E886700310FC8 /* GSUtils.h in Headers */,
+ A2E66437139E886700310FC8 /* Matching.h in Headers */,
+ A2DE329A14EB071200117503 /* Logger.h in Headers */,
+ A298DD1D14EB61C100F59F56 /* Stdio.h in Headers */,
+ A2C76D2C14F196E900961680 /* StringBuffer.h in Headers */,
+ A2CB5AC515000A0D00B5C154 /* File.h in Headers */,
+ A230584A15D5BBCC00BDF69C /* MessageWindowLogger.h in Headers */,
+ A2969F11168CDC0D00D9C6FC /* CombatInfo.h in Headers */,
+ A2E27EF916EEA7B00079E104 /* InterfaceConfig.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ 8D1107260486CEB800E47090 /* GemRB OS X */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "GemRB OS X" */;
+ buildPhases = (
+ 8D1107290486CEB800E47090 /* Resources */,
+ 8D11072C0486CEB800E47090 /* Sources */,
+ 002F39FD09D0883400EBEB88 /* Copy Frameworks into .app bundle */,
+ 8D11072E0486CEB800E47090 /* Frameworks */,
+ A2E9965214DE051F0052BABE /* CopyFiles */,
+ A249187F141079510038B170 /* ShellScript */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ A2FE2C8316F231CB00DDC6C7 /* PBXTargetDependency */,
+ A295047A1609725F00BB22AA /* PBXTargetDependency */,
+ A29F3EE415A8E6DE00C85084 /* PBXTargetDependency */,
+ A2AF8FCD14DDCEBD005CAC5D /* PBXTargetDependency */,
+ A2E6633C139E876900310FC8 /* PBXTargetDependency */,
+ A23EBFFC1419A81500CC049E /* PBXTargetDependency */,
+ A2375BA113AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BA313AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BA513AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BA713AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BA913AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BAB13AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BAD13AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BAF13AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BB113AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BB313AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BB513AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BB713AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BB913AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BBB13AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BBD13AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BBF13AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BC113AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BC313AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BC513AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BC713AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BC913AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BCB13AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BCD13AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BCF13AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BD313AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BD513AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BD713AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BD913AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BDD13AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BDF13AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BE113AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BE313AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BE513AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BE713AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BE913AAF58E00E7EF9B /* PBXTargetDependency */,
+ A2375BEB13AAF58E00E7EF9B /* PBXTargetDependency */,
+ );
+ name = "GemRB OS X";
+ productInstallPath = "$(HOME)/Applications";
+ productName = GemRB_OSX;
+ productReference = 8D1107320486CEB800E47090 /* GemRB.app */;
+ productType = "com.apple.product-type.application";
+ };
+ A2462F1013A036B1002D1F02 /* AREImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A2462F1813A036C8002D1F02 /* Build configuration list for PBXNativeTarget "AREImporter" */;
+ buildPhases = (
+ A2462F0E13A036B1002D1F02 /* Sources */,
+ A2462F0F13A036B1002D1F02 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ A2C48CEF14A3FEFD00575FE5 /* PBXTargetDependency */,
+ );
+ name = AREImporter;
+ productName = AREImporter;
+ productReference = A2462F1113A036B1002D1F02 /* AREImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B3C913A2867900D41A8A /* BIFImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B3CD13A2869700D41A8A /* Build configuration list for PBXNativeTarget "BIFImporter" */;
+ buildPhases = (
+ A276B3C713A2867900D41A8A /* Sources */,
+ A276B3C813A2867900D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ A2C48CF314A3FF0300575FE5 /* PBXTargetDependency */,
+ );
+ name = BIFImporter;
+ productName = BIFImporter;
+ productReference = A276B3CA13A2867900D41A8A /* BIFImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B3D013A286A800D41A8A /* BIKPlayer */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B43513A287CC00D41A8A /* Build configuration list for PBXNativeTarget "BIKPlayer" */;
+ buildPhases = (
+ A276B3CE13A286A800D41A8A /* Sources */,
+ A276B3CF13A286A800D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ A2C48CF514A3FF0600575FE5 /* PBXTargetDependency */,
+ );
+ name = BIKPlayer;
+ productName = BIKPlayer;
+ productReference = A276B3D113A286A800D41A8A /* BIKPlayer.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B3D613A286BC00D41A8A /* BMPImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B43613A287CC00D41A8A /* Build configuration list for PBXNativeTarget "BMPImporter" */;
+ buildPhases = (
+ A276B3D413A286BC00D41A8A /* Sources */,
+ A276B3D513A286BC00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ A2C48CF714A3FF0900575FE5 /* PBXTargetDependency */,
+ );
+ name = BMPImporter;
+ productName = BMPImporter;
+ productReference = A276B3D713A286BC00D41A8A /* BMPImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B3DC13A286CD00D41A8A /* BMPWriter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B43713A287CC00D41A8A /* Build configuration list for PBXNativeTarget "BMPWriter" */;
+ buildPhases = (
+ A276B3DA13A286CD00D41A8A /* Sources */,
+ A276B3DB13A286CD00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ A2C48CF914A3FF0D00575FE5 /* PBXTargetDependency */,
+ );
+ name = BMPWriter;
+ productName = BMPWriter;
+ productReference = A276B3DD13A286CD00D41A8A /* BMPWriter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B3E213A286DE00D41A8A /* CHUImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B43813A287CC00D41A8A /* Build configuration list for PBXNativeTarget "CHUImporter" */;
+ buildPhases = (
+ A276B3E013A286DE00D41A8A /* Sources */,
+ A276B3E113A286DE00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = CHUImporter;
+ productName = CHUImporter;
+ productReference = A276B3E313A286DE00D41A8A /* CHUImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B3E813A286EC00D41A8A /* CREImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B43913A287CC00D41A8A /* Build configuration list for PBXNativeTarget "CREImporter" */;
+ buildPhases = (
+ A276B3E613A286EC00D41A8A /* Sources */,
+ A276B3E713A286EC00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = CREImporter;
+ productName = CREImporter;
+ productReference = A276B3E913A286EC00D41A8A /* CREImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B3EE13A286FB00D41A8A /* DirectoryImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B43A13A287CC00D41A8A /* Build configuration list for PBXNativeTarget "DirectoryImporter" */;
+ buildPhases = (
+ A276B3EC13A286FB00D41A8A /* Sources */,
+ A276B3ED13A286FB00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = DirectoryImporter;
+ productName = DirectoryImporter;
+ productReference = A276B3EF13A286FB00D41A8A /* DirectoryImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B3F413A2871300D41A8A /* DLGImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B43B13A287CC00D41A8A /* Build configuration list for PBXNativeTarget "DLGImporter" */;
+ buildPhases = (
+ A276B3F213A2871300D41A8A /* Sources */,
+ A276B3F313A2871300D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = DLGImporter;
+ productName = DLGImporter;
+ productReference = A276B3F513A2871300D41A8A /* DLGImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B3FA13A2872500D41A8A /* EFFImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B43C13A287CC00D41A8A /* Build configuration list for PBXNativeTarget "EFFImporter" */;
+ buildPhases = (
+ A276B3F813A2872500D41A8A /* Sources */,
+ A276B3F913A2872500D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = EFFImporter;
+ productName = EFFImporter;
+ productReference = A276B3FB13A2872500D41A8A /* EFFImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B40013A2873700D41A8A /* FXOpcodes */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B43D13A287CC00D41A8A /* Build configuration list for PBXNativeTarget "FXOpcodes" */;
+ buildPhases = (
+ A276B3FE13A2873700D41A8A /* Sources */,
+ A276B3FF13A2873700D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = FXOpcodes;
+ productName = FXOpcodes;
+ productReference = A276B40113A2873700D41A8A /* FXOpcodes.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B40613A2874700D41A8A /* GAMImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B43E13A287CC00D41A8A /* Build configuration list for PBXNativeTarget "GAMImporter" */;
+ buildPhases = (
+ A276B40413A2874700D41A8A /* Sources */,
+ A276B40513A2874700D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = GAMImporter;
+ productName = GAMImporter;
+ productReference = A276B40713A2874700D41A8A /* GAMImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B40C13A2875400D41A8A /* GUIScript */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B43F13A287CC00D41A8A /* Build configuration list for PBXNativeTarget "GUIScript" */;
+ buildPhases = (
+ A276B40A13A2875400D41A8A /* Sources */,
+ A276B40B13A2875400D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = GUIScript;
+ productName = GUIScript;
+ productReference = A276B40D13A2875400D41A8A /* GUIScript.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B41213A2876300D41A8A /* IDSImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B44013A287CC00D41A8A /* Build configuration list for PBXNativeTarget "IDSImporter" */;
+ buildPhases = (
+ A276B41013A2876300D41A8A /* Sources */,
+ A276B41113A2876300D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = IDSImporter;
+ productName = IDSImporter;
+ productReference = A276B41313A2876300D41A8A /* IDSImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B41813A2877100D41A8A /* INIImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B44113A287CC00D41A8A /* Build configuration list for PBXNativeTarget "INIImporter" */;
+ buildPhases = (
+ A276B41613A2877100D41A8A /* Sources */,
+ A276B41713A2877100D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = INIImporter;
+ productName = INIImporter;
+ productReference = A276B41913A2877100D41A8A /* INIImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B41E13A2878400D41A8A /* ITMImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B44213A287CC00D41A8A /* Build configuration list for PBXNativeTarget "ITMImporter" */;
+ buildPhases = (
+ A276B41C13A2878400D41A8A /* Sources */,
+ A276B41D13A2878400D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = ITMImporter;
+ productName = ITMImporter;
+ productReference = A276B41F13A2878400D41A8A /* ITMImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B42413A2879900D41A8A /* IWDOpcodes */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B44313A287CC00D41A8A /* Build configuration list for PBXNativeTarget "IWDOpcodes" */;
+ buildPhases = (
+ A276B42213A2879900D41A8A /* Sources */,
+ A276B42313A2879900D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = IWDOpcodes;
+ productName = IWDOpcodes;
+ productReference = A276B42513A2879900D41A8A /* IWDOpcodes.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B42A13A287AB00D41A8A /* KEYImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B44413A287CC00D41A8A /* Build configuration list for PBXNativeTarget "KEYImporter" */;
+ buildPhases = (
+ A276B42813A287AB00D41A8A /* Sources */,
+ A276B42913A287AB00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = KEYImporter;
+ productName = KEYImporter;
+ productReference = A276B42B13A287AB00D41A8A /* KEYImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B43013A287BC00D41A8A /* MOSImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B44513A287CC00D41A8A /* Build configuration list for PBXNativeTarget "MOSImporter" */;
+ buildPhases = (
+ A276B42E13A287BC00D41A8A /* Sources */,
+ A276B42F13A287BC00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = MOSImporter;
+ productName = MOSImporter;
+ productReference = A276B43113A287BD00D41A8A /* MOSImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B44813A289E000D41A8A /* MUSImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4B313A28AF400D41A8A /* Build configuration list for PBXNativeTarget "MUSImporter" */;
+ buildPhases = (
+ A276B44613A289E000D41A8A /* Sources */,
+ A276B44713A289E000D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = MUSImporter;
+ productName = MUSImporter;
+ productReference = A276B44913A289E000D41A8A /* MUSImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B44E13A28A0000D41A8A /* MVEPlayer */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4B413A28AF400D41A8A /* Build configuration list for PBXNativeTarget "MVEPlayer" */;
+ buildPhases = (
+ A276B44C13A28A0000D41A8A /* Sources */,
+ A276B44D13A28A0000D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = MVEPlayer;
+ productName = MVEPlayer;
+ productReference = A276B44F13A28A0000D41A8A /* MVEPlayer.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B45413A28A0E00D41A8A /* NullSound */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4B513A28AF400D41A8A /* Build configuration list for PBXNativeTarget "NullSound" */;
+ buildPhases = (
+ A276B45213A28A0E00D41A8A /* Sources */,
+ A276B45313A28A0E00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = NullSound;
+ productName = NullSound;
+ productReference = A276B45513A28A0E00D41A8A /* NullSound.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B45A13A28A1C00D41A8A /* OGGReader */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4B613A28AF400D41A8A /* Build configuration list for PBXNativeTarget "OGGReader" */;
+ buildPhases = (
+ A276B45813A28A1C00D41A8A /* Sources */,
+ A276B45913A28A1C00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ A2E9967E14DE12970052BABE /* PBXTargetDependency */,
+ );
+ name = OGGReader;
+ productName = OGGReader;
+ productReference = A276B45B13A28A1C00D41A8A /* OGGReader.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B46013A28A3100D41A8A /* OpenALAudio */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4B713A28AF400D41A8A /* Build configuration list for PBXNativeTarget "OpenALAudio" */;
+ buildPhases = (
+ A276B45E13A28A3100D41A8A /* Sources */,
+ A276B45F13A28A3100D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = OpenALAudio;
+ productName = OpenALAudio;
+ productReference = A276B46113A28A3100D41A8A /* OpenALAudio.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B46613A28A3F00D41A8A /* PLTImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4B813A28AF400D41A8A /* Build configuration list for PBXNativeTarget "PLTImporter" */;
+ buildPhases = (
+ A276B46413A28A3F00D41A8A /* Sources */,
+ A276B46513A28A3F00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = PLTImporter;
+ productName = PLTImporter;
+ productReference = A276B46713A28A3F00D41A8A /* PLTImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B46C13A28A5000D41A8A /* PNGImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4B913A28AF400D41A8A /* Build configuration list for PBXNativeTarget "PNGImporter" */;
+ buildPhases = (
+ A276B46A13A28A5000D41A8A /* Sources */,
+ A276B46B13A28A5000D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ A2E9968014DE12A90052BABE /* PBXTargetDependency */,
+ );
+ name = PNGImporter;
+ productName = PNGImporter;
+ productReference = A276B46D13A28A5000D41A8A /* PNGImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B47213A28A5D00D41A8A /* PROImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4BA13A28AF400D41A8A /* Build configuration list for PBXNativeTarget "PROImporter" */;
+ buildPhases = (
+ A276B47013A28A5D00D41A8A /* Sources */,
+ A276B47113A28A5D00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = PROImporter;
+ productName = PROImporter;
+ productReference = A276B47313A28A5D00D41A8A /* PROImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B47813A28A7600D41A8A /* PSTOpcodes */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4BB13A28AF400D41A8A /* Build configuration list for PBXNativeTarget "PSTOpcodes" */;
+ buildPhases = (
+ A276B47613A28A7600D41A8A /* Sources */,
+ A276B47713A28A7600D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = PSTOpcodes;
+ productName = PSTOpcodes;
+ productReference = A276B47913A28A7600D41A8A /* PSTOpcodes.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B47E13A28A8500D41A8A /* SDLAudio */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4BC13A28AF400D41A8A /* Build configuration list for PBXNativeTarget "SDLAudio" */;
+ buildPhases = (
+ A276B47C13A28A8500D41A8A /* Sources */,
+ A276B47D13A28A8500D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = SDLAudio;
+ productName = SDLAudio;
+ productReference = A276B47F13A28A8500D41A8A /* SDLAudio.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B48413A28A9000D41A8A /* SDLVideo */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4BD13A28AF400D41A8A /* Build configuration list for PBXNativeTarget "SDLVideo" */;
+ buildPhases = (
+ A276B48213A28A9000D41A8A /* Sources */,
+ A276B48313A28A9000D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = SDLVideo;
+ productName = SDLVideo;
+ productReference = A276B48513A28A9000D41A8A /* SDLVideo.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B48A13A28A9E00D41A8A /* SPLImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4BE13A28AF400D41A8A /* Build configuration list for PBXNativeTarget "SPLImporter" */;
+ buildPhases = (
+ A276B48813A28A9E00D41A8A /* Sources */,
+ A276B48913A28A9E00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = SPLImporter;
+ productName = SPLImporter;
+ productReference = A276B48B13A28A9E00D41A8A /* SPLImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B49013A28AA800D41A8A /* TISImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4BF13A28AF400D41A8A /* Build configuration list for PBXNativeTarget "TISImporter" */;
+ buildPhases = (
+ A276B48E13A28AA800D41A8A /* Sources */,
+ A276B48F13A28AA800D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = TISImporter;
+ productName = TISImporter;
+ productReference = A276B49113A28AA900D41A8A /* TISImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B49613A28AB800D41A8A /* TLKImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4C013A28AF400D41A8A /* Build configuration list for PBXNativeTarget "TLKImporter" */;
+ buildPhases = (
+ A276B49413A28AB800D41A8A /* Sources */,
+ A276B49513A28AB800D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = TLKImporter;
+ productName = TLKImporter;
+ productReference = A276B49713A28AB800D41A8A /* TLKImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B49C13A28AC800D41A8A /* WAVReader */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4C113A28AF400D41A8A /* Build configuration list for PBXNativeTarget "WAVReader" */;
+ buildPhases = (
+ A276B49A13A28AC800D41A8A /* Sources */,
+ A276B49B13A28AC800D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = WAVReader;
+ productName = WAVReader;
+ productReference = A276B49D13A28AC800D41A8A /* WAVReader.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B4A213A28AD300D41A8A /* WEDImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4C213A28AF400D41A8A /* Build configuration list for PBXNativeTarget "WEDImporter" */;
+ buildPhases = (
+ A276B4A013A28AD300D41A8A /* Sources */,
+ A276B4A113A28AD300D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = WEDImporter;
+ productName = WEDImporter;
+ productReference = A276B4A313A28AD300D41A8A /* WEDImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B4A813A28AE100D41A8A /* WMPImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4C313A28AF400D41A8A /* Build configuration list for PBXNativeTarget "WMPImporter" */;
+ buildPhases = (
+ A276B4A613A28AE100D41A8A /* Sources */,
+ A276B4A713A28AE100D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = WMPImporter;
+ productName = WMPImporter;
+ productReference = A276B4A913A28AE100D41A8A /* WMPImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B4AE13A28AEE00D41A8A /* ZLibManager */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B4C413A28AF400D41A8A /* Build configuration list for PBXNativeTarget "ZLibManager" */;
+ buildPhases = (
+ A276B4AC13A28AEE00D41A8A /* Sources */,
+ A276B4AD13A28AEE00D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = ZLibManager;
+ productName = ZLibManager;
+ productReference = A276B4AF13A28AEE00D41A8A /* ZLibManager.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A276B4F313A28C0400D41A8A /* STOImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A276B52413A28C4400D41A8A /* Build configuration list for PBXNativeTarget "STOImporter" */;
+ buildPhases = (
+ A276B4F113A28C0400D41A8A /* Sources */,
+ A276B4F213A28C0400D41A8A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = STOImporter;
+ productName = STOImporter;
+ productReference = A276B4F413A28C0400D41A8A /* STOImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A27E830913A0358200B41410 /* 2DAImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A27E831213A035B800B41410 /* Build configuration list for PBXNativeTarget "2DAImporter" */;
+ buildPhases = (
+ A27E830713A0358200B41410 /* Sources */,
+ A27E830813A0358200B41410 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ A2C48CEB14A3FEF600575FE5 /* PBXTargetDependency */,
+ );
+ name = 2DAImporter;
+ productName = 2DAImporter;
+ productReference = A27E830A13A0358200B41410 /* 2DAImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A295046C1609721300BB22AA /* TTFImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A29504741609721300BB22AA /* Build configuration list for PBXNativeTarget "TTFImporter" */;
+ buildPhases = (
+ A295046F1609721300BB22AA /* Sources */,
+ A29504711609721300BB22AA /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ A295046D1609721300BB22AA /* PBXTargetDependency */,
+ );
+ name = TTFImporter;
+ productName = SAVImporter;
+ productReference = A29504771609721300BB22AA /* TTFImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A298DD0614EB4E8C00F59F56 /* SDL2Video */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A298DD0E14EB4E8C00F59F56 /* Build configuration list for PBXNativeTarget "SDL2Video" */;
+ buildPhases = (
+ A298DD0714EB4E8C00F59F56 /* Sources */,
+ A298DD0A14EB4E8C00F59F56 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = SDL2Video;
+ productName = SDLVideo;
+ productReference = A298DD1114EB4E8C00F59F56 /* SDL2Video.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A29BF7B113A0380F00C812DD /* BAMImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A29BF7B913A0381D00C812DD /* Build configuration list for PBXNativeTarget "BAMImporter" */;
+ buildPhases = (
+ A29BF7AF13A0380F00C812DD /* Sources */,
+ A29BF7B013A0380F00C812DD /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ A2C48CF114A3FF0000575FE5 /* PBXTargetDependency */,
+ );
+ name = BAMImporter;
+ productName = BAMImporter;
+ productReference = A29BF7B213A0380F00C812DD /* BAMImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A29BF85B13A0427900C812DD /* GemRB iOS */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A29BF86313A042B600C812DD /* Build configuration list for PBXNativeTarget "GemRB iOS" */;
+ buildPhases = (
+ A22DCCDD14A8F78C0067D6D1 /* ShellScript */,
+ A29BF85813A0427900C812DD /* Resources */,
+ A29BF85913A0427900C812DD /* Sources */,
+ A29BF85A13A0427900C812DD /* Frameworks */,
+ A2D4C61613A978520086BCC4 /* Run Script */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "GemRB iOS";
+ productName = "GemRB iOS";
+ productReference = A29BF85C13A0427900C812DD /* GemRB.app */;
+ productType = "com.apple.product-type.application";
+ };
+ A2BD124A15A7EDFE000FAB95 /* VLCPlayer */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A2BD125315A7EDFE000FAB95 /* Build configuration list for PBXNativeTarget "VLCPlayer" */;
+ buildPhases = (
+ A2BD124D15A7EDFE000FAB95 /* Sources */,
+ A2BD124F15A7EDFE000FAB95 /* Frameworks */,
+ A2BD125D15A8E32B000FAB95 /* ShellScript */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ A2BD124B15A7EDFE000FAB95 /* PBXTargetDependency */,
+ );
+ name = VLCPlayer;
+ productName = SAVImporter;
+ productReference = A2BD125615A7EDFE000FAB95 /* VLCPlayer.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A2E66337139E875400310FC8 /* gemrb_core */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A2E6633D139E87A400310FC8 /* Build configuration list for PBXNativeTarget "gemrb_core" */;
+ buildPhases = (
+ A2E66334139E875400310FC8 /* Headers */,
+ A2E66335139E875400310FC8 /* Sources */,
+ A2E66336139E875400310FC8 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = gemrb_core;
+ productName = libgemrb_core.dylib;
+ productReference = A2E6646F139E8DFA00310FC8 /* libgemrb_core.dylib */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A2F0505013ABB80B0023B7EB /* SAVImporter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A2F0505713ABB8320023B7EB /* Build configuration list for PBXNativeTarget "SAVImporter" */;
+ buildPhases = (
+ A2F0504E13ABB80B0023B7EB /* Sources */,
+ A2F0504F13ABB80B0023B7EB /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = SAVImporter;
+ productName = SAVImporter;
+ productReference = A2F0505113ABB80B0023B7EB /* SAVImporter.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A2FCD5FA13A0366100271997 /* ACMReader */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A2FCD60213A0366F00271997 /* Build configuration list for PBXNativeTarget "ACMReader" */;
+ buildPhases = (
+ A2FCD5F813A0366100271997 /* Sources */,
+ A2FCD5F913A0366100271997 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ A2C48CED14A3FEFA00575FE5 /* PBXTargetDependency */,
+ );
+ name = ACMReader;
+ productName = ACMReader;
+ productReference = A2FCD5FB13A0366100271997 /* ACMReader.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A2FE2C7916F2316400DDC6C7 /* NullSource */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A2FE2C7E16F2316400DDC6C7 /* Build configuration list for PBXNativeTarget "NullSource" */;
+ buildPhases = (
+ A2FE2C7A16F2316400DDC6C7 /* Sources */,
+ A2FE2C7C16F2316400DDC6C7 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = NullSource;
+ productName = DirectoryImporter;
+ productReference = A2FE2C8116F2316400DDC6C7 /* NullSource.so */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 29B97313FDCFA39411CA2CEA /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ BuildIndependentTargetsInParallel = YES;
+ LastUpgradeCheck = 0460;
+ };
+ buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "GemRB" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 1;
+ knownRegions = (
+ English,
+ Japanese,
+ French,
+ German,
+ );
+ mainGroup = 29B97314FDCFA39411CA2CEA /* GemRB_OSX */;
+ projectDirPath = "";
+ projectRoots = (
+ "",
+ ../gemrb,
+ );
+ targets = (
+ A2E66337139E875400310FC8 /* gemrb_core */,
+ 8D1107260486CEB800E47090 /* GemRB OS X */,
+ A29BF85B13A0427900C812DD /* GemRB iOS */,
+ A27E830913A0358200B41410 /* 2DAImporter */,
+ A2FCD5FA13A0366100271997 /* ACMReader */,
+ A2462F1013A036B1002D1F02 /* AREImporter */,
+ A29BF7B113A0380F00C812DD /* BAMImporter */,
+ A276B3C913A2867900D41A8A /* BIFImporter */,
+ A276B3D013A286A800D41A8A /* BIKPlayer */,
+ A276B3D613A286BC00D41A8A /* BMPImporter */,
+ A276B3DC13A286CD00D41A8A /* BMPWriter */,
+ A276B3E213A286DE00D41A8A /* CHUImporter */,
+ A276B3E813A286EC00D41A8A /* CREImporter */,
+ A276B3EE13A286FB00D41A8A /* DirectoryImporter */,
+ A276B3F413A2871300D41A8A /* DLGImporter */,
+ A276B3FA13A2872500D41A8A /* EFFImporter */,
+ A276B40013A2873700D41A8A /* FXOpcodes */,
+ A276B40613A2874700D41A8A /* GAMImporter */,
+ A276B40C13A2875400D41A8A /* GUIScript */,
+ A276B41213A2876300D41A8A /* IDSImporter */,
+ A276B41813A2877100D41A8A /* INIImporter */,
+ A276B41E13A2878400D41A8A /* ITMImporter */,
+ A276B42413A2879900D41A8A /* IWDOpcodes */,
+ A276B42A13A287AB00D41A8A /* KEYImporter */,
+ A276B43013A287BC00D41A8A /* MOSImporter */,
+ A276B44813A289E000D41A8A /* MUSImporter */,
+ A276B44E13A28A0000D41A8A /* MVEPlayer */,
+ A276B45413A28A0E00D41A8A /* NullSound */,
+ A2FE2C7916F2316400DDC6C7 /* NullSource */,
+ A276B45A13A28A1C00D41A8A /* OGGReader */,
+ A276B46013A28A3100D41A8A /* OpenALAudio */,
+ A276B46613A28A3F00D41A8A /* PLTImporter */,
+ A276B46C13A28A5000D41A8A /* PNGImporter */,
+ A276B47213A28A5D00D41A8A /* PROImporter */,
+ A276B47813A28A7600D41A8A /* PSTOpcodes */,
+ A276B47E13A28A8500D41A8A /* SDLAudio */,
+ A276B48413A28A9000D41A8A /* SDLVideo */,
+ A298DD0614EB4E8C00F59F56 /* SDL2Video */,
+ A276B48A13A28A9E00D41A8A /* SPLImporter */,
+ A276B4F313A28C0400D41A8A /* STOImporter */,
+ A276B49013A28AA800D41A8A /* TISImporter */,
+ A276B49613A28AB800D41A8A /* TLKImporter */,
+ A295046C1609721300BB22AA /* TTFImporter */,
+ A2BD124A15A7EDFE000FAB95 /* VLCPlayer */,
+ A276B49C13A28AC800D41A8A /* WAVReader */,
+ A276B4A213A28AD300D41A8A /* WEDImporter */,
+ A276B4A813A28AE100D41A8A /* WMPImporter */,
+ A276B4AE13A28AEE00D41A8A /* ZLibManager */,
+ A2F0505013ABB80B0023B7EB /* SAVImporter */,
+ A2F8708C14AE439000F9CC1F /* ReleasePackage */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 8D1107290486CEB800E47090 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */,
+ A218A75214A8F3DB001142CF /* ../artwork/gemrb.icns in Resources */,
+ A2E27EFC16F12B5A0079E104 /* GemRB.xib in Resources */,
+ A2FE2C7316F21CBF00DDC6C7 /* defaults.plist in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A29BF85813A0427900C812DD /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A238174B14B781F00058BFF4 /* GemRB.cfg.newinstall in Resources */,
+ A2A3A7E714A5130F00F705CF /* GEM_ConfController-ipad.xib in Resources */,
+ A2A3A7E814A5130F00F705CF /* GEM_ConfController-iphone.xib in Resources */,
+ A22DCCDF14A8FE0F0067D6D1 /* ios/Icon.png in Resources */,
+ A22DCCE114A8FE120067D6D1 /* ios/Icon at 2x.png in Resources */,
+ A22DCCE314A8FE870067D6D1 /* ios/Icon-72.png in Resources */,
+ A2FE2C7416F21CBF00DDC6C7 /* defaults.plist in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ A22DCCDD14A8F78C0067D6D1 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ "$(SRCROOT)/../artwork/gemrb.icns",
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "/*\nThis script makes the bundle thumbnails\n*/\nf=${SRCROOT}\nin=${SRCROOT}/../artwork/gemrb.icns\npng512=${f}/ios/iTunesArtwork\n\nsips --resampleWidth 512 \"${in}\" --out \"${png512}\"\nin=${png512}\necho $in\nsips --setProperty format png --resampleWidth 57 \"${in}\" --out \"${f}/ios/Icon.png\"\nsips --setProperty format png --resampleWidth 114 \"${in}\" --out \"${f}/ios/Icon at 2x.png\"\nsips --setProperty format png --resampleWidth 29 \"${in}\" --out \"${f}/ios/Icon- [...]
+ };
+ A249187F141079510038B170 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/bash;
+ shellScript = "#build the SDLVideo driver. we cannot have it as a target dependency because we use \"bundle loader\"\nxcodebuild -project GemRB.xcodeproj -target SDLVideo -configuration $CONFIGURATION SYMROOT=\"$SYMROOT\"\ncp \"$BUILT_PRODUCTS_DIR\"/SDLVideo.so \"$BUILT_PRODUCTS_DIR/$PLUGINS_FOLDER_PATH\"/SDLVideo.so\n\n#copy GUIScripts to bundle\ncp -r ../gemrb/GUIScripts/ \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH\"/Resources/GUIScripts\n#copy Override to bundle\ncp -r ../gemrb/ove [...]
+ };
+ A2BD125D15A8E32B000FAB95 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# if the user has VLC installed re-link to its libraries.\n# this way the user doesnt have to install libVLC to use this plugin\n\nVLC=`mdfind \"kMDItemFSName==VLC.app&&kMDItemKind==Application\"`\nlibVLC=\"$VLC/Contents/MacOS/lib/libvlc.5.dylib\"\n\nif [ -e `$VLC`] # note: use VLC path because we wont have permission to the lib path\nthen\n echo \"found libVLC:$libVLC\"\n install_name_tool -change @loader_path/lib/libvlc.5.dylib \"${libVLC}\" \"$BUILT_PRODUCTS_DI [...]
+ };
+ A2D4C61613A978520086BCC4 /* Run Script */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ ../gemrb/GUIScripts/,
+ ../gemrb/override/,
+ ios/GemRB.cfg,
+ ios/iTunesArtWork,
+ ios/iTunesMetadata.plist,
+ );
+ name = "Run Script";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "#increment the version number for the build\nREV=`git log --pretty=format:'' | wc -l | sed 's/\\ //g'`\nVERSION=`git describe --tags --dirty=-patched`\nDATE=`date -u +%Y-%m-%d\\T%T\\Z`\n\n/usr/libexec/PlistBuddy -c \"Set :CFBundleVersion $REV\" \"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}\"\n/usr/libexec/PlistBuddy -c \"Set :CFBundleShortVersionString $VERSION\" \"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}\"\n\n#updtate the iTumesMetaData\ncp ios/iTunesMetadata.plist.in ios/iTune [...]
+ };
+ A2F8709214AE448500F9CC1F /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "VERSION=`git describe --tags --dirty=-patched`\n\n# packagemaker is depricated\n# /Developer/usr/bin/packagemaker --verbose --doc osx/GemRB.pmdoc --out osx/GemRB-osx-$VERSION.pkg\n\n#make iOS ipa\n#purge payload of everything\nif [ -d `ios/Payload`];\nthen\nrm -r ios/Payload;\nfi\nmkdir ios/Payload\n\ncp -r \"$BUILT_PRODUCTS_DIR\"-iphoneos/GemRB.app ios/Payload/GemRB.app\ncd ios\nzip -r GemRB-ios-$VERSION.ipa iTunesArtWork iTunesMetadata.plist Payload\n\n# copy the opti [...]
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 8D11072C0486CEB800E47090 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2A3A7D914A505FD00F705CF /* CocoaWrapper.mm in Sources */,
+ A2C229C2150D89F300A0E3BE /* AppleLogger.mm in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A2462F0E13A036B1002D1F02 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A29BF81313A03C2600C812DD /* AREImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3C713A2867900D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4C513A28B0000D41A8A /* BIFImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3CE13A286A800D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4C613A28B0D00D41A8A /* BIKPlayer.cpp in Sources */,
+ A276B4C713A28B0D00D41A8A /* dct.cpp in Sources */,
+ A276B4C813A28B0D00D41A8A /* fft.cpp in Sources */,
+ A276B4C913A28B0D00D41A8A /* GetBitContext.cpp in Sources */,
+ A276B4CA13A28B0D00D41A8A /* mem.cpp in Sources */,
+ A276B4CB13A28B0D00D41A8A /* rational.cpp in Sources */,
+ A276B4CC13A28B0D00D41A8A /* rdft.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3D413A286BC00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4CD13A28B2000D41A8A /* BMPImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3DA13A286CD00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4CE13A28B2900D41A8A /* BMPWriter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3E013A286DE00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4CF13A28B2F00D41A8A /* CHUImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3E613A286EC00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4D013A28B3500D41A8A /* CREImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3EC13A286FB00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4D113A28B3B00D41A8A /* DirectoryImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3F213A2871300D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4D213A28B4300D41A8A /* DLGImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3F813A2872500D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4D313A28B4B00D41A8A /* EFFImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B3FE13A2873700D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4D413A28B5000D41A8A /* FXOpcodes.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B40413A2874700D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4D513A28B5600D41A8A /* GAMImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B40A13A2875400D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4D613A28B5E00D41A8A /* GUIScript.cpp in Sources */,
+ A276B4D713A28B5E00D41A8A /* PythonHelpers.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B41013A2876300D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4D813A28B6600D41A8A /* IDSImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B41613A2877100D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4D913A28B6B00D41A8A /* INIImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B41C13A2878400D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4DA13A28B7200D41A8A /* ITMImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B42213A2879900D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4DB13A28B7D00D41A8A /* IWDOpcodes.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B42813A287AB00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4DD13A28B8500D41A8A /* KEYImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B42E13A287BC00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4DE13A28B8D00D41A8A /* MOSImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B44613A289E000D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4DF13A28B9400D41A8A /* MUSImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B44C13A28A0000D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4E013A28B9F00D41A8A /* mve_player.cpp in Sources */,
+ A276B4E113A28B9F00D41A8A /* mveaudiodec.cpp in Sources */,
+ A276B4E213A28B9F00D41A8A /* MVEPlayer.cpp in Sources */,
+ A276B4E313A28B9F00D41A8A /* mvevideodec16.cpp in Sources */,
+ A276B4E413A28B9F00D41A8A /* mvevideodec8.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B45213A28A0E00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4E513A28BA500D41A8A /* NullSound.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B45813A28A1C00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4E613A28BAC00D41A8A /* OGGReader.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B45E13A28A3100D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4E713A28BB400D41A8A /* AmbientMgrAL.cpp in Sources */,
+ A276B4E813A28BB400D41A8A /* OpenALAudio.cpp in Sources */,
+ A276B4E913A28BB400D41A8A /* StackLock.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B46413A28A3F00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4EA13A28BBC00D41A8A /* PLTImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B46A13A28A5000D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4EB13A28BC500D41A8A /* PNGImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B47013A28A5D00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4EC13A28BCC00D41A8A /* PROImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B47613A28A7600D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4ED13A28BD400D41A8A /* PSTOpcodes.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B47C13A28A8500D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4EE13A28BDB00D41A8A /* SDLAudio.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B48213A28A9000D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A22693791422934E004468E8 /* CocoaWrapper.m in Sources */,
+ A276B4EF13A28BE100D41A8A /* SDLVideo.cpp in Sources */,
+ A298DD1614EB4EDE00F59F56 /* SDL12Video.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B48813A28A9E00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4F013A28BE800D41A8A /* SPLImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B48E13A28AA800D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4F813A28C2200D41A8A /* TISImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B49413A28AB800D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4F913A28C2900D41A8A /* TLKImporter.cpp in Sources */,
+ A276B4FA13A28C2900D41A8A /* TlkOverride.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B49A13A28AC800D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4FB13A28C3000D41A8A /* WAVReader.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B4A013A28AD300D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4FC13A28C3500D41A8A /* WEDImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B4A613A28AE100D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4FD13A28C3B00D41A8A /* WMPImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B4AC13A28AEE00D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4FE13A28C4100D41A8A /* ZLibManager.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A276B4F113A28C0400D41A8A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A276B4F713A28C1300D41A8A /* STOImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A27E830713A0358200B41410 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A27E831313A035C600B41410 /* 2DAImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A295046F1609721300BB22AA /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A29504701609721300BB22AA /* TTFFontManager.cpp in Sources */,
+ A2A2EA3516A5EB630092B903 /* TTFFont.cpp in Sources */,
+ A2A2EA3916A5FC860092B903 /* Freetype.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A298DD0714EB4E8C00F59F56 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A298DD0814EB4E8C00F59F56 /* CocoaWrapper.m in Sources */,
+ A298DD0914EB4E8C00F59F56 /* SDLVideo.cpp in Sources */,
+ A298DD1A14EB4EEB00F59F56 /* SDL20Video.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A29BF7AF13A0380F00C812DD /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2B0CCD61486FF780074E54B /* BAMFontManager.cpp in Sources */,
+ A29BF82B13A03DFC00C812DD /* BAMImporter.cpp in Sources */,
+ A2A2EA3016A5EB4C0092B903 /* BAMFont.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A29BF85913A0427900C812DD /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2FE2C8416F231ED00DDC6C7 /* NullSound.cpp in Sources */,
+ A2FE2C8516F231ED00DDC6C7 /* NullSource.cpp in Sources */,
+ A2E27EFA16F109090079E104 /* InterfaceConfig.cpp in Sources */,
+ A29BF8A213A04A6F00C812DD /* ActorMgr.cpp in Sources */,
+ A29BF8A313A04A6F00C812DD /* Ambient.cpp in Sources */,
+ A29BF8A413A04A6F00C812DD /* AmbientMgr.cpp in Sources */,
+ A29BF8A513A04A6F00C812DD /* Animation.cpp in Sources */,
+ A29BF8A613A04A6F00C812DD /* AnimationFactory.cpp in Sources */,
+ A29BF8A713A04A6F00C812DD /* AnimationMgr.cpp in Sources */,
+ A29BF8A813A04A6F00C812DD /* ArchiveImporter.cpp in Sources */,
+ A29BF8A913A04A6F00C812DD /* Audio.cpp in Sources */,
+ A29BF8AA13A04A6F00C812DD /* Bitmap.cpp in Sources */,
+ A29BF8AB13A04A6F00C812DD /* Cache.cpp in Sources */,
+ A29BF8AC13A04A6F00C812DD /* Calendar.cpp in Sources */,
+ A29BF8AD13A04A6F00C812DD /* Callback.cpp in Sources */,
+ A29BF8AE13A04A6F00C812DD /* CharAnimations.cpp in Sources */,
+ A29BF8AF13A04A6F00C812DD /* Compressor.cpp in Sources */,
+ A29BF8B013A04A6F00C812DD /* ControlAnimation.cpp in Sources */,
+ A29BF8B113A04A6F00C812DD /* Core.cpp in Sources */,
+ A29BF8B213A04A6F00C812DD /* DataFileMgr.cpp in Sources */,
+ A29BF8B313A04A6F00C812DD /* Dialog.cpp in Sources */,
+ A29BF8B413A04A6F00C812DD /* DialogHandler.cpp in Sources */,
+ A29BF8B513A04A6F00C812DD /* DialogMgr.cpp in Sources */,
+ A29BF8B613A04A6F00C812DD /* DisplayMessage.cpp in Sources */,
+ A29BF8B713A04A6F00C812DD /* EffectMgr.cpp in Sources */,
+ A29BF8B813A04A6F00C812DD /* EffectQueue.cpp in Sources */,
+ A29BF8B913A04A6F00C812DD /* Factory.cpp in Sources */,
+ A29BF8BA13A04A6F00C812DD /* FactoryObject.cpp in Sources */,
+ A29BF8BB13A04A6F00C812DD /* Font.cpp in Sources */,
+ A29BF8BC13A04A6F00C812DD /* Game.cpp in Sources */,
+ A29BF8BD13A04A6F00C812DD /* GameData.cpp in Sources */,
+ A29BF8BE13A04A6F00C812DD /* GlobalTimer.cpp in Sources */,
+ A29BF8BF13A04A6F00C812DD /* Image.cpp in Sources */,
+ A29BF8C013A04A6F00C812DD /* ImageFactory.cpp in Sources */,
+ A29BF8C113A04A6F00C812DD /* ImageMgr.cpp in Sources */,
+ A29BF8C213A04A6F00C812DD /* ImageWriter.cpp in Sources */,
+ A29BF8C313A04A6F00C812DD /* IniSpawn.cpp in Sources */,
+ A29BF8C413A04A6F00C812DD /* Interface.cpp in Sources */,
+ A29BF8C513A04A6F00C812DD /* Inventory.cpp in Sources */,
+ A29BF8C613A04A6F00C812DD /* Item.cpp in Sources */,
+ A29BF8C713A04A6F00C812DD /* ItemMgr.cpp in Sources */,
+ A29BF8C813A04A6F00C812DD /* LRUCache.cpp in Sources */,
+ A29BF8C913A04A6F00C812DD /* Map.cpp in Sources */,
+ A29BF8CA13A04A6F00C812DD /* MapMgr.cpp in Sources */,
+ A29BF8CB13A04A6F00C812DD /* MoviePlayer.cpp in Sources */,
+ A29BF8CC13A04A6F00C812DD /* MusicMgr.cpp in Sources */,
+ A29BF8CD13A04A6F00C812DD /* Palette.cpp in Sources */,
+ A29BF8CE13A04A6F00C812DD /* PalettedImageMgr.cpp in Sources */,
+ A29BF8CF13A04A6F00C812DD /* Particles.cpp in Sources */,
+ A29BF8D013A04A6F00C812DD /* Plugin.cpp in Sources */,
+ A29BF8D113A04A6F00C812DD /* PluginMgr.cpp in Sources */,
+ A29BF8D213A04A6F00C812DD /* Polygon.cpp in Sources */,
+ A29BF8D313A04A6F00C812DD /* Projectile.cpp in Sources */,
+ A29BF8D413A04A6F00C812DD /* ProjectileMgr.cpp in Sources */,
+ A29BF8D513A04A6F00C812DD /* ProjectileServer.cpp in Sources */,
+ A29BF8D613A04A6F00C812DD /* Region.cpp in Sources */,
+ A29BF8D713A04A6F00C812DD /* Resource.cpp in Sources */,
+ A29BF8D813A04A6F00C812DD /* ResourceDesc.cpp in Sources */,
+ A29BF8D913A04A6F00C812DD /* ResourceManager.cpp in Sources */,
+ A29BF8DA13A04A6F00C812DD /* ResourceSource.cpp in Sources */,
+ A29BF8DB13A04A6F00C812DD /* SaveGameIterator.cpp in Sources */,
+ A29BF8DC13A04A6F00C812DD /* SaveGameMgr.cpp in Sources */,
+ A29BF8DD13A04A6F00C812DD /* ScriptedAnimation.cpp in Sources */,
+ A29BF8DE13A04A6F00C812DD /* ScriptEngine.cpp in Sources */,
+ A29BF8DF13A04A6F00C812DD /* SoundMgr.cpp in Sources */,
+ A29BF8E013A04A6F00C812DD /* Spell.cpp in Sources */,
+ A29BF8E113A04A6F00C812DD /* Spellbook.cpp in Sources */,
+ A29BF8E213A04A6F00C812DD /* SpellMgr.cpp in Sources */,
+ A29BF8E313A04A6F00C812DD /* Sprite2D.cpp in Sources */,
+ A29BF8E413A04A6F00C812DD /* SpriteCover.cpp in Sources */,
+ A29BF8E513A04A6F00C812DD /* Store.cpp in Sources */,
+ A29BF8E613A04A6F00C812DD /* StoreMgr.cpp in Sources */,
+ A29BF8E713A04A6F00C812DD /* StringMgr.cpp in Sources */,
+ A29BF8E813A04A6F00C812DD /* SymbolMgr.cpp in Sources */,
+ A29BF8E913A04A6F00C812DD /* TableMgr.cpp in Sources */,
+ A29BF8EA13A04A6F00C812DD /* Tile.cpp in Sources */,
+ A29BF8EB13A04A6F00C812DD /* TileMap.cpp in Sources */,
+ A29BF8EC13A04A6F00C812DD /* TileMapMgr.cpp in Sources */,
+ A29BF8ED13A04A6F00C812DD /* TileOverlay.cpp in Sources */,
+ A29BF8EE13A04A6F00C812DD /* TileSetMgr.cpp in Sources */,
+ A29BF8EF13A04A6F00C812DD /* Variables.cpp in Sources */,
+ A29BF8F013A04A6F00C812DD /* Video.cpp in Sources */,
+ A29BF8F113A04A6F00C812DD /* WindowMgr.cpp in Sources */,
+ A29BF8F213A04A6F00C812DD /* WorldMap.cpp in Sources */,
+ A29BF8F313A04A6F00C812DD /* WorldMapMgr.cpp in Sources */,
+ A29BF8F513A04A6F00C812DD /* DataStream.cpp in Sources */,
+ A29BF8F613A04A6F00C812DD /* FileStream.cpp in Sources */,
+ A29BF8F713A04A6F00C812DD /* MemoryStream.cpp in Sources */,
+ A29BF8F913A04A6F00C812DD /* swab.c in Sources */,
+ A29BF8FA13A04A6F00C812DD /* VFS.cpp in Sources */,
+ A29BF8FB13A04A6F00C812DD /* Actor.cpp in Sources */,
+ A29BF8FC13A04A6F00C812DD /* Container.cpp in Sources */,
+ A29BF8FD13A04A6F00C812DD /* Door.cpp in Sources */,
+ A29BF8FE13A04A6F00C812DD /* InfoPoint.cpp in Sources */,
+ A29BF8FF13A04A6F00C812DD /* PCStatStruct.cpp in Sources */,
+ A29BF90013A04A6F00C812DD /* Scriptable.cpp in Sources */,
+ A29BF90113A04A6F00C812DD /* Button.cpp in Sources */,
+ A29BF90213A04A6F00C812DD /* Console.cpp in Sources */,
+ A29BF90313A04A6F00C812DD /* Control.cpp in Sources */,
+ A29BF90413A04A6F00C812DD /* EventMgr.cpp in Sources */,
+ A29BF90513A04A6F00C812DD /* GameControl.cpp in Sources */,
+ A29BF90613A04A6F00C812DD /* Label.cpp in Sources */,
+ A29BF90713A04A6F00C812DD /* MapControl.cpp in Sources */,
+ A29BF90813A04A6F00C812DD /* Progressbar.cpp in Sources */,
+ A29BF90913A04A6F00C812DD /* ScrollBar.cpp in Sources */,
+ A29BF90A13A04A6F00C812DD /* Slider.cpp in Sources */,
+ A29BF90B13A04A6F00C812DD /* TextArea.cpp in Sources */,
+ A29BF90C13A04A6F00C812DD /* TextEdit.cpp in Sources */,
+ A29BF90D13A04A6F00C812DD /* Window.cpp in Sources */,
+ A29BF90E13A04A6F00C812DD /* WorldMapControl.cpp in Sources */,
+ A29BF90F13A04A6F00C812DD /* Actions.cpp in Sources */,
+ A29BF91013A04A6F00C812DD /* GameScript.cpp in Sources */,
+ A29BF91113A04A6F00C812DD /* GSUtils.cpp in Sources */,
+ A29BF91213A04A6F00C812DD /* Matching.cpp in Sources */,
+ A29BF91313A04A6F00C812DD /* Objects.cpp in Sources */,
+ A29BF91413A04A6F00C812DD /* Triggers.cpp in Sources */,
+ A226F41013A119D8009CE75E /* 2DAImporter.cpp in Sources */,
+ A226F41113A119E2009CE75E /* ACMReader.cpp in Sources */,
+ A226F41213A119E2009CE75E /* decoder.cpp in Sources */,
+ A226F41313A119E2009CE75E /* unpacker.cpp in Sources */,
+ A226F41713A119EA009CE75E /* AREImporter.cpp in Sources */,
+ A226F41813A119F1009CE75E /* BAMImporter.cpp in Sources */,
+ A226F41913A119F6009CE75E /* BIFImporter.cpp in Sources */,
+ A226F41A13A11A00009CE75E /* BIKPlayer.cpp in Sources */,
+ A226F41B13A11A00009CE75E /* dct.cpp in Sources */,
+ A226F41C13A11A00009CE75E /* fft.cpp in Sources */,
+ A226F41D13A11A00009CE75E /* GetBitContext.cpp in Sources */,
+ A226F41E13A11A00009CE75E /* mem.cpp in Sources */,
+ A226F41F13A11A00009CE75E /* rational.cpp in Sources */,
+ A226F42013A11A00009CE75E /* rdft.cpp in Sources */,
+ A226F42113A11A07009CE75E /* BMPImporter.cpp in Sources */,
+ A226F42213A11A0C009CE75E /* BMPWriter.cpp in Sources */,
+ A226F42313A11A11009CE75E /* CHUImporter.cpp in Sources */,
+ A226F42413A11A17009CE75E /* CREImporter.cpp in Sources */,
+ A226F42513A11A1C009CE75E /* DirectoryImporter.cpp in Sources */,
+ A226F42613A11A22009CE75E /* DLGImporter.cpp in Sources */,
+ A226F42713A11A27009CE75E /* EFFImporter.cpp in Sources */,
+ A226F42813A11A2C009CE75E /* FXOpcodes.cpp in Sources */,
+ A226F42913A11A31009CE75E /* GAMImporter.cpp in Sources */,
+ A226F42A13A11A39009CE75E /* GUIScript.cpp in Sources */,
+ A226F42B13A11A39009CE75E /* PythonHelpers.cpp in Sources */,
+ A226F42C13A11A3F009CE75E /* IDSImporter.cpp in Sources */,
+ A226F42D13A11A44009CE75E /* INIImporter.cpp in Sources */,
+ A226F42E13A11A49009CE75E /* ITMImporter.cpp in Sources */,
+ A226F42F13A11A4E009CE75E /* IWDOpcodes.cpp in Sources */,
+ A226F43113A11A53009CE75E /* KEYImporter.cpp in Sources */,
+ A226F43213A11A58009CE75E /* MOSImporter.cpp in Sources */,
+ A226F43313A11A5E009CE75E /* MUSImporter.cpp in Sources */,
+ A226F43413A11A66009CE75E /* mve_player.cpp in Sources */,
+ A226F43513A11A66009CE75E /* mveaudiodec.cpp in Sources */,
+ A226F43613A11A66009CE75E /* MVEPlayer.cpp in Sources */,
+ A226F43713A11A66009CE75E /* mvevideodec16.cpp in Sources */,
+ A226F43813A11A66009CE75E /* mvevideodec8.cpp in Sources */,
+ A226F43E13A11A7E009CE75E /* PLTImporter.cpp in Sources */,
+ A226F44013A11A8D009CE75E /* PROImporter.cpp in Sources */,
+ A226F44113A11A94009CE75E /* PSTOpcodes.cpp in Sources */,
+ A226F44413A11AA3009CE75E /* SPLImporter.cpp in Sources */,
+ A226F44513A11AA8009CE75E /* STOImporter.cpp in Sources */,
+ A226F44613A11AAC009CE75E /* TISImporter.cpp in Sources */,
+ A226F44713A11AB4009CE75E /* TLKImporter.cpp in Sources */,
+ A226F44813A11AB4009CE75E /* TlkOverride.cpp in Sources */,
+ A226F44913A11AB9009CE75E /* WAVReader.cpp in Sources */,
+ A226F44A13A11ABE009CE75E /* WEDImporter.cpp in Sources */,
+ A226F44B13A11AC3009CE75E /* WMPImporter.cpp in Sources */,
+ A226F44C13A11AC8009CE75E /* ZLibManager.cpp in Sources */,
+ A2AAF33A13A14A4500AE8402 /* SDLVideo.cpp in Sources */,
+ A265ECDC13A8661600C6DF12 /* FileCache.cpp in Sources */,
+ A265ECDD13A8661600C6DF12 /* IndexedArchive.cpp in Sources */,
+ A265ECDE13A8661600C6DF12 /* KeyMap.cpp in Sources */,
+ A265ECDF13A8661600C6DF12 /* PluginLoader.cpp in Sources */,
+ A265ECED13A8669700C6DF12 /* Logging.cpp in Sources */,
+ A265ECEE13A8669700C6DF12 /* SlicedStream.cpp in Sources */,
+ A265ECEF13A8669700C6DF12 /* String.cpp in Sources */,
+ A27979AF13ABA509009A6FEF /* SAVImporter.cpp in Sources */,
+ A20C698013B0FA430082EEBA /* AmbientMgrAL.cpp in Sources */,
+ A20C698113B0FA430082EEBA /* OpenALAudio.cpp in Sources */,
+ A20C698213B0FA430082EEBA /* StackLock.cpp in Sources */,
+ A28D249A143BEA4200A27897 /* FontManager.cpp in Sources */,
+ A2A6A45C146893CC000F1688 /* TTFFontManager.cpp in Sources */,
+ A2A3A7E514A5130F00F705CF /* CocoaMain.m in Sources */,
+ A2A3A7E614A5130F00F705CF /* GEM_ConfController.m in Sources */,
+ A2A3A7EF14A51B1800F705CF /* GEM_SDL_Keyboard.m in Sources */,
+ A288622314A550BF009AC280 /* BAMFontManager.cpp in Sources */,
+ A2E1583114D1D8DA0044F3C5 /* GEM_AppDelegate.mm in Sources */,
+ A2DE32AD14EB0C6900117503 /* Logger.cpp in Sources */,
+ A298DD1914EB4EEB00F59F56 /* SDL20Video.cpp in Sources */,
+ A298DD2314EB61D300F59F56 /* Stdio.cpp in Sources */,
+ A2C76D2B14F196E900961680 /* StringBuffer.cpp in Sources */,
+ A22EBDCE14FF18030029C9C1 /* AppleLogger.mm in Sources */,
+ A2CB5AC415000A0D00B5C154 /* File.cpp in Sources */,
+ A2DB6D5A15D9EE8C00D70E88 /* MessageWindowLogger.cpp in Sources */,
+ A2969F10168CDC0D00D9C6FC /* CombatInfo.cpp in Sources */,
+ A2A2EA2F16A5EB4C0092B903 /* BAMFont.cpp in Sources */,
+ A2A2EA3416A5EB630092B903 /* TTFFont.cpp in Sources */,
+ A2A2EA3816A5FC860092B903 /* Freetype.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A2BD124D15A7EDFE000FAB95 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2BD125A15A7EE61000FAB95 /* VLCPlayer.cpp in Sources */,
+ A2A26ADD15AA729800A8E25D /* VideoContext.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A2E66335139E875400310FC8 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2B0CCD51486FF710074E54B /* FontManager.cpp in Sources */,
+ A23EBFFA141979D500CC049E /* KeyMap.cpp in Sources */,
+ A208210D1419712F002CD244 /* String.cpp in Sources */,
+ A208210E1419712F002CD244 /* IndexedArchive.cpp in Sources */,
+ A20821101419712F002CD244 /* PluginLoader.cpp in Sources */,
+ A20821111419712F002CD244 /* MemoryStream.cpp in Sources */,
+ A2E6634E139E882900310FC8 /* ActorMgr.cpp in Sources */,
+ A2E66350139E882900310FC8 /* Ambient.cpp in Sources */,
+ A2E66352139E882900310FC8 /* AmbientMgr.cpp in Sources */,
+ A2E66354139E882900310FC8 /* Animation.cpp in Sources */,
+ A2E66356139E882900310FC8 /* AnimationFactory.cpp in Sources */,
+ A2E66358139E883100310FC8 /* AnimationMgr.cpp in Sources */,
+ A2E6635B139E883100310FC8 /* ArchiveImporter.cpp in Sources */,
+ A2E6635D139E883100310FC8 /* Audio.cpp in Sources */,
+ A2E6635F139E883100310FC8 /* Bitmap.cpp in Sources */,
+ A2E66361139E883100310FC8 /* Cache.cpp in Sources */,
+ A2E66363139E883100310FC8 /* Calendar.cpp in Sources */,
+ A2E66365139E883100310FC8 /* Callback.cpp in Sources */,
+ A2E66367139E883100310FC8 /* CharAnimations.cpp in Sources */,
+ A2E66369139E883100310FC8 /* Compressor.cpp in Sources */,
+ A2E6636B139E883100310FC8 /* ControlAnimation.cpp in Sources */,
+ A2E6636D139E883100310FC8 /* Core.cpp in Sources */,
+ A2E6636F139E883100310FC8 /* DataFileMgr.cpp in Sources */,
+ A2E66371139E883100310FC8 /* Dialog.cpp in Sources */,
+ A2E66373139E883100310FC8 /* DialogHandler.cpp in Sources */,
+ A2E66375139E883100310FC8 /* DialogMgr.cpp in Sources */,
+ A2E66377139E883100310FC8 /* DisplayMessage.cpp in Sources */,
+ A2E6637A139E883100310FC8 /* EffectMgr.cpp in Sources */,
+ A2E6637C139E883100310FC8 /* EffectQueue.cpp in Sources */,
+ A2E6637E139E883100310FC8 /* Factory.cpp in Sources */,
+ A2E66380139E883100310FC8 /* FactoryObject.cpp in Sources */,
+ A2E66382139E883100310FC8 /* Font.cpp in Sources */,
+ A2E66384139E883100310FC8 /* Game.cpp in Sources */,
+ A2E66386139E883100310FC8 /* GameData.cpp in Sources */,
+ A2E66388139E883700310FC8 /* GlobalTimer.cpp in Sources */,
+ A2E6638B139E883E00310FC8 /* Image.cpp in Sources */,
+ A2E6638D139E883E00310FC8 /* ImageFactory.cpp in Sources */,
+ A2E6638F139E883E00310FC8 /* ImageMgr.cpp in Sources */,
+ A2E66391139E883E00310FC8 /* ImageWriter.cpp in Sources */,
+ A2E66393139E883E00310FC8 /* IniSpawn.cpp in Sources */,
+ A2E66395139E883E00310FC8 /* Interface.cpp in Sources */,
+ A2E66397139E883E00310FC8 /* Inventory.cpp in Sources */,
+ A2E66399139E883E00310FC8 /* Item.cpp in Sources */,
+ A2E6639B139E883E00310FC8 /* ItemMgr.cpp in Sources */,
+ A2E6639D139E883E00310FC8 /* LRUCache.cpp in Sources */,
+ A2E6639F139E883E00310FC8 /* Map.cpp in Sources */,
+ A2E663A1139E883E00310FC8 /* MapMgr.cpp in Sources */,
+ A2E663A3139E883E00310FC8 /* MoviePlayer.cpp in Sources */,
+ A2E663A5139E883E00310FC8 /* MusicMgr.cpp in Sources */,
+ A2E663A7139E883E00310FC8 /* Palette.cpp in Sources */,
+ A2E663A9139E883E00310FC8 /* PalettedImageMgr.cpp in Sources */,
+ A2E663AB139E883E00310FC8 /* Particles.cpp in Sources */,
+ A2E663AE139E883E00310FC8 /* Plugin.cpp in Sources */,
+ A2E663B0139E883E00310FC8 /* PluginMgr.cpp in Sources */,
+ A2E663B2139E883E00310FC8 /* Polygon.cpp in Sources */,
+ A2E663B5139E883E00310FC8 /* Projectile.cpp in Sources */,
+ A2E663B7139E883E00310FC8 /* ProjectileMgr.cpp in Sources */,
+ A2E663B9139E883E00310FC8 /* ProjectileServer.cpp in Sources */,
+ A2E663BB139E883E00310FC8 /* Region.cpp in Sources */,
+ A2E663BD139E883E00310FC8 /* Resource.cpp in Sources */,
+ A2E663BF139E883E00310FC8 /* ResourceDesc.cpp in Sources */,
+ A2E663C1139E883E00310FC8 /* ResourceManager.cpp in Sources */,
+ A2E663C3139E883E00310FC8 /* ResourceSource.cpp in Sources */,
+ A2E663C6139E883E00310FC8 /* SaveGameIterator.cpp in Sources */,
+ A2E663C8139E883E00310FC8 /* SaveGameMgr.cpp in Sources */,
+ A2E663CA139E884500310FC8 /* ScriptedAnimation.cpp in Sources */,
+ A2E663CC139E884500310FC8 /* ScriptEngine.cpp in Sources */,
+ A2E663CE139E884500310FC8 /* SoundMgr.cpp in Sources */,
+ A2E663D0139E884500310FC8 /* Spell.cpp in Sources */,
+ A2E663D2139E884500310FC8 /* Spellbook.cpp in Sources */,
+ A2E663D4139E884500310FC8 /* SpellMgr.cpp in Sources */,
+ A2E663D6139E884500310FC8 /* Sprite2D.cpp in Sources */,
+ A2E663D8139E884500310FC8 /* SpriteCover.cpp in Sources */,
+ A2E663DA139E884500310FC8 /* Store.cpp in Sources */,
+ A2E663DC139E884500310FC8 /* StoreMgr.cpp in Sources */,
+ A2E663DE139E884500310FC8 /* StringMgr.cpp in Sources */,
+ A2E663E0139E884500310FC8 /* SymbolMgr.cpp in Sources */,
+ A2E663E2139E884B00310FC8 /* TableMgr.cpp in Sources */,
+ A2E663E4139E884B00310FC8 /* Tile.cpp in Sources */,
+ A2E663E6139E884B00310FC8 /* TileMap.cpp in Sources */,
+ A2E663E8139E884B00310FC8 /* TileMapMgr.cpp in Sources */,
+ A2E663EA139E884B00310FC8 /* TileOverlay.cpp in Sources */,
+ A2E663EC139E884B00310FC8 /* TileSetMgr.cpp in Sources */,
+ A2E663EF139E884B00310FC8 /* Variables.cpp in Sources */,
+ A2E663F1139E884B00310FC8 /* Video.cpp in Sources */,
+ A2E663F4139E884B00310FC8 /* WindowMgr.cpp in Sources */,
+ A2E663F6139E884B00310FC8 /* WorldMap.cpp in Sources */,
+ A2E663F8139E884B00310FC8 /* WorldMapMgr.cpp in Sources */,
+ A2E663FC139E885300310FC8 /* DataStream.cpp in Sources */,
+ A2E663FE139E885300310FC8 /* FileStream.cpp in Sources */,
+ A2E66404139E885300310FC8 /* swab.c in Sources */,
+ A2E66406139E885300310FC8 /* VFS.cpp in Sources */,
+ A2E66408139E885A00310FC8 /* Actor.cpp in Sources */,
+ A2E6640A139E885A00310FC8 /* Container.cpp in Sources */,
+ A2E6640C139E885A00310FC8 /* Door.cpp in Sources */,
+ A2E6640E139E885A00310FC8 /* InfoPoint.cpp in Sources */,
+ A2E66410139E885A00310FC8 /* PCStatStruct.cpp in Sources */,
+ A2E66412139E885A00310FC8 /* Scriptable.cpp in Sources */,
+ A2E66414139E886100310FC8 /* Button.cpp in Sources */,
+ A2E66416139E886100310FC8 /* Console.cpp in Sources */,
+ A2E66419139E886100310FC8 /* Control.cpp in Sources */,
+ A2E6641B139E886100310FC8 /* EventMgr.cpp in Sources */,
+ A2E6641D139E886100310FC8 /* GameControl.cpp in Sources */,
+ A2E6641F139E886100310FC8 /* Label.cpp in Sources */,
+ A2E66421139E886100310FC8 /* MapControl.cpp in Sources */,
+ A2E66423139E886100310FC8 /* Progressbar.cpp in Sources */,
+ A2E66425139E886100310FC8 /* ScrollBar.cpp in Sources */,
+ A2E66427139E886100310FC8 /* Slider.cpp in Sources */,
+ A2E66429139E886100310FC8 /* TextArea.cpp in Sources */,
+ A2E6642B139E886100310FC8 /* TextEdit.cpp in Sources */,
+ A2E6642D139E886100310FC8 /* Window.cpp in Sources */,
+ A2E6642F139E886100310FC8 /* WorldMapControl.cpp in Sources */,
+ A2E66431139E886700310FC8 /* Actions.cpp in Sources */,
+ A2E66432139E886700310FC8 /* GameScript.cpp in Sources */,
+ A2E66434139E886700310FC8 /* GSUtils.cpp in Sources */,
+ A2E66436139E886700310FC8 /* Matching.cpp in Sources */,
+ A2E66438139E886700310FC8 /* Objects.cpp in Sources */,
+ A2E66439139E886700310FC8 /* Triggers.cpp in Sources */,
+ A265ECE013A8661600C6DF12 /* FileCache.cpp in Sources */,
+ A265ECF013A8669700C6DF12 /* Logging.cpp in Sources */,
+ A265ECF113A8669700C6DF12 /* SlicedStream.cpp in Sources */,
+ A2DE329914EB071200117503 /* Logger.cpp in Sources */,
+ A298DD2214EB61D300F59F56 /* Stdio.cpp in Sources */,
+ A2C76D2A14F196E900961680 /* StringBuffer.cpp in Sources */,
+ A2CB5AC315000A0D00B5C154 /* File.cpp in Sources */,
+ A230584915D5BBCC00BDF69C /* MessageWindowLogger.cpp in Sources */,
+ A2969F0F168CDC0D00D9C6FC /* CombatInfo.cpp in Sources */,
+ A2E27EF716EEA7B00079E104 /* InterfaceConfig.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A2F0504E13ABB80B0023B7EB /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A2F0505613ABB82D0023B7EB /* SAVImporter.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A2FCD5F813A0366100271997 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A226F41413A119E5009CE75E /* ACMReader.cpp in Sources */,
+ A226F41513A119E5009CE75E /* decoder.cpp in Sources */,
+ A226F41613A119E5009CE75E /* unpacker.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A2FE2C7A16F2316400DDC6C7 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A27ABCD016F2396C00FE11EF /* NullSource.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ A2375BA113AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A27E830913A0358200B41410 /* 2DAImporter */;
+ targetProxy = A2375BA013AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BA313AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A2FCD5FA13A0366100271997 /* ACMReader */;
+ targetProxy = A2375BA213AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BA513AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A2462F1013A036B1002D1F02 /* AREImporter */;
+ targetProxy = A2375BA413AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BA713AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A29BF7B113A0380F00C812DD /* BAMImporter */;
+ targetProxy = A2375BA613AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BA913AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B3C913A2867900D41A8A /* BIFImporter */;
+ targetProxy = A2375BA813AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BAB13AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B3D013A286A800D41A8A /* BIKPlayer */;
+ targetProxy = A2375BAA13AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BAD13AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B3D613A286BC00D41A8A /* BMPImporter */;
+ targetProxy = A2375BAC13AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BAF13AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B3DC13A286CD00D41A8A /* BMPWriter */;
+ targetProxy = A2375BAE13AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BB113AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B3E213A286DE00D41A8A /* CHUImporter */;
+ targetProxy = A2375BB013AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BB313AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B3E813A286EC00D41A8A /* CREImporter */;
+ targetProxy = A2375BB213AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BB513AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B3EE13A286FB00D41A8A /* DirectoryImporter */;
+ targetProxy = A2375BB413AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BB713AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B3F413A2871300D41A8A /* DLGImporter */;
+ targetProxy = A2375BB613AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BB913AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B3FA13A2872500D41A8A /* EFFImporter */;
+ targetProxy = A2375BB813AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BBB13AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B40013A2873700D41A8A /* FXOpcodes */;
+ targetProxy = A2375BBA13AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BBD13AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B40613A2874700D41A8A /* GAMImporter */;
+ targetProxy = A2375BBC13AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BBF13AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B40C13A2875400D41A8A /* GUIScript */;
+ targetProxy = A2375BBE13AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BC113AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B41213A2876300D41A8A /* IDSImporter */;
+ targetProxy = A2375BC013AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BC313AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B41813A2877100D41A8A /* INIImporter */;
+ targetProxy = A2375BC213AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BC513AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B41E13A2878400D41A8A /* ITMImporter */;
+ targetProxy = A2375BC413AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BC713AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B42413A2879900D41A8A /* IWDOpcodes */;
+ targetProxy = A2375BC613AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BC913AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B42A13A287AB00D41A8A /* KEYImporter */;
+ targetProxy = A2375BC813AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BCB13AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B43013A287BC00D41A8A /* MOSImporter */;
+ targetProxy = A2375BCA13AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BCD13AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B44813A289E000D41A8A /* MUSImporter */;
+ targetProxy = A2375BCC13AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BCF13AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B44E13A28A0000D41A8A /* MVEPlayer */;
+ targetProxy = A2375BCE13AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BD313AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B46013A28A3100D41A8A /* OpenALAudio */;
+ targetProxy = A2375BD213AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BD513AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B46613A28A3F00D41A8A /* PLTImporter */;
+ targetProxy = A2375BD413AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BD713AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B47213A28A5D00D41A8A /* PROImporter */;
+ targetProxy = A2375BD613AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BD913AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B47813A28A7600D41A8A /* PSTOpcodes */;
+ targetProxy = A2375BD813AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BDD13AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B48A13A28A9E00D41A8A /* SPLImporter */;
+ targetProxy = A2375BDC13AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BDF13AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B4F313A28C0400D41A8A /* STOImporter */;
+ targetProxy = A2375BDE13AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BE113AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B49013A28AA800D41A8A /* TISImporter */;
+ targetProxy = A2375BE013AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BE313AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B49613A28AB800D41A8A /* TLKImporter */;
+ targetProxy = A2375BE213AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BE513AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B49C13A28AC800D41A8A /* WAVReader */;
+ targetProxy = A2375BE413AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BE713AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B4A213A28AD300D41A8A /* WEDImporter */;
+ targetProxy = A2375BE613AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BE913AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B4A813A28AE100D41A8A /* WMPImporter */;
+ targetProxy = A2375BE813AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A2375BEB13AAF58E00E7EF9B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B4AE13A28AEE00D41A8A /* ZLibManager */;
+ targetProxy = A2375BEA13AAF58E00E7EF9B /* PBXContainerItemProxy */;
+ };
+ A23EBFFC1419A81500CC049E /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A2F0505013ABB80B0023B7EB /* SAVImporter */;
+ targetProxy = A23EBFFB1419A81500CC049E /* PBXContainerItemProxy */;
+ };
+ A295046D1609721300BB22AA /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A2E66337139E875400310FC8 /* gemrb_core */;
+ targetProxy = A295046E1609721300BB22AA /* PBXContainerItemProxy */;
+ };
+ A295047A1609725F00BB22AA /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A295046C1609721300BB22AA /* TTFImporter */;
+ targetProxy = A29504791609725F00BB22AA /* PBXContainerItemProxy */;
+ };
+ A295048716097E3700BB22AA /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B45A13A28A1C00D41A8A /* OGGReader */;
+ targetProxy = A295048616097E3700BB22AA /* PBXContainerItemProxy */;
+ };
+ A295049116097F9D00BB22AA /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B46C13A28A5000D41A8A /* PNGImporter */;
+ targetProxy = A295049016097F9D00BB22AA /* PBXContainerItemProxy */;
+ };
+ A29F3EE415A8E6DE00C85084 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A2BD124A15A7EDFE000FAB95 /* VLCPlayer */;
+ targetProxy = A29F3EE315A8E6DE00C85084 /* PBXContainerItemProxy */;
+ };
+ A2AF8FCD14DDCEBD005CAC5D /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A276B45413A28A0E00D41A8A /* NullSound */;
+ targetProxy = A2AF8FCC14DDCEBD005CAC5D /* PBXContainerItemProxy */;
+ };
+ A2BD124B15A7EDFE000FAB95 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A2E66337139E875400310FC8 /* gemrb_core */;
+ targetProxy = A2BD124C15A7EDFE000FAB95 /* PBXContainerItemProxy */;
+ };
+ A2C48CEB14A3FEF600575FE5 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A2E66337139E875400310FC8 /* gemrb_core */;
+ targetProxy = A2C48CEA14A3FEF600575FE5 /* PBXContainerItemProxy */;
+ };
+ A2C48CED14A3FEFA00575FE5 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A2E66337139E875400310FC8 /* gemrb_core */;
+ targetProxy = A2C48CEC14A3FEFA00575FE5 /* PBXContainerItemProxy */;
+ };
+ A2C48CEF14A3FEFD00575FE5 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A2E66337139E875400310FC8 /* gemrb_core */;
+ targetProxy = A2C48CEE14A3FEFD00575FE5 /* PBXContainerItemProxy */;
+ };
+ A2C48CF114A3FF0000575FE5 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A2E66337139E875400310FC8 /* gemrb_core */;
+ targetProxy = A2C48CF014A3FF0000575FE5 /* PBXContainerItemProxy */;
+ };
+ A2C48CF314A3FF0300575FE5 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A2E66337139E875400310FC8 /* gemrb_core */;
+ targetProxy = A2C48CF214A3FF0300575FE5 /* PBXContainerItemProxy */;
+ };
+ A2C48CF514A3FF0600575FE5 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A2E66337139E875400310FC8 /* gemrb_core */;
+ targetProxy = A2C48CF414A3FF0600575FE5 /* PBXContainerItemProxy */;
+ };
+ A2C48CF714A3FF0900575FE5 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A2E66337139E875400310FC8 /* gemrb_core */;
+ targetProxy = A2C48CF614A3FF0900575FE5 /* PBXContainerItemProxy */;
+ };
+ A2C48CF914A3FF0D00575FE5 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A2E66337139E875400310FC8 /* gemrb_core */;
+ targetProxy = A2C48CF814A3FF0D00575FE5 /* PBXContainerItemProxy */;
+ };
+ A2E6633C139E876900310FC8 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A2E66337139E875400310FC8 /* gemrb_core */;
+ targetProxy = A2E6633B139E876900310FC8 /* PBXContainerItemProxy */;
+ };
+ A2E9967E14DE12970052BABE /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A2E66337139E875400310FC8 /* gemrb_core */;
+ targetProxy = A2E9967D14DE12970052BABE /* PBXContainerItemProxy */;
+ };
+ A2E9968014DE12A90052BABE /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A2E66337139E875400310FC8 /* gemrb_core */;
+ targetProxy = A2E9967F14DE12A90052BABE /* PBXContainerItemProxy */;
+ };
+ A2F8709114AE43BB00F9CC1F /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 8D1107260486CEB800E47090 /* GemRB OS X */;
+ targetProxy = A2F8709014AE43BB00F9CC1F /* PBXContainerItemProxy */;
+ };
+ A2F8709414AE4A8F00F9CC1F /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A29BF85B13A0427900C812DD /* GemRB iOS */;
+ targetProxy = A2F8709314AE4A8F00F9CC1F /* PBXContainerItemProxy */;
+ };
+ A2FE2C8316F231CB00DDC6C7 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A2FE2C7916F2316400DDC6C7 /* NullSource */;
+ targetProxy = A2FE2C8216F231CB00DDC6C7 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 089C165DFE840E0CC02AAC07 /* English */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ A2462F1213A036B2002D1F02 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = AREImporter;
+ };
+ name = Debug;
+ };
+ A2462F1313A036B2002D1F02 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = AREImporter;
+ };
+ name = Release;
+ };
+ A276B3CB13A2867900D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = BIFImporter;
+ };
+ name = Debug;
+ };
+ A276B3CC13A2867900D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = BIFImporter;
+ };
+ name = Release;
+ };
+ A276B3D213A286A800D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = BIKPlayer;
+ };
+ name = Debug;
+ };
+ A276B3D313A286A800D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = BIKPlayer;
+ };
+ name = Release;
+ };
+ A276B3D813A286BD00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = BMPImporter;
+ };
+ name = Debug;
+ };
+ A276B3D913A286BD00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = BMPImporter;
+ };
+ name = Release;
+ };
+ A276B3DE13A286CD00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = BMPWriter;
+ };
+ name = Debug;
+ };
+ A276B3DF13A286CD00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = BMPWriter;
+ };
+ name = Release;
+ };
+ A276B3E413A286DE00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = CHUImporter;
+ };
+ name = Debug;
+ };
+ A276B3E513A286DE00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = CHUImporter;
+ };
+ name = Release;
+ };
+ A276B3EA13A286ED00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = CREImporter;
+ };
+ name = Debug;
+ };
+ A276B3EB13A286ED00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = CREImporter;
+ };
+ name = Release;
+ };
+ A276B3F013A286FB00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = DirectoryImporter;
+ };
+ name = Debug;
+ };
+ A276B3F113A286FB00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = DirectoryImporter;
+ };
+ name = Release;
+ };
+ A276B3F613A2871400D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = DLGImporter;
+ };
+ name = Debug;
+ };
+ A276B3F713A2871400D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = DLGImporter;
+ };
+ name = Release;
+ };
+ A276B3FC13A2872600D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = EFFImporter;
+ };
+ name = Debug;
+ };
+ A276B3FD13A2872600D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = EFFImporter;
+ };
+ name = Release;
+ };
+ A276B40213A2873700D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = FXOpcodes;
+ };
+ name = Debug;
+ };
+ A276B40313A2873700D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = FXOpcodes;
+ };
+ name = Release;
+ };
+ A276B40813A2874800D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = GAMImporter;
+ };
+ name = Debug;
+ };
+ A276B40913A2874800D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = GAMImporter;
+ };
+ name = Release;
+ };
+ A276B40E13A2875500D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ HEADER_SEARCH_PATHS = (
+ /System/Library/Frameworks/Python.framework/Headers,
+ "$(HEADER_SEARCH_PATHS)",
+ );
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = GUIScript;
+ };
+ name = Debug;
+ };
+ A276B40F13A2875500D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ HEADER_SEARCH_PATHS = (
+ /System/Library/Frameworks/Python.framework/Headers,
+ "$(HEADER_SEARCH_PATHS)",
+ );
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = GUIScript;
+ };
+ name = Release;
+ };
+ A276B41413A2876400D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = IDSImporter;
+ };
+ name = Debug;
+ };
+ A276B41513A2876400D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = IDSImporter;
+ };
+ name = Release;
+ };
+ A276B41A13A2877100D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = INIImporter;
+ };
+ name = Debug;
+ };
+ A276B41B13A2877100D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = INIImporter;
+ };
+ name = Release;
+ };
+ A276B42013A2878400D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = ITMImporter;
+ };
+ name = Debug;
+ };
+ A276B42113A2878400D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = ITMImporter;
+ };
+ name = Release;
+ };
+ A276B42613A2879A00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = IWDOpcodes;
+ };
+ name = Debug;
+ };
+ A276B42713A2879A00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = IWDOpcodes;
+ };
+ name = Release;
+ };
+ A276B42C13A287AB00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = KEYImporter;
+ };
+ name = Debug;
+ };
+ A276B42D13A287AB00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = KEYImporter;
+ };
+ name = Release;
+ };
+ A276B43213A287BD00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = MOSImporter;
+ };
+ name = Debug;
+ };
+ A276B43313A287BD00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = MOSImporter;
+ };
+ name = Release;
+ };
+ A276B44A13A289E100D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = MUSImporter;
+ };
+ name = Debug;
+ };
+ A276B44B13A289E100D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = MUSImporter;
+ };
+ name = Release;
+ };
+ A276B45013A28A0100D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = MVEPlayer;
+ };
+ name = Debug;
+ };
+ A276B45113A28A0100D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = MVEPlayer;
+ };
+ name = Release;
+ };
+ A276B45613A28A0F00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = NullSound;
+ };
+ name = Debug;
+ };
+ A276B45713A28A0F00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = NullSound;
+ };
+ name = Release;
+ };
+ A276B45C13A28A1C00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = OGGReader;
+ };
+ name = Debug;
+ };
+ A276B45D13A28A1C00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = OGGReader;
+ };
+ name = Release;
+ };
+ A276B46213A28A3100D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ "GCC_VERSION[arch=x86_64]" = "";
+ HEADER_SEARCH_PATHS = /Library/Frameworks/SDL.framework/Headers;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = OpenALAudio;
+ };
+ name = Debug;
+ };
+ A276B46313A28A3100D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ "GCC_VERSION[arch=x86_64]" = "";
+ HEADER_SEARCH_PATHS = /Library/Frameworks/SDL.framework/Headers;
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = OpenALAudio;
+ };
+ name = Release;
+ };
+ A276B46813A28A3F00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = PLTImporter;
+ };
+ name = Debug;
+ };
+ A276B46913A28A3F00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = PLTImporter;
+ };
+ name = Release;
+ };
+ A276B46E13A28A5000D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ HEADER_SEARCH_PATHS = (
+ "$(HEADER_SEARCH_PATHS)",
+ ../gemrb/includes,
+ /usr/X11/include,
+ );
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ LIBRARY_SEARCH_PATHS = /usr/X11/lib;
+ MACH_O_TYPE = mh_bundle;
+ OTHER_LDFLAGS = "-lpng";
+ PRODUCT_NAME = PNGImporter;
+ };
+ name = Debug;
+ };
+ A276B46F13A28A5000D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ HEADER_SEARCH_PATHS = (
+ "$(HEADER_SEARCH_PATHS)",
+ ../gemrb/includes,
+ /usr/X11/include,
+ );
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ LIBRARY_SEARCH_PATHS = /usr/X11/lib;
+ MACH_O_TYPE = mh_bundle;
+ OTHER_LDFLAGS = "-lpng";
+ PRODUCT_NAME = PNGImporter;
+ };
+ name = Release;
+ };
+ A276B47413A28A5D00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = PROImporter;
+ };
+ name = Debug;
+ };
+ A276B47513A28A5D00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = PROImporter;
+ };
+ name = Release;
+ };
+ A276B47A13A28A7600D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = PSTOpcodes;
+ };
+ name = Debug;
+ };
+ A276B47B13A28A7600D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = PSTOpcodes;
+ };
+ name = Release;
+ };
+ A276B48013A28A8500D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ HEADER_SEARCH_PATHS = (
+ /Library/Frameworks/SDL.framework/Headers,
+ "$(HEADER_SEARCH_PATHS)",
+ );
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = SDLAudio;
+ };
+ name = Debug;
+ };
+ A276B48113A28A8500D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ HEADER_SEARCH_PATHS = (
+ /Library/Frameworks/SDL.framework/Headers,
+ "$(HEADER_SEARCH_PATHS)",
+ );
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = SDLAudio;
+ };
+ name = Release;
+ };
+ A276B48613A28A9000D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUNDLE_LOADER = "${BUILT_PRODUCTS_DIR}/GemRB.app/Contents/MacOS/GemRB";
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ HEADER_SEARCH_PATHS = (
+ /Library/Frameworks/SDL.framework/Headers,
+ "$(HEADER_SEARCH_PATHS)",
+ );
+ INSTALL_PATH = "$(HOME)/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = SDLVideo;
+ UNEXPORTED_SYMBOLS_FILE = "";
+ };
+ name = Debug;
+ };
+ A276B48713A28A9000D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUNDLE_LOADER = "${BUILT_PRODUCTS_DIR}/GemRB.app/Contents/MacOS/GemRB";
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ HEADER_SEARCH_PATHS = (
+ /Library/Frameworks/SDL.framework/Headers,
+ "$(HEADER_SEARCH_PATHS)",
+ );
+ INSTALL_PATH = "$(HOME)/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = SDLVideo;
+ UNEXPORTED_SYMBOLS_FILE = "";
+ };
+ name = Release;
+ };
+ A276B48C13A28A9E00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = SPLImporter;
+ };
+ name = Debug;
+ };
+ A276B48D13A28A9E00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = SPLImporter;
+ };
+ name = Release;
+ };
+ A276B49213A28AA900D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = TISImporter;
+ };
+ name = Debug;
+ };
+ A276B49313A28AA900D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = TISImporter;
+ };
+ name = Release;
+ };
+ A276B49813A28AB800D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = TLKImporter;
+ };
+ name = Debug;
+ };
+ A276B49913A28AB800D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = TLKImporter;
+ };
+ name = Release;
+ };
+ A276B49E13A28AC800D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = WAVReader;
+ };
+ name = Debug;
+ };
+ A276B49F13A28AC800D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = WAVReader;
+ };
+ name = Release;
+ };
+ A276B4A413A28AD300D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = WEDImporter;
+ };
+ name = Debug;
+ };
+ A276B4A513A28AD300D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = WEDImporter;
+ };
+ name = Release;
+ };
+ A276B4AA13A28AE100D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = WMPImporter;
+ };
+ name = Debug;
+ };
+ A276B4AB13A28AE100D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = WMPImporter;
+ };
+ name = Release;
+ };
+ A276B4B013A28AEE00D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = ZLibManager;
+ };
+ name = Debug;
+ };
+ A276B4B113A28AEE00D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = ZLibManager;
+ };
+ name = Release;
+ };
+ A276B4F513A28C0500D41A8A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = STOImporter;
+ };
+ name = Debug;
+ };
+ A276B4F613A28C0500D41A8A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = STOImporter;
+ };
+ name = Release;
+ };
+ A27E830B13A0358300B41410 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = 2DAImporter;
+ };
+ name = Debug;
+ };
+ A27E830C13A0358300B41410 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = 2DAImporter;
+ };
+ name = Release;
+ };
+ A29504751609721300BB22AA /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ HEADER_SEARCH_PATHS = (
+ "$(HEADER_SEARCH_PATHS)",
+ ../gemrb/includes,
+ /Library/Frameworks/FreeType.framework/Headers,
+ );
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = TTFImporter;
+ };
+ name = Debug;
+ };
+ A29504761609721300BB22AA /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ HEADER_SEARCH_PATHS = (
+ "$(HEADER_SEARCH_PATHS)",
+ ../gemrb/includes,
+ /Library/Frameworks/FreeType.framework/Headers,
+ );
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = TTFImporter;
+ };
+ name = Release;
+ };
+ A298DD0F14EB4E8C00F59F56 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUNDLE_LOADER = "${BUILT_PRODUCTS_DIR}/GemRB.app/Contents/MacOS/GemRB";
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ HEADER_SEARCH_PATHS = (
+ /Library/Frameworks/SDL.framework/Headers,
+ "$(HEADER_SEARCH_PATHS)",
+ );
+ INSTALL_PATH = "$(HOME)/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = SDL2Video;
+ UNEXPORTED_SYMBOLS_FILE = "";
+ };
+ name = Debug;
+ };
+ A298DD1014EB4E8C00F59F56 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUNDLE_LOADER = "${BUILT_PRODUCTS_DIR}/GemRB.app/Contents/MacOS/GemRB";
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ HEADER_SEARCH_PATHS = (
+ /Library/Frameworks/SDL.framework/Headers,
+ "$(HEADER_SEARCH_PATHS)",
+ );
+ INSTALL_PATH = "$(HOME)/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = SDL2Video;
+ UNEXPORTED_SYMBOLS_FILE = "";
+ };
+ name = Release;
+ };
+ A29BF7B313A0380F00C812DD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = BAMImporter;
+ };
+ name = Debug;
+ };
+ A29BF7B413A0380F00C812DD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = BAMImporter;
+ };
+ name = Release;
+ };
+ A29BF85E13A0427A00C812DD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = YES;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ FRAMEWORK_SEARCH_PATHS = "";
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GEM_IOS_INC_PATH = ios/lib/include;
+ GEM_IOS_LIB_PATH = ios/lib;
+ HEADER_SEARCH_PATHS = (
+ ./,
+ ../gemrb/includes,
+ $GEM_IOS_INC_PATH,
+ $GEM_IOS_INC_PATH/SDL,
+ $GEM_IOS_INC_PATH/python,
+ );
+ INFOPLIST_FILE = ios/Info.plist;
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ $SDK_DIR/usr/lib,
+ "\"$(SRCROOT)/ios/lib/$PLATFORM_NAME\"",
+ $GEM_IOS_LIB_PATH/$PLATFORM_NAME,
+ );
+ MACOSX_DEPLOYMENT_TARGET = "";
+ OTHER_CFLAGS = (
+ "-DTARGET_OS_IPHONE",
+ "-isystem",
+ ./,
+ "-DSTATIC_LINK",
+ "-DHAVE_CONFIG_H",
+ "-W",
+ "-Wextra",
+ );
+ PRODUCT_NAME = GemRB;
+ PROVISIONING_PROFILE = "";
+ SDKROOT = iphoneos;
+ "SDKROOT[arch=*]" = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALID_ARCHS = "armv7 i386";
+ };
+ name = Debug;
+ };
+ A29BF85F13A0427A00C812DD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = YES;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ FRAMEWORK_SEARCH_PATHS = "";
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GEM_IOS_INC_PATH = ios/lib/include;
+ GEM_IOS_LIB_PATH = ios/lib;
+ HEADER_SEARCH_PATHS = (
+ ./,
+ ../gemrb/includes,
+ $GEM_IOS_INC_PATH,
+ $GEM_IOS_INC_PATH/SDL,
+ $GEM_IOS_INC_PATH/python,
+ );
+ INFOPLIST_FILE = ios/Info.plist;
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ $SDK_DIR/usr/lib,
+ "\"$(SRCROOT)/ios/lib/$PLATFORM_NAME\"",
+ $GEM_IOS_LIB_PATH/$PLATFORM_NAME,
+ );
+ MACOSX_DEPLOYMENT_TARGET = "";
+ OTHER_CFLAGS = (
+ "-isystem",
+ ./,
+ "-DSTATIC_LINK",
+ "-DHAVE_CONFIG_H",
+ "-DTARGET_OS_IPHONE",
+ "-W",
+ "-Wextra",
+ );
+ PRODUCT_NAME = GemRB;
+ PROVISIONING_PROFILE = "";
+ SDKROOT = iphoneos;
+ "SDKROOT[arch=*]" = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALID_ARCHS = "armv7 i386";
+ };
+ name = Release;
+ };
+ A2BD125415A7EDFE000FAB95 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ HEADER_SEARCH_PATHS = (
+ /Applications/VLC.app/Contents/MacOS/include,
+ "$(HEADER_SEARCH_PATHS)",
+ ../gemrb/includes,
+ );
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ LD_RUNPATH_SEARCH_PATHS = "\"$(SYSTEM_APPS_DIR)/VLC.app/Contents/MacOS/lib\"";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"$(SYSTEM_APPS_DIR)/VLC.app/Contents/MacOS/lib\"",
+ );
+ MACH_O_TYPE = mh_bundle;
+ OTHER_LDFLAGS = "-lvlc";
+ PRODUCT_NAME = VLCPlayer;
+ };
+ name = Debug;
+ };
+ A2BD125515A7EDFE000FAB95 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ HEADER_SEARCH_PATHS = (
+ /Applications/VLC.app/Contents/MacOS/include,
+ "$(HEADER_SEARCH_PATHS)",
+ ../gemrb/includes,
+ );
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ LD_RUNPATH_SEARCH_PATHS = "\"$(SYSTEM_APPS_DIR)/VLC.app/Contents/MacOS/lib\"";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"$(SYSTEM_APPS_DIR)/VLC.app/Contents/MacOS/lib\"",
+ );
+ MACH_O_TYPE = mh_bundle;
+ OTHER_LDFLAGS = "-lvlc";
+ PRODUCT_NAME = VLCPlayer;
+ };
+ name = Release;
+ };
+ A2E66339139E875500310FC8 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ EXECUTABLE_PREFIX = lib;
+ HEADER_SEARCH_PATHS = (
+ ../gemrb/core,
+ "$(HOME)/Library/Frameworks/SDL.framework/Headers",
+ /Library/Frameworks/SDL.framework/Headers,
+ "$(HEADER_SEARCH_PATHS)",
+ );
+ INSTALL_PATH = "@rpath";
+ PRODUCT_NAME = gemrb_core;
+ };
+ name = Debug;
+ };
+ A2E6633A139E875500310FC8 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ EXECUTABLE_PREFIX = lib;
+ HEADER_SEARCH_PATHS = (
+ ../gemrb/core,
+ "$(HOME)/Library/Frameworks/SDL.framework/Headers",
+ /Library/Frameworks/SDL.framework/Headers,
+ "$(HEADER_SEARCH_PATHS)",
+ );
+ INSTALL_PATH = "@rpath";
+ PRODUCT_NAME = gemrb_core;
+ };
+ name = Release;
+ };
+ A2F0505213ABB80C0023B7EB /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = SAVImporter;
+ };
+ name = Debug;
+ };
+ A2F0505313ABB80C0023B7EB /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = SAVImporter;
+ };
+ name = Release;
+ };
+ A2F8708E14AE439000F9CC1F /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ A2F8708F14AE439000F9CC1F /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
+ A2FCD5FC13A0366100271997 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = ACMReader;
+ };
+ name = Debug;
+ };
+ A2FCD5FD13A0366100271997 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = ACMReader;
+ };
+ name = Release;
+ };
+ A2FE2C7F16F2316400DDC6C7 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = NullSource;
+ };
+ name = Debug;
+ };
+ A2FE2C8016F2316400DDC6C7 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = "";
+ DYLIB_CURRENT_VERSION = "";
+ EXECUTABLE_EXTENSION = so;
+ EXECUTABLE_PREFIX = "";
+ INSTALL_PATH = "~/Library/Application Support/GemRB/plugins";
+ MACH_O_TYPE = mh_bundle;
+ PRODUCT_NAME = NullSource;
+ };
+ name = Release;
+ };
+ C01FCF4B08A954540054247B /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = YES;
+ COMBINE_HIDPI_IMAGES = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ /Library/Frameworks,
+ /System/Library/Frameworks,
+ "$(FRAMEWORK_SEARCH_PATHS)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ INFOPLIST_FILE = osx/Info.plist;
+ PRODUCT_NAME = GemRB;
+ WRAPPER_EXTENSION = app;
+ };
+ name = Debug;
+ };
+ C01FCF4C08A954540054247B /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = YES;
+ COMBINE_HIDPI_IMAGES = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ /System/Library/Frameworks,
+ "$(FRAMEWORK_SEARCH_PATHS)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ INFOPLIST_FILE = osx/Info.plist;
+ PRODUCT_NAME = GemRB;
+ WRAPPER_EXTENSION = app;
+ };
+ name = Release;
+ };
+ C01FCF4F08A954540054247B /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ DEPLOYMENT_POSTPROCESSING = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(FRAMEWORK_SEARCH_PATHS)",
+ /Library/Frameworks/,
+ );
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ "GCC_VERSION[arch=x86_64]" = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_PEDANTIC = NO;
+ GCC_WARN_SIGN_COMPARE = YES;
+ GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_LABEL = YES;
+ GCC_WARN_UNUSED_PARAMETER = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = (
+ "$(HEADER_SEARCH_PATHS)",
+ ../gemrb/includes,
+ );
+ IPHONEOS_DEPLOYMENT_TARGET = 4.3;
+ LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
+ MACOSX_DEPLOYMENT_TARGET = 10.5;
+ OTHER_CFLAGS = (
+ "-DTARGET_OS_MAC=1",
+ "-DHAVE_CONFIG_H",
+ "-g",
+ "-D_DEBUG",
+ "-isystem",
+ ./,
+ "-W",
+ "-Wextra",
+ "-Wformat",
+ "-Wall",
+ );
+ SDKROOT = "";
+ "SDKROOT[arch=*]" = "";
+ STRIP_INSTALLED_PRODUCT = NO;
+ STRIP_STYLE = debugging;
+ USER_HEADER_SEARCH_PATHS = "./ ../gemrb/ ../gemrb/core/ ../gemrb/includes/";
+ USE_HEADERMAP = NO;
+ VALID_ARCHS = "i386 x86_64";
+ };
+ name = Debug;
+ };
+ C01FCF5008A954540054247B /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DEPLOYMENT_POSTPROCESSING = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(FRAMEWORK_SEARCH_PATHS)",
+ /Library/Frameworks/,
+ );
+ GCC_OPTIMIZATION_LEVEL = 3;
+ GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ "GCC_VERSION[arch=x86_64]" = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_PEDANTIC = NO;
+ GCC_WARN_SIGN_COMPARE = YES;
+ GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_LABEL = YES;
+ GCC_WARN_UNUSED_PARAMETER = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = (
+ "$(HEADER_SEARCH_PATHS)",
+ ../gemrb/includes,
+ );
+ IPHONEOS_DEPLOYMENT_TARGET = 4.3;
+ LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
+ MACOSX_DEPLOYMENT_TARGET = 10.5;
+ OTHER_CFLAGS = (
+ "-DTARGET_OS_MAC=1",
+ "-DHAVE_CONFIG_H",
+ "-isystem",
+ ./,
+ "-W",
+ "-Wextra",
+ "-Wformat",
+ );
+ SDKROOT = "";
+ "SDKROOT[arch=*]" = "";
+ USER_HEADER_SEARCH_PATHS = "./ ../gemrb/ ../gemrb/core/ ../gemrb/includes/";
+ USE_HEADERMAP = NO;
+ VALID_ARCHS = "i386 x86_64";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ A2462F1813A036C8002D1F02 /* Build configuration list for PBXNativeTarget "AREImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A2462F1213A036B2002D1F02 /* Debug */,
+ A2462F1313A036B2002D1F02 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B3CD13A2869700D41A8A /* Build configuration list for PBXNativeTarget "BIFImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B3CB13A2867900D41A8A /* Debug */,
+ A276B3CC13A2867900D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B43513A287CC00D41A8A /* Build configuration list for PBXNativeTarget "BIKPlayer" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B3D213A286A800D41A8A /* Debug */,
+ A276B3D313A286A800D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B43613A287CC00D41A8A /* Build configuration list for PBXNativeTarget "BMPImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B3D813A286BD00D41A8A /* Debug */,
+ A276B3D913A286BD00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B43713A287CC00D41A8A /* Build configuration list for PBXNativeTarget "BMPWriter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B3DE13A286CD00D41A8A /* Debug */,
+ A276B3DF13A286CD00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B43813A287CC00D41A8A /* Build configuration list for PBXNativeTarget "CHUImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B3E413A286DE00D41A8A /* Debug */,
+ A276B3E513A286DE00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B43913A287CC00D41A8A /* Build configuration list for PBXNativeTarget "CREImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B3EA13A286ED00D41A8A /* Debug */,
+ A276B3EB13A286ED00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B43A13A287CC00D41A8A /* Build configuration list for PBXNativeTarget "DirectoryImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B3F013A286FB00D41A8A /* Debug */,
+ A276B3F113A286FB00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B43B13A287CC00D41A8A /* Build configuration list for PBXNativeTarget "DLGImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B3F613A2871400D41A8A /* Debug */,
+ A276B3F713A2871400D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B43C13A287CC00D41A8A /* Build configuration list for PBXNativeTarget "EFFImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B3FC13A2872600D41A8A /* Debug */,
+ A276B3FD13A2872600D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B43D13A287CC00D41A8A /* Build configuration list for PBXNativeTarget "FXOpcodes" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B40213A2873700D41A8A /* Debug */,
+ A276B40313A2873700D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B43E13A287CC00D41A8A /* Build configuration list for PBXNativeTarget "GAMImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B40813A2874800D41A8A /* Debug */,
+ A276B40913A2874800D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B43F13A287CC00D41A8A /* Build configuration list for PBXNativeTarget "GUIScript" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B40E13A2875500D41A8A /* Debug */,
+ A276B40F13A2875500D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B44013A287CC00D41A8A /* Build configuration list for PBXNativeTarget "IDSImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B41413A2876400D41A8A /* Debug */,
+ A276B41513A2876400D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B44113A287CC00D41A8A /* Build configuration list for PBXNativeTarget "INIImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B41A13A2877100D41A8A /* Debug */,
+ A276B41B13A2877100D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B44213A287CC00D41A8A /* Build configuration list for PBXNativeTarget "ITMImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B42013A2878400D41A8A /* Debug */,
+ A276B42113A2878400D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B44313A287CC00D41A8A /* Build configuration list for PBXNativeTarget "IWDOpcodes" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B42613A2879A00D41A8A /* Debug */,
+ A276B42713A2879A00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B44413A287CC00D41A8A /* Build configuration list for PBXNativeTarget "KEYImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B42C13A287AB00D41A8A /* Debug */,
+ A276B42D13A287AB00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B44513A287CC00D41A8A /* Build configuration list for PBXNativeTarget "MOSImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B43213A287BD00D41A8A /* Debug */,
+ A276B43313A287BD00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4B313A28AF400D41A8A /* Build configuration list for PBXNativeTarget "MUSImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B44A13A289E100D41A8A /* Debug */,
+ A276B44B13A289E100D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4B413A28AF400D41A8A /* Build configuration list for PBXNativeTarget "MVEPlayer" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B45013A28A0100D41A8A /* Debug */,
+ A276B45113A28A0100D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4B513A28AF400D41A8A /* Build configuration list for PBXNativeTarget "NullSound" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B45613A28A0F00D41A8A /* Debug */,
+ A276B45713A28A0F00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4B613A28AF400D41A8A /* Build configuration list for PBXNativeTarget "OGGReader" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B45C13A28A1C00D41A8A /* Debug */,
+ A276B45D13A28A1C00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4B713A28AF400D41A8A /* Build configuration list for PBXNativeTarget "OpenALAudio" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B46213A28A3100D41A8A /* Debug */,
+ A276B46313A28A3100D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4B813A28AF400D41A8A /* Build configuration list for PBXNativeTarget "PLTImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B46813A28A3F00D41A8A /* Debug */,
+ A276B46913A28A3F00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4B913A28AF400D41A8A /* Build configuration list for PBXNativeTarget "PNGImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B46E13A28A5000D41A8A /* Debug */,
+ A276B46F13A28A5000D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4BA13A28AF400D41A8A /* Build configuration list for PBXNativeTarget "PROImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B47413A28A5D00D41A8A /* Debug */,
+ A276B47513A28A5D00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4BB13A28AF400D41A8A /* Build configuration list for PBXNativeTarget "PSTOpcodes" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B47A13A28A7600D41A8A /* Debug */,
+ A276B47B13A28A7600D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4BC13A28AF400D41A8A /* Build configuration list for PBXNativeTarget "SDLAudio" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B48013A28A8500D41A8A /* Debug */,
+ A276B48113A28A8500D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4BD13A28AF400D41A8A /* Build configuration list for PBXNativeTarget "SDLVideo" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B48613A28A9000D41A8A /* Debug */,
+ A276B48713A28A9000D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4BE13A28AF400D41A8A /* Build configuration list for PBXNativeTarget "SPLImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B48C13A28A9E00D41A8A /* Debug */,
+ A276B48D13A28A9E00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4BF13A28AF400D41A8A /* Build configuration list for PBXNativeTarget "TISImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B49213A28AA900D41A8A /* Debug */,
+ A276B49313A28AA900D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4C013A28AF400D41A8A /* Build configuration list for PBXNativeTarget "TLKImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B49813A28AB800D41A8A /* Debug */,
+ A276B49913A28AB800D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4C113A28AF400D41A8A /* Build configuration list for PBXNativeTarget "WAVReader" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B49E13A28AC800D41A8A /* Debug */,
+ A276B49F13A28AC800D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4C213A28AF400D41A8A /* Build configuration list for PBXNativeTarget "WEDImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B4A413A28AD300D41A8A /* Debug */,
+ A276B4A513A28AD300D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4C313A28AF400D41A8A /* Build configuration list for PBXNativeTarget "WMPImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B4AA13A28AE100D41A8A /* Debug */,
+ A276B4AB13A28AE100D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B4C413A28AF400D41A8A /* Build configuration list for PBXNativeTarget "ZLibManager" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B4B013A28AEE00D41A8A /* Debug */,
+ A276B4B113A28AEE00D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A276B52413A28C4400D41A8A /* Build configuration list for PBXNativeTarget "STOImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A276B4F513A28C0500D41A8A /* Debug */,
+ A276B4F613A28C0500D41A8A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A27E831213A035B800B41410 /* Build configuration list for PBXNativeTarget "2DAImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A27E830B13A0358300B41410 /* Debug */,
+ A27E830C13A0358300B41410 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A29504741609721300BB22AA /* Build configuration list for PBXNativeTarget "TTFImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A29504751609721300BB22AA /* Debug */,
+ A29504761609721300BB22AA /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A298DD0E14EB4E8C00F59F56 /* Build configuration list for PBXNativeTarget "SDL2Video" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A298DD0F14EB4E8C00F59F56 /* Debug */,
+ A298DD1014EB4E8C00F59F56 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A29BF7B913A0381D00C812DD /* Build configuration list for PBXNativeTarget "BAMImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A29BF7B313A0380F00C812DD /* Debug */,
+ A29BF7B413A0380F00C812DD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A29BF86313A042B600C812DD /* Build configuration list for PBXNativeTarget "GemRB iOS" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A29BF85E13A0427A00C812DD /* Debug */,
+ A29BF85F13A0427A00C812DD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A2BD125315A7EDFE000FAB95 /* Build configuration list for PBXNativeTarget "VLCPlayer" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A2BD125415A7EDFE000FAB95 /* Debug */,
+ A2BD125515A7EDFE000FAB95 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A2E6633D139E87A400310FC8 /* Build configuration list for PBXNativeTarget "gemrb_core" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A2E66339139E875500310FC8 /* Debug */,
+ A2E6633A139E875500310FC8 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A2F0505713ABB8320023B7EB /* Build configuration list for PBXNativeTarget "SAVImporter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A2F0505213ABB80C0023B7EB /* Debug */,
+ A2F0505313ABB80C0023B7EB /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A2F8708D14AE439000F9CC1F /* Build configuration list for PBXAggregateTarget "ReleasePackage" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A2F8708E14AE439000F9CC1F /* Debug */,
+ A2F8708F14AE439000F9CC1F /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A2FCD60213A0366F00271997 /* Build configuration list for PBXNativeTarget "ACMReader" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A2FCD5FC13A0366100271997 /* Debug */,
+ A2FCD5FD13A0366100271997 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A2FE2C7E16F2316400DDC6C7 /* Build configuration list for PBXNativeTarget "NullSource" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A2FE2C7F16F2316400DDC6C7 /* Debug */,
+ A2FE2C8016F2316400DDC6C7 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "GemRB OS X" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C01FCF4B08A954540054247B /* Debug */,
+ C01FCF4C08A954540054247B /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C01FCF4E08A954540054247B /* Build configuration list for PBXProject "GemRB" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C01FCF4F08A954540054247B /* Debug */,
+ C01FCF5008A954540054247B /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
+}
diff --git a/apple/GemRB.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/apple/GemRB.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..7acc29c
--- /dev/null
+++ b/apple/GemRB.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:GemRB.xcodeproj">
+ </FileRef>
+</Workspace>
diff --git a/apple/README b/apple/README
new file mode 100644
index 0000000..5a0a341
--- /dev/null
+++ b/apple/README
@@ -0,0 +1,35 @@
+Introduction
+------------
+This Xcode project contains build targets for both Mac OS X, and an iOS universal application (supports both iPhone and iPad).
+
+Please report problems in documentation or the project to bradallred at me.com
+
+Words of Advice
+---------------
+
+1.
+When building GemRB plugins for OS X use the provided Xcode target template. (osx/xcode templates/GemRB Plugin.trgttmpl)
+
+I installed the template at /Developer/Library/Xcode/Target Templates/Application Plug-in, but there may be a place in application support for it as well.
+
+2.
+building python for iOS: There is a bug in either Python or GemRB that effects iOS. I have tried both 2.6 and 2.7 (latest stable or each) and at some level of compiler optimization higher than 0 will cause a crash when accessing the spellbooks. I haven't attempted to find the highest level of optimization achievable before the crash occurs and have just built Python sans optimization and performance isn't noticeably impacted.
+
+I'm sure there is a better location for adding python header files to the iOS SDK, but I have created a folder ios/Python where you can place the python headers Include folder and static lib and the project will find them there.
+
+Tip: it is handy to change the build path of your Python target to this directory so you don't have to manually copy each build (if you are changing Python source maybe to find the afore mentioned crash for instance)
+
+Notes
+-----
+
+see the iOS and osx folders for platform specific READMEs.
+
+TODO
+----
+(in no particular order)
+
+1. add external build scripts to build outside dependancies not included is OS X/iOS (SDL, Python)
+
+2. some minor build option cleanup
+
+3. use cake to generate the config.h and default config files.
diff --git a/apple/config.h b/apple/config.h
new file mode 100644
index 0000000..cb8fe23
--- /dev/null
+++ b/apple/config.h
@@ -0,0 +1,42 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#define NOCOLOR 1
+#define HAVE_ICONV 1
+
+#ifndef HAVE_SNPRINTF
+ #define HAVE_SNPRINTF 1
+#endif
+
+#if TARGET_OS_IPHONE
+ #define PACKAGE "GemRB"
+ #define TOUCHSCREEN
+ #define STATIC_LINK//this is in the target build settings now.
+ #define SIZEOF_INT 4
+ #define SIZEOF_LONG_INT 8
+#else
+ #define PACKAGE "GemRB"
+ #define SIZEOF_INT 4
+ #define SIZEOF_LONG_INT 8
+
+ #define MAC_GEMRB_APPSUPPORT "~/Library/Application Support/GemRB"
+#endif
+
+#define HAVE_FORBIDDEN_OBJECT_TO_FUNCTION_CAST 1
diff --git a/apple/defaults.plist b/apple/defaults.plist
new file mode 100644
index 0000000..d757ac6
--- /dev/null
+++ b/apple/defaults.plist
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>GUIEnhancements</key>
+ <true/>
+ <key>SkipIntroVideos</key>
+ <false/>
+ <key>DrawFPS</key>
+ <false/>
+ <key>FogOfWar</key>
+ <true/>
+ <key>EnableCheatKeys</key>
+ <true/>
+ <key>Fullscreen</key>
+ <false/>
+ <key>Width</key>
+ <integer>640</integer>
+ <key>Height</key>
+ <integer>480</integer>
+</dict>
+</plist>
diff --git a/apple/ios/GemRB.cfg.newinstall b/apple/ios/GemRB.cfg.newinstall
new file mode 100644
index 0000000..4edb2f6
--- /dev/null
+++ b/apple/ios/GemRB.cfg.newinstall
@@ -0,0 +1,101 @@
+#automatically generated configuration file
+
+#####################################################
+# GUI Parameters #
+#####################################################
+# #
+# GemRB may enhance the GUI of the Infinity Engine #
+# games (so far only in bg2) creating functionally #
+# new buttons or scrollbars where they weren't #
+# present in original games. It may improve its #
+# usability, but is not quite compatible with #
+# mods changing graphics and alignment in the *.chu #
+# files (e.g. the buttons will appear in old #
+# coordinates and may stop being clickable). #
+#####################################################
+
+# Enable all gui enhancements ? [Boolean]
+GUIEnhancements = 1
+
+#####################################################
+# Debug #
+#####################################################
+
+# Do not play intro videos [Boolean], useful for development
+#SkipIntroVideos=1
+
+# Draw Frames per Second info [Boolean]
+#DrawFPS=1
+
+# Hide unexplored parts of a map
+#FogOfWar=1
+
+# Enable debug and cheat keystrokes, see docs/en/CheatKeys.txt
+# full listing
+#EnableCheatKeys=1
+
+#####################################################
+# Input Parameters #
+#####################################################
+
+#whether or not to use software keyboard on devices that support one
+UseSoftKeyboard=1
+
+#Adds a gutter around the screen for scrolling
+#TouchScrollAreas=1
+
+#####################################################
+# MouseFeedback #
+# Bitfield with reserved bits for disabling #
+# the mouse. Those bits cannot be set via config #
+# #
+# Show mouse+tooltips = 0 #
+# Hide mouse = 1 #
+# Hide tooltips = 2 #
+# Hide mouse+tooltips = 3 #
+#####################################################
+
+# For a strictly touchscreen device we recommend
+# Changing this to 3.
+
+# default is 0
+MouseFeedback=3
+
+#####################################################
+# Touch Gesture Input Parameters #
+# All "NumFing" settings must be > 1 and < 5 #
+# NumFingScroll and NumFingKboard cannot be equal #
+#####################################################
+
+NumFingScroll=2
+
+NumFingKboard=3
+
+NumFingInfo=2
+
+#####################################################
+# Video Parameters #
+#####################################################
+#NOTE: SCREEN width and height can NOT be ARBITRARY without installing the
+# widescreen mod: http://www.gibberlings3.net/widescreen/
+#Resolutions supported by the original games (gemrb) are:
+# * 640x480 (except in iwd2)
+# * 800x600 (bg2, iwd:how, iwd2)
+# * 1024x768 (bg2, iwd:how, iwd2)
+# * 1280x1024 (bg2, iwd:how, iwd2)
+
+#Bits per pixel [Integer:16,32]
+Bpp=32
+
+#Fullscreen [Boolean]
+Fullscreen=1
+
+# Delay before tooltips appear [milliseconds]
+TooltipDelay=500
+
+#####################################################
+# Paths #
+#####################################################
+
+# these were automatically created when you installed
+# this game
diff --git a/apple/ios/Info.plist b/apple/ios/Info.plist
new file mode 100644
index 0000000..44198ec
--- /dev/null
+++ b/apple/ios/Info.plist
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleDisplayName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIconFile</key>
+ <string>Icon.png</string>
+ <key>CFBundleIconFiles</key>
+ <array>
+ <string>Icon.png</string>
+ <string>Icon at 2x.png</string>
+ <string>Icon-72.png</string>
+ </array>
+ <key>CFBundleIcons</key>
+ <dict>
+ <key>CFBundlePrimaryIcon</key>
+ <dict>
+ <key>CFBundleIconFiles</key>
+ <array>
+ <string>gemrb.png</string>
+ <string>Icon.png</string>
+ <string>Icon at 2x.png</string>
+ <string>Icon-72.png</string>
+ </array>
+ <key>UIPrerenderedIcon</key>
+ <false/>
+ </dict>
+ </dict>
+ <key>CFBundleIdentifier</key>
+ <string>net.sourceforge.${PRODUCT_NAME:identifier}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>automatic</string>
+ <key>CFBundleSignature</key>
+ <string>GMRB</string>
+ <key>CFBundleVersion</key>
+ <string>automatic</string>
+ <key>LSRequiresIPhoneOS</key>
+ <false/>
+ <key>UIFileSharingEnabled</key>
+ <true/>
+ <key>UIPrerenderedIcon</key>
+ <string>NO</string>
+ <key>UISupportedInterfaceOrientations</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ </array>
+ <key>UISupportedInterfaceOrientations~ipad</key>
+ <array>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+</dict>
+</plist>
diff --git a/apple/ios/README b/apple/ios/README
new file mode 100644
index 0000000..192b488
--- /dev/null
+++ b/apple/ios/README
@@ -0,0 +1,20 @@
+GemRB for iOS
+------------
+
+Developing without a certificate
+--------------------------------
+You need to alter the iOS SSK if you wish to develop without an Apple developer certificate. Instructions for this procedure are here: http://iphonedevwiki.net/index.php/Xcode#Developing_without_Provisioning_Profile. This page has been archived in this directory as "Xcode - iPhone Development Wiki.html".
+
+Required 3rd party libraries
+----------------------------
+* SDL
+* SDL_ttf
+* freetype2
+* Python
+
+These libraries should be placed in a sub directory to this one directory called "lib".
+you will have to compile these yourself. Most have iOS versions available either officially or as special forks, but as of this writing I had to build Python myself which was a bit hair-pulling.
+
+put the binaries compiled for ARM in "lib/iphoneos" and simulator libraries in "lib/iphonesimulator".
+
+the headers for these libraries should go in "lib/include"
diff --git a/apple/ios/iTunesMetadata.plist.in b/apple/ios/iTunesMetadata.plist.in
new file mode 100644
index 0000000..f7673fe
--- /dev/null
+++ b/apple/ios/iTunesMetadata.plist.in
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>appleId</key>
+ <string></string>
+ <key>artistId</key>
+ <integer>0</integer>
+ <key>artistName</key>
+ <string>sourceforge</string>
+ <key>buy-only</key>
+ <true/>
+ <key>buyParams</key>
+ <string></string>
+ <key>copyright</key>
+ <string>Copyright © 2011 The GemRB Project</string>
+ <key>drmVersionNumber</key>
+ <integer>0</integer>
+ <key>fileExtension</key>
+ <string>.app</string>
+ <key>genre</key>
+ <string>Games</string>
+ <key>genreId</key>
+ <integer>6014</integer>
+ <key>itemId</key>
+ <integer>0</integer>
+ <key>itemName</key>
+ <string>GemRB</string>
+ <key>kind</key>
+ <string>software</string>
+ <key>playlistArtistName</key>
+ <string>Sourceforge</string>
+ <key>playlistName</key>
+ <string>GemRB</string>
+ <key>price</key>
+ <integer>0</integer>
+ <key>priceDisplay</key>
+ <string>nil</string>
+ <key>rating</key>
+ <dict>
+ <key>content</key>
+ <string></string>
+ <key>label</key>
+ <string>4+</string>
+ <key>rank</key>
+ <integer>100</integer>
+ <key>system</key>
+ <string>itunes-games</string>
+ </dict>
+ <key>releaseDate</key>
+ <string></string>
+ <key>s</key>
+ <integer>143441</integer>
+ <key>softwareIcon57x57URL</key>
+ <string></string>
+ <key>softwareIconNeedsShine</key>
+ <false/>
+ <key>softwareSupportedDeviceIds</key>
+ <array>
+ <integer>1</integer>
+ </array>
+ <key>softwareVersionBundleId</key>
+ <string>net.sourceforgepany.GemRB</string>
+ <key>softwareVersionExternalIdentifier</key>
+ <integer>0</integer>
+ <key>softwareVersionExternalIdentifiers</key>
+ <array>
+ <integer>1466803</integer>
+ <integer>1529132</integer>
+ <integer>1602608</integer>
+ <integer>1651681</integer>
+ <integer>1750461</integer>
+ <integer>1930253</integer>
+ <integer>1961532</integer>
+ <integer>1973932</integer>
+ <integer>2026202</integer>
+ <integer>2526384</integer>
+ <integer>2641622</integer>
+ <integer>2703653</integer>
+ </array>
+ <key>vendorId</key>
+ <integer>0</integer>
+ <key>versionRestrictions</key>
+ <integer>0</integer>
+</dict>
+</plist>
diff --git a/apple/osx/Info.plist b/apple/osx/Info.plist
new file mode 100644
index 0000000..b85a62e
--- /dev/null
+++ b/apple/osx/Info.plist
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIconFile</key>
+ <string>gemrb.icns</string>
+ <key>CFBundleIdentifier</key>
+ <string>net.sourceforge.gemrb</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>automatic</string>
+ <key>CFBundleSignature</key>
+ <string>GMRB</string>
+ <key>CFBundleVersion</key>
+ <string>automatic</string>
+ <key>LSApplicationCategoryType</key>
+ <string>public.app-category.role-playing-games</string>
+ <key>LSMinimumSystemVersionByArchitecture</key>
+ <dict>
+ <key>x86_64</key>
+ <string>10.6.0</string>
+ </dict>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+</dict>
+</plist>
diff --git a/apple/osx/README b/apple/osx/README
new file mode 100644
index 0000000..8fc525a
--- /dev/null
+++ b/apple/osx/README
@@ -0,0 +1,17 @@
+GemRB for Mac
+------------
+
+Required 3rd party libraries
+----------------------------
+* SDL
+* Python - included with mac os. please don't try to use a non standard python.
+
+Optional 3rd party libraries
+----------------------------
+* SDL_ttf
+* freetype2
+* ogg/vorbis
+
+
+SDL and SDL_ttf should be build or downloaded as mac frameworks and NOT unix libraries.
+SDL dylib especially is known to be incompatible with GemRB for Mac OS X
diff --git a/artwork/gemrb-logo-36px.png b/artwork/gemrb-logo-36px.png
new file mode 100644
index 0000000..6891b53
Binary files /dev/null and b/artwork/gemrb-logo-36px.png differ
diff --git a/artwork/gemrb-logo-48px.png b/artwork/gemrb-logo-48px.png
new file mode 100644
index 0000000..7ef7a0b
Binary files /dev/null and b/artwork/gemrb-logo-48px.png differ
diff --git a/artwork/gemrb-logo-72px.png b/artwork/gemrb-logo-72px.png
new file mode 100644
index 0000000..2d35db7
Binary files /dev/null and b/artwork/gemrb-logo-72px.png differ
diff --git a/artwork/gemrb-logo-glow-36px.png b/artwork/gemrb-logo-glow-36px.png
new file mode 100644
index 0000000..88c1abe
Binary files /dev/null and b/artwork/gemrb-logo-glow-36px.png differ
diff --git a/artwork/gemrb-logo-glow-48px.png b/artwork/gemrb-logo-glow-48px.png
new file mode 100644
index 0000000..4592234
Binary files /dev/null and b/artwork/gemrb-logo-glow-48px.png differ
diff --git a/artwork/gemrb-logo-glow-72px.png b/artwork/gemrb-logo-glow-72px.png
new file mode 100644
index 0000000..6d6f078
Binary files /dev/null and b/artwork/gemrb-logo-glow-72px.png differ
diff --git a/artwork/gemrb-logo-glow.png b/artwork/gemrb-logo-glow.png
new file mode 100644
index 0000000..41d8736
Binary files /dev/null and b/artwork/gemrb-logo-glow.png differ
diff --git a/artwork/gemrb.icns b/artwork/gemrb.icns
new file mode 100644
index 0000000..1986009
Binary files /dev/null and b/artwork/gemrb.icns differ
diff --git a/artwork/logo-rb_only-light_glow.svg b/artwork/logo-rb_only-light_glow.svg
new file mode 100644
index 0000000..14ddb4e
--- /dev/null
+++ b/artwork/logo-rb_only-light_glow.svg
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ id="Layer_1"
+ x="0px"
+ y="0px"
+ width="200px"
+ height="200px"
+ viewBox="0 0 200 200"
+ xml:space="preserve"
+ inkscape:version="0.48.4 r9939"
+ sodipodi:docname="logo-rb_only-light_glow.svg"><metadata
+ id="metadata25"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs23"><filter
+ id="filter4246"
+ style="color-interpolation-filters:sRGB;"
+ inkscape:label="Drop Shadow"><feFlood
+ id="feFlood4248"
+ flood-opacity="0.5"
+ flood-color="rgb(255,255,255)"
+ result="flood" /><feComposite
+ id="feComposite4250"
+ in2="SourceGraphic"
+ in="flood"
+ operator="in"
+ result="composite1" /><feGaussianBlur
+ id="feGaussianBlur4252"
+ in="composite"
+ stdDeviation="10"
+ result="blur" /><feOffset
+ id="feOffset4254"
+ dx="0"
+ dy="0"
+ result="offset" /><feComposite
+ id="feComposite4256"
+ in2="offset"
+ in="SourceGraphic"
+ operator="over"
+ result="composite2" /></filter></defs><sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1278"
+ inkscape:window-height="748"
+ id="namedview21"
+ showgrid="false"
+ inkscape:zoom="1.0748023"
+ inkscape:cx="152.52136"
+ inkscape:cy="95.261117"
+ inkscape:window-x="86"
+ inkscape:window-y="-3"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="Layer_1" />
+<g
+ id="g3"
+ transform="matrix(0.93221496,0,0,0.93221496,6.7780379,6.778504)"
+ style="filter:url(#filter4246)"
+ inkscape:export-filename="/home/lynx/dev/gemrb/gemrb/artwork/gemrb-logo-glow.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ id="rb1_3_"
+ d="M 27.873,193.766 V 135.24 c 0,-23.674 19.191,-42.865 42.866,-42.865 v 37.508 c 0,35.279 28.603,63.883 63.883,63.883 35.281,0 63.884,-28.604 63.884,-63.883 0,-35.283 -28.603,-63.885 -63.884,-63.885 H 97.116 V 6.234 l -26.378,26.378 0.001,33.387 c -38.242,0 -69.244,31 -69.244,69.241 v 58.525 h 26.378 z"
+ inkscape:connector-curvature="0" />
+ <g
+ id="gem_1_">
+ <path
+ d="m 98.383,139.588 c -0.827,-3.096 -1.267,-6.348 -1.267,-9.705 V 92.375 l 37.506,37.508 -36.239,9.705 z"
+ id="path7"
+ inkscape:connector-curvature="0"
+ style="fill:#6156ff" />
+ <path
+ d="m 134.622,129.883 -9.709,36.236 C 112,162.67 101.832,152.502 98.383,139.588 l 36.239,-9.705 z"
+ id="path9"
+ inkscape:connector-curvature="0"
+ style="fill:#867dff" />
+ <path
+ d="m 134.622,129.883 26.521,26.52 c -6.787,6.787 -16.163,10.988 -26.521,10.988 -3.357,0 -6.612,-0.443 -9.709,-1.271 l 9.709,-36.237 z"
+ id="path11"
+ inkscape:connector-curvature="0"
+ style="fill:#6156ff" />
+ <path
+ d="m 170.859,120.172 c 0.828,3.098 1.27,6.352 1.27,9.711 0,10.357 -4.198,19.732 -10.986,26.52 l -26.521,-26.52 36.237,-9.711 z"
+ id="path13"
+ inkscape:connector-curvature="0"
+ style="fill:#3c2eff" />
+ <path
+ d="m 134.622,129.883 9.71,-36.239 c 12.91,3.451 23.077,13.616 26.527,26.528 l -36.237,9.711 z"
+ id="path15"
+ inkscape:connector-curvature="0"
+ style="fill:#2212ff" />
+ <path
+ d="m 97.116,92.375 h 37.506 c 3.357,0 6.613,0.442 9.71,1.269 l -9.71,36.239 -37.506,-37.508 z"
+ id="path17"
+ inkscape:connector-curvature="0"
+ style="fill:#3c2eff" />
+ <polygon
+ points="120.049,115.309 139.956,109.975 154.529,124.547 149.195,144.455 129.288,149.789 114.715,135.215 "
+ id="polygon19"
+ style="fill:#aaa4ff" />
+ </g>
+</g>
+</svg>
\ No newline at end of file
diff --git a/artwork/shirts/README b/artwork/shirts/README
new file mode 100644
index 0000000..e43b488
--- /dev/null
+++ b/artwork/shirts/README
@@ -0,0 +1,6 @@
+The font used in the shirts is Eadui (available under the Open Font license).
+
+Only one pair of motives is encoded in CMYK, saved as PDF.
+
+The files with the "source-" prefix have the original text, not converted to
+shapes and are therefore editable.
diff --git a/artwork/shirts/detailed-back.svg b/artwork/shirts/detailed-back.svg
new file mode 100644
index 0000000..57a9df2
--- /dev/null
+++ b/artwork/shirts/detailed-back.svg
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.2"
+ width="1052.3622"
+ height="744.09448"
+ viewBox="0 0 1052.3622 744.09448"
+ id="Layer_1"
+ xml:space="preserve"><metadata
+ id="metadata3618"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs3616" />
+<g
+ transform="matrix(0.96849033,0,0,0.96849033,31.002883,55.535439)"
+ id="Version_2b">
+ <path
+ d="m 727.579,321.447 v -98.756 c 0,-39.945 32.384,-72.329 72.331,-72.329 v 63.289 c 0,59.531 48.266,107.796 107.796,107.796 59.533,0 107.796,-48.265 107.796,-107.796 0,-59.534 -48.263,-107.796 -107.796,-107.796 H 844.42 V 5.011 l -44.51,44.51 v 56.336 c -64.529,0 -116.841,52.31 -116.841,116.836 v 98.754 h 44.51 z"
+ id="rb1" />
+ <g
+ id="gem">
+ <path
+ d="m 846.555,230.029 c -1.394,-5.226 -2.137,-10.713 -2.137,-16.378 v -63.289 l 63.286,63.289 -61.149,16.378 z"
+ id="path3595"
+ style="fill:#6156ff" />
+ <path
+ d="m 907.704,213.651 -16.382,61.146 c -21.789,-5.823 -38.945,-22.979 -44.768,-44.769 l 61.15,-16.377 z"
+ id="path3597"
+ style="fill:#867dff" />
+ <path
+ d="m 907.704,213.651 44.751,44.75 c -11.453,11.453 -27.273,18.539 -44.751,18.539 -5.665,0 -11.156,-0.747 -16.382,-2.143 l 16.382,-61.146 z"
+ id="path3599"
+ style="fill:#6156ff" />
+ <path
+ d="m 968.851,197.266 c 1.396,5.226 2.144,10.718 2.144,16.386 0,17.478 -7.086,33.297 -18.539,44.75 l -44.751,-44.75 61.146,-16.386 z"
+ id="path3601"
+ style="fill:#3c2eff" />
+ <path
+ d="m 907.704,213.651 16.386,-61.147 c 21.785,5.823 38.938,22.976 44.761,44.761 l -61.147,16.386 z"
+ id="path3603"
+ style="fill:#2212ff" />
+ <path
+ d="m 844.418,150.363 h 63.286 c 5.665,0 11.16,0.746 16.386,2.142 l -16.386,61.147 -63.286,-63.289 z"
+ id="path3605"
+ style="fill:#3c2eff" />
+ <path
+ d="m 883.116,189.059 33.591,-8.999 24.588,24.588 -8.999,33.591 -33.591,9.003 -24.592,-24.592 z"
+ id="polygon3607"
+ style="fill:#aaa4ff" />
+ </g>
+ <path
+ d="m 416.691,281.119 -22.85,-21.763 c 2.838,-8.699 4.392,-17.978 4.392,-27.624 h -36.844 c 0,28.809 -23.353,52.162 -52.16,52.162 -28.809,0 -52.161,-23.354 -52.161,-52.162 0,-28.807 23.353,-52.159 52.161,-52.159 14.399,0 27.437,5.834 36.876,15.27 l -36.876,36.889 h 52.16 l 36.857,-36.854 -18.645,-18.644 13.726,-27.655 -16.803,-14.101 -25.396,18.723 c -7.289,-3.897 -15.181,-6.809 -23.504,-8.558 l -7.423,-30.669 h -21.934 l -7.421,30.666 c -8.324,1.749 -16.216,4.66 -23.505,8.556 l -25.4, [...]
+ id="e2b" />
+ <path
+ d="m 420.784,231.734 c 0,-49.158 39.848,-89.005 89.004,-89.005 13.854,0 26.966,3.166 38.656,8.812 11.69,-5.646 24.805,-8.812 38.655,-8.812 49.156,0 89.006,39.848 89.006,89.005 v 89.713 h -36.844 v -89.713 c 0,-28.809 -23.354,-52.161 -52.162,-52.161 -15.327,0 -29.112,6.613 -38.655,17.143 -9.544,-10.53 -23.325,-17.143 -38.656,-17.143 -28.808,0 -52.16,23.353 -52.16,52.161 v 89.713 h -36.844 v -89.713 z"
+ id="m" />
+ <g
+ id="g_9_">
+ <path
+ d="m 97.207,283.895 c -28.807,0 -52.16,-23.354 -52.16,-52.162 0,-28.807 23.353,-52.159 52.16,-52.159 28.807,0 52.16,23.353 52.16,52.159 v 52.162 h -52.16 z m 89.706,-52.163 c 0,-49.543 -40.162,-89.704 -89.706,-89.704 -49.544,0 -89.706,40.161 -89.706,89.704 0,49.544 40.162,89.708 89.706,89.708 h 52.16 v 21.821 c 0,14.406 -5.836,27.447 -15.275,36.887 l 26.547,26.55 c 16.233,-16.235 26.274,-38.663 26.274,-63.437 V 231.732 z"
+ id="g" />
+ <path
+ d="m 149.367,283.89499 37.54601,0 0,37.546 -37.54601,0 z"
+ id="square"
+ style="fill:#ff4a2f" />
+ </g>
+</g>
+<g
+ transform="translate(92.76828,-10.118752)"
+ id="flowRoot3620"
+ style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><path
+ d="m 548.61621,478.99313 c 0.17576,0 0.32224,0.0732 0.43945,0.21973 0.14646,0.14648 0.21971,0.32226 0.21973,0.52734 -2e-5,0.17578 -0.0733,0.32227 -0.21973,0.43945 -0.1465,0.11719 -0.30764,0.17578 -0.48339,0.17578 -2.90042,0.41016 -4.59963,0.64454 -5.09766,0.70313 -0.46877,0.0879 -1.084,0.0439 -1.8457,-0.13184 -0.73244,-0.14648 -1.45021,-0.16113 -2.15332,-0.0439 -0.67385,0.14648 -1.30373,0.19043 -1.88965,0.13183 -0.58595,-0.0293 -1.12794,0.0147 -1.62598,0.13184 -0.46876,0.14648 -1.31 [...]
+ id="path3648"
+ style="font-size:90px;font-variant:normal;font-weight:500;font-stretch:normal;word-spacing:12.18000317px;font-family:Eadui;-inkscape-font-specification:Eadui Medium" /><path
+ d="m 594.53906,451.21969 c -0.14653,5.44925 -0.48344,8.17385 -1.01074,8.17383 -0.32231,2e-5 -0.57134,-0.2783 -0.74707,-0.83496 -0.14653,-0.55662 -0.27837,-1.39158 -0.39551,-2.50488 l -14.85351,0.0879 c -9.72659,0.0879 -15.36623,0.60061 -16.91895,1.53808 -0.76173,0.46878 -1.21583,1.46487 -1.3623,2.98828 -0.1172,1.52346 0.13182,3.45705 0.74707,5.80079 0.61522,2.31446 1.1865,3.85255 1.71386,4.61425 0.52733,0.76173 1.36229,1.71388 2.50489,2.85645 1.17185,1.11329 2.63669,2.09473 4.39453, [...]
+ id="path3650"
+ style="font-size:90px;font-variant:normal;font-weight:500;font-stretch:normal;word-spacing:12.18000317px;font-family:Eadui;-inkscape-font-specification:Eadui Medium" /><path
+ d="m 651.41145,462.3818 c -3e-5,1.1133 -0.0147,2.32912 -0.0439,3.64746 l -0.26367,8.39356 c 0.29294,0.38086 1.02536,1.12793 2.19726,2.24121 1.20115,1.08399 2.24119,1.62598 3.12012,1.62597 0.99607,10e-6 1.84567,-0.19042 2.54883,-0.57128 0.70309,-0.38086 1.05465,-0.54199 1.05469,-0.4834 -4e-5,0.0586 -0.20511,0.32227 -0.61524,0.79101 -0.41018,0.46876 -1.58206,1.15723 -3.51562,2.06543 -1.93362,0.90821 -3.70608,1.36231 -5.31739,1.36231 -1.61134,0 -2.87111,-0.71778 -3.77929,-2.15332 -0.87 [...]
+ id="path3652"
+ style="font-size:90px;font-variant:normal;font-weight:500;font-stretch:normal;word-spacing:12.18000317px;font-family:Eadui;-inkscape-font-specification:Eadui Medium" /><path
+ d="m 690.08333,456.93258 c -3e-5,2.57815 -0.30765,5.81545 -0.92285,9.71192 l -0.83496,5.31738 c -0.26371,1.66993 -0.39554,2.81251 -0.39551,3.42773 -3e-5,0.61524 0.0732,1.08399 0.21972,1.40625 0.14646,0.32227 0.33689,0.58595 0.57129,0.79102 0.23435,0.17578 0.74704,0.39551 1.53809,0.65918 0.79098,0.23438 1.18649,0.5127 1.18652,0.83496 -3e-5,0.32227 -0.43948,0.67383 -1.31836,1.05469 -1.81643,0.79101 -4.04299,1.18652 -6.67968,1.18652 -0.84964,0 -1.36233,-0.13183 -1.53809,-0.39551 -0.146 [...]
+ id="path3654"
+ style="font-size:90px;font-variant:normal;font-weight:500;font-stretch:normal;word-spacing:12.18000317px;font-family:Eadui;-inkscape-font-specification:Eadui Medium" /><path
+ d="m 719.61458,447.87985 c 1.28903,3e-5 2.59274,0.30765 3.91113,0.92285 1.31833,0.58597 2.47555,0.98148 3.47168,1.18652 0.99606,0.20511 1.49411,0.52738 1.49414,0.9668 -3e-5,0.3223 -0.93753,1.24515 -2.8125,2.76856 -1.84573,1.52346 -2.92972,2.5049 -3.25195,2.94433 -0.293,0.41018 -1.09866,2.0508 -2.41699,4.92188 -1.31839,2.84181 -2.70999,5.7129 -4.17481,8.61328 -1.43557,2.8711 -2.56349,5.2002 -3.38379,6.9873 -0.82033,1.75782 -1.74318,3.67676 -2.76855,5.75684 -1.02541,2.10937 -2.79787,4 [...]
+ id="path3656"
+ style="font-size:90px;font-variant:normal;font-weight:500;font-stretch:normal;word-spacing:12.18000317px;font-family:Eadui;-inkscape-font-specification:Eadui Medium" /><path
+ d="m 782.93977,451.43942 c -5e-5,1.2305 -1.45024,4.9512 -4.35058,11.16211 -4.04302,8.64259 -6.79692,14.45801 -8.26172,17.44629 -1.05473,2.13867 -1.7725,3.208 -2.15332,3.20801 -0.61527,-10e-6 -1.36234,-0.83497 -2.24121,-2.50489 -1.40629,-2.57812 -2.94437,-5.58105 -4.61426,-9.00879 -1.52347,-3.10545 -2.68069,-5.30272 -3.47168,-6.59179 -0.32229,-0.49803 -0.60061,-0.74706 -0.83496,-0.74707 -0.2637,10e-6 -0.52737,0.26368 -0.79102,0.79101 l -7.07519,14.85352 c -1.05471,2.13867 -1.77248,3. [...]
+ id="path3658"
+ style="font-size:90px;font-variant:normal;font-weight:500;font-stretch:normal;word-spacing:12.18000317px;font-family:Eadui;-inkscape-font-specification:Eadui Medium" /><path
+ d="m 819.5462,463.61227 c -3e-5,2.13869 -0.36624,4.04298 -1.09863,5.71289 -0.90823,2.08009 -2.29983,4.16016 -4.1748,6.24024 -2.25589,2.51953 -4.33597,4.30664 -6.24024,5.36132 l -2.68066,1.49414 c -0.14651,0.0879 -0.26369,0.13184 -0.35156,0.13184 -0.11721,0 -0.21975,-0.0439 -0.30762,-0.13184 -0.11721,-0.17578 -0.044,-0.38086 0.21972,-0.61523 l 1.9336,-1.58203 c 0.55662,-0.46875 1.31834,-1.3623 2.28515,-2.68067 1.17185,-1.64062 2.09471,-3.53026 2.76856,-5.66894 0.6738,-2.13866 1.01071 [...]
+ id="path3660"
+ style="font-size:90px;font-variant:normal;font-weight:500;font-stretch:normal;word-spacing:12.18000317px;font-family:Eadui;-inkscape-font-specification:Eadui Medium" /><path
+ d="m 875.35675,452.36227 c -5e-5,0.58597 -0.35161,1.02542 -1.05469,1.31836 -0.67388,0.2637 -1.8604,0.55667 -3.55957,0.87891 -1.69926,0.32229 -2.88579,0.48342 -3.55957,0.48339 -0.64457,3e-5 -1.40629,-0.23434 -2.28515,-0.70312 -0.87895,-0.46872 -1.45024,-0.7031 -1.71387,-0.70313 -0.3809,3e-5 -0.8936,0.27835 -1.53809,0.83497 -0.64457,0.55666 -1.39164,1.5674 -2.24121,3.03222 -0.82035,1.43557 -1.37699,3.55959 -1.66992,6.37207 -0.26371,2.78322 -0.43949,5.37599 -0.52734,7.77832 -0.0586,2.3 [...]
+ id="path3662"
+ style="font-size:90px;font-variant:normal;font-weight:500;font-stretch:normal;word-spacing:12.18000317px;font-family:Eadui;-inkscape-font-specification:Eadui Medium" /><path
+ d="m 899.87823,472.97262 c -2e-5,0.29298 -0.2637,0.84962 -0.79101,1.66992 -0.49807,0.79102 -1.37698,1.75782 -2.63672,2.90039 -1.23049,1.11329 -3.00295,2.00684 -5.31738,2.68067 -2.28518,0.64453 -4.52638,0.9668 -6.72364,0.9668 -2.02149,0 -3.85254,-0.36622 -5.49316,-1.09864 -1.64063,-0.73242 -2.79786,-1.40625 -3.47168,-2.02148 -0.67383,-0.64453 -1.31836,-1.69922 -1.93359,-3.16406 -0.61524,-1.49414 -0.92286,-4.51171 -0.92285,-9.05274 -10e-6,-5.03904 0.93749,-8.77439 2.8125,-11.20605 1.9 [...]
+ id="path3664"
+ style="font-size:90px;font-variant:normal;font-weight:500;font-stretch:normal;word-spacing:12.18000317px;font-family:Eadui;-inkscape-font-specification:Eadui Medium" /><path
+ d="m 915.43488,435.09176 c -2e-5,5.44926 -0.45412,12.72953 -1.36231,21.84082 -0.41017,4.51174 -1.30372,8.59865 -2.68066,12.26075 -0.1172,0.17579 -0.41017,0.20508 -0.87891,0.0879 -0.43946,-0.0586 -0.71778,-0.17577 -0.83496,-0.35157 0.0586,-1.81639 -10e-6,-7.54392 -0.17578,-17.18261 -0.1172,-5.41989 -1.34767,-10.50289 -3.69141,-15.24903 l 1.62598,-4.6582 c 0.41015,-1.14253 1.3037,-1.71382 2.68066,-1.71387 3.54491,5e-5 5.31737,1.65532 5.31739,4.96582 m -0.70313,41.3086 c -2e-5,1.14258 [...]
+ id="path3666"
+ style="font-size:90px;font-variant:normal;font-weight:500;font-stretch:normal;word-spacing:12.18000317px;font-family:Eadui;-inkscape-font-specification:Eadui Medium" /></g></svg>
\ No newline at end of file
diff --git a/artwork/shirts/detailed-front.svg b/artwork/shirts/detailed-front.svg
new file mode 100644
index 0000000..647cf4d
--- /dev/null
+++ b/artwork/shirts/detailed-front.svg
@@ -0,0 +1,584 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.2"
+ width="744.09448"
+ height="1052.3622"
+ id="svg2">
+ <defs
+ id="defs4" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1">
+ <flowRoot
+ id="flowRoot2985"
+ xml:space="preserve"
+ style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><flowRegion
+ id="flowRegion2987"><rect
+ width="630.33521"
+ height="319.20819"
+ x="64.649765"
+ y="304.8493"
+ id="rect2989" /></flowRegion><flowPara
+ id="flowPara2991" /></flowRoot> <g
+ transform="matrix(1.0344169,0,0,1,-7.5300745,-72)"
+ id="flowRoot2993"
+ style="font-size:72px;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0.11798681px;fill:#000000;fill-opacity:1;stroke:none;font-family:Eadui;-inkscape-font-specification:Eadui Medium">
+ <path
+ d="m 153.21278,338.60004 c 0.19528,0 0.35804,0.0814 0.48828,0.24414 0.16273,0.16277 0.24411,0.35808 0.24414,0.58594 -3e-5,0.19531 -0.0814,0.35807 -0.24414,0.48828 -0.16279,0.13021 -0.34183,0.19531 -0.53711,0.19531 -3.22268,0.45573 -5.1107,0.71615 -5.66406,0.78125 -0.52086,0.0977 -1.20445,0.0488 -2.05079,-0.14648 -0.81382,-0.16276 -1.61134,-0.17904 -2.39257,-0.0488 -0.74872,0.16276 -1.44859,0.21159 -2.09961,0.14649 -0.65106,-0.0326 -1.25327,0.0163 -1.80664,0.14648 -0.52085,0.1627 [...]
+ id="path3257"
+ style="font-size:100px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 165.7616,276.88129 c -0.6185,2.40892 -1.52996,6.31516 -2.73437,11.71875 -1.39975,7.38937 -2.09962,11.65369 -2.09961,12.79297 -0.0651,0.48832 -0.5534,0.83012 -1.46484,1.02539 -0.22788,0.0326 -0.43947,0.0489 -0.63477,0.0488 -0.55339,4e-5 -0.94402,-0.14645 -1.17187,-0.43945 -1e-5,0.0651 -1e-5,0.0977 0,0.0976 -0.0651,4e-5 -0.27671,-1.90425 -0.63477,-5.71289 -0.52084,-5.79422 -0.78126,-11.36062 -0.78125,-16.69922 1.20442,-3.54811 2.97851,-5.3222 5.32227,-5.32226 2.24607,6e-5 3.6 [...]
+ id="path3259"
+ style="font-size:100px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 228.35926,314.08832 c -6e-5,2.86461 -0.35813,6.46161 -1.07422,10.79102 l -0.92773,5.9082 c -0.29303,1.85548 -0.43951,3.23894 -0.43946,4.15039 -5e-5,0.87891 0.21154,1.4974 0.63477,1.85547 0.42312,0.35808 1.09044,0.6836 2.00195,0.97656 0.87885,0.26042 1.3183,0.56967 1.31836,0.92774 -6e-5,0.35807 -0.74875,0.86263 -2.24609,1.51367 -1.49745,0.65104 -3.22271,0.97656 -5.17578,0.97656 -1.92063,0 -2.97857,-0.14648 -3.17383,-0.43945 -0.19536,-0.26042 -0.24419,-0.78125 -0.14649,-1.562 [...]
+ id="path3261"
+ style="font-size:100px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 298.33656,314.08832 c -4e-5,2.86461 -0.34184,6.46161 -1.0254,10.79102 l -0.92773,5.9082 c -0.293,1.85548 -0.43949,3.12501 -0.43945,3.8086 -4e-5,0.6836 0.0813,1.20443 0.24414,1.5625 0.16272,0.35807 0.37431,0.65104 0.63476,0.8789 0.26038,0.19532 0.83005,0.43946 1.70899,0.73242 0.87887,0.26042 1.31832,0.56967 1.31836,0.92774 -4e-5,0.35807 -0.48832,0.7487 -1.46485,1.17187 -2.01826,0.87891 -4.49222,1.31836 -7.42187,1.31836 -0.94404,0 -1.5137,-0.14648 -1.70899,-0.43945 -0.16278,- [...]
+ id="path3263"
+ style="font-size:100px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 337.74085,320.43598 c -3e-5,3.32033 -0.65107,6.28257 -1.95312,8.88672 -1.30212,2.57162 -2.96227,4.78516 -4.98047,6.64062 -2.01826,1.85548 -4.18297,3.20639 -6.49414,4.05274 -2.31122,0.8138 -4.18296,1.2207 -5.61524,1.2207 -0.6836,0 -1.95313,-0.0977 -3.80859,-0.29297 -1.82293,-0.16276 -3.64584,-1.10677 -5.46875,-2.83203 -1.82292,-1.75781 -3.10873,-3.30403 -3.85742,-4.63867 -0.71615,-1.36718 -1.07422,-3.48306 -1.07422,-6.34766 0,-2.89712 0.22786,-5.19204 0.68359,-6.88476 0.4557 [...]
+ id="path3265"
+ style="font-size:100px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 351.51038,323.17036 c -10e-6,4.13412 0.71614,7.25912 2.14844,9.375 1.43228,2.11589 3.07616,3.41797 4.93164,3.90625 1.85545,0.48828 3.92251,0.73242 6.20117,0.73242 1.43227,0 2.58787,-0.29297 3.4668,-0.87891 0.91143,-0.58593 2.00192,-1.88801 3.27148,-3.90625 1.30206,-2.01822 1.9531,-3.43423 1.95313,-4.24805 0.4557,-0.55337 1.05791,-0.91144 1.80664,-1.07421 0.19528,0.52084 0.56963,0.78126 1.12305,0.78125 0.55335,10e-6 0.83004,0.26042 0.83008,0.78125 -4e-5,0.52084 -0.32556,1.41 [...]
+ id="path3267"
+ style="font-size:100px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 426.95643,320.14301 c -3e-5,1.237 -0.0163,2.58791 -0.0488,4.05274 l -0.29297,9.32617 c 0.3255,0.42318 1.1393,1.25326 2.44141,2.49023 1.3346,1.20443 2.4902,1.80665 3.46679,1.80664 1.10674,1e-5 2.05075,-0.21158 2.83204,-0.63476 0.78121,-0.42318 1.17183,-0.60221 1.17187,-0.53711 -4e-5,0.0651 -0.2279,0.35807 -0.68359,0.8789 -0.45577,0.52084 -1.75785,1.28581 -3.90625,2.29493 -2.14847,1.00911 -4.11787,1.51367 -5.90821,1.51367 -1.79038,0 -3.19012,-0.79753 -4.19922,-2.39258 -0.9765 [...]
+ id="path3269"
+ style="font-size:100px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 496.78724,316.4809 c -4e-5,3.38544 -0.47204,5.9896 -1.41602,7.8125 -0.94404,1.82293 -2.22985,3.64585 -3.85742,5.46875 -1.62763,1.79038 -3.09247,3.22267 -4.39453,4.29688 -1.30211,1.07422 -1.95315,1.87175 -1.95313,2.39258 -2e-5,0.48828 0.50454,1.04166 1.51368,1.66015 1.04164,0.61849 2.65296,1.20443 4.83398,1.75781 2.18096,0.52084 4.50843,1.18815 6.98242,2.00196 2.50647,0.84635 4.67119,2.11588 6.49414,3.80859 1.85543,1.6927 2.78316,4.70377 2.78321,9.0332 -5e-5,3.90624 -1.23703 [...]
+ id="path3271"
+ style="font-size:100px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 572.86146,312.03754 c -7e-5,0.74873 -0.39069,1.31839 -1.17188,1.70899 -1.43235,0.68362 -3.40175,1.10679 -5.9082,1.26953 -2.50657,0.16278 -4.06907,0.27672 -4.6875,0.3418 -0.58599,0.0326 -2.47401,0.21161 -5.66406,0.5371 -3.19015,0.293 -5.37114,0.52086 -6.54297,0.6836 -1.17192,0.13023 -1.92061,0.29299 -2.2461,0.48828 -0.42321,0.19534 -0.78128,0.71617 -1.07421,1.5625 -0.13025,0.39065 -0.27674,1.20445 -0.43946,2.44141 -0.13024,1.23699 -0.19535,2.44142 -0.19531,3.61328 -4e-5,1.59 [...]
+ id="path3273"
+ style="font-size:100px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 613.87708,335.03559 c -4e-5,1.04167 -1.15564,2.26237 -3.46679,3.66211 -2.27869,1.36719 -3.74353,2.05078 -4.39454,2.05078 -0.65107,0 -2.84834,-1.12305 -6.59179,-3.36914 -3.71097,-2.24609 -6.90107,-4.83398 -9.57032,-7.76367 -2.63673,-2.96223 -4.23178,-4.44335 -4.78515,-4.44336 l -2.09961,0 c -1.46486,1e-5 -2.2461,1.13934 -2.34375,3.41797 -0.0326,0.26043 -0.0326,1.87175 0,4.83398 0.0325,1.92058 0.56965,3.14128 1.61133,3.66211 1.04165,0.48828 1.61131,0.76498 1.70898,0.83008 0.1 [...]
+ id="path3275"
+ style="font-size:100px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 68.237649,427.07345 c 0.138247,1e-5 0.253469,0.0576 0.345664,0.17284 0.115203,0.11522 0.172814,0.25349 0.172833,0.41479 -1.9e-5,0.13827 -0.05763,0.25349 -0.172833,0.34567 -0.11524,0.0922 -0.241983,0.13827 -0.380231,0.13826 -2.281401,0.32262 -3.617969,0.50698 -4.009707,0.55307 -0.368723,0.0691 -0.852653,0.0346 -1.451791,-0.1037 -0.57612,-0.11522 -1.140705,-0.12675 -1.693756,-0.0346 -0.53003,0.11522 -1.025482,0.14979 -1.486357,0.1037 -0.460896,-0.023 -0.887215,0.0115 -1.27895 [...]
+ id="path3277"
+ style="font-size:70.79208374px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 77.121226,383.38147 c -0.437852,1.70532 -1.083092,4.47063 -1.935721,8.29594 -0.990913,5.23109 -1.486365,8.24989 -1.486357,9.05641 -0.0461,0.34569 -0.391761,0.58766 -1.036994,0.7259 -0.161316,0.0231 -0.311104,0.0346 -0.449363,0.0346 -0.391759,3e-5 -0.668291,-0.10367 -0.829595,-0.31109 -6e-6,0.0461 -6e-6,0.0692 0,0.0691 -0.04609,3e-5 -0.195882,-1.34806 -0.449364,-4.04428 -0.368713,-4.10185 -0.553068,-8.04242 -0.553063,-11.82172 0.852634,-2.51178 2.108547,-3.7677 3.767743,-3.7 [...]
+ id="path3279"
+ style="font-size:70.79208374px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 121.43541,409.7211 c -4e-5,2.02791 -0.25353,4.57431 -0.76046,7.63918 l -0.65676,4.18254 c -0.20744,1.31353 -0.31114,2.29292 -0.3111,2.93815 -4e-5,0.6222 0.14975,1.06004 0.44936,1.31353 0.29954,0.25349 0.77195,0.48393 1.41723,0.69133 0.62215,0.18435 0.93325,0.40327 0.93329,0.65676 -4e-5,0.25349 -0.53006,0.61067 -1.59006,1.07156 -1.06007,0.46088 -2.28142,0.69133 -3.66404,0.69133 -1.35965,0 -2.10859,-0.1037 -2.24682,-0.3111 -0.1383,-0.18436 -0.17286,-0.55306 -0.1037,-1.10613 0 [...]
+ id="path3281"
+ style="font-size:70.79208374px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 166.12916,414.00734 c -2e-5,0.87569 -0.0115,1.83203 -0.0346,2.86901 l -0.2074,6.60219 c 0.23043,0.29958 0.80654,0.88721 1.72833,1.76289 0.94479,0.85264 1.76286,1.27896 2.45422,1.27896 0.78348,0 1.45176,-0.14978 2.00485,-0.44936 0.55304,-0.29958 0.82957,-0.42632 0.82959,-0.38023 -2e-5,0.0461 -0.16133,0.25349 -0.48393,0.62219 -0.32264,0.36871 -1.24441,0.91025 -2.76531,1.62463 -1.52095,0.71437 -2.91513,1.07156 -4.18254,1.07156 -1.26746,0 -2.25836,-0.56459 -2.97272,-1.69376 -0. [...]
+ id="path3283"
+ style="font-size:70.79208374px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 214.38326,422.68352 c -3e-5,0.73742 -0.51852,1.5094 -1.55549,2.31595 -1.03702,0.78351 -2.55794,1.59006 -4.56278,2.41965 -1.98182,0.80655 -3.4797,1.23287 -4.49363,1.27896 -1.01396,0.0461 -1.93573,0.0691 -2.76532,0.0691 -1.91268,0 -3.36447,-0.46089 -4.35537,-1.38266 -0.99091,-0.94481 -1.48636,-1.63614 -1.48636,-2.07398 0,-0.46089 0.19588,-3.99818 0.58763,-10.6119 0.4148,-6.63674 0.59915,-11.5106 0.55306,-14.62161 -0.023,-3.11095 -0.11522,-5.35777 -0.27653,-6.74046 -0.13827,-1 [...]
+ id="path3285"
+ style="font-size:70.79208374px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 232.08128,422.33785 c -2e-5,0.23045 -0.20742,0.66829 -0.6222,1.31353 -0.39177,0.6222 -1.0831,1.38266 -2.07398,2.28138 -0.96788,0.87569 -2.36206,1.57854 -4.18254,2.10856 -1.79747,0.50697 -3.56036,0.76046 -5.28867,0.76046 -1.59006,0 -3.03033,-0.28806 -4.32081,-0.86416 -1.29048,-0.57611 -2.20073,-1.10613 -2.73074,-1.59006 -0.53003,-0.50697 -1.037,-1.33657 -1.52093,-2.48878 -0.48393,-1.17526 -0.72589,-3.54882 -0.72589,-7.12069 0,-3.96361 0.73741,-6.90175 2.21225,-8.81445 1.4978 [...]
+ id="path3287"
+ style="font-size:70.79208374px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 254.79144,405.40029 c -3e-5,0.96789 -1.18681,4.02125 -3.56035,9.16011 -2.37358,5.13889 -4.49365,9.58643 -6.36022,13.34265 -0.82961,1.68223 -1.3942,2.52335 -1.69376,2.52335 -0.50699,0 -1.09462,-0.65676 -1.76289,-1.97029 -1.61311,-3.0188 -3.26078,-6.19891 -4.943,-9.54034 -1.6592,-3.36445 -3.54883,-6.55608 -5.6689,-9.5749 -0.46089,-0.7374 -0.69133,-1.46329 -0.69133,-2.17769 0,-0.99088 0.64524,-1.832 1.93572,-2.52335 1.29048,-0.71435 2.63857,-1.07153 4.04428,-1.07156 0.85263,3e [...]
+ id="path3289"
+ style="font-size:70.79208374px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 277.43246,422.33785 c -2e-5,0.23045 -0.20742,0.66829 -0.62219,1.31353 -0.39178,0.6222 -1.08311,1.38266 -2.07399,2.28138 -0.96788,0.87569 -2.36206,1.57854 -4.18254,2.10856 -1.79747,0.50697 -3.56036,0.76046 -5.28867,0.76046 -1.59006,0 -3.03033,-0.28806 -4.3208,-0.86416 -1.29049,-0.57611 -2.20074,-1.10613 -2.73075,-1.59006 -0.53002,-0.50697 -1.037,-1.33657 -1.52093,-2.48878 -0.48393,-1.17526 -0.72589,-3.54882 -0.72589,-7.12069 0,-3.96361 0.73741,-6.90175 2.21225,-8.81445 1.497 [...]
+ id="path3291"
+ style="font-size:70.79208374px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 297.481,422.68352 c -2e-5,0.73742 -0.51851,1.5094 -1.55549,2.31595 -1.03701,0.78351 -2.55793,1.59006 -4.56277,2.41965 -1.98182,0.80655 -3.4797,1.23287 -4.49364,1.27896 -1.01395,0.0461 -1.93573,0.0691 -2.76531,0.0691 -1.91268,0 -3.36447,-0.46089 -4.35537,-1.38266 -0.99091,-0.94481 -1.48636,-1.63614 -1.48636,-2.07398 0,-0.46089 0.19587,-3.99818 0.58763,-10.6119 0.41479,-6.63674 0.59915,-11.5106 0.55306,-14.62161 -0.0231,-3.11095 -0.11522,-5.35777 -0.27653,-6.74046 -0.13827,-1 [...]
+ id="path3293"
+ style="font-size:70.79208374px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 333.63684,427.00432 c -2e-5,1.10613 -0.34568,2.6501 -1.03699,4.63191 -0.6683,1.9818 -1.65921,3.72164 -2.97272,5.21953 -1.29049,1.52091 -2.52336,2.67313 -3.69861,3.45664 -1.17527,0.80654 -2.46575,1.47483 -3.87144,2.00486 -1.38266,0.53 -2.92663,0.92176 -4.6319,1.17526 -0.34567,-0.11524 -0.38024,-0.28807 -0.1037,-0.5185 2.00485,-0.8757 3.50272,-1.64768 4.49364,-2.31595 0.99089,-0.6683 2.05093,-1.67072 3.18011,-3.00728 1.12916,-1.33658 1.95875,-2.93816 2.48878,-4.80474 0.55305, [...]
+ id="path3295"
+ style="font-size:70.79208374px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 358.45556,382.37904 c -3e-5,0.23049 -0.11525,0.62224 -0.34567,1.17526 l -4.28624,9.5749 c -1.6592,3.75626 -3.11099,7.44334 -4.35537,11.06127 -1.2444,3.61797 -2.88055,7.58159 -4.90843,11.89085 -2.02791,4.3093 -3.29534,7.13222 -3.80231,8.46878 -0.48394,1.33658 -1.20983,2.38509 -2.17769,3.14555 l -2.48878,1.97029 c -0.43785,0.34566 -0.73742,0.51849 -0.89873,0.5185 -0.2074,-10e-6 -0.3111,-0.14979 -0.3111,-0.44937 0,-0.27653 0.1037,-0.70285 0.3111,-1.27896 0.94481,-2.62704 2.292 [...]
+ id="path3297"
+ style="font-size:70.79208374px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 377.43252,409.54827 c -2e-5,1.52094 -0.0922,2.68467 -0.27654,3.49121 -0.18437,0.78352 -0.44938,1.60159 -0.79502,2.45422 -0.32264,0.8296 -0.82962,1.82051 -1.52093,2.97271 -0.6683,1.12918 -1.47485,2.08552 -2.41965,2.86901 -0.94483,0.76047 -1.53246,1.22136 -1.76289,1.38266 -0.20741,0.16132 -0.49546,0.34567 -0.86416,0.55307 -0.36872,0.2074 -0.64525,0.38023 -0.82959,0.51849 -0.36872,0.29958 -0.31111,0.46089 0.17283,0.48393 1.22133,0.0461 2.69617,0.42633 4.4245,1.1407 1.72831,0.6 [...]
+ id="path3299"
+ style="font-size:70.79208374px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 431.32094,414.9752 c -3e-5,1.68224 -0.28808,3.18012 -0.86416,4.49364 -0.7144,1.63615 -1.809,3.27229 -3.28381,4.90843 -1.77444,1.98181 -3.41058,3.38751 -4.90844,4.21711 l -2.10855,1.17526 c -0.11524,0.0691 -0.20742,0.1037 -0.27653,0.1037 -0.0922,0 -0.17285,-0.0346 -0.24197,-0.1037 -0.0922,-0.13827 -0.0346,-0.29958 0.17283,-0.48393 l 1.52093,-1.24439 c 0.43782,-0.36871 1.03697,-1.07156 1.79745,-2.10856 0.92175,-1.29047 1.64765,-2.77683 2.17769,-4.45907 0.53,-1.68222 0.79501,- [...]
+ id="path3301"
+ style="font-size:70.79208374px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 449.50291,414.00734 c -2e-5,0.87569 -0.0115,1.83203 -0.0346,2.86901 l -0.2074,6.60219 c 0.23043,0.29958 0.80654,0.88721 1.72833,1.76289 0.94479,0.85264 1.76286,1.27896 2.45421,1.27896 0.78349,0 1.45177,-0.14978 2.00486,-0.44936 0.55304,-0.29958 0.82957,-0.42632 0.82959,-0.38023 -2e-5,0.0461 -0.16133,0.25349 -0.48393,0.62219 -0.32264,0.36871 -1.24441,0.91025 -2.76531,1.62463 -1.52095,0.71437 -2.91513,1.07156 -4.18254,1.07156 -1.26746,0 -2.25836,-0.56459 -2.97272,-1.69376 -0. [...]
+ id="path3303"
+ style="font-size:70.79208374px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 478.2622,418.91577 c -2e-5,2.18922 -0.70288,3.91754 -2.10855,5.18497 -1.40573,1.26744 -3.05339,2.40813 -4.94301,3.42208 -1.8666,0.9909 -4.41299,1.48636 -7.63918,1.48636 -2.02791,0 -3.90601,-0.67981 -5.63433,-2.03942 -1.72833,-1.38266 -2.59249,-3.75622 -2.59249,-7.12069 0,-3.13402 0.42632,-5.78411 1.27896,-7.95029 0.87568,-2.18918 1.88963,-3.85989 3.04185,-5.01213 1.17525,-1.15219 2.68465,-2.10853 4.52821,-2.86902 1.86657,-0.76043 3.53728,-1.14066 5.01213,-1.14069 1.45177,3e [...]
+ id="path3305"
+ style="font-size:70.79208374px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 506.95232,424.5501 c -3e-5,0.73742 -0.8181,1.60159 -2.45422,2.59249 -1.61312,0.96786 -2.65012,1.45179 -3.11098,1.45179 -0.46091,0 -2.0164,-0.79503 -4.66647,-2.38509 -2.62706,-1.59005 -4.8854,-3.42207 -6.77502,-5.49606 -1.8666,-2.09702 -2.99577,-3.14554 -3.38751,-3.14555 l -1.48636,0 c -1.037,1e-5 -1.59006,0.80656 -1.65919,2.41965 -0.0231,0.18437 -0.0231,1.32506 0,3.42208 0.023,1.35962 0.40327,2.22378 1.14069,2.59249 0.73741,0.34566 1.14069,0.54154 1.20983,0.58762 0.0922,0.0 [...]
+ id="path3307"
+ style="font-size:70.79208374px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 548.50121,406.12619 c -5e-5,0.46091 -0.27658,0.80657 -0.8296,1.03699 -0.53006,0.20742 -1.46335,0.43786 -2.79988,0.69133 -1.33661,0.25351 -2.2699,0.38025 -2.79988,0.38023 -0.50701,2e-5 -1.10616,-0.18433 -1.79746,-0.55306 -0.69136,-0.36869 -1.14072,-0.55304 -1.34809,-0.55307 -0.29961,3e-5 -0.70288,0.21895 -1.20983,0.65677 -0.507,0.43786 -1.09463,1.23289 -1.76288,2.38508 -0.64527,1.12919 -1.08312,2.7999 -1.31353,5.01214 -0.20743,2.18922 -0.34569,4.22863 -0.4148,6.11826 -0.0461 [...]
+ id="path3309"
+ style="font-size:70.79208374px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 570.90026,382.37904 c -2e-5,0.23049 -0.11524,0.62224 -0.34566,1.17526 l -4.28624,9.5749 c -1.65921,3.75626 -3.111,7.44334 -4.35538,11.06127 -1.2444,3.61797 -2.88055,7.58159 -4.90843,11.89085 -2.02791,4.3093 -3.29534,7.13222 -3.80231,8.46878 -0.48394,1.33658 -1.20983,2.38509 -2.17769,3.14555 l -2.48878,1.97029 c -0.43784,0.34566 -0.73742,0.51849 -0.89873,0.5185 -0.2074,-10e-6 -0.3111,-0.14979 -0.3111,-0.44937 0,-0.27653 0.1037,-0.70285 0.3111,-1.27896 0.94482,-2.62704 2.2929 [...]
+ id="path3311"
+ style="font-size:70.79208374px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 611.86148,409.7211 c -4e-5,2.02791 -0.25353,4.57431 -0.76046,7.63918 l -0.65677,4.18254 c -0.20743,1.31353 -0.31113,2.29292 -0.31109,2.93815 -4e-5,0.6222 0.14975,1.06004 0.44936,1.31353 0.29954,0.25349 0.77194,0.48393 1.41722,0.69133 0.62216,0.18435 0.93326,0.40327 0.9333,0.65676 -4e-5,0.25349 -0.53006,0.61067 -1.59006,1.07156 -1.06007,0.46088 -2.28142,0.69133 -3.66404,0.69133 -1.35965,0 -2.10859,-0.1037 -2.24682,-0.3111 -0.1383,-0.18436 -0.17287,-0.55306 -0.1037,-1.10613 0 [...]
+ id="path3313"
+ style="font-size:70.79208374px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 632.56681,414.00734 c -2e-5,0.87569 -0.0115,1.83203 -0.0346,2.86901 l -0.2074,6.60219 c 0.23042,0.29958 0.80653,0.88721 1.72832,1.76289 0.9448,0.85264 1.76287,1.27896 2.45422,1.27896 0.78348,0 1.45176,-0.14978 2.00485,-0.44936 0.55304,-0.29958 0.82957,-0.42632 0.8296,-0.38023 -3e-5,0.0461 -0.16134,0.25349 -0.48393,0.62219 -0.32265,0.36871 -1.24442,0.91025 -2.76532,1.62463 -1.52094,0.71437 -2.91512,1.07156 -4.18254,1.07156 -1.26745,0 -2.25836,-0.56459 -2.97271,-1.69376 -0.69 [...]
+ id="path3315"
+ style="font-size:70.79208374px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 662.1557,411.41485 c -3e-5,2.39663 -0.33417,4.24017 -1.00243,5.53064 -0.66831,1.29049 -1.57856,2.58097 -2.73075,3.87144 -1.15223,1.26744 -2.18923,2.28139 -3.11098,3.04185 -0.92179,0.76046 -1.38267,1.32505 -1.38266,1.69375 -1e-5,0.34567 0.35717,0.73742 1.07156,1.17526 0.7374,0.43784 1.87809,0.85264 3.42208,1.24439 1.54395,0.36871 3.19161,0.84112 4.943,1.41723 1.77439,0.59915 3.30683,1.49787 4.59734,2.69618 1.31349,1.1983 1.97026,3.32989 1.97029,6.39479 -3e-5,2.76531 -0.87572 [...]
+ id="path3317"
+ style="font-size:70.79208374px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 692.09025,422.33785 c -2e-5,0.23045 -0.20742,0.66829 -0.62219,1.31353 -0.39178,0.6222 -1.08311,1.38266 -2.07399,2.28138 -0.96788,0.87569 -2.36206,1.57854 -4.18254,2.10856 -1.79747,0.50697 -3.56036,0.76046 -5.28867,0.76046 -1.59006,0 -3.03033,-0.28806 -4.3208,-0.86416 -1.29049,-0.57611 -2.20074,-1.10613 -2.73075,-1.59006 -0.53002,-0.50697 -1.037,-1.33657 -1.52093,-2.48878 -0.48393,-1.17526 -0.72589,-3.54882 -0.72589,-7.12069 0,-3.96361 0.73741,-6.90175 2.21225,-8.81445 1.497 [...]
+ id="path3319"
+ style="font-size:70.79208374px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ </g>
+ <g
+ transform="matrix(1.0344169,0,0,1,-6.5559329,367.36316)"
+ id="flowRoot2993-2"
+ style="font-size:72px;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0.11798681px;fill:#000000;fill-opacity:1;stroke:none;font-family:Eadui;-inkscape-font-specification:Eadui Medium">
+ <path
+ d="m 104.88961,292.34956 c -0.0768,2.8575 -0.25351,4.28625 -0.53002,4.28624 -0.16901,10e-6 -0.2996,-0.14594 -0.39175,-0.43785 -0.0768,-0.29188 -0.14597,-0.72972 -0.2074,-1.31352 l -7.788971,0.0461 c -5.100483,0.0461 -8.057832,0.31495 -8.872055,0.80655 -0.399442,0.24582 -0.637566,0.76815 -0.714373,1.56701 -0.06146,0.79888 0.06913,1.81283 0.391753,3.04185 0.322612,1.21367 0.622188,2.02022 0.898727,2.41965 0.276523,0.39944 0.714365,0.89873 1.313525,1.49788 0.614505,0.58379 1.382647 [...]
+ id="path3082"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 120.99758,303.98693 c -2e-5,0.49161 -0.34568,1.00627 -1.037,1.54396 -0.69134,0.52234 -1.70529,1.06004 -3.04184,1.61311 -1.32122,0.5377 -2.3198,0.82191 -2.99576,0.85263 -0.67598,0.0307 -1.29049,0.0461 -1.84355,0.0461 -1.27512,0 -2.24298,-0.30725 -2.90358,-0.92177 -0.6606,-0.62987 -0.9909,-1.09076 -0.9909,-1.38266 0,-0.30725 0.13058,-2.66545 0.39175,-7.0746 0.27653,-4.42449 0.39943,-7.67373 0.36871,-9.74773 -0.0154,-2.07397 -0.0768,-3.57185 -0.18436,-4.49364 -0.0922,-0.92175 [...]
+ id="path3084"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 143.92665,295.34532 c -2e-5,1.35194 -0.16902,3.04953 -0.50697,5.09278 l -0.43784,2.78836 c -0.1383,0.87569 -0.20743,1.52861 -0.2074,1.95877 -3e-5,0.4148 0.0998,0.70669 0.29957,0.87568 0.19969,0.169 0.51463,0.32263 0.94482,0.46089 0.41477,0.1229 0.62217,0.26885 0.6222,0.43784 -3e-5,0.16899 -0.35338,0.40712 -1.06004,0.71437 -0.70672,0.30726 -1.52095,0.46089 -2.4427,0.46089 -0.90643,0 -1.40572,-0.0691 -1.49788,-0.2074 -0.0922,-0.1229 -0.11524,-0.36871 -0.0691,-0.73742 0.19969, [...]
+ id="path3086"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 150.49428,284.26101 c -0.2919,-0.30724 -0.43785,-0.70667 -0.43784,-1.19831 -1e-5,-0.50694 0.14594,-0.91406 0.43784,-1.22134 0.30725,-0.30723 0.70669,-0.46086 1.1983,-0.46089 0.50697,3e-5 0.91409,0.15366 1.22135,0.46089 0.30725,0.30728 0.46088,0.7144 0.46089,1.22134 -1e-5,0.49164 -0.15364,0.89107 -0.46089,1.19831 -0.30726,0.30728 -0.71438,0.46091 -1.22135,0.46088 -0.49161,3e-5 -0.89105,-0.1536 -1.1983,-0.46088 m 1.56701,18.1589 c 0,1.67456 0.0845,2.74228 0.25349,3.20316 0.16 [...]
+ id="path3088"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 173.49249,295.34532 c -2e-5,1.35194 -0.16133,3.04953 -0.48393,5.09278 l -0.43784,2.78836 c -0.13829,0.87569 -0.20742,1.47484 -0.2074,1.79746 -2e-5,0.32262 0.0384,0.56843 0.11522,0.73742 0.0768,0.16899 0.17666,0.30726 0.29958,0.41479 0.12288,0.0922 0.39173,0.20741 0.80655,0.34567 0.41478,0.1229 0.62217,0.26885 0.62219,0.43784 -2e-5,0.16899 -0.23046,0.35335 -0.69133,0.55306 -0.95251,0.4148 -2.12009,0.6222 -3.50273,0.6222 -0.44554,0 -0.71439,-0.0691 -0.80655,-0.2074 -0.0768,-0 [...]
+ id="path3090"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 188.30997,303.18038 c -1e-5,0.78351 -0.28423,1.58237 -0.85264,2.3966 -0.55307,0.81424 -1.67456,1.4902 -3.36447,2.0279 -1.67456,0.52234 -2.98808,0.78351 -3.94057,0.78351 -0.93714,0 -1.71297,-0.16899 -2.32748,-0.50698 -0.61451,-0.33798 -0.92177,-0.62987 -0.92177,-0.87568 0,-0.0768 0.0307,-0.16131 0.0922,-0.25349 0.75278,-0.93713 1.14453,-1.43642 1.17526,-1.49788 0.0768,-0.10753 0.23044,-0.13058 0.46088,-0.0691 1.04467,0.36871 1.85891,0.57611 2.4427,0.6222 0.59914,0.0461 1.136 [...]
+ id="path3092"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 194.62411,299.63155 c -1e-5,1.95109 0.33797,3.42593 1.01394,4.42451 0.67596,0.99859 1.45179,1.6131 2.32748,1.84354 0.87567,0.23045 1.85121,0.34567 2.92662,0.34567 0.67596,0 1.22134,-0.13827 1.63615,-0.4148 0.43015,-0.27653 0.9448,-0.89104 1.54397,-1.84354 0.6145,-0.9525 0.92175,-1.62078 0.92177,-2.00486 0.21506,-0.26116 0.49928,-0.43015 0.85264,-0.50697 0.0922,0.24581 0.26883,0.36871 0.53002,0.36871 0.26115,0 0.39173,0.12291 0.39175,0.36871 -2e-5,0.24581 -0.15365,0.66829 -0 [...]
+ id="path3094"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 232.20936,292.94871 c -3e-5,0.30727 -0.18438,0.53771 -0.55307,0.69133 -0.35337,0.13828 -0.97556,0.29191 -1.86658,0.46088 -0.89107,0.16901 -1.51327,0.2535 -1.86659,0.25349 -0.33801,1e-5 -0.73744,-0.12289 -1.19831,-0.36871 -0.4609,-0.24579 -0.76048,-0.36869 -0.89872,-0.36871 -0.19974,2e-5 -0.46859,0.14596 -0.80655,0.43784 -0.33801,0.29191 -0.72976,0.82193 -1.17526,1.59006 -0.43018,0.75279 -0.72208,1.8666 -0.87569,3.34142 -0.13828,1.45948 -0.23046,2.8191 -0.27653,4.07884 -0.03 [...]
+ id="path3096"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 253.91643,299.63155 c -1e-5,1.95109 0.33797,3.42593 1.01394,4.42451 0.67596,0.99859 1.45179,1.6131 2.32748,1.84354 0.87567,0.23045 1.85121,0.34567 2.92662,0.34567 0.67596,0 1.22134,-0.13827 1.63615,-0.4148 0.43015,-0.27653 0.9448,-0.89104 1.54397,-1.84354 0.6145,-0.9525 0.92175,-1.62078 0.92177,-2.00486 0.21506,-0.26116 0.49928,-0.43015 0.85264,-0.50697 0.0922,0.24581 0.26883,0.36871 0.53002,0.36871 0.26115,0 0.39173,0.12291 0.39175,0.36871 -2e-5,0.24581 -0.15365,0.66829 -0 [...]
+ id="path3098"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 281.77697,298.84805 c -1e-5,1.1215 -0.19205,2.12008 -0.5761,2.99576 -0.47627,1.09077 -1.20601,2.18153 -2.18921,3.27229 -1.18296,1.32121 -2.27372,2.25834 -3.27229,2.8114 l -1.4057,0.78351 c -0.0768,0.0461 -0.13828,0.0691 -0.18436,0.0691 -0.0615,0 -0.11523,-0.023 -0.16131,-0.0691 -0.0615,-0.0922 -0.0231,-0.19972 0.11522,-0.32262 l 1.01395,-0.8296 c 0.29188,-0.2458 0.69132,-0.71437 1.1983,-1.4057 0.61451,-0.86032 1.09844,-1.85122 1.4518,-2.97271 0.35333,-1.12149 0.53,-2.2737 0 [...]
+ id="path3100"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 287.12325,284.26101 c -0.2919,-0.30724 -0.43785,-0.70667 -0.43785,-1.19831 0,-0.50694 0.14595,-0.91406 0.43785,-1.22134 0.30725,-0.30723 0.70668,-0.46086 1.1983,-0.46089 0.50697,3e-5 0.91408,0.15366 1.22135,0.46089 0.30725,0.30728 0.46088,0.7144 0.46088,1.22134 0,0.49164 -0.15363,0.89107 -0.46088,1.19831 -0.30727,0.30728 -0.71438,0.46091 -1.22135,0.46088 -0.49162,3e-5 -0.89105,-0.1536 -1.1983,-0.46088 m 1.56701,18.1589 c -1e-5,1.67456 0.0845,2.74228 0.25349,3.20316 0.16898, [...]
+ id="path3102"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 304.19907,303.18038 c -1e-5,0.78351 -0.28422,1.58237 -0.85263,2.3966 -0.55308,0.81424 -1.67457,1.4902 -3.36447,2.0279 -1.67456,0.52234 -2.98808,0.78351 -3.94058,0.78351 -0.93713,0 -1.71296,-0.16899 -2.32747,-0.50698 -0.61452,-0.33798 -0.92177,-0.62987 -0.92177,-0.87568 0,-0.0768 0.0307,-0.16131 0.0922,-0.25349 0.75278,-0.93713 1.14454,-1.43642 1.17526,-1.49788 0.0768,-0.10753 0.23044,-0.13058 0.46089,-0.0691 1.04467,0.36871 1.8589,0.57611 2.4427,0.6222 0.59914,0.0461 1.1368 [...]
+ id="path3104"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 314.45379,305.30045 c -1e-5,0.69133 -0.26118,1.32889 -0.78351,1.91268 -0.52234,0.58379 -1.87428,1.75136 -4.0558,3.50273 -2.16616,1.76673 -3.52577,2.65009 -4.07884,2.6501 -0.13826,-10e-6 -0.28421,-0.0615 -0.43784,-0.18436 -0.16899,-0.10754 -0.25348,-0.25349 -0.25349,-0.43784 10e-6,-0.19972 0.12291,-0.46089 0.36871,-0.78351 0.23045,-0.32262 0.46089,-0.48393 0.69133,-0.48393 0.23044,0 0.75278,-0.17667 1.56701,-0.53002 0.81423,-0.35334 1.6976,-0.94481 2.6501,-1.77441 0.96785,-0 [...]
+ id="path3106"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 360.17301,292.34956 c -0.0768,2.8575 -0.25351,4.28625 -0.53002,4.28624 -0.16901,10e-6 -0.2996,-0.14594 -0.39175,-0.43785 -0.0768,-0.29188 -0.14597,-0.72972 -0.2074,-1.31352 l -7.78897,0.0461 c -5.10048,0.0461 -8.05783,0.31495 -8.87205,0.80655 -0.39945,0.24582 -0.63757,0.76815 -0.71438,1.56701 -0.0615,0.79888 0.0691,1.81283 0.39176,3.04185 0.32261,1.21367 0.62218,2.02022 0.89872,2.41965 0.27653,0.39944 0.71437,0.89873 1.31353,1.49788 0.6145,0.58379 1.38264,1.09845 2.30443,1. [...]
+ id="path3108"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 376.28097,303.98693 c -1e-5,0.49161 -0.34568,1.00627 -1.03699,1.54396 -0.69134,0.52234 -1.70529,1.06004 -3.04185,1.61311 -1.32122,0.5377 -2.3198,0.82191 -2.99576,0.85263 -0.67597,0.0307 -1.29049,0.0461 -1.84354,0.0461 -1.27512,0 -2.24298,-0.30725 -2.90358,-0.92177 -0.66061,-0.62987 -0.99091,-1.09076 -0.99091,-1.38266 0,-0.30725 0.13058,-2.66545 0.39175,-7.0746 0.27653,-4.42449 0.39944,-7.67373 0.36871,-9.74773 -0.0154,-2.07397 -0.0768,-3.57185 -0.18435,-4.49364 -0.0922,-0.9 [...]
+ id="path3110"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 399.21003,295.34532 c -2e-5,1.35194 -0.16901,3.04953 -0.50697,5.09278 l -0.43784,2.78836 c -0.13829,0.87569 -0.20743,1.52861 -0.2074,1.95877 -3e-5,0.4148 0.0998,0.70669 0.29958,0.87568 0.19969,0.169 0.51463,0.32263 0.94481,0.46089 0.41477,0.1229 0.62217,0.26885 0.6222,0.43784 -3e-5,0.16899 -0.35338,0.40712 -1.06004,0.71437 -0.70672,0.30726 -1.52095,0.46089 -2.4427,0.46089 -0.90643,0 -1.40572,-0.0691 -1.49787,-0.2074 -0.0922,-0.1229 -0.11525,-0.36871 -0.0691,-0.73742 0.1997, [...]
+ id="path3112"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 405.77767,284.26101 c -0.2919,-0.30724 -0.43785,-0.70667 -0.43785,-1.19831 0,-0.50694 0.14595,-0.91406 0.43785,-1.22134 0.30725,-0.30723 0.70668,-0.46086 1.1983,-0.46089 0.50697,3e-5 0.91408,0.15366 1.22135,0.46089 0.30725,0.30728 0.46088,0.7144 0.46088,1.22134 0,0.49164 -0.15363,0.89107 -0.46088,1.19831 -0.30727,0.30728 -0.71438,0.46091 -1.22135,0.46088 -0.49162,3e-5 -0.89105,-0.1536 -1.1983,-0.46088 m 1.56701,18.1589 c -10e-6,1.67456 0.0845,2.74228 0.25348,3.20316 0.16899 [...]
+ id="path3114"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 428.77587,295.34532 c -10e-6,1.35194 -0.16132,3.04953 -0.48393,5.09278 l -0.43784,2.78836 c -0.13828,0.87569 -0.20741,1.47484 -0.2074,1.79746 -1e-5,0.32262 0.0384,0.56843 0.11523,0.73742 0.0768,0.16899 0.17665,0.30726 0.29957,0.41479 0.12289,0.0922 0.39174,0.20741 0.80655,0.34567 0.41478,0.1229 0.62218,0.26885 0.6222,0.43784 -2e-5,0.16899 -0.23046,0.35335 -0.69133,0.55306 -0.95252,0.4148 -2.12009,0.6222 -3.50273,0.6222 -0.44554,0 -0.71439,-0.0691 -0.80655,-0.2074 -0.0768,-0 [...]
+ id="path3116"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 443.59338,303.18038 c -2e-5,0.78351 -0.28423,1.58237 -0.85264,2.3966 -0.55308,0.81424 -1.67456,1.4902 -3.36447,2.0279 -1.67456,0.52234 -2.98808,0.78351 -3.94057,0.78351 -0.93714,0 -1.71297,-0.16899 -2.32748,-0.50698 -0.61451,-0.33798 -0.92177,-0.62987 -0.92177,-0.87568 0,-0.0768 0.0307,-0.16131 0.0922,-0.25349 0.75278,-0.93713 1.14453,-1.43642 1.17526,-1.49788 0.0768,-0.10753 0.23044,-0.13058 0.46088,-0.0691 1.04467,0.36871 1.8589,0.57611 2.4427,0.6222 0.59914,0.0461 1.1368 [...]
+ id="path3118"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 449.90751,299.63155 c 0,1.95109 0.33798,3.42593 1.01395,4.42451 0.67596,0.99859 1.45179,1.6131 2.32748,1.84354 0.87567,0.23045 1.85121,0.34567 2.92662,0.34567 0.67596,0 1.22134,-0.13827 1.63615,-0.4148 0.43014,-0.27653 0.9448,-0.89104 1.54397,-1.84354 0.6145,-0.9525 0.92175,-1.62078 0.92177,-2.00486 0.21506,-0.26116 0.49928,-0.43015 0.85264,-0.50697 0.0922,0.24581 0.26883,0.36871 0.53002,0.36871 0.26115,0 0.39173,0.12291 0.39175,0.36871 -2e-5,0.24581 -0.15365,0.66829 -0.460 [...]
+ id="path3120"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 487.49275,292.94871 c -3e-5,0.30727 -0.18438,0.53771 -0.55306,0.69133 -0.35338,0.13828 -0.97557,0.29191 -1.86659,0.46088 -0.89107,0.16901 -1.51327,0.2535 -1.86659,0.25349 -0.338,1e-5 -0.73744,-0.12289 -1.1983,-0.36871 -0.46091,-0.24579 -0.76049,-0.36869 -0.89873,-0.36871 -0.19974,2e-5 -0.46859,0.14596 -0.80655,0.43784 -0.338,0.29191 -0.72976,0.82193 -1.17526,1.59006 -0.43018,0.75279 -0.72207,1.8666 -0.87568,3.34142 -0.13829,1.45948 -0.23046,2.8191 -0.27653,4.07884 -0.0308,1 [...]
+ id="path3122"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 509.19981,299.63155 c 0,1.95109 0.33798,3.42593 1.01395,4.42451 0.67596,0.99859 1.45178,1.6131 2.32747,1.84354 0.87568,0.23045 1.85122,0.34567 2.92663,0.34567 0.67595,0 1.22134,-0.13827 1.63615,-0.4148 0.43014,-0.27653 0.9448,-0.89104 1.54396,-1.84354 0.6145,-0.9525 0.92176,-1.62078 0.92178,-2.00486 0.21506,-0.26116 0.49927,-0.43015 0.85263,-0.50697 0.0922,0.24581 0.26884,0.36871 0.53002,0.36871 0.26115,0 0.39174,0.12291 0.39176,0.36871 -2e-5,0.24581 -0.15365,0.66829 -0.460 [...]
+ id="path3124"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 537.06036,298.84805 c -2e-5,1.1215 -0.19205,2.12008 -0.57611,2.99576 -0.47626,1.09077 -1.206,2.18153 -2.18921,3.27229 -1.18295,1.32121 -2.27371,2.25834 -3.27229,2.8114 l -1.4057,0.78351 c -0.0768,0.0461 -0.13827,0.0691 -0.18435,0.0691 -0.0615,0 -0.11523,-0.023 -0.16131,-0.0691 -0.0615,-0.0922 -0.0231,-0.19972 0.11522,-0.32262 l 1.01395,-0.8296 c 0.29188,-0.2458 0.69131,-0.71437 1.1983,-1.4057 0.6145,-0.86032 1.09843,-1.85122 1.45179,-2.97271 0.35333,-1.12149 0.53001,-2.2737 [...]
+ id="path3126"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 549.18168,298.20281 c -10e-6,0.5838 -0.008,1.22135 -0.023,1.91267 l -0.13827,4.40147 c 0.15362,0.19972 0.53769,0.59147 1.15222,1.17525 0.62986,0.56843 1.17524,0.85265 1.63614,0.85264 0.52232,10e-6 0.96785,-0.0999 1.33657,-0.29957 0.36869,-0.19972 0.55305,-0.28421 0.55306,-0.25349 -10e-6,0.0307 -0.10755,0.16899 -0.32262,0.4148 -0.21509,0.2458 -0.82961,0.60683 -1.84354,1.08308 -1.01396,0.47625 -1.94341,0.71437 -2.78836,0.71437 -0.84497,0 -1.50557,-0.37639 -1.98181,-1.12917 -0 [...]
+ id="path3128"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 556.94761,299.63155 c 0,1.95109 0.33798,3.42593 1.01395,4.42451 0.67596,0.99859 1.45179,1.6131 2.32748,1.84354 0.87567,0.23045 1.85121,0.34567 2.92662,0.34567 0.67596,0 1.22134,-0.13827 1.63615,-0.4148 0.43015,-0.27653 0.9448,-0.89104 1.54397,-1.84354 0.6145,-0.9525 0.92175,-1.62078 0.92177,-2.00486 0.21506,-0.26116 0.49928,-0.43015 0.85264,-0.50697 0.0922,0.24581 0.26883,0.36871 0.53002,0.36871 0.26115,0 0.39173,0.12291 0.39175,0.36871 -2e-5,0.24581 -0.15365,0.66829 -0.460 [...]
+ id="path3130"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 574.78389,304.0791 c 0.59914,1e-5 0.89872,0.61452 0.89872,1.84355 0,0.59915 -0.0384,1.00627 -0.11522,1.22135 -0.0768,0.21508 -0.33799,0.46856 -0.7835,0.76046 -0.44553,0.29189 -0.88337,0.43784 -1.31353,0.43784 -0.44553,0 -0.79119,-0.14595 -1.03699,-0.43784 -0.23045,-0.27653 -0.34567,-0.66061 -0.34567,-1.15222 0,-0.52233 0.16131,-0.98322 0.48393,-1.38266 0.32262,-0.39943 0.70669,-0.71437 1.15222,-0.94481 0.46088,-0.23044 0.81422,-0.34566 1.06004,-0.34567"
+ id="path3132"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 620.59526,299.30893 c -2e-5,0.38408 -0.0615,1.3289 -0.18435,2.83445 -0.10757,1.50557 -0.16902,2.35821 -0.18436,2.55792 -2e-5,0.18436 -0.008,1.50556 -0.023,3.96362 -0.0154,2.47342 -0.0538,3.90984 -0.11522,4.30928 -0.0461,0.39943 -0.13829,1.88195 -0.27653,4.44755 -0.13829,2.58095 -0.61454,5.0851 -1.42875,7.51244 -0.79889,2.42732 -1.87429,4.40144 -3.2262,5.92239 -1.35195,1.5209 -2.74997,2.28136 -4.19407,2.28138 -0.52235,-2e-5 -1.02932,-0.24583 -1.52092,-0.73741 -0.47626,-0.476 [...]
+ id="path3134"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 626.49461,284.26101 c -0.29189,-0.30724 -0.43784,-0.70667 -0.43784,-1.19831 0,-0.50694 0.14595,-0.91406 0.43784,-1.22134 0.30726,-0.30723 0.70669,-0.46086 1.19831,-0.46089 0.50697,3e-5 0.91408,0.15366 1.22135,0.46089 0.30725,0.30728 0.46088,0.7144 0.46088,1.22134 0,0.49164 -0.15363,0.89107 -0.46088,1.19831 -0.30727,0.30728 -0.71438,0.46091 -1.22135,0.46088 -0.49162,3e-5 -0.89105,-0.1536 -1.19831,-0.46088 m 1.56702,18.1589 c -1e-5,1.67456 0.0845,2.74228 0.25348,3.20316 0.168 [...]
+ id="path3136"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 647.16533,292.46478 c -1e-5,0.64525 -0.7912,2.68083 -2.37356,6.10674 -1.58239,3.42592 -2.99577,6.39095 -4.24015,8.8951 -0.55307,1.12148 -0.92946,1.68223 -1.12917,1.68223 -0.33799,0 -0.72974,-0.43784 -1.17526,-1.31353 -1.07541,-2.01253 -2.17385,-4.1326 -3.29533,-6.36022 -1.10613,-2.24297 -2.36589,-4.37073 -3.77927,-6.38327 -0.30726,-0.4916 -0.46089,-0.97553 -0.46088,-1.45179 -1e-5,-0.66059 0.43015,-1.22134 1.29048,-1.68224 0.86031,-0.47623 1.75904,-0.71435 2.69618,-0.71437 0 [...]
+ id="path3138"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 662.2594,303.75648 c -10e-6,0.15364 -0.13828,0.44553 -0.4148,0.87569 -0.26118,0.4148 -0.72206,0.92177 -1.38265,1.52092 -0.64526,0.58379 -1.57471,1.05236 -2.78836,1.4057 -1.19832,0.33799 -2.37357,0.50698 -3.52578,0.50698 -1.06004,0 -2.02022,-0.19204 -2.88054,-0.57611 -0.86032,-0.38407 -1.46715,-0.73742 -1.8205,-1.06004 -0.35335,-0.33798 -0.69133,-0.89104 -1.01395,-1.65919 -0.32262,-0.7835 -0.48393,-2.36587 -0.48393,-4.74712 0,-2.6424 0.49161,-4.60117 1.47484,-5.8763 0.99858, [...]
+ id="path3140"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 99.164101,357.14735 c -3.4e-5,0.0922 -0.530053,0.23812 -1.590056,0.43784 -1.044707,0.18435 -2.219965,0.26117 -3.525778,0.23044 -1.290509,-0.0307 -1.974155,-0.0461 -2.050942,-0.0461 -0.07684,0 -0.483957,0.0768 -1.221348,0.23045 -0.72208,0.16899 -1.282824,0.25348 -1.682234,0.25349 -0.384095,-10e-6 -0.576131,-0.12291 -0.576107,-0.36871 -2.4e-5,-0.23045 0.330277,-0.54538 0.990905,-0.94482 0.660577,-0.39943 0.99856,-0.7835 1.013949,-1.15221 0.01534,-0.36871 -2.6e-5,-1.54397 -0.0 [...]
+ id="path3142"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 125.59591,342.37595 c -0.0768,2.85751 -0.25351,4.28625 -0.53002,4.28624 -0.16901,10e-6 -0.2996,-0.14593 -0.39175,-0.43784 -0.0768,-0.29188 -0.14597,-0.72972 -0.2074,-1.31352 l -7.78897,0.0461 c -5.10048,0.0461 -8.05783,0.31495 -8.87206,0.80655 -0.39944,0.24581 -0.63756,0.76815 -0.71437,1.56701 -0.0615,0.79888 0.0691,1.81282 0.39175,3.04185 0.32262,1.21367 0.62219,2.02022 0.89873,2.41965 0.27652,0.39944 0.71437,0.89873 1.31353,1.49788 0.6145,0.58379 1.38264,1.09844 2.30443,1 [...]
+ id="path3144"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 157.64986,345.25649 c -1e-5,1.01396 -0.0615,1.78979 -0.18435,2.32748 -0.12292,0.52234 -0.29959,1.06772 -0.53002,1.63614 -0.21509,0.55307 -0.55307,1.21367 -1.01395,1.98181 -0.44553,0.75279 -0.98323,1.39034 -1.6131,1.91268 -0.62989,0.50698 -1.02164,0.81423 -1.17526,0.92177 -0.13827,0.10754 -0.33031,0.23045 -0.57611,0.36871 -0.24581,0.13827 -0.43016,0.25349 -0.55306,0.34566 -0.24581,0.19972 -0.2074,0.30726 0.11522,0.32262 0.81423,0.0307 1.79745,0.28422 2.94967,0.76046 1.15221, [...]
+ id="path3146"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 178.75844,348.36747 c -1e-5,1.56702 -0.30727,2.96504 -0.92177,4.19406 -0.61453,1.21367 -1.39803,2.25835 -2.35052,3.13403 -0.95251,0.87568 -1.97414,1.51324 -3.06489,1.91267 -1.09077,0.38408 -1.97414,0.57611 -2.65009,0.57611 -0.32263,0 -0.92178,-0.0461 -1.79746,-0.13826 -0.86032,-0.0768 -1.72064,-0.52234 -2.58096,-1.33657 -0.86032,-0.8296 -1.46716,-1.55933 -1.8205,-2.18921 -0.33798,-0.64524 -0.50697,-1.64382 -0.50697,-2.99576 0,-1.36729 0.10754,-2.45037 0.32262,-3.24925 0.215 [...]
+ id="path3148"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 198.02347,348.36747 c -1e-5,1.56702 -0.30727,2.96504 -0.92177,4.19406 -0.61453,1.21367 -1.39803,2.25835 -2.35052,3.13403 -0.95251,0.87568 -1.97414,1.51324 -3.06489,1.91267 -1.09077,0.38408 -1.97414,0.57611 -2.65009,0.57611 -0.32263,0 -0.92178,-0.0461 -1.79746,-0.13826 -0.86032,-0.0768 -1.72064,-0.52234 -2.58096,-1.33657 -0.86032,-0.8296 -1.46716,-1.55933 -1.8205,-2.18921 -0.33798,-0.64524 -0.50698,-1.64382 -0.50697,-2.99576 -1e-5,-1.36729 0.10753,-2.45037 0.32262,-3.24925 0 [...]
+ id="path3150"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 217.28851,348.36747 c -2e-5,1.56702 -0.30727,2.96504 -0.92177,4.19406 -0.61453,1.21367 -1.39804,2.25835 -2.35052,3.13403 -0.95251,0.87568 -1.97414,1.51324 -3.06489,1.91267 -1.09077,0.38408 -1.97414,0.57611 -2.6501,0.57611 -0.32262,0 -0.92177,-0.0461 -1.79745,-0.13826 -0.86033,-0.0768 -1.72065,-0.52234 -2.58096,-1.33657 -0.86033,-0.8296 -1.46716,-1.55933 -1.8205,-2.18921 -0.33799,-0.64524 -0.50698,-1.64382 -0.50698,-2.99576 0,-1.36729 0.10754,-2.45037 0.32262,-3.24925 0.2150 [...]
+ id="path3152"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 250.37945,340.62459 c 0.67595,10e-6 1.3596,0.16132 2.05094,0.48393 0.69132,0.30727 1.29815,0.51467 1.8205,0.62219 0.52232,0.10756 0.78349,0.27655 0.78351,0.50698 -2e-5,0.16901 -0.49163,0.65294 -1.47483,1.45179 -0.96788,0.79888 -1.53631,1.31354 -1.70528,1.54397 -0.15365,0.21509 -0.57612,1.07541 -1.26744,2.58096 -0.69134,1.4902 -1.42108,2.99576 -2.18921,4.51668 -0.75279,1.50557 -1.34426,2.72691 -1.77441,3.66404 -0.43017,0.92178 -0.9141,1.92804 -1.45179,3.01881 -0.53771,1.1061 [...]
+ id="path3154"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 276.8343,341.2007 c 0.39941,1e-5 0.82957,0.23045 1.29048,0.69132 0.46087,0.46091 0.78349,1.23673 0.96786,2.32748 0.1997,1.09077 0.39173,3.0649 0.57611,5.92238 0.18433,2.8575 0.47622,4.64727 0.87569,5.36932 0.41477,0.72206 1.229,1.08309 2.44269,1.08309 0.67594,0 1.16755,-0.0614 1.47484,-0.18436 0.30722,-0.1229 0.76043,-0.46856 1.35961,-1.03699 0.59912,-0.56842 1.01392,-0.85264 1.24439,-0.85264 0.12287,0 0.18432,0.12291 0.18436,0.36871 -4e-5,0.24581 -0.39179,0.62988 -1.17526, [...]
+ id="path3156"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 299.85556,342.53726 c -1e-5,0.30728 -0.17669,0.53772 -0.53002,0.69133 -0.35336,0.13828 -0.97555,0.29191 -1.86658,0.46089 -0.89106,0.169 -1.51326,0.2535 -1.86659,0.25349 -0.35336,10e-6 -0.76047,-0.12289 -1.22135,-0.36871 -0.4609,-0.24579 -0.75279,-0.3687 -0.87568,-0.36871 -0.21509,10e-6 -0.49162,0.15364 -0.8296,0.46088 -0.33799,0.29191 -0.67597,0.72975 -1.01395,1.31353 -0.33799,0.56844 -0.59147,1.09078 -0.76046,1.56701 -0.169,0.4609 -0.29958,1.4134 -0.39175,2.85749 -0.0768,1 [...]
+ id="path3158"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 309.44198,353.20677 c -10e-6,0.78351 -0.28422,1.58238 -0.85264,2.39661 -0.55307,0.81423 -1.67456,1.4902 -3.36447,2.0279 -1.67455,0.52234 -2.98808,0.7835 -3.94057,0.78351 -0.93714,-10e-6 -1.71296,-0.169 -2.32747,-0.50698 -0.61452,-0.33798 -0.92178,-0.62988 -0.92178,-0.87568 0,-0.0768 0.0307,-0.16131 0.0922,-0.25349 0.75278,-0.93713 1.14453,-1.43643 1.17526,-1.49788 0.0768,-0.10754 0.23044,-0.13058 0.46089,-0.0691 1.04467,0.36871 1.8589,0.57611 2.44269,0.62219 0.59915,0.0461 [...]
+ id="path3160"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 340.64331,348.22921 c -2e-5,0.58379 -0.008,1.22135 -0.0231,1.91267 l -0.13826,4.40146 c 0.15361,0.19972 0.53768,0.59148 1.15221,1.17526 0.62987,0.56843 1.17525,0.85264 1.63615,0.85264 0.52232,0 0.96784,-0.0999 1.33657,-0.29957 0.36869,-0.19972 0.55304,-0.28422 0.55306,-0.25349 -2e-5,0.0307 -0.10756,0.16899 -0.32262,0.4148 -0.2151,0.2458 -0.82961,0.60683 -1.84354,1.08308 -1.01397,0.47625 -1.94342,0.71437 -2.78836,0.71437 -0.84497,0 -1.50558,-0.37639 -1.98181,-1.12917 -0.4609 [...]
+ id="path3162"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 360.92228,345.37171 c -10e-6,1.35195 -0.16132,3.04954 -0.48393,5.09279 l -0.43784,2.78836 c -0.13828,0.87569 -0.20741,1.47484 -0.2074,1.79746 -1e-5,0.32262 0.0384,0.56843 0.11522,0.73742 0.0768,0.16899 0.17666,0.30725 0.29958,0.41479 0.12289,0.0922 0.39174,0.2074 0.80655,0.34567 0.41478,0.1229 0.62218,0.26885 0.6222,0.43784 -2e-5,0.16899 -0.23046,0.35335 -0.69133,0.55306 -0.95252,0.4148 -2.12009,0.6222 -3.50274,0.6222 -0.44553,0 -0.71438,-0.0691 -0.80655,-0.2074 -0.0768,-0. [...]
+ id="path3164"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 383.80526,357.05517 c -2e-5,0.19972 -0.46859,0.53002 -1.4057,0.99091 -0.92179,0.46088 -2.16618,0.69132 -3.73318,0.69133 -0.47626,-1e-5 -0.82961,-0.0845 -1.06004,-0.25349 -0.23045,-0.15363 -0.26886,-0.5377 -0.11522,-1.15222 0.15362,-0.62987 0.12289,-1.01394 -0.0922,-1.15221 -0.2151,-0.13827 -0.91411,0.0922 -2.09704,0.69133 -1.16758,0.58379 -1.9895,0.93713 -2.46574,1.06004 -0.47625,0.1229 -0.9525,0.18435 -1.42874,0.18435 -2.67315,0 -4.53205,-0.42248 -5.57672,-1.26744 -1.04468 [...]
+ id="path3166"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 413.85437,348.22921 c -2e-5,0.58379 -0.008,1.22135 -0.0231,1.91267 l -0.13826,4.40146 c 0.15361,0.19972 0.53768,0.59148 1.15221,1.17526 0.62987,0.56843 1.17525,0.85264 1.63615,0.85264 0.52232,0 0.96784,-0.0999 1.33657,-0.29957 0.36869,-0.19972 0.55304,-0.28422 0.55306,-0.25349 -2e-5,0.0307 -0.10756,0.16899 -0.32262,0.4148 -0.2151,0.2458 -0.82961,0.60683 -1.84354,1.08308 -1.01397,0.47625 -1.94342,0.71437 -2.78836,0.71437 -0.84497,0 -1.50558,-0.37639 -1.98181,-1.12917 -0.4609 [...]
+ id="path3168"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 454.04295,348.92053 c -2e-5,1.30586 -0.0768,2.20458 -0.23044,2.69619 -0.13829,0.47625 -0.47627,1.11381 -1.01395,1.91267 -0.53772,0.78351 -1.26746,1.52861 -2.18921,2.2353 -0.90643,0.70669 -1.79747,1.29048 -2.67314,1.75137 -0.86033,0.46088 -2.03559,0.69133 -3.52578,0.69133 -0.61452,0 -1.8205,-0.16131 -3.61795,-0.48393 -0.61452,-0.10754 -0.96019,0.0999 -1.037,0.62219 -0.15363,1.01395 -0.28421,2.81908 -0.39175,5.41541 -0.0922,2.59632 -0.16899,4.16333 -0.23044,4.70104 -0.0461,0. [...]
+ id="path3170"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 471.37226,348.36747 c -10e-6,1.56702 -0.30727,2.96504 -0.92177,4.19406 -0.61453,1.21367 -1.39803,2.25835 -2.35052,3.13403 -0.95251,0.87568 -1.97414,1.51324 -3.06489,1.91267 -1.09077,0.38408 -1.97414,0.57611 -2.65009,0.57611 -0.32263,0 -0.92178,-0.0461 -1.79746,-0.13826 -0.86032,-0.0768 -1.72064,-0.52234 -2.58096,-1.33657 -0.86032,-0.8296 -1.46716,-1.55933 -1.8205,-2.18921 -0.33798,-0.64524 -0.50698,-1.64382 -0.50698,-2.99576 0,-1.36729 0.10754,-2.45037 0.32262,-3.24925 0.21 [...]
+ id="path3172"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 476.6955,334.28741 c -0.2919,-0.30724 -0.43785,-0.70667 -0.43784,-1.19831 -10e-6,-0.50695 0.14594,-0.91406 0.43784,-1.22135 0.30725,-0.30723 0.70668,-0.46085 1.1983,-0.46088 0.50697,3e-5 0.91409,0.15365 1.22135,0.46088 0.30725,0.30729 0.46088,0.7144 0.46088,1.22135 0,0.49164 -0.15363,0.89107 -0.46088,1.19831 -0.30726,0.30728 -0.71438,0.4609 -1.22135,0.46088 -0.49162,2e-5 -0.89105,-0.1536 -1.1983,-0.46088 m 1.56701,18.1589 c -1e-5,1.67456 0.0845,2.74228 0.25349,3.20316 0.168 [...]
+ id="path3174"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 499.69371,345.37171 c -2e-5,1.35195 -0.16133,3.04954 -0.48393,5.09279 l -0.43785,2.78836 c -0.13828,0.87569 -0.20741,1.47484 -0.20739,1.79746 -2e-5,0.32262 0.0384,0.56843 0.11522,0.73742 0.0768,0.16899 0.17665,0.30725 0.29957,0.41479 0.12289,0.0922 0.39174,0.2074 0.80655,0.34567 0.41478,0.1229 0.62218,0.26885 0.6222,0.43784 -2e-5,0.16899 -0.23046,0.35335 -0.69133,0.55306 -0.95251,0.4148 -2.12009,0.6222 -3.50273,0.6222 -0.44554,0 -0.71439,-0.0691 -0.80655,-0.2074 -0.0768,-0. [...]
+ id="path3176"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 507.45962,349.65795 c 0,1.95109 0.33798,3.42593 1.01395,4.42451 0.67596,0.99859 1.45179,1.6131 2.32748,1.84354 0.87567,0.23045 1.85121,0.34567 2.92662,0.34567 0.67596,0 1.22134,-0.13827 1.63615,-0.4148 0.43014,-0.27653 0.9448,-0.89105 1.54397,-1.84355 0.6145,-0.95249 0.92175,-1.62077 0.92177,-2.00485 0.21506,-0.26116 0.49927,-0.43015 0.85264,-0.50697 0.0922,0.24581 0.26883,0.36871 0.53002,0.3687 0.26115,10e-6 0.39173,0.12291 0.39175,0.36871 -2e-5,0.24581 -0.15365,0.66829 -0 [...]
+ id="path3178"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 532.69314,340.62459 c 0.67595,10e-6 1.3596,0.16132 2.05095,0.48393 0.69131,0.30727 1.29814,0.51467 1.82049,0.62219 0.52232,0.10756 0.78349,0.27655 0.78351,0.50698 -2e-5,0.16901 -0.49163,0.65294 -1.47483,1.45179 -0.96788,0.79888 -1.53631,1.31354 -1.70528,1.54397 -0.15365,0.21509 -0.57612,1.07541 -1.26744,2.58096 -0.69134,1.4902 -1.42108,2.99576 -2.18921,4.51668 -0.75279,1.50557 -1.34426,2.72691 -1.77441,3.66404 -0.43017,0.92178 -0.9141,1.92804 -1.45179,3.01881 -0.53771,1.106 [...]
+ id="path3180"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 572.95088,348.87445 c -2e-5,1.12149 -0.19205,2.12008 -0.57611,2.99575 -0.47626,1.09077 -1.206,2.18154 -2.18921,3.2723 -1.18295,1.3212 -2.27371,2.25834 -3.27229,2.8114 l -1.4057,0.78351 c -0.0768,0.0461 -0.13828,0.0691 -0.18435,0.0691 -0.0615,0 -0.11524,-0.0231 -0.16131,-0.0691 -0.0615,-0.0922 -0.0231,-0.19972 0.11522,-0.32262 l 1.01395,-0.8296 c 0.29188,-0.2458 0.69131,-0.71437 1.1983,-1.4057 0.6145,-0.86032 1.09843,-1.85122 1.45179,-2.97272 0.35333,-1.12148 0.53001,-2.2736 [...]
+ id="path3182"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 585.07217,348.22921 c -10e-6,0.58379 -0.008,1.22135 -0.023,1.91267 l -0.13827,4.40146 c 0.15362,0.19972 0.53769,0.59148 1.15222,1.17526 0.62986,0.56843 1.17524,0.85264 1.63614,0.85264 0.52232,0 0.96785,-0.0999 1.33657,-0.29957 0.36869,-0.19972 0.55305,-0.28422 0.55306,-0.25349 -10e-6,0.0307 -0.10755,0.16899 -0.32262,0.4148 -0.21509,0.2458 -0.82961,0.60683 -1.84354,1.08308 -1.01396,0.47625 -1.94342,0.71437 -2.78836,0.71437 -0.84497,0 -1.50557,-0.37639 -1.98181,-1.12917 -0.46 [...]
+ id="path3184"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 592.8381,349.65795 c 0,1.95109 0.33798,3.42593 1.01395,4.42451 0.67596,0.99859 1.45179,1.6131 2.32748,1.84354 0.87567,0.23045 1.85121,0.34567 2.92662,0.34567 0.67596,0 1.22134,-0.13827 1.63615,-0.4148 0.43014,-0.27653 0.9448,-0.89105 1.54396,-1.84355 0.6145,-0.95249 0.92176,-1.62077 0.92178,-2.00485 0.21506,-0.26116 0.49927,-0.43015 0.85264,-0.50697 0.0922,0.24581 0.26883,0.36871 0.53001,0.3687 0.26116,10e-6 0.39174,0.12291 0.39176,0.36871 -2e-5,0.24581 -0.15365,0.66829 -0. [...]
+ id="path3186"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 632.93451,348.22921 c -2e-5,0.58379 -0.008,1.22135 -0.0231,1.91267 l -0.13826,4.40146 c 0.15361,0.19972 0.53768,0.59148 1.15221,1.17526 0.62986,0.56843 1.17525,0.85264 1.63615,0.85264 0.52232,0 0.96784,-0.0999 1.33657,-0.29957 0.36869,-0.19972 0.55304,-0.28422 0.55306,-0.25349 -2e-5,0.0307 -0.10756,0.16899 -0.32262,0.4148 -0.2151,0.2458 -0.82961,0.60683 -1.84355,1.08308 -1.01396,0.47625 -1.94341,0.71437 -2.78836,0.71437 -0.84496,0 -1.50557,-0.37639 -1.98181,-1.12917 -0.4608 [...]
+ id="path3188"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 653.21351,345.37171 c -1e-5,1.35195 -0.16132,3.04954 -0.48393,5.09279 l -0.43784,2.78836 c -0.13828,0.87569 -0.20741,1.47484 -0.2074,1.79746 -10e-6,0.32262 0.0384,0.56843 0.11522,0.73742 0.0768,0.16899 0.17666,0.30725 0.29958,0.41479 0.12289,0.0922 0.39174,0.2074 0.80655,0.34567 0.41478,0.1229 0.62218,0.26885 0.6222,0.43784 -2e-5,0.16899 -0.23046,0.35335 -0.69133,0.55306 -0.95252,0.4148 -2.12009,0.6222 -3.50274,0.6222 -0.44553,0 -0.71438,-0.0691 -0.80655,-0.2074 -0.0768,-0. [...]
+ id="path3190"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 676.09646,357.05517 c -2e-5,0.19972 -0.46859,0.53002 -1.4057,0.99091 -0.92179,0.46088 -2.16618,0.69132 -3.73318,0.69133 -0.47626,-1e-5 -0.82961,-0.0845 -1.06004,-0.25349 -0.23045,-0.15363 -0.26886,-0.5377 -0.11522,-1.15222 0.15362,-0.62987 0.12289,-1.01394 -0.0922,-1.15221 -0.21509,-0.13827 -0.9141,0.0922 -2.09703,0.69133 -1.16759,0.58379 -1.9895,0.93713 -2.46574,1.06004 -0.47625,0.1229 -0.9525,0.18435 -1.42874,0.18435 -2.67315,0 -4.53205,-0.42248 -5.57672,-1.26744 -1.04468 [...]
+ id="path3192"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 247.47587,406.96635 c 0.0922,0 0.16898,0.0384 0.23044,0.11522 0.0768,0.0768 0.11521,0.16899 0.11522,0.27653 -1e-5,0.0922 -0.0384,0.16899 -0.11522,0.23044 -0.0768,0.0615 -0.16132,0.0922 -0.25348,0.0922 -1.52094,0.21508 -2.41198,0.33798 -2.67314,0.36871 -0.24582,0.0461 -0.56844,0.023 -0.96786,-0.0691 -0.38408,-0.0768 -0.76047,-0.0845 -1.12917,-0.0231 -0.35336,0.0768 -0.68366,0.0999 -0.99091,0.0691 -0.30726,-0.0154 -0.59148,0.008 -0.85264,0.0691 -0.24581,0.0768 -0.69133,0.0922 [...]
+ id="path3194"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 253.39825,377.83836 c -0.2919,1.13688 -0.72206,2.98042 -1.29048,5.53063 -0.6606,3.48739 -0.99091,5.49992 -0.9909,6.0376 -0.0307,0.23046 -0.26117,0.39177 -0.69133,0.48393 -0.10754,0.0154 -0.2074,0.0231 -0.29958,0.0231 -0.26117,2e-5 -0.44552,-0.0691 -0.55306,-0.2074 0,0.0307 0,0.0461 0,0.0461 -0.0307,2e-5 -0.13059,-0.89871 -0.29957,-2.69619 -0.24581,-2.73456 -0.36872,-5.36161 -0.36871,-7.88114 0.56842,-1.67453 1.40569,-2.5118 2.51183,-2.51183 1.06003,3e-5 1.72063,0.39178 1.98 [...]
+ id="path3196"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 270.05928,404.03972 c -10e-6,0.49162 -0.34568,1.00627 -1.03699,1.54397 -0.69134,0.52234 -1.70529,1.06004 -3.04185,1.6131 -1.32121,0.5377 -2.3198,0.82191 -2.99576,0.85264 -0.67597,0.0307 -1.29048,0.0461 -1.84354,0.0461 -1.27512,0 -2.24298,-0.30726 -2.90358,-0.92177 -0.66061,-0.62988 -0.99091,-1.09077 -0.99091,-1.38266 0,-0.30726 0.13058,-2.66545 0.39176,-7.0746 0.27652,-4.42449 0.39943,-7.67373 0.3687,-9.74774 -0.0154,-2.07396 -0.0768,-3.57184 -0.18435,-4.49364 -0.0922,-0.92 [...]
+ id="path3198"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 281.21272,404.03972 c -10e-6,0.49162 -0.34568,1.00627 -1.03699,1.54397 -0.69134,0.52234 -1.70529,1.06004 -3.04185,1.6131 -1.32121,0.5377 -2.3198,0.82191 -2.99576,0.85264 -0.67597,0.0307 -1.29048,0.0461 -1.84354,0.0461 -1.27512,0 -2.24298,-0.30726 -2.90358,-0.92177 -0.66061,-0.62988 -0.99091,-1.09077 -0.99091,-1.38266 0,-0.30726 0.13059,-2.66545 0.39176,-7.0746 0.27652,-4.42449 0.39943,-7.67373 0.3687,-9.74774 -0.0154,-2.07396 -0.0768,-3.57184 -0.18435,-4.49364 -0.0922,-0.92 [...]
+ id="path3200"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 316.35461,405.28411 c -2e-5,0.49162 -0.5454,1.06772 -1.63614,1.72833 -1.07542,0.64524 -1.76675,0.96786 -2.07399,0.96786 -0.30727,0 -1.34427,-0.53002 -3.11098,-1.59006 -1.75138,-1.06003 -3.25694,-2.28138 -4.51668,-3.66404 -1.2444,-1.39802 -1.99718,-2.09703 -2.25834,-2.09703 l -0.99091,0 c -0.69133,0 -1.06004,0.5377 -1.10613,1.6131 -0.0154,0.12291 -0.0154,0.88337 0,2.28138 0.0154,0.90641 0.26885,1.48252 0.76047,1.72832 0.4916,0.23045 0.76045,0.36103 0.80655,0.39176 0.0614,0.0 [...]
+ id="path3202"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 320.13387,384.3138 c -0.2919,-0.30723 -0.43784,-0.70666 -0.43784,-1.1983 0,-0.50695 0.14594,-0.91406 0.43784,-1.22135 0.30725,-0.30723 0.70669,-0.46086 1.1983,-0.46088 0.50697,2e-5 0.91409,0.15365 1.22135,0.46088 0.30725,0.30729 0.46088,0.7144 0.46089,1.22135 -10e-6,0.49164 -0.15364,0.89107 -0.46089,1.1983 -0.30726,0.30728 -0.71438,0.46091 -1.22135,0.46089 -0.49161,2e-5 -0.89105,-0.15361 -1.1983,-0.46089 m 1.56701,18.15891 c 0,1.67456 0.0845,2.74227 0.25349,3.20316 0.16899, [...]
+ id="path3204"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 342.02595,401.52789 c -1e-5,1.45948 -0.46858,2.61169 -1.4057,3.45665 -0.93715,0.84496 -2.03559,1.60542 -3.29533,2.28138 -1.24441,0.66061 -2.942,0.99091 -5.09279,0.99091 -1.35194,0 -2.60401,-0.45321 -3.75622,-1.35961 -1.15222,-0.92177 -1.72833,-2.50415 -1.72833,-4.74713 0,-2.08934 0.28422,-3.85607 0.85264,-5.30019 0.58379,-1.45946 1.25976,-2.57326 2.0279,-3.34142 0.7835,-0.76813 1.78977,-1.40569 3.0188,-1.91268 1.24439,-0.50696 2.3582,-0.76044 3.34143,-0.76046 0.96785,2e-5 1 [...]
+ id="path3206"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 361.15272,405.28411 c -2e-5,0.49162 -0.5454,1.06772 -1.63614,1.72833 -1.07542,0.64524 -1.76675,0.96786 -2.07399,0.96786 -0.30727,0 -1.34427,-0.53002 -3.11098,-1.59006 -1.75138,-1.06003 -3.25694,-2.28138 -4.51668,-3.66404 -1.2444,-1.39802 -1.99718,-2.09703 -2.25834,-2.09703 l -0.99091,0 c -0.69133,0 -1.06004,0.5377 -1.10612,1.6131 -0.0154,0.12291 -0.0154,0.88337 0,2.28138 0.0154,0.90641 0.26884,1.48252 0.76046,1.72832 0.4916,0.23045 0.76045,0.36103 0.80655,0.39176 0.0614,0.0 [...]
+ id="path3208"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 396.47897,398.90084 c -1e-5,1.1215 -0.19205,2.12009 -0.5761,2.99576 -0.47627,1.09077 -1.20601,2.18153 -2.18921,3.27229 -1.18296,1.32121 -2.27372,2.25834 -3.27229,2.81141 l -1.4057,0.7835 c -0.0768,0.0461 -0.13828,0.0691 -0.18436,0.0691 -0.0615,0 -0.11523,-0.0231 -0.16131,-0.0691 -0.0615,-0.0922 -0.0231,-0.19971 0.11522,-0.32262 l 1.01395,-0.82959 c 0.29188,-0.24581 0.69132,-0.71437 1.1983,-1.4057 0.61451,-0.86032 1.09844,-1.85123 1.4518,-2.97272 0.35333,-1.12148 0.53,-2.273 [...]
+ id="path3210"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 401.82525,384.3138 c -0.2919,-0.30723 -0.43785,-0.70666 -0.43785,-1.1983 0,-0.50695 0.14595,-0.91406 0.43785,-1.22135 0.30725,-0.30723 0.70668,-0.46086 1.1983,-0.46088 0.50697,2e-5 0.91408,0.15365 1.22135,0.46088 0.30725,0.30729 0.46088,0.7144 0.46088,1.22135 0,0.49164 -0.15363,0.89107 -0.46088,1.1983 -0.30727,0.30728 -0.71438,0.46091 -1.22135,0.46089 -0.49162,2e-5 -0.89105,-0.15361 -1.1983,-0.46089 m 1.56701,18.15891 c -1e-5,1.67456 0.0845,2.74227 0.25349,3.20316 0.16898,0 [...]
+ id="path3212"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 418.90107,403.23317 c -1e-5,0.78351 -0.28422,1.58238 -0.85263,2.39661 -0.55308,0.81423 -1.67457,1.4902 -3.36447,2.0279 -1.67456,0.52233 -2.98808,0.7835 -3.94058,0.7835 -0.93713,0 -1.71296,-0.16899 -2.32747,-0.50697 -0.61452,-0.33798 -0.92177,-0.62988 -0.92177,-0.87568 0,-0.0768 0.0307,-0.16131 0.0922,-0.25349 0.75278,-0.93713 1.14454,-1.43643 1.17526,-1.49788 0.0768,-0.10754 0.23044,-0.13058 0.46089,-0.0691 1.04467,0.36871 1.8589,0.57611 2.4427,0.62219 0.59914,0.0461 1.1368 [...]
+ id="path3214"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 450.10239,398.2556 c -2e-5,0.5838 -0.008,1.22136 -0.0231,1.91268 l -0.13826,4.40146 c 0.15361,0.19972 0.53768,0.59147 1.15221,1.17526 0.62986,0.56843 1.17525,0.85264 1.63615,0.85264 0.52232,0 0.96784,-0.0999 1.33657,-0.29958 0.36869,-0.19971 0.55304,-0.28421 0.55306,-0.25348 -2e-5,0.0307 -0.10756,0.16899 -0.32262,0.41479 -0.2151,0.24581 -0.82961,0.60684 -1.84355,1.08309 -1.01396,0.47624 -1.94341,0.71437 -2.78836,0.71437 -0.84496,0 -1.50557,-0.37639 -1.9818,-1.12917 -0.4609, [...]
+ id="path3216"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 468.4226,392.56366 c -2e-5,0.30727 -0.17669,0.53772 -0.53002,0.69133 -0.35336,0.13828 -0.97556,0.29191 -1.86659,0.46089 -0.89106,0.169 -1.51325,0.2535 -1.86659,0.25348 -0.35335,2e-5 -0.76047,-0.12288 -1.22135,-0.3687 -0.46089,-0.2458 -0.75278,-0.3687 -0.87568,-0.36871 -0.21509,1e-5 -0.49162,0.15364 -0.82959,0.46088 -0.33799,0.29191 -0.67598,0.72975 -1.01395,1.31353 -0.33799,0.56844 -0.59148,1.09077 -0.76046,1.56701 -0.169,0.4609 -0.29959,1.41339 -0.39176,2.85749 -0.0768,1.4 [...]
+ id="path3218"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 478.00903,403.23317 c -10e-6,0.78351 -0.28422,1.58238 -0.85264,2.39661 -0.55307,0.81423 -1.67456,1.4902 -3.36447,2.0279 -1.67455,0.52233 -2.98808,0.7835 -3.94057,0.7835 -0.93714,0 -1.71296,-0.16899 -2.32747,-0.50697 -0.61452,-0.33798 -0.92178,-0.62988 -0.92178,-0.87568 0,-0.0768 0.0307,-0.16131 0.0922,-0.25349 0.75278,-0.93713 1.14453,-1.43643 1.17526,-1.49788 0.0768,-0.10754 0.23044,-0.13058 0.46089,-0.0691 1.04467,0.36871 1.8589,0.57611 2.44269,0.62219 0.59915,0.0461 1.13 [...]
+ id="path3220"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 494.94659,403.80928 c -2e-5,0.15363 -0.13829,0.44553 -0.4148,0.87568 -0.26119,0.4148 -0.72207,0.92178 -1.38266,1.52093 -0.64525,0.58379 -1.57471,1.05235 -2.78836,1.4057 -1.19831,0.33798 -2.37357,0.50697 -3.52578,0.50697 -1.06004,0 -2.02022,-0.19203 -2.88053,-0.5761 -0.86033,-0.38408 -1.46716,-0.73742 -1.8205,-1.06004 -0.35335,-0.33798 -0.69133,-0.89105 -1.01395,-1.65919 -0.32262,-0.7835 -0.48393,-2.36588 -0.48393,-4.74713 0,-2.6424 0.49161,-4.60116 1.47483,-5.87629 0.99858, [...]
+ id="path3222"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 503.10426,383.94509 c -1e-5,2.85752 -0.23813,6.67519 -0.71437,11.45302 -0.21509,2.36589 -0.68366,4.50901 -1.40571,6.42936 -0.0614,0.0922 -0.21508,0.10755 -0.46088,0.0461 -0.23045,-0.0307 -0.3764,-0.0922 -0.43784,-0.18436 0.0307,-0.95249 -1e-5,-3.95592 -0.0922,-9.01032 -0.0615,-2.84211 -0.7067,-5.50756 -1.93572,-7.99637 l 0.85264,-2.44269 c 0.21507,-0.59913 0.68364,-0.8987 1.4057,-0.89873 1.8589,3e-5 2.78835,0.86803 2.78836,2.604 m -0.36871,21.66164 c -10e-6,0.59916 -0.13827 [...]
+ id="path3224"
+ style="font-size:47.19472122px;text-align:center;word-spacing:8.50268078px;text-anchor:middle" />
+ <path
+ d="m 373.10108,449.6877 c -1e-5,-0.86031 2.21224,-1.50555 6.63675,-1.93572 2.02789,-0.1997 3.42591,-0.43783 4.19407,-0.71437 0.29188,-0.10753 0.60682,-0.0691 0.94481,0.11522 l 0.50698,0.29958 -0.50698,0.39175 c -0.41481,0.33799 -1.02164,0.59916 -1.8205,0.78351 -0.78351,0.18436 -2.38125,0.44553 -4.79321,0.7835 -1.01396,0.13828 -1.84355,0.24582 -2.48879,0.32262 -0.62988,0.0768 -1.15221,0.13059 -1.56701,0.16131 -0.39943,0.0154 -0.68365,0.008 -0.85264,-0.023 -0.16899,-0.0307 -0.2534 [...]
+ id="path3226"
+ style="font-size:47.19472122px;text-align:end;word-spacing:8.50268078px;text-anchor:end" />
+ <path
+ d="m 430.04287,442.42875 c -0.0768,2.85751 -0.25351,4.28625 -0.53002,4.28624 -0.16902,10e-6 -0.2996,-0.14594 -0.39175,-0.43784 -0.0768,-0.29189 -0.14597,-0.72973 -0.2074,-1.31353 l -7.78897,0.0461 c -5.10049,0.0461 -8.05784,0.31495 -8.87206,0.80655 -0.39944,0.24582 -0.63756,0.76816 -0.71437,1.56701 -0.0615,0.79888 0.0691,1.81283 0.39175,3.04185 0.32261,1.21367 0.62219,2.02022 0.89873,2.41965 0.27652,0.39944 0.71436,0.89873 1.31352,1.49788 0.61451,0.58379 1.38265,1.09845 2.30443, [...]
+ id="path3228"
+ style="font-size:47.19472122px;text-align:end;word-spacing:8.50268078px;text-anchor:end" />
+ <path
+ d="m 452.21148,457.10797 c -2e-5,0.19971 -0.46858,0.53002 -1.4057,0.9909 -0.92179,0.46089 -2.16618,0.69133 -3.73317,0.69133 -0.47627,0 -0.82961,-0.0845 -1.06004,-0.25349 -0.23046,-0.15363 -0.26887,-0.5377 -0.11522,-1.15221 0.15361,-0.62988 0.12289,-1.01395 -0.0922,-1.15222 -0.21509,-0.13826 -0.9141,0.0922 -2.09703,0.69133 -1.16759,0.58379 -1.9895,0.93714 -2.46574,1.06004 -0.47626,0.1229 -0.95251,0.18435 -1.42875,0.18435 -2.67314,0 -4.53205,-0.42247 -5.57672,-1.26743 -1.04467,-0. [...]
+ id="path3230"
+ style="font-size:47.19472122px;text-align:end;word-spacing:8.50268078px;text-anchor:end" />
+ <path
+ d="m 479.31158,442.54397 c -3e-5,0.64526 -0.76049,2.59634 -2.28138,5.85325 -2.1201,4.53205 -3.56421,7.58158 -4.33233,9.14859 -0.55309,1.12149 -0.92948,1.68223 -1.12917,1.68223 -0.32264,0 -0.7144,-0.43784 -1.17526,-1.31352 -0.73744,-1.35193 -1.54399,-2.92663 -2.41965,-4.72408 -0.79889,-1.62846 -1.40572,-2.78067 -1.8205,-3.45665 -0.16901,-0.26116 -0.31496,-0.39174 -0.43784,-0.39175 -0.13828,10e-6 -0.27655,0.13827 -0.4148,0.4148 l -3.71013,7.78897 c -0.55308,1.12149 -0.92947,1.6822 [...]
+ id="path3232"
+ style="font-size:47.19472122px;text-align:end;word-spacing:8.50268078px;text-anchor:end" />
+ <path
+ d="m 484.6809,434.3402 c -0.29189,-0.30723 -0.43784,-0.70667 -0.43784,-1.1983 0,-0.50695 0.14595,-0.91407 0.43784,-1.22135 0.30726,-0.30723 0.70669,-0.46086 1.19831,-0.46089 0.50697,3e-5 0.91408,0.15366 1.22135,0.46089 0.30725,0.30728 0.46087,0.7144 0.46088,1.22135 -1e-5,0.49163 -0.15363,0.89107 -0.46088,1.1983 -0.30727,0.30728 -0.71438,0.46091 -1.22135,0.46089 -0.49162,2e-5 -0.89105,-0.15361 -1.19831,-0.46089 m 1.56702,18.15891 c -1e-5,1.67455 0.0845,2.74227 0.25348,3.20315 0.1 [...]
+ id="path3234"
+ style="font-size:47.19472122px;text-align:end;word-spacing:8.50268078px;text-anchor:end" />
+ <path
+ d="m 507.67911,445.42451 c -10e-6,1.35194 -0.16132,3.04954 -0.48393,5.09279 l -0.43784,2.78836 c -0.13828,0.87569 -0.20741,1.47484 -0.2074,1.79745 -10e-6,0.32263 0.0384,0.56843 0.11522,0.73742 0.0768,0.16899 0.17666,0.30726 0.29958,0.4148 0.12289,0.0922 0.39174,0.2074 0.80655,0.34566 0.41478,0.12291 0.62218,0.26885 0.6222,0.43784 -2e-5,0.169 -0.23046,0.35335 -0.69133,0.55307 -0.95252,0.41479 -2.12009,0.62219 -3.50274,0.62219 -0.44553,0 -0.71438,-0.0691 -0.80655,-0.2074 -0.0768,- [...]
+ id="path3236"
+ style="font-size:47.19472122px;text-align:end;word-spacing:8.50268078px;text-anchor:end" />
+ <path
+ d="m 557.59239,445.2632 c -3e-5,1.49021 -0.0692,2.57329 -0.2074,3.24924 -0.12293,0.67598 -0.43787,1.4518 -0.94481,2.32748 -0.49164,0.87569 -1.12152,1.7821 -1.88964,2.71923 -0.76817,0.93713 -1.9511,1.88195 -3.54882,2.83444 -1.58239,0.93714 -2.96505,1.4902 -4.14797,1.65919 -1.18296,0.18436 -1.82052,0.30726 -1.91268,0.36871 -0.0768,0.0614 -0.37641,0.0922 -0.89873,0.0922 -3.21085,0 -5.59209,-0.29958 -7.14373,-0.89873 -1.53629,-0.59915 -2.79605,-1.20598 -3.77926,-1.8205 -0.96787,-0.6 [...]
+ id="path3238"
+ style="font-size:47.19472122px;text-align:end;word-spacing:8.50268078px;text-anchor:end" />
+ <path
+ d="m 578.9775,457.10797 c -2e-5,0.19971 -0.46858,0.53002 -1.4057,0.9909 -0.92179,0.46089 -2.16618,0.69133 -3.73318,0.69133 -0.47626,0 -0.82961,-0.0845 -1.06003,-0.25349 -0.23046,-0.15363 -0.26887,-0.5377 -0.11523,-1.15221 0.15362,-0.62988 0.12289,-1.01395 -0.0922,-1.15222 -0.2151,-0.13826 -0.91411,0.0922 -2.09703,0.69133 -1.16759,0.58379 -1.9895,0.93714 -2.46574,1.06004 -0.47626,0.1229 -0.95251,0.18435 -1.42875,0.18435 -2.67314,0 -4.53205,-0.42247 -5.57672,-1.26743 -1.04468,-0.8 [...]
+ id="path3240"
+ style="font-size:47.19472122px;text-align:end;word-spacing:8.50268078px;text-anchor:end" />
+ <path
+ d="m 593.84107,453.83568 c -2e-5,0.15363 -0.13828,0.44552 -0.4148,0.87568 -0.26118,0.4148 -0.72207,0.92177 -1.38266,1.52092 -0.64525,0.58379 -1.5747,1.05236 -2.78836,1.40571 -1.19831,0.33798 -2.37357,0.50697 -3.52577,0.50697 -1.06005,0 -2.02023,-0.19204 -2.88054,-0.57611 -0.86032,-0.38407 -1.46716,-0.73741 -1.8205,-1.06003 -0.35335,-0.33799 -0.69133,-0.89105 -1.01395,-1.65919 -0.32262,-0.78351 -0.48393,-2.36588 -0.48393,-4.74713 0,-2.6424 0.49161,-4.60116 1.47484,-5.8763 0.99858 [...]
+ id="path3242"
+ style="font-size:47.19472122px;text-align:end;word-spacing:8.50268078px;text-anchor:end" />
+ <path
+ d="m 605.20192,453.25957 c -2e-5,0.78351 -0.28423,1.58238 -0.85264,2.39661 -0.55308,0.81423 -1.67457,1.4902 -3.36447,2.02789 -1.67456,0.52234 -2.98808,0.78351 -3.94058,0.78351 -0.93713,0 -1.71296,-0.16899 -2.32747,-0.50697 -0.61452,-0.33799 -0.92177,-0.62988 -0.92177,-0.87569 0,-0.0768 0.0307,-0.16131 0.0922,-0.25348 0.75277,-0.93714 1.14453,-1.43643 1.17525,-1.49788 0.0768,-0.10754 0.23044,-0.13059 0.46089,-0.0691 1.04467,0.36871 1.8589,0.57611 2.4427,0.6222 0.59914,0.0461 1.13 [...]
+ id="path3244"
+ style="font-size:47.19472122px;text-align:end;word-spacing:8.50268078px;text-anchor:end" />
+ <path
+ d="m 617.55366,453.25957 c -1e-5,0.78351 -0.28422,1.58238 -0.85264,2.39661 -0.55307,0.81423 -1.67456,1.4902 -3.36447,2.02789 -1.67455,0.52234 -2.98808,0.78351 -3.94057,0.78351 -0.93714,0 -1.71296,-0.16899 -2.32747,-0.50697 -0.61452,-0.33799 -0.92178,-0.62988 -0.92178,-0.87569 0,-0.0768 0.0307,-0.16131 0.0922,-0.25348 0.75278,-0.93714 1.14453,-1.43643 1.17526,-1.49788 0.0768,-0.10754 0.23044,-0.13059 0.46089,-0.0691 1.04467,0.36871 1.8589,0.57611 2.44269,0.6222 0.59915,0.0461 1.1 [...]
+ id="path3246"
+ style="font-size:47.19472122px;text-align:end;word-spacing:8.50268078px;text-anchor:end" />
+ <path
+ d="m 643.08674,455.51791 c -3e-5,0.13827 -0.58381,0.50698 -1.75137,1.10613 -1.1676,0.58379 -2.00487,0.94481 -2.51183,1.08308 -0.50699,0.13826 -1.15991,0.2074 -1.95876,0.2074 -0.79889,0 -1.30586,-0.023 -1.52093,-0.0691 -0.21509,-0.0614 -0.27654,-0.15362 -0.18435,-0.27653 0.0922,-0.1229 0.19202,-0.56842 0.29958,-1.33657 0.10752,-0.76814 0.20738,-1.54396 0.29957,-2.32747 0.0922,-0.7835 0.16898,-1.70527 0.23044,-2.76532 0.0614,-1.06003 0.0922,-2.12774 0.0922,-3.20315 -10e-6,-1.09076 [...]
+ id="path3248"
+ style="font-size:47.19472122px;text-align:end;word-spacing:8.50268078px;text-anchor:end" />
+ <path
+ d="m 658.20378,442.59006 c -1e-5,0.30727 -0.17668,0.53771 -0.53001,0.69133 -0.35336,0.13828 -0.97556,0.29191 -1.86659,0.46088 -0.89106,0.16901 -1.51326,0.25351 -1.86659,0.25349 -0.35336,2e-5 -0.76047,-0.12289 -1.22135,-0.36871 -0.46089,-0.24579 -0.75279,-0.36869 -0.87568,-0.36871 -0.21509,2e-5 -0.49162,0.15365 -0.8296,0.46089 -0.33799,0.29191 -0.67597,0.72975 -1.01395,1.31353 -0.33799,0.56843 -0.59147,1.09077 -0.76046,1.56701 -0.169,0.46089 -0.29958,1.41339 -0.39175,2.85749 -0.0 [...]
+ id="path3250"
+ style="font-size:47.19472122px;text-align:end;word-spacing:8.50268078px;text-anchor:end" />
+ <path
+ d="m 671.01643,448.42027 c -2e-5,1.56702 -0.30728,2.96504 -0.92177,4.19406 -0.61453,1.21367 -1.39804,2.25834 -2.35052,3.13402 -0.95251,0.87569 -1.97414,1.51325 -3.06489,1.91268 -1.09078,0.38407 -1.97414,0.57611 -2.6501,0.57611 -0.32263,0 -0.92178,-0.0461 -1.79745,-0.13827 -0.86033,-0.0768 -1.72065,-0.52234 -2.58096,-1.33657 -0.86033,-0.82959 -1.46716,-1.55933 -1.8205,-2.18921 -0.33799,-0.64523 -0.50698,-1.64382 -0.50698,-2.99575 0,-1.36729 0.10754,-2.45037 0.32262,-3.24925 0.215 [...]
+ id="path3252"
+ style="font-size:47.19472122px;text-align:end;word-spacing:8.50268078px;text-anchor:end" />
+ <path
+ d="m 689.56709,445.42451 c -2e-5,1.35194 -0.16133,3.04954 -0.48393,5.09279 l -0.43784,2.78836 c -0.13828,0.87569 -0.20742,1.47484 -0.2074,1.79745 -2e-5,0.32263 0.0384,0.56843 0.11522,0.73742 0.0768,0.16899 0.17666,0.30726 0.29958,0.4148 0.12288,0.0922 0.39173,0.2074 0.80655,0.34566 0.41478,0.12291 0.62218,0.26885 0.62219,0.43784 -1e-5,0.169 -0.23046,0.35335 -0.69133,0.55307 -0.95251,0.41479 -2.12009,0.62219 -3.50273,0.62219 -0.44553,0 -0.71438,-0.0691 -0.80655,-0.2074 -0.0768,-0 [...]
+ id="path3254"
+ style="font-size:47.19472122px;text-align:end;word-spacing:8.50268078px;text-anchor:end" />
+ </g>
+ <flowRoot
+ id="flowRoot3037"
+ xml:space="preserve"
+ style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><flowRegion
+ id="flowRegion3039"><rect
+ width="1060.6602"
+ height="727.30981"
+ x="-202.0305"
+ y="201.81374"
+ id="rect3041" /></flowRegion><flowPara
+ id="flowPara3043"></flowPara></flowRoot> <g
+ transform="translate(282.85664,402.6479)"
+ id="g3046">
+ <path
+ d="M 27.873,193.766 V 135.24 c 0,-23.674 19.191,-42.865 42.866,-42.865 v 37.508 c 0,35.279 28.603,63.883 63.883,63.883 35.281,0 63.884,-28.604 63.884,-63.883 0,-35.283 -28.603,-63.885 -63.884,-63.885 H 97.116 V 6.234 l -26.378,26.378 0.001,33.387 c -38.242,0 -69.244,31 -69.244,69.241 v 58.525 h 26.378 z"
+ id="rb1_3_" />
+
+ <g
+ id="gem_1_">
+ <path
+ d="m 98.383,139.588 c -0.827,-3.096 -1.267,-6.348 -1.267,-9.705 V 92.375 l 37.506,37.508 -36.239,9.705 z"
+ id="path3050"
+ style="fill:#6156ff" />
+
+ <path
+ d="m 134.622,129.883 -9.709,36.236 C 112,162.67 101.832,152.502 98.383,139.588 l 36.239,-9.705 z"
+ id="path3052"
+ style="fill:#867dff" />
+
+ <path
+ d="m 134.622,129.883 26.521,26.52 c -6.787,6.787 -16.163,10.988 -26.521,10.988 -3.357,0 -6.612,-0.443 -9.709,-1.271 l 9.709,-36.237 z"
+ id="path3054"
+ style="fill:#6156ff" />
+
+ <path
+ d="m 170.859,120.172 c 0.828,3.098 1.27,6.352 1.27,9.711 0,10.357 -4.198,19.732 -10.986,26.52 l -26.521,-26.52 36.237,-9.711 z"
+ id="path3056"
+ style="fill:#3c2eff" />
+
+ <path
+ d="m 134.622,129.883 9.71,-36.239 c 12.91,3.451 23.077,13.616 26.527,26.528 l -36.237,9.711 z"
+ id="path3058"
+ style="fill:#2212ff" />
+
+ <path
+ d="m 97.116,92.375 h 37.506 c 3.357,0 6.613,0.442 9.71,1.269 l -9.71,36.239 -37.506,-37.508 z"
+ id="path3060"
+ style="fill:#3c2eff" />
+
+ <path
+ d="m 149.195,144.455 -19.907,5.334 -14.573,-14.574 5.334,-19.906 19.907,-5.334 14.573,14.572 z"
+ id="polygon3062"
+ style="fill:#aaa4ff" />
+
+ </g>
+
+</g>
+ </g>
+</svg>
diff --git a/artwork/shirts/minimal-back.pdf b/artwork/shirts/minimal-back.pdf
new file mode 100644
index 0000000..f0b1c4a
Binary files /dev/null and b/artwork/shirts/minimal-back.pdf differ
diff --git a/artwork/shirts/minimal-back.svg b/artwork/shirts/minimal-back.svg
new file mode 100644
index 0000000..abee532
--- /dev/null
+++ b/artwork/shirts/minimal-back.svg
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.2"
+ width="1052.3622"
+ height="744.09448"
+ viewBox="0 0 1052.3622 744.09448"
+ id="Layer_1"
+ xml:space="preserve"><metadata
+ id="metadata3618"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs3616" />
+<g
+ transform="matrix(0.96849033,0,0,0.96849033,31.002883,55.535439)"
+ id="Version_2b">
+ <path
+ d="m 727.579,321.447 v -98.756 c 0,-39.945 32.384,-72.329 72.331,-72.329 v 63.289 c 0,59.531 48.266,107.796 107.796,107.796 59.533,0 107.796,-48.265 107.796,-107.796 0,-59.534 -48.263,-107.796 -107.796,-107.796 H 844.42 V 5.011 l -44.51,44.51 v 56.336 c -64.529,0 -116.841,52.31 -116.841,116.836 v 98.754 h 44.51 z"
+ id="rb1" />
+ <g
+ id="gem">
+ <path
+ d="m 846.555,230.029 c -1.394,-5.226 -2.137,-10.713 -2.137,-16.378 v -63.289 l 63.286,63.289 -61.149,16.378 z"
+ id="path3595"
+ style="fill:#6156ff" />
+ <path
+ d="m 907.704,213.651 -16.382,61.146 c -21.789,-5.823 -38.945,-22.979 -44.768,-44.769 l 61.15,-16.377 z"
+ id="path3597"
+ style="fill:#867dff" />
+ <path
+ d="m 907.704,213.651 44.751,44.75 c -11.453,11.453 -27.273,18.539 -44.751,18.539 -5.665,0 -11.156,-0.747 -16.382,-2.143 l 16.382,-61.146 z"
+ id="path3599"
+ style="fill:#6156ff" />
+ <path
+ d="m 968.851,197.266 c 1.396,5.226 2.144,10.718 2.144,16.386 0,17.478 -7.086,33.297 -18.539,44.75 l -44.751,-44.75 61.146,-16.386 z"
+ id="path3601"
+ style="fill:#3c2eff" />
+ <path
+ d="m 907.704,213.651 16.386,-61.147 c 21.785,5.823 38.938,22.976 44.761,44.761 l -61.147,16.386 z"
+ id="path3603"
+ style="fill:#2212ff" />
+ <path
+ d="m 844.418,150.363 h 63.286 c 5.665,0 11.16,0.746 16.386,2.142 l -16.386,61.147 -63.286,-63.289 z"
+ id="path3605"
+ style="fill:#3c2eff" />
+ <path
+ d="m 883.116,189.059 33.591,-8.999 24.588,24.588 -8.999,33.591 -33.591,9.003 -24.592,-24.592 z"
+ id="polygon3607"
+ style="fill:#aaa4ff" />
+ </g>
+ <path
+ d="m 416.691,281.119 -22.85,-21.763 c 2.838,-8.699 4.392,-17.978 4.392,-27.624 h -36.844 c 0,28.809 -23.353,52.162 -52.16,52.162 -28.809,0 -52.161,-23.354 -52.161,-52.162 0,-28.807 23.353,-52.159 52.161,-52.159 14.399,0 27.437,5.834 36.876,15.27 l -36.876,36.889 h 52.16 l 36.857,-36.854 -18.645,-18.644 13.726,-27.655 -16.803,-14.101 -25.396,18.723 c -7.289,-3.897 -15.181,-6.809 -23.504,-8.558 l -7.423,-30.669 h -21.934 l -7.421,30.666 c -8.324,1.749 -16.216,4.66 -23.505,8.556 l -25.4, [...]
+ id="e2b" />
+ <path
+ d="m 420.784,231.734 c 0,-49.158 39.848,-89.005 89.004,-89.005 13.854,0 26.966,3.166 38.656,8.812 11.69,-5.646 24.805,-8.812 38.655,-8.812 49.156,0 89.006,39.848 89.006,89.005 v 89.713 h -36.844 v -89.713 c 0,-28.809 -23.354,-52.161 -52.162,-52.161 -15.327,0 -29.112,6.613 -38.655,17.143 -9.544,-10.53 -23.325,-17.143 -38.656,-17.143 -28.808,0 -52.16,23.353 -52.16,52.161 v 89.713 h -36.844 v -89.713 z"
+ id="m" />
+ <g
+ id="g_9_">
+ <path
+ d="m 97.207,283.895 c -28.807,0 -52.16,-23.354 -52.16,-52.162 0,-28.807 23.353,-52.159 52.16,-52.159 28.807,0 52.16,23.353 52.16,52.159 v 52.162 h -52.16 z m 89.706,-52.163 c 0,-49.543 -40.162,-89.704 -89.706,-89.704 -49.544,0 -89.706,40.161 -89.706,89.704 0,49.544 40.162,89.708 89.706,89.708 h 52.16 v 21.821 c 0,14.406 -5.836,27.447 -15.275,36.887 l 26.547,26.55 c 16.233,-16.235 26.274,-38.663 26.274,-63.437 V 231.732 z"
+ id="g" />
+ <path
+ d="m 149.367,283.89499 37.54601,0 0,37.546 -37.54601,0 z"
+ id="square"
+ style="fill:#ff4a2f" />
+ </g>
+</g>
+</svg>
\ No newline at end of file
diff --git a/artwork/shirts/minimal-front.pdf b/artwork/shirts/minimal-front.pdf
new file mode 100644
index 0000000..e5bff2b
Binary files /dev/null and b/artwork/shirts/minimal-front.pdf differ
diff --git a/artwork/shirts/minimal-front.svg b/artwork/shirts/minimal-front.svg
new file mode 100644
index 0000000..e76f9b5
--- /dev/null
+++ b/artwork/shirts/minimal-front.svg
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.2"
+ width="744.09448"
+ height="1052.3622"
+ viewBox="0 0 744.09449 1052.3622"
+ id="Layer_1"
+ xml:space="preserve"><metadata
+ id="metadata3618"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs3616" />
+<g
+ transform="matrix(0.96849033,0,0,0.96849033,31.002883,363.80314)"
+ id="Version_2b">
+ <path
+ d="m 500.29563,30.383222 v -47.19951 c 0,-19.091341 15.47763,-34.568972 34.56993,-34.568972 v 30.248388 c 0,28.4522869 23.06829,51.520094 51.5201,51.520094 28.45324,0 51.52009,-23.0678071 51.52009,-51.520094 0,-28.453721 -23.06685,-51.520095 -51.52009,-51.520095 H 556.1387 v -48.197453 l -21.27314,21.273142 v 26.925267 c -30.84103,0 -55.84307,25.001078 -55.84307,55.840679 v 47.198554 h 21.27314 z"
+ id="rb1" />
+ <g
+ transform="matrix(0.47794069,0,0,0.47794069,152.55602,-123.24938)"
+ id="gem">
+ <path
+ d="m 846.555,230.029 c -1.394,-5.226 -2.137,-10.713 -2.137,-16.378 v -63.289 l 63.286,63.289 -61.149,16.378 z"
+ id="path3595"
+ style="fill:#6156ff" />
+ <path
+ d="m 907.704,213.651 -16.382,61.146 c -21.789,-5.823 -38.945,-22.979 -44.768,-44.769 l 61.15,-16.377 z"
+ id="path3597"
+ style="fill:#867dff" />
+ <path
+ d="m 907.704,213.651 44.751,44.75 c -11.453,11.453 -27.273,18.539 -44.751,18.539 -5.665,0 -11.156,-0.747 -16.382,-2.143 l 16.382,-61.146 z"
+ id="path3599"
+ style="fill:#6156ff" />
+ <path
+ d="m 968.851,197.266 c 1.396,5.226 2.144,10.718 2.144,16.386 0,17.478 -7.086,33.297 -18.539,44.75 l -44.751,-44.75 61.146,-16.386 z"
+ id="path3601"
+ style="fill:#3c2eff" />
+ <path
+ d="m 907.704,213.651 16.386,-61.147 c 21.785,5.823 38.938,22.976 44.761,44.761 l -61.147,16.386 z"
+ id="path3603"
+ style="fill:#2212ff" />
+ <path
+ d="m 844.418,150.363 h 63.286 c 5.665,0 11.16,0.746 16.386,2.142 l -16.386,61.147 -63.286,-63.289 z"
+ id="path3605"
+ style="fill:#3c2eff" />
+ <path
+ d="m 883.116,189.059 33.591,-8.999 24.588,24.588 -8.999,33.591 -33.591,9.003 -24.592,-24.592 z"
+ id="polygon3607"
+ style="fill:#aaa4ff" />
+ </g>
+
+
+
+</g>
+</svg>
\ No newline at end of file
diff --git a/artwork/shirts/source-detailed-back.svg b/artwork/shirts/source-detailed-back.svg
new file mode 100644
index 0000000..fb6b537
--- /dev/null
+++ b/artwork/shirts/source-detailed-back.svg
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 14.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 43363) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ id="Layer_1"
+ x="0px"
+ y="0px"
+ width="1052.3622"
+ height="744.09448"
+ viewBox="0 0 1052.3622 744.09448"
+ xml:space="preserve"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="t-back.svg"><metadata
+ id="metadata3618"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs3616" /><sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1276"
+ inkscape:window-height="748"
+ id="namedview3614"
+ showgrid="false"
+ inkscape:zoom="0.16760024"
+ inkscape:cx="1770.3279"
+ inkscape:cy="-34.35442"
+ inkscape:window-x="88"
+ inkscape:window-y="-3"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="Layer_1" />
+<g
+ id="Version_2b"
+ transform="matrix(0.96849033,0,0,0.96849033,31.002883,55.535439)">
+ <path
+ id="rb1"
+ d="m 727.579,321.447 v -98.756 c 0,-39.945 32.384,-72.329 72.331,-72.329 v 63.289 c 0,59.531 48.266,107.796 107.796,107.796 59.533,0 107.796,-48.265 107.796,-107.796 0,-59.534 -48.263,-107.796 -107.796,-107.796 H 844.42 V 5.011 l -44.51,44.51 v 56.336 c -64.529,0 -116.841,52.31 -116.841,116.836 v 98.754 h 44.51 z"
+ inkscape:connector-curvature="0" />
+ <g
+ id="gem">
+ <path
+ d="m 846.555,230.029 c -1.394,-5.226 -2.137,-10.713 -2.137,-16.378 v -63.289 l 63.286,63.289 -61.149,16.378 z"
+ id="path3595"
+ inkscape:connector-curvature="0"
+ style="fill:#6156ff" />
+ <path
+ d="m 907.704,213.651 -16.382,61.146 c -21.789,-5.823 -38.945,-22.979 -44.768,-44.769 l 61.15,-16.377 z"
+ id="path3597"
+ inkscape:connector-curvature="0"
+ style="fill:#867dff" />
+ <path
+ d="m 907.704,213.651 44.751,44.75 c -11.453,11.453 -27.273,18.539 -44.751,18.539 -5.665,0 -11.156,-0.747 -16.382,-2.143 l 16.382,-61.146 z"
+ id="path3599"
+ inkscape:connector-curvature="0"
+ style="fill:#6156ff" />
+ <path
+ d="m 968.851,197.266 c 1.396,5.226 2.144,10.718 2.144,16.386 0,17.478 -7.086,33.297 -18.539,44.75 l -44.751,-44.75 61.146,-16.386 z"
+ id="path3601"
+ inkscape:connector-curvature="0"
+ style="fill:#3c2eff" />
+ <path
+ d="m 907.704,213.651 16.386,-61.147 c 21.785,5.823 38.938,22.976 44.761,44.761 l -61.147,16.386 z"
+ id="path3603"
+ inkscape:connector-curvature="0"
+ style="fill:#2212ff" />
+ <path
+ d="m 844.418,150.363 h 63.286 c 5.665,0 11.16,0.746 16.386,2.142 l -16.386,61.147 -63.286,-63.289 z"
+ id="path3605"
+ inkscape:connector-curvature="0"
+ style="fill:#3c2eff" />
+ <polygon
+ points="883.116,189.059 916.707,180.06 941.295,204.648 932.296,238.239 898.705,247.242 874.113,222.65 "
+ id="polygon3607"
+ style="fill:#aaa4ff" />
+ </g>
+ <path
+ id="e2b"
+ d="m 416.691,281.119 -22.85,-21.763 c 2.838,-8.699 4.392,-17.978 4.392,-27.624 h -36.844 c 0,28.809 -23.353,52.162 -52.16,52.162 -28.809,0 -52.161,-23.354 -52.161,-52.162 0,-28.807 23.353,-52.159 52.161,-52.159 14.399,0 27.437,5.834 36.876,15.27 l -36.876,36.889 h 52.16 l 36.857,-36.854 -18.645,-18.644 13.726,-27.655 -16.803,-14.101 -25.396,18.723 c -7.289,-3.897 -15.181,-6.809 -23.504,-8.558 l -7.423,-30.669 h -21.934 l -7.421,30.666 c -8.324,1.749 -16.216,4.66 -23.505,8.556 l -25.4, [...]
+ inkscape:connector-curvature="0" />
+ <path
+ id="m"
+ d="m 420.784,231.734 c 0,-49.158 39.848,-89.005 89.004,-89.005 13.854,0 26.966,3.166 38.656,8.812 11.69,-5.646 24.805,-8.812 38.655,-8.812 49.156,0 89.006,39.848 89.006,89.005 v 89.713 h -36.844 v -89.713 c 0,-28.809 -23.354,-52.161 -52.162,-52.161 -15.327,0 -29.112,6.613 -38.655,17.143 -9.544,-10.53 -23.325,-17.143 -38.656,-17.143 -28.808,0 -52.16,23.353 -52.16,52.161 v 89.713 h -36.844 v -89.713 z"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g_9_">
+ <path
+ id="g"
+ d="m 97.207,283.895 c -28.807,0 -52.16,-23.354 -52.16,-52.162 0,-28.807 23.353,-52.159 52.16,-52.159 28.807,0 52.16,23.353 52.16,52.159 v 52.162 h -52.16 z m 89.706,-52.163 c 0,-49.543 -40.162,-89.704 -89.706,-89.704 -49.544,0 -89.706,40.161 -89.706,89.704 0,49.544 40.162,89.708 89.706,89.708 h 52.16 v 21.821 c 0,14.406 -5.836,27.447 -15.275,36.887 l 26.547,26.55 c 16.233,-16.235 26.274,-38.663 26.274,-63.437 V 231.732 z"
+ inkscape:connector-curvature="0" />
+ <rect
+ id="square"
+ x="149.367"
+ y="283.89499"
+ width="37.546001"
+ height="37.546001"
+ style="fill:#ff4a2f" />
+ </g>
+</g>
+<flowRoot
+ xml:space="preserve"
+ id="flowRoot3620"
+ style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ transform="translate(92.76828,-10.118752)"><flowRegion
+ id="flowRegion3622"><rect
+ id="rect3624"
+ width="493.62399"
+ height="149.77478"
+ x="525.26654"
+ y="415.01184" /></flowRegion><flowPara
+ id="flowPara3626"
+ style="font-size:90px;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;word-spacing:12.18000317px;font-family:Eadui;-inkscape-font-specification:Eadui Medium">IE anywhere!</flowPara></flowRoot></svg>
\ No newline at end of file
diff --git a/artwork/shirts/source-detailed-front.svg b/artwork/shirts/source-detailed-front.svg
new file mode 100644
index 0000000..f82cca1
--- /dev/null
+++ b/artwork/shirts/source-detailed-front.svg
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="744.09448819"
+ height="1052.3622047"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="t-front.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.35"
+ inkscape:cx="-473.90302"
+ inkscape:cy="398.15535"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1276"
+ inkscape:window-height="748"
+ inkscape:window-x="88"
+ inkscape:window-y="-3"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <flowRoot
+ xml:space="preserve"
+ id="flowRoot2985"
+ style="fill:black;stroke:none;stroke-opacity:1;stroke-width:1px;stroke-linejoin:miter;stroke-linecap:butt;fill-opacity:1;font-family:Sans;font-style:normal;font-weight:normal;font-size:40px;line-height:125%;letter-spacing:0px;word-spacing:0px"><flowRegion
+ id="flowRegion2987"><rect
+ id="rect2989"
+ width="630.33521"
+ height="319.20819"
+ x="64.649765"
+ y="304.8493" /></flowRegion><flowPara
+ id="flowPara2991" /></flowRoot> <flowRoot
+ xml:space="preserve"
+ id="flowRoot2993"
+ style="font-size:72px;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0.11798681px;fill:#000000;fill-opacity:1;stroke:none;font-family:Eadui;-inkscape-font-specification:Eadui Medium"
+ transform="matrix(1.0344169,0,0,1,-7.5300745,-72)"><flowRegion
+ id="flowRegion2995"><rect
+ id="rect2997"
+ width="643.64044"
+ height="384.44974"
+ x="48.487324"
+ y="278.58533"
+ style="font-size:72px;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;word-spacing:0.11798681px;font-family:Eadui;-inkscape-font-specification:Eadui Medium" /></flowRegion><flowPara
+ id="flowPara3033"
+ style="font-size:100px;text-align:center;line-height:105.99999428%;word-spacing:8.50268078px;text-anchor:middle">I'm not a geek</flowPara><flowPara
+ id="flowPara3035"
+ style="font-size:70.79208374px;text-align:center;line-height:105.99999428%;word-spacing:8.50268078px;text-anchor:middle">I'm a level 3/2 hacker/mage </flowPara></flowRoot> <flowRoot
+ xml:space="preserve"
+ id="flowRoot2993-2"
+ style="font-size:72px;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0.11798681px;fill:#000000;fill-opacity:1;stroke:none;font-family:Eadui;-inkscape-font-specification:Eadui Medium"
+ transform="matrix(1.0344169,0,0,1,-6.5559329,367.36316)"><flowRegion
+ id="flowRegion2995-0"><rect
+ id="rect2997-2"
+ width="643.64044"
+ height="384.44974"
+ x="48.487324"
+ y="278.58533"
+ style="font-size:72px;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;word-spacing:0.11798681px;font-family:Eadui;-inkscape-font-specification:Eadui Medium" /></flowRegion><flowPara
+ id="flowPara3035-7"
+ style="font-size:47.19472122px;text-align:center;line-height:105.99999428%;word-spacing:8.50268078px;text-anchor:middle">Elminster this, Elminster that. Give ME 2000 years and a pointy hat and I'll kick his arse! </flowPara><flowPara
+ style="font-size:47.19472122px;text-align:end;line-height:105.99999428%;word-spacing:8.50268078px;text-anchor:end"
+ id="flowPara3027">- Edwin Odesseiron </flowPara></flowRoot> <flowRoot
+ xml:space="preserve"
+ id="flowRoot3037"
+ style="fill:black;stroke:none;stroke-opacity:1;stroke-width:1px;stroke-linejoin:miter;stroke-linecap:butt;fill-opacity:1;font-family:Sans;font-style:normal;font-weight:normal;font-size:40px;line-height:125%;letter-spacing:0px;word-spacing:0px"><flowRegion
+ id="flowRegion3039"><rect
+ id="rect3041"
+ width="1060.6602"
+ height="727.30981"
+ x="-202.0305"
+ y="201.81374" /></flowRegion><flowPara
+ id="flowPara3043"></flowPara></flowRoot> <g
+ id="g3046"
+ transform="translate(282.85664,402.6479)">
+ <path
+ d="M 27.873,193.766 V 135.24 c 0,-23.674 19.191,-42.865 42.866,-42.865 v 37.508 c 0,35.279 28.603,63.883 63.883,63.883 35.281,0 63.884,-28.604 63.884,-63.883 0,-35.283 -28.603,-63.885 -63.884,-63.885 H 97.116 V 6.234 l -26.378,26.378 0.001,33.387 c -38.242,0 -69.244,31 -69.244,69.241 v 58.525 h 26.378 z"
+ id="rb1_3_"
+ inkscape:connector-curvature="0" />
+
+ <g
+ id="gem_1_">
+ <path
+ id="path3050"
+ d="m 98.383,139.588 c -0.827,-3.096 -1.267,-6.348 -1.267,-9.705 V 92.375 l 37.506,37.508 -36.239,9.705 z"
+ inkscape:connector-curvature="0"
+ style="fill:#6156ff" />
+
+ <path
+ id="path3052"
+ d="m 134.622,129.883 -9.709,36.236 C 112,162.67 101.832,152.502 98.383,139.588 l 36.239,-9.705 z"
+ inkscape:connector-curvature="0"
+ style="fill:#867dff" />
+
+ <path
+ id="path3054"
+ d="m 134.622,129.883 26.521,26.52 c -6.787,6.787 -16.163,10.988 -26.521,10.988 -3.357,0 -6.612,-0.443 -9.709,-1.271 l 9.709,-36.237 z"
+ inkscape:connector-curvature="0"
+ style="fill:#6156ff" />
+
+ <path
+ id="path3056"
+ d="m 170.859,120.172 c 0.828,3.098 1.27,6.352 1.27,9.711 0,10.357 -4.198,19.732 -10.986,26.52 l -26.521,-26.52 36.237,-9.711 z"
+ inkscape:connector-curvature="0"
+ style="fill:#3c2eff" />
+
+ <path
+ id="path3058"
+ d="m 134.622,129.883 9.71,-36.239 c 12.91,3.451 23.077,13.616 26.527,26.528 l -36.237,9.711 z"
+ inkscape:connector-curvature="0"
+ style="fill:#2212ff" />
+
+ <path
+ id="path3060"
+ d="m 97.116,92.375 h 37.506 c 3.357,0 6.613,0.442 9.71,1.269 l -9.71,36.239 -37.506,-37.508 z"
+ inkscape:connector-curvature="0"
+ style="fill:#3c2eff" />
+
+ <polygon
+ id="polygon3062"
+ points="149.195,144.455 129.288,149.789 114.715,135.215 120.049,115.309 139.956,109.975 154.529,124.547 "
+ style="fill:#aaa4ff" />
+
+ </g>
+
+</g>
+ </g>
+</svg>
diff --git a/autogen.sh b/autogen.sh
index 52845e3..8654781 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -19,7 +19,7 @@ future versions! Please switch to using cmake instead.
if [ "$1" = "" ]; then
dest=$HOME/GemRB
else
- if [ "${1:0:1}" == "/" ]; then
+ if [ "${1:0:1}" = "/" ]; then
dest=$1
else
dest=$PWD/$1
diff --git a/cmake/cmake_config.h.in b/cmake/cmake_config.h.in
new file mode 100644
index 0000000..24e3f59
--- /dev/null
+++ b/cmake/cmake_config.h.in
@@ -0,0 +1,15 @@
+#define PACKAGE "gemrb"
+
+#cmakedefine SIZEOF_INT ${SIZEOF_INT}
+#cmakedefine SIZEOF_LONG_INT ${SIZEOF_LONG_INT}
+#cmakedefine HAVE_STRNDUP 1
+#cmakedefine HAVE_STRLCPY 1
+#cmakedefine HAVE_FORBIDDEN_OBJECT_TO_FUNCTION_CAST 1
+#define PLUGINDIR "${PLUGIN_DIR}"
+#define DATADIR "${DATA_DIR}"
+#define SYSCONFDIR "${SYSCONF_DIR}"
+#cmakedefine NOCOLOR ${NOCOLOR}
+#cmakedefine HAVE_MALLOC_H 1
+#cmakedefine HAVE_UNISTD_H 1
+#cmakedefine WIN32_USE_STDIO 1
+#cmakedefine HAVE_ICONV 1
diff --git a/cmake_uninstall.cmake.in b/cmake/cmake_uninstall.cmake.in
similarity index 100%
rename from cmake_uninstall.cmake.in
rename to cmake/cmake_uninstall.cmake.in
diff --git a/cmake/modules/FindICONV.cmake b/cmake/modules/FindICONV.cmake
new file mode 100644
index 0000000..303ceb2
--- /dev/null
+++ b/cmake/modules/FindICONV.cmake
@@ -0,0 +1,102 @@
+# vim:ts=4:sw=4:expandtab:autoindent:
+#
+# The MIT License
+#
+# Copyright (c) 2008, 2009 Flusspferd contributors (see "CONTRIBUTORS" or
+# http://flusspferd.org/contributors.txt)
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+Include(CheckFunctionExists)
+include(CheckCXXSourceCompiles)
+
+if(ICONV_INCLUDE_DIR)
+ set(ICONV_FIND_QUIETLY TRUE)
+endif()
+
+find_path(ICONV_INCLUDE_DIR iconv.h)
+
+if(NOT ICONV_INCLUDE_DIR STREQUAL "ICONV_INCLUDE_DIR-NOTFOUND")
+ set(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR})
+ check_function_exists(iconv_open ICONV_IN_GLIBC)
+endif()
+
+if(NOT ICONV_IN_GLIBC)
+ find_library(ICONV_LIBRARY NAMES iconv)
+ set(ICONV_TEST ${ICONV_LIBRARY})
+else()
+ set(ICONV_TEST "In glibc")
+endif()
+
+set(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR})
+set(CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARY})
+check_cxx_source_compiles(
+ "#include <iconv.h>
+ int main() {
+ iconv(iconv_t(-1), 0, 0, 0, 0);
+ }"
+ ICONV_COMPILES)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(ICONV DEFAULT_MSG ICONV_TEST ICONV_INCLUDE_DIR ICONV_COMPILES)
+
+if(ICONV_FOUND)
+ set(ICONV_LIBRARIES ${ICONV_LIBRARY})
+else(ICONV_FOUND)
+ set(ICONV_LIBRARIES)
+endif(ICONV_FOUND)
+
+if(ICONV_FOUND)
+ set(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR})
+ set(CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARIES})
+
+ if (NOT DEFINED ICONV_ACCEPTS_NONCONST_INPUT)
+ # Display a useful message first time we come through here
+ message(STATUS "One (and only one) of the ICONV_ACCEPTS_... tests must pass")
+ endif()
+ check_cxx_source_compiles(
+ "#include <iconv.h>
+ int main() {
+ char *p = 0;
+ iconv(iconv_t(-1), &p, 0, 0, 0);
+ }"
+ ICONV_ACCEPTS_NONCONST_INPUT)
+
+ check_cxx_source_compiles(
+ "#include <iconv.h>
+ int main() {
+ char const *p = 0;
+ iconv(iconv_t(-1), &p, 0, 0, 0);
+ }"
+ ICONV_ACCEPTS_CONST_INPUT)
+
+ if (ICONV_LIBRARY)
+ list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARY})
+ list(REMOVE_DUPLICATES CMAKE_REQUIRED_LIBRARIES)
+ endif()
+endif()
+
+if(NOT ICONV_ACCEPTS_CONST_INPUT AND NOT ICONV_ACCEPTS_NONCONST_INPUT)
+ MESSAGE(WARNING "Unable to determine iconv() signature")
+elseif(ICONV_ACCEPTS_CONST_INPUT AND ICONV_ACCEPTS_NONCONST_INPUT)
+ MESSAGE(WARNING "Unable to determine iconv() signature - both test cases passed!")
+endif()
+
+mark_as_advanced(ICONV_LIBRARY ICONV_INCLUDE_DIR)
diff --git a/cmake/modules/FindLIBVLC.cmake b/cmake/modules/FindLIBVLC.cmake
new file mode 100644
index 0000000..04f05f3
--- /dev/null
+++ b/cmake/modules/FindLIBVLC.cmake
@@ -0,0 +1,78 @@
+
+# CMake module to search for LIBVLC (VLC library)
+# Author: Rohit Yadav <rohityadav89 at gmail.com>
+#
+# If it's found it sets LIBVLC_FOUND to TRUE
+# and following variables are set:
+# LIBVLC_INCLUDE_DIR
+# LIBVLC_LIBRARY
+
+
+# FIND_PATH and FIND_LIBRARY normally search standard locations
+# before the specified paths. To search non-standard paths first,
+# FIND_* is invoked first with specified paths and NO_DEFAULT_PATH
+# and then again with no specified paths to search the default
+# locations. When an earlier FIND_* succeeds, subsequent FIND_*s
+# searching for the same item do nothing.
+
+#Put here path to custom location
+#example: /home/user/vlc/include etc..
+FIND_PATH(LIBVLC_INCLUDE_DIR vlc/vlc.h
+ "$ENV{LIBVLC_INCLUDE_PATH}"
+ "$ENV{LIB_DIR}/include"
+ "$ENV{LIB_DIR}/include/vlc"
+ "/usr/include"
+ "/usr/include/vlc"
+ "/usr/local/include"
+ "/usr/local/include/vlc"
+ #mingw
+ c:/msys/local/include
+ NO_DEFAULT_PATH
+ )
+FIND_PATH(LIBVLC_INCLUDE_DIR vlc.h)
+
+#Put here path to custom location
+#example: /home/user/vlc/lib etc..
+FIND_LIBRARY(LIBVLC_LIBRARY NAMES vlc PATHS
+ "$ENV{LIBVLC_LIBRARY_PATH}"
+ "$ENV{LIB_DIR}/lib"
+ #mingw
+ c:/msys/local/lib
+ NO_DEFAULT_PATH
+ )
+FIND_LIBRARY(LIBVLC_LIBRARY NAMES vlc)
+FIND_LIBRARY(LIBVLCCORE_LIBRARY NAMES vlccore PATHS
+ "$ENV{LIBVLC_LIBRARY_PATH}"
+ "$ENV{LIB_DIR}/lib"
+ #mingw
+ c:/msys/local/lib
+ NO_DEFAULT_PATH
+ )
+FIND_LIBRARY(LIBVLCCORE_LIBRARY NAMES vlccore)
+
+IF (LIBVLC_INCLUDE_DIR AND LIBVLC_LIBRARY AND LIBVLCCORE_LIBRARY)
+ # we require this function from 2.0
+ execute_process(
+ COMMAND grep -sq libvlc_video_set_format_callbacks "${LIBVLC_INCLUDE_DIR}/vlc/libvlc_media_player.h" "${LIBVLC_INCLUDE_DIR}/libvlc_media_player.h"
+ RESULT_VARIABLE LIBVLC_GOOD
+ OUTPUT_VARIABLE TM
+ )
+ #message("1111111: ${LIBVLC_LIBRARY} + ${LIBVLC_INCLUDE_DIR} : ${LIBVLC_GOOD} ~ ${TM}")
+ IF (LIBVLC_GOOD EQUAL 0)
+ SET(LIBVLC_FOUND TRUE)
+ ELSE (LIBVLC_GOOD EQUAL 0)
+ message ("The VLCPlayer plugin requires at least VLC 2.0.0 to build, skipping!")
+ ENDIF (LIBVLC_GOOD EQUAL 0)
+ENDIF (LIBVLC_INCLUDE_DIR AND LIBVLC_LIBRARY AND LIBVLCCORE_LIBRARY)
+
+IF (LIBVLC_FOUND)
+ IF (NOT LIBVLC_FIND_QUIETLY)
+ MESSAGE(STATUS "Found LibVLC include-dir path: ${LIBVLC_INCLUDE_DIR}")
+ MESSAGE(STATUS "Found LibVLC library path:${LIBVLC_LIBRARY}")
+ MESSAGE(STATUS "Found LibVLCcore library path:${LIBVLCCORE_LIBRARY}")
+ ENDIF (NOT LIBVLC_FIND_QUIETLY)
+ELSE (LIBVLC_FOUND)
+ IF (LIBVLC_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Could not find LibVLC")
+ ENDIF (LIBVLC_FIND_REQUIRED)
+ENDIF (LIBVLC_FOUND)
diff --git a/cmake_config.h.in b/cmake_config.h.in
deleted file mode 100644
index 7f69962..0000000
--- a/cmake_config.h.in
+++ /dev/null
@@ -1,16 +0,0 @@
-#define PACKAGE "gemrb"
-
-#cmakedefine SIZEOF_INT ${SIZEOF_INT}
-#cmakedefine SIZEOF_LONG_INT ${SIZEOF_LONG_INT}
-#ifndef HAVE_SNPRINTF
-#cmakedefine HAVE_SNPRINTF 1
-#endif
-#ifndef HAVE_STRNDUP
-#cmakedefine HAVE_STRNDUP 1
-#endif
-#cmakedefine HAVE_FORBIDDEN_OBJECT_TO_FUNCTION_CAST 1
-#define PLUGINDIR "${PLUGIN_DIR}"
-#define DATADIR "${DATA_DIR}"
-#define SYSCONFDIR "${SYSCONF_DIR}"
-#cmakedefine NOCOLOR ${NOCOLOR}
-#cmakedefine TOUCHSCREEN ${TOUCHSCREEN}
diff --git a/configure.in b/configure.in
index 2b13417..43cff66 100644
--- a/configure.in
+++ b/configure.in
@@ -27,7 +27,7 @@
dnl Initialize autoconf and automake
AC_PREREQ([2.57])
-AC_INIT(gemrb, 0.6.4)
+AC_INIT(gemrb, 0.8.0)
AC_MSG_WARN([
@@ -119,7 +119,7 @@ AC_CHECK_FUNCS([strtol])
AC_CHECK_FUNCS([strtoul])
AC_CHECK_FUNCS([strndup])
AC_CHECK_FUNCS([strnlen])
-AC_CHECK_FUNCS([snprintf])
+AC_CHECK_FUNCS([strlcpy])
AC_CHECK_HEADERS([fcntl.h])
AC_CHECK_HEADERS([stddef.h])
AC_CHECK_HEADERS([sys/time.h])
@@ -238,6 +238,14 @@ gemrb/override/iwd/Makefile
gemrb/override/iwd2/Makefile
gemrb/override/pst/Makefile
gemrb/override/shared/Makefile
+gemrb/unhardcoded/Makefile
+gemrb/unhardcoded/bg1/Makefile
+gemrb/unhardcoded/bg2/Makefile
+gemrb/unhardcoded/how/Makefile
+gemrb/unhardcoded/iwd/Makefile
+gemrb/unhardcoded/iwd2/Makefile
+gemrb/unhardcoded/pst/Makefile
+gemrb/unhardcoded/shared/Makefile
gemrb/GUIScripts/Makefile
gemrb/GUIScripts/bg1/Makefile
gemrb/GUIScripts/bg2/Makefile
@@ -277,11 +285,13 @@ gemrb/plugins/NullSound/Makefile
gemrb/plugins/OpenALAudio/Makefile
gemrb/plugins/PLTImporter/Makefile
gemrb/plugins/PROImporter/Makefile
+gemrb/plugins/SAVImporter/Makefile
gemrb/plugins/SDLVideo/Makefile
gemrb/plugins/SPLImporter/Makefile
gemrb/plugins/STOImporter/Makefile
gemrb/plugins/TISImporter/Makefile
gemrb/plugins/TLKImporter/Makefile
+gemrb/plugins/TTFImporter/Makefile
gemrb/plugins/WEDImporter/Makefile
gemrb/plugins/WMPImporter/Makefile
gemrb/plugins/ZLibManager/Makefile
diff --git a/contrib/manhole.py b/contrib/manhole.py
new file mode 100644
index 0000000..271ec65
--- /dev/null
+++ b/contrib/manhole.py
@@ -0,0 +1,33 @@
+# This is a script that allows you to talk to the embedded python interpreter
+# using ssh. To use it, put it in the GUIScript directory and then add the
+# following to include.py, or issue using the python console
+#
+# import manhole
+# manhole.createManhole(port = 2222, users = { 'gemrb': 'password' })
+#
+# Then you can connect using ssh to the given port and issue python commands.
+
+
+import GemRB
+from twisted.internet import reactor
+
+reactor.startRunning()
+GemRB.SetTickHook(lambda: reactor.iterate())
+
+from twisted.conch import manhole, manhole_ssh
+from twisted.conch.insults import insults
+from twisted.cred import checkers, portal
+def createManhole(port = 2222, users = { 'gemrb': 'password' }):
+ """Create a twisted manhole for accessing the embedded python interpreter"""
+ namespace = { 'GemRB' : GemRB }
+
+ def makeProtocol():
+ return insults.ServerProtocol(manhole.ColoredManhole, namespace)
+ r = manhole_ssh.TerminalRealm()
+ r.chainedProtocolFactory = makeProtocol
+ c = checkers.InMemoryUsernamePasswordDatabaseDontUse()
+ for (username, password) in users.iteritems():
+ c.addUser(username, password)
+ p = portal.Portal(r, [c])
+ f = manhole_ssh.ConchFactory(p)
+ return reactor.listenTCP(port, f)
diff --git a/demo/TODO b/demo/TODO
new file mode 100644
index 0000000..dfb8343
--- /dev/null
+++ b/demo/TODO
@@ -0,0 +1,23 @@
+if ready by release, add to install targets, sample config (gametype!) and
+ add instructions with a preconfigured config. Decide about including fonts.
+
+CODE:
+fix actor selection
+set actor palette
+
+DATA:
+real bams for cursors (add as needed), tooltip bg
+fist.itm is missing some resources like icons
+dialog.tlk entries
+(proper mapicon0.png)
+
+add an infopoint somewhere
+make the cave entrance, sides a travel region (to self)
+add area music
+add another actor
+write dialogs
+add a cutscene
+
+CONSIDER REMOVING:
+- mastarea.2da
+- the fonts, now included for easier testing (otherwise add all the needed boilerplate)
diff --git a/demo/chitin.key b/demo/chitin.key
new file mode 100644
index 0000000..c3b170e
Binary files /dev/null and b/demo/chitin.key differ
diff --git a/demo/data/AR0100.WED b/demo/data/AR0100.WED
new file mode 100644
index 0000000..3d297ef
Binary files /dev/null and b/demo/data/AR0100.WED differ
diff --git a/demo/data/AR0100HT.BMP b/demo/data/AR0100HT.BMP
new file mode 100644
index 0000000..299e883
Binary files /dev/null and b/demo/data/AR0100HT.BMP differ
diff --git a/demo/data/AR0100LM.BMP b/demo/data/AR0100LM.BMP
new file mode 100644
index 0000000..271b524
Binary files /dev/null and b/demo/data/AR0100LM.BMP differ
diff --git a/demo/data/AR0100SR.BMP b/demo/data/AR0100SR.BMP
new file mode 100644
index 0000000..4872e3c
Binary files /dev/null and b/demo/data/AR0100SR.BMP differ
diff --git a/demo/data/AR0100TMP.BMP b/demo/data/AR0100TMP.BMP
new file mode 100644
index 0000000..5baf932
Binary files /dev/null and b/demo/data/AR0100TMP.BMP differ
diff --git a/demo/data/DejaVuSans.ttf b/demo/data/DejaVuSans.ttf
new file mode 100644
index 0000000..27cff47
Binary files /dev/null and b/demo/data/DejaVuSans.ttf differ
diff --git a/demo/data/Eadui.ttf b/demo/data/Eadui.ttf
new file mode 100644
index 0000000..a65cb21
Binary files /dev/null and b/demo/data/Eadui.ttf differ
diff --git a/demo/data/README b/demo/data/README
new file mode 100644
index 0000000..1548b77
--- /dev/null
+++ b/demo/data/README
@@ -0,0 +1,14 @@
+AUTHORS
+
+If not otherwise noted, the author of the files is GemRB team and they are available under GPL2+ like GemRB itself.
+
+The background graphic for ar0100 was contributed by Aranthor (made from scratch) and is available as-is, requiring only attribution.
+
+The avatar animation was contributed by deepinthewoods.
+
+The big avatar animation was contributed by Copyright 2010-2012 Jochen Winkler <http://www.jochen-winkler.com/> under GPL3 or CC-BY-SA3.
+
+The Eadui font was made by Peter S. Baker and is available under the OFL (SIL Open Font License).
+DejaVu fonts were made by the DejaVu project and are available under http://dejavu-fonts.org/wiki/License .
+
+Hand cursor icon was done by yd of OpenGameArt (CC0)
diff --git a/demo/data/ZHMW1A1.bam b/demo/data/ZHMW1A1.bam
new file mode 100644
index 0000000..70d429e
Binary files /dev/null and b/demo/data/ZHMW1A1.bam differ
diff --git a/demo/data/ZHMW1A2.bam b/demo/data/ZHMW1A2.bam
new file mode 100644
index 0000000..6054c60
Binary files /dev/null and b/demo/data/ZHMW1A2.bam differ
diff --git a/demo/data/ZHMW1A3.bam b/demo/data/ZHMW1A3.bam
new file mode 100644
index 0000000..e14b2e3
Binary files /dev/null and b/demo/data/ZHMW1A3.bam differ
diff --git a/demo/data/ZHMW1A4.bam b/demo/data/ZHMW1A4.bam
new file mode 100644
index 0000000..4c3f0f4
Binary files /dev/null and b/demo/data/ZHMW1A4.bam differ
diff --git a/demo/data/ZHMW1A5.bam b/demo/data/ZHMW1A5.bam
new file mode 100644
index 0000000..3970d96
Binary files /dev/null and b/demo/data/ZHMW1A5.bam differ
diff --git a/demo/data/ZHMW1A6.bam b/demo/data/ZHMW1A6.bam
new file mode 100644
index 0000000..9f1aa31
Binary files /dev/null and b/demo/data/ZHMW1A6.bam differ
diff --git a/demo/data/ZHMW1A7.bam b/demo/data/ZHMW1A7.bam
new file mode 100644
index 0000000..50a8800
Binary files /dev/null and b/demo/data/ZHMW1A7.bam differ
diff --git a/demo/data/ZHMW1A8.bam b/demo/data/ZHMW1A8.bam
new file mode 100644
index 0000000..00694a4
Binary files /dev/null and b/demo/data/ZHMW1A8.bam differ
diff --git a/demo/data/ZHMW1CA.bam b/demo/data/ZHMW1CA.bam
new file mode 100644
index 0000000..64e9402
Binary files /dev/null and b/demo/data/ZHMW1CA.bam differ
diff --git a/demo/data/ZHMW1DE.bam b/demo/data/ZHMW1DE.bam
new file mode 100644
index 0000000..0054287
Binary files /dev/null and b/demo/data/ZHMW1DE.bam differ
diff --git a/demo/data/ZHMW1GH.bam b/demo/data/ZHMW1GH.bam
new file mode 100644
index 0000000..e0b218b
Binary files /dev/null and b/demo/data/ZHMW1GH.bam differ
diff --git a/demo/data/ZHMW1GU.bam b/demo/data/ZHMW1GU.bam
new file mode 100644
index 0000000..dc06134
Binary files /dev/null and b/demo/data/ZHMW1GU.bam differ
diff --git a/demo/data/ZHMW1SC.bam b/demo/data/ZHMW1SC.bam
new file mode 100644
index 0000000..461755b
Binary files /dev/null and b/demo/data/ZHMW1SC.bam differ
diff --git a/demo/data/ZHMW1SD.bam b/demo/data/ZHMW1SD.bam
new file mode 100644
index 0000000..8c1219b
Binary files /dev/null and b/demo/data/ZHMW1SD.bam differ
diff --git a/demo/data/ZHMW1SL.bam b/demo/data/ZHMW1SL.bam
new file mode 100644
index 0000000..423eaa2
Binary files /dev/null and b/demo/data/ZHMW1SL.bam differ
diff --git a/demo/data/ZHMW1SP.bam b/demo/data/ZHMW1SP.bam
new file mode 100644
index 0000000..1016ecb
Binary files /dev/null and b/demo/data/ZHMW1SP.bam differ
diff --git a/demo/data/ZHMW1TW.bam b/demo/data/ZHMW1TW.bam
new file mode 100644
index 0000000..1c0004c
Binary files /dev/null and b/demo/data/ZHMW1TW.bam differ
diff --git a/demo/data/ZHMW1WK.bam b/demo/data/ZHMW1WK.bam
new file mode 100644
index 0000000..b1a49c6
Binary files /dev/null and b/demo/data/ZHMW1WK.bam differ
diff --git a/demo/data/action.ids b/demo/data/action.ids
new file mode 100644
index 0000000..e69de29
diff --git a/demo/data/ar0100.are b/demo/data/ar0100.are
new file mode 100644
index 0000000..23d1f31
Binary files /dev/null and b/demo/data/ar0100.are differ
diff --git a/demo/data/ar0100.mos b/demo/data/ar0100.mos
new file mode 100644
index 0000000..a71ac25
Binary files /dev/null and b/demo/data/ar0100.mos differ
diff --git a/demo/data/ar0100.tis b/demo/data/ar0100.tis
new file mode 100755
index 0000000..53aaea4
Binary files /dev/null and b/demo/data/ar0100.tis differ
diff --git a/demo/data/avatars.2da b/demo/data/avatars.2da
new file mode 100644
index 0000000..c8a4d12
--- /dev/null
+++ b/demo/data/avatars.2da
@@ -0,0 +1,8 @@
+2DA V1.0
+*
+ AT_1 AT_2 AT_3 AT_4 TYPE SPACE PALETTE SIZE
+0x0300 SPSMPUFF SPSMPUFF SPSMPUFF SPSMPUFF 13 0 0 *
+0x0400 SKLH SKLH SKLH SKLH 13 0 1 *
+0x1000 MWYV MWYV MWYV MWYV 11 3 1 *
+0xc800 ZHMW1 ZHMW1 ZHMW1 ZHMW1 9 2 1 *
+
diff --git a/demo/data/carot.bam b/demo/data/carot.bam
new file mode 100644
index 0000000..ea697cf
Binary files /dev/null and b/demo/data/carot.bam differ
diff --git a/demo/data/chrmodst.2da b/demo/data/chrmodst.2da
new file mode 100644
index 0000000..eb83234
--- /dev/null
+++ b/demo/data/chrmodst.2da
@@ -0,0 +1,4 @@
+2DA V1.0
+*
+ RESREF
+DEFAULT *
diff --git a/demo/data/classes.2da b/demo/data/classes.2da
new file mode 100644
index 0000000..e69de29
diff --git a/demo/data/clskills.2da b/demo/data/clskills.2da
new file mode 100644
index 0000000..e69de29
diff --git a/demo/data/cursors.bam b/demo/data/cursors.bam
new file mode 100644
index 0000000..65bc513
Binary files /dev/null and b/demo/data/cursors.bam differ
diff --git a/demo/data/defsound.2da b/demo/data/defsound.2da
new file mode 100644
index 0000000..eb83234
--- /dev/null
+++ b/demo/data/defsound.2da
@@ -0,0 +1,4 @@
+2DA V1.0
+*
+ RESREF
+DEFAULT *
diff --git a/demo/data/dexmod.2da b/demo/data/dexmod.2da
new file mode 100644
index 0000000..eb83234
--- /dev/null
+++ b/demo/data/dexmod.2da
@@ -0,0 +1,4 @@
+2DA V1.0
+*
+ RESREF
+DEFAULT *
diff --git a/demo/data/effects.ids b/demo/data/effects.ids
new file mode 100644
index 0000000..e69de29
diff --git a/demo/data/fist.itm b/demo/data/fist.itm
new file mode 100644
index 0000000..cb5f60d
Binary files /dev/null and b/demo/data/fist.itm differ
diff --git a/demo/data/fogowar.bam b/demo/data/fogowar.bam
new file mode 100644
index 0000000..b3af33b
Binary files /dev/null and b/demo/data/fogowar.bam differ
diff --git a/demo/data/fonts.2da b/demo/data/fonts.2da
new file mode 100644
index 0000000..a96cdde
--- /dev/null
+++ b/demo/data/fonts.2da
@@ -0,0 +1,10 @@
+2DA V1.0
+NORMAL
+ RESREF NEED_PALETTE FONT_NAME PT_SIZE STYLE COLOR
+0 NORMAL 1 DejaVuSans 14 0 0xffffffff
+1 FLOATTXT 1 DejaVuSans 12 0 0xffffffff
+#these are the same font so list the larger one first and gemrb only needs to create one font
+2 INITIALS 0 Eadui 36 0 0xffffffff
+3 NUMBER 0 Eadui 14 0 0xffffffff
+
+# Customization How To: http://gemrb.sourceforge.net/wiki/doku.php?id=plugins:ttf
diff --git a/gemrb/override/bg1/gametime.2da b/demo/data/gametime.2da
similarity index 100%
rename from gemrb/override/bg1/gametime.2da
rename to demo/data/gametime.2da
diff --git a/demo/data/gem-demo.gam b/demo/data/gem-demo.gam
new file mode 100644
index 0000000..5bd90c1
Binary files /dev/null and b/demo/data/gem-demo.gam differ
diff --git a/demo/data/gemrb.ini b/demo/data/gemrb.ini
new file mode 100644
index 0000000..9740721
--- /dev/null
+++ b/demo/data/gemrb.ini
@@ -0,0 +1,126 @@
+; GemRB - Infinity Engine Emulator
+; Copyright (C) 2003 The GemRB Project
+;
+; This program is free software; you can redistribute it and/or
+; modify it under the terms of the GNU General Public License
+; as published by the Free Software Foundation; either version 2
+; of the License, or (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program; if not, write to the Free Software
+; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+;
+
+
+; gemrb.ini - game type-specific settings for GemRB engine
+
+[resources]
+
+; Bitmap resource for cursors
+CursorBAM = CAROT
+
+; Bitmap resource for scroll cursor arrow
+ScrollCursorBAM = CURSORS
+
+; Bitmap resource for dialog buttons font
+ButtonFont = STONESML
+
+; Font used to display subtitles (ToB)
+MovieFont = STONESML
+
+; Font used to display tooltips
+TooltipFont = TOOLFONT
+
+; Sprite displayed behind the tooltip text, if any
+TooltipBack = TOOLSCRL
+
+; Tooltip text color (RGBA)
+TooltipColor = #f0b08000
+
+; Space between tooltip text and sides of TooltipBack (x2)
+#TooltipMargin = 10
+TooltipMargin = 5
+
+; INI file from the original games
+INIConfig = gem-demo.ini
+
+; Palette bitmaps in various widths
+Palette16 = palette
+Palette32 = palette
+Palette256 = palette
+
+3EdRules = 0
+AllStringsTagged = 0
+AreaVisitedVar = 0
+AreaOverride = 0
+AutomapINI = 0
+AutoSearchHidden = 1
+BiographyIsRes = 0
+BreakableWeapons = 0
+CastingSounds = 1
+ChallengeRating = 0
+CharNameIsGabber = 0
+CheckAbilities = 1
+CutsceneAreascripts = 0
+DeathOnZeroStat = 1
+DialogueScrolls = 0
+EnhancedCastingSounds = 1
+EnhancedEffects = 0
+FistStat = 232
+ForceAreaScript = 0
+FlexibleWorldmap = 0
+ForceStereo = 0
+HasBeastsINI = 0
+HasDescIcon = 1
+HasDPLAYER = 1
+HasEXPTABLE = 0
+HasFloatMenu = 0
+HasHideInShadows = 1
+HasKaputz = 0
+HasNoNPCFlag = 1
+HasPartyINI = 0
+HasPickSound = 0
+HasResDataIni = 0
+HasSongList = 1
+HasSoundsIni = 0
+HasSpecificDamageBonus = 0
+HasSpellList = 0
+HasUsePointFlag = 1
+HasWisdomBonusTable = 0
+IgnoreButtonFrames = 1
+IWD2DeathVarFormat = 0
+IWD2ScriptName = 0
+IWDMapDimensions = 0
+JournalHasSections = 1
+KnowWorld = 0
+LevelslotPerClass = 0
+LowerLabelText = 0
+MagicBit = 0
+MaximumAbility = 25
+NoDropCanMove = 0
+NoNewVariables = 0
+OneByteAnimationID = 0
+OnScreenText = 0
+ProperBackstab = 1
+ProtagonistTalks = 0
+PSTStateFlags = 0
+RareActionSounds = 0
+RedrawTile = 0
+ReverseDoor = 0
+ReverseToHit = 1
+SaveForHalfDamage = 0
+SelectiveMagicRes = 1
+SmallFog = 0
+SoundFolders = 0
+SpawnIni = 0
+SpellBookIconHack = 1
+StartActive = 1
+StealIsAttack = 1
+StrrefSaveGame = 0
+TeamMovement = 0
+UpperButtonText = 1
diff --git a/demo/data/guiw.chu b/demo/data/guiw.chu
new file mode 100644
index 0000000..9719c74
Binary files /dev/null and b/demo/data/guiw.chu differ
diff --git a/demo/data/hpconbon.2da b/demo/data/hpconbon.2da
new file mode 100644
index 0000000..eb83234
--- /dev/null
+++ b/demo/data/hpconbon.2da
@@ -0,0 +1,4 @@
+2DA V1.0
+*
+ RESREF
+DEFAULT *
diff --git a/demo/data/instant.ids b/demo/data/instant.ids
new file mode 100644
index 0000000..e69de29
diff --git a/demo/data/intmod.2da b/demo/data/intmod.2da
new file mode 100644
index 0000000..eb83234
--- /dev/null
+++ b/demo/data/intmod.2da
@@ -0,0 +1,4 @@
+2DA V1.0
+*
+ RESREF
+DEFAULT *
diff --git a/gemrb/override/bg2/itemtype.2da b/demo/data/itemtype.2da
similarity index 100%
copy from gemrb/override/bg2/itemtype.2da
copy to demo/data/itemtype.2da
diff --git a/demo/data/kitlist.2da b/demo/data/kitlist.2da
new file mode 100644
index 0000000..e69de29
diff --git a/demo/data/lorebon.2da b/demo/data/lorebon.2da
new file mode 100644
index 0000000..eb83234
--- /dev/null
+++ b/demo/data/lorebon.2da
@@ -0,0 +1,4 @@
+2DA V1.0
+*
+ RESREF
+DEFAULT *
diff --git a/demo/data/mapicon0.bam b/demo/data/mapicon0.bam
new file mode 100644
index 0000000..e9912b4
Binary files /dev/null and b/demo/data/mapicon0.bam differ
diff --git a/demo/data/mastarea.2da b/demo/data/mastarea.2da
new file mode 100644
index 0000000..b8c605b
--- /dev/null
+++ b/demo/data/mastarea.2da
@@ -0,0 +1,4 @@
+2DA V1.0
+0
+ LABEL
+AR0100 value
diff --git a/demo/data/numtest.bam b/demo/data/numtest.bam
new file mode 100644
index 0000000..1e26902
Binary files /dev/null and b/demo/data/numtest.bam differ
diff --git a/demo/data/object.ids b/demo/data/object.ids
new file mode 100644
index 0000000..e69de29
diff --git a/demo/data/palette.png b/demo/data/palette.png
new file mode 100644
index 0000000..e2880a9
Binary files /dev/null and b/demo/data/palette.png differ
diff --git a/demo/data/protagon.cre b/demo/data/protagon.cre
new file mode 100644
index 0000000..5a1a749
Binary files /dev/null and b/demo/data/protagon.cre differ
diff --git a/demo/data/purple.mos b/demo/data/purple.mos
new file mode 100644
index 0000000..685588b
Binary files /dev/null and b/demo/data/purple.mos differ
diff --git a/demo/data/races.2da b/demo/data/races.2da
new file mode 100644
index 0000000..e69de29
diff --git a/demo/data/script.2da b/demo/data/script.2da
new file mode 100644
index 0000000..eb83234
--- /dev/null
+++ b/demo/data/script.2da
@@ -0,0 +1,4 @@
+2DA V1.0
+*
+ RESREF
+DEFAULT *
diff --git a/demo/data/scrlbar1.bam b/demo/data/scrlbar1.bam
new file mode 100644
index 0000000..da7ed64
Binary files /dev/null and b/demo/data/scrlbar1.bam differ
diff --git a/demo/data/slottype.2da b/demo/data/slottype.2da
new file mode 100644
index 0000000..078e49f
--- /dev/null
+++ b/demo/data/slottype.2da
@@ -0,0 +1,5 @@
+2DA V1.0
+*
+ BITS SCRIPT ICON STRREF EFFECT FLAGS
+0 0 0 * 0 2 0
+1 256 1 * 0 4 1
diff --git a/demo/data/source/ar0100.bmp b/demo/data/source/ar0100.bmp
new file mode 100644
index 0000000..106a572
Binary files /dev/null and b/demo/data/source/ar0100.bmp differ
diff --git a/demo/data/source/carot.bmp b/demo/data/source/carot.bmp
new file mode 100644
index 0000000..d224df0
Binary files /dev/null and b/demo/data/source/carot.bmp differ
diff --git a/demo/data/source/glove-pointy.png b/demo/data/source/glove-pointy.png
new file mode 100644
index 0000000..40971da
Binary files /dev/null and b/demo/data/source/glove-pointy.png differ
diff --git a/demo/data/source/purple.bmp b/demo/data/source/purple.bmp
new file mode 100644
index 0000000..c01a5ce
Binary files /dev/null and b/demo/data/source/purple.bmp differ
diff --git a/demo/data/source/scroll0.bmp b/demo/data/source/scroll0.bmp
new file mode 100644
index 0000000..644db98
Binary files /dev/null and b/demo/data/source/scroll0.bmp differ
diff --git a/demo/data/source/scroll1.bmp b/demo/data/source/scroll1.bmp
new file mode 100644
index 0000000..fc8c7ef
Binary files /dev/null and b/demo/data/source/scroll1.bmp differ
diff --git a/demo/data/source/scroll2.bmp b/demo/data/source/scroll2.bmp
new file mode 100644
index 0000000..6104c56
Binary files /dev/null and b/demo/data/source/scroll2.bmp differ
diff --git a/demo/data/source/scroll3.bmp b/demo/data/source/scroll3.bmp
new file mode 100644
index 0000000..ed5c94b
Binary files /dev/null and b/demo/data/source/scroll3.bmp differ
diff --git a/demo/data/source/scroll4.bmp b/demo/data/source/scroll4.bmp
new file mode 100644
index 0000000..dcc196f
Binary files /dev/null and b/demo/data/source/scroll4.bmp differ
diff --git a/demo/data/source/scroll5.bmp b/demo/data/source/scroll5.bmp
new file mode 100644
index 0000000..34ed4cc
Binary files /dev/null and b/demo/data/source/scroll5.bmp differ
diff --git a/gemrb/override/bg1/start.2da b/demo/data/start.2da
similarity index 100%
copy from gemrb/override/bg1/start.2da
copy to demo/data/start.2da
diff --git a/demo/data/startare.2da b/demo/data/startare.2da
new file mode 100644
index 0000000..b6d1f0e
--- /dev/null
+++ b/demo/data/startare.2da
@@ -0,0 +1,6 @@
+2DA V1.0
+BADVAL
+ VALUE
+START_AREA AR0100
+START_XPOS 760
+START_YPOS 760
diff --git a/demo/data/startpos.2da b/demo/data/startpos.2da
new file mode 100644
index 0000000..c178aa2
--- /dev/null
+++ b/demo/data/startpos.2da
@@ -0,0 +1,5 @@
+2DA V1.0
+0
+ 1 2 3 4 5 6
+START_XPOS 741 585 532 374 824 889
+START_YPOS 801 917 956 368 447 479
diff --git a/demo/data/strmod.2da b/demo/data/strmod.2da
new file mode 100644
index 0000000..eb83234
--- /dev/null
+++ b/demo/data/strmod.2da
@@ -0,0 +1,4 @@
+2DA V1.0
+*
+ RESREF
+DEFAULT *
diff --git a/demo/data/strmodex.2da b/demo/data/strmodex.2da
new file mode 100644
index 0000000..eb83234
--- /dev/null
+++ b/demo/data/strmodex.2da
@@ -0,0 +1,4 @@
+2DA V1.0
+*
+ RESREF
+DEFAULT *
diff --git a/demo/data/toolscrl.bam b/demo/data/toolscrl.bam
new file mode 100644
index 0000000..8668e2a
Binary files /dev/null and b/demo/data/toolscrl.bam differ
diff --git a/demo/data/trigger.ids b/demo/data/trigger.ids
new file mode 100644
index 0000000..e69de29
diff --git a/demo/data/worldmap.wmp b/demo/data/worldmap.wmp
new file mode 100644
index 0000000..939af9a
Binary files /dev/null and b/demo/data/worldmap.wmp differ
diff --git a/demo/data/xplevel.2da b/demo/data/xplevel.2da
new file mode 100644
index 0000000..e69de29
diff --git a/demo/dialog.tlk b/demo/dialog.tlk
new file mode 100644
index 0000000..518dc05
Binary files /dev/null and b/demo/dialog.tlk differ
diff --git a/demo/gem-demo.ini b/demo/gem-demo.ini
new file mode 100644
index 0000000..41db163
--- /dev/null
+++ b/demo/gem-demo.ini
@@ -0,0 +1,4 @@
+[Program Options]
+Full Screen = 0
+[Game Options]
+Mouse Scroll Speed = 15
diff --git a/gemrb.6.in b/gemrb.6.in
index c337b85..787e311 100644
--- a/gemrb.6.in
+++ b/gemrb.6.in
@@ -59,7 +59,7 @@ binary and then run
instead.
.\"###################################################
-.SH Configuration File
+.SH CONFIGURATION
.PD 0
A configuration file consists of pairs
.IR PARAMETER=VALUE ,
@@ -69,42 +69,48 @@ more than once, only the last occurence is used.
Empty lines and lines starting with `#' (hash sign) are ignored.
-.B Parameters:
+At least the
+.I GameType
+and
+.I GamePath
+parameters need to be changed. That is often enough, so do not fiddle with the other paths too much.
+
+.SH General Parameters:
.TP
-.BR GameType =(bg1|bg2|iwd|iwd2|how|pst)
+.BR GameType =(auto|bg1|bg2|iwd|iwd2|how|pst)
Type of the game. The value is a name of subdirectory in override/
and GUIScripts/ directories
with game type-specific files and scripts. It is at present also used
-for various tweaks hardcoded in the GemRB engine.
+for various tweaks hardcoded in the GemRB engine. To autodetect the game
+type, use "auto".
.TP
.BR GameName =STRING
Arbitrary name of the game. It will be displayed in the window's title bar.
.TP
-.BR GamePath =PATH
-Path to the directory where the original game is installed. If you can't
-install the game under MS Windows or with WINE, you can try to unpack the data files
-with the
-.I unshield
-program found at
-.IR http://synce.sourceforge.net .
+.BR Encoding =(default|polish|czech)
+Specify language used in the game data. Except of polish version of BG1, it's
+safe to leave it commented out.
.TP
-.BR CD1 =PATH
+.BR GUIEnhancements =INT
+The value is a bitfield. Setit to 1 to enable a few GUI enhancements, mostly in BG2.
+Set to 2 or 3 to try to autoidentify items on transfer (if the character has enough lore).
+Disabled by default.
+
.TP
-.BR CD2 =PATH
+.BR EndianSwitch =(0|1)
+Set this to 1 if you are running GemRB on a big-endian machine. Disabled by default.
+
.TP
-.BR CDn =...
-Path to the data files for the game's particular CDs.
+.BR MultipleQuickSaves =(0|1)
+EXPERIMENTAL. Set this to 1 if you want GemRB to keep multiple quicksaves around. Disabled by default.
-.\".TP
-.\".BR INIConfig =FILE
-.\"Name of the game's INI file, relative to
-.\".IR GamePath .
-.\"E.g. for Baldur's Gate game it is baldur.ini.
+.\"###################################################
+.SH Video Parameters:
.TP
.BR Width =INT
@@ -130,13 +136,6 @@ Color depth of the game window (in bits per pixel).
.BR Fullscreen =(0|1)
Whether the game should run in fullscreen mode.
-.\".TP
-.\".BR ForceStereo =(0|1)
-.\"Some older games such as BG1 and PST need this parameter to be
-.\".IR 1 .
-.\"For other game types set it to
-.\".IR 0 .
-
.TP
.BR TooltipDelay =INT
Delay (in miliseconds) before tooltips are displayed when the mouse is not moving.
@@ -146,6 +145,29 @@ The default is
.IR 100 .
.TP
+.BR SkipIntroVideos =(0|1)
+If set to
+.IR 1 ,
+the intro and logo videos are skipped to save developer's nerves. The default is
+.IR 0 .
+
+.TP
+.BR FogOfWar =(0|1)
+If set to
+.IR 1 ,
+the unexplored parts of an area are blacked out. It is enabled by default.
+
+
+.\"###################################################
+.SH Audio Parameters:
+
+.TP
+.BR AudioDriver =(openal|sdlaudio|none)
+Use the specified plugin as the audio driver. The default is openal, while
+.I none
+will disable all audio.
+
+.TP
.BR VolumeAmbients =INT
Volume of ambient sounds in percents. The default is
.IR 100 .
@@ -170,26 +192,186 @@ Volume of sound effects in percents. The default is
Volume of PC or NPC voices in percents. The default is
.IR 100 .
+.\"###################################################
+.SH Path parameters:
.TP
-.BR SkipIntroVideos =(0|1)
-This parameter is meant for developers. If set to
+.BR CaseSensitive =(0|1)
+When
+this parameter is set to
.IR 1 ,
-the intro and logo videos are skipped to save developer's nerves. The default is
-.IR 0 .
+the engine will try to find files regardless of their names' case at the cost
+of a slight speed penalty. This is especially important when using
+game files on CD-ROMs, where the files can't be renamed. Like
+many Windows programs, the original games use inconsistent mix
+of lower/upper case letters for naming and referencing their files.
+
+Set this parameter to
+.I 1
+on Unix-like systems.
.TP
-.BR DrawFPS =(0|1)
-This parameter is meant for developers. If set to
-.IR 1 ,
-the current FPS (Frames per Second) value is drawn in the top left window corner. The default is
-.IR 0 .
+.BR GamePath =PATH
+Path to the directory where the original game is installed. If you can't
+install the game under MS Windows or with WINE, you can try to unpack the data files
+with the
+.I unshield
+program found at
+.IR http://synce.sourceforge.net .
.TP
-.BR FogOfWar =(0|1)
-If set to
-.IR 1 ,
-the unexplored parts of an area are blacked out. It is enabled by default.
+.BR CD1 =PATH
+.TP
+.BR CD2 =PATH
+.TP
+.BR CDn =...
+Path to the data files for the game's particular CDs or any other data sources.
+
+.TP
+.BR CachePath =PATH
+User-writable directory where the engine caches uncompressed and temporary
+files. Defaults to a subdirectory of the current directory.
+
+.TP
+.BR GemRBPath =PATH
+Path to the GemRB installation. (To be obsoleted; preset at build time).
+
+.TP
+.BR GUIScriptsPath =PATH
+Path to the directory with scripts controlling the game's GUI. (To be obsoleted; preset at build time).
+
+.TP
+.BR GemRBOverridePath =PATH
+Path where GemRB looks for its game override directory.
+It defaults to
+.IR GemRBPath .
+GemRB reuses some of the unused files from the original or replaces them
+and this is the where they can be found. The path is preset at build time.
+This directory has the highest priority when searching, so putting files in
+the game override will not affect them. Use another directory and add it as
+.IR ModPath
+to the GemRB config.
+
+.TP
+.BR GemRBUnhardcodedPath =PATH
+Path where GemRB looks for its unhardcoded engine data.
+It defaults to
+.IR GemRBPath .
+The original games hardcoded this information in the engine.
+The path is preset at build time.
+
+.TP
+.I The following variables do not need to be altered, unless you are doing something really special!
+
+.TP
+.BR SavePath =PATH
+Path to the directory with save games. Note that this directory has to
+contain
+.I save/
+and/or eventually
+.I mpsave/
+subdirectories and that only these subdirectories contain the actual
+saved games.
+
+.I SavePath
+defaults to
+.IR GamePath .
+
+.TP
+.BR GameDataPath =PATH
+Path to the original game's installed data files, relative to GamePath.
+Usually it's
+.IR data .
+
+.TP
+.BR GameOverridePath =PATH
+Path to the original game's override dir, relative to GamePath.
+Usually it's
+.IR override .
+Original games use this directory to place last-minute patches.
+
+.TP
+.BR GameCharactersPath =PATH
+Path to the original game's installed data files, relative to GamePath.
+Usually it's
+.IR characters .
+
+.TP
+.BR GamePortraitsPath =PATH
+Path to the original game's installed data files, relative to GamePath.
+Usually it's
+.IR portraits .
+
+.TP
+.BR GameScriptsPath =PATH
+Path to the original game's installed data files, relative to GamePath.
+Usually it's
+.IR scripts .
+
+.TP
+.BR GameSoundsPath =PATH
+Path to the original game's installed data files, relative to GamePath.
+Usually it's
+.IR sounds .
+
+.TP
+.BR ModPath =PATH
+Path where GemRB looks for additional engine override files.
+It is not set by default. This directory has precedence over
+.IR GemRBOverridePath .
+
+.TP
+.BR CustomFontPath =PATH
+Path where GemRB looks for additional font files. It is meant to be used
+with the TTF font plugin and fonts.2da as a way to specify where to look for
+system or other external fonts. Check the online documentation for the details.
+It is not set by default.
+
+.\"###################################################
+.SH Input Parameters:
+
+.TP
+.BR DoubleClickDelay =INT
+Milisecond threshold for detecting a double click. The default is 250.
+
+.TP
+.BR RepeatKeyDelay =INT
+Milisecond threshold for detecting a repeated key press. The default is 250.
+
+.TP
+.BR TouchScrollAreas =(0|1)
+Toggles a wider and visible gutter around the screen for scrolling the game
+area. Intended for devices with a touch interface. Disabled by default.
+
+.TP
+.BR UseSoftKeyboard =(0|1)
+Toggles use of software keyboard on devices that support one. It pops up when
+text input is required. Disabled by default.
+
+.TP
+.BR NumFingScroll =(2|3|4)
+Number of fingers for multitouch to trigger scrolling. The default is 2.
+
+.TP
+.BR NumFingKboard =(2|3|4)
+Number of fingers for multitouch to open up the software keyboard. The default is 3.
+The value should not be equal to
+.IR NumFingScroll " above."
+
+.TP
+.BR NumFingInfo =(2|3|4)
+Number of fingers for multitouch to emulate a special keypress (alt, tab). The default is 2.
+
+.TP
+.BR MouseFeedback =(0-3)
+Bitfield with reserved bits for disabling the mouse.
+ Show mouse+tooltips = 0 (default)
+ Hide mouse = 1
+ Hide tooltips = 2
+ Hide mouse+tooltips = 3
+
+.\"###################################################
+.SH Development parameters:
.TP
.BR EnableCheatKeys =(0|1)
@@ -202,6 +384,13 @@ file. Do NOT use this option unless you want to make your hands dirty :-). The d
.IR 0 .
.TP
+.BR DrawFPS =(0|1)
+This parameter is meant for developers. If set to
+.IR 1 ,
+the current FPS (Frames per Second) value is drawn in the top left window corner. The default is
+.IR 0 .
+
+.TP
.BR ScriptDebugMode =(n)
This parameter is meant for developers. It is a combination of bit values
@@ -224,21 +413,6 @@ The default is
.IR 0 .
.TP
-.BR CaseSensitive =(0|1)
-When
-this parameter is set to
-.IR 1 ,
-the engine will try to find files regardless of their names' case at the cost
-of a slight speed penalty. This is especially important when using
-game files on CD-ROMs, where the files can't be renamed. Like
-many Windows programs, the original games use inconsistent mix
-of lower/upper case letters for naming and referencing their files.
-
-Set this parameter to
-.I 1
-on Unix-like systems.
-
-.TP
.BR DelayPlugin =FILENAME
Named plugin will be loaded after other (nondelayed) plugins were loaded.
.IR FILENAME
@@ -259,76 +433,29 @@ or
You can use this parameter more than once.
.TP
-.BR AudioDriver =(openal|sdlaudio|none)
-Use the specified plugin as the audio driver. The default is openal, while
-.I none
-will disable all audio.
-
-.TP
.BR SaveAsOriginal =(0|1)
Set this parameter to
.IR 1 ,
if you want to keep the save game compatible with the original engine. It is enabled by default.
.TP
-.BR CachePath =PATH
-User-writable directory where the engine caches uncompressed and temporary
-files.
-
-.TP
-.BR GemRBPath =PATH
-Path to the GemRB installation. (To be obsoleted; preset at build time).
-
-.TP
-.BR GUIScriptsPath =PATH
-Path to the directory with scripts controlling the game's GUI.
-
-.TP
-.BR SavePath =PATH
-Path to the directory with save games. Note that this directory has to
-contain
-.I save/
-and/or eventually
-.I mpsave/
-subdirectories and that only these subdirectories contain the actual
-saved games.
-
-.I SavePath
-defaults to
-.IR GamePath .
-
-.TP
-.BR GameOnCD =(0|1)
-defaults to
-.IR 0 .
-
-
-.TP
-.BR GameDataPath =PATH
-Path to the original game's installed data files, relative to GamePath.
-Usually it's
-.IR data .
-
-
-.TP
-.BR GameOverridePath =PATH
-Path to the original game's override dir, relative to GamePath.
-Usually it's
-.IR override .
-Original games use this directory to place last-minute patches.
+.BR KeepCache =(0|1)
+Set this parameter to
+.IR 1 ,
+if you want to keep the cache after exiting GemRB. It is disabled by default.
.TP
-.BR GemRBOverridePath =PATH
-Path where GemRB looks for its game override directory.
-It defaults to
-.IR GemRBPath .
-The original games hardcoded this information in the engine.
+.BR IgnoreOriginalINI =(0|1)
+Set this parameter to
+.IR 1 ,
+if you want to ignore the settings from the original configuration files - baldur.ini
+/ icewind.ini / torment.ini. It is disabled by default.
.\"###################################################
.SH FILES
.PD 0
-.TP 20
+.TP
.B @SYSCONF_DIR@/gemrb.cfg
system-wide configuration file
@@ -363,17 +490,17 @@ Many.
is still in an early development stage and not nearly complete.
If you stumble over something which is supposed to work, either make a bug report
-at http://sourceforge.net/projects/gemrb or come to IRC channel
+at http://sourceforge.net/projects/gemrb or come to the official IRC channel
.I #GemRB
at FreeNode.
.\"###################################################
.SH AUTHOR
-The GemRB Project development team at http://gemrb.sourceforge.net
+The GemRB Project development team at http://gemrb.org
.\"###################################################
.SH COPYING
-Copyright (C) 2003-2008 The GemRB Project
+Copyright (C) 2003-2011 The GemRB Project
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/gemrb/CMakeLists.txt b/gemrb/CMakeLists.txt
index 0abc5d9..1739f44 100644
--- a/gemrb/CMakeLists.txt
+++ b/gemrb/CMakeLists.txt
@@ -1,24 +1,91 @@
ADD_SUBDIRECTORY( core )
+
+# GUIScripts and override go directly in the bundle
+SET(RESOURCE_LIST "GUIScripts" "override" "unhardcoded")
+SET(RESOURCE_FILES "")
+
+FOREACH(RESOURCE_DIR_NAME ${RESOURCE_LIST})
+ SET(RESOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${RESOURCE_DIR_NAME}")
+ IF (APPLE)
+ FILE(GLOB CHILDREN RELATIVE "${RESOURCE_DIR}" ${RESOURCE_DIR}/*)
+ FOREACH(CHILD ${CHILDREN})
+ IF(IS_DIRECTORY "${RESOURCE_DIR}/${CHILD}")
+ # be wary of .DS_Store files. glob them out by using [A-Za-z]*.*
+ FILE(GLOB RESOURCE_DIR_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${RESOURCE_DIR}/${CHILD}/[A-Za-z]*.*")
+ SET_SOURCE_FILES_PROPERTIES(
+ ${RESOURCE_DIR_FILES}
+ PROPERTIES MACOSX_PACKAGE_LOCATION Resources/${RESOURCE_DIR_NAME}/${CHILD}
+ )
+ SET(RESOURCE_FILES ${RESOURCE_FILES} ${RESOURCE_DIR_FILES})
+ ELSE()
+ IF (NOT ${CHILD} MATCHES "\\.DS_Store|.*\\.am")
+ SET_SOURCE_FILES_PROPERTIES(
+ "${RESOURCE_DIR}/${CHILD}"
+ PROPERTIES MACOSX_PACKAGE_LOCATION Resources/${RESOURCE_DIR_NAME}
+ )
+ SET(RESOURCE_FILES ${RESOURCE_FILES} "${RESOURCE_DIR_NAME}/${CHILD}")
+ ENDIF()
+ ENDIF()
+ ENDFOREACH()
+ ELSE (APPLE)
+ INSTALL( DIRECTORY ${RESOURCE_DIR} DESTINATION "${DATA_DIR}" PATTERN "*.am" EXCLUDE)
+ ENDIF (APPLE)
+ENDFOREACH()
+
+IF(APPLE) #application bundle generation
+ # icon
+ SET_SOURCE_FILES_PROPERTIES(
+ ../artwork/gemrb.icns
+ PROPERTIES MACOSX_PACKAGE_LOCATION Resources
+ )
+
+ # default values
+ SET_SOURCE_FILES_PROPERTIES(
+ ../apple/defaults.plist
+ PROPERTIES MACOSX_PACKAGE_LOCATION Resources
+ )
+
+ SET(MACOSX_BUNDLE_ICON_FILE gemrb)
+ ADD_EXECUTABLE(gemrb MACOSX_BUNDLE ../apple/CocoaWrapper/mac/CocoaWrapper.mm ../apple/AppleLogger.mm
+ ../artwork/gemrb.icns ../apple/defaults.plist
+ ${RESOURCE_FILES})
+ SET (BUNDLE_LOADER "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.app/Contents/MacOS/${PROJECT_NAME}") # BUNDLE_LOADER is used by plugins needing to extend the cocoa wrapper (SDLVideo).
+ SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -bundle_loader \"${BUNDLE_LOADER}\"")
+ELSE(APPLE)
+ ADD_SUBDIRECTORY( docs )
+ ADD_SUBDIRECTORY( tests )
+
+ ADD_EXECUTABLE(gemrb GemRB.cpp )
+
+ INSTALL( FILES "${CMAKE_CURRENT_BINARY_DIR}/GemRB.cfg.sample" GemRB.cfg.noinstall.sample DESTINATION ${EXAMPLE_CONF_DIR} )
+ENDIF(APPLE)
+
+# we need to add gemrb target before processing plugins or COCOA plugins don't work right.
ADD_SUBDIRECTORY( plugins )
-ADD_SUBDIRECTORY( override )
-ADD_SUBDIRECTORY( GUIScripts )
-ADD_SUBDIRECTORY( docs )
-ADD_SUBDIRECTORY( tests )
-ADD_EXECUTABLE(gemrb GemRB.cpp )
SET_TARGET_PROPERTIES(gemrb PROPERTIES INSTALL_RPATH ${LIB_DIR})
INCLUDE_DIRECTORIES( ${SDL_INCLUDE_DIR} )
IF(WIN32)
TARGET_LINK_LIBRARIES(gemrb gemrb_core)
ELSE(WIN32)
IF(APPLE)
+ # custom info.plist
+ SET_TARGET_PROPERTIES(gemrb PROPERTIES MACOSX_BUNDLE_INFO_PLIST ../../apple/osx/Info.plist)
+
+ # compile nib
+ ADD_CUSTOM_COMMAND (TARGET gemrb POST_BUILD
+ COMMAND ${IBTOOL} --errors --warnings --notices --output-format human-readable-text
+ --compile ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.app/Contents/Resources/GemRB.nib
+ ../../apple/CocoaWrapper/mac/nibs/GemRB.xib
+ COMMENT "Compiling GemRB.xib")
+
if (STATIC_LINK)
- TARGET_LINK_LIBRARIES(gemrb ${SDL_LIBRARY}
- ${SDL_MAIN_LIBRARY_PATH} ${COCOA_LIBRARY_PATH} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}
+ TARGET_LINK_LIBRARIES(gemrb
+ ${COCOA_LIBRARY_PATH} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}
gemrb_core ${plugins} -Wl,-all_load)
else (STATIC_LINK)
- TARGET_LINK_LIBRARIES(gemrb gemrb_core ${SDL_LIBRARY}
- ${SDL_MAIN_LIBRARY_PATH} ${COCOA_LIBRARY_PATH} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT})
+ TARGET_LINK_LIBRARIES(gemrb gemrb_core
+ ${COCOA_LIBRARY_PATH} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT})
endif (STATIC_LINK)
ELSE(APPLE)
if (STATIC_LINK)
@@ -38,4 +105,3 @@ CONFIGURE_FILE(
)
INSTALL( TARGETS gemrb DESTINATION ${BIN_DIR} )
-INSTALL( FILES "${CMAKE_CURRENT_BINARY_DIR}/GemRB.cfg.sample" GemRB.cfg.noinstall.sample DESTINATION ${SYSCONF_DIR} )
diff --git a/gemrb/GUIScripts/Actor.py b/gemrb/GUIScripts/Actor.py
index fd2e2cb..c970a5d 100644
--- a/gemrb/GUIScripts/Actor.py
+++ b/gemrb/GUIScripts/Actor.py
@@ -20,6 +20,7 @@
# Actor.py: Contains the actor class.
import GemRB
+import GUICommon
from GUIDefines import *
from ie_stats import *
#this import is primarily for the tables
@@ -55,12 +56,13 @@ class Actor:
dualswap = [0]*classcount
for i in range(classcount):
- classid = CommonTables.Classes.GetValue (i, 5)
- classnames = CommonTables.Classes.GetRowName(i).split("_")
+ rowname = CommonTables.Classes.GetRowName(i)
+ classid = CommonTables.Classes.GetValue (rowname, "ID")
+ classnames = rowname.split("_")
#set the MC_WAS_ID of the first class
if len(classnames) == 2:
- dualswap[classid-1] = CommonTables.Classes.GetValue (i, 8)
+ dualswap[classid-1] = CommonTables.Classes.GetValue (rowname, "MC_WAS_ID")
def Classes (self):
"""Returns a list with all the class IDs."""
@@ -74,7 +76,7 @@ class Actor:
"""Returns a list will all the class names."""
if self.__classnames == None:
- self.__classnames = CommonTables.Classes.GetRowName (CommonTables.Classes.FindValue (5, self.classid) ).split("_")
+ self.__classnames = GUICommon.GetClassRowName (self.classid, "class").split("_")
if self.IsDualSwap():
self.__classnames.reverse()
return self.__classnames
@@ -86,10 +88,10 @@ class Actor:
return self.__classtitle
self.__classtitle = GemRB.GetPlayerStat (self.pc, IE_TITLE1)
-
+ self.ClassNames()
if self.__classtitle == 0:
if self.multiclass and self.isdual == 0:
- self.__classtitle = CommonTables.Classes.GetValue (self.classindex, 2)
+ self.__classtitle = CommonTables.Classes.GetValue ("_".join(self.__classnames), "CAP_REF")
self.__classtitle = GemRB.GetString (self.__classtitle)
elif self.isdual:
# first (previous) kit or class of the dual class
@@ -97,16 +99,14 @@ class Actor:
if self.KitIndex():
self.__classtitle = CommonTables.KitList.GetValue (self.__kitindex, 2)
else:
- self.__classtitle = CommonTables.Classes.GetValue (CommonTables.Classes.FindValue \
- (5, self.__classes[1]), 2)
+ self.__classtitle = CommonTables.Classes.GetValue (self.__classnames[1], "CAP_REF")
self.__classtitle = GemRB.GetString (self.__classtitle) + " / " + \
- GemRB.GetString (CommonTables.Classes.GetValue (CommonTables.Classes.FindValue \
- (5, self.__classes[0]), 2) )
+ GemRB.GetString (CommonTables.Classes.GetValue (self.__classnames[0], "CAP_REF") )
else: # ordinary class or kit
if self.KitIndex():
self.__classtitle = CommonTables.KitList.GetValue (self.__kitindex, 2)
else:
- self.__classtitle = CommonTables.Classes.GetValue (self.classindex, 2)
+ self.__classtitle = CommonTables.Classes.GetValue ("_".join(self.__classnames), "CAP_REF")
self.__classtitle = GemRB.GetString (self.__classtitle)
if self.__classtitle == "*":
@@ -210,9 +210,8 @@ class Actor:
#accessible variables
self.pc = pc
self.classid = GemRB.GetPlayerStat (self.pc, IE_CLASS)
- self.classindex = CommonTables.Classes.FindValue (5, self.classid)
self.isdual = GemRB.GetPlayerStat (self.pc, IE_MC_FLAGS) & MC_WAS_ANY_CLASS
- self.multiclass = CommonTables.Classes.GetValue (self.classindex, 4)
+ self.multiclass = CommonTables.Classes.GetValue (GUICommon.GetClassRowName (pc), "MULTI")
#internal variables - these are only intialized on the first
#call to their respective function, and stored thereafter
diff --git a/gemrb/GUIScripts/BGCommon.py b/gemrb/GUIScripts/BGCommon.py
index baf9e1c..82feff5 100644
--- a/gemrb/GUIScripts/BGCommon.py
+++ b/gemrb/GUIScripts/BGCommon.py
@@ -20,7 +20,8 @@
import GemRB
import CommonTables
-from ie_stats import IE_RACE, IE_CLASS, IE_SEX
+import GUICommon
+from ie_stats import IE_RACE, IE_SEX
def RefreshPDoll(button, MinorColor, MajorColor, SkinColor, HairColor):
MyChar = GemRB.GetVar ("Slot")
@@ -29,8 +30,8 @@ def RefreshPDoll(button, MinorColor, MajorColor, SkinColor, HairColor):
Race = GemRB.GetPlayerStat (MyChar, IE_RACE)
AnimID = AnimID + table.GetValue(Race, 0)
table = GemRB.LoadTable ("avprefc")
- Class = GemRB.GetPlayerStat (MyChar, IE_CLASS)
- AnimID = AnimID + table.GetValue (Class, 0)
+ ClassName = GUICommon.GetClassRowName (MyChar)
+ AnimID = AnimID + table.GetValue (ClassName, "CLASS")
table = GemRB.LoadTable ("avprefg")
Gender = GemRB.GetPlayerStat (MyChar, IE_SEX)
AnimID = AnimID + table.GetValue (Gender, 0)
diff --git a/gemrb/GUIScripts/CMakeLists.txt b/gemrb/GUIScripts/CMakeLists.txt
deleted file mode 100644
index 811c581..0000000
--- a/gemrb/GUIScripts/CMakeLists.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-FILE( GLOB FILES_TO_INSTALL *.py )
-
-INSTALL( FILES ${FILES_TO_INSTALL} DESTINATION ${DATA_DIR}/GUIScripts )
-
-ADD_SUBDIRECTORY( bg1 )
-ADD_SUBDIRECTORY( bg2 )
-ADD_SUBDIRECTORY( iwd )
-ADD_SUBDIRECTORY( iwd2 )
-ADD_SUBDIRECTORY( pst )
-
-INSTALL( DIRECTORY test DESTINATION ${DATA_DIR}/GUIScripts )
diff --git a/gemrb/GUIScripts/CommonTables.py b/gemrb/GUIScripts/CommonTables.py
index cda3f95..b8637b4 100644
--- a/gemrb/GUIScripts/CommonTables.py
+++ b/gemrb/GUIScripts/CommonTables.py
@@ -17,17 +17,19 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# the place for preloading the most commonly used tables
+# helps with code deduplication, reduced log spam and tiny lookup savings
import GemRB
from ie_restype import RES_2DA
# these two are only used in SetEncumbranceLabels, but that is called very often
StrMod = StrModEx = None
Classes = KitList = ClassSkills = Races = NextLevel = None
-Pdolls = None
+Pdolls = SpellDisplay = Aligns = ItemType =None
def Load():
global Classes, KitList, ClassSkills, Races, NextLevel
- global Pdolls, StrModEx, StrMod
+ global Pdolls, StrModEx, StrMod, SpellDisplay, Aligns
+ global ItemType
print # so the following output isn't appended to an existing line
if not Classes:
@@ -45,3 +47,9 @@ def Load():
if not StrMod:
StrMod = GemRB.LoadTable ("strmod")
StrModEx = GemRB.LoadTable ("strmodex")
+ if not SpellDisplay:
+ SpellDisplay = GemRB.LoadTable ("spldisp")
+ if not Aligns and GemRB.HasResource("aligns", RES_2DA):
+ Aligns = GemRB.LoadTable ("aligns")
+ if not ItemType:
+ ItemType = GemRB.LoadTable ("itemtype")
diff --git a/gemrb/GUIScripts/CommonWindow.py b/gemrb/GUIScripts/CommonWindow.py
index 196008c..13413a2 100644
--- a/gemrb/GUIScripts/CommonWindow.py
+++ b/gemrb/GUIScripts/CommonWindow.py
@@ -80,17 +80,13 @@ def UpdateContainerWindow ():
Container = GemRB.GetContainer (0) #will use first selected pc anyway
LeftCount = Container['ItemCount']
ScrollBar = Window.GetControl (52)
- Count = LeftCount / leftdiv
- if Count < 1:
- Count = 1
+ Count = max (0, (LeftCount - ground_size + leftdiv - 1) / leftdiv)
ScrollBar.SetVarAssoc ("LeftTopIndex", Count)
inventory_slots = GemRB.GetSlots (pc, 0x8000)
RightCount = len(inventory_slots)
ScrollBar = Window.GetControl (53)
- Count = RightCount / 2
- if Count < 1:
- Count = 1
+ Count = max (0, (RightCount - 4 + 1) / 2)
ScrollBar.SetVarAssoc ("RightTopIndex", Count)
RedrawContainerWindow ()
@@ -251,6 +247,8 @@ def OpenContainerWindow ():
Button = Window.GetControl (51)
if GUICommon.GameIsPST():
Button.SetText (1403)
+ elif GUICommon.GameIsIWD2():
+ Button.SetText ("")
else:
Button.SetText (11973)
Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
@@ -265,18 +263,20 @@ def OpenContainerWindow ():
def CloseContainerWindow ():
global ContainerWindow
- if ContainerWindow == None:
+ if not ContainerWindow:
return
hideflag = GemRB.HideGUI ()
- if ContainerWindow:
- ContainerWindow.Unload ()
- ContainerWindow = None
+ ContainerWindow.Unload ()
if GUICommon.GameIsPST():
- GUICommonWindows.EnableAnimatedWindows ()
GemRB.SetVar ("PortraitWindow", GUIWORLD.OldPortraitWindow.ID)
+ GUICommonWindows.EnableAnimatedWindows ()
+ #PST needs a reminder to redraw the clock for some reason
+ if GUICommonWindows.ActionsWindow:
+ GUICommonWindows.ActionsWindow.SetVisible(WINDOW_VISIBLE)
+
# FIXME: iwd2 bug or just bad naming?
if GUICommon.GameIsIWD2():
diff --git a/gemrb/GUIScripts/DualClass.py b/gemrb/GUIScripts/DualClass.py
index 2c64bea..32a2d07 100644
--- a/gemrb/GUIScripts/DualClass.py
+++ b/gemrb/GUIScripts/DualClass.py
@@ -21,7 +21,9 @@ import GemRB
from GUIDefines import *
from ie_stats import *
from ie_restype import RES_2DA
+from ie_slots import *
import GUICommon
+import Spellbook
import CommonTables
import LUSpellSelection
import LUProfsSelection
@@ -125,7 +127,7 @@ def DualClassWindow ():
# class name
Kit = GUICommon.GetKitIndex (pc)
- OldClassName = CommonTables.Classes.GetRowName (CommonTables.Classes.FindValue (5, GemRB.GetPlayerStat (pc, IE_CLASS) ) )
+ OldClassName = GUICommon.GetClassRowName (pc)
if Kit:
OldKitName = CommonTables.KitList.GetValue (Kit, 0, 0)
else:
@@ -148,6 +150,7 @@ def DCMainDonePress ():
This de-activates our old class and readjusts the basic actor stats, such as
THAC0, spell casting, proficiencies, and so forth, to the new class."""
import GUIREC
+ global ClassName
# save our proficiencies
LUProfsSelection.ProfsSave (pc, LUProfsSelection.LUPROFS_TYPE_DUALCLASS)
@@ -165,7 +168,7 @@ def DCMainDonePress ():
if not NewMageSpells:
for i in range (9):
GemRB.SetMemorizableSpellsCount (pc, 0, IE_SPELL_TYPE_WIZARD, i)
- GUICommon.RemoveKnownSpells (pc, IE_SPELL_TYPE_PRIEST, 1,7, 1)
+ Spellbook.RemoveKnownSpells (pc, IE_SPELL_TYPE_PRIEST, 1,7, 1)
# apply our class abilities
ABTable = CommonTables.ClassSkills.GetValue (ClassName, "ABILITIES")
@@ -174,7 +177,7 @@ def DCMainDonePress ():
# learn our new priest spells
if NewPriestMask:
- GUICommon.LearnPriestSpells (pc, 1, NewPriestMask)
+ Spellbook.LearnPriestSpells (pc, 1, NewPriestMask)
GemRB.SetMemorizableSpellsCount (pc, 1, IE_SPELL_TYPE_PRIEST, 0)
# save our thief skills if we have them
@@ -183,8 +186,9 @@ def DCMainDonePress ():
# save our new class and say was multi
OldClassId = GemRB.GetPlayerStat (pc, IE_CLASS)
MultClassId = (1 << (NewClassId-1)) | (1 << (OldClassId-1))
- MultClassId = CommonTables.Classes.FindValue (4, MultClassId)
- MultClassId = CommonTables.Classes.GetValue (MultClassId, 5)
+ MultClassId = CommonTables.Classes.FindValue ("MULTI", MultClassId)
+ MultClassId = CommonTables.Classes.GetRowName (MultClassId)
+ MultClassId = CommonTables.Classes.GetValue (MultClassId, "ID")
GemRB.SetPlayerStat (pc, IE_CLASS, MultClassId)
GemRB.SetPlayerStat (pc, IE_MC_FLAGS, CommonTables.Classes.GetValue (OldClassName, "MC_WAS_ID", 1))
@@ -201,11 +205,27 @@ def DCMainDonePress ():
GemRB.SetPlayerStat (pc, IE_TOHIT, ThacoTable.GetValue (NewClassId-1, 0, 1))
# new saves
- SavesTable = CommonTables.Classes.GetValue (CommonTables.Classes.FindValue (5, NewClassId), 3, 0)
+ SavesTable = CommonTables.Classes.GetValue (ClassName, "SAVE", 0)
SavesTable = GemRB.LoadTable (SavesTable)
for i in range (5):
GemRB.SetPlayerStat (pc, IE_SAVEVSDEATH+i, SavesTable.GetValue (i, 0))
+ # dump any equipped items that are now unusable
+ SlotTypes = [ SLOT_ARMOUR, SLOT_SHIELD, SLOT_HELM, SLOT_RING, SLOT_CLOAK, SLOT_BOOT, SLOT_AMULET, SLOT_GLOVE, SLOT_BELT, SLOT_ITEM, SLOT_WEAPON, SLOT_QUIVER ]
+ for type in SlotTypes:
+ Slots = GemRB.GetSlots (pc, type)
+ if not len(Slots):
+ # nothing there
+ continue
+ for slot in Slots:
+ SlotType = GemRB.GetSlotType (slot, pc)
+ CREItem = GemRB.GetSlotItem (pc, slot)
+ if not GemRB.CanUseItemType (SlotType["Type"], CREItem["ItemResRef"], pc):
+ # move it to a free inventory slot by mimicking dragging
+ Item = GemRB.GetItem (CREItem["ItemResRef"])
+ GemRB.DragItem (pc, slot, Item["ItemIcon"])
+ GemRB.DropDraggedItem (pc, -3)
+
# close our window
if DCMainWindow:
DCMainWindow.Unload ()
@@ -245,7 +265,7 @@ def DCMainBackPress ():
# un-learn our spells and skills
if NewMageSpells:
- GUICommon.RemoveKnownSpells (pc, IE_SPELL_TYPE_WIZARD, 1,1, 1)
+ Spellbook.RemoveKnownSpells (pc, IE_SPELL_TYPE_WIZARD, 1,1, 1)
LUSkillsSelection.SkillsNullify ()
NewPriestMask = 0
@@ -382,10 +402,9 @@ def CanDualInto (index):
# make sure we aren't restricted by alignment
AlignmentTable = GemRB.LoadTable ("alignmnt")
- AlignsTable = GemRB.LoadTable ("aligns")
Alignment = GemRB.GetPlayerStat (pc, IE_ALIGNMENT) # our alignment
- Alignment = AlignsTable.FindValue (3, Alignment)
- Alignment = AlignsTable.GetValue (Alignment, 4) # convert the alignment
+ Alignment = CommonTables.Aligns.FindValue (3, Alignment)
+ Alignment = CommonTables.Aligns.GetValue (Alignment, 4) # convert the alignment
if not AlignmentTable.GetValue (DCClasses[index], Alignment, 1): # check it
return 0
diff --git a/gemrb/GUIScripts/GUIClasses.py b/gemrb/GUIScripts/GUIClasses.py
index 6429342..da3265b 100644
--- a/gemrb/GUIScripts/GUIClasses.py
+++ b/gemrb/GUIScripts/GUIClasses.py
@@ -50,6 +50,7 @@ class GSymbol:
class GWindow:
__metaclass__ = metaIDWrapper
methods = {
+ 'GetRect': _GemRB.Window_GetRect,
'SetSize': _GemRB.Window_SetSize,
'SetFrame': _GemRB.Window_SetFrame,
'SetPicture': _GemRB.Window_SetPicture,
@@ -57,11 +58,11 @@ class GWindow:
'HasControl': _GemRB.Window_HasControl,
'DeleteControl': _GemRB.Window_DeleteControl,
'SetupEquipmentIcons': _GemRB.Window_SetupEquipmentIcons,
- 'SetupSpellIcons': _GemRB.Window_SetupSpellIcons,
'SetupControls': _GemRB.Window_SetupControls,
'SetVisible': _GemRB.Window_SetVisible,
'ShowModal': _GemRB.Window_ShowModal,
- 'Invalidate': _GemRB.Window_Invalidate
+ 'Invalidate': _GemRB.Window_Invalidate,
+ 'UpdateVarAssoc': _GemRB.Window_UpdateVarAssoc
}
def __nonzero__(self):
return self.ID != -1
@@ -94,6 +95,8 @@ class GWindow:
class GControl:
__metaclass__ = metaControl
methods = {
+ 'GetRect': _GemRB.Control_GetRect,
+ 'HasAnimation': _GemRB.Control_HasAnimation,
'SetVarAssoc': _GemRB.Control_SetVarAssoc,
'SetPos': _GemRB.Control_SetPos,
'SetSize': _GemRB.Control_SetSize,
@@ -113,6 +116,7 @@ class GControl:
class GLabel(GControl):
__metaclass__ = metaControl
methods = {
+ 'SetFont': _GemRB.Label_SetFont,
'SetTextColor': _GemRB.Label_SetTextColor,
'SetUseRGB': _GemRB.Label_SetUseRGB
}
@@ -137,7 +141,8 @@ class GTextArea(GControl):
class GTextEdit(GControl):
__metaclass__ = metaControl
methods = {
- 'SetBufferLength': _GemRB.TextEdit_SetBufferLength
+ 'SetBufferLength': _GemRB.TextEdit_SetBufferLength,
+ 'SetBackground': _GemRB.TextEdit_SetBackground
}
def ConvertEdit(self, ScrollBarID):
newID = _GemRB.TextEdit_ConvertEdit(self.WinID, self.ID, ScrollBarID)
@@ -158,6 +163,8 @@ class GButton(GControl):
'SetBorder': _GemRB.Button_SetBorder,
'EnableBorder': _GemRB.Button_EnableBorder,
'SetFont': _GemRB.Button_SetFont,
+ 'SetAnchor': _GemRB.Button_SetAnchor,
+ 'SetPushOffset': _GemRB.Button_SetPushOffset,
'SetTextColor': _GemRB.Button_SetTextColor,
'SetFlags': _GemRB.Button_SetFlags,
'SetState': _GemRB.Button_SetState,
diff --git a/gemrb/GUIScripts/GUICommon.py b/gemrb/GUIScripts/GUICommon.py
index 705ef52..97a616d 100644
--- a/gemrb/GUIScripts/GUICommon.py
+++ b/gemrb/GUIScripts/GUICommon.py
@@ -22,12 +22,12 @@
import GemRB
import GUIClasses
import CommonTables
-from ie_restype import RES_CHU, RES_2DA, RES_WMP, RES_ARE
-from ie_spells import LS_MEMO, LSR_KNOWN, LSR_LEVEL, LSR_STAT
+from ie_restype import RES_CHU, RES_WMP, RES_ARE
+from ie_spells import LS_MEMO
from GUIDefines import *
from ie_stats import *
-from ie_action import ACT_QSLOT1, ACT_QSLOT2, ACT_QSLOT3, ACT_QSLOT4, ACT_QSLOT5
from ie_slots import SLOT_ALL
+from ie_feats import FEAT_STRONG_BACK
OtherWindowFn = None
NextWindowFn = None
@@ -86,18 +86,19 @@ def GetWindowPack():
# fallback to the smallest resolution
return default
-def RestPress ():
- GemRB.RestParty(0,0,0)
+def LocationPressed ():
+ AreaInfo = GemRB.GetAreaInfo()
+ print( "%s [%d.%d]\n"%(AreaInfo["CurrentArea"], AreaInfo["PositionX"], AreaInfo["PositionY"]) )
return
def SelectFormation ():
GemRB.GameSetFormation (GemRB.GetVar ("Formation"))
return
-def OpenFloatMenuWindow ():
+def OpenFloatMenuWindow (x, y):
if GameIsPST():
import FloatMenuWindow
- FloatMenuWindow.OpenFloatMenuWindow()
+ FloatMenuWindow.OpenFloatMenuWindow(x, y)
else:
GemRB.GameControlSetTargetMode (TARGET_MODE_NONE)
@@ -118,98 +119,9 @@ def GearsClicked ():
#GemRB.SetPlayerStat(GemRB.GameGetFirstSelectedPC (),44,249990)
GemRB.GamePause (2, 0)
-def GetMageSpells (Kit, Alignment, Level):
- MageSpells = []
- SpellType = 99
- Table = GemRB.LoadTable ("aligns")
- v = Table.FindValue (3, Alignment)
- Usability = Kit | Table.GetValue(v, 5)
-
- SpellsTable = GemRB.LoadTable ("spells")
- for i in range(SpellsTable.GetValue ("MAGE", str(Level), 1) ):
- SpellName = "SPWI%d%02d"%(Level,i+1)
- ms = GemRB.GetSpell (SpellName, 1)
- if ms == None:
- continue
-
- if Usability & ms['SpellExclusion']:
- SpellType = 0
- else:
- SpellType = 1
- if Kit & (1 << ms['SpellSchool']+5): # of matching specialist school
- SpellType = 2
- # Wild mage spells are of normal schools, so we have to find them
- # separately. Generalists can learn any spell but the wild ones, so
- # we check if the mage is wild and if a generalist wouldn't be able
- # to learn the spell.
- if Kit == 0x8000 and (0x4000 & ms['SpellExclusion']):
- SpellType = 2
- MageSpells.append ([SpellName, SpellType])
-
- return MageSpells
-
-def GetLearnableMageSpells (Kit, Alignment, Level):
- Learnable = []
-
- for Spell in GetMageSpells (Kit, Alignment, Level):
- if Spell[1]:
- Learnable.append (Spell[0])
- return Learnable
-
-def GetLearnablePriestSpells (Class, Alignment, Level):
- Learnable =[]
-
- Table=GemRB.LoadTable("aligns")
- v = Table.FindValue(3, Alignment)
- #usability is the bitset we look for
- Usability=Table.GetValue(v, 5)
-
- SpellsTable = GemRB.LoadTable ("spells")
- for i in range(SpellsTable.GetValue ("PRIEST", str (Level), 1) ):
- SpellName = "SPPR%d%02d"%(Level,i+1)
- ms = GemRB.GetSpell(SpellName, 1)
- if ms == None:
- continue
- if Class & ms['SpellDivine']:
- continue
- if Usability & ms['SpellExclusion']:
- continue
- Learnable.append (SpellName)
- return Learnable
-
-def SetupSpellLevels (pc, TableName, Type, Level):
- #don't die on a missing reference
- #FIXME: try to do this in a non-hard way?
- if not GemRB.HasResource (TableName, RES_2DA):
- if TableName == "MXSPLDRU":
- SetupSpellLevels (pc, "MXSPLPRS", Type, Level)
- return
-
- Table = GemRB.LoadTable (TableName)
- for i in range(Table.GetColumnCount ()):
- # do a string lookup since some tables don't have entries for all levels
- value = Table.GetValue (str(Level), str(i+1), 1)
- # specialist mages get an extra spell if they already know that level
- # FIXME: get a general routine to find specialists
- school = GemRB.GetVar("MAGESCHOOL")
- if Type == IE_SPELL_TYPE_WIZARD and school != 0:
- if value > 0:
- value += 1
- GemRB.SetMemorizableSpellsCount (pc, value, Type, i)
- return
-
-def UnsetupSpellLevels (pc, TableName, Type, Level):
- #don't die on a missing reference
- #FIXME: try to do this in a non-hard way?
- if not GemRB.HasResource (TableName, RES_2DA):
- if TableName == "MXSPLDRU":
- UnsetupSpellLevels (pc, "MXSPLPRS", Type, Level)
- return
-
- Table = GemRB.LoadTable (TableName)
- for i in range(Table.GetColumnCount ()):
- GemRB.SetMemorizableSpellsCount (pc, 0, Type, i)
- return
+def GetAbilityBonus (Actor, Stat):
+ Ability = GemRB.GetPlayerStat (Actor, Stat)
+ return Ability//2-5
def SetColorStat (Actor, Stat, Value):
t = Value & 0xFF
@@ -268,8 +180,8 @@ def HasHOW ():
def HasTOTL ():
return GemRB.HasResource ("ar9700", RES_ARE)
-def GetIWDSpellButtonCount ():
- if HasHOW():
+def GetGUISpellButtonCount ():
+ if HasHOW() or GameIsBG2():
return 24
else:
return 20
@@ -278,23 +190,18 @@ def SetGamedaysAndHourToken ():
currentTime = GemRB.GetGameTime()
days = currentTime / 7200
hours = (currentTime % 7200) / 300
+ GemRB.SetToken ('GAMEDAY', str (days))
GemRB.SetToken ('GAMEDAYS', str (days))
GemRB.SetToken ('HOUR', str (hours))
-# Returns -1 if not found; otherwise, the index of the spell
-def HasSpell (Actor, SpellType, Level, Ref):
- # loop through each spell in the spell level and check for a matching ref
- for i in range (GemRB.GetKnownSpellsCount (Actor, SpellType, Level)):
- Spell = GemRB.GetKnownSpell(Actor, SpellType, Level, i)
- if Spell["SpellResRef"].upper() == Ref.upper(): # ensure case is the same
- return i
-
- # not found
- return -1
+def Gain(infostr, ability):
+ GemRB.SetToken ('SPECIALABILITYNAME', GemRB.GetString(int(ability) ) )
+ GemRB.DisplayString (infostr)
# Adds class/kit abilities
def AddClassAbilities (pc, table, Level=1, LevelDiff=1, align=-1):
TmpTable = GemRB.LoadTable (table)
+ import Spellbook
# gotta stay positive
if Level-LevelDiff < 0:
@@ -325,25 +232,34 @@ def AddClassAbilities (pc, table, Level=1, LevelDiff=1, align=-1):
ab = "GA_" + ab
# apply spell (AP_) or gain spell (GA_)
- if ab[:2] == "AP":
+ if ab[:3] == "AP_":
GemRB.ApplySpell (pc, ab[3:])
- elif ab[:2] == "GA":
- SpellIndex = HasSpell (pc, IE_SPELL_TYPE_INNATE, 0, ab[3:])
+ elif ab[:3] == "GA_":
+ SpellIndex = Spellbook.HasSpell (pc, IE_SPELL_TYPE_INNATE, 0, ab[3:])
if SpellIndex == -1:
GemRB.LearnSpell (pc, ab[3:], LS_MEMO)
else:
- # make room for one more memorization
- max_mem_cnt = GemRB.GetMemorizableSpellsCount (pc, IE_SPELL_TYPE_INNATE, 0, 0)
- GemRB.SetMemorizableSpellsCount (pc, max_mem_cnt+1, IE_SPELL_TYPE_INNATE, 0)
- # memorize another spell instance
GemRB.MemorizeSpell (pc, IE_SPELL_TYPE_INNATE, 0, SpellIndex)
+ elif ab[:3] == "FS_":
+ Gain(26320, ab[3:])
+ elif ab[:3] == "FA_":
+ Gain(10514, ab[3:])
else:
print "ERROR, unknown class ability (type): ", ab
+def MakeSpellCount (pc, spell, count):
+ have = GemRB.CountSpells (pc, spell, 1)
+ if count<=have:
+ return
+ for i in range (count-have):
+ GemRB.LearnSpell (pc, spell, LS_MEMO)
+ return
+
# remove all class abilities up to the given level
# for dual-classing mainly
def RemoveClassAbilities (pc, table, Level):
TmpTable = GemRB.LoadTable (table)
+ import Spellbook
# gotta stay positive
if Level < 0:
@@ -359,53 +275,31 @@ def RemoveClassAbilities (pc, table, Level):
ab = TmpTable.GetValue (i, j, 0)
if ab and ab != "****":
# get the index
- SpellIndex = HasSpell (pc, IE_SPELL_TYPE_INNATE, 0, ab[3:])
+ SpellIndex = Spellbook.HasSpell (pc, IE_SPELL_TYPE_INNATE, 0, ab[3:])
# seems all SPINs act like GA_*
if ab[:4] == "SPIN":
ab = "GA_" + ab
# apply spell (AP_) or gain spell (GA_)?
- if ab[:2] == "AP":
+ if ab[:3] == "AP_":
GemRB.RemoveEffects (pc, ab[3:])
- elif ab[:2] == "GA":
+ elif ab[:3] == "GA_":
if SpellIndex >= 0:
# TODO: get the correct counts to avoid removing an innate ability
# given by more than one thing?
# RemoveSpell will unmemorize them all too
GemRB.RemoveSpell (pc, IE_SPELL_TYPE_INNATE, 0, SpellIndex)
- else:
+ elif ab[:3] != "FA_" and ab[:3] != "FS_":
print "ERROR, unknown class ability (type): ", ab
-def CannotLearnSlotSpell ():
- pc = GemRB.GameGetSelectedPCSingle ()
-
- # disqualify sorcerors immediately
- if GemRB.GetPlayerStat (pc, IE_CLASS) == 19:
- return LSR_STAT
-
- slot_item = GemRB.GetSlotItem (pc, GemRB.GetVar ("ItemButton"))
- spell_ref = GemRB.GetItem (slot_item['ItemResRef'], pc)['Spell']
- spell = GemRB.GetSpell (spell_ref)
-
- # maybe she already knows this spell
- if HasSpell (pc, IE_SPELL_TYPE_WIZARD, spell['SpellLevel']-1, spell_ref) != -1:
- return LSR_KNOWN
-
- # level check (needs enough intelligence for this level of spell)
- dumbness = GemRB.GetPlayerStat (pc, IE_INT)
- if spell['SpellLevel'] > GemRB.GetAbilityBonus (IE_INT, 1, dumbness):
- return LSR_LEVEL
-
- return 0
-
def UpdateInventorySlot (pc, Button, Slot, Type, Equipped=False):
Button.SetFont ("NUMBER")
Button.SetBorder (0, 0,0,0,0, 128,128,255,64, 0,1)
Button.SetBorder (1, 2,2,2,2, 32,32,255,0, 0,0)
Button.SetBorder (2, 0,0,0,0, 255,128,128,64, 0,1)
- Button.SetFlags (IE_GUI_BUTTON_ALIGN_RIGHT | IE_GUI_BUTTON_ALIGN_TOP | IE_GUI_BUTTON_PICTURE, OP_OR)
Button.SetText ("")
+ Button.SetFlags (IE_GUI_BUTTON_ALIGN_RIGHT | IE_GUI_BUTTON_ALIGN_BOTTOM | IE_GUI_BUTTON_PICTURE, OP_OR)
if Slot == None:
Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_NAND)
@@ -423,8 +317,8 @@ def UpdateInventorySlot (pc, Button, Slot, Type, Equipped=False):
identified = Slot["Flags"] & IE_INV_ITEM_IDENTIFIED
magical = Slot["Flags"] & IE_INV_ITEM_MAGICAL
- # StackAmount holds the *maximum* item count in the stack while Usages0 holds the actual
- if item["StackAmount"] > 1:
+ # MaxStackAmount holds the *maximum* item count in the stack while Usages0 holds the actual
+ if item["MaxStackAmount"] > 1:
Button.SetText (str (Slot["Usages0"]))
else:
Button.SetText ("")
@@ -454,35 +348,13 @@ def UpdateInventorySlot (pc, Button, Slot, Type, Equipped=False):
return
-def LearnPriestSpells (pc, level, mask):
- """Learns all the priest spells through the given spell level.
-
- Mask distinguishes clerical and druidic spells."""
- if level > 7: # make sure we don't have too high a level
- level = 7
-
- # go through each level
- alignment = GemRB.GetPlayerStat (pc, IE_ALIGNMENT)
- for i in range (level):
- learnable = GetLearnablePriestSpells (mask, alignment, i+1)
-
- for spell in learnable:
- # if the spell isn't learned, learn it
- if HasSpell (pc, IE_SPELL_TYPE_PRIEST, i, spell) < 0:
- GemRB.LearnSpell (pc, spell)
- return
-
# PST uses a button, IWD2 two types, the rest are the same with two labels
def SetEncumbranceLabels (Window, ControlID, Control2ID, pc, invert_colors = False):
"""Displays the encumbrance as a ratio of current to maximum."""
- # Getting the character's strength
- sstr = GemRB.GetPlayerStat (pc, IE_STR)
- ext_str = GemRB.GetPlayerStat (pc, IE_STREXTRA)
-
# encumbrance
- max_encumb = CommonTables.StrMod.GetValue (sstr, 3) + CommonTables.StrModEx.GetValue (ext_str, 3)
encumbrance = GemRB.GetPlayerStat (pc, IE_ENCUMBRANCE)
+ max_encumb = GemRB.GetMaxEncumbrance (pc)
Control = Window.GetControl (ControlID)
if GameIsPST():
@@ -499,24 +371,33 @@ def SetEncumbranceLabels (Window, ControlID, Control2ID, pc, invert_colors = Fal
Control2.SetText (str (max_encumb) + ":")
ratio = (0.0 + encumbrance) / max_encumb
- if ratio > 1.0:
- if invert_colors:
- Control.SetTextColor (255, 0, 0, True)
- else:
- Control.SetTextColor (255, 0, 0)
- elif ratio > 0.8:
- if invert_colors:
- Control.SetTextColor (255, 255, 0, True)
+ if GameIsIWD2 () or GameIsPST ():
+ if ratio > 1.0:
+ if invert_colors:
+ Control.SetTextColor (255, 0, 0, True)
+ else:
+ Control.SetTextColor (255, 0, 0)
+ elif ratio > 0.8:
+ if invert_colors:
+ Control.SetTextColor (255, 255, 0, True)
+ else:
+ Control.SetTextColor (255, 255, 0)
else:
- Control.SetTextColor (255, 255, 0)
+ if invert_colors:
+ Control.SetTextColor (255, 255, 255, True)
+ else:
+ Control.SetTextColor (255, 255, 255)
+
+ if Control2ID:
+ Control2.SetTextColor (255, 0, 0)
+
else:
- if invert_colors:
- Control.SetTextColor (255, 255, 255, True)
+ if ratio > 1.0:
+ Control.SetFont ("NUMBER3");
+ elif ratio > 0.8:
+ Control.SetFont ("NUMBER2");
else:
- Control.SetTextColor (255, 255, 255)
-
- if Control2ID:
- Control2.SetTextColor (255, 0, 0)
+ Control.SetFont ("NUMBER");
return
@@ -526,14 +407,13 @@ def GetActorClassTitle (actor):
ClassTitle = GemRB.GetPlayerStat (actor, IE_TITLE1)
if ClassTitle == 0:
- Class = GemRB.GetPlayerStat (actor, IE_CLASS)
- ClassIndex = CommonTables.Classes.FindValue ( 5, Class )
+ ClassName = GetClassRowName (actor)
KitIndex = GetKitIndex (actor)
- Multi = CommonTables.Classes.GetValue (ClassIndex, 4)
+ Multi = HasMultiClassBits (actor)
Dual = IsDualClassed (actor, 1)
if Multi and Dual[0] == 0: # true multi class
- ClassTitle = CommonTables.Classes.GetValue (ClassIndex, 2)
+ ClassTitle = CommonTables.Classes.GetValue (ClassName, "CAP_REF")
ClassTitle = GemRB.GetString (ClassTitle)
else:
if Dual[0]: # dual class
@@ -541,15 +421,16 @@ def GetActorClassTitle (actor):
if Dual[0] == 1:
ClassTitle = CommonTables.KitList.GetValue (Dual[1], 2)
elif Dual[0] == 2:
- ClassTitle = CommonTables.Classes.GetValue (Dual[1], 2)
+ ClassTitle = CommonTables.Classes.GetValue (GetClassRowName(Dual[1], "index"), "CAP_REF")
ClassTitle = GemRB.GetString (ClassTitle) + " / "
- ClassTitle += GemRB.GetString (CommonTables.Classes.GetValue (Dual[2], 2))
+ ClassTitle += GemRB.GetString (CommonTables.Classes.GetValue (GetClassRowName(Dual[2], "index"), "CAP_REF"))
else: # ordinary class or kit
if KitIndex:
ClassTitle = CommonTables.KitList.GetValue (KitIndex, 2)
else:
- ClassTitle = CommonTables.Classes.GetValue (ClassIndex, 2)
- ClassTitle = GemRB.GetString (ClassTitle)
+ ClassTitle = CommonTables.Classes.GetValue (ClassName, "CAP_REF")
+ if ClassTitle != "*":
+ ClassTitle = GemRB.GetString (ClassTitle)
else:
ClassTitle = GemRB.GetString (ClassTitle)
@@ -565,7 +446,6 @@ def GetKitIndex (actor):
Returns 0 if the class is not kitted."""
- Class = GemRB.GetPlayerStat (actor, IE_CLASS)
Kit = GemRB.GetPlayerStat (actor, IE_KIT)
KitIndex = 0
@@ -581,6 +461,33 @@ def GetKitIndex (actor):
return KitIndex
+# fetches the rowname of the passed actor's (base) class from classes.2da
+# NOTE: only the "index" method is iwd2-ready, since you can have multiple classes and kits
+def GetClassRowName(value, which=-1):
+ if which == "index":
+ ClassIndex = value
+ # if barbarians cause problems, repeat the lookup again here
+ else:
+ if which == -1:
+ Class = GemRB.GetPlayerStat (value, IE_CLASS)
+ elif which == "class":
+ Class = value
+ else:
+ raise RuntimeError, "Bad type parameter for GetClassRowName: ", which
+ ClassIndex = CommonTables.Classes.FindValue ("ID", Class)
+ ClassRowName = CommonTables.Classes.GetRowName (ClassIndex)
+ return ClassRowName
+
+# checks the classes.2da table if the class is multiclass/dualclass capable (bits define the class combination)
+def HasMultiClassBits(actor):
+ MultiBits = CommonTables.Classes.GetValue (GetClassRowName(actor), "MULTI")
+
+ # we have no entries for npc creature classes, so treat them as single-classed
+ if MultiBits == "*":
+ MultiBits = 0
+
+ return MultiBits
+
def IsDualClassed(actor, verbose):
"""Returns an array containing the dual class information.
@@ -592,18 +499,19 @@ def IsDualClassed(actor, verbose):
if GameIsIWD2():
return (0,-1,-1)
+ Multi = HasMultiClassBits (actor)
+
+ if Multi == 0:
+ return (0, -1, -1)
+
DualedFrom = GemRB.GetPlayerStat (actor, IE_MC_FLAGS) & MC_WAS_ANY_CLASS
if verbose:
- Class = GemRB.GetPlayerStat (actor, IE_CLASS)
- ClassIndex = CommonTables.Classes.FindValue (5, Class)
- Multi = CommonTables.Classes.GetValue (ClassIndex, 4)
DualInfo = []
KitIndex = GetKitIndex (actor)
if DualedFrom > 0: # first (previous) class of the dual class
- MCColumn = CommonTables.Classes.GetColumnIndex ("MC_WAS_ID")
- FirstClassIndex = CommonTables.Classes.FindValue (MCColumn, DualedFrom)
+ FirstClassIndex = CommonTables.Classes.FindValue ("MC_WAS_ID", DualedFrom)
if KitIndex:
DualInfo.append (1)
DualInfo.append (KitIndex)
@@ -615,7 +523,7 @@ def IsDualClassed(actor, verbose):
Mask = 1
for i in range (1,16):
if Multi & Mask:
- ClassIndex = CommonTables.Classes.FindValue (5, i)
+ ClassIndex = CommonTables.Classes.FindValue ("ID", i)
if ClassIndex == FirstClassIndex:
Mask = 1 << i
continue
@@ -624,7 +532,7 @@ def IsDualClassed(actor, verbose):
Mask = 1 << i
if len(DualInfo) != 3:
print "WARNING: Invalid dualclass combination, treating as a single class!"
- print DualedFrom, Class, Multi, KitIndex, DualInfo
+ print DualedFrom, Multi, KitIndex, DualInfo
return (0,-1,-1)
return DualInfo
@@ -653,19 +561,18 @@ def IsDualSwap (actor):
# split the full class name into its individual parts
# i.e FIGHTER_MAGE becomes [FIGHTER, MAGE]
- Class = GemRB.GetPlayerStat (actor, IE_CLASS)
- Class = CommonTables.Classes.FindValue (5, Class)
- Class = CommonTables.Classes.GetRowName (Class)
- Class = Class.split("_")
+ Class = GetClassRowName(actor).split("_")
# get our old class name
if Dual[0] == 2:
- BaseClass = CommonTables.Classes.GetRowName (Dual[1])
+ BaseClass = GetClassRowName(Dual[1], "index")
else:
BaseClass = GetKitIndex (actor)
BaseClass = CommonTables.KitList.GetValue (BaseClass, 7)
- BaseClass = CommonTables.Classes.FindValue (5, BaseClass)
- BaseClass = CommonTables.Classes.GetRowName (BaseClass)
+ if BaseClass == "*":
+ # mod boilerplate
+ return 0
+ BaseClass = GetClassRowName(BaseClass, "index")
# if our old class is the first class, we need to swap
if Class[0] == BaseClass:
@@ -685,8 +592,7 @@ def IsMultiClassed (actor, verbose):
return (0,-1,-1,-1)
# get our base class
- ClassIndex = CommonTables.Classes.FindValue (5, GemRB.GetPlayerStat (actor, IE_CLASS))
- IsMulti = CommonTables.Classes.GetValue (ClassIndex, 4) # 0 if not multi'd
+ IsMulti = HasMultiClassBits (actor)
IsDual = IsDualClassed (actor, 0)
# dual-class char's look like multi-class chars
@@ -699,15 +605,18 @@ def IsMultiClassed (actor, verbose):
Classes = [0]*3
NumClasses = 0
Mask = 1 # we're looking at multiples of 2
- ClassNames = CommonTables.Classes.GetRowName(ClassIndex).split("_")
+ ClassNames = GetClassRowName(actor).split("_")
# loop through each class and test it as a mask
- # TODO: make 16 dynamic? -- allows for custom classes (not just kits)
- for i in range (1, 16):
+ ClassCount = CommonTables.Classes.GetRowCount()
+ for i in range (1, ClassCount):
if IsMulti&Mask: # it's part of this class
#we need to place the classes in the array based on their order in the name,
#NOT the order they are detected in
- CurrentName = CommonTables.Classes.GetRowName (CommonTables.Classes.FindValue (5, i));
+ CurrentName = GetClassRowName (i, "class")
+ if CurrentName == "*":
+ # we read too far, as the upper range limit is greater than the number of "single" classes
+ break
for j in range(len(ClassNames)):
if ClassNames[j] == CurrentName:
Classes[j] = i # mask is (i-1)^2 where i is class id
@@ -716,83 +625,12 @@ def IsMultiClassed (actor, verbose):
# in case we couldn't figure out to which classes the multi belonged
if NumClasses < 2:
+ print "ERROR: couldn't figure out the individual classes of multiclass", ClassNames
return (0,-1,-1,-1)
# return the tuple
return (NumClasses, Classes[0], Classes[1], Classes[2])
-def RemoveKnownSpells (pc, type, level1=1, level2=1, noslots=0, kit=0):
- """Removes all known spells of a given type between two spell levels.
-
- If noslots is true, all memorization counts are set to 0.
- Kit is used to identify the priest spell mask of the spells to be removed;
- this is only used when removing spells in a dualclass."""
-
- # choose the correct limit based upon class type
- if type == IE_SPELL_TYPE_WIZARD:
- limit = 9
- elif type == IE_SPELL_TYPE_PRIEST:
- limit = 7
-
- # make sure that we get the original kit, if we have one
- if kit:
- originalkit = GetKitIndex (pc)
-
- if originalkit: # kitted; find the class value
- originalkit = CommonTables.KitList.GetValue (originalkit, 7)
- else: # just get the class value
- originalkit = GemRB.GetPlayerStat (pc, IE_CLASS)
-
- # this is is specifically for dual-classes and will not work to remove only one
- # spell type from a ranger/cleric multi-class
- if CommonTables.ClassSkills.GetValue (originalkit, 0, 0) != "*": # knows druid spells
- originalkit = 0x8000
- elif CommonTables.ClassSkills.GetValue (originalkit, 1, 0) != "*": # knows cleric spells
- originalkit = 0x4000
- else: # don't know any other spells
- originalkit = 0
-
- # don't know how this would happen, but better to be safe
- if originalkit == kit:
- originalkit = 0
- elif type == IE_SPELL_TYPE_INNATE:
- limit = 1
- else: # can't do anything if an improper spell type is sent
- return 0
-
- # make sure we're within parameters
- if level1 < 1 or level2 > limit or level1 > level2:
- return 0
-
- # remove all spells for each level
- for level in range (level1-1, level2):
- # we need the count because we remove each spell in reverse order
- count = GemRB.GetKnownSpellsCount (pc, type, level)
- mod = count-1
-
- for spell in range (count):
- # see if we need to check for kit
- if type == IE_SPELL_TYPE_PRIEST and kit:
- # get the spell's ref data
- ref = GemRB.GetKnownSpell (pc, type, level, mod-spell)
- ref = GemRB.GetSpell (ref['SpellResRef'], 1)
-
- # we have to look at the originalkit as well specifically for ranger/cleric dual-classes
- # we wouldn't want to remove all cleric spells and druid spells if we lost our cleric class
- # only the cleric ones
- if kit&ref['SpellDivine'] or (originalkit and not originalkit&ref['SpellDivine']):
- continue
-
- # remove the spell
- GemRB.RemoveSpell (pc, type, level, mod-spell)
-
- # remove memorization counts if desired
- if noslots:
- GemRB.SetMemorizableSpellsCount (pc, 0, type, level)
-
- # return success
- return 1
-
def CanDualClass(actor):
# human
if GemRB.GetPlayerStat (actor, IE_RACE) != 1:
@@ -805,9 +643,7 @@ def CanDualClass(actor):
DualClassTable = GemRB.LoadTable ("dualclas")
CurrentStatTable = GemRB.LoadTable ("abdcscrq")
- Class = GemRB.GetPlayerStat (actor, IE_CLASS)
- ClassIndex = CommonTables.Classes.FindValue (5, Class)
- ClassName = CommonTables.Classes.GetRowName (ClassIndex)
+ ClassName = GetClassRowName(actor)
KitIndex = GetKitIndex (actor)
if KitIndex == 0:
ClassTitle = ClassName
@@ -815,8 +651,11 @@ def CanDualClass(actor):
ClassTitle = CommonTables.KitList.GetValue (KitIndex, 0)
Row = DualClassTable.GetRowIndex (ClassTitle)
- # a lookup table for the DualClassTable columns
- classes = [ "FIGHTER", "CLERIC", "MAGE", "THIEF", "DRUID", "RANGER" ]
+ # create a lookup table for the DualClassTable columns
+ classes = []
+ for col in range(DualClassTable.GetColumnCount()):
+ classes.append(DualClassTable.GetColumnName(col))
+
matches = []
Sum = 0
for col in range (0, DualClassTable.GetColumnCount ()):
@@ -836,10 +675,12 @@ def CanDualClass(actor):
return 1
AlignmentTable = GemRB.LoadTable ("alignmnt")
- AlignsTable = GemRB.LoadTable ("aligns")
Alignment = GemRB.GetPlayerStat (actor, IE_ALIGNMENT)
- AlignmentColName = AlignsTable.FindValue (3, Alignment)
- AlignmentColName = AlignsTable.GetValue (AlignmentColName, 4)
+ AlignmentColName = CommonTables.Aligns.FindValue (3, Alignment)
+ AlignmentColName = CommonTables.Aligns.GetValue (AlignmentColName, 4)
+ if AlignmentColName == -1:
+ print "CannotDualClass: extraordinary character alignment"
+ return 1
Sum = 0
for classy in matches:
Sum += AlignmentTable.GetValue (classy, AlignmentColName)
@@ -860,15 +701,16 @@ def CanDualClass(actor):
# check new class' stat limitations - make sure there are any good class choices
TargetStatTable = GemRB.LoadTable ("abdcdsrq")
+ bad = 0
for match in matches:
ClassStatIndex = TargetStatTable.GetRowIndex (match)
for stat in range (6):
minimum = TargetStatTable.GetValue (ClassStatIndex, stat)
name = TargetStatTable.GetColumnName (stat)
if GemRB.GetPlayerStat (actor, eval ("IE_" + name[4:])) < minimum:
- matches.remove (match)
+ bad += 1
break
- if len(matches) == 0:
+ if len(matches) == bad:
print "CannotDualClass: no good new class choices"
return 1
@@ -878,7 +720,27 @@ def CanDualClass(actor):
return 1
return 0
-def SetupDamageInfo (pc, Button):
+def IsWarrior (actor):
+ IsWarrior = CommonTables.ClassSkills.GetValue (GetClassRowName(actor), "NO_PROF")
+
+ # warriors get only a -2 penalty for wielding weapons they are not proficient with
+ # FIXME: make the check more robust, someone may change the value!
+ IsWarrior = (IsWarrior == -2)
+
+ Dual = IsDualClassed (actor, 0)
+ if Dual[0] > 0:
+ DualedFrom = GemRB.GetPlayerStat (actor, IE_MC_FLAGS) & MC_WAS_ANY_CLASS
+ FirstClassIndex = CommonTables.Classes.FindValue ("MC_WAS_ID", DualedFrom)
+ FirstClassName = CommonTables.Classes.GetRowName (FirstClassIndex)
+ OldIsWarrior = CommonTables.ClassSkills.GetValue (FirstClassName, "NO_PROF")
+ # there are no warrior to warrior dualclasses, so if the previous class was one, the current one certainly isn't
+ if OldIsWarrior == -2:
+ return 0
+ # but there are also non-warrior to non-warrior dualclasses, so just use the new class check
+
+ return IsWarrior
+
+def SetupDamageInfo (pc, Button, Window):
hp = GemRB.GetPlayerStat (pc, IE_HITPOINTS)
hp_max = GemRB.GetPlayerStat (pc, IE_MAXHITPOINTS)
state = GemRB.GetPlayerStat (pc, IE_STATE_ID)
@@ -890,12 +752,72 @@ def SetupDamageInfo (pc, Button):
if hp < 1 or (state & STATE_DEAD):
Button.SetOverlay (0, 64,64,64,200, 64,64,64,200)
+
+ if ratio == 1:
+ band = 0
+ color = (255, 255, 255) # white
+ elif ratio >= 0.75:
+ band = 1
+ color = (0, 255, 0) # green
+ elif ratio >= 0.50:
+ band = 2
+ color = (255, 255, 0) # yellow
+ elif ratio >= 0.25:
+ band = 3
+ color = (255, 128, 0) # orange
+ else:
+ band = 4
+ color = (255, 0, 0) # red
+
+ if GemRB.GetVar("Old Portrait Health") or not GameIsIWD2():
+ # draw the blood overlay
+ if hp >= 1 and not (state & STATE_DEAD):
+ Button.SetOverlay (ratio, 160,0,0,200, 60,0,0,190)
else:
- Button.SetOverlay (ratio, 140,0,0,205, 128,0,0,200)
+ # scale the hp bar under the portraits and recolor it
+ # GUIHITPT has 5 frames with different severity colors
+ # luckily their ids follow a nice pattern
+ hpBar = Window.GetControl (pc-1 + 50)
+ hpBar.SetBAM ("GUIHITPT", band, 0)
+ hpBar.SetPictureClipping (ratio)
+ hpBar.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_OR)
+
ratio_str = "\n%d/%d" %(hp, hp_max)
Button.SetTooltip (GemRB.GetPlayerName (pc, 1) + ratio_str)
- return ratio_str
+ return ratio_str, color
+
+def SetCurrentDateTokens (stat):
+ # NOTE: currentTime is in seconds, joinTime is in seconds * 15
+ # (script updates). In each case, there are 60 seconds
+ # in a minute, 24 hours in a day, but ONLY 5 minutes in an hour!!
+ # Hence currentTime (and joinTime after div by 15) has
+ # 7200 secs a day (60 * 5 * 24)
+ currentTime = GemRB.GetGameTime ()
+ joinTime = stat['JoinDate'] - stat['AwayTime']
+
+ party_time = currentTime - (joinTime / 15)
+ days = party_time / 7200
+ hours = (party_time % 7200) / 300
+
+ # it is true, they changed the token
+ if GameIsBG2():
+ GemRB.SetToken ('GAMEDAY', str (days))
+ else:
+ GemRB.SetToken ('GAMEDAYS', str (days))
+ GemRB.SetToken ('HOUR', str (hours))
+
+ return (days, hours)
+
+# gray out window or mark it as visible depending on the actor's state
+# Always greys it out for actors that are: dead, berserking
+# The third parameter is another check which must be 0 to maintain window visibility
+def AdjustWindowVisibility (Window, pc, additionalCheck):
+ if not additionalCheck and GemRB.ValidTarget (pc, GA_SELECT|GA_NO_DEAD):
+ Window.SetVisible (WINDOW_VISIBLE)
+ else:
+ Window.SetVisible (WINDOW_GRAYED)
+ return
# return ceil(n/d)
#
@@ -907,5 +829,28 @@ def ceildiv (n, d):
else:
return (n+d-1)/d
+# a placeholder for unimplemented and hardcoded key actions
+def ResolveKey():
+ return
+
GameWindow = GUIClasses.GWindow(0)
GameControl = GUIClasses.GControl(0,0)
+
+class _stdioWrapper(object):
+ def __init__(self, log_level):
+ self.log_level = log_level
+ self.buffer = ""
+ def write(self, message):
+ self.buffer += str(message)
+ if self.buffer.endswith("\n"):
+ out = self.buffer.rstrip("\n")
+ if out:
+ GemRB.Log(self.log_level, "Python", out)
+ self.buffer = ""
+
+def _wrapStdio():
+ import sys
+ sys.stdout = _stdioWrapper(LOG_MESSAGE)
+ sys.stderr = _stdioWrapper(LOG_ERROR)
+
+_wrapStdio()
diff --git a/gemrb/GUIScripts/GUICommonWindows.py b/gemrb/GUIScripts/GUICommonWindows.py
new file mode 100644
index 0000000..040db61
--- /dev/null
+++ b/gemrb/GUIScripts/GUICommonWindows.py
@@ -0,0 +1,1818 @@
+# -*-python-*-
+# GemRB - Infinity Engine Emulator
+# Copyright (C) 2003-2004 The GemRB Project
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+
+# GUICommonWindows.py - functions to open common
+# windows in lower part of the screen
+###################################################
+
+import GemRB
+from GUIDefines import *
+from ie_stats import *
+from ie_modal import *
+from ie_action import *
+from ie_slots import SLOT_QUIVER
+from ie_restype import RES_2DA
+import GUICommon
+import CommonTables
+import LUCommon
+import InventoryCommon
+if not GUICommon.GameIsPST():
+ import Spellbook ##not used in pst - YET
+
+# needed for all the Open*Window callbacks in the OptionsWindow
+import GUIJRNL
+import GUIMA
+import GUIINV
+import GUIOPT
+if GUICommon.GameIsIWD2():
+ # one spellbook for all spell types
+ import GUISPL
+else:
+ import GUIMG
+ import GUIPR
+import GUIREC
+
+FRAME_PC_SELECTED = 0
+FRAME_PC_TARGET = 1
+
+PortraitWindow = None
+OptionsWindow = None
+ActionsWindow = None
+CurrentWindow = None
+DraggedPortrait = None
+ActionBarControlOffset = 0
+ReturnToGame = None
+
+#The following tables deal with the different control indexes and string refs of each game
+#so that actual interface code can be game neutral
+if GUICommon.GameIsPST(): #Torment
+ import GUIClasses
+ TimeWindow = None
+ PortWindow = None
+ MenuWindow = None
+ MainWindow = None
+ DiscWindow = None
+ AITip = { "Deactivate" : 41631, "Enable" : 41646 }
+ OptionTip = { #dictionary to the stringrefs in each games dialog.tlk
+ 'Inventory' : 41601,'Map': 41625,'Mage': 41624,'Priest': 4709,'Stats': 4707,'Journal': 41623,
+ 'Options' : 41626,'Rest': 41628,'Follow': 41647,'Expand': 41660,'AI' : 1,'Game' : 1,'Party' : 1
+ }
+ OptionControl = { #dictionary to the control indexes in the window (.CHU)
+ 'Inventory' : 1, 'Map' : 2, 'Mage': 3, 'Priest': 7, 'Stats': 5, 'Journal': 6,
+ 'Options' : 8, 'Rest': 9, 'Follow': 0, 'Expand': 10, 'AI': 4,
+ 'Game': 0, 'Party' : 8 , 'Time': 9 #not in pst
+ }
+elif GUICommon.GameIsIWD2(): #Icewind Dale 2
+ OptionTip = {
+ 'Inventory' : 16307, 'Map': 16310, 'Mage': 16309, 'Priest': 14930, 'Stats': 16306, 'Journal': 16308,
+ 'Options' : 16311, 'Rest': 11942, 'Follow': 41647, 'Expand': 41660, 'AI' : 1,'Game' : 16313, 'Party' : 16312,
+ 'SpellBook': 16309, 'SelectAll': 10485
+ }
+ OptionControl = {
+ 'Inventory' : 5, 'Map' : 7, 'Mage': 5, 'Priest': 6, 'Stats': 8, 'Journal': 6,
+ 'Options' : 9, 'Rest': 12, 'Follow': 0, 'Expand': 10, 'AI': 6,
+ 'Game': 0, 'Party' : 13, 'Time': 10, #not in pst
+ 'SpellBook': 4, 'SelectAll': 11
+ }
+else: # Baldurs Gate, Icewind Dale
+ AITip = {"Deactivate" : 15918, "Enable" : 15917}
+ OptionTip = {
+ 'Inventory' : 16307, 'Map': 16310, 'Mage': 16309, 'Priest': 14930, 'Stats': 16306, 'Journal': 16308,
+ 'Options' : 16311, 'Rest': 11942, 'Follow': 41647, 'Expand': 41660, 'AI' : 1, 'Game' : 16313, 'Party' : 16312
+ }
+ OptionControl = {
+ 'Inventory' : 3, 'Map' : 1, 'Mage': 5, 'Priest': 6, 'Stats': 4, 'Journal': 2,
+ 'Options' : 7, 'Rest': 9, 'Follow': 0, 'Expand': 10, 'AI': 6,
+ 'Game': 0, 'Party' : 8, 'Time': 9 #not in pst
+ }
+
+# Generic option button init. Pass it the options window. Index is a key to the dicts,
+# IsPage means whether the game should mark the button selected
+def InitOptionButton(Window, Index, Action=0,IsPage=1):
+ if not Window.HasControl(OptionControl[Index]):
+ print "InitOptionButton cannot find the button: " + Index
+ return
+
+ Button = Window.GetControl (OptionControl[Index])
+ # FIXME: add "(key)" to tooltips!
+ Button.SetTooltip (OptionTip[Index])
+ if Action:
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, Action)
+ if IsPage:
+ Button.SetVarAssoc ("SelectedWindow", OptionControl[Index])
+ return Button
+
+##these defaults don't seem to break the games other than pst
+def SetupMenuWindowControls (Window, Gears=None, CloseWindowCallback=None):
+ """Binds all of the basic controls and windows to the options pane."""
+
+ global OptionsWindow, ActionBarControlOffset, ReturnToGame
+
+ OptionsWindow = Window
+ ReturnToGame = CloseWindowCallback
+
+ bg1 = GUICommon.GameIsBG1()
+ bg2 = GUICommon.GameIsBG2()
+ iwd1 = GUICommon.GameIsIWD1()
+ how = GUICommon.HasHOW()
+ iwd2 = GUICommon.GameIsIWD2()
+ pst = GUICommon.GameIsPST()
+ #store these instead of doing 50 calls...
+
+ if iwd2: # IWD2 has one spellbook to rule them all
+ ActionBarControlOffset = 6 #portrait and action window were merged
+ # Spellbook
+ Button = InitOptionButton(Window, 'SpellBook', GUISPL.OpenSpellBookWindow)
+ if Gears: # todo: don't know if it needs this if or if it's if'fing around
+ # Select All
+ Button = InitOptionButton(Window, 'SelectAll', GUICommon.SelectAllOnPress)
+
+ elif pst: #pst has these three controls here instead of portrait pane
+ # (Un)Lock view on character
+ Button = InitOptionButton(Window, 'Follow', OnLockViewPress) # or 41648 Unlock ...
+ # AI
+ Button = InitOptionButton(Window, 'AI', AIPress)
+ AIPress(0) #this initialises the state and tooltip
+
+ # Message popup FIXME disable on non game screen...
+ Button = InitOptionButton(Window,'Expand')# or 41661 Close ...
+
+ else: ## pst lacks this control here. it is on the clock. iwd2 seems to skip it
+ # Return to Game
+ Button = InitOptionButton(Window,'Game', ReturnToGame)
+ Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+ if bg1:
+ # enabled BAM isn't present in .chu, defining it here
+ Button.SetSprites ("GUILSOP", 0,16,17,28,16)
+ if iwd1:
+ # disabled/selected frame isn't present in .chu, defining it here
+ Button.SetSprites ("GUILSOP", 0,16,17,16,16)
+
+ # Party managment / character arbitration. Distinct form reform party window.
+ if not pst:
+ Button = Window.GetControl (OptionControl['Party'])
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, None) #TODO: OpenPartyWindow
+ if bg1 or bg2:
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+ Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_OR)
+ else:
+ Button.SetTooltip (OptionTip['Party'])
+
+ # Map
+ Button = InitOptionButton(Window, 'Map', GUIMA.OpenMapWindow)
+ if bg1:
+ Button.SetSprites ("GUILSOP", 0,0,1,20,0)
+ if iwd1:
+ Button.SetSprites ("GUILSOP", 0,0,1,20,20)
+
+ # Journal
+ Button = InitOptionButton(Window, 'Journal', GUIJRNL.OpenJournalWindow)
+ if bg1:
+ Button.SetSprites ("GUILSOP", 0,4,5,22,4)
+ if iwd1:
+ Button.SetSprites ("GUILSOP", 0,4,5,22,22)
+
+ # Inventory
+ Button = InitOptionButton(Window, 'Inventory', GUIINV.OpenInventoryWindow)
+ if bg1:
+ Button.SetSprites ("GUILSOP", 0,2,3,21,2)
+ if iwd1:
+ Button.SetSprites ("GUILSOP", 0,2,3,21,21)
+
+ # Records
+ Button = InitOptionButton(Window, 'Stats', GUIREC.OpenRecordsWindow)
+ if bg1:
+ Button.SetSprites ("GUILSOP", 0,6,7,23,6)
+ if iwd1:
+ Button.SetSprites ("GUILSOP", 0,6,7,23,23)
+
+ if not iwd2: # All Other Games Have Fancy Distinct Spell Pages
+ # Mage
+ Button = InitOptionButton(Window, 'Mage', GUIMG.OpenMageWindow)
+ if bg1:
+ Button.SetSprites ("GUILSOP", 0,8,9,24,8)
+ if iwd1:
+ Button.SetSprites ("GUILSOP", 0,8,9,24,24)
+
+ # Priest
+ Button = InitOptionButton(Window, 'Priest', GUIPR.OpenPriestWindow)
+ if bg1:
+ Button.SetSprites ("GUILSOP", 0,10,11,25,10)
+ if iwd1:
+ Button.SetSprites ("GUILSOP", 0,10,11,25,25)
+
+ # Options
+ Button = InitOptionButton(Window, 'Options', GUIOPT.OpenOptionsWindow)
+ if bg1:
+ Button.SetSprites ("GUILSOP", 0,12,13,26,12)
+ if iwd1:
+ Button.SetSprites ("GUILSOP", 0,12,13,26,26)
+
+
+ # pause button
+ if Gears:
+ # Pendulum, gears, sun/moon dial (time)
+ # FIXME: display all animations: CPEN, CGEAR, CDIAL
+ if how: # how doesn't have this in the right place
+ pos = GemRB.GetSystemVariable (SV_HEIGHT)-71
+ Window.CreateButton (OptionControl['Time'], 6, pos, 64, 71)
+ Button = Window.GetControl (OptionControl['Time'])
+ if bg2:
+ Label = Button.CreateLabelOnButton (0x10000009, "NORMAL", 0)
+ Label.SetAnimation ("CPEN")
+
+ Button.SetAnimation ("CGEAR")
+ Button.SetState (IE_GUI_BUTTON_ENABLED)
+ Button.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_ANIMATED|IE_GUI_BUTTON_NORMAL, OP_SET)
+ Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, GUICommon.GearsClicked)
+ if iwd2:
+ Button.SetState (IE_GUI_BUTTON_LOCKED) #no button depression, timer is an inset stone planet
+ rb = OptionControl['Rest']
+ else:
+ rb = 11
+ UpdateClock ()
+ else:
+ rb = OptionControl['Rest']
+
+ # Rest
+ if Window.HasControl (rb):
+ Button = Window.GetControl (rb)
+ Button.SetTooltip (OptionTip['Rest'])
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, RestPress)
+
+ if bg1 or iwd1 or bg2:
+ MarkMenuButton (Window)
+
+ if PortraitWindow:
+ UpdatePortraitWindow ()
+ return
+
+def MarkMenuButton (WindowIndex):
+ Pressed = WindowIndex.GetControl( GemRB.GetVar ("SelectedWindow") )
+
+ for button in range (9):
+ Button = WindowIndex.GetControl (button)
+ Button.SetState (IE_GUI_BUTTON_ENABLED)
+
+ if Pressed:
+ Button = Pressed
+ else: # highlight return to game
+ Button = WindowIndex.GetControl (0)
+
+ # NOTE: Alternatively, comment out this block or add a feature check, so that
+ # clicking button the second time closes a window again, which might be preferred
+ if GUICommon.GameIsIWD1() and GemRB.GetVar ("SelectedWindow") != 0:
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+ return
+
+ Button.SetState (IE_GUI_BUTTON_SELECTED)
+
+ return
+
+def OptionsPress ():
+ """Toggles the options pane """
+ PP = GemRB.GetMessageWindowSize () & GS_OPTIONPANE
+ if PP:
+ GemRB.GameSetScreenFlags (GS_OPTIONPANE, OP_NAND)
+ else:
+ GemRB.GameSetScreenFlags (GS_OPTIONPANE, OP_OR)
+ return
+
+def OnLockViewPress ():
+ Button = OptionsWindow.GetControl (0)
+ GemRB.GameControlSetScreenFlags (SF_CENTERONACTOR | SF_ALWAYSCENTER, OP_XOR)
+
+ # no way to get the screen flags
+ if OnLockViewPress.counter % 2:
+ # unlock
+ Button.SetTooltip (41648)
+ Button.SetState(IE_GUI_BUTTON_SELECTED)#dont ask
+ else:
+ # lock
+ Button.SetTooltip (41647)
+ Button.SetState(IE_GUI_BUTTON_NORMAL)
+ OnLockViewPress.counter += 1
+
+ return
+
+OnLockViewPress.counter = 1
+
+def PortraitPress (): #not used in pst. TODO:make an enhancement option?
+ """Toggles the portraits pane """
+ PP = GemRB.GetMessageWindowSize () & GS_PORTRAITPANE
+ if PP:
+ GemRB.GameSetScreenFlags (GS_PORTRAITPANE, OP_NAND)
+ else:
+ GemRB.GameSetScreenFlags (GS_PORTRAITPANE, OP_OR)
+ return
+
+def AIPress (toggle=1):
+ """Toggles the party AI or refreshes the button state if toggle = 0"""
+
+ if GUICommon.GameIsPST():
+ Button = OptionsWindow.GetControl (OptionControl['AI'])
+ else:
+ Button = PortraitWindow.GetControl (OptionControl['AI'])
+
+ print "AIPress: GS_PARTYAI was:", GemRB.GetMessageWindowSize () & GS_PARTYAI, "at toggle:", toggle
+ if toggle:
+ GemRB.GameSetScreenFlags (GS_PARTYAI, OP_XOR)
+
+ AI = GemRB.GetMessageWindowSize () & GS_PARTYAI
+ if AI:
+ GemRB.SetVar ("AI", 0)
+ Button.SetTooltip (AITip['Deactivate'])
+ Button.SetState(IE_GUI_BUTTON_SELECTED)
+ else:
+ GemRB.SetVar ("AI", GS_PARTYAI)
+ Button.SetTooltip (AITip['Enable'])
+ Button.SetState(IE_GUI_BUTTON_NORMAL)
+
+ #force redrawing, in case a hotkey triggered this function
+ Button.SetVarAssoc ("AI", GS_PARTYAI)
+ return
+
+## The following four functions are for the action bar
+## they are currently unused in pst
+def EmptyControls ():
+ if GUICommon.GameIsPST():
+ return
+ Selected = GemRB.GetSelectedSize()
+ if Selected==1:
+ pc = GemRB.GameGetFirstSelectedActor ()
+ #init spell list
+ GemRB.SpellCast (pc, -1, 0)
+
+ GemRB.SetVar ("ActionLevel", 0)
+ for i in range (12):
+ Button = CurrentWindow.GetControl (i+ActionBarControlOffset)
+ Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
+ Button.SetPicture ("")
+ Button.SetText ("")
+ Button.SetActionIcon (globals(), -1)
+ return
+
+def SelectFormationPreset ():
+ """Choose the default formation."""
+ GemRB.GameSetFormation (GemRB.GetVar ("Value"), GemRB.GetVar ("Formation") )
+ GroupControls ()
+ return
+
+def SetupFormation ():
+ """Opens the formation selection section."""
+ for i in range (12):
+ Button = CurrentWindow.GetControl (i+ActionBarControlOffset)
+ Button.SetFlags (IE_GUI_BUTTON_NORMAL, OP_SET)
+ Button.SetSprites ("GUIBTBUT",0,0,1,2,3)
+ Button.SetBAM ("FORM%x"%i,0,0,-1)
+ Button.SetVarAssoc ("Value", i)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SelectFormationPreset)
+ Button.SetState (IE_GUI_BUTTON_UNPRESSED)
+ return
+
+def GroupControls ():
+ """Sections that control group actions."""
+ GemRB.SetVar ("ActionLevel", 0)
+ Button = CurrentWindow.GetControl (ActionBarControlOffset)
+ if GUICommon.GameIsBG2():
+ Button.SetActionIcon (globals(), 7) #talk icon
+ else:
+ Button.SetActionIcon (globals(), 14)#guard icon
+ Button = CurrentWindow.GetControl (1+ActionBarControlOffset)
+ Button.SetActionIcon (globals(), 15)
+ Button = CurrentWindow.GetControl (2+ActionBarControlOffset)
+ Button.SetActionIcon (globals(), 21)
+ Button = CurrentWindow.GetControl (3+ActionBarControlOffset)
+ Button.SetActionIcon (globals(), -1)
+ Button = CurrentWindow.GetControl (4+ActionBarControlOffset)
+ Button.SetActionIcon (globals(), -1)
+ Button = CurrentWindow.GetControl (5+ActionBarControlOffset)
+ Button.SetActionIcon (globals(), -1)
+ Button = CurrentWindow.GetControl (6+ActionBarControlOffset)
+ Button.SetActionIcon (globals(), -1)
+ GemRB.SetVar ("Formation", GemRB.GameGetFormation ())
+ for i in range (5):
+ Button = CurrentWindow.GetControl (7+ActionBarControlOffset+i)
+ Button.SetState (IE_GUI_BUTTON_ENABLED)
+ idx = GemRB.GameGetFormation (i)
+ Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON|IE_GUI_BUTTON_NORMAL, OP_SET)
+ # kill the previous sprites or they show through
+ Button.SetSprites ("GUIBTBUT",0,0,1,2,3)
+ Button.SetBAM ("FORM%x"%idx,0,0,-1)
+ Button.SetVarAssoc ("Formation", i)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUICommon.SelectFormation)
+ Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, SetupFormation)
+ Button.SetTooltip (4935, 8+i)
+ return
+
+def OpenActionsWindowControls (Window): #FIXME:unused in pst. one day could be?
+ global ActionsWindow
+
+ ActionsWindow = Window
+ # 1280 and higher don't have this control
+ if not Window.HasControl (62):
+ UpdateActionsWindow ()
+ return
+ # Gears (time) when options pane is down
+ Button = Window.GetControl (62)
+ Label = Button.CreateLabelOnButton (0x1000003e, "NORMAL", 0)
+
+ # FIXME: display all animations
+ Label.SetAnimation ("CPEN")
+ Button.SetAnimation ("CGEAR")
+ Button.SetState (IE_GUI_BUTTON_ENABLED)
+ Button.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_ANIMATED|IE_GUI_BUTTON_NORMAL, OP_SET)
+ Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, GUICommon.GearsClicked)
+ UpdateActionsWindow ()
+ return
+
+def SetupClockWindowControls (Window):
+ global ActionsWindow
+
+ ActionsWindow = Window
+ # time button
+ Button = Window.GetControl (0)
+ Button.SetAnimation ("WMTIME")
+ Button.SetState (IE_GUI_BUTTON_LOCKED)
+ Button.SetFlags (IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_ANIMATED, OP_SET)
+ Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, GUICommon.GearsClicked)
+ Button.SetEvent(IE_GUI_MOUSE_ENTER_BUTTON, UpdateClock)
+ SetPSTGamedaysAndHourToken ()
+ Button.SetTooltip (GemRB.GetString(65027))
+
+ # 41627 - Return to the Game World
+ Button = Window.GetControl (2)
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+ Button.SetTooltip (41627)
+
+ # Select all characters
+ Button = Window.GetControl (1)
+ Button.SetTooltip (41659)
+
+ # Abort current action
+ Button = Window.GetControl (3)
+ Button.SetTooltip (41655)
+
+ # Formations
+ Button = Window.GetControl (4)
+ Button.SetTooltip (44945)
+
+ return
+
+##not used in pst - not sure any items have abilities, but it is worth making a note to find out
+def SelectItemAbility():
+ pc = GemRB.GameGetFirstSelectedActor ()
+ slot = GemRB.GetVar ("Slot")
+ ability = GemRB.GetVar ("Ability")
+ GemRB.SetupQuickSlot (pc, 0, slot, ability)
+ GemRB.SetVar ("ActionLevel", 0)
+ return
+
+#in pst only nordom has bolts and they show on the same floatmenu as quickweapons, so needs work here
+def SelectQuiverSlot():
+ pc = GemRB.GameGetFirstSelectedActor ()
+ slot = GemRB.GetVar ("Slot")
+ slot_item = GemRB.GetSlotItem (pc, slot)
+ # HACK: implement SetEquippedAmmunition instead?
+ if not GemRB.IsDraggingItem ():
+ item = GemRB.GetItem (slot_item["ItemResRef"])
+ GemRB.DragItem (pc, slot, item["ItemIcon"]) #, 0, 0)
+ GemRB.DropDraggedItem (pc, slot)
+ GemRB.SetVar ("ActionLevel", 0)
+ return
+
+#this doubles up as an ammo selector (not yet used in pst)
+def SetupItemAbilities(pc, slot):
+ slot_item = GemRB.GetSlotItem(pc, slot)
+ if not slot_item:
+ # CHIV: Could configure empty quickslots from the game screen ala spells heres
+ return
+
+ item = GemRB.GetItem (slot_item["ItemResRef"])
+ Tips = item["Tooltips"]
+
+ # clear buttons here
+ EmptyControls()
+
+ # check A: whether ranged weapon and B: whether to bother at all
+ ammotype = 0
+ if item["Type"] == CommonTables.ItemType.GetRowIndex ("BOW"):
+ ammotype = CommonTables.ItemType.GetRowIndex ("ARROW")
+ elif item["Type"] == CommonTables.ItemType.GetRowIndex ("XBOW"):
+ ammotype = CommonTables.ItemType.GetRowIndex ("BOLT")
+ elif item["Type"] == CommonTables.ItemType.GetRowIndex ("SLING"):
+ ammotype = CommonTables.ItemType.GetRowIndex ("BULLET")
+
+ # FIXME: ammo does not preclude the item from also having abilities (eg. bg2:bow19)
+ ammoSlotCount = 0
+ if ammotype:
+ ammoslots = GemRB.GetSlots(pc, SLOT_QUIVER, 1)
+ currentammo = GemRB.GetEquippedAmmunition (pc)
+ for i in range (12):
+ Button = CurrentWindow.GetControl (i+ActionBarControlOffset)
+ if i < len(ammoslots):
+ ammoslot = GemRB.GetSlotItem (pc, ammoslots[i])
+ st = GemRB.GetSlotType (ammoslots[i])
+ ammoitem = GemRB.GetItem (ammoslot['ItemResRef']) # needed to show the ammo count
+ Tips = ammoitem["Tooltips"]
+ # if this item is valid ammo and was really found in a quiver slot
+ if ammoitem['Type'] == ammotype and st["Type"] == SLOT_QUIVER:
+ ammoSlotCount += 1
+ Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON|IE_GUI_BUTTON_ALIGN_BOTTOM|IE_GUI_BUTTON_ALIGN_RIGHT, OP_SET)
+ Button.SetSprites ("GUIBTBUT",0,0,1,2,3)
+ Button.SetItemIcon (ammoslot['ItemResRef'])
+ Button.SetText (str(ammoslot["Usages0"]))
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SelectQuiverSlot)
+ Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, SelectQuiverSlot)
+ Button.SetVarAssoc ("Slot", ammoslots[i])
+ Button.SetTooltip ("%s" % (GemRB.GetString (Tips[0])))
+ print currentammo, i+1, ammoslots[i]
+ if currentammo == ammoslots[i]: # this check is ok, but the results are unreliable?!
+ Button.SetState (IE_GUI_BUTTON_SELECTED)
+
+ # skip when there is only one choice
+ if ammoSlotCount == 1:
+ ammoSlotCount = 0
+
+ # reset back to the main action bar if there are no extra headers or quivers
+ reset = not ammoSlotCount
+ # check for item abilities and skip the first that crops up (main header - nothing special)
+ if (len(Tips) > 1):
+ reset = False
+ rmax = min(len(Tips) - 1, 12-ammoSlotCount)
+ for i in range (rmax):
+ Button = CurrentWindow.GetControl (i+ActionBarControlOffset+ammoSlotCount)
+ Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON|IE_GUI_BUTTON_NORMAL, OP_SET)
+ Button.SetSprites ("GUIBTBUT",0,0,1,2,3)
+ Button.SetItemIcon (slot_item['ItemResRef'], i+6)
+ Button.SetText ("")
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SelectItemAbility)
+ Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, SelectItemAbility)
+ Button.SetVarAssoc ("Ability", i)
+ Button.SetState (IE_GUI_BUTTON_ENABLED)
+ Button.SetTooltip ("F%d - %s"%(i,GemRB.GetString(Tips[i])) )
+
+ if reset:
+ GemRB.SetVar ("ActionLevel", 0)
+ UpdateActionsWindow ()
+ return
+
+ #only in iwd2? could be exported...
+def SetupBookSelection ():
+ for i in range (12):
+ Button = CurrentWindow.GetControl (i+ActionBarControlOffset)
+ Button.SetActionIcon (globals(), 50+i)
+ return
+
+#you can change this for custom skills, this is the original engine
+skillbar=(ACT_STEALTH, ACT_SEARCH, ACT_THIEVING, ACT_WILDERNESS, ACT_TAMING, 100, 100, 100, 100, 100, 100, 100)
+def SetupSkillSelection ():
+ pc = GemRB.GameGetFirstSelectedActor ()
+ CurrentWindow.SetupControls( globals(), pc, ActionBarControlOffset, skillbar)
+ return
+
+########################
+
+#None of the following functions are implemented yet for pst (or not fully)
+#some are needed (eg stealth, innates), but some may be redundant
+#however, it would still be nice to add them via game mods for replay value
+
+########################
+
+def UpdateActionsWindow ():
+ """Redraws the actions section of the window."""
+ global CurrentWindow, OptionsWindow, PortraitWindow
+ global level, TopIndex
+
+ if GUICommon.GameIsPST():
+ return
+ if GUICommon.GameIsIWD2():
+ CurrentWindow = PortraitWindow
+ ActionBarControlOffset = 6 # set it here too, since we get called before menu setup
+ else:
+ CurrentWindow = ActionsWindow
+ ActionBarControlOffset = 0
+
+ if CurrentWindow == -1:
+ return
+
+ if CurrentWindow == None:
+ return
+
+ #fully redraw the side panes to cover the actions window
+ #do this only when there is no 'otherwindow'
+ if GUICommon.GameIsIWD2():
+ if GemRB.GetVar ("OtherWindow") != -1:
+ return
+ else:
+ UpdateClock ()
+ if GemRB.GetVar ("OtherWindow") == -1:
+ if PortraitWindow:
+ PortraitWindow.Invalidate ()
+ if OptionsWindow:
+ OptionsWindow.Invalidate ()
+
+ Selected = GemRB.GetSelectedSize()
+
+ #setting up the disabled button overlay (using the second border slot)
+ for i in range (12):
+ Button = CurrentWindow.GetControl (i+ActionBarControlOffset)
+ if GUICommon.GameIsBG1():
+ Button.SetBorder (0,6,6,4,4,0,254,0,255)
+ Button.SetBorder (1, 0, 0, 0, 0, 50,30,10,120, 0, 1)
+ Button.SetFont ("NUMBER")
+ Button.SetText ("")
+ Button.SetTooltip("")
+
+ if Selected == 0:
+ EmptyControls ()
+ return
+ if Selected > 1:
+ GroupControls ()
+ return
+
+ #we are sure there is only one actor selected
+ pc = GemRB.GameGetFirstSelectedActor ()
+
+ level = GemRB.GetVar ("ActionLevel")
+ TopIndex = GemRB.GetVar ("TopIndex")
+ if level == 0:
+ #this is based on class
+ CurrentWindow.SetupControls (globals(), pc, ActionBarControlOffset)
+ elif level == 1:
+ CurrentWindow.SetupEquipmentIcons(globals(), pc, TopIndex, ActionBarControlOffset)
+ elif level == 2: #spells
+ if GUICommon.GameIsIWD2():
+ type = 255
+ else:
+ type = 3
+ GemRB.SetVar ("Type", type)
+ Spellbook.SetupSpellIcons(CurrentWindow, type, TopIndex, ActionBarControlOffset)
+ elif level == 3: #innates
+ if GUICommon.GameIsIWD2():
+ type = 256 + 1024
+ else:
+ type = 4
+ GemRB.SetVar ("Type", type)
+ Spellbook.SetupSpellIcons(CurrentWindow, type, TopIndex, ActionBarControlOffset)
+ elif level == 4: #quick weapon/item ability selection
+ SetupItemAbilities(pc, GemRB.GetVar("Slot") )
+ elif level == 5: #all known mage spells
+ GemRB.SetVar ("Type", -1)
+ Spellbook.SetupSpellIcons(CurrentWindow, -1, TopIndex, ActionBarControlOffset)
+ elif level == 6: # iwd2 skills
+ SetupSkillSelection()
+ elif level == 7: # quickspells, but with innates too
+ if GUICommon.GameIsIWD2():
+ type = 255 + 256 + 1024
+ else:
+ type = 7
+ GemRB.SetVar ("Type", type)
+ Spellbook.SetupSpellIcons(CurrentWindow, type, TopIndex, ActionBarControlOffset)
+ elif level == 8: # shapes selection
+ GemRB.SetVar ("Type", 1024)
+ Spellbook.SetupSpellIcons(CurrentWindow, 1024, TopIndex, ActionBarControlOffset)
+ elif level == 9: # songs selection
+ GemRB.SetVar ("Type", 512)
+ Spellbook.SetupSpellIcons(CurrentWindow, 512, TopIndex, ActionBarControlOffset)
+ elif level == 10: # spellbook selection
+ type = GemRB.GetVar ("Type")
+ Spellbook.SetupSpellIcons(CurrentWindow, type, TopIndex, ActionBarControlOffset)
+ elif level == 11: # spells from a 2da (fx_select_spell)
+ if GUICommon.GameIsIWD2():
+ type = 255
+ else:
+ type = 3
+ GemRB.SetVar ("Type", type)
+ Spellbook.SetupSpellIcons (CurrentWindow, type, TopIndex, ActionBarControlOffset)
+ else:
+ print "Invalid action level:", level
+ GemRB.SetVar ("ActionLevel", 0)
+ return
+
+def ActionQWeaponPressed (which):
+ """Selects the given quickslot weapon if possible."""
+
+ pc = GemRB.GameGetFirstSelectedActor ()
+ qs = GemRB.GetEquippedQuickSlot (pc, 1)
+
+ #38 is the magic slot
+ if ((qs==which) or (qs==38)) and GemRB.GameControlGetTargetMode() != TARGET_MODE_ATTACK:
+ GemRB.GameControlSetTargetMode (TARGET_MODE_ATTACK, GA_NO_DEAD|GA_NO_SELF|GA_NO_HIDDEN)
+ else:
+ GemRB.GameControlSetTargetMode (TARGET_MODE_NONE)
+ GemRB.SetEquippedQuickSlot (pc, which, -1)
+
+ CurrentWindow.SetupControls (globals(), pc, ActionBarControlOffset)
+ UpdateActionsWindow ()
+ return
+
+def ActionQWeapon1Pressed ():
+ ActionQWeaponPressed(0)
+
+def ActionQWeapon2Pressed ():
+ ActionQWeaponPressed(1)
+
+def ActionQWeapon3Pressed ():
+ ActionQWeaponPressed(2)
+
+def ActionQWeapon4Pressed ():
+ ActionQWeaponPressed(3)
+
+def ActionQSpellPressed (which):
+ pc = GemRB.GameGetFirstSelectedActor ()
+
+ GemRB.SpellCast (pc, -2, which)
+ UpdateActionsWindow ()
+ return
+
+def ActionQSpell1Pressed ():
+ ActionQSpellPressed(0)
+
+def ActionQSpell2Pressed ():
+ ActionQSpellPressed(1)
+
+def ActionQSpell3Pressed ():
+ ActionQSpellPressed(2)
+
+def ActionQSpellRightPressed (which):
+ GemRB.SetVar ("QSpell", which)
+ GemRB.SetVar ("TopIndex", 0)
+ GemRB.SetVar ("ActionLevel", 7)
+ UpdateActionsWindow ()
+ return
+
+def ActionQSpell1RightPressed ():
+ ActionQSpellRightPressed(0)
+
+def ActionQSpell2RightPressed ():
+ ActionQSpellRightPressed(1)
+
+def ActionQSpell3RightPressed ():
+ ActionQSpellRightPressed(2)
+
+# can't pass the globals dictionary from another module
+def SetActionIconWorkaround(Button, action, function):
+ Button.SetActionIcon (globals(), action, function)
+
+#no check needed because the button wouldn't be drawn if illegal
+def ActionLeftPressed ():
+ """Scrolls the actions window left.
+
+ Used primarily for spell selection."""
+
+ TopIndex = GemRB.GetVar ("TopIndex")
+ if TopIndex>10:
+ TopIndex -= 10
+ else:
+ TopIndex = 0
+ GemRB.SetVar ("TopIndex", TopIndex)
+ UpdateActionsWindow ()
+ return
+
+#no check needed because the button wouldn't be drawn if illegal
+def ActionRightPressed ():
+ """Scrolls the action window right.
+
+ Used primarily for spell selection."""
+
+ pc = GemRB.GameGetFirstSelectedActor ()
+ TopIndex = GemRB.GetVar ("TopIndex")
+ Type = GemRB.GetVar ("Type")
+ print "Type:", Type
+ #Type is a bitfield if there is no level given
+ #This is to make sure cleric/mages get all spells listed
+ if GemRB.GetVar ("ActionLevel") == 5:
+ if Type == 3:
+ Max = len(Spellbook.GetKnownSpells (pc, IE_SPELL_TYPE_PRIEST) + Spellbook.GetKnownSpells (pc, IE_SPELL_TYPE_WIZARD))
+ else:
+ Max = GemRB.GetKnownSpellsCount (pc, Type, -1) # this can handle only one type at a time
+ else:
+ Max = GemRB.GetMemorizedSpellsCount(pc, Type, -1, 1)
+ print "Max:",Max
+ TopIndex += 10
+ if TopIndex > Max - 10:
+ if Max>10:
+ if TopIndex > Max:
+ TopIndex = Max - 10
+ else:
+ TopIndex = 0
+ GemRB.SetVar ("TopIndex", TopIndex)
+ UpdateActionsWindow ()
+ return
+
+def ActionMeleePressed ():
+ """ switches to the most damaging melee weapon"""
+ #get the party Index
+ pc = GemRB.GameGetFirstSelectedPC ()
+ GemRB.ExecuteString("EquipMostDamagingMelee()", pc)
+ return
+
+def ActionRangePressed ():
+ """ switches to the most damaging ranged weapon"""
+ #get the party Index
+ pc = GemRB.GameGetFirstSelectedPC ()
+ GemRB.ExecuteString("EquipRanged()", pc)
+ return
+
+def ActionShapeChangePressed ():
+ GemRB.SetVar ("ActionLevel", 8)
+ UpdateActionsWindow ()
+ return
+
+def ActionBardSongRightPressed ():
+ """Selects a bardsong."""
+ GemRB.SetVar ("ActionLevel", 9)
+ UpdateActionsWindow ()
+ return
+
+def ActionBardSongPressed ():
+ """Toggles the battle song."""
+
+ ##FIXME: check if the actor can actually switch to this state
+ #get the global ID
+ pc = GemRB.GameGetFirstSelectedActor ()
+ GemRB.SetModalState (pc, MS_BATTLESONG)
+ GemRB.PlaySound ("act_01")
+ GemRB.SetVar ("ActionLevel", 0)
+ UpdateActionsWindow ()
+ return
+
+def ActionSearchPressed ():
+ """Toggles detect traps."""
+
+ ##FIXME: check if the actor can actually switch to this state
+ #get the global ID
+ pc = GemRB.GameGetFirstSelectedActor ()
+ GemRB.SetModalState (pc, MS_DETECTTRAPS)
+ GemRB.SetVar ("ActionLevel", 0)
+ UpdateActionsWindow ()
+ return
+
+def ActionStealthPressed ():
+ """Toggles stealth."""
+ pc = GemRB.GameGetFirstSelectedActor ()
+ GemRB.SetModalState (pc, MS_STEALTH)
+ GemRB.PlaySound ("act_07")
+ GemRB.SetVar ("ActionLevel", 0)
+ UpdateActionsWindow ()
+ return
+
+def ActionTurnPressed ():
+ """Toggles turn undead."""
+ pc = GemRB.GameGetFirstSelectedActor ()
+ GemRB.SetModalState (pc, MS_TURNUNDEAD)
+ GemRB.PlaySound ("act_06")
+ GemRB.SetVar ("ActionLevel", 0)
+ UpdateActionsWindow ()
+ return
+
+def ActionTamingPressed ():
+ GemRB.SetVar ("ActionLevel", 0)
+ UpdateActionsWindow ()
+ return
+
+def ActionWildernessPressed ():
+ GemRB.SetVar ("ActionLevel", 0)
+ UpdateActionsWindow ()
+ return
+
+def ActionUseItemPressed ():
+ GemRB.SetVar ("TopIndex", 0)
+ GemRB.SetVar ("ActionLevel", 1)
+ UpdateActionsWindow ()
+ return
+
+def ActionCastPressed ():
+ """Opens the spell choice scrollbar."""
+ GemRB.SetVar ("QSpell", -1)
+ GemRB.SetVar ("TopIndex", 0)
+ GemRB.SetVar ("ActionLevel", 2)
+ UpdateActionsWindow ()
+ return
+
+def ActionQItemPressed (action):
+ """Uses the given quick item."""
+ pc = GemRB.GameGetFirstSelectedActor ()
+ #quick slot
+ GemRB.UseItem (pc, -2, action, -1)
+ return
+
+def ActionQItem1Pressed ():
+ ActionQItemPressed (ACT_QSLOT1)
+ return
+
+def ActionQItem2Pressed ():
+ ActionQItemPressed (ACT_QSLOT2)
+ return
+
+def ActionQItem3Pressed ():
+ ActionQItemPressed (ACT_QSLOT3)
+ return
+
+def ActionQItem4Pressed ():
+ ActionQItemPressed (ACT_QSLOT4)
+ return
+
+def ActionQItem5Pressed ():
+ ActionQItemPressed (ACT_QSLOT5)
+ return
+
+def ActionQItemRightPressed (action):
+ """Selects the used ability of the quick item."""
+ pc = GemRB.GameGetFirstSelectedActor ()
+ GemRB.SetVar ("Slot", action)
+ GemRB.SetVar ("ActionLevel", 4)
+ UpdateActionsWindow ()
+ return
+
+def ActionQItem1RightPressed ():
+ ActionQItemRightPressed (19)
+
+def ActionQItem2RightPressed ():
+ ActionQItemRightPressed (20)
+
+def ActionQItem3RightPressed ():
+ ActionQItemRightPressed (21)
+
+def ActionQItem4RightPressed ():
+ ActionQItemRightPressed (22)
+
+def ActionQItem5RightPressed ():
+ ActionQItemRightPressed (23)
+
+def ActionQWeapon1RightPressed ():
+ ActionQItemRightPressed (10)
+
+def ActionQWeapon2RightPressed ():
+ ActionQItemRightPressed (11)
+
+def ActionQWeapon3RightPressed ():
+ ActionQItemRightPressed (12)
+
+def ActionQWeapon4RightPressed ():
+ ActionQItemRightPressed (13)
+
+def ActionInnatePressed ():
+ """Opens the innate spell scrollbar."""
+ GemRB.SetVar ("QSpell", -1)
+ GemRB.SetVar ("TopIndex", 0)
+ GemRB.SetVar ("ActionLevel", 3)
+ UpdateActionsWindow ()
+ return
+
+def ActionSkillsPressed ():
+ GemRB.SetVar ("TopIndex", 0)
+ GemRB.SetVar ("ActionLevel", 6)
+ UpdateActionsWindow ()
+ return
+
+def TypeSpellPressed (type):
+ GemRB.SetVar ("Type", 1<<type)
+ GemRB.SetVar ("ActionLevel", 10)
+ UpdateActionsWindow ()
+ return
+
+def ActionBardSpellPressed ():
+ TypeSpellPressed(IE_IWD2_SPELL_BARD)
+ return
+
+def ActionClericSpellPressed ():
+ TypeSpellPressed(IE_IWD2_SPELL_CLERIC)
+ return
+
+def ActionDruidSpellPressed ():
+ TypeSpellPressed(IE_IWD2_SPELL_DRUID)
+ return
+
+def ActionPaladinSpellPressed ():
+ TypeSpellPressed(IE_IWD2_SPELL_PALADIN)
+ return
+
+def ActionRangerSpellPressed ():
+ TypeSpellPressed(IE_IWD2_SPELL_RANGER)
+ return
+
+def ActionSorcererSpellPressed ():
+ TypeSpellPressed(IE_IWD2_SPELL_SORCERER)
+ return
+
+def ActionWizardSpellPressed ():
+ TypeSpellPressed(IE_IWD2_SPELL_WIZARD)
+ return
+
+def ActionDomainSpellPressed ():
+ TypeSpellPressed(IE_IWD2_SPELL_DOMAIN)
+ return
+
+def ActionWildShapesPressed ():
+ TypeSpellPressed(IE_IWD2_SPELL_SHAPE)
+ return
+
+# This is the endpoint for spellcasting, finally calling SpellCast. This always happens at least
+# twice though, the second time to reset the action bar (more if wild magic or subspell selection is involved).
+# Spell and Type (spellbook type) are set during the spell bar construction/use, which is in turn
+# affected by ActionLevel (see UpdateActionsWindow of this module).
+# Keep in mind, that the core resets Type and/or ActionLevel in the case of subspells (fx_select_spell).
+def SpellPressed ():
+ """Prepares a spell to be cast."""
+
+ pc = GemRB.GameGetFirstSelectedActor ()
+
+ Spell = GemRB.GetVar ("Spell")
+ Type = GemRB.GetVar ("Type")
+
+ if Type == 1024:
+ #SelectBardSong(Spell)
+ ActionBardSongPressed()
+ return
+
+ GemRB.GameControlSetTargetMode (TARGET_MODE_CAST)
+ if Type != -1:
+ Type = Spell // 1000
+ Spell = Spell % 1000
+ slot = GemRB.GetVar ("QSpell")
+ if slot>=0:
+ #setup quickspell slot
+ #if spell has no target, return
+ #otherwise continue with casting
+ Target = GemRB.SetupQuickSpell (pc, slot, Spell, Type)
+ #sabotage the immediate casting of self targeting spells
+ if Target == 5 or Target == 7:
+ Type = -1
+ GemRB.GameControlSetTargetMode (TARGET_MODE_NONE)
+
+ if Type==-1:
+ GemRB.SetVar ("ActionLevel", 0)
+ GemRB.SetVar("Type", 0)
+ GemRB.SpellCast (pc, Type, Spell)
+ if GemRB.GetVar ("Type")!=-1:
+ GemRB.SetVar ("ActionLevel", 0)
+ #init spell list
+ GemRB.SpellCast (pc, -1, 0)
+ GemRB.SetVar ("TopIndex", 0)
+ UpdateActionsWindow ()
+ return
+
+def EquipmentPressed ():
+ pc = GemRB.GameGetFirstSelectedActor ()
+
+ GemRB.GameControlSetTargetMode (TARGET_MODE_CAST)
+ Item = GemRB.GetVar ("Equipment")
+ #equipment index
+ GemRB.UseItem (pc, -1, Item, -1)
+ GemRB.SetVar ("ActionLevel", 0)
+ UpdateActionsWindow ()
+ return
+
+######################
+
+#End of features that need adding to pst
+
+######################
+
+# NOTE: the following two features are only used in pst
+# which=INVENTORY|STATS|FMENU
+def GetActorPortrait (actor, which):
+ #return GemRB.GetPlayerPortrait( actor, which)
+
+ # only the lowest byte is meaningful here (OneByteAnimID)
+ anim_id = GemRB.GetPlayerStat (actor, IE_ANIMATION_ID) & 255
+ row = "0x%02X" %anim_id
+
+ return CommonTables.Pdolls.GetValue (row, which)
+
+
+def UpdateAnimation ():
+ if not GemRB.HasResource ("ANIMS", RES_2DA):
+ # FIXME: make a simpler version for non-pst too
+ # this is a callback from the core on EF_UPDATEANIM!
+ return
+
+ pc = GemRB.GameGetSelectedPCSingle ()
+
+ disguise = GemRB.GetGameVar ("APPEARANCE")
+ if disguise == 2: #dustman
+ animid = "DR"
+ elif disguise == 1: #zombie
+ animid = "ZO"
+ else:
+ slot = GemRB.GetEquippedQuickSlot (pc)
+ item = GemRB.GetSlotItem (pc, slot )
+ animid = ""
+ if item:
+ item = GemRB.GetItem(item["ItemResRef"])
+ if item:
+ animid = item["AnimationType"]
+
+ BioTable = GemRB.LoadTable ("BIOS")
+ Specific = "%d"%GemRB.GetPlayerStat (pc, IE_SPECIFIC)
+ AvatarName = BioTable.GetValue (Specific, "PC")
+ AnimTable = GemRB.LoadTable ("ANIMS")
+ if animid=="":
+ animid="*"
+ value = AnimTable.GetValue (animid, AvatarName)
+ if value<0:
+ return
+ GemRB.SetPlayerStat (pc, IE_ANIMATION_ID, value)
+ return
+
+# NOTE: the following 4 functions are only used in iwd2
+def GetActorRaceTitle (actor):
+ RaceID = GemRB.GetPlayerStat (actor, IE_SUBRACE)
+ if RaceID:
+ RaceID += GemRB.GetPlayerStat (actor, IE_RACE)<<16
+ else:
+ RaceID = GemRB.GetPlayerStat (actor, IE_RACE)
+ row = CommonTables.Races.FindValue (3, RaceID )
+ RaceTitle = CommonTables.Races.GetValue (row, 2)
+ return RaceTitle
+
+# NOTE: this function is called with the primary classes
+def GetKitIndex (actor, ClassIndex):
+ Kit = GemRB.GetPlayerStat (actor, IE_KIT)
+
+ KitIndex = -1
+ ClassName = CommonTables.Classes.GetRowName (ClassIndex)
+ ClassID = CommonTables.Classes.GetValue (ClassName, "ID")
+ # skip the primary classes
+ # start at the first original kit - in iwd2 both classes and kits are in the same table
+ KitOffset = CommonTables.Classes.FindValue ("CLASS", 7)
+ for ci in range (KitOffset, CommonTables.Classes.GetRowCount ()):
+ RowName = CommonTables.Classes.GetRowName (ci)
+ BaseClass = CommonTables.Classes.GetValue (RowName, "CLASS")
+ if BaseClass == ClassID and Kit & CommonTables.Classes.GetValue (RowName, "ID"):
+ #FIXME: this will return the last kit only, check if proper multikit return values are needed
+ KitIndex = ci
+
+ if KitIndex == -1:
+ return 0
+
+ return KitIndex
+
+def GetActorClassTitle (actor, ClassIndex):
+ ClassTitle = GemRB.GetPlayerStat (actor, IE_TITLE1)
+ if ClassTitle:
+ return ClassTitle
+
+ KitIndex = GetKitIndex (actor, ClassIndex)
+ if KitIndex == 0:
+ ClassName = CommonTables.Classes.GetRowName (ClassIndex)
+ else:
+ ClassName = CommonTables.Classes.GetRowName (KitIndex)
+ ClassTitle = CommonTables.Classes.GetValue (ClassName, "NAME_REF")
+
+ if ClassTitle == "*":
+ return 0
+ return ClassTitle
+
+# overriding the one in GUICommon, since we use a different table and animations
+def GetActorPaperDoll (actor):
+ level = GemRB.GetPlayerStat (actor, IE_ARMOR_TYPE)
+ return GemRB.GetAvatarsValue (actor, level)
+
+
+SelectionChangeHandler = None
+SelectionChangeMultiHandler = None ##relates to floatmenu
+
+def SetSelectionChangeHandler (handler):
+ """Updates the selection handler."""
+
+ global SelectionChangeHandler
+
+ # Switching from walking to non-walking environment:
+ # set the first selected PC in walking env as a selected
+ # in nonwalking env
+ #if (not SelectionChangeHandler) and handler:
+ if (not SelectionChangeHandler) and handler and (not GUICommon.NextWindowFn):
+ sel = GemRB.GameGetFirstSelectedPC ()
+ if not sel:
+ sel = 1
+ GemRB.GameSelectPCSingle (sel)
+
+ SelectionChangeHandler = handler
+
+ # redraw selection on change main selection | single selection
+ SelectionChanged ()
+ return
+
+def SetSelectionChangeMultiHandler (handler):
+ global SelectionChangeMultiHandler
+ SelectionChangeMultiHandler = handler
+ #SelectionChanged ()
+
+def RunSelectionChangeHandler ():
+ if SelectionChangeHandler:
+ SelectionChangeHandler ()
+ return
+
+#NOTE: this is for pst's hp buttons, but it could be optionally exported to other games
+portrait_hp_numeric = [0, 0, 0, 0, 0, 0]
+
+def OpenPortraitWindow (needcontrols=0):
+ global PortraitWindow
+
+ #take care, this window is different in how/iwd
+ if GUICommon.HasHOW() and needcontrols:
+ PortraitWindow = Window = GemRB.LoadWindow (26)
+ else:
+ PortraitWindow = Window = GemRB.LoadWindow (1)
+
+ if needcontrols and not GUICommon.GameIsPST(): #not in pst
+ print "DEBUG:GUICommonWindows.OpenPortraitWindow:NEEDCONTROLS ON"
+ # 1280 and higher don't have this control
+ if Window.HasControl (8):
+ Button=Window.GetControl (8)
+ if GUICommon.GameIsIWD():
+ # Rest (iwd)
+ Button.SetTooltip (11942)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, RestPress)
+ else:
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, MinimizePortraits)
+ else:
+ if GUICommon.HasHOW():
+ # Rest (how)
+ pos = GemRB.GetSystemVariable (SV_HEIGHT) - 37
+ Window.CreateButton (8, 6, pos, 55, 37)
+ Button = Window.GetControl (8)
+ Button.SetSprites ("GUIRSBUT", 0,0,1,0,0)
+ Button.SetTooltip (11942)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, RestPress)
+
+ pos = pos - 37
+ Window.CreateButton (6, 6, pos, 27, 36)
+
+ # AI
+ Button = Window.GetControl (6)
+ #fixing a gui bug, and while we are at it, hacking it to be easier
+ Button.SetSprites ("GUIBTACT", 0, 46, 47, 48, 49)
+ Button = InitOptionButton(Window, 'AI', AIPress)
+ AIPress(0) #this initialises the state and tooltip
+
+ #Select All
+ if GUICommon.HasHOW():
+ Window.CreateButton (7, 33, pos, 27, 36)
+ Button = Window.GetControl (7)
+ Button.SetSprites ("GUIBTACT", 0, 50, 51, 50, 51)
+ else:
+ Button = Window.GetControl (7)
+ Button.SetTooltip (10485)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUICommon.SelectAllOnPress)
+ else:
+ # Rest
+ if Window.HasControl(6) and not GUICommon.GameIsIWD2():
+ Button = Window.GetControl (6)
+ Button.SetTooltip (11942)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, RestPress)
+
+ for i in range (PARTY_SIZE):
+ Button = Window.GetControl (i)
+ if GUICommon.GameIsIWD1() or GUICommon.GameIsIWD2():
+ Button.SetFont ("STATES")
+ # label for status flags (dialog, store, level up)
+ Button.CreateLabelOnButton(200 + i, "STATES", IE_FONT_ALIGN_TOP | IE_FONT_ALIGN_RIGHT) #level up icon is on the right
+ elif not GUICommon.GameIsPST():
+ Button.SetFont ("STATES2")
+ # label for status flags (dialog, store, level up)
+ Button.CreateLabelOnButton(200 + i, "STATES2", IE_FONT_ALIGN_TOP | IE_FONT_ALIGN_RIGHT) #level up icon is on the right
+
+ Button.SetVarAssoc ("PressedPortrait", i+1)
+
+ if needcontrols or GUICommon.GameIsIWD2():
+ Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, GUIINV.OpenInventoryWindowClick)
+ else:
+ Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, PortraitButtonOnPress)
+
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, PortraitButtonOnPress)
+ Button.SetEvent (IE_GUI_BUTTON_ON_SHIFT_PRESS, PortraitButtonOnShiftPress)
+ Button.SetEvent (IE_GUI_BUTTON_ON_DRAG_DROP, InventoryCommon.OnDropItemToPC)
+ Button.SetEvent (IE_GUI_BUTTON_ON_DRAG_DROP_PORTRAIT, OnDropPortraitToPC)
+ Button.SetEvent (IE_GUI_BUTTON_ON_DRAG, PortraitButtonOnDrag)
+ Button.SetEvent (IE_GUI_MOUSE_ENTER_BUTTON, PortraitButtonOnMouseEnter)
+ Button.SetEvent (IE_GUI_MOUSE_LEAVE_BUTTON, PortraitButtonOnMouseLeave)
+
+ if GUICommon.GameIsIWD1():
+ # overlay a label, so we can display the hp with the correct font. Regular button label
+ # is used by effect icons
+ Button.CreateLabelOnButton(100+i, "NUMFONT", IE_FONT_ALIGN_TOP|IE_FONT_ALIGN_LEFT)
+ HPLabel = Window.GetControl (100+i)
+ HPLabel.SetUseRGB (True)
+
+ # unlike other buttons, this one lacks extra frames for a selection effect
+ # so we create it and shift it to cover the grooves of the image
+ # except iwd2's second frame already has it incorporated (but we miscolor it)
+ if GUICommon.GameIsIWD2():
+ Button.SetBorder (FRAME_PC_SELECTED, 0, 0, 0, 0, 0, 255, 0, 255)
+ Button.SetBorder (FRAME_PC_TARGET, 2, 2, 3, 3, 255, 255, 0, 255)
+ elif GUICommon.GameIsPST():
+ Button.SetBorder (FRAME_PC_SELECTED, 1, 1, 2, 2, 0, 255, 0, 255)
+ Button.SetBorder (FRAME_PC_TARGET, 3, 3, 4, 4, 255, 255, 0, 255)
+ ButtonHP = Window.GetControl (6 + i)
+ ButtonHP.SetVarAssoc ('PressedPortraitHP', i+1)
+ ButtonHP.SetEvent (IE_GUI_BUTTON_ON_PRESS, PortraitButtonHPOnPress)
+ else:
+ Button.SetBorder (FRAME_PC_SELECTED, 4, 3, 4, 3, 0, 255, 0, 255)
+ Button.SetBorder (FRAME_PC_TARGET, 2, 2, 3, 3, 255, 255, 0, 255)
+
+ UpdatePortraitWindow ()
+ SelectionChanged ()
+ return Window
+
+def UpdatePortraitWindow ():
+ """Updates all of the portraits."""
+
+ Window = PortraitWindow
+
+ pc = GemRB.GameGetSelectedPCSingle ()
+ Inventory = GemRB.GetVar ("Inventory")
+
+ for portid in range (PARTY_SIZE):
+ if GUICommon.GameIsPST():
+ UpdateAnimatedPortrait(Window,portid)
+ continue
+
+ Button = Window.GetControl (portid)
+ pic = GemRB.GetPlayerPortrait (portid+1, 1)
+ if Inventory and pc != portid+1:
+ pic = None
+
+ if pic and GemRB.GetPlayerStat(portid+1, IE_STATE_ID) & STATE_DEAD:
+ import GUISTORE
+ # dead pcs are hidden in all stores but temples
+ if GUISTORE.StoreWindow and not GUISTORE.StoreHealWindow:
+ pic = None
+
+ if not pic:
+ Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+ Button.SetText ("")
+ Button.SetTooltip ("")
+ continue
+
+ portraitFlags = IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_HORIZONTAL | IE_GUI_BUTTON_ALIGN_LEFT | \
+ IE_GUI_BUTTON_DRAGGABLE | IE_GUI_BUTTON_MULTILINE | IE_GUI_BUTTON_ALIGN_BOTTOM
+ if GUICommon.GameIsIWD2():
+ Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, GUIINV.OpenInventoryWindowClick)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, PortraitButtonOnPress)
+
+ Button.SetFlags (portraitFlags, OP_SET)
+
+ Button.SetState (IE_GUI_BUTTON_LOCKED)
+ Button.SetPicture (pic, "NOPORTSM")
+ ratio_str, color = GUICommon.SetupDamageInfo (portid+1, Button, Window)
+
+ # character - 1 == bam cycle
+ talk = store = flag = blank = ""
+ if GUICommon.GameIsBG2():
+ # as far as I can tell only BG2 has icons for talk or store
+ flag = blank = chr(238)
+ talk = 154 # dialog icon
+ store = 155 # shopping icon
+
+ if pc==portid+1:
+ if GemRB.GetStore()!=None:
+ flag = chr(store)
+ # talk icon
+ if GemRB.GameGetSelectedPCSingle(1)==portid+1:
+ flag = chr(talk)
+
+ if LUCommon.CanLevelUp (portid+1):
+ flag = flag + blank + chr(255)
+ elif GUICommon.GameIsIWD1():
+ HPLabel = Window.GetControl (100+portid)
+ HPLabel.SetText (ratio_str)
+ HPLabel.SetTextColor (*color)
+
+ #add effects on the portrait
+ effects = GemRB.GetPlayerStates (portid+1)
+
+ numCols = 4 if GUICommon.GameIsIWD2() else 3
+ numEffects = len(effects)
+
+ states = ""
+ # calculate the partial row
+ idx = numEffects % numCols
+ states = effects[0:idx] + "\n"
+
+ for x in range(idx, numEffects): # now do any rows that are full
+ states = states + effects[x]
+ if (x - idx) % numCols == numCols - 1:
+ states = states + "\n"
+
+ FlagLabel = Window.GetControl(200 + portid)
+ if flag != blank:
+ FlagLabel.SetText(flag)
+ else:
+ FlagLabel.SetText("")
+ Button.SetText(states)
+ return
+
+def UpdateAnimatedPortrait (Window,i):
+ """Selects the correct portrait cycle depending on character state"""
+ #FIXME: Actually doesn't, and I can't see why. Same in master. Help?
+ #note: there are actually two portraits per chr, eg PPPANN, WMPANN
+ Button = Window.GetControl (i)
+ ButtonHP = Window.GetControl (6 + i)
+ pic = GemRB.GetPlayerPortrait (i+1, 0)
+ if not pic:
+ Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
+ ButtonHP.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
+ return
+ #sel = GemRB.GameGetSelectedPCSingle () == i + 1
+ Button.SetBAM (pic, 0, 0, -1)
+ state = GemRB.GetPlayerStat (i+1, IE_STATE_ID)
+ hp = GemRB.GetPlayerStat (i+1, IE_HITPOINTS)
+ hp_max = GemRB.GetPlayerStat (i+1, IE_MAXHITPOINTS)
+ if state & STATE_DEAD:
+ cycle = 9
+ elif state & STATE_HELPLESS:
+ cycle = 8
+ elif state & STATE_PETRIFIED:
+ cycle = 7
+ elif state & STATE_PANIC:
+ cycle = 6
+ elif state & STATE_POISONED:
+ cycle = 2
+ elif hp<hp_max/2:
+ cycle = 4
+ else:
+ cycle = 0
+ if cycle<6:
+ Button.SetFlags(IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_ANIMATED | IE_GUI_BUTTON_PLAYRANDOM|IE_GUI_BUTTON_DRAGGABLE|IE_GUI_BUTTON_MULTILINE, OP_SET)
+ else:
+ Button.SetFlags(IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_ANIMATED | IE_GUI_BUTTON_DRAGGABLE|IE_GUI_BUTTON_MULTILINE, OP_SET)
+
+ Button.SetAnimation (pic, cycle)
+ ButtonHP.SetFlags(IE_GUI_BUTTON_PICTURE, OP_SET)
+
+ if hp_max<1:
+ ratio = 0.0
+ else:
+ ratio = (hp + 0.0) / hp_max
+ if ratio > 1.0: ratio = 1.0
+
+ r = int (255 * (1.0 - ratio))
+ g = int (255 * ratio)
+
+ ButtonHP.SetText ("%d / %d" %(hp, hp_max))
+ ButtonHP.SetTextColor (r, g, 0, False)
+ ButtonHP.SetBAM ('FILLBAR', 0, 0, -1)
+ ButtonHP.SetPictureClipping (ratio)
+
+ #print "PORTRAIT DEBUG:"
+ #print "state: " + str(state) + " hp: " + str(hp) + " hp_max: " + str(hp_max) + "ratio: " + str(ratio) + " cycle: " + str(cycle) + " state: " + str(state)
+
+ if portrait_hp_numeric[i]:
+ op = OP_NAND
+ else:
+ op = OP_OR
+ ButtonHP.SetFlags (IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_NO_TEXT, op)
+
+ #if sel:
+ # Button.EnableBorder(FRAME_PC_SELECTED, 1)
+ #else:
+ # Button.EnableBorder(FRAME_PC_SELECTED, 0)
+ return
+
+def PortraitButtonOnDrag ():
+ global DraggedPortrait
+
+ #they start from 1
+ DraggedPortrait = GemRB.GetVar ("PressedPortrait")
+ GemRB.DragItem (DraggedPortrait, -1, "")
+ return
+
+def PortraitButtonOnPress ():
+ """Selects the portrait individually."""
+
+ i = GemRB.GetVar ("PressedPortrait")
+
+ if not i:
+ return
+
+ if GemRB.GameControlGetTargetMode() != TARGET_MODE_NONE:
+ GemRB.ActOnPC (i)
+ return
+
+ if (not SelectionChangeHandler):
+ if GemRB.GameIsPCSelected (i):
+ GemRB.GameControlSetScreenFlags (SF_CENTERONACTOR, OP_OR)
+ GemRB.GameSelectPC (i, True, SELECT_REPLACE)
+ else:
+ GemRB.GameSelectPCSingle (i)
+ SelectionChanged ()
+ RunSelectionChangeHandler ()
+ return
+
+def PortraitButtonOnShiftPress ():
+ """Handles selecting multiple portaits with shift."""
+
+ i = GemRB.GetVar ("PressedPortrait")
+
+ if not i:
+ return
+
+ if (not SelectionChangeHandler):
+ sel = GemRB.GameIsPCSelected (i)
+ sel = not sel
+ GemRB.GameSelectPC (i, sel)
+ else:
+ GemRB.GameSelectPCSingle (i)
+ SelectionChanged ()
+ RunSelectionChangeHandler ()
+ return
+
+def PortraitButtonHPOnPress (): ##pst hitpoint display
+ Window = PortraitWindow
+
+ i = GemRB.GetVar ('PressedPortraitHP')
+
+ portrait_hp_numeric[i-1] = not portrait_hp_numeric[i-1]
+ ButtonHP = Window.GetControl (5 + i)
+
+ if portrait_hp_numeric[i-1]:
+ op = OP_NAND
+ else:
+ op = OP_OR
+
+ ButtonHP.SetFlags (IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_NO_TEXT, op)
+ return
+
+def SelectionChanged ():
+ """Ran by the Game class when a PC selection is changed."""
+
+ global PortraitWindow
+
+ if not PortraitWindow:
+ return
+
+ # FIXME: hack. If defined, display single selection
+ GemRB.SetVar ("ActionLevel", 0)
+ if (not SelectionChangeHandler):
+ UpdateActionsWindow ()
+ for i in range (PARTY_SIZE):
+ Button = PortraitWindow.GetControl (i)
+ Button.EnableBorder (FRAME_PC_SELECTED, GemRB.GameIsPCSelected (i + 1))
+ if SelectionChangeMultiHandler:
+ SelectionChangeMultiHandler ()
+ else:
+ sel = GemRB.GameGetSelectedPCSingle ()
+
+ #update mage school
+ GemRB.SetVar ("MAGESCHOOL", 0)
+ Kit = GUICommon.GetKitIndex (sel)
+ if Kit and CommonTables.KitList.GetValue (Kit, 7) == 1:
+ MageTable = GemRB.LoadTable ("magesch")
+ GemRB.SetVar ("MAGESCHOOL", MageTable.FindValue (3, CommonTables.KitList.GetValue (Kit, 6) ) )
+
+ for i in range (PARTY_SIZE):
+ Button = PortraitWindow.GetControl (i)
+ Button.EnableBorder (FRAME_PC_SELECTED, i + 1 == sel)
+ import CommonWindow
+ CommonWindow.CloseContainerWindow()
+
+ return
+
+def PortraitButtonOnMouseEnter ():
+ global DraggedPortrait
+
+ i = GemRB.GetVar ("PressedPortrait")
+
+ if not i:
+ return
+
+ GemRB.GameControlSetLastActor( i )
+ if GemRB.IsDraggingItem()==2:
+ if DraggedPortrait != None:
+ GemRB.SwapPCs (DraggedPortrait, i)
+ if not GUICommon.GameIsPST():
+ GemRB.SetVar ("PressedPortrait", DraggedPortrait)
+ #possibly review why the other games do that ^^
+ #it completely breaks the dragging in PST
+ DraggedPortrait = i
+ GemRB.SetTimedEvent (CheckDragging, 1)
+ else:
+ OnDropPortraitToPC()
+ return
+
+ if GemRB.IsDraggingItem ():
+ Button = PortraitWindow.GetControl (i-1)
+ Button.EnableBorder (FRAME_PC_TARGET, 1)
+ return
+
+def OnDropPortraitToPC ():
+ GemRB.SetVar ("PressedPortrait",0)
+ GemRB.DragItem (0, -1, "")
+ DraggedPortrait = None
+ return
+
+def CheckDragging():
+ """Contains portrait dragging in case of mouse out-of-range."""
+
+ global DraggedPortrait
+
+ i = GemRB.GetVar ("PressedPortrait")
+ if not i:
+ GemRB.DragItem (0, -1, "")
+
+ if GemRB.IsDraggingItem()!=2:
+ DraggedPortrait = None
+ return
+
+def PortraitButtonOnMouseLeave ():
+ i = GemRB.GetVar ("PressedPortrait")
+ if not i:
+ return
+
+ Button = PortraitWindow.GetControl (i-1)
+ Button.EnableBorder (FRAME_PC_TARGET, 0)
+ GemRB.SetVar ("PressedPortrait", 0)
+ GemRB.SetTimedEvent (CheckDragging, 1)
+ return
+
+def ActionStopPressed ():
+ for i in GemRB.GetSelectedActors():
+ GemRB.ClearActions (i)
+ return
+
+def ActionTalkPressed ():
+ GemRB.GameControlSetTargetMode (TARGET_MODE_TALK,GA_NO_DEAD|GA_NO_ENEMY|GA_NO_HIDDEN)
+
+def ActionAttackPressed ():
+ GemRB.GameControlSetTargetMode (TARGET_MODE_ATTACK,GA_NO_DEAD|GA_NO_SELF|GA_NO_HIDDEN)
+
+def ActionDefendPressed ():
+ GemRB.GameControlSetTargetMode (TARGET_MODE_DEFEND,GA_NO_SELF|GA_NO_ENEMY|GA_NO_HIDDEN)
+#FIXME: there is currently no way to use this in pst
+def ActionThievingPressed ():
+ GemRB.GameControlSetTargetMode (TARGET_MODE_PICK, GA_NO_DEAD|GA_NO_SELF|GA_NO_ENEMY|GA_NO_HIDDEN)
+
+def MinimizePortraits(): #bg2
+ GemRB.GameSetScreenFlags(GS_PORTRAITPANE, OP_OR)
+
+def DisableAnimatedWindows (): #pst
+ global ActionsWindow, OptionsWindow
+ GemRB.SetVar ("PortraitWindow", -1)
+ ActionsWindow = GUIClasses.GWindow( GemRB.GetVar ("ActionsWindow") )
+ GemRB.SetVar ("ActionsWindow", -1)
+ OptionsWindow = GUIClasses.GWindow( GemRB.GetVar ("OptionsWindow") )
+ GemRB.SetVar ("OptionsWindow", -1)
+ GemRB.GamePause (1,3)
+
+def EnableAnimatedWindows (): #pst
+ GemRB.SetVar ("PortraitWindow", PortraitWindow.ID)
+ GemRB.SetVar ("ActionsWindow", ActionsWindow.ID)
+ GemRB.SetVar ("OptionsWindow", OptionsWindow.ID)
+ GemRB.GamePause (0,3)
+
+def SetItemButton (Window, Button, Slot, PressHandler, RightPressHandler): #relates to pst containers
+ if Slot != None:
+ Item = GemRB.GetItem (Slot['ItemResRef'])
+ identified = Slot['Flags'] & IE_INV_ITEM_IDENTIFIED
+ #Button.SetVarAssoc ("LeftIndex", LeftTopIndex+i)
+ #Button.SetSprites ('IVSLOT', 0, 0, 0, 0, 0)
+ Button.SetItemIcon (Slot['ItemResRef'],0)
+
+ if Item['MaxStackAmount'] > 1:
+ Button.SetText (str (Slot['Usages0']))
+ else:
+ Button.SetText ('')
+
+
+ if not identified or Item['ItemNameIdentified'] == -1:
+ Button.SetTooltip (Item['ItemName'])
+ else:
+ Button.SetTooltip (Item['ItemNameIdentified'])
+
+ #Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_OR)
+ #Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_NAND)
+
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, PressHandler)
+ Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, RightPressHandler)
+ #Button.SetEvent (IE_GUI_BUTTON_ON_SHIFT_PRESS, ShiftPressHandler)
+ #Button.SetEvent (IE_GUI_BUTTON_ON_DRAG_DROP, DragDropHandler)
+
+ else:
+ #Button.SetVarAssoc ("LeftIndex", -1)
+ Button.SetItemIcon ('')
+ Button.SetTooltip (4273) # Ground Item
+ Button.SetText ('')
+ Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_NAND)
+
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, None)
+ Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, None)
+ #Button.SetEvent (IE_GUI_BUTTON_ON_SHIFT_PRESS, None)
+ #Button.SetEvent (IE_GUI_BUTTON_ON_DRAG_DROP, None)
+
+def OpenWaitForDiscWindow ():
+ global DiscWindow
+
+ if DiscWindow:
+ GemRB.HideGUI ()
+ if DiscWindow:
+ DiscWindow.Unload ()
+ GemRB.SetVar ("OtherWindow", -1)
+ # ...LoadWindowPack()
+ EnableAnimatedWindows ()
+ DiscWindow = None
+ GemRB.UnhideGUI ()
+ return
+
+ try:
+ GemRB.HideGUI ()
+ except:
+ pass
+
+ GemRB.LoadWindowPack ("GUIID")
+ DiscWindow = Window = GemRB.LoadWindow (0)
+ GemRB.SetVar ("OtherWindow", Window.ID)
+ label = DiscWindow.GetControl (0)
+
+ disc_num = GemRB.GetVar ("WaitForDisc")
+ #disc_path = GemRB.GetVar ("WaitForDiscPath")
+ disc_path = 'XX:'
+
+ text = GemRB.GetString (31483) + " " + str (disc_num) + " " + GemRB.GetString (31569) + " " + disc_path + "\n" + GemRB.GetString (49152)
+ label.SetText (text)
+ DisableAnimatedWindows ()
+ # 31483 - Please place PS:T disc number
+ # 31568 - Please place the PS:T DVD
+ # 31569 - in drive
+ # 31570 - Wrong disc in drive
+ # 31571 - There is no disc in drive
+ # 31578 - No disc could be found in drive. Please place Disc 1 in drive.
+ # 49152 - To quit the game, press Alt-F4
+
+ try:
+ GemRB.UnhideGUI ()
+ except:
+ DiscWindow.SetVisible (WINDOW_VISIBLE)
+
+def SetPSTGamedaysAndHourToken ():
+ currentTime = GemRB.GetGameTime()
+ hours = (currentTime % 7200) / 300
+ if hours < 12:
+ ampm = "AM"
+ else:
+ ampm = "PM"
+ hours -= 12
+ minutes = (currentTime % 300) / 60
+
+ GemRB.SetToken ('CLOCK_HOUR', str (hours))
+ GemRB.SetToken ('CLOCK_MINUTE', '%02d' %minutes)
+ GemRB.SetToken ('CLOCK_AMPM', ampm)
+
+def UpdateClock ():
+ global ActionsWindow, OptionsWindow
+
+ if GUICommon.GameIsPST ():
+ #used to update the pst clock tooltip
+ ActionsWindow = GemRB.LoadWindow(0)
+ Button = ActionsWindow.GetControl (0)
+ SetPSTGamedaysAndHourToken ()
+ Button.SetTooltip (GemRB.GetString(65027))
+ #this function does update the clock tip, but the core fails to display it
+
+ else:
+ Clock = None
+ if OptionsWindow and OptionsWindow.HasControl (9):
+ Clock = OptionsWindow.GetControl (9)
+ elif ActionsWindow and ActionsWindow.HasControl (62):
+ Clock = ActionsWindow.GetControl (62)
+
+ if Clock and Clock.HasAnimation("CGEAR"):
+ Hours = (GemRB.GetGameTime () % 7200) / 300
+ GUICommon.SetGamedaysAndHourToken ()
+ Clock.SetBAM ("CDIAL", 0, (Hours + 12) % 24)
+ Clock.SetTooltip (GemRB.GetString (16041)) # refetch the string, since the tokens changed
+
+def CheckLevelUp(pc):
+ GemRB.SetVar ("CheckLevelUp"+str(pc), LUCommon.CanLevelUp (pc))
+
+def HideInterface(): #todo:should really add to pst if possible
+ GemRB.GameSetScreenFlags (GS_HIDEGUI, OP_XOR)
+ return
+
+def ToggleAlwaysRun():
+ GemRB.GameControlToggleAlwaysRun()
+
+def RestPress ():
+ GemRB.RestParty(0, 0, 1)
+ return
diff --git a/gemrb/GUIScripts/GUIDefines.py b/gemrb/GUIScripts/GUIDefines.py
index 2612e2f..756ac42 100644
--- a/gemrb/GUIScripts/GUIDefines.py
+++ b/gemrb/GUIScripts/GUIDefines.py
@@ -25,7 +25,7 @@ IE_GUI_BUTTON_NORMAL = 0x00000004 #default button, doesn't stick
IE_GUI_BUTTON_NO_IMAGE = 0x00000001
IE_GUI_BUTTON_PICTURE = 0x00000002
IE_GUI_BUTTON_SOUND = 0x00000004
-IE_GUI_BUTTON_ALT_SOUND = 0x00000008
+IE_GUI_BUTTON_CAPS = 0x00000008 #capitalize all the text
IE_GUI_BUTTON_CHECKBOX = 0x00000010 #or radio button
IE_GUI_BUTTON_RADIOBUTTON= 0x00000020 #sticks in a state
IE_GUI_BUTTON_DEFAULT = 0x00000040 #enter key triggers it
@@ -45,12 +45,12 @@ IE_GUI_BUTTON_DRAGGABLE = 0x00008000
IE_GUI_BUTTON_NO_TEXT = 0x00010000 # don't draw button label
IE_GUI_BUTTON_PLAYRANDOM = 0x00020000 # the button animation is random
IE_GUI_BUTTON_PLAYONCE = 0x00040000 # the button animation won't restart
+IE_GUI_BUTTON_PLAYALWAYS = 0x00080000 # animation will play when game is paused
-IE_GUI_BUTTON_CENTER_PICTURES = 0x00080000 # center the button's PictureList
-IE_GUI_BUTTON_BG1_PAPERDOLL = 0x00100000 # BG1-style paperdoll
-IE_GUI_BUTTON_HORIZONTAL = 0x00200000 # horizontal clipping of overlay
-IE_GUI_BUTTON_CANCEL = 0x00400000 # escape key triggers it
-IE_GUI_BUTTON_CAPS = 0x00800000 # capitalize all the text (default for bg2)
+IE_GUI_BUTTON_CENTER_PICTURES = 0x00100000 # center the button's PictureList
+IE_GUI_BUTTON_BG1_PAPERDOLL = 0x00200000 # BG1-style paperdoll
+IE_GUI_BUTTON_HORIZONTAL = 0x00400000 # horizontal clipping of overlay
+IE_GUI_BUTTON_CANCEL = 0x00800000 # escape key triggers it
#scrollbar flags
IE_GUI_SCROLLBAR_DEFAULT = 0x00000040 # mousewheel triggers it (same value as default button)
@@ -91,7 +91,6 @@ IE_GUI_EDIT_ON_CHANGE = 0x03000000
IE_GUI_EDIT_ON_DONE = 0x03000001
IE_GUI_EDIT_ON_CANCEL = 0x03000002
IE_GUI_TEXTAREA_ON_CHANGE = 0x05000000
-IE_GUI_TEXTAREA_OUT_OF_TEXT = 0x05000001
IE_GUI_LABEL_ON_PRESS = 0x06000000
IE_GUI_SCROLLBAR_ON_CHANGE = 0x07000000
IE_GUI_WORLDMAP_ON_PRESS = 0x08000000
@@ -112,9 +111,9 @@ IE_GUI_BUTTON_DISABLED = 0x00000003
# Like DISABLED, but processes MouseOver events and draws UNPRESSED bitmap
IE_GUI_BUTTON_LOCKED = 0x00000004
# Draws DISABLED bitmap, but it isn't disabled
-IE_GUI_BUTTON_THIRD = 0x00000005
+IE_GUI_BUTTON_FAKEDISABLED = 0x00000005
# Draws PRESSED bitmap, but it isn't shifted
-IE_GUI_BUTTON_SECOND = 0x00000006
+IE_GUI_BUTTON_FAKEPRESSED = 0x00000006
#edit field states
IE_GUI_EDIT_NUMBER = 0x030000001
@@ -220,6 +219,19 @@ IE_SPELL_TYPE_PRIEST = 0
IE_SPELL_TYPE_WIZARD = 1
IE_SPELL_TYPE_INNATE = 2
+# IWD2 spell types
+IE_IWD2_SPELL_BARD = 0
+IE_IWD2_SPELL_CLERIC = 1
+IE_IWD2_SPELL_DRUID = 2
+IE_IWD2_SPELL_PALADIN = 3
+IE_IWD2_SPELL_RANGER = 4
+IE_IWD2_SPELL_SORCERER = 5
+IE_IWD2_SPELL_WIZARD = 6
+IE_IWD2_SPELL_DOMAIN = 7
+IE_IWD2_SPELL_INNATE = 8
+IE_IWD2_SPELL_SONG = 9
+IE_IWD2_SPELL_SHAPE = 10
+
# Item Flags bits
# !!! Keep these synchronized with Item.h !!!
IE_ITEM_CRITICAL = 0x00000001
@@ -283,6 +295,7 @@ TOOLTIP_DELAY_FACTOR = 250
#game strings
STR_LOADMOS = 0
STR_AREANAME = 1
+STR_TEXTSCREEN = 2
#game integers
SV_BPP = 0
@@ -290,3 +303,19 @@ SV_WIDTH = 1
SV_HEIGHT = 2
global GEMRB_VERSION
GEMRB_VERSION = -1
+
+# GUIEnhancements bits
+GE_SCROLLBARS = 1
+GE_TRY_IDENTIFY_ON_TRANSFER = 2
+GE_ALWAYS_OPEN_CONTAINER_ITEMS = 4
+
+# Log Levels
+# !!! Keep this synchronized with System/Logging.h !!!
+# no need for LOG_INTERNAL here since its internal to the logger class
+LOG_NONE = -1 # here just for the scripts, not needed in core
+LOG_FATAL = 0
+LOG_ERROR = 1
+LOG_WARNING = 2
+LOG_MESSAGE = 3
+LOG_COMBAT = 4
+LOG_DEBUG = 5
diff --git a/gemrb/GUIScripts/GUILOAD.py b/gemrb/GUIScripts/GUILOAD.py
new file mode 100644
index 0000000..c7482f6
--- /dev/null
+++ b/gemrb/GUIScripts/GUILOAD.py
@@ -0,0 +1,207 @@
+# -*-python-*-
+# GemRB - Infinity Engine Emulator
+# Copyright (C) 2003 The GemRB Project
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+
+# GUILOAD.py - Load window
+
+###################################################
+
+import GemRB
+import LoadScreen
+import GUICommon
+
+LoadWindow = 0
+TextAreaControl = 0
+Games = ()
+ScrollBar = 0
+
+def OnLoad ():
+ global LoadWindow, TextAreaControl, Games, ScrollBar
+
+ if GUICommon.GameIsIWD1():
+ GemRB.SetVar ("PlayMode",0) #iwd is always using 'mpsave'
+ GemRB.SetVar ("SaveDir",1) #iwd is always using 'mpsave'
+ GemRB.LoadWindowPack ("GUILOAD", 640, 480)
+ LoadWindow = GemRB.LoadWindow (0)
+ LoadWindow.SetFrame ()
+
+ CancelButton=LoadWindow.GetControl (34)
+ CancelButton.SetText (13727)
+ CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CancelPress)
+ CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+
+ GemRB.SetVar ("LoadIdx",0)
+ for i in range (4):
+ Button = LoadWindow.GetControl (26+i)
+ Button.SetText (15590)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, LoadGamePress)
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+ Button.SetVarAssoc ("LoadIdx",i)
+
+ Button = LoadWindow.GetControl (30+i)
+ Button.SetText (13957)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, DeleteGamePress)
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+ Button.SetVarAssoc ("LoadIdx",i)
+
+ #area previews
+ Button = LoadWindow.GetControl (1+i)
+ Button.SetState (IE_GUI_BUTTON_LOCKED)
+ Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE|IE_GUI_BUTTON_PICTURE,OP_SET)
+
+ #PC portraits
+ for j in range (PARTY_SIZE):
+ Button = LoadWindow.GetControl (40 + i*PARTY_SIZE + j)
+ Button.SetState (IE_GUI_BUTTON_LOCKED)
+ Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE|IE_GUI_BUTTON_PICTURE,OP_SET)
+
+ ScrollBar=LoadWindow.GetControl (25)
+ ScrollBar.SetEvent (IE_GUI_SCROLLBAR_ON_CHANGE, ScrollBarPress)
+ Games=GemRB.GetSaveGames ()
+ TopIndex = max (0, len(Games) - 4)
+ GemRB.SetVar ("TopIndex",TopIndex)
+ ScrollBar.SetVarAssoc ("TopIndex", TopIndex+1)
+ ScrollBarPress ()
+ LoadWindow.SetVisible (WINDOW_VISIBLE)
+ return
+
+def ScrollBarPress ():
+ #draw load game portraits
+ Pos = GemRB.GetVar ("TopIndex")
+ for i in range (4):
+ ActPos = Pos + i
+
+ Button1 = LoadWindow.GetControl (26+i)
+ Button2 = LoadWindow.GetControl (30+i)
+ if ActPos<len(Games):
+ Button1.SetState (IE_GUI_BUTTON_ENABLED)
+ Button2.SetState (IE_GUI_BUTTON_ENABLED)
+ else:
+ Button1.SetState (IE_GUI_BUTTON_DISABLED)
+ Button2.SetState (IE_GUI_BUTTON_DISABLED)
+
+ if ActPos<len(Games):
+ Slotname = Games[ActPos].GetName()
+ else:
+ Slotname = ""
+ Label = LoadWindow.GetControl (0x10000008+i)
+ Label.SetText (Slotname)
+
+ if ActPos<len(Games):
+ Slotname = Games[ActPos].GetGameDate()
+ else:
+ Slotname = ""
+ Label = LoadWindow.GetControl (0x10000010+i)
+ Label.SetText (Slotname)
+
+ Button=LoadWindow.GetControl (1+i)
+ if ActPos<len(Games):
+ Button.SetSprite2D(Games[ActPos].GetPreview())
+ else:
+ Button.SetPicture ("")
+ for j in range (PARTY_SIZE):
+ Button=LoadWindow.GetControl (40 + i*PARTY_SIZE + j)
+ if ActPos<len(Games):
+ Button.SetSprite2D(Games[ActPos].GetPortrait(j))
+ else:
+ Button.SetPicture ("")
+ return
+
+def LoadGamePress ():
+ if LoadWindow:
+ LoadWindow.Unload ()
+ Pos = GemRB.GetVar ("TopIndex")+GemRB.GetVar ("LoadIdx")
+ LoadScreen.StartLoadScreen()
+ #loads savegame
+ GemRB.LoadGame (Games[Pos])
+
+ #enters game
+ if GUICommon.GameIsIWD1():
+ GemRB.SetNextScript ("PartyFormation")
+ else:
+ # it will close windows, including the loadscreen
+ GemRB.EnterGame ()
+ return
+
+def GetQuickLoadSlot():
+ global Games
+
+ Games=GemRB.GetSaveGames()
+ QuickLoadSlot = None
+ for Game in Games:
+ Slotname = Game.GetSaveID()
+ # quick save is 1
+ if Slotname == 1:
+ QuickLoadSlot = Game
+ break
+ return QuickLoadSlot
+
+def QuickLoadPressed():
+ QuickLoadSlot = GetQuickLoadSlot()
+ if QuickLoadSlot!=None:
+ LoadScreen.StartLoadScreen()
+ GemRB.LoadGame(QuickLoadSlot)
+ GemRB.EnterGame ()
+ return
+
+def DeleteGameConfirm():
+ global Games
+
+ TopIndex = GemRB.GetVar ("TopIndex")
+ Pos = TopIndex +GemRB.GetVar ("LoadIdx")
+ GemRB.DeleteSaveGame(Games[Pos])
+ if TopIndex>0:
+ GemRB.SetVar ("TopIndex",TopIndex-1)
+ del Games[Pos]
+ ScrollBar.SetVarAssoc ("TopIndex", len(Games))
+ ScrollBarPress ()
+ if ConfirmWindow:
+ ConfirmWindow.Unload ()
+ LoadWindow.SetVisible (WINDOW_VISIBLE)
+ return
+
+def DeleteGameCancel ():
+ if ConfirmWindow:
+ ConfirmWindow.Unload ()
+ LoadWindow.SetVisible (WINDOW_VISIBLE)
+ return
+
+def DeleteGamePress ():
+ global ConfirmWindow
+
+ LoadWindow.SetVisible (WINDOW_INVISIBLE)
+ ConfirmWindow=GemRB.LoadWindow (1)
+ Text=ConfirmWindow.GetControl (0)
+ Text.SetText (15305)
+ DeleteButton=ConfirmWindow.GetControl (1)
+ DeleteButton.SetText (13957)
+ DeleteButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DeleteGameConfirm)
+ CancelButton=ConfirmWindow.GetControl (2)
+ CancelButton.SetText (13727)
+ CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DeleteGameCancel)
+ CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+
+ ConfirmWindow.SetVisible (WINDOW_VISIBLE)
+ return
+
+def CancelPress ():
+ if LoadWindow:
+ LoadWindow.Unload ()
+ GemRB.SetNextScript ("Start")
+ return
diff --git a/gemrb/GUIScripts/GUIOPT.py b/gemrb/GUIScripts/GUIOPT.py
new file mode 100644
index 0000000..2dc254f
--- /dev/null
+++ b/gemrb/GUIScripts/GUIOPT.py
@@ -0,0 +1,709 @@
+# -*-python-*-
+# GemRB - Infinity Engine Emulator
+# Copyright (C) 2012 The GemRB Project
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+# GUIOPT.py - scripts to control options windows mostly from the GUIOPT winpack:
+# 0 - Main options window (peacock tail)
+# 1 - Video options window
+# 2 - msg win with 1 button
+# 3 - msg win with 2 buttons
+# 4 - msg win with 3 buttons
+# 5 - Audio options window
+# 6 - Gameplay options window
+# 8 - Feedback options window
+# 9 - Autopause options window
+
+###################################################
+import CommonWindow
+import GemRB
+import GUICommon
+import GUICommonWindows
+import GUISAVE
+import GUIOPTControls
+from GUIDefines import *
+
+###################################################
+GameOptionsWindow = None # not in PST
+PortraitWindow = None # not in BG1 or PST
+OldPortraitWindow = None #not in BG1 or PST
+OptionsWindow = None
+OldOptionsWindow = None
+HelpTextArea = None
+
+LoadMsgWindow = None
+QuitMsgWindow = None
+SubOptionsWindow = None
+SubSubOptionsWindow = None
+
+if GUICommon.GameIsBG1():
+ HelpTextArea2 = None
+else:
+ # just an alias to keep our logic from being plagued by too many GUICommon.GameIsBG1() checks
+ HelpTextArea2 = HelpTextArea
+
+if GUICommon.GameIsIWD2():
+ WIDTH = 800
+ HEIGHT = 600
+else:
+ WIDTH = 640
+ HEIGHT = 480
+
+###################################################
+def CloseOptionsWindow ():
+ global GameOptionsWindow, OptionsWindow, PortraitWindow
+ global OldPortraitWindow, OldOptionsWindow
+
+ if GameOptionsWindow == None:
+ return
+
+ if GameOptionsWindow:
+ GameOptionsWindow.Unload ()
+ if OptionsWindow:
+ OptionsWindow.Unload ()
+ if PortraitWindow:
+ PortraitWindow.Unload ()
+
+ GameOptionsWindow = None
+ GemRB.SetVar ("OtherWindow", -1)
+ GUICommon.GameWindow.SetVisible(WINDOW_VISIBLE)
+ GemRB.UnhideGUI ()
+ GUICommonWindows.OptionsWindow = OldOptionsWindow
+ OldOptionsWindow = None
+ if not GUICommon.GameIsBG1():
+ GUICommonWindows.PortraitWindow = OldPortraitWindow
+ OldPortraitWindow = None
+
+ GemRB.GamePause (0, 3)
+ return
+
+###################################################
+def OpenOptionsWindow ():
+ """Open main options window"""
+
+ global GameOptionsWindow, OptionsWindow, PortraitWindow
+ global OldPortraitWindow, OldOptionsWindow
+
+ if GUICommon.CloseOtherWindow (OpenOptionsWindow):
+ CloseOptionsWindow()
+ return
+
+ GemRB.GamePause (1, 3)
+
+ CommonWindow.CloseContainerWindow ()
+ GemRB.HideGUI ()
+ GUICommon.GameWindow.SetVisible(WINDOW_INVISIBLE)
+ if GUICommon.GameIsBG1():
+ GUICommonWindows.SetSelectionChangeHandler (None)
+
+ GemRB.LoadWindowPack ("GUIOPT", WIDTH, HEIGHT)
+ GameOptionsWindow = Window = GemRB.LoadWindow (2)
+ GemRB.SetVar ("OtherWindow", GameOptionsWindow.ID)
+
+ if OldOptionsWindow == None:
+ # OptionsWindow is the leftmost menu bar window present in most of the games
+ OldOptionsWindow = GUICommonWindows.OptionsWindow
+ OptionsWindow = GemRB.LoadWindow (0)
+ if GUICommon.GameIsBG2():
+ GUICommonWindows.MarkMenuButton (OptionsWindow)
+ GUICommonWindows.SetupMenuWindowControls (OptionsWindow, 0, OpenOptionsWindow)
+ OptionsWindow.SetFrame ()
+ if not GUICommon.GameIsBG1(): #not in PST either, but it has its own OpenOptionsWindow()
+ OptionsWindow.SetFrame ()
+ #saving the original portrait window
+ OldPortraitWindow = GUICommonWindows.PortraitWindow
+ PortraitWindow = GUICommonWindows.OpenPortraitWindow (0)
+
+ # Return to Game
+ Button = Window.GetControl (11)
+ Button.SetText (10308)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenOptionsWindow)
+ Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+
+ # Quit Game
+ Button = Window.GetControl (10)
+ Button.SetText (13731)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenQuitMsgWindow)
+
+ # Load Game
+ Button = Window.GetControl (5)
+ Button.SetText (13729)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenLoadMsgWindow)
+
+ # Save Game
+ Button = Window.GetControl (6)
+ Button.SetText (13730)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenSaveMsgWindow)
+
+ # Video Options
+ Button = Window.GetControl (7)
+ Button.SetText (17162)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenVideoOptionsWindow)
+
+ # Audio Options
+ Button = Window.GetControl (8)
+ Button.SetText (17164)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenAudioOptionsWindow)
+
+ # Gameplay Options
+ Button = Window.GetControl (9)
+ Button.SetText (17165)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenGameplayOptionsWindow)
+
+ # game version, e.g. v1.1.0000
+ VersionLabel = Window.GetControl (0x1000000b)
+ VersionLabel.SetText (GEMRB_VERSION)
+
+ if GUICommon.GameIsIWD2():
+ # Keyboard shortcuts
+ KeyboardButton = Window.GetControl (13)
+ KeyboardButton.SetText (33468)
+ KeyboardButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenHotkeyOptionsWindow)
+
+ # Movies
+ MoviesButton = Window.GetControl (14)
+ MoviesButton.SetText (15415)
+ MoviesButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenMovieWindow)
+
+ RestoreWinVisibility ()
+
+ return
+
+def TrySavingConfiguration():
+ if not GemRB.SaveConfig():
+ print "ARGH, could not write config to disk!!"
+
+###################################################
+
+def CloseVideoOptionsWindow ():
+ CloseSubOptionsWindow ()
+ TrySavingConfiguration()
+
+def OpenVideoOptionsWindow ():
+ """Open video options window"""
+ global SubOptionsWindow, HelpTextArea
+
+ Window = SubOptionsWindow
+ CloseSubOptionsWindow ()
+
+ Window = GemRB.LoadWindow (6)
+
+ HelpTextArea = GUIOPTControls.OptHelpText ('VideoOptions', Window, 33, 18038)
+
+ GUIOPTControls.OptDone (CloseVideoOptionsWindow, Window, 21)
+ GUIOPTControls.OptCancel (CloseVideoOptionsWindow, Window, 32)
+
+ GUIOPTControls.OptSlider (18038, 17203, HelpTextArea, Window, 3, 35, 17129, 'Brightness Correction', DisplayHelpBrightness, 4)
+ GUIOPTControls.OptSlider (18038, 17204, HelpTextArea, Window, 22, 36, 17128, 'Gamma Correction', DisplayHelpContrast)
+
+ GUIOPTControls.OptRadio (DisplayHelpBPP, Window, 5, 37, 'BitsPerPixel', 16)
+ GUIOPTControls.OptRadio (DisplayHelpBPP, Window, 6, 37, 'BitsPerPixel', 24)
+ GUIOPTControls.OptRadio (DisplayHelpBPP, Window, 7, 37, 'BitsPerPixel', 32)
+
+ GUIOPTControls.OptCheckbox (18038, 18000, HelpTextArea, Window, 9, 38, 17131, 'Full Screen', DisplayHelpFullScreen)
+
+ GUIOPTControls.OptCheckbox (18038, 20620, HelpTextArea, Window, 51, 50, 20617, 'Translucent Shadows')
+ GUIOPTControls.OptCheckbox (18038, 18004, HelpTextArea, Window, 40, 44, 17134, 'SoftMirrorBlt')
+ GUIOPTControls.OptCheckbox (18038, 18006, HelpTextArea, Window, 41, 46, 17136, 'SoftSrcKeyBlt') # software standard blit
+ GUIOPTControls.OptCheckbox (18038, 18007, HelpTextArea, Window, 42, 48, 17135, 'SoftBltFast') # software transparent blit
+
+ SubOptionsWindow = Window
+
+ Window.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def DisplayHelpFullScreen ():
+ HelpTextArea.SetText (18000)
+ GemRB.SetFullScreen (GemRB.GetVar("Full Screen"))
+
+def DisplayHelpBPP ():
+ HelpTextArea.SetText (17205)
+
+def DisplayHelpBrightness ():
+ HelpTextArea.SetText (17203)
+ SetGfxCorrection ()
+
+def DisplayHelpContrast ():
+ HelpTextArea.SetText (17204)
+ SetGfxCorrection ()
+
+# different games have different slider ranges, but the engine wants:
+# gamma: 0-5
+# brightness: 0-40
+def SetGfxCorrection ():
+ Brightness = GemRB.GetVar("Brightness Correction")
+ Gamma = GemRB.GetVar("Gamma Correction")
+ if GUICommon.GameIsIWD2(): # 10/11 ticks
+ Gamma /= 2
+
+ GemRB.SetGamma (Brightness, Gamma)
+
+###################################################
+
+def CloseAudioOptionsWindow ():
+ CloseSubOptionsWindow ()
+ TrySavingConfiguration()
+
+def OpenAudioOptionsWindow ():
+ """Open audio options window"""
+ global SubOptionsWindow, HelpTextArea
+
+ Window = SubOptionsWindow
+ CloseSubOptionsWindow ()
+
+ Window = GemRB.LoadWindow (7)
+ HelpTextArea = GUIOPTControls.OptHelpText ('AudioOptions', Window, 14, 18040)
+
+ GUIOPTControls.OptDone (CloseAudioOptionsWindow, Window, 24)
+ GUIOPTControls.OptCancel (CloseAudioOptionsWindow, Window, 25)
+ GUIOPTControls.OptButton (OpenCharacterSoundsWindow, Window, 13, 17778)
+
+ GUIOPTControls.OptSlider (18040, 18008, HelpTextArea, Window, 1, 16, 16514, 'Volume Ambients', DisplayHelpAmbientVolume, 10)
+ GUIOPTControls.OptSlider (18040, 18009, HelpTextArea, Window, 2, 17, 16515, 'Volume SFX', None, 10)
+ GUIOPTControls.OptSlider (18040, 18010, HelpTextArea, Window, 3, 18, 16512, 'Volume Voices', None, 10)
+ GUIOPTControls.OptSlider (18040, 18011, HelpTextArea, Window, 4, 19, 16511, 'Volume Music', DisplayHelpMusicVolume, 10)
+ GUIOPTControls.OptSlider (18040, 18012, HelpTextArea, Window, 22, 20, 16546, 'Volume Movie', None, 10)
+
+ GUIOPTControls.OptCheckbox (18040, 18022, HelpTextArea, Window, 26, 28, 20689, 'Environmental Audio')
+
+ SubOptionsWindow = Window
+
+ Window.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def DisplayHelpAmbientVolume ():
+ HelpTextArea.SetText (18008)
+ GemRB.UpdateAmbientsVolume ()
+
+def DisplayHelpMusicVolume ():
+ HelpTextArea.SetText (18011)
+ GemRB.UpdateMusicVolume ()
+
+###################################################
+
+def CloseCharacterSoundsWindow ():
+ CloseSubSubOptionsWindow ()
+
+def OpenCharacterSoundsWindow ():
+ """Open character sounds window"""
+
+ global SubSubOptionsWindow, HelpTextArea2
+
+ Window = SubSubOptionsWindow
+ CloseSubSubOptionsWindow ()
+
+ Window = GemRB.LoadWindow (12)
+ HelpTextArea2 = GUIOPTControls.OptHelpText ('CharacterSounds', Window, 16, 18041)
+
+ GUIOPTControls.OptDone (CloseCharacterSoundsWindow, Window, 24)
+ GUIOPTControls.OptCancel (CloseCharacterSoundsWindow, Window, 25)
+
+ GUIOPTControls.OptCheckbox (18041, 18015, HelpTextArea2, Window, 5, 20, 17138, 'Subtitles')
+ GUIOPTControls.OptCheckbox (18041, 18013, HelpTextArea2, Window, 6, 18, 17139, 'Attack Sound')
+ GUIOPTControls.OptCheckbox (18041, 18014, HelpTextArea2, Window, 7, 19, 17140, 'Footsteps')
+ GUIOPTControls.OptRadio (DisplayHelpCommandSounds, Window, 8, 21, 'Command Sounds Frequency', 2)
+ GUIOPTControls.OptRadio (DisplayHelpCommandSounds, Window, 9, 21, 'Command Sounds Frequency', 1)
+ GUIOPTControls.OptRadio (DisplayHelpCommandSounds, Window, 10, 21, 'Command Sounds Frequency', 0)
+ GUIOPTControls.OptRadio (DisplayHelpSelectionSounds, Window, 58, 57, 'Selection Sounds Frequency', 2)
+ GUIOPTControls.OptRadio (DisplayHelpSelectionSounds, Window, 59, 57, 'Selection Sounds Frequency', 1)
+ GUIOPTControls.OptRadio (DisplayHelpSelectionSounds, Window, 60, 57, 'Selection Sounds Frequency', 0)
+
+ Window.ShowModal (MODAL_SHADOW_GRAY)
+
+ SubSubOptionsWindow = Window
+
+def DisplayHelpCommandSounds ():
+ # same as HelpTextArea if not BG1
+ HelpTextArea2.SetText (18016)
+
+def DisplayHelpSelectionSounds ():
+ # same as HelpTextArea if not BG1
+ HelpTextArea2.SetText (11352)
+
+###################################################
+
+def CloseGameplayOptionsWindow ():
+ # FIXME: don't need to do anything, since we save stuff immediately
+ # ergo canceling does not work
+ CloseSubOptionsWindow ()
+ TrySavingConfiguration()
+
+def OpenGameplayOptionsWindow ():
+ """Open gameplay options window"""
+ global SubOptionsWindow, HelpTextArea
+
+ Window = SubOptionsWindow
+ CloseSubOptionsWindow ()
+
+ #gameplayoptions
+ Window = GemRB.LoadWindow (8)
+
+ HelpTextArea = GUIOPTControls.OptHelpText ('GameplayOptions', Window, 40, 18042)
+
+ GUIOPTControls.OptDone (CloseGameplayOptionsWindow, Window, 7)
+ GUIOPTControls.OptCancel (CloseGameplayOptionsWindow, Window, 20)
+
+ GUIOPTControls.OptSlider (18042, 18017, HelpTextArea, Window, 1, 21, 17143, 'Tooltips', DisplayHelpTooltipDelay, TOOLTIP_DELAY_FACTOR)
+ GUIOPTControls.OptSlider (18042, 18018, HelpTextArea, Window, 2, 22, 17144, 'Mouse Scroll Speed', DisplayHelpMouseScrollingSpeed, 5)
+ GUIOPTControls.OptSlider (18042, 18019, HelpTextArea, Window, 3, 23, 17145, 'Keyboard Scroll Speed', None, 5)
+ GUIOPTControls.OptSlider (18042, 18020, HelpTextArea, Window, 12, 24, 13911, 'Difficulty Level', None, 0)
+
+ GUIOPTControls.OptCheckbox (18042, 18021, HelpTextArea, Window, 14, 25, 13697, 'Always Dither')
+ GUIOPTControls.OptCheckbox (18042, 18023, HelpTextArea, Window, 19, 27, 17182, 'Gore')
+ GUIOPTControls.OptCheckbox (18042, 11797, HelpTextArea, Window, 42, 44, 11795, 'Infravision')
+ GUIOPTControls.OptCheckbox (18042, 20619, HelpTextArea, Window, 47, 46, 20618, 'Weather')
+ if GUICommon.GameIsBG2():
+ GUIOPTControls.OptCheckbox (18042, 2242, HelpTextArea, Window, 50, 48, 2241, 'Heal Party on Rest')
+ elif GUICommon.GameIsIWD2():
+ GUIOPTControls.OptCheckbox (18042, 15136, HelpTextArea, Window, 50, 49, 17378, 'Maximum HP')
+
+ GUIOPTControls.OptButton (OpenFeedbackOptionsWindow, Window, 5, 17163)
+ GUIOPTControls.OptButton (OpenAutopauseOptionsWindow, Window, 6, 17166)
+ if GUICommon.GameIsBG2():
+ GUIOPTControls.OptButton (OpenHotkeyOptionsWindow, Window, 51, 816)
+
+ SubOptionsWindow = Window
+ Window.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def DisplayHelpTooltipDelay ():
+ HelpTextArea.SetText (18017)
+ GemRB.SetTooltipDelay (GemRB.GetVar ("Tooltips") )
+
+def DisplayHelpMouseScrollingSpeed ():
+ HelpTextArea.SetText (18018)
+ GemRB.SetMouseScrollSpeed (GemRB.GetVar ("Mouse Scroll Speed") )
+
+###################################################
+
+def CloseFeedbackOptionsWindow ():
+ # FIXME: don't need to do anything, since we save stuff immediately
+ # ergo canceling does not work
+ CloseSubSubOptionsWindow ()
+
+def OpenFeedbackOptionsWindow ():
+ """Open feedback options window"""
+
+ global SubSubOptionsWindow, HelpTextArea2
+
+ Window = SubSubOptionsWindow
+ CloseSubSubOptionsWindow ()
+
+ Window = GemRB.LoadWindow (9)
+ # same as HelpTextArea if not BG1
+ HelpTextArea2 = GUIOPTControls.OptHelpText ('FeedbackOptions', Window, 28, 18043)
+
+ GemRB.SetVar ("Circle Feedback", GemRB.GetVar ("GUI Feedback Level") - 1)
+
+ GUIOPTControls.OptDone (CloseFeedbackOptionsWindow, Window, 26)
+ GUIOPTControls.OptCancel (CloseFeedbackOptionsWindow, Window, 27)
+
+ GUIOPTControls.OptSlider (18043, 18024, HelpTextArea2, Window, 8, 30, 13688, 'Circle Feedback', DisplayHelpMarkerFeedback)
+ GUIOPTControls.OptSlider (18043, 18025, HelpTextArea2, Window, 9, 31, 17769, 'Locator Feedback Level')
+
+ GUIOPTControls.OptCheckbox (18043, 18026, HelpTextArea2, Window, 10, 32, 17149, 'Rolls')
+ GUIOPTControls.OptCheckbox (18043, 18027, HelpTextArea2, Window, 11, 33, 17150, 'Combat Info')
+ GUIOPTControls.OptCheckbox (18043, 18028, HelpTextArea2, Window, 12, 34, 17151, 'Actions')
+ GUIOPTControls.OptCheckbox (18043, 18029, HelpTextArea2, Window, 13, 35, 17152, 'State Changes')
+ GUIOPTControls.OptCheckbox (18043, 18030, HelpTextArea2, Window, 14, 36, 17181, 'Selection Text')
+ GUIOPTControls.OptCheckbox (18043, 18031, HelpTextArea2, Window, 15, 37, 17153, 'Miscellaneous Text')
+
+ Window.ShowModal (MODAL_SHADOW_GRAY)
+
+ SubSubOptionsWindow = Window
+
+ return
+
+def DisplayHelpMarkerFeedback ():
+ # same as HelpTextArea if not BG1
+ HelpTextArea2.SetText (18024)
+ GemRB.SetVar ("GUI Feedback Level", GemRB.GetVar ("Circle Feedback") + 1)
+
+###################################################
+
+def CloseAutopauseOptionsWindow ():
+ # FIXME: don't need to do anything, since we save stuff immediately
+ # ergo canceling does not work
+ CloseSubSubOptionsWindow ()
+
+def OpenAutopauseOptionsWindow ():
+ """Open autopause options window"""
+
+ global SubSubOptionsWindow, HelpTextArea2
+
+ Window = SubSubOptionsWindow
+ CloseSubSubOptionsWindow ()
+
+ Window = GemRB.LoadWindow (10)
+ HelpTextArea2 = GUIOPTControls.OptHelpText ('AutopauseOptions', Window, 15, 18044)
+
+ GUIOPTControls.OptDone (CloseAutopauseOptionsWindow, Window, 11)
+ GUIOPTControls.OptCancel (CloseAutopauseOptionsWindow, Window, 14)
+
+ # checkboxes OR the values if they associate to the same variable
+ GUIOPTControls.OptCheckbox (18044, 18032, HelpTextArea2, Window, 1, 17, 17155, 'Auto Pause State', None, 4) # hit
+ GUIOPTControls.OptCheckbox (18044, 18033, HelpTextArea2, Window, 2, 18, 17156, 'Auto Pause State', None, 8) # wounded
+ GUIOPTControls.OptCheckbox (18044, 18034, HelpTextArea2, Window, 3, 19, 17157, 'Auto Pause State', None, 16) # dead
+ GUIOPTControls.OptCheckbox (18044, 18035, HelpTextArea2, Window, 4, 20, 17158, 'Auto Pause State', None, 2) # attacked
+ GUIOPTControls.OptCheckbox (18044, 18036, HelpTextArea2, Window, 5, 21, 17159, 'Auto Pause State', None, 1) # weapon unusable
+ GUIOPTControls.OptCheckbox (18044, 18037, HelpTextArea2, Window, 13, 22, 17160, 'Auto Pause State', None, 32) # target gone
+ GUIOPTControls.OptCheckbox (18044, 10640, HelpTextArea2, Window, 25, 24, 10639, 'Auto Pause State', None, 64) # end of round
+ if GUICommon.GameIsIWD2():
+ GUIOPTControls.OptCheckbox (18044, 23514, HelpTextArea2, Window, 30, 31, 23516, 'Auto Pause State', None, 128) # enemy sighted
+ GUIOPTControls.OptCheckbox (18044, 18560, HelpTextArea2, Window, 26, 28, 16519, 'Auto Pause State', None, 256) # trap found
+ GUIOPTControls.OptCheckbox (18044, 26311, HelpTextArea2, Window, 36, 37, 26310, 'Auto Pause State', None, 512) # spell cast
+ GUIOPTControls.OptCheckbox (18044, 24888, HelpTextArea2, Window, 33, 34, 10574, 'Auto Pause Center', None, 1)
+ elif not GUICommon.GameIsIWD1():
+ GUIOPTControls.OptCheckbox (18044, 23514, HelpTextArea2, Window, 26, 27, 23516, 'Auto Pause State', None, 128) # enemy sighted
+ if GUICommon.GameIsBG2():
+ GUIOPTControls.OptCheckbox (18044, 58171, HelpTextArea2, Window, 31, 30, 31875, 'Auto Pause State', None, 512) # spell cast
+ GUIOPTControls.OptCheckbox (18044, 31872, HelpTextArea2, Window, 34, 33, 57354, 'Auto Pause State', None, 256) # trap found
+ GUIOPTControls.OptCheckbox (18044, 10571, HelpTextArea2, Window, 37, 36, 10574, 'Auto Pause Center', None, 1)
+
+ SubSubOptionsWindow = Window
+
+ Window.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+###################################################
+
+def MoviePlayPress():
+ s = GemRB.GetVar("MovieIndex")
+ for i in range(0, MoviesTable.GetRowCount() ):
+ t = MoviesTable.GetRowName(i)
+ #temporarily out (change simultaneously with OpenMovieWindow)
+ #if GemRB.GetVar(t)==1:
+ if 1==1:
+ if s==0:
+ s = MoviesTable.GetRowName(i)
+ GemRB.PlayMovie(s, 1)
+ SubOptionsWindow.Invalidate()
+ return
+ s = s - 1
+ return
+
+def MovieCreditsPress():
+ GemRB.PlayMovie("CREDITS")
+ SubOptionsWindow.Invalidate()
+ return
+
+def OpenMovieWindow ():
+ global SubOptionsWindow, TextAreaControl, MoviesTable
+
+ GemRB.LoadWindowPack("GUIMOVIE", 800, 600)
+ SubOptionsWindow = Window = GemRB.LoadWindow(2)
+ Window.SetFrame ()
+ #reloading the guiopt windowpack
+ GemRB.LoadWindowPack ("GUIOPT", 800, 600)
+ TextAreaControl = Window.GetControl(0)
+ TextAreaControl.SetFlags(IE_GUI_TEXTAREA_SELECTABLE)
+ PlayButton = Window.GetControl(2)
+ CreditsButton = Window.GetControl(3)
+ DoneButton = Window.GetControl(4)
+ MoviesTable = GemRB.LoadTable("MOVIDESC")
+ for i in range(0, MoviesTable.GetRowCount() ):
+ t = MoviesTable.GetRowName(i)
+ #temporarily out too (see above)
+ #if GemRB.GetVar(t)==1:
+ if 1==1:
+ s = MoviesTable.GetValue(i, 0)
+ TextAreaControl.Append(s,-1)
+ TextAreaControl.SetVarAssoc("MovieIndex",0)
+ PlayButton.SetText(17318)
+ CreditsButton.SetText(15591)
+ DoneButton.SetText(11973)
+ PlayButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, MoviePlayPress)
+ CreditsButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, MovieCreditsPress)
+ DoneButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, CloseSubOptionsWindow)
+ Window.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+###################################################
+
+def CloseSubOptionsWindow ():
+ global SubOptionsWindow, GameOptionsWindow
+
+ if SubOptionsWindow:
+ SubOptionsWindow.Unload ()
+ SubOptionsWindow = None
+ if GameOptionsWindow:
+ GameOptionsWindow.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def CloseSubSubOptionsWindow ():
+ global SubSubOptionsWindow, SubOptionsWindow
+
+ if SubSubOptionsWindow:
+ SubSubOptionsWindow.Unload ()
+ SubSubOptionsWindow = None
+ if SubOptionsWindow:
+ SubOptionsWindow.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def RestoreWinVisibility ():
+ if OptionsWindow:
+ OptionsWindow.SetVisible (WINDOW_VISIBLE)
+ if GameOptionsWindow:
+ GameOptionsWindow.SetVisible (WINDOW_VISIBLE)
+ if PortraitWindow:
+ PortraitWindow.SetVisible (WINDOW_VISIBLE)
+
+###################################################
+
+def OpenSaveMsgWindow ():
+ GemRB.SetVar("QuitAfterSave",0)
+ GUISAVE.OpenSaveWindow ()
+ #save the game without quitting
+ return
+
+###################################################
+
+def OpenLoadMsgWindow ():
+ global LoadMsgWindow
+
+ if LoadMsgWindow:
+ return
+
+ LoadMsgWindow = Window = GemRB.LoadWindow (4)
+
+ # Load
+ Button = Window.GetControl (0)
+ Button.SetText (15590)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, LoadGamePress)
+ Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
+
+ # Cancel
+ Button = Window.GetControl (1)
+ Button.SetText (GUIOPTControls.STR_OPT_CANCEL)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseLoadMsgWindow)
+ Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+
+ # Loading a game will destroy ...
+ Text = Window.GetControl (3)
+ Text.SetText (19531)
+
+ Window.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def CloseLoadMsgWindow ():
+ global LoadMsgWindow
+
+ if LoadMsgWindow:
+ LoadMsgWindow.Unload ()
+ LoadMsgWindow = None
+
+ RestoreWinVisibility ()
+
+ return
+
+def LoadGamePress ():
+ global LoadMsgWindow
+
+ if LoadMsgWindow:
+ LoadMsgWindow.Unload ()
+ LoadMsgWindow = None
+ GemRB.QuitGame ()
+ OpenOptionsWindow()
+ GemRB.SetNextScript ("GUILOAD")
+ return
+
+#save game AND quit
+def SaveGamePress ():
+ CloseQuitMsgWindow()
+ #we need to set a state: quit after save
+ GemRB.SetVar("QuitAfterSave",1)
+ OpenOptionsWindow()
+ GUISAVE.OpenSaveWindow ()
+ return
+
+def QuitGamePress ():
+ if GemRB.GetVar("AskAndExit") == 1:
+ GemRB.Quit()
+ return
+
+ CloseQuitMsgWindow()
+
+ GemRB.QuitGame ()
+ OpenOptionsWindow()
+ GemRB.SetNextScript ("Start")
+ return
+
+###################################################
+
+def OpenQuitMsgWindow ():
+ global QuitMsgWindow
+
+ if QuitMsgWindow:
+ return
+
+ QuitMsgWindow = Window = GemRB.LoadWindow (5)
+
+ # Save
+ Button = Window.GetControl (0)
+ Button.SetText (15589)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SaveGamePress)
+
+ # Quit Game
+ Button = Window.GetControl (1)
+ Button.SetText (15417)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, QuitGamePress)
+ Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
+
+ # Cancel
+ Button = Window.GetControl (2)
+ Button.SetText (GUIOPTControls.STR_OPT_CANCEL)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CancelQuitMsgWindow)
+ Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+
+ # Do you wish to save the game ....
+ Text = Window.GetControl (3)
+ Text.SetText (16456)
+
+ Window.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def CancelQuitMsgWindow ():
+ CloseQuitMsgWindow()
+
+ if not GameOptionsWindow:
+ GUICommon.GameWindow.SetVisible(WINDOW_VISIBLE)
+
+ RestoreWinVisibility ()
+
+ return
+
+def CloseQuitMsgWindow ():
+ global QuitMsgWindow
+
+ if QuitMsgWindow:
+ QuitMsgWindow.Unload ()
+ QuitMsgWindow = None
+
+ GemRB.SetVar("AskAndExit", 0)
+ return
+
+###################################################
+def OpenHotkeyOptionsWindow ():
+ print("TODO: implement OpenHotkeyOptionsWindow!")
+ # check if pst's guiopt's OpenKeyboardMappingsWindow is reusable
+ return
+
+def CloseHotkeyOptionsWindow ():
+ return
+
+###################################################
+# End of file GUIOPT.py
diff --git a/gemrb/GUIScripts/GUIOPTControls.py b/gemrb/GUIScripts/GUIOPTControls.py
new file mode 100644
index 0000000..4bebac2
--- /dev/null
+++ b/gemrb/GUIScripts/GUIOPTControls.py
@@ -0,0 +1,145 @@
+# -*-python-*-
+# GemRB - Infinity Engine Emulator
+# Copyright (C) 2012 The GemRB Project
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+# GUIOPTControls.py - control functions for the GUIOPT winpack:
+
+###################################################
+import GUICommon
+from GUIDefines import *
+
+###################################################
+# strrefs
+if GUICommon.GameIsPST():
+ STR_OPT_DONE = 1403
+ STR_OPT_CANCEL = 4196
+else:
+ STR_OPT_DONE = 11973
+ STR_OPT_CANCEL = 13727
+
+###################################################
+# These functions help to setup controls found
+# in Video, Audio, Gameplay, Feedback and Autopause
+# options windows
+
+# These controls are usually made from an active
+# control (button, slider ...) and a label
+
+# NOTE: make sure handler users also set the strref in them!
+def OptSlider (winhelp, ctlhelp, help_ta, window, slider_id, label_id, label_strref, variable, action = None, value = 1):
+ """Standard slider for option windows"""
+ slider = window.GetControl (slider_id)
+ slider.SetVarAssoc (variable, value)
+ if action:
+ slider.SetEvent (IE_GUI_SLIDER_ON_CHANGE, action)
+ else:
+ # create an anonymous callback, so we don't need to create a separate function for each string
+ slider.SetEvent (IE_GUI_SLIDER_ON_CHANGE, lambda s=ctlhelp, ta=help_ta: ta.SetText (s))
+
+ OptBuddyLabel (window, label_id, label_strref, help_ta, ctlhelp, winhelp)
+
+ return slider
+
+def OptRadio (action, window, button_id, label_id, variable, value):
+ """Standard radio button for option windows"""
+
+ button = window.GetControl (button_id)
+ button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
+ button.SetEvent (IE_GUI_BUTTON_ON_PRESS, action)
+ button.SetVarAssoc (variable, value)
+ if GUICommon.GameIsIWD2():
+ button.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
+ elif GUICommon.GameIsIWD1() or GUICommon.GameIsBG1():
+ button.SetSprites ("TOGGLE", 0, 0, 1, 3, 2)
+
+ OptBuddyLabel (window, label_id)
+
+ return button
+
+# NOTE: make sure handler users also set the strref in them!
+def OptCheckbox (winhelp, ctlhelp, help_ta, window, button_id, label_id, label_strref, variable, handler=None, value=1):
+ """Standard checkbox for option windows"""
+
+ button = window.GetControl (button_id)
+ button.SetFlags (IE_GUI_BUTTON_CHECKBOX, OP_OR)
+ if variable:
+ button.SetVarAssoc (variable, value)
+
+ if GUICommon.GameIsIWD2():
+ button.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
+ elif GUICommon.GameIsIWD1() or GUICommon.GameIsBG1():
+ button.SetSprites ("GMPPARBC", 3, 1, 2, 3, 5)
+
+ if handler:
+ button.SetEvent (IE_GUI_BUTTON_ON_PRESS, handler)
+ else:
+ # create an anonymous callback, so we don't need to create a separate function for each string
+ # FIXME: IE_GUI_MOUSE_ENTER_BUTTON would be more UX-sensible, but interferes with toggling
+ button.SetEvent (IE_GUI_BUTTON_ON_PRESS, lambda s=ctlhelp, ta=help_ta: ta.SetText (s))
+
+ OptBuddyLabel (window, label_id, label_strref, help_ta, ctlhelp, winhelp)
+
+ return button
+
+def OptButton (action, window, button_id, button_strref):
+ """Standard subwindow button for option windows"""
+
+ button = window.GetControl (button_id)
+ button.SetEvent (IE_GUI_BUTTON_ON_PRESS, action)
+ button.SetText (button_strref)
+
+def OptDone (action, window, button_id):
+ """Standard `Done' button for option windows"""
+
+ button = window.GetControl (button_id)
+ button.SetText (STR_OPT_DONE) # Done
+ button.SetEvent (IE_GUI_BUTTON_ON_PRESS, action)
+ button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
+
+ if GUICommon.GameIsPST():
+ button.SetVarAssoc ("Cancel", 0)
+
+def OptCancel (action, window, button_id):
+ """Standard `Cancel' button for option windows"""
+
+ button = window.GetControl (button_id)
+ button.SetText (STR_OPT_CANCEL) # Cancel
+ button.SetEvent (IE_GUI_BUTTON_ON_PRESS, action)
+ button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+
+ if GUICommon.GameIsPST():
+ button.SetVarAssoc ("Cancel", 1)
+
+def OptHelpText (name, window, text_id, text_strref):
+ """Standard textarea with context help for option windows"""
+ text = window.GetControl (text_id)
+ text.SetText (text_strref)
+ return text
+
+def OptBuddyLabel (window, label_id, label_strref = None, help_ta = None, ctlname = None, winname = None):
+ label = window.GetControl (label_id)
+ label.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
+ label.SetState (IE_GUI_BUTTON_LOCKED)
+ if label_strref and GUICommon.GameIsPST():
+ label.SetText (label_strref)
+ if help_ta:
+ label.SetEvent (IE_GUI_MOUSE_ENTER_BUTTON, lambda: help_ta.SetText (ctlname))
+ label.SetEvent (IE_GUI_MOUSE_LEAVE_BUTTON, lambda: help_ta.SetText (winname))
+
+###################################################
+# End of file GUIOPTControls.py
diff --git a/gemrb/GUIScripts/GUIPR.py b/gemrb/GUIScripts/GUIPR.py
new file mode 100644
index 0000000..60ba7ff
--- /dev/null
+++ b/gemrb/GUIScripts/GUIPR.py
@@ -0,0 +1,375 @@
+# -*-python-*-
+# GemRB - Infinity Engine Emulator
+# Copyright (C) 2003-2004 The GemRB Project
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+
+# GUIPR.py - scripts to control the priest spells windows from the GUIPR winpack
+
+###################################################
+
+import GemRB
+import GUICommon
+import CommonTables
+from GUIDefines import *
+from ie_stats import *
+from ie_action import ACT_CAST
+
+PriestWindow = None
+PriestSpellInfoWindow = None
+PriestSpellLevel = 0
+PriestSpellUnmemorizeWindow = None
+PortraitWindow = None
+OptionsWindow = None
+OldPortraitWindow = None
+OldOptionsWindow = None
+
+def OpenPriestWindow ():
+ import GUICommonWindows
+ global PriestWindow, OptionsWindow, PortraitWindow
+ global OldPortraitWindow, OldOptionsWindow
+
+ if GUICommon.CloseOtherWindow (OpenPriestWindow):
+ if PriestWindow:
+ PriestWindow.Unload ()
+ if OptionsWindow:
+ OptionsWindow.Unload ()
+ if PortraitWindow:
+ PortraitWindow.Unload ()
+
+ PriestWindow = None
+ GemRB.SetVar ("OtherWindow", -1)
+ GUICommon.GameWindow.SetVisible(WINDOW_VISIBLE)
+ GemRB.UnhideGUI ()
+ GUICommonWindows.PortraitWindow = OldPortraitWindow
+ OldPortraitWindow = None
+ GUICommonWindows.OptionsWindow = OldOptionsWindow
+ OldOptionsWindow = None
+ GUICommonWindows.SetSelectionChangeHandler (None)
+ return
+
+ GemRB.HideGUI ()
+ GUICommon.GameWindow.SetVisible(WINDOW_INVISIBLE)
+
+ GemRB.LoadWindowPack ("GUIPR", 640, 480)
+ PriestWindow = Window = GemRB.LoadWindow (2)
+ GemRB.SetVar ("OtherWindow", PriestWindow.ID)
+ #saving the original portrait window
+ OldOptionsWindow = GUICommonWindows.OptionsWindow
+ OptionsWindow = GemRB.LoadWindow (0)
+ GUICommonWindows.MarkMenuButton (OptionsWindow)
+ GUICommonWindows.SetupMenuWindowControls (OptionsWindow, 0, OpenPriestWindow)
+ OptionsWindow.SetFrame ()
+ OldPortraitWindow = GUICommonWindows.PortraitWindow
+ PortraitWindow = GUICommonWindows.OpenPortraitWindow (0)
+
+ Button = Window.GetControl (1)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, PriestPrevLevelPress)
+
+ Button = Window.GetControl (2)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, PriestNextLevelPress)
+
+ #setup level buttons
+ if GUICommon.GameIsBG2():
+ for i in range (7):
+ Button = Window.GetControl (55 + i)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, RefreshPriestLevel)
+ Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
+
+ for i in range (7):
+ Button = Window.GetControl (55 + i)
+ Button.SetVarAssoc ("PriestSpellLevel", i)
+
+ # Setup memorized spells buttons
+ for i in range (12):
+ Button = Window.GetControl (3 + i)
+ Button.SetBorder (0,0,0,0,0,0,0,0,64,0,1)
+ Button.SetSprites ("SPELFRAM",0,0,0,0,0)
+ Button.SetFlags (IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_PLAYONCE, OP_OR)
+ Button.SetState (IE_GUI_BUTTON_LOCKED)
+
+ # Setup book spells buttons
+ for i in range (GUICommon.GetGUISpellButtonCount()):
+ Button = Window.GetControl (27 + i)
+ Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE | IE_GUI_BUTTON_PLAYONCE, OP_OR)
+ Button.SetState (IE_GUI_BUTTON_LOCKED)
+
+ GUICommonWindows.SetSelectionChangeHandler (UpdatePriestWindow)
+ UpdatePriestWindow ()
+ OptionsWindow.SetVisible (WINDOW_VISIBLE)
+ #bringing window front
+ Window.SetVisible (WINDOW_FRONT)
+ PortraitWindow.SetVisible (WINDOW_VISIBLE)
+ return
+
+def UpdatePriestWindow ():
+ global PriestMemorizedSpellList, PriestKnownSpellList
+
+ PriestMemorizedSpellList = []
+ PriestKnownSpellList = []
+
+ Window = PriestWindow
+ pc = GemRB.GameGetSelectedPCSingle ()
+ type = IE_SPELL_TYPE_PRIEST
+ level = PriestSpellLevel
+ max_mem_cnt = GemRB.GetMemorizableSpellsCount (pc, type, level)
+
+ Label = Window.GetControl (0x10000032)
+ # bg2 uses a shorthand form
+ if GUICommon.GameIsBG2():
+ GemRB.SetToken ("SPELLLEVEL", str(level+1))
+ Label.SetText (10345)
+ else:
+ GemRB.SetToken ('LEVEL', str(level+1))
+ Label.SetText (12137)
+
+ Name = GemRB.GetPlayerName (pc, 0)
+ Label = Window.GetControl (0x10000035)
+ Label.SetText (Name)
+
+ mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level, False)
+ for i in range (12):
+ Button = Window.GetControl (3 + i)
+ if i < mem_cnt:
+ ms = GemRB.GetMemorizedSpell (pc, type, level, i)
+ Button.SetSpellIcon (ms['SpellResRef'], 0)
+ Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_NAND)
+ Button.SetFlags (IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_PLAYONCE, OP_OR)
+ if ms['Flags']:
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenPriestSpellUnmemorizeWindow)
+ else:
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OnPriestUnmemorizeSpell)
+ Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, OpenPriestSpellInfoWindow)
+ spell = GemRB.GetSpell (ms['SpellResRef'])
+ Button.SetTooltip (spell['SpellName'])
+ PriestMemorizedSpellList.append (ms['SpellResRef'])
+ Button.SetVarAssoc ("SpellButton", i)
+ Button.EnableBorder (0, ms['Flags'] == 0)
+ else:
+ if i < max_mem_cnt:
+ Button.SetFlags (IE_GUI_BUTTON_NORMAL | IE_GUI_BUTTON_PLAYONCE, OP_SET)
+ else:
+ Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, None)
+ Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, None)
+ Button.SetTooltip ('')
+ Button.EnableBorder (0, 0)
+
+ known_cnt = GemRB.GetKnownSpellsCount (pc, type, level)
+ for i in range (GUICommon.GetGUISpellButtonCount()):
+ Button = Window.GetControl (27 + i)
+ if i < known_cnt:
+ ks = GemRB.GetKnownSpell (pc, type, level, i)
+ Button.SetSpellIcon (ks['SpellResRef'], 0)
+ Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_NAND)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OnPriestMemorizeSpell)
+ Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, OpenPriestSpellInfoWindow)
+ spell = GemRB.GetSpell (ks['SpellResRef'])
+ Button.SetTooltip (spell['SpellName'])
+ PriestKnownSpellList.append (ks['SpellResRef'])
+ Button.SetVarAssoc ("SpellButton", 100 + i)
+ else:
+ Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_OR)
+ Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_NAND)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, None)
+ Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, None)
+ Button.SetTooltip ('')
+ Button.EnableBorder (0, 0)
+
+ ClassName = GUICommon.GetClassRowName (pc)
+ DivineCaster = CommonTables.ClassSkills.GetValue (ClassName, "CLERICSPELL")
+ if DivineCaster == "*":
+ # also check the DRUIDSPELL column
+ DivineCaster = CommonTables.ClassSkills.GetValue (ClassName, "DRUIDSPELL")
+ CantCast = DivineCaster == "*"
+ CantCast += GemRB.GetPlayerStat(pc, IE_DISABLEDBUTTON)&(1<<ACT_CAST)
+
+ GUICommon.AdjustWindowVisibility (Window, pc, CantCast)
+ return
+
+def PriestPrevLevelPress ():
+ global PriestSpellLevel
+
+ if PriestSpellLevel > 0:
+ PriestSpellLevel = PriestSpellLevel - 1
+ UpdatePriestWindow ()
+ return
+
+def PriestNextLevelPress ():
+ global PriestSpellLevel
+
+ if PriestSpellLevel < 6:
+ PriestSpellLevel = PriestSpellLevel + 1
+ UpdatePriestWindow ()
+ return
+
+def RefreshPriestLevel ():
+ global PriestSpellLevel
+
+ PriestSpellLevel = GemRB.GetVar ("PriestSpellLevel")
+ UpdatePriestWindow ()
+ return
+
+def OpenPriestSpellInfoWindow ():
+ global PriestSpellInfoWindow
+
+ if PriestSpellInfoWindow != None:
+ if PriestSpellInfoWindow:
+ PriestSpellInfoWindow.Unload ()
+ PriestSpellInfoWindow = None
+ return
+
+ PriestSpellInfoWindow = Window = GemRB.LoadWindow (3)
+
+ #back
+ Button = Window.GetControl (5)
+ Button.SetText (15416)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenPriestSpellInfoWindow)
+
+ index = GemRB.GetVar ("SpellButton")
+ if index < 100:
+ ResRef = PriestMemorizedSpellList[index]
+ else:
+ ResRef = PriestKnownSpellList[index - 100]
+
+ spell = GemRB.GetSpell (ResRef)
+
+ if GUICommon.GameIsBG2():
+ Label = Window.GetControl (0x0fffffff)
+ else:
+ Label = Window.GetControl (0x10000000)
+ Label.SetText (spell['SpellName'])
+
+ Button = Window.GetControl (2)
+ Button.SetSpellIcon (ResRef, 1)
+
+ Text = Window.GetControl (3)
+ Text.SetText (spell['SpellDesc'])
+
+ Window.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def OnPriestMemorizeSpell ():
+ pc = GemRB.GameGetSelectedPCSingle ()
+ level = PriestSpellLevel
+ type = IE_SPELL_TYPE_PRIEST
+
+ index = GemRB.GetVar ("SpellButton") - 100
+
+ if GemRB.MemorizeSpell (pc, type, level, index):
+ UpdatePriestWindow ()
+ GemRB.PlaySound ("GAM_24")
+ Button = PriestWindow.GetControl(index + 27)
+ mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level, False)
+ Button2 = PriestWindow.GetControl(mem_cnt + 2)
+ if GUICommon.GameIsBG2(): # no blending
+ Button.SetAnimation ("FLASH")
+ Button2.SetAnimation ("FLASH")
+ else:
+ Button.SetAnimation ("FLASH", 0, 1)
+ Button2.SetAnimation ("FLASH", 0, 1)
+ return
+
+def OpenPriestSpellRemoveWindow ():
+ global PriestSpellUnmemorizeWindow
+
+ PriestSpellUnmemorizeWindow = Window = GemRB.LoadWindow (5)
+
+ # "Are you sure you want to ....?"
+ TextArea = Window.GetControl (3)
+ TextArea.SetText (11824)
+
+ # Remove
+ Button = Window.GetControl (0)
+ Button.SetText (17507)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OnPriestRemoveSpell)
+ Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
+
+ # Cancel
+ Button = Window.GetControl (1)
+ Button.SetText (13727)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, ClosePriestSpellUnmemorizeWindow)
+ Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+
+ Window.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def ClosePriestSpellUnmemorizeWindow ():
+ global PriestSpellUnmemorizeWindow
+
+ if PriestSpellUnmemorizeWindow:
+ PriestSpellUnmemorizeWindow.Unload ()
+ PriestSpellUnmemorizeWindow = None
+ return
+
+def OpenPriestSpellUnmemorizeWindow ():
+ global PriestSpellUnmemorizeWindow
+
+ PriestSpellUnmemorizeWindow = Window = GemRB.LoadWindow (5)
+
+ # "Are you sure you want to ....?"
+ TextArea = Window.GetControl (3)
+ TextArea.SetText (11824)
+
+ # Remove
+ Button = Window.GetControl (0)
+ Button.SetText (17507)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OnPriestUnmemorizeSpell)
+ Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
+
+ # Cancel
+ Button = Window.GetControl (1)
+ Button.SetText (13727)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, ClosePriestSpellUnmemorizeWindow)
+ Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+
+ Window.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def OnPriestUnmemorizeSpell ():
+ if PriestSpellUnmemorizeWindow:
+ ClosePriestSpellUnmemorizeWindow ()
+
+ pc = GemRB.GameGetSelectedPCSingle ()
+ level = PriestSpellLevel
+ type = IE_SPELL_TYPE_PRIEST
+
+ index = GemRB.GetVar ("SpellButton")
+
+ if GemRB.UnmemorizeSpell (pc, type, level, index):
+ UpdatePriestWindow ()
+ GemRB.PlaySound ("GAM_44")
+ Button = PriestWindow.GetControl(index + 3)
+ Button.SetAnimation ("FLASH", 0, GUICommon.GameIsBG2() is False) # no blending for bg2
+ return
+
+def OnPriestRemoveSpell ():
+ ClosePriestSpellUnmemorizeWindow()
+
+ pc = GemRB.GameGetSelectedPCSingle ()
+ level = PriestSpellLevel
+ type = IE_SPELL_TYPE_PRIEST
+
+ index = GemRB.GetVar ("SpellButton") - 100
+
+ #remove spell from memory
+ GemRB.RemoveSpell (pc, type, level, index)
+ OpenPriestSpellInfoWindow()
+ return
+
+###################################################
+# End of file GUIPR.py
diff --git a/gemrb/GUIScripts/GUIREC.py b/gemrb/GUIScripts/GUIREC.py
new file mode 100644
index 0000000..c6efeb4
--- /dev/null
+++ b/gemrb/GUIScripts/GUIREC.py
@@ -0,0 +1,1056 @@
+# -*-python-*-
+# GemRB - Infinity Engine Emulator
+# Copyright (C) 2003-2009 The GemRB Project
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+
+# GUIREC.py - scripts to control stats/records windows from the GUIREC winpack
+###################################################
+import GemRB
+import GUICommon
+import Spellbook
+import CommonTables
+import LUCommon
+import LevelUp
+import GUIWORLD
+import DualClass
+import GUIRECCommon
+from GUIDefines import *
+from ie_stats import *
+from ie_restype import *
+###################################################
+RecordsWindow = None
+InformationWindow = None
+PortraitWindow = None
+OptionsWindow = None
+OldPortraitWindow = None
+OldOptionsWindow = None
+KitInfoWindow = None
+ColorTable = None
+ColorIndex = None
+ScriptTextArea = None
+SelectedTextArea = None
+
+###################################################
+def OpenRecordsWindow ():
+ import GUICommonWindows
+
+ global RecordsWindow, OptionsWindow, PortraitWindow
+ global OldPortraitWindow, OldOptionsWindow
+
+ if GUICommon.CloseOtherWindow (OpenRecordsWindow):
+ if InformationWindow: OpenInformationWindow ()
+
+ if RecordsWindow:
+ RecordsWindow.Unload ()
+ if OptionsWindow:
+ OptionsWindow.Unload ()
+ if PortraitWindow:
+ PortraitWindow.Unload ()
+
+ RecordsWindow = None
+ GemRB.SetVar ("OtherWindow", -1)
+ GUICommon.GameWindow.SetVisible(WINDOW_VISIBLE)
+ GemRB.UnhideGUI ()
+ GUICommonWindows.PortraitWindow = OldPortraitWindow
+ OldPortraitWindow = None
+ GUICommonWindows.UpdatePortraitWindow ()
+ GUICommonWindows.OptionsWindow = OldOptionsWindow
+ OldOptionsWindow = None
+ GUICommonWindows.SetSelectionChangeHandler (None)
+ return
+
+ GemRB.HideGUI ()
+ GUICommon.GameWindow.SetVisible(WINDOW_INVISIBLE)
+
+ GemRB.LoadWindowPack ("GUIREC", 640, 480)
+ RecordsWindow = Window = GemRB.LoadWindow (2)
+ GemRB.SetVar ("OtherWindow", RecordsWindow.ID)
+ # saving the original portrait window
+ OldOptionsWindow = GUICommonWindows.OptionsWindow
+ OptionsWindow = GemRB.LoadWindow (0)
+ GUICommonWindows.SetupMenuWindowControls (OptionsWindow, 0, OpenRecordsWindow)
+ if GUICommon.GameIsBG2():
+ GUICommonWindows.MarkMenuButton (OptionsWindow)
+ OptionsWindow.SetFrame ()
+ OldPortraitWindow = GUICommonWindows.PortraitWindow
+ PortraitWindow = GUICommonWindows.OpenPortraitWindow (0)
+
+ # dual class
+ Button = Window.GetControl (0)
+ Button.SetText (7174)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, DualClass.DualClassWindow)
+
+ # levelup
+ Button = Window.GetControl (37)
+ Button.SetText (7175)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, LevelUp.OpenLevelUpWindow)
+
+ # information
+ Button = Window.GetControl (1)
+ Button.SetText (11946)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenInformationWindow)
+
+ # reform party
+ Button = Window.GetControl (51)
+ Button.SetText (16559)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenRecReformPartyWindow)
+
+ # customize
+ Button = Window.GetControl (50)
+ Button.SetText (10645)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIRECCommon.OpenCustomizeWindow)
+
+ # export
+ Button = Window.GetControl (36)
+ Button.SetText (13956)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIRECCommon.OpenExportWindow)
+
+ # kit info
+ if GUICommon.GameIsBG2():
+ Button = Window.GetControl (52)
+ Button.SetText (61265)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenKitInfoWindow)
+
+ GUICommonWindows.SetSelectionChangeHandler (UpdateRecordsWindow)
+ UpdateRecordsWindow ()
+
+ OptionsWindow.SetVisible (WINDOW_VISIBLE)
+ Window.SetVisible (WINDOW_VISIBLE)
+ PortraitWindow.SetVisible (WINDOW_VISIBLE)
+ return
+
+#original returns to game before continuing...
+def OpenRecReformPartyWindow ():
+ OpenRecordsWindow ()
+ GemRB.SetTimedEvent (GUIWORLD.OpenReformPartyWindow, 1)
+ return
+
+#don't allow exporting polymorphed or dead characters
+def Exportable(pc):
+ if not (GemRB.GetPlayerStat (pc, IE_MC_FLAGS)&MC_EXPORTABLE): return False
+ if GemRB.GetPlayerStat (pc, IE_POLYMORPHED): return False
+ if GemRB.GetPlayerStat (pc, IE_STATE_ID)&STATE_DEAD: return False
+ return True
+
+def UpdateRecordsWindow ():
+ global stats_overview, alignment_help
+
+ Window = RecordsWindow
+ if not RecordsWindow:
+ print "SelectionChange handler points to non existing window\n"
+ return
+
+ pc = GemRB.GameGetSelectedPCSingle ()
+
+ #update mage school
+ GemRB.SetVar ("MAGESCHOOL", 0)
+ Kit = GUICommon.GetKitIndex (pc)
+ if Kit and CommonTables.KitList.GetValue (Kit, 7) == 1:
+ MageTable = GemRB.LoadTable ("magesch")
+ GemRB.SetVar ("MAGESCHOOL", MageTable.FindValue (3, CommonTables.KitList.GetValue (Kit, 6) ) )
+
+ # exportable
+ Button = Window.GetControl (36)
+ if Exportable (pc):
+ Button.SetState (IE_GUI_BUTTON_ENABLED)
+ else:
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+
+ # dual-classable
+ Button = Window.GetControl (0)
+ if GUICommon.CanDualClass (pc):
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+ else:
+ Button.SetState (IE_GUI_BUTTON_ENABLED)
+
+ # levelup
+ Button = Window.GetControl (37)
+ if LUCommon.CanLevelUp (pc):
+ Button.SetState (IE_GUI_BUTTON_ENABLED)
+ else:
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+
+ # name
+ Label = Window.GetControl (0x1000000e)
+ Label.SetText (GemRB.GetPlayerName (pc, 0))
+
+ # portrait
+ Button = Window.GetControl (2)
+ Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE | IE_GUI_BUTTON_PICTURE, OP_SET)
+ Button.SetState (IE_GUI_BUTTON_LOCKED)
+ if (GUICommon.GameIsBG2() or GUICommon.GameIsIWD1()) and not GUICommon.GameIsBG2Demo():
+ Button.SetPicture (GemRB.GetPlayerPortrait (pc,0), "NOPORTMD")
+ else:
+ Button.SetPicture (GemRB.GetPlayerPortrait (pc,0), "NOPORTLG")
+
+ # armorclass
+ Label = Window.GetControl (0x10000028)
+ ac = GemRB.GetPlayerStat (pc, IE_ARMORCLASS)
+ Label.SetText (str (ac))
+ Label.SetTooltip (17183)
+
+ # hp now
+ Label = Window.GetControl (0x10000029)
+ Label.SetText (str (GemRB.GetPlayerStat (pc, IE_HITPOINTS)))
+ Label.SetTooltip (17184)
+
+ # hp max
+ Label = Window.GetControl (0x1000002a)
+ Label.SetText (str (GemRB.GetPlayerStat (pc, IE_MAXHITPOINTS)))
+ Label.SetTooltip (17378)
+
+ # stats
+ sstr = GemRB.GetPlayerStat (pc, IE_STR)
+ sstrx = GemRB.GetPlayerStat (pc, IE_STREXTRA)
+ cstr = GetStatColor (pc, IE_STR)
+ if sstrx > 0 and sstr==18:
+ sstr = "%d/%02d" %(sstr, sstrx % 100)
+ else:
+ sstr = str (sstr)
+
+ sint = str (GemRB.GetPlayerStat (pc, IE_INT))
+ cint = GetStatColor (pc, IE_INT)
+ swis = str (GemRB.GetPlayerStat (pc, IE_WIS))
+ cwis = GetStatColor (pc, IE_WIS)
+ sdex = str (GemRB.GetPlayerStat (pc, IE_DEX))
+ cdex = GetStatColor (pc, IE_DEX)
+ scon = str (GemRB.GetPlayerStat (pc, IE_CON))
+ ccon = GetStatColor (pc, IE_CON)
+ schr = str (GemRB.GetPlayerStat (pc, IE_CHR))
+ cchr = GetStatColor (pc, IE_CHR)
+
+ Label = Window.GetControl (0x1000002f)
+ Label.SetText (sstr)
+ Label.SetTextColor (cstr[0], cstr[1], cstr[2])
+
+ Label = Window.GetControl (0x10000009)
+ Label.SetText (sdex)
+ Label.SetTextColor (cdex[0], cdex[1], cdex[2])
+
+ Label = Window.GetControl (0x1000000a)
+ Label.SetText (scon)
+ Label.SetTextColor (ccon[0], ccon[1], ccon[2])
+
+ Label = Window.GetControl (0x1000000b)
+ Label.SetText (sint)
+ Label.SetTextColor (cint[0], cint[1], cint[2])
+
+ Label = Window.GetControl (0x1000000c)
+ Label.SetText (swis)
+ Label.SetTextColor (cwis[0], cwis[1], cwis[2])
+
+ Label = Window.GetControl (0x1000000d)
+ Label.SetText (schr)
+ Label.SetTextColor (cchr[0], cchr[1], cchr[2])
+
+ # class
+ ClassTitle = GUICommon.GetActorClassTitle (pc)
+ Label = Window.GetControl (0x10000030)
+ Label.SetText (ClassTitle)
+
+ # race
+ text = CommonTables.Races.GetValue (CommonTables.Races.FindValue (3, GemRB.GetPlayerStat (pc, IE_RACE)) , 0)
+
+ Label = Window.GetControl (0x1000000f)
+ Label.SetText (text)
+
+ # alignment
+ text = CommonTables.Aligns.FindValue (3, GemRB.GetPlayerStat (pc, IE_ALIGNMENT))
+ text = CommonTables.Aligns.GetValue (text, 0)
+ Label = Window.GetControl (0x10000010)
+ Label.SetText (text)
+
+ # gender
+ Label = Window.GetControl (0x10000011)
+ if GemRB.GetPlayerStat (pc, IE_SEX) == 1:
+ Label.SetText (7198)
+ else:
+ Label.SetText (7199)
+
+ # help, info textarea
+ stats_overview = GetStatOverview (pc)
+ Text = Window.GetControl (45)
+ Text.SetText (stats_overview)
+ #TODO: making window visible/shaded depending on the pc's state
+ Window.SetVisible (WINDOW_VISIBLE)
+ return
+
+def GetStatColor (pc, stat):
+ a = GemRB.GetPlayerStat (pc, stat)
+ b = GemRB.GetPlayerStat (pc, stat, 1)
+ if a==b:
+ return (255,255,255)
+ if a<b:
+ return (255,255,0)
+ return (0,255,0)
+
+# GemRB.GetPlayerStat wrapper that only returns nonnegative values
+def GSNN (pc, stat):
+ val = GemRB.GetPlayerStat (pc, stat)
+ if val >= 0:
+ return val
+ else:
+ return 0
+
+# LevelDiff is used only from the level up code and holds the level
+# difference for each class
+def GetStatOverview (pc, LevelDiff=[0,0,0]):
+ StateTable = GemRB.LoadTable ("statdesc")
+
+ GS = lambda s, pc=pc: GemRB.GetPlayerStat (pc, s)
+ GB = lambda s, pc=pc: GemRB.GetPlayerStat (pc, s, 1)
+ GA = lambda s, col, pc=pc: GemRB.GetAbilityBonus (s, col, GS (s) )
+
+ # everyone but bg1 has it somewhere
+ if GUICommon.GameIsBG2():
+ str_None = GemRB.GetString (61560)
+ elif GUICommon.GameIsBG1():
+ str_None = -1
+ elif GUICommon.GameIsPST():
+ str_None = GemRB.GetString (41275)
+ else:
+ str_None = GemRB.GetString (17093)
+
+ stats = []
+ cdet = GemRB.GetCombatDetails(pc, 0)
+ tohit = cdet["ToHitStats"]
+
+ # class levels
+ # 16480 <CLASS>: Level <LEVEL>
+ # Experience: <EXPERIENCE>
+ # Next Level: <NEXTLEVEL>
+
+ # collecting tokens for stat overview
+ ClassTitle = GUICommon.GetActorClassTitle (pc)
+ GemRB.SetToken ("CLASS", ClassTitle)
+ Class = GUICommon.GetClassRowName (pc)
+ Dual = GUICommon.IsDualClassed (pc, 1)
+ Multi = GUICommon.IsMultiClassed (pc, 1)
+ XP = GemRB.GetPlayerStat (pc, IE_XP)
+ LevelDrain = GS (IE_LEVELDRAIN)
+
+ if GS (IE_STATE_ID) & STATE_DEAD:
+ stats.append ( (11829,1,'c') ) # DEAD
+ stats.append (None)
+
+ if Multi[0] > 1: # we're multiclassed
+ print "\tMulticlassed"
+ Levels = [GemRB.GetPlayerStat (pc, IE_LEVEL), GemRB.GetPlayerStat (pc, IE_LEVEL2), GemRB.GetPlayerStat (pc, IE_LEVEL3)]
+
+ stats.append ( (19721,1,'c') )
+ stats.append (None)
+ for i in range (Multi[0]):
+ Class = GUICommon.GetClassRowName (Multi[i+1], "class")
+ ClassTitle = GemRB.GetString (CommonTables.Classes.GetValue (Class, "CAP_REF"))
+ GemRB.SetToken ("CLASS", ClassTitle)
+ GemRB.SetToken ("LEVEL", str (Levels[i]+LevelDiff[i]-int(LevelDrain/Multi[0])) )
+ GemRB.SetToken ("EXPERIENCE", str (XP/Multi[0]) )
+ if LevelDrain:
+ stats.append ( (GemRB.GetString (19720),1,'d') )
+ stats.append ( (GemRB.GetString (57435),1,'d') ) # LEVEL DRAINED
+ else:
+ GemRB.SetToken ("NEXTLEVEL", LUCommon.GetNextLevelExp (Levels[i]+LevelDiff[i], Class) )
+ stats.append ( (GemRB.GetString (16480),"",'d') )
+ stats.append (None)
+ print "\t\tClass (Level):",Class,"(",Levels[i],")"
+
+ elif Dual[0] > 0: # dual classed; first show the new class
+ print "\tDual classed"
+ stats.append ( (19722,1,'c') )
+ stats.append (None)
+
+ Levels = [GemRB.GetPlayerStat (pc, IE_LEVEL), GemRB.GetPlayerStat (pc, IE_LEVEL2), GemRB.GetPlayerStat (pc, IE_LEVEL3)]
+
+ # the levels are stored in the class order (eg. FIGHTER_MAGE)
+ # the current active class does not matter!
+ if GUICommon.IsDualSwap (pc):
+ Levels = [Levels[1], Levels[0], Levels[2]]
+
+ Levels[0] += LevelDiff[0]
+
+ Class = CommonTables.Classes.GetRowName (Dual[2])
+ ClassTitle = GemRB.GetString (CommonTables.Classes.GetValue (Class, "CAP_REF"))
+ GemRB.SetToken ("CLASS", ClassTitle)
+ GemRB.SetToken ("LEVEL", str (Levels[0]-LevelDrain))
+ XP2 = GemRB.GetPlayerStat (pc, IE_XP)
+ GemRB.SetToken ("EXPERIENCE", str (XP2) )
+ if LevelDrain:
+ stats.append ( (GemRB.GetString (19720),1,'d') )
+ stats.append ( (GemRB.GetString (57435),1,'d') ) # LEVEL DRAINED
+ else:
+ GemRB.SetToken ("NEXTLEVEL", LUCommon.GetNextLevelExp (Levels[0], Class) )
+ stats.append ( (GemRB.GetString (16480),"",'d') )
+ stats.append (None)
+
+ # the first class (shown second)
+ if Dual[0] == 1:
+ ClassTitle = GemRB.GetString (CommonTables.KitList.GetValue (Dual[1], 2))
+ elif Dual[0] == 2:
+ ClassTitle = GUICommon.GetClassRowName(Dual[1], "index")
+ ClassTitle = GemRB.GetString (CommonTables.Classes.GetValue (ClassTitle, "CAP_REF"))
+ GemRB.SetToken ("CLASS", ClassTitle)
+ GemRB.SetToken ("LEVEL", str (Levels[1]) )
+
+ # the xp table contains only classes, so we have to determine the base class for kits
+ if Dual[0] == 2:
+ BaseClass = CommonTables.Classes.GetRowName (Dual[1])
+ else:
+ BaseClass = GUICommon.GetKitIndex (pc)
+ BaseClass = CommonTables.KitList.GetValue (BaseClass, 7)
+ BaseClass = GUICommon.GetClassRowName (BaseClass, "class")
+ # the first class' XP is discarded and set to the minimum level
+ # requirement, so if you don't dual class right after a levelup,
+ # the game would eat some of your XP
+ XP1 = CommonTables.NextLevel.GetValue (BaseClass, str (Levels[1]))
+ GemRB.SetToken ("EXPERIENCE", str (XP1) )
+
+ # inactive until the new class SURPASSES the former
+ if Levels[0] <= Levels[1]:
+ # inactive
+ stats.append ( (19719,1,'c') )
+ else:
+ stats.append ( (19720,1,'c') )
+ stats.append (None)
+ else: # single classed
+ print "\tSingle classed"
+ Level = GemRB.GetPlayerStat (pc, IE_LEVEL) + LevelDiff[0]
+ GemRB.SetToken ("LEVEL", str (Level-LevelDrain))
+ GemRB.SetToken ("EXPERIENCE", str (XP) )
+ if LevelDrain:
+ stats.append ( (19720,1,'c') )
+ stats.append ( (57435,1,'c') ) # LEVEL DRAINED
+ else:
+ GemRB.SetToken ("NEXTLEVEL", LUCommon.GetNextLevelExp (Level, Class) )
+ stats.append ( (16480,1,'c') )
+ stats.append (None)
+ print "\t\tClass (Level):",Class,"(",Level,")"
+
+ # check to see if we have a level diff anywhere
+ if sum (LevelDiff) == 0:
+ effects = GemRB.GetPlayerStates (pc)
+ if len (effects):
+ for c in effects:
+ tmp = StateTable.GetValue (str(ord(c)-66), "DESCRIPTION")
+ stats.append ( (tmp,c,'a') )
+ stats.append (None)
+
+ #proficiencies
+ stats.append ( (8442,1,'c') )
+
+ # look ma, I can use both hands
+
+ if GUICommon.GameIsBG2():
+ stats.append ( (61932, tohit["Base"], '0') )
+ if (GemRB.IsDualWielding(pc)):
+ stats.append ( (56911, tohit["Total"], '0') ) # main
+ stats.append ( (56910, GemRB.GetCombatDetails(pc, 1)["ToHitStats"]["Total"], '0') ) # offhand
+ else:
+ stats.append ( (9457, tohit["Total"], '0') )
+ else:
+ stats.append ( (9457, str(tohit["Base"])+" ("+str(tohit["Total"])+")", '0') )
+
+ tmp = cdet["APR"]
+ if (tmp&1):
+ tmp2 = str (tmp/2) + chr (189) #must use one higher than the frame count
+ else:
+ tmp2 = str (tmp/2)
+ stats.append ( (9458, tmp2, '') )
+ stats.append ( (9459, GSNN (pc, IE_LORE), '0') )
+ if GUICommon.GameIsBG1() or GUICommon.GameIsIWD1():
+ stats.append ( (19224, GS (IE_RESISTMAGIC), '') )
+
+ # party's reputation
+ reptxt = GetReputation (GemRB.GameGetReputation ()/10)
+ stats.append ( (9465, reptxt, '') )
+ stats.append ( (9460, GSNN (pc, IE_LOCKPICKING), '') )
+ stats.append ( (9462, GSNN (pc, IE_TRAPS), '') )
+ stats.append ( (9463, GSNN (pc, IE_PICKPOCKET), '') )
+ stats.append ( (9461, GSNN (pc, IE_STEALTH), '') )
+ HatedRace = GS (IE_HATEDRACE)
+ if HatedRace:
+ HateTable = GemRB.LoadTable ("haterace")
+ Racist = HateTable.FindValue (1, HatedRace)
+ if Racist != -1:
+ HatedRace = HateTable.GetValue (Racist, 0)
+ stats.append ( (15982, GemRB.GetString (HatedRace), '') )
+
+ # these skills were new in bg2
+ if GUICommon.GameIsBG2() or GUICommon.GameIsIWD1():
+ stats.append ( (34120, GSNN (pc, IE_HIDEINSHADOWS), '') )
+ stats.append ( (34121, GSNN (pc, IE_DETECTILLUSIONS), '') )
+ stats.append ( (34122, GSNN (pc, IE_SETTRAPS), '') )
+ stats.append ( (12128, GS (IE_BACKSTABDAMAGEMULTIPLIER), 'x') )
+ stats.append ( (12126, GS (IE_TURNUNDEADLEVEL), '') )
+
+ #this hack only displays LOH if we know the spell
+ #TODO: the core should just not set LOH if the paladin can't learn it
+ if (Spellbook.HasSpell (pc, IE_SPELL_TYPE_INNATE, 0, "SPCL211") >= 0):
+ stats.append ( (12127, GS (IE_LAYONHANDSAMOUNT), '') )
+
+ #script
+ aiscript = GemRB.GetPlayerScript (pc )
+ stats.append ( (2078, aiscript, '') )
+ stats.append (None)
+
+ # 17379 Saving throws
+ stats.append (17379)
+ # 17380 Paralyze/Poison/Death
+ stats.append ( (17380, IE_SAVEVSDEATH, 's') )
+ # 17381 Rod/Staff/Wand
+ stats.append ( (17381, IE_SAVEVSWANDS, 's') )
+ # 17382 Petrify/Polymorph
+ stats.append ( (17382, IE_SAVEVSPOLY, 's') )
+ # 17383 Breath weapon
+ stats.append ( (17383, IE_SAVEVSBREATH, 's') )
+ # 17384 Spells
+ stats.append ( (17384, IE_SAVEVSSPELL, 's') )
+ stats.append (None)
+
+ # 9466 Weapon proficiencies
+ stats.append (9466)
+ table = GemRB.LoadTable ("weapprof")
+ RowCount = table.GetRowCount ()
+ # the first 7 profs are foobared (bg1 style)
+ if GUICommon.GameIsBG2():
+ offset = 8
+ else:
+ offset = 0
+ for i in range (offset, RowCount):
+ # iwd displays capitalised strings
+ # FIXME: ignore it and do the capitalisation manually, so it works for everyone
+ if GUICommon.GameIsIWD1():
+ text = table.GetValue (i, 3)
+ else:
+ text = table.GetValue (i, 1)
+ stat = table.GetValue (i, 0)
+ if not offset and not GUICommon.GameIsIWD1(): # TODO: fishy, recheck
+ stat = stat + IE_PROFICIENCYBASTARDSWORD
+ stats.append ( (text, GS (stat)&0x07, '+') )
+ stats.append (None)
+
+ # 11766 AC Bonuses
+ stats.append (11766)
+ # 11770 AC vs. Crushing
+ stats.append ((11770, GS (IE_ACCRUSHINGMOD), 'p'))
+ # 11767 AC vs. Missile
+ stats.append ((11767, GS (IE_ACMISSILEMOD), 'p'))
+ # 11769 AC vs. Piercing
+ stats.append ((11769, GS (IE_ACPIERCINGMOD), 'p'))
+ # 11768 AC vs. Slashing
+ stats.append ((11768, GS (IE_ACSLASHINGMOD), 'p'))
+ stats.append (None)
+
+ # 10315 Ability bonuses
+ stats.append (10315)
+ value = GemRB.GetPlayerStat (pc, IE_STR)
+ ex = GemRB.GetPlayerStat (pc, IE_STREXTRA)
+ # 10332 to hit
+ stats.append ( (10332, GemRB.GetAbilityBonus (IE_STR,0,value,ex), 'p') )
+ # 10336 damage
+ stats.append ( (10336, GemRB.GetAbilityBonus (IE_STR,1,value,ex), 'p') )
+ # 10337 open doors (bend bars lift gates)
+ stats.append ( (10337, GemRB.GetAbilityBonus (IE_STR,2,value,ex), '0') )
+ # 10338 weight allowance
+ stats.append ( (10338, GemRB.GetAbilityBonus (IE_STR,3,value,ex), '0') )
+ # 10339 AC
+ stats.append ( (10339, GA (IE_DEX,2), '0') )
+ # 10340 Missile adjustment
+ stats.append ( (10340, GA (IE_DEX,1), 'p') )
+ # 10341 Reaction adjustment
+ stats.append ( (10341, GA (IE_DEX,0), 'p') )
+ # 10342 CON HP Bonus/Level
+ # dual-classed chars get no bonus while the primary class is inactive
+ # and the new class' bonus afterwards
+ # single- and multi-classed chars are straightforward - the highest class bonus counts
+ if GUICommon.IsWarrior (pc):
+ stats.append ( (10342, GA (IE_CON, 1), 'p') )
+ else:
+ stats.append ( (10342, GA (IE_CON, 0), 'p') )
+ # 10343 Chance To Learn spell
+ if GemRB.GetMemorizableSpellsCount (pc, IE_SPELL_TYPE_WIZARD, 0, 0)>0:
+ stats.append ( (10343, GA (IE_INT,0), '%' ) )
+ # 10347 Reaction
+ stats.append ( (10347, GA (IE_REPUTATION,0), '0') )
+ stats.append (None)
+
+ # 10344 Bonus Priest spells
+ if GemRB.GetMemorizableSpellsCount (pc, IE_SPELL_TYPE_PRIEST, 0, 0)>0:
+ stats.append (10344)
+ for level in range (7):
+ GemRB.SetToken ("SPELLLEVEL", str (level+1) )
+ #get the bonus spell count
+ base = GemRB.GetMemorizableSpellsCount (pc, IE_SPELL_TYPE_PRIEST, level, 0)
+ if base:
+ count = GemRB.GetMemorizableSpellsCount (pc, IE_SPELL_TYPE_PRIEST, level)
+ stats.append ( (GemRB.GetString (10345), count-base, 'r') )
+ stats.append (None)
+
+ # only bg2 displayed all the resistances, but it is useful information
+ # Resistances
+ if GUICommon.GameIsBG2():
+ stats.append(32204)
+ elif not GUICommon.GameIsBG1():
+ stats.append (15544)
+ # 32213 Normal Fire
+ # 32222 Magic Fire
+ # 32214 Normal Cold
+ # 32223 Magic Cold
+ if GUICommon.GameIsBG2():
+ stats.append ((32213, GS (IE_RESISTFIRE), '%'))
+ stats.append ((32222, GS (IE_RESISTMAGICFIRE), '%'))
+ stats.append ((32214, GS (IE_RESISTCOLD), '%'))
+ stats.append ((32223, GS (IE_RESISTMAGICCOLD), '%'))
+ elif GUICommon.GameIsBG1():
+ stats.append ((14012, GS (IE_RESISTFIRE), '%'))
+ stats.append ((14077, GS (IE_RESISTMAGICFIRE), '%'))
+ stats.append ((14014, GS (IE_RESISTCOLD), '%'))
+ stats.append ((14078, GS (IE_RESISTMAGICCOLD), '%'))
+ else:
+ stats.append ((15545, GS (IE_RESISTFIRE), '%'))
+ stats.append ((15579, GS (IE_RESISTMAGICFIRE), '%'))
+ stats.append ((15546, GS (IE_RESISTCOLD), '%'))
+ stats.append ((15580, GS (IE_RESISTMAGICCOLD), '%'))
+ # 32220 Electricity
+ if GUICommon.GameIsBG1() or GUICommon.GameIsIWD1():
+ stats.append ((14013, GS (IE_RESISTELECTRICITY), '%'))
+ else:
+ stats.append ((32220, GS (IE_RESISTELECTRICITY), '%'))
+ # 32221 Acid
+ if GUICommon.GameIsBG1():
+ stats.append ((14015, GS (IE_RESISTACID), '%'))
+ else:
+ stats.append ((32221, GS (IE_RESISTACID), '%'))
+ if GUICommon.GameIsBG2():
+ # Magic (others show it higher up)
+ stats.append ((62146, GS (IE_RESISTMAGIC), '%'))
+ # Magic Damage
+ if GUICommon.GameIsIWD2():
+ stats.append ((40319, GS (IE_MAGICDAMAGERESISTANCE), '%'))
+ else: # bg2
+ stats.append ((32233, GS (IE_MAGICDAMAGERESISTANCE), '%'))
+ # Missile
+ stats.append ((11767, GS (IE_RESISTMISSILE), '%'))
+ # Slashing
+ stats.append ((11768, GS (IE_RESISTSLASHING), '%'))
+ # Piercing
+ stats.append ((11769, GS (IE_RESISTPIERCING), '%'))
+ # Crushing
+ stats.append ((11770, GS (IE_RESISTCRUSHING), '%'))
+ # Poison
+ stats.append ((14017, GS (IE_RESISTPOISON), '%'))
+ stats.append (None)
+
+ if GUICommon.GameIsBG2():
+ # Weapon Style bonuses
+ stats.append (32131)
+ wstyle = cdet["Style"] # equipped weapon style + 1000 * proficiency level
+ profcount = wstyle / 1000
+ if profcount:
+ wstyletables = { IE_PROFICIENCY2WEAPON:"wstwowpn", IE_PROFICIENCY2HANDED:"wstwohnd", IE_PROFICIENCYSINGLEWEAPON:"wssingle", IE_PROFICIENCYSWORDANDSHIELD:"wsshield" }
+ bonusrefs = { "THAC0BONUSRIGHT":56911, "THAC0BONUSLEFT":56910, "DAMAGEBONUS":10336, "CRITICALHITBONUS":32140, "PHYSICALSPEED":32141, "AC":10339, "ACVSMISSLE":10340 }
+ WStyleTable = GemRB.LoadTable (wstyletables[wstyle%1000])
+ for col in range(WStyleTable.GetColumnCount()):
+ value = WStyleTable.GetValue (profcount, col)
+ stats.append ((bonusrefs[WStyleTable.GetColumnName(col)], value, ''))
+ stats.append (None)
+
+ res = []
+ lines = 0
+ for s in stats:
+ try:
+ strref, val, type = s
+ if val == 0 and type != '0':
+ continue
+ if type == '+': #pluses
+ res.append ("[capital=0]"+GemRB.GetString (strref) + ' '+ '+' * val)
+ elif type == 'p': #a plus prefix if positive
+ if val > 0:
+ res.append ("[capital=0]" + GemRB.GetString (strref) + ' +' + str (val) )
+ else:
+ res.append ("[capital=0]" + GemRB.GetString (strref) + ' ' + str (val) )
+ elif type == 'r': #a plus prefix if positive, strref is an already resolved string
+ if val > 0:
+ res.append ("[capital=0]" + strref + ' +' + str (val) )
+ else:
+ res.append ("[capital=0]" + strref + ' ' + str (val) )
+ elif type == 's': #both base and (modified) stat, but only if they differ
+ base = GB (val)
+ stat = GS (val)
+ base_str = "[capital=0]" + GemRB.GetString (strref) + ': ' + str(stat)
+ if base == stat:
+ res.append (base_str)
+ else:
+ res.append (base_str + " (" + str(stat-base) + ")")
+ elif type == 'x': #x character before value
+ res.append ("[capital=0]"+GemRB.GetString (strref) +': x' + str (val) )
+ elif type == 'a': #value (portrait icon) + string
+ res.append ("[capital=2]"+val+" "+GemRB.GetString (strref))
+ elif type == 'b': #strref is an already resolved string
+ res.append ("[capital=0]"+strref+": "+str (val))
+ elif type == 'c': #normal string
+ res.append ("[capital=0]"+GemRB.GetString (strref))
+ elif type == 'd': #strref is an already resolved string
+ res.append ("[capital=0]"+strref)
+ elif type == '0': #normal value
+ res.append (GemRB.GetString (strref) + ': ' + str (val))
+ else: #normal value + type character, for example percent sign
+ res.append ("[capital=0]"+GemRB.GetString (strref) + ': ' + str (val) + type)
+ lines = 1
+ except:
+ if s != None:
+ res.append ("[capital=0]"+ GemRB.GetString (s) )
+ lines = 0
+ else:
+ if not lines and str_None != -1:
+ res.append (str_None)
+ res.append ("")
+ lines = 0
+
+ return "\n".join (res)
+
+def GetReputation (repvalue):
+ table = GemRB.LoadTable ("reptxt")
+ if repvalue>20:
+ repvalue=20
+ txt = GemRB.GetString (table.GetValue (repvalue, 0) )
+ return txt+" ("+str (repvalue)+")"
+
+def OpenInformationWindow ():
+ global InformationWindow
+
+ if InformationWindow != None:
+ GUIRECCommon.CloseBiographyWindow ()
+ CloseInformationWindow ()
+ return
+
+ InformationWindow = Window = GemRB.LoadWindow (4)
+
+ # Biography
+ Button = Window.GetControl (26)
+ Button.SetText (18003)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIRECCommon.OpenBiographyWindow)
+
+ # Done
+ Button = Window.GetControl (24)
+ Button.SetText (11973)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseInformationWindow)
+ Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+
+ TotalPartyExp = 0
+ ChapterPartyExp = 0
+ TotalPartyKills = 0
+ ChapterCount = 0
+ for i in range (1, GemRB.GetPartySize () + 1):
+ stat = GemRB.GetPCStats(i)
+ TotalPartyExp = TotalPartyExp + stat['KillsTotalXP']
+ ChapterPartyExp = ChapterPartyExp + stat['KillsChapterXP']
+ TotalPartyKills = TotalPartyKills + stat['KillsTotalCount']
+ ChapterCount = ChapterCount + stat['KillsChapterCount']
+
+ # These are used to get the stats
+ pc = GemRB.GameGetSelectedPCSingle ()
+ stat = GemRB.GetPCStats (pc)
+
+ Label = Window.GetControl (0x10000000)
+ Label.SetText (GemRB.GetPlayerName (pc, 1))
+ # class
+ ClassTitle = GUICommon.GetActorClassTitle (pc)
+ Label = Window.GetControl (0x10000018)
+ Label.SetText (ClassTitle)
+
+ #most powerful vanquished
+ Label = Window.GetControl (0x10000005)
+ #we need getstring, so -1 will translate to empty string
+ Label.SetText (GemRB.GetString (stat['BestKilledName']))
+
+ Label = Window.GetControl (0x10000006)
+ GUICommon.SetCurrentDateTokens (stat)
+ #actually it is 16043 <DURATION>, but duration is translated to
+ #16041, hopefully this won't cause problem with international version
+ Label.SetText (16041)
+
+ #favourite spell
+ Label = Window.GetControl (0x10000007)
+ Label.SetText (stat['FavouriteSpell'])
+
+ #favourite weapon
+ Label = Window.GetControl (0x10000008)
+ #actually it is 10479 <WEAPONNAME>, but weaponname is translated to
+ #the real weapon name (which we should set using SetToken)
+ #there are other strings like bow+wname/xbow+wname/sling+wname
+ #are they used?
+ Label.SetText (stat['FavouriteWeapon'])
+
+ #total party xp
+ Label = Window.GetControl (0x10000013)
+ if TotalPartyExp != 0:
+ PartyExp = int ((stat['KillsTotalXP'] * 100) / TotalPartyExp)
+ Label.SetText (str (PartyExp) + '%')
+ else:
+ Label.SetText ("0%")
+
+ # chapter party xp
+ Label = Window.GetControl (0x1000000f)
+ if ChapterPartyExp != 0:
+ PartyExp = int ((stat['KillsChapterXP'] * 100) / ChapterPartyExp)
+ Label.SetText (str (PartyExp) + '%')
+ else:
+ Label.SetText ("0%")
+
+ # total kills
+ Label = Window.GetControl (0x10000014)
+ if TotalPartyKills != 0:
+ PartyKills = int ((stat['KillsTotalCount'] * 100) / TotalPartyKills)
+ Label.SetText (str (PartyKills) + '%')
+ else:
+ Label.SetText ("0%")
+
+ # chapter kills
+ Label = Window.GetControl (0x10000010)
+ if ChapterCount != 0:
+ PartyKills = int ((stat['KillsChapterCount'] * 100) / ChapterCount)
+ Label.SetText (str (PartyKills) + '%')
+ else:
+ Label.SetText ("0%")
+
+ Label = Window.GetControl (0x10000011)
+ Label.SetText (str (stat['KillsChapterXP']))
+ Label = Window.GetControl (0x10000015)
+ Label.SetText (str (stat['KillsTotalXP']))
+
+ #count of kills in chapter/game
+ Label = Window.GetControl (0x10000012)
+ Label.SetText (str (stat['KillsChapterCount']))
+ Label = Window.GetControl (0x10000016)
+ Label.SetText (str (stat['KillsTotalCount']))
+
+ Window.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def CloseInformationWindow ():
+ import GUICommonWindows
+ global InformationWindow
+
+ if InformationWindow:
+ InformationWindow.Unload ()
+ InformationWindow = None
+
+ OptionsWindow.SetVisible (WINDOW_VISIBLE)
+ RecordsWindow.SetVisible (WINDOW_VISIBLE)
+ PortraitWindow.SetVisible (WINDOW_VISIBLE)
+ return
+
+def OpenKitInfoWindow ():
+ global KitInfoWindow
+
+ KitInfoWindow = GemRB.LoadWindow (24)
+
+ #back button (setting first, to be less error prone)
+ DoneButton = KitInfoWindow.GetControl (2)
+ DoneButton.SetText (11973)
+ DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, KitDonePress)
+
+ #kit or class description
+ TextArea = KitInfoWindow.GetControl (0)
+
+ pc = GemRB.GameGetSelectedPCSingle ()
+ ClassName = GUICommon.GetClassRowName (pc)
+ Multi = GUICommon.HasMultiClassBits (pc)
+ Dual = GUICommon.IsDualClassed (pc, 1)
+
+ if Multi and Dual[0] == 0: # true multi class
+ text = CommonTables.Classes.GetValue (ClassName, "DESC_REF")
+ TextArea.SetText (text)
+ KitInfoWindow.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+ KitIndex = GUICommon.GetKitIndex (pc)
+
+ if Dual[0]: # dual class
+ # first (previous) kit or class of the dual class
+ if Dual[0] == 1:
+ text = CommonTables.KitList.GetValue (Dual[1], 3)
+ elif Dual[0] == 2:
+ text = GUICommon.GetClassRowName(Dual[1], "index")
+ text = CommonTables.Classes.GetValue (text, "DESC_REF")
+
+ TextArea.SetText (text)
+ TextArea.Append ("\n\n")
+ text = GUICommon.GetClassRowName(Dual[2], "index")
+ text = CommonTables.Classes.GetValue (text, "DESC_REF")
+
+ else: # ordinary class or kit
+ if KitIndex:
+ text = CommonTables.KitList.GetValue (KitIndex, 3)
+ else:
+ text = CommonTables.Classes.GetValue (ClassName, "DESC_REF")
+
+ TextArea.Append (text)
+
+ KitInfoWindow.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def KitDonePress():
+ if KitInfoWindow:
+ KitInfoWindow.Unload()
+ return
+
+def OpenColorWindow ():
+ global PortraitWindow
+ global PaperdollButton
+ global HairButton, SkinButton, MajorButton, MinorButton
+ global HairColor, SkinColor, MajorColor, MinorColor
+
+ pc = GemRB.GameGetSelectedPCSingle ()
+ MinorColor = GemRB.GetPlayerStat (pc, IE_MINOR_COLOR)
+ MajorColor = GemRB.GetPlayerStat (pc, IE_MAJOR_COLOR)
+ SkinColor = GemRB.GetPlayerStat (pc, IE_SKIN_COLOR)
+ HairColor = GemRB.GetPlayerStat (pc, IE_HAIR_COLOR)
+ GUIRECCommon.SubCustomizeWindow = GemRB.LoadWindow (21)
+
+ PaperdollButton = GUIRECCommon.SubCustomizeWindow.GetControl (0)
+ PaperdollButton.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_NO_IMAGE,OP_SET)
+ PaperdollButton.SetState (IE_GUI_BUTTON_LOCKED)
+
+ HairButton = GUIRECCommon.SubCustomizeWindow.GetControl (3)
+ SkinButton = GUIRECCommon.SubCustomizeWindow.GetControl (4)
+ MajorButton = GUIRECCommon.SubCustomizeWindow.GetControl (5)
+ MinorButton = GUIRECCommon.SubCustomizeWindow.GetControl (6)
+
+ DoneButton = GUIRECCommon.SubCustomizeWindow.GetControl (12)
+ DoneButton.SetText (11973)
+ DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
+
+ CancelButton = GUIRECCommon.SubCustomizeWindow.GetControl (13)
+ CancelButton.SetText (13727)
+ CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+
+ HairButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, SetHairColor)
+ SkinButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, SetSkinColor)
+ MajorButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, SetMajorColor)
+ MinorButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, SetMinorColor)
+ DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DoneColorWindow)
+ CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIRECCommon.CloseSubCustomizeWindow)
+ UpdatePaperDoll ()
+
+ GUIRECCommon.SubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def DoneColorWindow ():
+ pc = GemRB.GameGetSelectedPCSingle ()
+ GemRB.SetPlayerStat (pc, IE_MINOR_COLOR, MinorColor)
+ GemRB.SetPlayerStat (pc, IE_MAJOR_COLOR, MajorColor)
+ GemRB.SetPlayerStat (pc, IE_SKIN_COLOR, SkinColor)
+ GemRB.SetPlayerStat (pc, IE_HAIR_COLOR, HairColor)
+ GUIRECCommon.CloseSubCustomizeWindow ()
+ return
+
+def UpdatePaperDoll ():
+ pc = GemRB.GameGetSelectedPCSingle ()
+ Color1 = GemRB.GetPlayerStat (pc, IE_METAL_COLOR)
+ MinorButton.SetBAM ("COLGRAD", 0, 0, MinorColor&0xff)
+ MajorButton.SetBAM ("COLGRAD", 0, 0, MajorColor&0xff)
+ SkinButton.SetBAM ("COLGRAD", 0, 0, SkinColor&0xff)
+ Color5 = GemRB.GetPlayerStat (pc, IE_LEATHER_COLOR)
+ Color6 = GemRB.GetPlayerStat (pc, IE_ARMOR_COLOR)
+ HairButton.SetBAM ("COLGRAD", 0, 0, HairColor&0xff)
+ PaperdollButton.SetPLT (GUICommon.GetActorPaperDoll (pc),
+ Color1, MinorColor, MajorColor, SkinColor, Color5, Color6, HairColor, 0, 0)
+ return
+
+def SetHairColor ():
+ global ColorIndex, PickedColor
+
+ ColorIndex = 0
+ PickedColor = HairColor
+ OpenColorPicker ()
+ return
+
+def SetSkinColor ():
+ global ColorIndex, PickedColor
+
+ ColorIndex = 1
+ PickedColor = SkinColor
+ OpenColorPicker ()
+ return
+
+def SetMinorColor ():
+ global ColorIndex, PickedColor
+
+ ColorIndex = 2
+ PickedColor = MinorColor
+ OpenColorPicker ()
+ return
+
+def SetMajorColor ():
+ global ColorIndex, PickedColor
+
+ ColorIndex = 3
+ PickedColor = MajorColor
+ OpenColorPicker ()
+ return
+
+def OpenColorPicker ():
+ GUIRECCommon.SubSubCustomizeWindow = GemRB.LoadWindow (22)
+
+ GemRB.SetVar ("Selected",-1)
+ for i in range (1,35):
+ Button = GUIRECCommon.SubSubCustomizeWindow.GetControl (i)
+ Button.SetState (IE_GUI_BUTTON_LOCKED)
+ Button.SetFlags (IE_GUI_BUTTON_PICTURE,OP_OR)
+
+ for i in range (34):
+ MyColor = ColorTable.GetValue (ColorIndex, i)
+ if MyColor == "*":
+ break
+ Button = GUIRECCommon.SubSubCustomizeWindow.GetControl (i+1)
+ Button.SetBAM("COLGRAD", 2, 0, MyColor)
+ if PickedColor == MyColor:
+ GemRB.SetVar ("Selected",i)
+ Button.SetState (IE_GUI_BUTTON_ENABLED)
+ Button.SetVarAssoc("Selected",i)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, DonePress)
+
+ GUIRECCommon.SubSubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def DonePress():
+ global HairColor, SkinColor, MajorColor, MinorColor
+ global PickedColor
+
+ GUIRECCommon.CloseSubSubCustomizeWindow ()
+ PickedColor=ColorTable.GetValue (ColorIndex, GemRB.GetVar ("Selected"))
+ if ColorIndex==0:
+ HairColor=PickedColor
+ UpdatePaperDoll ()
+ return
+ if ColorIndex==1:
+ SkinColor=PickedColor
+ UpdatePaperDoll ()
+ return
+ if ColorIndex==2:
+ MinorColor=PickedColor
+ UpdatePaperDoll ()
+ return
+
+ MajorColor=PickedColor
+ UpdatePaperDoll ()
+ return
+
+###################################################
+# End of file GUIREC.py
diff --git a/gemrb/GUIScripts/GUIRECCommon.py b/gemrb/GUIScripts/GUIRECCommon.py
new file mode 100644
index 0000000..29536a6
--- /dev/null
+++ b/gemrb/GUIScripts/GUIRECCommon.py
@@ -0,0 +1,632 @@
+# -*-python-*-
+# GemRB - Infinity Engine Emulator
+# Copyright (C) 2011 The GemRB Project
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# code shared between the common GUIREC and that of iwd2 (pst)
+import GemRB
+import GUICommon
+import Portrait
+from GUIDefines import *
+from ie_stats import IE_SEX, IE_CLASS, IE_MC_FLAGS, MC_EXPORTABLE
+from ie_restype import RES_WAV
+
+BiographyWindow = None
+CustomizeWindow = None
+SubCustomizeWindow = None
+SubSubCustomizeWindow = None
+ExportWindow = None
+NameField = ExportDoneButton = None
+ScriptsTable = None
+
+if GUICommon.GameIsBG2() or GUICommon.GameIsBG1():
+ BioStrRefSlot = 74
+else:
+ BioStrRefSlot = 63
+
+if GUICommon.GameIsBG2() or GUICommon.GameIsIWD2():
+ PortraitNameSuffix = "L"
+else:
+ PortraitNameSuffix = "G"
+
+PortraitPictureButton = None
+PortraitList1 = PortraitList2 = RowCount1 = RowCount2 = None
+
+# the available sounds
+if GUICommon.GameIsIWD1() or GUICommon.GameIsIWD2():
+ SoundSequence = [ '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', \
+ '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', \
+ '25', '26', '27', '28', '29', '30', '31']
+else:
+ SoundSequence = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', \
+ 'm', 's', 't', 'u', 'v', '_', 'x', 'y', 'z', '0', '1', '2', \
+ '3', '4', '5', '6', '7', '8', '9']
+SoundIndex = 0
+VoiceList = None
+OldVoiceSet = None
+Gender = None
+
+def OpenCustomizeWindow ():
+ import GUIREC
+ global CustomizeWindow, ScriptsTable, Gender
+
+ pc = GemRB.GameGetSelectedPCSingle ()
+ if GemRB.GetPlayerStat (pc, IE_MC_FLAGS)&MC_EXPORTABLE:
+ Exportable = 1
+ else:
+ Exportable = 0
+
+ ScriptsTable = GemRB.LoadTable ("SCRPDESC")
+ GUIREC.ColorTable = GemRB.LoadTable ("CLOWNCOL")
+ Gender = GemRB.GetPlayerStat (pc, IE_SEX)
+ CustomizeWindow = GemRB.LoadWindow (17)
+
+ PortraitSelectButton = CustomizeWindow.GetControl (0)
+ PortraitSelectButton.SetText (11961)
+ if not Exportable:
+ PortraitSelectButton.SetState (IE_GUI_BUTTON_DISABLED)
+
+ SoundButton = CustomizeWindow.GetControl (1)
+ SoundButton.SetText (10647)
+ if not Exportable:
+ SoundButton.SetState (IE_GUI_BUTTON_DISABLED)
+
+ if not GUICommon.GameIsIWD2():
+ ColorButton = CustomizeWindow.GetControl (2)
+ ColorButton.SetText (10646)
+ ColorButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIREC.OpenColorWindow)
+ if not Exportable:
+ ColorButton.SetState (IE_GUI_BUTTON_DISABLED)
+
+ ScriptButton = CustomizeWindow.GetControl (3)
+ ScriptButton.SetText (17111)
+
+ #This button does not exist in bg1 and pst, but theoretically we could create it here
+ if not (GUICommon.GameIsBG1() or GUICommon.GameIsPST()):
+ BiographyButton = CustomizeWindow.GetControl (9)
+ BiographyButton.SetText (18003)
+ BiographyButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenBiographyEditWindow)
+ if not Exportable:
+ BiographyButton.SetState (IE_GUI_BUTTON_DISABLED)
+
+ TextArea = CustomizeWindow.GetControl (5)
+ TextArea.SetText (11327)
+
+ CustomizeDoneButton = CustomizeWindow.GetControl (7)
+ CustomizeDoneButton.SetText (11973)
+ CustomizeDoneButton.SetState (IE_GUI_BUTTON_ENABLED)
+
+ CancelButton = CustomizeWindow.GetControl (8)
+ CancelButton.SetText (13727)
+ CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+
+ PortraitSelectButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenPortraitSelectWindow)
+ SoundButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenSoundWindow)
+ ScriptButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenScriptWindow)
+ CustomizeDoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CustomizeDonePress)
+ CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CustomizeCancelPress)
+
+ CustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def CustomizeDonePress ():
+ CloseCustomizeWindow ()
+ return
+
+def CustomizeCancelPress ():
+ CloseCustomizeWindow ()
+ return
+
+def CloseCustomizeWindow ():
+ import GUIREC
+ global CustomizeWindow
+ if CustomizeWindow:
+ CustomizeWindow.Unload ()
+ CustomizeWindow = None
+ GUIREC.UpdateRecordsWindow ()
+ return
+
+def OpenPortraitSelectWindow ():
+ global PortraitPictureButton, SubCustomizeWindow
+
+ SubCustomizeWindow = GemRB.LoadWindow (18)
+
+ PortraitPictureButton = SubCustomizeWindow.GetControl (0)
+ PortraitPictureButton.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_NO_IMAGE,OP_SET)
+ PortraitPictureButton.SetState (IE_GUI_BUTTON_LOCKED)
+
+ PortraitLeftButton = SubCustomizeWindow.GetControl (1)
+ PortraitLeftButton.SetState (IE_GUI_BUTTON_ENABLED)
+ PortraitLeftButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, PortraitLeftPress)
+
+ PortraitRightButton = SubCustomizeWindow.GetControl (2)
+ PortraitRightButton.SetState (IE_GUI_BUTTON_ENABLED)
+ PortraitRightButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, PortraitRightPress)
+
+ PortraitDoneButton = SubCustomizeWindow.GetControl (3)
+ PortraitDoneButton.SetState (IE_GUI_BUTTON_ENABLED)
+ PortraitDoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, PortraitDonePress)
+ PortraitDoneButton.SetText (11973)
+ PortraitDoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
+
+ PortraitCancelButton = SubCustomizeWindow.GetControl (4)
+ PortraitCancelButton.SetState (IE_GUI_BUTTON_ENABLED)
+ PortraitCancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSubCustomizeWindow)
+ PortraitCancelButton.SetText (13727)
+ PortraitCancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+
+ PortraitCustomButton = SubCustomizeWindow.GetControl (5)
+ PortraitCustomButton.SetState (IE_GUI_BUTTON_ENABLED)
+ PortraitCustomButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenCustomPortraitWindow)
+ PortraitCustomButton.SetText (17545)
+
+ # get players gender and portrait
+ Pc = GemRB.GameGetSelectedPCSingle ()
+ PcPortrait = GemRB.GetPlayerPortrait(Pc,0)
+
+ # initialize and set portrait
+ Portrait.Init (Gender)
+ Portrait.Set (PcPortrait)
+ PortraitPictureButton.SetPicture (Portrait.Name () + PortraitNameSuffix, "NOPORTLG")
+
+ SubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def PortraitDonePress ():
+ pc = GemRB.GameGetSelectedPCSingle ()
+ # eh, different sizes
+ if GUICommon.GameIsBG2():
+ GemRB.FillPlayerInfo (pc, Portrait.Name () + "M", Portrait.Name () + "S")
+ else:
+ GemRB.FillPlayerInfo (pc, Portrait.Name () + "L", Portrait.Name () + "S")
+ CloseSubCustomizeWindow ()
+ return
+
+def PortraitLeftPress ():
+ global PortraitPictureButton
+
+ PortraitPictureButton.SetPicture (Portrait.Previous () + PortraitNameSuffix, "NOPORTLG")
+
+def PortraitRightPress ():
+ global PortraitPictureButton
+
+ PortraitPictureButton.SetPicture (Portrait.Next () + PortraitNameSuffix, "NOPORTLG")
+
+def OpenCustomPortraitWindow ():
+ global SubSubCustomizeWindow
+ global PortraitList1, PortraitList2
+ global RowCount1, RowCount2
+
+ SubSubCustomizeWindow = GemRB.LoadWindow (19)
+
+ CustomPortraitDoneButton = SubSubCustomizeWindow.GetControl (10)
+ CustomPortraitDoneButton.SetState (IE_GUI_BUTTON_DISABLED)
+ CustomPortraitDoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CustomPortraitDonePress)
+ CustomPortraitDoneButton.SetText (11973)
+ CustomPortraitDoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
+
+ CustomPortraitCancelButton = SubSubCustomizeWindow.GetControl (11)
+ CustomPortraitCancelButton.SetState (IE_GUI_BUTTON_ENABLED)
+ CustomPortraitCancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSubSubCustomizeWindow)
+ CustomPortraitCancelButton.SetText (13727)
+ CustomPortraitCancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+
+ if not GUICommon.GameIsIWD1():
+ SmallPortraitButton = SubSubCustomizeWindow.GetControl (1)
+ SmallPortraitButton.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_NO_IMAGE,OP_SET)
+ LargePortraitButton = SubSubCustomizeWindow.GetControl (0)
+ LargePortraitButton.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_NO_IMAGE,OP_SET)
+
+ # Portrait List Large
+ PortraitList1 = SubSubCustomizeWindow.GetControl (2)
+ RowCount1 = PortraitList1.GetPortraits (0)
+ PortraitList1.SetEvent (IE_GUI_TEXTAREA_ON_CHANGE, LargeCustomPortrait)
+ GemRB.SetVar ("Row1", RowCount1)
+ PortraitList1.SetVarAssoc ("Row1",RowCount1)
+
+ # Portrait List Small
+ PortraitList2 = SubSubCustomizeWindow.GetControl (3)
+ RowCount2 = PortraitList2.GetPortraits (1)
+ PortraitList2.SetEvent (IE_GUI_TEXTAREA_ON_CHANGE, SmallCustomPortrait)
+ GemRB.SetVar ("Row2", RowCount2)
+ PortraitList2.SetVarAssoc ("Row2",RowCount2)
+
+ SubSubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def CustomPortraitDonePress ():
+ pc = GemRB.GameGetSelectedPCSingle ()
+ GemRB.FillPlayerInfo (pc, PortraitList1.QueryText () , PortraitList2.QueryText ())
+
+ CloseSubSubCustomizeWindow ()
+ #closing the generic portraits, because we just set a custom one
+ CloseSubCustomizeWindow ()
+ return
+
+def LargeCustomPortrait ():
+ Window = SubSubCustomizeWindow
+
+ Portrait = PortraitList1.QueryText ()
+ #small hack
+ if GemRB.GetVar ("Row1") == RowCount1:
+ return
+
+ Label = Window.GetControl (0x10000007)
+ Label.SetText (Portrait)
+
+ Button = Window.GetControl (10)
+ if Portrait=="":
+ Portrait = "NOPORTMD"
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+ else:
+ if PortraitList2.QueryText ()!="":
+ Button.SetState (IE_GUI_BUTTON_ENABLED)
+
+ Button = Window.GetControl (0)
+ Button.SetPicture (Portrait, "NOPORTMD")
+ return
+
+def SmallCustomPortrait ():
+ Window = SubSubCustomizeWindow
+
+ Portrait = PortraitList2.QueryText ()
+ #small hack
+ if GemRB.GetVar ("Row2") == RowCount2:
+ return
+
+ Label = Window.GetControl (0x10000008)
+ Label.SetText (Portrait)
+
+ Button = Window.GetControl (10)
+ if Portrait=="":
+ Portrait = "NOPORTSM"
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+ else:
+ if PortraitList1.QueryText ()!="":
+ Button.SetState (IE_GUI_BUTTON_ENABLED)
+
+ Button = Window.GetControl (1)
+ Button.SetPicture (Portrait, "NOPORTSM")
+ return
+
+def OpenSoundWindow ():
+ global VoiceList, OldVoiceSet
+ global SubCustomizeWindow
+
+ pc = GemRB.GameGetSelectedPCSingle ()
+ OldVoiceSet = GemRB.GetPlayerSound (pc)
+ SubCustomizeWindow = GemRB.LoadWindow (20)
+
+ VoiceList = SubCustomizeWindow.GetControl (5)
+ VoiceList.SetFlags (IE_GUI_TEXTAREA_SELECTABLE)
+
+ VoiceList.SetVarAssoc ("Selected", 0)
+ VoiceList.GetCharSounds()
+ VoiceList.SelectText (OldVoiceSet)
+
+ PlayButton = SubCustomizeWindow.GetControl (7)
+ PlayButton.SetText (17318)
+
+ TextArea = SubCustomizeWindow.GetControl (8)
+ TextArea.SetText (11315)
+
+ DoneButton = SubCustomizeWindow.GetControl (10)
+ DoneButton.SetText (11973)
+ DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
+
+ CancelButton = SubCustomizeWindow.GetControl (11)
+ CancelButton.SetText (13727)
+ CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+
+ PlayButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, PlaySoundPressed)
+ DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DoneSoundWindow)
+ CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSoundWindow)
+
+ SubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def CloseSoundWindow ():
+ pc = GemRB.GameGetSelectedPCSingle ()
+ GemRB.SetPlayerSound (pc, OldVoiceSet)
+ CloseSubCustomizeWindow ()
+ return
+
+def DoneSoundWindow ():
+ pc = GemRB.GameGetSelectedPCSingle ()
+ CharSound = VoiceList.QueryText ()
+ GemRB.SetPlayerSound (pc, CharSound)
+
+ CloseSubCustomizeWindow ()
+ return
+
+def PlaySoundPressed():
+ global SoundIndex, SoundSequence
+
+ CharSound = VoiceList.QueryText ()
+ if GUICommon.GameIsIWD1() or GUICommon.GameIsIWD2():
+ pc = GemRB.GameGetSelectedPCSingle ()
+ GemRB.SetPlayerSound (pc, CharSound)
+ VoiceSet = GemRB.GetPlayerSound (pc, 1)
+ else:
+ VoiceSet = CharSound
+ tmp = SoundIndex
+ while (not GemRB.HasResource (VoiceSet + SoundSequence[SoundIndex], RES_WAV)):
+ NextSound()
+ if SoundIndex == tmp:
+ break
+ else:
+ NextSound()
+ GemRB.PlaySound (VoiceSet + SoundSequence[SoundIndex], 0, 0, 5)
+ return
+
+def NextSound():
+ global SoundIndex, SoundSequence
+ SoundIndex += 1
+ if SoundIndex >= len(SoundSequence):
+ SoundIndex = 0
+ return
+
+def OpenScriptWindow ():
+ global SubCustomizeWindow
+ global ScriptTextArea, SelectedTextArea
+
+ SubCustomizeWindow = GemRB.LoadWindow (11)
+
+ ScriptTextArea = SubCustomizeWindow.GetControl (2)
+ ScriptTextArea.SetFlags (IE_GUI_TEXTAREA_SELECTABLE)
+ FillScriptList ()
+ pc = GemRB.GameGetSelectedPCSingle ()
+ script = GemRB.GetPlayerScript (pc)
+ scriptindex = ScriptsTable.GetRowIndex (script)
+ GemRB.SetVar ("Selected", scriptindex)
+ ScriptTextArea.SetVarAssoc ("Selected", scriptindex)
+
+ SelectedTextArea = SubCustomizeWindow.GetControl (4)
+ UpdateScriptSelection ()
+
+ DoneButton = SubCustomizeWindow.GetControl (5)
+ DoneButton.SetText (11973)
+ DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
+
+ CancelButton = SubCustomizeWindow.GetControl (6)
+ CancelButton.SetText (13727)
+ CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+
+ DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DoneScriptWindow)
+ CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSubCustomizeWindow)
+ ScriptTextArea.SetEvent (IE_GUI_TEXTAREA_ON_CHANGE, UpdateScriptSelection)
+
+ SubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def FillScriptList ():
+ global ScriptTextArea
+
+ ScriptTextArea.Clear ()
+ row = ScriptsTable.GetRowCount ()
+ for i in range (row):
+ GemRB.SetToken ("script", ScriptsTable.GetRowName (i) )
+ title = ScriptsTable.GetValue (i,0)
+ if title!=-1:
+ desc = ScriptsTable.GetValue (i,1)
+ txt = GemRB.GetString (title)
+ if (desc!=-1):
+ txt += GemRB.GetString (desc)
+ ScriptTextArea.Append (txt+"\n", -1)
+ else:
+ ScriptTextArea.Append (ScriptsTable.GetRowName (i)+"\n" ,-1)
+ return
+
+def DoneScriptWindow ():
+ pc = GemRB.GameGetSelectedPCSingle ()
+ script = ScriptsTable.GetRowName (GemRB.GetVar ("Selected") )
+ GemRB.SetPlayerScript (pc, script)
+ CloseSubCustomizeWindow ()
+ return
+
+def UpdateScriptSelection():
+ text = ScriptTextArea.QueryText ()
+ SelectedTextArea.SetText (text)
+ return
+
+def RevertBiography():
+ global BioStrRef
+
+ if GUICommon.GameIsIWD2():
+ BioTable = GemRB.LoadTable ("bios")
+ pc = GemRB.GameGetSelectedPCSingle ()
+ Class = GemRB.GetPlayerStat (pc, IE_CLASS)
+ BioStrRef = BioTable.GetValue(Class,1) # TODO: check if it is really class ordered and what happens for multiclassed chars
+ else:
+ BioStrRef = 33347
+ TextArea.SetText (BioStrRef)
+ CloseSubCustomizeWindow ()
+ return
+
+def OpenBiographyEditWindow ():
+ global SubCustomizeWindow
+ global BioStrRef
+ global TextArea
+
+ Changed = 0
+ pc = GemRB.GameGetSelectedPCSingle ()
+ BioStrRef = GemRB.GetPlayerString (pc, BioStrRefSlot)
+ if BioStrRef != 33347:
+ Changed = 1
+
+ # TODO: check if this is really needed
+ if GUICommon.GameIsIWD1() or GUICommon.GameIsIWD2():
+ SubCustomizeWindow = GemRB.LoadWindow (51)
+ else:
+ SubCustomizeWindow = GemRB.LoadWindow (23)
+
+ ClearButton = SubCustomizeWindow.GetControl (5)
+ if GUICommon.GameIsBG2():
+ ClearButton.SetText (34881)
+ else:
+ ClearButton.SetText (18622)
+
+ DoneButton = SubCustomizeWindow.GetControl (1)
+ DoneButton.SetText (11973)
+ DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
+
+ if GUICommon.GameIsIWD1() or GUICommon.GameIsIWD2():
+ RevertButton = SubCustomizeWindow.GetControl (6)
+ else:
+ RevertButton = SubCustomizeWindow.GetControl (3)
+ RevertButton.SetText (2240)
+ if not Changed:
+ RevertButton.SetState (IE_GUI_BUTTON_DISABLED)
+
+ CancelButton = SubCustomizeWindow.GetControl (2)
+ CancelButton.SetText (13727)
+ CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+
+ TextArea = SubCustomizeWindow.GetControl (4)
+ TextArea.SetBufferLength (65535)
+ TextArea.SetText (BioStrRef)
+
+ ClearButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, ClearBiography)
+ DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DoneBiographyWindow)
+ RevertButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, RevertBiography)
+ CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSubCustomizeWindow)
+
+ SubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def ClearBiography():
+ pc = GemRB.GameGetSelectedPCSingle ()
+ BioStrRef = 62015+pc
+ #GemRB.CreateString (BioStrRef, "")
+ TextArea.SetText ("")
+ return
+
+def DoneBiographyWindow ():
+ global BioStrRef
+
+ #TODO set bio
+ pc = GemRB.GameGetSelectedPCSingle ()
+ #pc is 1 based
+ BioStrRef = 62015+pc
+ GemRB.CreateString (BioStrRef, TextArea.QueryText())
+ GemRB.SetPlayerString (pc, BioStrRefSlot, BioStrRef)
+ CloseSubCustomizeWindow ()
+ return
+
+def OpenBiographyWindow ():
+ global BiographyWindow
+
+ if BiographyWindow != None:
+ CloseBiographyWindow ()
+ return
+
+ BiographyWindow = Window = GemRB.LoadWindow (12)
+
+ TextArea = Window.GetControl (0)
+ pc = GemRB.GameGetSelectedPCSingle ()
+ TextArea.SetText (GemRB.GetPlayerString (pc, BioStrRefSlot) )
+
+ # Done
+ Button = Window.GetControl (2)
+ Button.SetText (11973)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseBiographyWindow)
+
+ Window.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def CloseBiographyWindow ():
+ import GUIREC
+ global BiographyWindow
+
+ if BiographyWindow:
+ BiographyWindow.Unload ()
+ BiographyWindow = None
+ # TODO: check if bg1 wouldn't benefit from modality too
+ if GUIREC.InformationWindow:
+ if GUICommon.GameIsBG2() or GUICommon.GameIsIWD1():
+ GUIREC.InformationWindow.ShowModal (MODAL_SHADOW_GRAY)
+ else:
+ GUIREC.InformationWindow.SetVisible (WINDOW_VISIBLE)
+ return
+
+def OpenExportWindow ():
+ global ExportWindow, NameField, ExportDoneButton
+
+ ExportWindow = GemRB.LoadWindow (13)
+
+ TextArea = ExportWindow.GetControl (2)
+ TextArea.SetText (10962)
+
+ TextArea = ExportWindow.GetControl (0)
+ TextArea.GetCharacters ()
+
+ ExportDoneButton = ExportWindow.GetControl (4)
+ ExportDoneButton.SetText (11973)
+ ExportDoneButton.SetState (IE_GUI_BUTTON_DISABLED)
+
+ CancelButton = ExportWindow.GetControl (5)
+ CancelButton.SetText (13727)
+ CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+
+ NameField = ExportWindow.GetControl (6)
+
+ ExportDoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, ExportDonePress)
+ CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, ExportCancelPress)
+ NameField.SetEvent (IE_GUI_EDIT_ON_CHANGE, ExportEditChanged)
+ ExportWindow.ShowModal (MODAL_SHADOW_GRAY)
+ NameField.SetStatus (IE_GUI_CONTROL_FOCUSED)
+ return
+
+def ExportDonePress():
+ #save file under name from EditControl
+ pc = GemRB.GameGetSelectedPCSingle ()
+ GemRB.SaveCharacter (pc, NameField.QueryText ())
+ if ExportWindow:
+ ExportWindow.Unload()
+ return
+
+def ExportCancelPress():
+ global ExportWindow
+ if ExportWindow:
+ ExportWindow.Unload()
+ ExportWindow = None
+ return
+
+def ExportEditChanged():
+ ExportFileName = NameField.QueryText ()
+ if ExportFileName == "":
+ ExportDoneButton.SetState (IE_GUI_BUTTON_DISABLED)
+ else:
+ ExportDoneButton.SetState (IE_GUI_BUTTON_ENABLED)
+ return
+
+def CloseSubCustomizeWindow ():
+ global SubCustomizeWindow, CustomizeWindow
+
+ if SubCustomizeWindow:
+ SubCustomizeWindow.Unload ()
+ SubCustomizeWindow = None
+ CustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def CloseSubSubCustomizeWindow ():
+ global SubSubCustomizeWindow, SubCustomizeWindow
+
+ if SubSubCustomizeWindow:
+ SubSubCustomizeWindow.Unload ()
+ SubSubCustomizeWindow = None
+ SubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
+ return
diff --git a/gemrb/GUIScripts/GUISAVE.py b/gemrb/GUIScripts/GUISAVE.py
new file mode 100644
index 0000000..822ef2c
--- /dev/null
+++ b/gemrb/GUIScripts/GUISAVE.py
@@ -0,0 +1,327 @@
+# -*-python-*-
+# GemRB - Infinity Engine Emulator
+# Copyright (C) 2003 The GemRB Project
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+
+# GUISAVE.py - Save window
+
+###################################################
+
+import GemRB
+import GUICommon
+import LoadScreen
+from GUIDefines import *
+
+SaveWindow = 0
+ConfirmWindow = 0
+NameField = 0
+SaveButton = 0
+TextAreaControl = 0
+Games = ()
+ScrollBar = 0
+# this lookup table is used only by bg2
+str_chapter = (48007, 48006, 16205, 16206, 16207, 16208, 16209, 71020, 71021, 71022)
+num_rows = 4
+ctrl_offset = (26, 30, 40, 0x10000008, 0x10000010)
+sav_version = 0
+
+def OpenSaveWindow ():
+ global SaveWindow, TextAreaControl, Games, ScrollBar
+ global num_rows, ctrl_offset, sav_version
+
+ if GUICommon.CloseOtherWindow (OpenSaveWindow):
+ CloseSaveWindow ()
+ return
+
+ GemRB.HideGUI ()
+ GUICommon.GameWindow.SetVisible(WINDOW_INVISIBLE)
+
+ if GUICommon.GameIsIWD2():
+ GemRB.LoadWindowPack ("GUISAVE", 800, 600)
+ num_rows = 5
+ ctrl_offset = (55, 60, 25, 0x10000005, 0x1000000a)
+ sav_version = 22
+ else:
+ GemRB.LoadWindowPack ("GUISAVE", 640, 480)
+ Window = SaveWindow = GemRB.LoadWindow (0)
+ Window.SetFrame ()
+ if GUICommon.GameIsIWD2():
+ CancelButton=Window.GetControl (22)
+ else:
+ CancelButton=Window.GetControl (34)
+ CancelButton.SetText (13727)
+ CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenSaveWindow)
+ CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+ GemRB.SetVar ("LoadIdx",0)
+
+ for i in range(num_rows):
+ Button = Window.GetControl (ctrl_offset[0]+i)
+ Button.SetText (15588)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SavePress)
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+ Button.SetVarAssoc ("LoadIdx",i)
+
+ Button = Window.GetControl (ctrl_offset[1]+i)
+ Button.SetText (13957)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, DeleteGamePress)
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+ Button.SetVarAssoc ("LoadIdx",i)
+
+ #area previews
+ Button = Window.GetControl (1+i)
+ Button.SetState (IE_GUI_BUTTON_LOCKED)
+ Button.SetFlags(IE_GUI_BUTTON_NO_IMAGE|IE_GUI_BUTTON_PICTURE,OP_SET)
+
+ #PC portraits
+ for j in range(PARTY_SIZE):
+ Button = Window.GetControl (ctrl_offset[2]+i*PARTY_SIZE+j)
+ Button.SetState (IE_GUI_BUTTON_LOCKED)
+ Button.SetFlags(IE_GUI_BUTTON_NO_IMAGE|IE_GUI_BUTTON_PICTURE,OP_SET)
+
+ if GUICommon.GameIsIWD2():
+ ScrollBar=Window.GetControl (23)
+ else:
+ ScrollBar=Window.GetControl (25)
+ ScrollBar.SetEvent (IE_GUI_SCROLLBAR_ON_CHANGE, ScrollBarPress)
+ Games=GemRB.GetSaveGames ()
+ TopIndex = max (0, len(Games) - num_rows + 1) #one more for the 'new game'
+ GemRB.SetVar ("TopIndex",TopIndex)
+ ScrollBar.SetVarAssoc ("TopIndex", TopIndex+1)
+ ScrollBar.SetDefaultScrollBar ()
+ ScrollBarPress ()
+ Window.SetVisible (WINDOW_VISIBLE)
+ return
+
+def ScrollBarPress():
+ Window = SaveWindow
+
+ #draw load game portraits
+ Pos = GemRB.GetVar ("TopIndex")
+ for i in range(num_rows):
+ ActPos = Pos + i
+
+ Button1 = Window.GetControl (ctrl_offset[0]+i)
+ Button2 = Window.GetControl (ctrl_offset[1]+i)
+ if ActPos<=len(Games):
+ Button1.SetState (IE_GUI_BUTTON_ENABLED)
+ else:
+ Button1.SetState (IE_GUI_BUTTON_DISABLED)
+
+ if ActPos<len(Games):
+ Slotname = Games[ActPos].GetName()
+ Button2.SetState (IE_GUI_BUTTON_ENABLED)
+ elif ActPos == len(Games):
+ Slotname = 15304
+ Button2.SetState (IE_GUI_BUTTON_DISABLED)
+ else:
+ Slotname = ""
+ Button2.SetState (IE_GUI_BUTTON_DISABLED)
+
+ Label = Window.GetControl (ctrl_offset[3]+i)
+ Label.SetText (Slotname)
+
+ if ActPos<len(Games):
+ Slotname = Games[ActPos].GetGameDate()
+ else:
+ Slotname = ""
+ Label = Window.GetControl (ctrl_offset[4]+i)
+ Label.SetText (Slotname)
+
+ Button=Window.GetControl (1+i)
+ if ActPos<len(Games):
+ Button.SetSprite2D(Games[ActPos].GetPreview())
+ else:
+ Button.SetPicture("")
+ for j in range(PARTY_SIZE):
+ Button=Window.GetControl (ctrl_offset[2]+i*PARTY_SIZE+j)
+ if ActPos<len(Games):
+ Button.SetSprite2D(Games[ActPos].GetPortrait(j))
+ else:
+ Button.SetPicture("")
+ return
+
+def QuickSavePressed():
+ Slot = 1
+
+ if GUICommon.GameIsTOB():
+ Slot = 4
+
+ GemRB.SaveGame(Slot)
+ return
+
+def AbortedSaveGame():
+ global ConfirmWindow
+
+ if ConfirmWindow:
+ ConfirmWindow.Unload ()
+ ConfirmWindow = None
+ SaveWindow.SetVisible (WINDOW_VISIBLE)
+ return
+
+def ConfirmedSaveGame():
+ global ConfirmWindow
+
+ Pos = GemRB.GetVar ("TopIndex")+GemRB.GetVar ("LoadIdx")
+ Label = ConfirmWindow.GetControl (3)
+ Slotname = Label.QueryText ()
+ Slotname = Slotname.replace ("/", "|") # can't have path separators in the name
+ #FIXME: make this work
+ #LoadScreen.StartLoadScreen()
+ if ConfirmWindow:
+ ConfirmWindow.Unload ()
+ ConfirmWindow = None
+ OpenSaveWindow() # close window
+ GemRB.HideGUI ()
+ if Pos < len(Games):
+ GemRB.SaveGame(Games[Pos], Slotname, sav_version)
+ else:
+ GemRB.SaveGame(None, Slotname, sav_version)
+ GemRB.UnhideGUI ()
+ return
+
+def SavePress():
+ global ConfirmWindow, NameField, SaveButton
+
+ Pos = GemRB.GetVar ("TopIndex")+GemRB.GetVar ("LoadIdx")
+ ConfirmWindow = GemRB.LoadWindow (1)
+
+ #slot name
+ if Pos<len(Games):
+ Slotname = Games[Pos].GetName()
+ save_strref = 15306
+ else:
+ Slotname = ""
+ save_strref = 15588
+ NameField = ConfirmWindow.GetControl (3)
+ NameField.SetText (Slotname)
+ NameField.SetEvent (IE_GUI_EDIT_ON_CHANGE, EditChange)
+
+ #game hours (should be generated from game)
+ if Pos<len(Games):
+ if GUICommon.GameIsBG2():
+ Chapter = GemRB.GetGameVar ("CHAPTER") & 0x7fffffff
+ Slotname = GemRB.GetString(str_chapter[Chapter-1]) + " " + Games[Pos].GetGameDate()
+ else:
+ Slotname = Games[Pos].GetGameDate()
+ else:
+ Slotname = ""
+ Label = ConfirmWindow.GetControl (0x10000004)
+ Label.SetText (Slotname)
+
+ #areapreview
+ if not GUICommon.GameIsIWD2():
+ Button=ConfirmWindow.GetControl (0)
+ if Pos<len(Games):
+ Button.SetSprite2D(Games[Pos].GetPreview())
+ else:
+ Button.SetPicture("")
+
+ #portraits
+ for j in range(PARTY_SIZE):
+ Button=ConfirmWindow.GetControl (40+j)
+ if Pos<len(Games):
+ Button.SetSprite2D(Games[Pos].GetPortrait(j))
+ else:
+ Button.SetPicture("")
+
+ #save
+ SaveButton=ConfirmWindow.GetControl (7)
+ SaveButton.SetText (save_strref)
+ SaveButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, ConfirmedSaveGame)
+ SaveButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
+ #SaveButton.SetState (IE_GUI_BUTTON_DISABLED)
+ if Slotname == "":
+ SaveButton.SetState (IE_GUI_BUTTON_DISABLED)
+
+ #cancel
+ CancelButton=ConfirmWindow.GetControl (8)
+ CancelButton.SetText (13727)
+ CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, AbortedSaveGame)
+ CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+
+ ConfirmWindow.SetVisible (WINDOW_VISIBLE)
+ ConfirmWindow.ShowModal (MODAL_SHADOW_NONE)
+ NameField.SetStatus (IE_GUI_CONTROL_FOCUSED)
+ return
+
+def EditChange():
+ Name = NameField.QueryText ()
+ if len(Name)==0:
+ SaveButton.SetState (IE_GUI_BUTTON_DISABLED)
+ else:
+ SaveButton.SetState (IE_GUI_BUTTON_ENABLED)
+ return
+
+def DeleteGameConfirm():
+ global Games, ConfirmWindow
+
+ TopIndex = GemRB.GetVar ("TopIndex")
+ Pos = TopIndex +GemRB.GetVar ("LoadIdx")
+ GemRB.DeleteSaveGame(Games[Pos])
+ del Games[Pos]
+ if TopIndex>0:
+ GemRB.SetVar ("TopIndex",TopIndex-1)
+ ScrollBar.SetVarAssoc ("TopIndex", len(Games))
+ ScrollBarPress()
+ if ConfirmWindow:
+ ConfirmWindow.Unload ()
+ ConfirmWindow = None
+ SaveWindow.SetVisible (WINDOW_VISIBLE)
+ return
+
+def DeleteGameCancel():
+ global ConfirmWindow
+
+ if ConfirmWindow:
+ ConfirmWindow.Unload ()
+ ConfirmWindow = None
+ SaveWindow.SetVisible (WINDOW_VISIBLE)
+ return
+
+def DeleteGamePress():
+ global ConfirmWindow
+
+ SaveWindow.SetVisible (WINDOW_INVISIBLE)
+ ConfirmWindow=GemRB.LoadWindow (2)
+ Text=ConfirmWindow.GetControl (0)
+ Text.SetText (15305)
+ DeleteButton=ConfirmWindow.GetControl (1)
+ DeleteButton.SetText (13957)
+ DeleteButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DeleteGameConfirm)
+ CancelButton=ConfirmWindow.GetControl (2)
+ CancelButton.SetText (13727)
+ CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DeleteGameCancel)
+ CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+
+ ConfirmWindow.SetVisible (WINDOW_VISIBLE)
+ return
+
+def CloseSaveWindow ():
+ global SaveWindow
+
+ if SaveWindow:
+ SaveWindow.Unload ()
+ SaveWindow = None
+ if GemRB.GetVar ("QuitAfterSave"):
+ GemRB.QuitGame ()
+ GemRB.SetNextScript ("Start")
+ return
+
+ GUICommon.GameWindow.SetVisible(WINDOW_VISIBLE) #enabling the game control screen
+ GemRB.UnhideGUI () #enabling the other windows
+ return
diff --git a/gemrb/GUIScripts/GUISTORE.py b/gemrb/GUIScripts/GUISTORE.py
index c0d9eb7..755d660 100644
--- a/gemrb/GUIScripts/GUISTORE.py
+++ b/gemrb/GUIScripts/GUISTORE.py
@@ -28,6 +28,8 @@ import GUICommonWindows
from GUIDefines import *
from ie_stats import *
from ie_slots import *
+from ie_sounds import *
+from ie_feats import FEAT_MERCANTILE_BACKGROUND
StoreWindow = None
MessageWindow = None
@@ -60,6 +62,7 @@ if GUICommon.GameIsIWD2():
else:
ItemButtonCount = 4
RepModTable = None
+SpellTable = None
PreviousPC = 0
BarteringPC = 0
@@ -119,6 +122,7 @@ def CloseStoreWindow ():
if Inventory:
GUIINV.OpenInventoryWindow ()
else:
+ GemRB.GamePause (0, 3)
GUICommon.GameWindow.SetVisible(WINDOW_VISIBLE) #enabling the game control screen
GemRB.UnhideGUI () #enabling the other windows
GUICommonWindows.SetSelectionChangeHandler( None )
@@ -129,7 +133,8 @@ def OpenStoreWindow ():
global StoreWindow, ActionWindow, PortraitWindow
global OldPortraitWindow
global store_funcs
- global Inventory, RepModTable, BarteringPC
+ global SpellTable, RepModTable
+ global Inventory, BarteringPC
#these are function pointers, not strings
#can't put this in global init, doh!
@@ -139,6 +144,7 @@ def OpenStoreWindow ():
OpenStoreRumourWindow,OpenStoreRentWindow )
RepModTable = GemRB.LoadTable ("repmodst")
+ SpellTable = GemRB.LoadTable ("storespl", 1)
GemRB.HideGUI ()
GUICommon.GameWindow.SetVisible(WINDOW_INVISIBLE) #removing the game control screen
@@ -147,6 +153,8 @@ def OpenStoreWindow ():
Inventory = 1
else:
Inventory = None
+ # pause the game, so we don't get interrupted
+ GemRB.GamePause (1, 3)
GemRB.SetVar ("Action", 0)
if GUICommon.GameIsIWD2():
@@ -154,13 +162,6 @@ def OpenStoreWindow ():
else:
GemRB.LoadWindowPack ("GUISTORE", 640, 480)
StoreWindow = Window = GemRB.LoadWindow (3)
- #saving the original portrait window
- OldPortraitWindow = GUICommonWindows.PortraitWindow
- if GUICommon.GameIsIWD2() or GUICommon.GameIsBG1():
- #PortraitWindow = GUICommonWindows.OpenPortraitWindow ()
- pass
- else:
- PortraitWindow = GUICommonWindows.OpenPortraitWindow (0)
ActionWindow = GemRB.LoadWindow (0)
#this window is static and grey, but good to stick the frame onto
ActionWindow.SetFrame ()
@@ -203,6 +204,17 @@ def OpenStoreWindow ():
ActionWindow.SetVisible (WINDOW_VISIBLE)
Window.SetVisible (WINDOW_VISIBLE)
store_funcs[store_buttons[0]] ()
+
+ # Portrait window must be loaded after store, because UpdatePortraitWindow
+ # checks GUISTORE.StoreHealWindow
+ #saving the original portrait window
+ OldPortraitWindow = GUICommonWindows.PortraitWindow
+ if GUICommon.GameIsIWD2() or GUICommon.GameIsBG1():
+ #PortraitWindow = GUICommonWindows.OpenPortraitWindow ()
+ pass
+ else:
+ PortraitWindow = GUICommonWindows.OpenPortraitWindow (0)
+
if not GUICommon.GameIsIWD2():
if GUICommon.GameIsBG1():
GUICommonWindows.PortraitWindow.SetVisible (WINDOW_VISIBLE)
@@ -216,6 +228,11 @@ def OpenStoreShoppingWindow ():
CloseWindows()
+ GemRB.SetVar ("LeftIndex", 0) # reset the shopkeeps list
+ GemRB.SetVar ("LeftTopIndex", 0)
+ GemRB.SetVar ("RightTopIndex", 0)
+ GemRB.SetVar ("LeftTopIndex", 0)
+
StoreShoppingWindow = Window = GemRB.LoadWindow (2)
# left scrollbar
@@ -265,7 +282,7 @@ def OpenStoreShoppingWindow ():
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SelectBuy)
Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, InfoLeftWindow)
Button.SetFont ("NUMBER")
- Button.SetFlags (IE_GUI_BUTTON_ALIGN_RIGHT|IE_GUI_BUTTON_ALIGN_TOP, OP_OR)
+ Button.SetFlags (IE_GUI_BUTTON_ALIGN_RIGHT|IE_GUI_BUTTON_ALIGN_BOTTOM, OP_OR)
Button.AttachScrollBar (ScrollBarLeft)
Button = Window.GetControl (i+13)
@@ -278,16 +295,16 @@ def OpenStoreShoppingWindow ():
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SelectSell)
Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, InfoRightWindow)
Button.SetFont ("NUMBER")
- Button.SetFlags (IE_GUI_BUTTON_ALIGN_RIGHT|IE_GUI_BUTTON_ALIGN_TOP, OP_OR)
+ Button.SetFlags (IE_GUI_BUTTON_ALIGN_RIGHT|IE_GUI_BUTTON_ALIGN_BOTTOM, OP_OR)
Button.AttachScrollBar (ScrollBarRight)
+ UnselectNoRedraw ()
+
# Buy
LeftButton = Button = Window.GetControl (2)
if Inventory:
- if GUICommon.GameIsIWD2():
+ if GUICommon.GameIsIWD1() or GUICommon.GameIsIWD2():
Button.SetText (26287)
- elif GUICommon.GameIsIWD1():
- Button.SetText (26288)
elif GUICommon.GameIsBG2():
Button.SetText (51882)
else:
@@ -323,8 +340,11 @@ def OpenStoreShoppingWindow ():
Button.SetState (IE_GUI_BUTTON_LOCKED)
# encumbrance
- Label = Window.CreateLabel (0x10000043, 15,325,60,15,"NUMBER","0:",IE_FONT_ALIGN_LEFT|IE_FONT_ALIGN_TOP)
- Label = Window.CreateLabel (0x10000044, 15,365,80,15,"NUMBER","0:",IE_FONT_ALIGN_RIGHT|IE_FONT_ALIGN_TOP)
+ r = Button.GetRect ()
+ Label = Window.CreateLabel (0x10000043, r["X"],r["Y"],r["Width"],15,
+ "NUMBER","0:",IE_FONT_ALIGN_LEFT|IE_FONT_ALIGN_TOP)
+ Label = Window.CreateLabel (0x10000044, r["X"],r["Y"]+r["Height"]-15,r["Width"],15,
+ "NUMBER","0:",IE_FONT_ALIGN_RIGHT|IE_FONT_ALIGN_BOTTOM)
GUICommonWindows.SetSelectionChangeHandler( UpdateStoreShoppingWindow )
UpdateStoreShoppingWindow ()
@@ -371,9 +391,11 @@ def OpenStoreIdentifyWindow ():
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SelectID)
Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, InfoIdentifyWindow)
Button.SetFont ("NUMBER")
- Button.SetFlags (IE_GUI_BUTTON_ALIGN_RIGHT|IE_GUI_BUTTON_ALIGN_TOP, OP_OR)
+ Button.SetFlags (IE_GUI_BUTTON_ALIGN_RIGHT|IE_GUI_BUTTON_ALIGN_BOTTOM, OP_OR)
Button.AttachScrollBar (ScrollBar)
+ UnselectNoRedraw ()
+
GUICommonWindows.SetSelectionChangeHandler( UpdateStoreIdentifyWindow )
UpdateStoreIdentifyWindow ()
Window.SetVisible (WINDOW_VISIBLE)
@@ -415,9 +437,11 @@ def OpenStoreStealWindow ():
Button.SetBorder (0,0,0,0,0,32,32,192,128,0,1)
Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, InfoRightWindow)
Button.SetFont ("NUMBER")
- Button.SetFlags (IE_GUI_BUTTON_ALIGN_RIGHT|IE_GUI_BUTTON_ALIGN_TOP, OP_OR)
+ Button.SetFlags (IE_GUI_BUTTON_ALIGN_RIGHT|IE_GUI_BUTTON_ALIGN_BOTTOM, OP_OR)
Button.AttachScrollBar (ScrollBarRight)
+ UnselectNoRedraw ()
+
# Steal
LeftButton = Button = Window.GetControl (1)
Button.SetText (14179)
@@ -427,8 +451,11 @@ def OpenStoreStealWindow ():
Button.SetState (IE_GUI_BUTTON_LOCKED)
# encumbrance
- Label = Window.CreateLabel (0x10000043, 15,325,60,15,"NUMBER","0:",IE_FONT_ALIGN_LEFT|IE_FONT_ALIGN_TOP)
- Label = Window.CreateLabel (0x10000044, 15,365,80,15,"NUMBER","0:",IE_FONT_ALIGN_RIGHT|IE_FONT_ALIGN_TOP)
+ r = Button.GetRect ()
+ Label = Window.CreateLabel (0x10000043, r["X"],r["Y"],r["Width"],15,
+ "NUMBER","0:",IE_FONT_ALIGN_LEFT|IE_FONT_ALIGN_TOP)
+ Label = Window.CreateLabel (0x10000044, r["X"],r["Y"]+r["Height"]-15,r["Width"],15,
+ "NUMBER","0:",IE_FONT_ALIGN_RIGHT|IE_FONT_ALIGN_BOTTOM)
GUICommonWindows.SetSelectionChangeHandler( UpdateStoreStealWindow )
UpdateStoreStealWindow ()
@@ -444,7 +471,7 @@ def OpenStoreDonateWindow ():
# graphics
Button = Window.GetControl (10)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_ANIMATED|IE_GUI_BUTTON_PLAYONCE, OP_OR)
+ Button.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_ANIMATED|IE_GUI_BUTTON_PLAYONCE|IE_GUI_BUTTON_PLAYALWAYS, OP_OR)
Button.SetState (IE_GUI_BUTTON_LOCKED)
# Donate
@@ -491,6 +518,8 @@ def OpenStoreHealWindow ():
Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, InfoHealWindow)
#Button.AttachScrollBar (ScrollBar)
+ UnselectNoRedraw ()
+
# price tag
Label = Window.GetControl (0x10000003)
Label.SetText ("0")
@@ -506,7 +535,7 @@ def OpenStoreHealWindow ():
Count = Count-4
else:
Count = 0
- ScrollBar.SetVarAssoc ("TopIndex", Count+1)
+ ScrollBar.SetVarAssoc ("TopIndex", Count)
GUICommonWindows.SetSelectionChangeHandler( UpdateStoreHealWindow )
UpdateStoreHealWindow ()
@@ -522,10 +551,15 @@ def OpenStoreRumourWindow ():
StoreRumourWindow = Window = GemRB.LoadWindow (8)
#removing those pesky labels
- for i in range (5):
- Window.DeleteControl (0x10000005+i)
+ if not GUICommon.GameIsIWD2():
+ for i in range (5):
+ Window.DeleteControl (0x10000005+i)
- TextArea = Window.GetControl (11)
+ TextArea = None
+ if GUICommon.GameIsIWD2():
+ TextArea = Window.GetControl (13)
+ else:
+ TextArea = Window.GetControl (11)
TextArea.SetText (14144)
#tavern quality image
@@ -538,11 +572,11 @@ def OpenStoreRumourWindow ():
ScrollBar = Window.GetControl (5)
ScrollBar.SetEvent (IE_GUI_SCROLLBAR_ON_CHANGE, UpdateStoreRumourWindow)
Count = Store['StoreDrinkCount']
- if Count>4:
- Count = Count-4
+ if Count>5:
+ Count = Count-5
else:
Count = 0
- ScrollBar.SetVarAssoc ("TopIndex", Count+1)
+ ScrollBar.SetVarAssoc ("TopIndex", Count)
GUICommonWindows.SetSelectionChangeHandler( UpdateStoreRumourWindow )
UpdateStoreRumourWindow ()
@@ -587,6 +621,7 @@ def OpenStoreRentWindow ():
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, RentRoom)
GemRB.SetVar ("RentIndex", RentIndex)
+ Window.UpdateVarAssoc ("RentIndex")
GUICommonWindows.SetSelectionChangeHandler( UpdateStoreRentWindow )
UpdateStoreRentWindow ()
@@ -595,8 +630,9 @@ def OpenStoreRentWindow ():
def UpdateStoreCommon (Window, title, name, gold):
- Label = Window.GetControl (title)
- Label.SetText (Store['StoreName'])
+ if Store['StoreName'] != -1:
+ Label = Window.GetControl (title)
+ Label.SetText (Store['StoreName'])
if name:
pc = GemRB.GameGetSelectedPCSingle ()
@@ -616,11 +652,10 @@ def GetPC():
PreviousPC = pc
# reset the store indices, to prevent overscrolling
GemRB.SetVar ("RightIndex", 0)
- GemRB.SetVar ("LeftIndex", 0)
GemRB.SetVar ("RightTopIndex", 0)
- GemRB.SetVar ("LeftTopIndex", 0)
GemRB.SetVar ("Index", 0)
GemRB.SetVar ("TopIndex", 0)
+ UnselectNoRedraw ()
else:
PreviousPC = GemRB.GameGetSelectedPCSingle ()
pc = PreviousPC
@@ -635,7 +670,7 @@ def UpdateStoreShoppingWindow ():
Store = GemRB.GetStore ()
pc = GetPC()
- LeftCount = Store['StoreItemCount'] - ItemButtonCount + 1
+ LeftCount = Store['StoreItemCount'] - ItemButtonCount
if LeftCount<0:
LeftCount=0
ScrollBar = Window.GetControl (11)
@@ -646,7 +681,7 @@ def UpdateStoreShoppingWindow ():
pc = GemRB.GameGetSelectedPCSingle ()
inventory_slots = GemRB.GetSlots (pc, SLOT_INVENTORY)
- RightCount = len(inventory_slots) - ItemButtonCount + 1
+ RightCount = len(inventory_slots) - ItemButtonCount
if RightCount<0:
RightCount=0
ScrollBar = Window.GetControl (12)
@@ -658,6 +693,22 @@ def UpdateStoreShoppingWindow ():
RedrawStoreShoppingWindow ()
return
+# Unselects all the selected buttons, so they are not preselected in other windows
+def UnselectNoRedraw ():
+ pc = GemRB.GameGetSelectedPCSingle ()
+ LeftCount = Store['StoreItemCount']
+ for i in range (LeftCount, 0, -1):
+ Flags = GemRB.IsValidStoreItem (pc, i-1, ITEM_STORE)&SHOP_SELECT
+ if Flags:
+ GemRB.ChangeStoreItem (pc, i-1, SHOP_BUY|SHOP_SELECT)
+
+ RightCount = len (inventory_slots)
+ for Slot in range (RightCount):
+ Flags = GemRB.IsValidStoreItem (pc, inventory_slots[Slot], ITEM_PC) & SHOP_SELECT
+ if Flags:
+ GemRB.ChangeStoreItem (pc, inventory_slots[Slot], SHOP_SELL|SHOP_SELECT)
+ # same code for ID, so no repeat needed
+
def SelectID ():
pc = GemRB.GameGetSelectedPCSingle ()
Index = GemRB.GetVar ("Index")
@@ -746,6 +797,7 @@ def SellPressed ():
GemRB.ChangeStoreItem (pc, inventory_slots[Slot], SHOP_SELL)
GemRB.GameSetPartyGold (GemRB.GameGetPartyGold ()+SellSum)
+ GemRB.PlaySound(DEF_SOLD)
UpdateStoreShoppingWindow ()
return
@@ -798,8 +850,17 @@ def RedrawStoreShoppingWindow ():
Label.SetText ("")
else:
Label.SetText (str(BuySum) )
+
+ # shade the inventory icon if it is full
+ free_slots = len(GemRB.GetSlots (pc, SLOT_INVENTORY, -1))
+ Button = Window.GetControl (44)
+ if free_slots == 0:
+ Button.SetState (IE_GUI_BUTTON_PRESSED)
+ else:
+ Button.SetState (IE_GUI_BUTTON_LOCKED)
+
# also disable the button if the inventory is full
- if BuySum and selected_count <= len(GemRB.GetSlots (pc, SLOT_INVENTORY, -1)):
+ if BuySum and selected_count <= free_slots:
LeftButton.SetState (IE_GUI_BUTTON_ENABLED)
else:
LeftButton.SetState (IE_GUI_BUTTON_DISABLED)
@@ -833,6 +894,7 @@ def RedrawStoreShoppingWindow ():
Button.SetVarAssoc ("RightIndex", RightTopIndex+i)
SetupItems (pc, Slot, Button, Label, i, ITEM_PC, idx)
+ GUICommon.SetEncumbranceLabels ( Window, 0x10000043, 0x10000044, pc)
return
def UpdateStoreIdentifyWindow ():
@@ -844,7 +906,7 @@ def UpdateStoreIdentifyWindow ():
inventory_slots = GemRB.GetSlots (pc, SLOT_INVENTORY)
Count = len(inventory_slots)
ScrollBar = Window.GetControl (7)
- ScrollBar.SetVarAssoc ("TopIndex", Count-ItemButtonCount+1)
+ ScrollBar.SetVarAssoc ("TopIndex", Count-ItemButtonCount)
GemRB.SetVar ("Index", -1)
RedrawStoreIdentifyWindow ()
return
@@ -881,7 +943,7 @@ def RedrawStoreIdentifyWindow ():
Flags = GemRB.IsValidStoreItem (pc, inventory_slots[TopIndex+i], ITEM_PC)
Item = GemRB.GetItem (Slot['ItemResRef'])
Button.SetItemIcon (Slot['ItemResRef'], 0)
- if Item['StackAmount'] > 1:
+ if Item['MaxStackAmount'] > 1:
Button.SetText (str(Slot['Usages0']))
else:
Button.SetText ("")
@@ -907,6 +969,7 @@ def RedrawStoreIdentifyWindow ():
Button.SetState (IE_GUI_BUTTON_DISABLED)
Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_OR)
Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_NAND)
+ Button.SetText ("")
Label.SetText ("")
Button = Window.GetControl (5)
@@ -988,26 +1051,33 @@ def InfoWindow (Slot, Item):
MessageWindow = Window = GemRB.LoadWindow (12)
+ # TODO: check non-bg2 games to see which label is which
+ if GUICommon.GameIsBG2():
+ NameLabel = Window.GetControl (0x10000000)
+ FakeLabel = Window.GetControl (0x10000007)
+ else:
+ NameLabel = Window.GetControl (0x10000007)
+ FakeLabel = Window.GetControl (0x10000000)
+
#fake label
- Label = Window.GetControl (0x10000000)
- Label.SetText ("")
+ FakeLabel.SetText ("")
#description bam
if GUICommon.GameIsBG1() or GUICommon.GameIsBG2():
Button = Window.GetControl (7)
+ Button.SetFlags (IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_CENTER_PICTURES | IE_GUI_BUTTON_NO_IMAGE, OP_OR)
Button.SetItemIcon (Slot['ItemResRef'], 2)
#slot bam
Button = Window.GetControl (2)
Button.SetItemIcon (Slot['ItemResRef'], 0)
- Label = Window.GetControl (0x10000007)
TextArea = Window.GetControl (5)
if Identify:
- Label.SetText (Item['ItemNameIdentified'])
+ NameLabel.SetText (Item['ItemNameIdentified'])
TextArea.SetText (Item['ItemDescIdentified'])
else:
- Label.SetText (Item['ItemName'])
+ NameLabel.SetText (Item['ItemName'])
TextArea.SetText (Item['ItemDesc'])
#Done
@@ -1031,13 +1101,13 @@ def UpdateStoreStealWindow ():
Store = GemRB.GetStore ()
LeftCount = Store['StoreItemCount']
ScrollBar = Window.GetControl (9)
- ScrollBar.SetVarAssoc ("LeftTopIndex", LeftCount-ItemButtonCount+1)
+ ScrollBar.SetVarAssoc ("LeftTopIndex", LeftCount-ItemButtonCount)
pc = GetPC()
inventory_slots = GemRB.GetSlots (pc, SLOT_INVENTORY)
RightCount = len(inventory_slots)
ScrollBar = Window.GetControl (10)
- ScrollBar.SetVarAssoc ("RightTopIndex", RightCount-ItemButtonCount+1)
+ ScrollBar.SetVarAssoc ("RightTopIndex", RightCount-ItemButtonCount)
GemRB.SetVar ("LeftIndex", -1)
LeftButton.SetState (IE_GUI_BUTTON_DISABLED)
RedrawStoreStealWindow ()
@@ -1055,6 +1125,7 @@ def StealPressed ():
#if skill>random(100)+difficulty - success
if GUICommon.CheckStat100 (pc, IE_PICKPOCKET, Store['StealFailure']):
GemRB.ChangeStoreItem (pc, LeftIndex, SHOP_STEAL)
+ GemRB.PlaySound(DEF_STOLEN)
UpdateStoreStealWindow ()
else:
GemRB.StealFailed ()
@@ -1095,11 +1166,21 @@ def RedrawStoreStealWindow ():
if Flags & SHOP_SELECT:
selected_count += 1
+ # shade the inventory icon if it is full
+ Button = Window.GetControl (37)
+ free_slots = len(GemRB.GetSlots (pc, SLOT_INVENTORY, -1))
+ if free_slots == 0:
+ Button.SetState (IE_GUI_BUTTON_PRESSED)
+ else:
+ Button.SetState (IE_GUI_BUTTON_LOCKED)
+
# also disable the button if the inventory is full
- if LeftIndex>=0 and selected_count <= len(GemRB.GetSlots (pc, SLOT_INVENTORY, -1)):
+ if LeftIndex>=0 and selected_count <= free_slots:
LeftButton.SetState (IE_GUI_BUTTON_ENABLED)
else:
LeftButton.SetState (IE_GUI_BUTTON_DISABLED)
+
+ GUICommon.SetEncumbranceLabels ( Window, 0x10000043, 0x10000044, pc)
return
def SetupItems (pc, Slot, Button, Label, i, type, idx, steal=0):
@@ -1116,7 +1197,7 @@ def SetupItems (pc, Slot, Button, Label, i, type, idx, steal=0):
Item = GemRB.GetItem (Slot['ItemResRef'])
Button.SetItemIcon (Slot['ItemResRef'], 0)
- if Item['StackAmount']>1:
+ if Item['MaxStackAmount']>1:
Button.SetText ( str(Slot['Usages0']) )
else:
Button.SetText ("")
@@ -1165,40 +1246,51 @@ def SetupItems (pc, Slot, Button, Label, i, type, idx, steal=0):
Button.SetState (IE_GUI_BUTTON_DISABLED)
if Flags & SHOP_ID:
- GemRB.SetToken ("ITEMNAME", GemRB.GetString (Item['ItemName']))
+ Name = GemRB.GetString (Item['ItemName'])
Button.EnableBorder (0, 1)
if not steal and type == ITEM_PC:
Price = 1
else:
- GemRB.SetToken ("ITEMNAME", GemRB.GetString (Item['ItemNameIdentified']))
+ Name = GemRB.GetString (Item['ItemNameIdentified'])
Button.EnableBorder (0, 0)
+ GemRB.SetToken ("ITEMNAME", Name)
if Inventory:
if GUICommon.GameIsIWD1() or GUICommon.GameIsIWD2():
- Label.SetText (24890)
+ LabelText = GemRB.GetString (24890)
elif GUICommon.GameIsBG2():
- Label.SetText (28337)
+ LabelText = GemRB.GetString (28337)
else:
- Label.SetText ("")
+ LabelText = ""
else:
GemRB.SetToken ("ITEMCOST", str(Price) )
- Label.SetText (10162)
+ LabelText = GemRB.GetString(10162)
+ if type == ITEM_STORE:
+ if steal:
+ LabelText = Name
+ elif Slot["Amount"] != -1:
+ LabelText = LabelText + " (" + str(Slot["Amount"]) + ")"
+ Label.SetText (LabelText)
return
def GetRealPrice (pc, mode, Item, Slot):
# get the base from the item
price = Item['Price']
- # FIXME: actually, the price for wands depends on their charge
- # how ...
- if Item['StackAmount']>1:
+ if Item['MaxStackAmount']>1:
price = price * Slot['Usages0']
+ elif Item['MaxCharge']>0:
+ price = price * Slot['Usages0'] / Item['MaxCharge']
# modifier from store properties (in percent)
if mode == "buy":
mod = Store['BuyMarkup']
+ if GemRB.HasFeat(pc, FEAT_MERCANTILE_BACKGROUND):
+ mod -= 5
else:
mod = Store['SellMarkup']
+ if GemRB.HasFeat(pc, FEAT_MERCANTILE_BACKGROUND):
+ mod += 5
# depreciation works like this:
# - if you sell the item the first time, SellMarkup is used;
@@ -1215,12 +1307,12 @@ def GetRealPrice (pc, mode, Item, Slot):
if count > 2:
count = 2
mod -= count * Store['Depreciation']
+ else:
+ # charisma modifier (in percent)
+ mod += GemRB.GetAbilityBonus (IE_CHR, GemRB.GetPlayerStat (BarteringPC, IE_CHR) - 1, 0)
- # charisma modifier (in percent)
- mod += GemRB.GetAbilityBonus (IE_CHR, GemRB.GetPlayerStat (BarteringPC, IE_CHR) - 1, 0)
-
- # reputation modifier (in percent, but absolute)
- mod = mod * RepModTable.GetValue (0, GemRB.GameGetReputation()/10 - 1) / 100
+ # reputation modifier (in percent, but absolute)
+ mod = mod * RepModTable.GetValue (0, GemRB.GameGetReputation()/10 - 1) / 100
return price * mod / 100
@@ -1280,12 +1372,12 @@ def DonateGold ():
GemRB.GameSetPartyGold (GemRB.GameGetPartyGold ()-donation)
if GemRB.IncreaseReputation (donation):
TextArea.Append (10468, -1)
- GemRB.PlaySound ("act_03")
+ GemRB.PlaySound (DEF_DONATE1)
UpdateStoreDonateWindow ()
return
TextArea.Append (10469, -1)
- GemRB.PlaySound ("act_03e")
+ GemRB.PlaySound (DEF_DONATE2)
UpdateStoreDonateWindow ()
return
@@ -1296,11 +1388,14 @@ def UpdateStoreHealWindow ():
TopIndex = GemRB.GetVar ("TopIndex")
Index = GemRB.GetVar ("Index")
pc = GemRB.GameGetSelectedPCSingle ()
+ labelOffset = 0x1000000c
+ if GUICommon.GameIsIWD2():
+ labelOffset += 1 # grrr
for i in range (ItemButtonCount):
Cure = GemRB.GetStoreCure (TopIndex+i)
Button = Window.GetControl (i+8)
- Label = Window.GetControl (0x1000000c+i)
+ Label = Window.GetControl (labelOffset+i)
Button.SetVarAssoc ("Index", TopIndex+i)
if Cure:
Spell = GemRB.GetSpell (Cure['CureResRef'])
@@ -1310,8 +1405,9 @@ def UpdateStoreHealWindow ():
dead = GemRB.GetPlayerStat (pc, IE_STATE_ID) & STATE_DEAD
# toggle raise dead/resurrect based on state
# unfortunately the flags are not set properly in iwd
- if (dead and Spell["SpellTargetType"] != 3) or \
- (not dead and Spell["SpellTargetType"] == 3): # 3 - non-living
+ if not GUICommon.GameIsIWD1() and ( # 3 - non-living
+ (dead and Spell["SpellTargetType"] != 3) or \
+ (not dead and Spell["SpellTargetType"] == 3)):
# locked and shaded
Button.SetState (IE_GUI_BUTTON_DISABLED)
Button.SetBorder (0, 0,0, 0,0, 200,0,0,100, 1,1)
@@ -1375,7 +1471,14 @@ def BuyHeal ():
GemRB.GameSetPartyGold (gold-Cure['Price'])
pc = GemRB.GameGetSelectedPCSingle ()
- GemRB.ApplySpell (pc, Cure['CureResRef'], Store['StoreOwner'])
+ GemRB.ApplySpell (pc, Cure['CureResRef'], pc)
+ if SpellTable:
+ sound = SpellTable.GetValue(Cure['CureResRef'], "SOUND")
+ else:
+ #if there is no table, simply use the spell's own completion sound
+ Spell = GemRB.GetSpell(Cure['CureResRef'])
+ sound = Spell['Completion']
+ GemRB.PlaySound (sound)
UpdateStoreHealWindow ()
return
@@ -1384,19 +1487,32 @@ def UpdateStoreRumourWindow ():
UpdateStoreCommon (Window, 0x10000011, 0, 0x10000012)
TopIndex = GemRB.GetVar ("TopIndex")
- for i in range (5):
+ DrinkButtonCount = ItemButtonCount + 1
+ offset = 0
+ if GUICommon.GameIsIWD2():
+ offset = 40
+ DrinkButtonCount += 1 # shows even more than with inventories
+ for i in range (DrinkButtonCount):
Drink = GemRB.GetStoreDrink (TopIndex+i)
- Button = Window.GetControl (i)
+ Button = Window.GetControl (i+offset)
Button.SetVarAssoc ("Index", i)
if Drink:
- GemRB.SetToken ("ITEMNAME", GemRB.GetString (Drink['DrinkName']))
- GemRB.SetToken ("ITEMCOST", str(Drink['Price']) )
- Button.SetText (10162)
+ if GUICommon.GameIsIWD2():
+ Button.SetText (GemRB.GetString (Drink['DrinkName']))
+ CostLabel = Window.GetControl (0x10000000+29+i)
+ CostLabel.SetText (str(Drink['Price']))
+ else:
+ GemRB.SetToken ("ITEMNAME", GemRB.GetString (Drink['DrinkName']))
+ GemRB.SetToken ("ITEMCOST", str(Drink['Price']) )
+ Button.SetText (10162)
Button.SetState (IE_GUI_BUTTON_ENABLED)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GulpDrink)
else:
Button.SetText ("")
Button.SetState (IE_GUI_BUTTON_DISABLED)
+ if GUICommon.GameIsIWD2():
+ CostLabel = Window.GetControl (0x10000000+29+i)
+ CostLabel.SetText ("")
return
def GulpDrink ():
@@ -1422,7 +1538,7 @@ def GulpDrink ():
GemRB.SetPlayerStat (pc, IE_INTOXICATION, intox+Drink['Strength'])
text = GemRB.GetRumour (Drink['Strength'], Store['TavernRumour'])
TextArea.Append (text, -1)
- GemRB.PlaySound ("gam_07")
+ GemRB.PlaySound (DEF_DRUNK)
UpdateStoreRumourWindow ()
return
@@ -1450,19 +1566,21 @@ def RentConfirm ():
price = Store['StoreRoomPrices'][RentIndex]
Gold = GemRB.GameGetPartyGold ()
GemRB.GameSetPartyGold (Gold-price)
- GemRB.RestParty (13, 1, RentIndex+1)
+ cutscene = GemRB.RestParty (13, 1, RentIndex+1)
if RentConfirmWindow:
RentConfirmWindow.Unload ()
Window = StoreRentWindow
- TextArea = Window.GetControl (12)
- #is there any way to change this???
- GemRB.SetToken ("HOUR", "8")
- GemRB.SetToken ("HP", "%d"%(RentIndex+1))
- TextArea.SetText (16476)
- GemRB.SetVar ("RentIndex", -1)
- Button = Window.GetControl (RentIndex+4)
- Button.SetState (IE_GUI_BUTTON_ENABLED)
- UpdateStoreRentWindow ()
+ if cutscene:
+ CloseStoreWindow ()
+ else:
+ TextArea = Window.GetControl (12)
+ #is there any way to change this???
+ GemRB.SetToken ("HP", "%d"%(RentIndex+1))
+ TextArea.SetText (16476)
+ GemRB.SetVar ("RentIndex", -1)
+ Button = Window.GetControl (RentIndex+4)
+ Button.SetState (IE_GUI_BUTTON_ENABLED)
+ UpdateStoreRentWindow ()
return
def RentDeny () :
diff --git a/gemrb/GUIScripts/GUIWORLD.py b/gemrb/GUIScripts/GUIWORLD.py
new file mode 100644
index 0000000..6f60d55
--- /dev/null
+++ b/gemrb/GUIScripts/GUIWORLD.py
@@ -0,0 +1,341 @@
+# -*-python-*-
+# GemRB - Infinity Engine Emulator
+# Copyright (C) 2003 The GemRB Project
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+
+# GUIW.py - scripts to control some windows from the GUIWORLD winpack
+# except of Actions, Portrait, Options and Dialog windows
+#################################################################
+
+import GemRB
+import GUICommon
+import GUICommonWindows
+import GUIClasses
+from GUIDefines import *
+from ie_stats import *
+import MessageWindow
+import CommonWindow
+
+FRAME_PC_SELECTED = 0
+FRAME_PC_TARGET = 1
+
+ContinueWindow = None
+ReformPartyWindow = None
+OldActionsWindow = None
+OldMessageWindow = None
+
+removable_pcs = []
+
+def DialogStarted ():
+ global ContinueWindow, OldActionsWindow
+
+ # try to force-close anything which is open
+ GUICommon.CloseOtherWindow(None)
+ CommonWindow.CloseContainerWindow()
+
+ # we need GUI for dialogs
+ GemRB.UnhideGUI()
+
+ # opening control size to maximum, enabling dialog window
+ GemRB.GameSetScreenFlags(GS_HIDEGUI, OP_NAND)
+ GemRB.GameSetScreenFlags(GS_DIALOG, OP_OR)
+
+ if GUICommonWindows.PortraitWindow:
+ GUICommonWindows.UpdatePortraitWindow ()
+
+ # we want this to happen before we start fiddling with the GUI
+ MessageWindow.UpdateControlStatus()
+
+ GemRB.LoadWindowPack (GUICommon.GetWindowPack())
+ ContinueWindow = Window = GemRB.LoadWindow (9)
+
+ GUICommonWindows.EmptyControls()
+ OldActionsWindow = GUICommonWindows.ActionsWindow
+ #GUICommonWindows.ActionsWindow = None
+ OldActionsWindow.SetVisible(WINDOW_INVISIBLE)
+ GemRB.SetVar ("ActionsWindow", -1)
+
+def DialogEnded ():
+ global ContinueWindow, OldActionsWindow
+
+ # TODO: why is this being called at game start?!
+ if not ContinueWindow:
+ return
+
+ #GUICommonWindows.ActionsWindow = OldActionsWindow
+ OldActionsWindow.SetVisible(WINDOW_VISIBLE)
+ GemRB.SetVar ("ActionsWindow", OldActionsWindow.ID)
+ GUICommonWindows.UpdateActionsWindow()
+
+ ContinueWindow.Unload ()
+ ContinueWindow = None
+ OldActionsWindow = None
+
+ if GUICommonWindows.PortraitWindow:
+ GUICommonWindows.UpdatePortraitWindow ()
+
+def CloseContinueWindow ():
+ # don't close the actual window now to avoid flickering: we might still want it open
+ GemRB.SetVar ("DialogChoose", GemRB.GetVar ("DialogOption"))
+
+def NextDialogState ():
+ if not ContinueWindow:
+ return
+
+ ContinueWindow.SetVisible(WINDOW_INVISIBLE)
+ OldActionsWindow.SetVisible(WINDOW_VISIBLE)
+
+ MessageWindow.TMessageTA.SetStatus (IE_GUI_CONTROL_FOCUSED)
+
+def OpenEndMessageWindow ():
+ ContinueWindow.SetVisible(WINDOW_VISIBLE)
+ OldActionsWindow.SetVisible(WINDOW_INVISIBLE)
+ Button = ContinueWindow.GetControl (0)
+ Button.SetText (9371)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseContinueWindow)
+ Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
+ Button.SetStatus (IE_GUI_CONTROL_FOCUSED)
+
+def OpenContinueMessageWindow ():
+ ContinueWindow.SetVisible(WINDOW_VISIBLE)
+ OldActionsWindow.SetVisible(WINDOW_INVISIBLE)
+ #continue
+ Button = ContinueWindow.GetControl (0)
+ Button.SetText (9372)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseContinueWindow)
+ Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
+ Button.SetStatus (IE_GUI_CONTROL_FOCUSED)
+
+def UpdateReformWindow ():
+ Window = ReformPartyWindow
+
+ select = GemRB.GetVar ("Selected")
+
+ need_to_drop = GemRB.GetPartySize ()-PARTY_SIZE
+ if need_to_drop<0:
+ need_to_drop = 0
+
+ #excess player number
+ Label = Window.GetControl (0x1000000f)
+ Label.SetText (str(need_to_drop) )
+
+ #done
+ Button = Window.GetControl (8)
+ if need_to_drop:
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+ else:
+ Button.SetState (IE_GUI_BUTTON_ENABLED)
+
+ #remove
+ Button = Window.GetControl (15)
+ if select:
+ Button.SetState (IE_GUI_BUTTON_ENABLED)
+ else:
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+
+ for i in range (PARTY_SIZE+1):
+ Button = Window.GetControl (i)
+ if i+1 not in removable_pcs:
+ Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
+ Button.SetState (IE_GUI_BUTTON_LOCKED)
+ continue
+
+ for i in removable_pcs:
+ Button = Window.GetControl (removable_pcs.index(i))
+ Button.EnableBorder (FRAME_PC_SELECTED, select == i )
+ pic = GemRB.GetPlayerPortrait (i, 1)
+ if not pic:
+ Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
+ Button.SetState (IE_GUI_BUTTON_LOCKED)
+ continue
+ Button.SetState (IE_GUI_BUTTON_ENABLED)
+ Button.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_ALIGN_BOTTOM|IE_GUI_BUTTON_ALIGN_LEFT, OP_SET)
+ Button.SetPicture (pic, "NOPORTSM")
+ GUICommonWindows.UpdatePortraitWindow ()
+ return
+
+def RemovePlayer ():
+ global ReformPartyWindow
+
+ hideflag = GemRB.HideGUI ()
+
+ GemRB.LoadWindowPack (GUICommon.GetWindowPack())
+ if ReformPartyWindow:
+ ReformPartyWindow.Unload ()
+ ReformPartyWindow = Window = GemRB.LoadWindow (25)
+ GemRB.SetVar ("OtherWindow", Window.ID)
+
+ #are you sure
+ Label = Window.GetControl (0x0fffffff)
+ Label.SetText (17518)
+
+ #confirm
+ Button = Window.GetControl (1)
+ Button.SetText (17507)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, RemovePlayerConfirm)
+ Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
+
+ #cancel
+ Button = Window.GetControl (2)
+ Button.SetText (13727)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, RemovePlayerCancel)
+ Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+
+ GemRB.SetVar ("OtherWindow", Window.ID)
+ GemRB.SetVar ("ActionsWindow", -1)
+ if hideflag:
+ GemRB.UnhideGUI ()
+ Window.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def RemovePlayerConfirm ():
+ slot = GemRB.GetVar ("Selected")
+ if GUICommon.GameIsBG2():
+ GemRB.LeaveParty (slot, 2)
+ elif GUICommon.GameIsBG1():
+ GemRB.LeaveParty (slot, 1)
+ else:
+ GemRB.LeaveParty (slot)
+ OpenReformPartyWindow ()
+ return
+
+def RemovePlayerCancel ():
+ #Once for getting rid of the confirmation window
+ OpenReformPartyWindow ()
+ #and once for reopening the reform party window
+ OpenReformPartyWindow ()
+ return
+
+def OpenReformPartyWindow ():
+ global ReformPartyWindow, OldActionsWindow, OldMessageWindow
+ global removable_pcs
+
+ GemRB.SetVar ("Selected", 0)
+ hideflag = GemRB.HideGUI ()
+
+ if ReformPartyWindow:
+ ReformPartyWindow.Unload ()
+ GemRB.SetVar ("ActionsWindow", OldActionsWindow.ID)
+ GemRB.SetVar ("MessageWindow", OldMessageWindow.ID)
+ GemRB.SetVar ("OtherWindow", -1)
+
+ OldActionsWindow = None
+ OldMessageWindow = None
+ ReformPartyWindow = None
+ if hideflag:
+ GemRB.UnhideGUI ()
+ #re-enabling party size control
+ GemRB.GameSetPartySize (PARTY_SIZE)
+ GUICommonWindows.UpdatePortraitWindow()
+ return
+
+ GemRB.LoadWindowPack (GUICommon.GetWindowPack())
+ ReformPartyWindow = Window = GemRB.LoadWindow (24)
+ GemRB.SetVar ("OtherWindow", Window.ID)
+
+ # skip exportable party members (usually only the protagonist)
+ removable_pcs = []
+ for i in range (1, GemRB.GetPartySize()+1):
+ if not GemRB.GetPlayerStat (i, IE_MC_FLAGS)&MC_EXPORTABLE:
+ removable_pcs.append(i)
+
+ #PC portraits
+ for j in range (PARTY_SIZE+1):
+ Button = Window.GetControl (j)
+ Button.SetState (IE_GUI_BUTTON_LOCKED)
+ Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON|IE_GUI_BUTTON_NO_IMAGE|IE_GUI_BUTTON_PICTURE,OP_SET)
+ Button.SetBorder (FRAME_PC_SELECTED, 1, 1, 2, 2, 0, 255, 0, 255)
+ if j < len(removable_pcs):
+ Button.SetVarAssoc ("Selected", removable_pcs[j])
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, UpdateReformWindow)
+
+ # Remove
+ Button = Window.GetControl (15)
+ Button.SetText (17507)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, RemovePlayer)
+
+ # Done
+ Button = Window.GetControl (8)
+ Button.SetText (11973)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenReformPartyWindow)
+
+ OldActionsWindow = GUIClasses.GWindow( GemRB.GetVar ("ActionsWindow") )
+ OldMessageWindow = GUIClasses.GWindow( GemRB.GetVar ("MessageWindow") )
+ GemRB.SetVar ("ActionsWindow", -1)
+ GemRB.SetVar ("MessageWindow", -1)
+
+ # if nobody can be removed, just close the window
+ if not removable_pcs:
+ OpenReformPartyWindow ()
+ if hideflag:
+ GemRB.UnhideGUI ()
+ return
+
+ UpdateReformWindow ()
+ if hideflag:
+ GemRB.UnhideGUI ()
+ Window.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def DeathWindow ():
+ if GUICommon.GameIsIWD1():
+ #no death movie, but music is changed
+ GemRB.LoadMusicPL ("Theme.mus",1)
+ GemRB.HideGUI ()
+ GemRB.SetTimedEvent (DeathWindowEnd, 10)
+ return
+
+def DeathWindowEnd ():
+ #playing death movie before continuing
+ if not GUICommon.GameIsIWD1():
+ GemRB.PlayMovie ("deathand",1)
+ GemRB.GamePause (1,3)
+
+ GemRB.LoadWindowPack (GUICommon.GetWindowPack())
+ Window = GemRB.LoadWindow (17)
+
+ #reason for death
+ Label = Window.GetControl (0x0fffffff)
+ Label.SetText (16498)
+
+ #load
+ Button = Window.GetControl (1)
+ Button.SetText (15590)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, LoadPress)
+
+ #quit
+ Button = Window.GetControl (2)
+ Button.SetText (15417)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, QuitPress)
+
+ GemRB.HideGUI ()
+ GemRB.SetVar ("MessageWindow", -1)
+ GemRB.UnhideGUI ()
+ Window.ShowModal (MODAL_SHADOW_GRAY)
+ return
+
+def QuitPress():
+ GemRB.QuitGame ()
+ GemRB.SetNextScript ("Start")
+ return
+
+def LoadPress():
+ GemRB.QuitGame ()
+ GemRB.SetNextScript ("GUILOAD")
+ return
+
diff --git a/gemrb/GUIScripts/InventoryCommon.py b/gemrb/GUIScripts/InventoryCommon.py
index 9c78074..f62105a 100644
--- a/gemrb/GUIScripts/InventoryCommon.py
+++ b/gemrb/GUIScripts/InventoryCommon.py
@@ -19,10 +19,12 @@
import GemRB
import GUICommon
+import Spellbook
from GUIDefines import *
from ie_stats import *
from ie_slots import *
from ie_spells import *
+from ie_sounds import DEF_IDENTIFY
OverSlot = None
UsedSlot = None
@@ -32,6 +34,7 @@ ItemIdentifyWindow = None
ItemAbilitiesWindow = None
ErrorWindow = None
StackAmount = 0
+pause = None
def OnDragItemGround ():
"""Drops and item to the ground."""
@@ -112,6 +115,9 @@ def OnDragItem ():
GemRB.LeaveStore()
GemRB.DropDraggedItem (pc, slot)
+ # drop item if it caused us to disable the inventory view (example: cursed berserking sword)
+ if GemRB.GetPlayerStat (pc, IE_STATE_ID) & (STATE_BERSERK) and GemRB.IsDraggingItem ():
+ GemRB.DropDraggedItem (pc, -3)
GUIINV.UpdateInventoryWindow ()
return
@@ -123,14 +129,6 @@ def OnDropItemToPC ():
#-3 : drop stuff in inventory (but not equippable slots)
GemRB.DropDraggedItem (pc, -3)
- if GemRB.IsDraggingItem ()==1:
- if GUICommon.HasTOB ():
- GemRB.DisplayString (61794, 0xffffff)
- elif GUICommon.GameIsPST ():
- GemRB.DisplayString (19257, 0xffffff)
- else:
- GemRB.DisplayString (17999, 0xffffff)
-
GUIINV.UpdateInventoryWindow ()
return
@@ -221,7 +219,7 @@ def MouseLeaveGround ():
Button = Window.GetControl (i+offset)
if GemRB.IsDraggingItem ()==1:
- Button.SetState (IE_GUI_BUTTON_SECOND)
+ Button.SetState (IE_GUI_BUTTON_FAKEPRESSED)
return
def CloseItemInfoWindow ():
@@ -263,7 +261,7 @@ def DisplayItem (itemresref, type):
Button = Window.GetControl (4)
Button.SetText (strrefs[0])
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseItemInfoWindow)
- Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+ Button.SetFlags (IE_GUI_BUTTON_CANCEL|IE_GUI_BUTTON_DEFAULT, OP_OR)
#textarea
Text = Window.GetControl (5)
@@ -301,7 +299,7 @@ def DisplayItem (itemresref, type):
Button = Window.GetControl(9)
drink = (type&1) and (item["Function"]&1)
read = (type&1) and (item["Function"]&2)
- #sorcerors cannot learn spells
+ # sorcerers cannot learn spells
# FIXME: unhardcode
pc = GemRB.GameGetSelectedPCSingle ()
if GemRB.GetPlayerStat (pc, IE_CLASS) == 19:
@@ -325,6 +323,9 @@ def DisplayItem (itemresref, type):
# FIXME: where do mods add the new string? This is untranslatable
Button.SetText ("Open container")
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenItemWindow)
+ # Just skip the redundant info page and go directly to the container
+ if GemRB.GetVar("GUIEnhancements")&GE_ALWAYS_OPEN_CONTAINER_ITEMS:
+ OpenItemWindow()
elif dialog:
Button.SetText (strrefs[5])
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, DialogItemWindow)
@@ -357,19 +358,21 @@ def DisplayItem (itemresref, type):
ItemInfoWindow.ShowModal(MODAL_SHADOW_GRAY)
return
-def OpenItemInfoWindow ():
+def OpenItemInfoWindow (slot = None):
pc = GemRB.GameGetSelectedPCSingle ()
- if GUICommon.GameIsPST():
- slot, slot_item = GUIINV.ItemHash[GemRB.GetVar ('ItemButton')]
+
+ if slot == None:
+ if GUICommon.GameIsPST():
+ slot, slot_item = GUIINV.ItemHash[GemRB.GetVar ('ItemButton')]
+ else:
+ slot = GemRB.GetVar ("ItemButton")
+ slot_item = GemRB.GetSlotItem (pc, slot)
else:
- slot = GemRB.GetVar ("ItemButton")
slot_item = GemRB.GetSlotItem (pc, slot)
+
item = GemRB.GetItem (slot_item["ItemResRef"])
- #auto identify when lore is high enough
- if item["LoreToID"]<=GemRB.GetPlayerStat (pc, IE_LORE):
- GemRB.ChangeItemFlag (pc, slot, IE_INV_ITEM_IDENTIFIED, OP_OR)
- slot_item["Flags"] |= IE_INV_ITEM_IDENTIFIED
+ if TryAutoIdentification(pc, item, slot, slot_item, True):
GUIINV.UpdateInventoryWindow ()
if slot_item["Flags"] & IE_INV_ITEM_IDENTIFIED:
@@ -379,6 +382,14 @@ def OpenItemInfoWindow ():
DisplayItem (slot_item["ItemResRef"], value)
return
+#auto identify when lore is high enough
+def TryAutoIdentification(pc, item, slot, slot_item, enabled=0):
+ if enabled and item["LoreToID"]<=GemRB.GetPlayerStat (pc, IE_LORE):
+ GemRB.ChangeItemFlag (pc, slot, IE_INV_ITEM_IDENTIFIED, OP_OR)
+ slot_item["Flags"] |= IE_INV_ITEM_IDENTIFIED
+ return True
+ return False
+
def OpenGroundItemInfoWindow ():
global ItemInfoWindow
@@ -498,6 +509,12 @@ def UpdateSlot (pc, slot):
Button.SetEvent (IE_GUI_BUTTON_ON_DRAG_DROP, OnDragItem)
Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_NAND)
+
+ # characters should auto-identify any item they recieve
+ if slot_item:
+ item = GemRB.GetItem (slot_item["ItemResRef"])
+ TryAutoIdentification(pc, item, slot+1, slot_item, GemRB.GetVar("GUIEnhancements")&GE_TRY_IDENTIFY_ON_TRANSFER)
+
GUICommon.UpdateInventorySlot (pc, Button, slot_item, "inventory", SlotType["Type"]&SLOT_INVENTORY == 0)
if slot_item:
@@ -532,10 +549,10 @@ def UpdateSlot (pc, slot):
if (SlotType["Type"]&SLOT_INVENTORY) or not GemRB.CanUseItemType (SlotType["Type"], itemname):
Button.SetState (IE_GUI_BUTTON_ENABLED)
else:
- Button.SetState (IE_GUI_BUTTON_SECOND)
+ Button.SetState (IE_GUI_BUTTON_FAKEPRESSED)
if slot_item and (GemRB.GetEquippedQuickSlot (pc)==slot+1 or GemRB.GetEquippedAmmunition (pc)==slot+1):
- Button.SetState (IE_GUI_BUTTON_THIRD)
+ Button.SetState (IE_GUI_BUTTON_FAKEDISABLED)
return
@@ -681,59 +698,53 @@ def CloseErrorWindow ():
return
def ReadItemWindow ():
- global level, spell_ref
+ global pause
"""Tries to learn the mage scroll."""
pc = GemRB.GameGetSelectedPCSingle ()
slot = GemRB.GetVar ("ItemButton")
- ret = GUICommon.CannotLearnSlotSpell()
+ ret = Spellbook.CannotLearnSlotSpell()
if ret:
- strref = 72873
+ # couldn't find any strrefs for the other undhandled values (stat, level)
+ if ret == LSR_KNOWN and GUICommon.HasTOB():
+ strref = 72873
+ elif ret == LSR_KNOWN and GUICommon.GameIsPST():
+ strref = 50394
+ elif ret == LSR_FULL and GUICommon.GameIsBG2():
+ strref = 32097
+ elif ret == LSR_FULL and GUICommon.GameIsPST():
+ strref = 50395
+ elif GUICommon.GameIsPST():
+ strref = 4250
+ else:
+ strref = 10831
+
CloseItemInfoWindow ()
- if GUICommon.HasTOB():
- OpenErrorWindow (strref)
- return
+ OpenErrorWindow (strref)
- slot_item = GemRB.GetSlotItem (pc, slot)
- spell_ref = GemRB.GetItem (slot_item['ItemResRef'], pc)['Spell']
- spell = GemRB.GetSpell (spell_ref)
- if spell:
- # can we learn more spells of this level?
- level = spell['SpellLevel']-1
- spell_count = GemRB.GetKnownSpellsCount (pc, IE_SPELL_TYPE_WIZARD, level)
- if spell_count > GemRB.GetAbilityBonus (IE_INT, 2, GemRB.GetPlayerStat (pc, IE_INT)):
- ret = LSR_FULL
- if GUICommon.GameIsBG2():
- strref = 32097
- else:
- strref = -1
- else:
- GemRB.UseItem (pc, slot, 1, 5)
- GemRB.SetTimedEvent(DelayedReadItemWindow, 1)
- return
else:
- print "WARNING: invalid spell header in item", slot_item['ItemResRef']
- CloseItemInfoWindow ()
- return -1
+ if GUICommon.GameIsPST():
+ slot, slot_item = GUIINV.ItemHash[GemRB.GetVar ('ItemButton')]
- CloseItemInfoWindow ()
- OpenErrorWindow (strref)
+ pause = GemRB.GamePause(3,1) #query the pause state
+ GemRB.GamePause(0,1)
+ GemRB.UseItem (pc, slot, 1, 5)
+ GemRB.SetTimedEvent(DelayedReadItemWindow, 1)
return ret
def DelayedReadItemWindow ():
- global level, spell_ref
+ #restore the pause state
+ if pause:
+ GemRB.GamePause(1,1)
- pc = GemRB.GameGetSelectedPCSingle ()
- if GUICommon.HasSpell (pc, IE_SPELL_TYPE_WIZARD, level, spell_ref):
- strref = 10830
- else:
- ret = LSR_FAILED
- strref = 10831
CloseItemInfoWindow ()
- if not GUICommon.GameIsPST():
- OpenErrorWindow (strref)
+ if GUICommon.GameIsPST():
+ strref = 4249
+ else:
+ strref = 10830
+ OpenErrorWindow (strref)
return
def OpenItemWindow ():
@@ -783,7 +794,8 @@ def IdentifyUseSpell ():
if ItemInfoWindow:
ItemInfoWindow.Unload ()
GemRB.ChangeItemFlag (pc, slot, IE_INV_ITEM_IDENTIFIED, OP_OR)
- OpenItemInfoWindow()
+ GemRB.PlaySound(DEF_IDENTIFY)
+ OpenItemInfoWindow(slot)
return
def IdentifyUseScroll ():
@@ -799,7 +811,8 @@ def IdentifyUseScroll ():
ItemInfoWindow.Unload ()
if GemRB.HasSpecialItem (pc, 1, 1):
GemRB.ChangeItemFlag (pc, slot, IE_INV_ITEM_IDENTIFIED, OP_OR)
- OpenItemInfoWindow()
+ GemRB.PlaySound(DEF_IDENTIFY)
+ OpenItemInfoWindow(slot)
return
def CloseIdentifyItemWindow ():
diff --git a/gemrb/GUIScripts/LUCommon.py b/gemrb/GUIScripts/LUCommon.py
index 11c5432..04f414e 100644
--- a/gemrb/GUIScripts/LUCommon.py
+++ b/gemrb/GUIScripts/LUCommon.py
@@ -23,6 +23,7 @@ import GemRB
import GUICommon
import CommonTables
from ie_stats import *
+from ie_feats import *
def GetNextLevelExp (Level, Class):
"""Returns the amount of XP required to gain the next level."""
@@ -30,15 +31,15 @@ def GetNextLevelExp (Level, Class):
if Level < CommonTables.NextLevel.GetColumnCount (Row):
return str (CommonTables.NextLevel.GetValue (Row, Level) )
- return 0
+ # we could display the current level's max, but likely nobody cares
+ # if you change it, check that all callers can handle it
+ return "0"
def CanLevelUp(actor):
"""Returns true if the actor can level up."""
# get our class and placements for Multi'd and Dual'd characters
- Class = GemRB.GetPlayerStat (actor, IE_CLASS)
- Class = CommonTables.Classes.FindValue (5, Class)
- Class = CommonTables.Classes.GetRowName (Class)
+ Class = GUICommon.GetClassRowName (actor)
Multi = GUICommon.IsMultiClassed (actor, 1)
Dual = GUICommon.IsDualClassed (actor, 1)
@@ -47,7 +48,6 @@ def CanLevelUp(actor):
Levels = [GemRB.GetPlayerStat (actor, IE_LEVEL), GemRB.GetPlayerStat (actor, IE_LEVEL2),\
GemRB.GetPlayerStat (actor, IE_LEVEL3)]
- #TODO: double-check this
if GemRB.GetPlayerStat(actor, IE_LEVELDRAIN)>0:
return 0
@@ -55,8 +55,8 @@ def CanLevelUp(actor):
xp = xp/Multi[0] # divide the xp evenly between the classes
for i in range (Multi[0]):
# if any class can level, return 1
- ClassIndex = CommonTables.Classes.FindValue (5, Multi[i+1])
- tmpNext = int(GetNextLevelExp (Levels[i], CommonTables.Classes.GetRowName (ClassIndex) ) )
+ TmpClassName = GUICommon.GetClassRowName (Multi[i+1], "class")
+ tmpNext = int(GetNextLevelExp (Levels[i], TmpClassName))
if tmpNext != 0 and tmpNext <= xp:
return 1
@@ -72,27 +72,23 @@ def CanLevelUp(actor):
tmpNext = int(GetNextLevelExp (Levels[0], Class) )
return (tmpNext != 0 and tmpNext <= xp)
-def SetupSavingThrows (pc, Level=None):
- """Updates an actors saving throws based upon level.
-
- Level should contain the actors current level.
- If Level is None, it is filled with the actors current level."""
-
+# internal shared function for the various Setup* stat updaters
+def _SetupLevels (pc, Level, offset=0, noclass=0):
#storing levels as an array makes them easier to deal with
if not Level:
- Levels = [GemRB.GetPlayerStat (pc, IE_LEVEL)-1, \
- GemRB.GetPlayerStat (pc, IE_LEVEL2)-1, \
- GemRB.GetPlayerStat (pc, IE_LEVEL3)-1]
+ Levels = [GemRB.GetPlayerStat (pc, IE_LEVEL)+offset, \
+ GemRB.GetPlayerStat (pc, IE_LEVEL2)+offset, \
+ GemRB.GetPlayerStat (pc, IE_LEVEL3)+offset]
else:
Levels = []
for level in Level:
- Levels.append (level-1)
+ Levels.append (level+offset)
- #get some basic values
- Class = [GemRB.GetPlayerStat (pc, IE_CLASS)]
- Race = GemRB.GetPlayerStat (pc, IE_RACE)
+ if noclass:
+ return Levels, -1, -1
- #adjust the class for multi/dual chars
+ # adjust the class for multi/dual chars
+ Class = [GemRB.GetPlayerStat (pc, IE_CLASS)]
Multi = GUICommon.IsMultiClassed (pc, 1)
Dual = GUICommon.IsDualClassed (pc, 1)
NumClasses = 1
@@ -100,13 +96,27 @@ def SetupSavingThrows (pc, Level=None):
NumClasses = Multi[0]
Class = [Multi[1], Multi[2], Multi[3]]
elif Dual[0]: #only worry about the newer class
- Class = [CommonTables.Classes.GetValue (Dual[2], 5)]
+ Class = GUICommon.GetClassRowName(Dual[2], "index")
+ Class = [CommonTables.Classes.GetValue (Class, "ID")]
#assume Level is correct if passed
if GUICommon.IsDualSwap(pc) and not Level:
Levels = [Levels[1], Levels[0], Levels[2]]
- if NumClasses>len(Levels):
+
+ return Levels, NumClasses, Class
+
+def SetupSavingThrows (pc, Level=None):
+ """Updates an actors saving throws based upon level.
+
+ Level should contain the actors current level.
+ If Level is None, it is filled with the actors current level."""
+
+ Levels, NumClasses, Class = _SetupLevels (pc, Level, -1)
+ if NumClasses > len(Levels):
return
+ #get some basic values
+ Race = GemRB.GetPlayerStat (pc, IE_RACE)
+
#see if we can add racial bonuses to saves
Race = CommonTables.Races.GetRowName (CommonTables.Races.FindValue (3, Race) )
RaceSaveTableName = CommonTables.Races.GetValue (Race, "SAVE", 0)
@@ -121,8 +131,7 @@ def SetupSavingThrows (pc, Level=None):
SaveTables = []
ClassBonus = 0
for i in range (NumClasses):
- Row = CommonTables.Classes.FindValue (5, Class[i])
- RowName = CommonTables.Classes.GetRowName (Row)
+ RowName = GUICommon.GetClassRowName (Class[i], "class")
SaveName = CommonTables.Classes.GetValue (RowName, "SAVE", 0)
SaveTables.append (GemRB.LoadTable (SaveName) )
#use numeric value
@@ -159,14 +168,14 @@ def SetupSavingThrows (pc, Level=None):
def GetNextLevelFromExp (XP, Class):
"""Gets the next level based on current experience."""
- ClassIndex = CommonTables.Classes.FindValue (5, Class)
- ClassName = CommonTables.Classes.GetRowName (ClassIndex)
+ ClassName = GUICommon.GetClassRowName (Class, "class")
Row = CommonTables.NextLevel.GetRowIndex (ClassName)
- for i in range(1, CommonTables.NextLevel.GetColumnCount()-1):
+ NLNumCols = CommonTables.NextLevel.GetColumnCount()
+ for i in range(1, NLNumCols):
if XP < CommonTables.NextLevel.GetValue (Row, i):
return i
# fix hacked characters that have more xp than the xp cap
- return 40
+ return NLNumCols
def SetupThaco (pc, Level=None):
"""Updates an actors THAC0 based upon level.
@@ -174,35 +183,13 @@ def SetupThaco (pc, Level=None):
Level should contain the actors current level.
If Level is None it is filled with the actors current level."""
- #storing levels as an array makes them easier to deal with
- if not Level:
- Levels = [GemRB.GetPlayerStat (pc, IE_LEVEL)-1, \
- GemRB.GetPlayerStat (pc, IE_LEVEL2)-1, \
- GemRB.GetPlayerStat (pc, IE_LEVEL3)-1]
- else:
- Levels = []
- for level in Level:
- Levels.append (level-1)
+ Levels, NumClasses, Class = _SetupLevels (pc, Level, -1)
+ if NumClasses > len(Levels):
+ return
#get some basic values
- Class = [GemRB.GetPlayerStat (pc, IE_CLASS)]
ThacoTable = GemRB.LoadTable ("THAC0")
- #adjust the class for multi/dual chars
- Multi = GUICommon.IsMultiClassed (pc, 1)
- Dual = GUICommon.IsDualClassed (pc, 1)
- NumClasses = 1
- if Multi[0]>1: #get each of the multi-classes
- NumClasses = Multi[0]
- Class = [Multi[1], Multi[2], Multi[3]]
- elif Dual[0]: #only worry about the newer class
- Class = [CommonTables.Classes.GetValue (Dual[2], 5)]
- #assume Level is correct if passed
- if GUICommon.IsDualSwap(pc) and not Level:
- Levels = [Levels[1], Levels[0], Levels[2]]
- if NumClasses>len(Levels):
- return
-
#make sure to limit the levels to the table allowable
MaxLevel = ThacoTable.GetColumnCount ()-1
for i in range (len(Levels)):
@@ -214,7 +201,7 @@ def SetupThaco (pc, Level=None):
for i in range (NumClasses):
#loop through each class and update the save value if we have
#a better thac0
- ClassName = CommonTables.Classes.GetRowName (CommonTables.Classes.FindValue (5, Class[i]))
+ ClassName = GUICommon.GetClassRowName (Class[i], "class")
TmpThaco = ThacoTable.GetValue (ClassName, str(Levels[i]+1))
if TmpThaco < CurrentThaco:
NewThaco = 1
@@ -233,40 +220,18 @@ def SetupLore (pc, LevelDiff=None):
Level and LevelDiff must be of the same length.
If either are None, they are filled with the actors current level."""
- #storing levels as an array makes them easier to deal with
- if not LevelDiff:
- LevelDiffs = [GemRB.GetPlayerStat (pc, IE_LEVEL), \
- GemRB.GetPlayerStat (pc, IE_LEVEL2), \
- GemRB.GetPlayerStat (pc, IE_LEVEL3)]
- else:
- LevelDiffs = []
- for diff in LevelDiff:
- LevelDiffs.append (diff)
+ LevelDiffs, NumClasses, Class = _SetupLevels (pc, LevelDiff)
+ if NumClasses > len(LevelDiffs):
+ return
#get some basic values
- Class = [GemRB.GetPlayerStat (pc, IE_CLASS)]
LoreTable = GemRB.LoadTable ("lore")
- #adjust the class for multi/dual chars
- Multi = GUICommon.IsMultiClassed (pc, 1)
- Dual = GUICommon.IsDualClassed (pc, 1)
- NumClasses = 1
- if Multi[0]>1: #get each of the multi-classes
- NumClasses = Multi[0]
- Class = [Multi[1], Multi[2], Multi[3]]
- elif Dual[0]: #only worry about the newer class
- Class = [CommonTables.Classes.GetValue (Dual[2], 5)]
- #if LevelDiff is passed, we assume it is correct
- if GUICommon.IsDualSwap(pc) and not LevelDiff:
- LevelDiffs = [LevelDiffs[1], LevelDiffs[0], LevelDiffs[2]]
- if NumClasses>len(LevelDiffs):
- return
-
#loop through each class and update the lore value if we have
CurrentLore = GemRB.GetPlayerStat (pc, IE_LORE, 1)
for i in range (NumClasses):
#correct unlisted progressions
- ClassName = CommonTables.Classes.GetRowName (CommonTables.Classes.FindValue (5, Class[i]) )
+ ClassName = GUICommon.GetClassRowName (Class[i], "class")
if ClassName == "SORCERER":
ClassName = "MAGE"
elif ClassName == "MONK": #monks have a rate of 1, so this is arbitrary
@@ -289,30 +254,13 @@ def SetupHP (pc, Level=None, LevelDiff=None):
Level and LevelDiff must be of the same length.
If either are None, they are filled with the actors current level."""
- #storing levels as an array makes them easier to deal with
- if not Level:
- Levels = [GemRB.GetPlayerStat (pc, IE_LEVEL), \
- GemRB.GetPlayerStat (pc, IE_LEVEL2), \
- GemRB.GetPlayerStat (pc, IE_LEVEL3)]
- else:
- Levels = []
- for level in Level:
- Levels.append (level)
- if not LevelDiff:
- LevelDiffs = [GemRB.GetPlayerStat (pc, IE_LEVEL), \
- GemRB.GetPlayerStat (pc, IE_LEVEL2), \
- GemRB.GetPlayerStat (pc, IE_LEVEL3)]
- else:
- LevelDiffs = []
- for diff in LevelDiff:
- LevelDiffs.append (diff)
+ Levels, NumClasses, Class = _SetupLevels (pc, Level, noclass=1)
+ LevelDiffs, NumClasses, Class = _SetupLevels (pc, LevelDiff, noclass=1)
if len (Levels) != len (LevelDiffs):
return
- #get some basic values
- Class = [GemRB.GetPlayerStat (pc, IE_CLASS)]
-
#adjust the class for multi/dual chars
+ Class = [GemRB.GetPlayerStat (pc, IE_CLASS)]
Multi = GUICommon.IsMultiClassed (pc, 1)
Dual = GUICommon.IsDualClassed (pc, 1)
NumClasses = 1
@@ -323,7 +271,8 @@ def SetupHP (pc, Level=None, LevelDiff=None):
#we only get the hp bonus if the old class is reactivated
if (Levels[0]<=Levels[1]):
return
- Class = [CommonTables.Classes.GetValue (Dual[2], 5)]
+ Class = GUICommon.GetClassRowName(Dual[2], "index")
+ Class = [CommonTables.Classes.GetValue (Class, "ID")]
#if Level and LevelDiff are passed, we assume it is correct
if GUICommon.IsDualSwap(pc) and not Level and not LevelDiff:
LevelDiffs = [LevelDiffs[1], LevelDiffs[0], LevelDiffs[2]]
@@ -338,6 +287,10 @@ def SetupHP (pc, Level=None, LevelDiff=None):
if CommonTables.Classes.GetRowIndex (KitName) >= 0:
ClassName = KitName
+ # determine the minimum hp roll
+ ConBonTable = GemRB.LoadTable ("hpconbon")
+ MinRoll = ConBonTable.GetValue (GemRB.GetPlayerStat (pc, IE_CON)-1, 2) # MIN_ROLL column
+
#loop through each class and update the hp
OldHP = GemRB.GetPlayerStat (pc, IE_MAXHITPOINTS, 1)
CurrentHP = 0
@@ -345,7 +298,7 @@ def SetupHP (pc, Level=None, LevelDiff=None):
for i in range (NumClasses):
#check this classes hp table for any gain
if not ClassName or NumClasses > 1:
- ClassName = CommonTables.Classes.GetRowName (CommonTables.Classes.FindValue (5, Class[i]) )
+ ClassName = GUICommon.GetClassRowName (Class[i], "class")
HPTable = CommonTables.Classes.GetValue (ClassName, "HP")
HPTable = GemRB.LoadTable (HPTable)
@@ -367,20 +320,142 @@ def SetupHP (pc, Level=None, LevelDiff=None):
#add all the hp for the given level
#we use ceil to ensure each class gets hp
for level in range(LowLevel, HiLevel):
+ sides = HPTable.GetValue (level, 0)
rolls = HPTable.GetValue (level, 1)
bonus = HPTable.GetValue (level, 2)
- # we only do a roll if core diff or higher, or uncheck max
+ # we only do a roll on core difficulty or higher
+ # and if maximum HP rolls (bg2 and later) are disabled
+ # and/or if it is bg1 chargen (I guess too many testers got annoyed)
+ # BUT when we do roll, constitution gives a kind of a luck bonus to the roll
if rolls:
- if GemRB.GetVar ("Difficulty Level") >= 3 and not GemRB.GetVar ("Maximum HP"):
- CurrentHP += int (GemRB.Roll (rolls, HPTable.GetValue (level, 0), bonus) / Divisor + 0.5)
+ if GemRB.GetVar ("Difficulty Level") >= 3 and not GemRB.GetVar ("Maximum HP") \
+ and not (GUICommon.GameIsBG1() and LowLevel == 0) and MinRoll < sides:
+ if MinRoll > 1:
+ roll = GemRB.Roll (rolls, sides, bonus)
+ if roll-bonus < MinRoll:
+ roll = MinRoll + bonus
+ AddedHP = int (roll / Divisor + 0.5)
+ else:
+ AddedHP = int (GemRB.Roll (rolls, sides, bonus) / Divisor + 0.5)
else:
- CurrentHP += int ((rolls * HPTable.GetValue (level, 0) + bonus) / Divisor + 0.5)
+ AddedHP = int ((rolls * sides + bonus) / Divisor + 0.5)
else:
- CurrentHP += int (bonus / Divisor + 0.5)
- CurrentHP = int (CurrentHP)
+ AddedHP = int (bonus / Divisor + 0.5)
+ # ensure atleast 1hp is given
+ # this is safe for inactive dualclass levels too (handled above)
+ if AddedHP == 0:
+ AddedHP = 1
+ CurrentHP += AddedHP
#update our hp values
GemRB.SetPlayerStat (pc, IE_MAXHITPOINTS, CurrentHP+OldHP)
- GemRB.SetPlayerStat (pc, IE_HITPOINTS, GemRB.GetPlayerStat (pc, IE_HITPOINTS, 1)+CurrentHP)
+ # HACK: account also for the new constitution bonus for the current hitpoints
+ GemRB.SetPlayerStat (pc, IE_HITPOINTS, GemRB.GetPlayerStat (pc, IE_HITPOINTS, 1)+CurrentHP+5)
return
+
+def ApplyFeats(MyChar):
+
+ #don't mess with feats outside of IWD2
+ if not GUICommon.GameIsIWD2():
+ return
+
+ #feats giving a single innate ability
+ SetSpell(MyChar, "SPIN111", FEAT_WILDSHAPE_BOAR)
+ SetSpell(MyChar, "SPIN197", FEAT_MAXIMIZED_ATTACKS)
+ SetSpell(MyChar, "SPIN231", FEAT_ENVENOM_WEAPON)
+ SetSpell(MyChar, "SPIN245", FEAT_WILDSHAPE_PANTHER)
+ SetSpell(MyChar, "SPIN246", FEAT_WILDSHAPE_SHAMBLER)
+ SetSpell(MyChar, "SPIN275", FEAT_POWER_ATTACK)
+ SetSpell(MyChar, "SPIN276", FEAT_EXPERTISE)
+ SetSpell(MyChar, "SPIN277", FEAT_ARTERIAL_STRIKE)
+ SetSpell(MyChar, "SPIN278", FEAT_HAMSTRING)
+ SetSpell(MyChar, "SPIN279", FEAT_RAPID_SHOT)
+
+ #extra rage
+ level = GemRB.GetPlayerStat(MyChar, IE_LEVELBARBARIAN)
+ if level>0:
+ if level>=15:
+ GemRB.RemoveSpell(MyChar, "SPIN236")
+ Spell = "SPIN260"
+ else:
+ GemRB.RemoveSpell(MyChar, "SPIN260")
+ Spell = "SPIN236"
+ cnt = GemRB.GetPlayerStat (MyChar, IE_FEAT_EXTRA_RAGE)+(level+3)/4
+ GUICommon.MakeSpellCount(MyChar, Spell, cnt)
+ else:
+ GemRB.RemoveSpell(MyChar, "SPIN236")
+ GemRB.RemoveSpell(MyChar, "SPIN260")
+
+ #TODO: extra shapeshifting
+ #GUICommon.MakeSpellCount(MyChar, "", cnt)
+
+ #extra smiting
+ level = GemRB.GetPlayerStat(MyChar, IE_LEVELPALADIN)
+ if level>1:
+ cnt = GemRB.GetPlayerStat (MyChar, IE_FEAT_EXTRA_SMITING) + 1
+ GUICommon.MakeSpellCount(MyChar, "SPIN152", cnt)
+ else:
+ GemRB.RemoveSpell(MyChar, "SPIN152")
+
+ #extra turning
+ level = GemRB.GetPlayerStat(MyChar, IE_TURNUNDEADLEVEL)
+ if level>0:
+ cnt = GUICommon.GetAbilityBonus(MyChar, IE_CHR) + 3
+ if cnt<1: cnt = 1
+ cnt += GemRB.GetPlayerStat (MyChar, IE_FEAT_EXTRA_TURNING)
+ GUICommon.MakeSpellCount(MyChar, "SPIN970", cnt)
+ else:
+ GemRB.RemoveSpell(MyChar, "SPIN970")
+
+ #stunning fist
+ if GemRB.HasFeat (MyChar, FEAT_STUNNING_FIST):
+ cnt = GemRB.GetPlayerStat(MyChar, IE_CLASSLEVELSUM) / 4
+ GUICommon.MakeSpellCount(MyChar, "SPIN232", cnt)
+ else:
+ GemRB.RemoveSpell(MyChar, "SPIN232")
+
+ #remove any previous SPLFOCUS
+ #GemRB.ApplyEffect(MyChar, "RemoveEffects",0,0,"SPLFOCUS")
+ #spell focus stats
+ SPLFocusTable = GemRB.LoadTable ("splfocus")
+ for i in range(SPLFocusTable.GetRowCount()):
+ Row = SPLFocusTable.GetRowName(i)
+ Stat = SPLFocusTable.GetValue(Row, "STAT", 2)
+ if Stat:
+ Column = GemRB.GetPlayerStat(MyChar, Stat)
+ if Column:
+ Value = SPLFocusTable.GetValue(i, Column)
+ if Value:
+ #add the effect, value could be 2 or 4, timing mode is 8 - so it is not saved
+ GemRB.ApplyEffect(MyChar, "SpellFocus", Value, i,"","","","SPLFOCUS", 8)
+ return
+
+def SetSpell(pc, SpellName, Feat):
+ if GemRB.HasFeat (pc, Feat):
+ GUICommon.MakeSpellCount(pc, SpellName, 1)
+ else:
+ GemRB.RemoveSpell(pc, SpellName)
+ return
+
+def AddPlayerStat(MyChar, stat, value):
+ value += GemRB.GetPlayerStat (MyChar, stat, 0)
+ #print "Set: ", stat," to ", value
+ GemRB.SetPlayerStat (MyChar, stat, value)
+ return
+
+def SetClassResistances(MyChar, clsstitle):
+ resistances = GemRB.LoadTable ("clssrsmd")
+ AddPlayerStat (MyChar, IE_RESISTFIRE, resistances.GetValue ( clsstitle, "FIRE") )
+ AddPlayerStat (MyChar, IE_RESISTCOLD, resistances.GetValue ( clsstitle, "COLD") )
+ AddPlayerStat (MyChar, IE_RESISTELECTRICITY, resistances.GetValue ( clsstitle, "ELEC") )
+ AddPlayerStat (MyChar, IE_RESISTACID, resistances.GetValue ( clsstitle, "ACID") )
+ AddPlayerStat (MyChar, IE_RESISTMAGIC, resistances.GetValue ( clsstitle, "SPELL") )
+ AddPlayerStat (MyChar, IE_RESISTMAGICFIRE, resistances.GetValue ( clsstitle, "MAGIC_FIRE") )
+ AddPlayerStat (MyChar, IE_RESISTMAGICCOLD, resistances.GetValue ( clsstitle, "MAGIC_COLD") )
+ AddPlayerStat (MyChar, IE_RESISTSLASHING, resistances.GetValue ( clsstitle, "SLASHING") )
+ AddPlayerStat (MyChar, IE_RESISTCRUSHING, resistances.GetValue ( clsstitle, "BLUDGEONING") )
+ AddPlayerStat (MyChar, IE_RESISTPIERCING, resistances.GetValue ( clsstitle, "PIERCING") )
+ AddPlayerStat (MyChar, IE_RESISTMISSILE, resistances.GetValue ( clsstitle, "MISSILE") )
+ return
+
diff --git a/gemrb/GUIScripts/LUProfsSelection.py b/gemrb/GUIScripts/LUProfsSelection.py
index 55be6e4..7987596 100644
--- a/gemrb/GUIScripts/LUProfsSelection.py
+++ b/gemrb/GUIScripts/LUProfsSelection.py
@@ -198,38 +198,39 @@ def SetupProfsWindow (pc, type, window, callback, level1=[0,0,0], level2=[1,1,1]
if classid: #for dual classes when we can't get the class dualing to
Class = classid
elif IsDual[0]:
- Class = CommonTables.Classes.GetValue (IsDual[2], 5)
+ Class = GUICommon.GetClassRowName(IsDual[2], "index")
+ Class = CommonTables.Classes.GetValue (Class, "ID")
else:
Class = GemRB.GetPlayerStat (pc, IE_CLASS)
- ClassName = CommonTables.Classes.FindValue (5, Class)
- ClassName = CommonTables.Classes.GetRowName (ClassName)
- if ClassName == "SORCERER":
- ClassName = "MAGE"
- ClassNameSave = ClassName
+ ClassName = GUICommon.GetClassRowName (Class, "class")
- #find the class with the greatest prof potential
- FastestProf = 0
- ProfsRate = 100
- IsMulti = GUICommon.IsMultiClassed (pc, 1)
- if IsMulti[0] > 1:
- for i in range (1, IsMulti[0]+1):
- TmpRate = ProfsTable.GetValue (IsMulti[i]-1, 1)
- if TmpRate < ProfsRate:
- ProfsRate = TmpRate
- FastestProf = i-1
- else:
- ProfsRate = ProfsTable.GetValue (Class-1, 1)
+ # profs.2da has entries for everyone, so no need to muck around
+ ProfsRate = ProfsTable.GetValue (ClassName, "RATE")
#figure out how many prof points we have
if sum (level1) == 0: #character is being generated (either chargen or dual)
ProfsPointsLeft = ProfsTable.GetValue (ClassName, "FIRST_LEVEL")
- #we need these 2 number to floor before subtracting
- ProfsPointsLeft += level2[FastestProf]/ProfsRate - level1[FastestProf]/ProfsRate
+ ProfIndex = 0
+ IsMulti = GUICommon.IsMultiClassed (pc, 1)
+ if IsMulti[0] > 1:
+ # sum the levels, since the rate is for the combined multiclass
+ ProfsPointsLeft += (sum(level2) - sum(level1))/ProfsRate
+ else:
+ if GUICommon.IsDualSwap (pc):
+ ProfIndex = 1
+
+ #we need these 2 number to floor before subtracting
+ ProfsPointsLeft += level2[ProfIndex]/ProfsRate - level1[ProfIndex]/ProfsRate
#setup prof vars for passing between functions
ProfsTable = GemRB.LoadTable ("weapprof")
+ # weapprof has no sorcerer entry
+ if ClassName == "SORCERER":
+ ClassName = "MAGE"
+ ClassNameSave = ClassName
+
# if we have the classweapons table, use it
if ClassWeaponsTable:
ProfsColumn = ClassWeaponsTable.GetRowIndex (ClassName)
@@ -254,7 +255,7 @@ def SetupProfsWindow (pc, type, window, callback, level1=[0,0,0], level2=[1,1,1]
if ProfName > 0x1000000 or ProfName < 0:
ProfCount -= 1
- #we only need the low 3 bits for profeciencies on levelup; otherwise
+ #we only need the low 3 bits for proficiencies on levelup; otherwise
#we just set them all to 0
currentprof = 0
if type == LUPROFS_TYPE_LEVELUP:
@@ -271,7 +272,10 @@ def SetupProfsWindow (pc, type, window, callback, level1=[0,0,0], level2=[1,1,1]
#see if we can assign to this prof
if ClassWeaponsTable:
- maxprof = ClassWeaponsTable.GetValue (ProfsColumn, i) # this table has profs as rows
+ # this table has profs as rows, so ignore the wierd use of the column var
+ # it also has different ordering than ProfsTable
+ col = ClassWeaponsTable.GetColumnIndex (ProfsTable.GetRowName(i))
+ maxprof = ClassWeaponsTable.GetValue (ProfsColumn, col)
else:
maxprof = ProfsTable.GetValue(i+ProfsTableOffset, ProfsColumn)
if maxprof > currentprof:
@@ -420,14 +424,14 @@ def ProfsLeftPress():
return
if GUICommon.GameIsIWD1() or GUICommon.GameIsBG1():
ProfMaxTable = GemRB.LoadTable ("profsmax")
- MaxProf = ProfMaxTable.GetValue(ClassNameSave, "OTHER_LEVELS")
+ if ProfsType == LUPROFS_TYPE_CHARGEN:
+ MaxProf = ProfMaxTable.GetValue(ClassNameSave, "FIRST_LEVEL")
+ else:
+ MaxProf = ProfMaxTable.GetValue(ClassNameSave, "OTHER_LEVELS")
else:
MaxProf = ProfsTable.GetValue(Pos+ProfsTableOffset, ProfsColumn)
if MaxProf>5:
MaxProf = 5
- # FIXME: use profsmax.2da (in all games? could be problematic for weapon styles)
- #if (MaxProf>2) and GUICommon.GameIsBG1():
- # MaxProf = 2
ActPoint = GemRB.GetVar("Prof "+str(Pos) )
if ActPoint >= MaxProf:
diff --git a/gemrb/GUIScripts/LUSkillsSelection.py b/gemrb/GUIScripts/LUSkillsSelection.py
index 2e5fdde..d5a1c4a 100644
--- a/gemrb/GUIScripts/LUSkillsSelection.py
+++ b/gemrb/GUIScripts/LUSkillsSelection.py
@@ -131,10 +131,11 @@ def SetupSkillsWindow (pc, type, window, callback, level1=[0,0,0], level2=[1,1,1
if classid: #used when dual-classing
Class = classid
elif IsDual[0]: #only care about the current class
- Class = CommonTables.Classes.GetValue (IsDual[2], 5)
+ Class = GUICommon.GetClassRowName(IsDual[2], "index")
+ Class = CommonTables.Classes.GetValue (Class, "ID")
else:
Class = GemRB.GetPlayerStat (pc, IE_CLASS)
- ClassName = CommonTables.Classes.GetRowName (CommonTables.Classes.FindValue (5, Class) )
+ ClassName = GUICommon.GetClassRowName(Class, "class")
#get the number of classes
if IsMulti[0]>1:
@@ -158,7 +159,8 @@ def SetupSkillsWindow (pc, type, window, callback, level1=[0,0,0], level2=[1,1,1
TmpClass = Class
if NumClasses > 1:
TmpClass = IsMulti[i+1]
- if (CommonTables.ClassSkills.GetValue (TmpClass, 5, 0) != "*"):
+ TmpClass = GUICommon.GetClassRowName (TmpClass, "class")
+ if (CommonTables.ClassSkills.GetValue (TmpClass, "THIEFSKILL", 0) != "*"):
SkillIndex = i
break
@@ -169,6 +171,7 @@ def SetupSkillsWindow (pc, type, window, callback, level1=[0,0,0], level2=[1,1,1
#also allows for thief kits
SkillsAssignable = 1
for i in range(SkillsTable.GetRowCount()-2):
+ # -2/+2 to compensate for the special first_level and rate rows
SkillName = SkillsTable.GetRowName (i+2)
if SkillsTable.GetValue (SkillName, SkillsKitName) != -1:
SkillsIndices.append(i)
@@ -186,21 +189,17 @@ def SetupSkillsWindow (pc, type, window, callback, level1=[0,0,0], level2=[1,1,1
#really don't have an entry
SkillPointsLeft = 0
else:
- #get racial values for dual-classing
- SkillRacTable = GemRB.LoadTable ("SKILLRAC")
- Race = CommonTables.Races.FindValue (3, GemRB.GetPlayerStat (pc, IE_RACE))
- Race = CommonTables.Races.GetRowName (Race)
-
#get the skill values
for i in range(SkillsTable.GetRowCount()-2):
+ # -2/+2 to compensate for the special first_level and rate rows
SkillName = SkillsTable.GetRowName (i+2)
SkillID = SkillsTable.GetValue (SkillName, "ID")
- if type != LUSKILLS_TYPE_LEVELUP: #give racial bonuses to starting classes
- SkillValue = SkillRacTable.GetValue (Race, SkillName)
- else:
- SkillValue = GemRB.GetPlayerStat (pc, SkillID, 1)
+ SkillValue = GemRB.GetPlayerStat (pc, SkillID)
+ BaseSkillValue = GemRB.GetPlayerStat (pc, SkillID, 1)
GemRB.SetVar("Skill "+str(i), SkillValue)
GemRB.SetVar("SkillBase "+str(i), SkillValue)
+ # display the modified stat to avoid confusion (account for dex, race and effect boni)
+ GemRB.SetVar("SkillDisplayMod "+str(i), SkillValue-BaseSkillValue)
TotalSkillsAssignable += LUSKILLS_MAX-SkillValue
#protect against having more skills than we can assign
@@ -215,7 +214,7 @@ def SetupSkillsWindow (pc, type, window, callback, level1=[0,0,0], level2=[1,1,1
classname = IsMulti[i+1]
else:
classname = Class
- classname = CommonTables.Classes.GetRowName (CommonTables.Classes.FindValue (5, classname))
+ classname = GUICommon.GetClassRowName (classname, "class")
for table in "RANGERSKILL", "BARDSKILL":
SpecialSkillsTable = CommonTables.ClassSkills.GetValue (classname, table)
if SpecialSkillsTable != "*":
@@ -242,7 +241,7 @@ def SetupSkillsWindow (pc, type, window, callback, level1=[0,0,0], level2=[1,1,1
if len(SkillsIndices) > SkillsNumButtons:
ScrollBar.SetEvent (IE_GUI_SCROLLBAR_ON_CHANGE, SkillScrollBarPress)
#decrease it with the number of controls on screen (list size) and two unrelated rows
- ScrollBar.SetVarAssoc ("SkillsTopIndex", SkillsTable.GetRowCount()-SkillsNumButtons-1)
+ ScrollBar.SetVarAssoc ("SkillsTopIndex", SkillsTable.GetRowCount()-SkillsNumButtons-2)
else:
if len(SkillsIndices) and SkillsAssignable:
#autoscroll to the first valid skill; luckily all three monk ones are adjacent
@@ -382,8 +381,8 @@ def SkillsSave (pc):
for i in range(SkillsTable.GetRowCount() - 2):
SkillName = SkillsTable.GetRowName (i+2)
SkillID = SkillsTable.GetValue (SkillName, "ID")
- SkillValue = GemRB.GetVar ("Skill "+str(i))
- if SkillValue >= 0:
+ SkillValue = GemRB.GetVar ("Skill "+str(i)) - GemRB.GetVar("SkillDisplayMod "+str(i))
+ if SkillValue > 0:
GemRB.SetPlayerStat (pc, SkillID, SkillValue)
def SkillsNullify ():
diff --git a/gemrb/GUIScripts/LUSpellSelection.py b/gemrb/GUIScripts/LUSpellSelection.py
index 2ed1790..c2a4af3 100644
--- a/gemrb/GUIScripts/LUSpellSelection.py
+++ b/gemrb/GUIScripts/LUSpellSelection.py
@@ -18,10 +18,11 @@
#
import GemRB
+import GUICommon
+import Spellbook
from GUIDefines import *
from ie_stats import *
from ie_restype import RES_BAM
-import GUICommon
# storage variables
pc = 0
@@ -37,6 +38,8 @@ SpellsSelectPointsLeft = [0]*9 # << spell selections left per level
Spells = [0]*9 # << spells learnable per level
SpellTopIndex = 0 # << scroll bar index
SpellBook = [] # << array containing all the spell indexes to learn
+MemoBook = [0]*24 # array containing all the spell indexes to memorize
+Memorization = 0 # marker for the memorisation part
SpellLevel = 0 # << current level of spells
SpellStart = 0 # << starting id of the spell list
SpellPointsLeftLabel = 0 # << label indicating the number of points left
@@ -59,10 +62,10 @@ def OpenSpellsWindow (actor, table, level, diff, kit=0, gen=0, recommend=True):
global SpellsWindow, DoneButton, SpellsSelectPointsLeft, Spells, chargen, SpellPointsLeftLabel
global SpellsTextArea, SpellsKnownTable, SpellTopIndex, SpellBook, SpellLevel, pc, SpellStart
- global KitMask, EnhanceGUI
+ global KitMask, EnhanceGUI, Memorization
#enhance GUI?
- if (GemRB.GetVar("GUIEnhancements")):
+ if (GemRB.GetVar("GUIEnhancements")&GE_SCROLLBARS):
EnhanceGUI = 1
# save our pc
@@ -129,6 +132,7 @@ def OpenSpellsWindow (actor, table, level, diff, kit=0, gen=0, recommend=True):
# setup our variables
GemRB.SetVar ("SpellTopIndex", 0)
+ Memorization = 0
# the done button also doubles as a next button
DoneButton.SetState(IE_GUI_BUTTON_DISABLED)
@@ -157,13 +161,13 @@ def OpenSpellsWindow (actor, table, level, diff, kit=0, gen=0, recommend=True):
SpellsSelectPointsLeft[i] += 1
# get all the spells of the given level
- Spells[i] = GUICommon.GetMageSpells (KitMask, GemRB.GetPlayerStat (pc, IE_ALIGNMENT), i+1)
+ Spells[i] = Spellbook.GetMageSpells (KitMask, GemRB.GetPlayerStat (pc, IE_ALIGNMENT), i+1)
# dump all the spells we already know
NumDeleted = 0
for j in range (len (Spells[i])):
CurrentIndex = j - NumDeleted # this ensure we don't go out of range
- if GUICommon.HasSpell (pc, IE_SPELL_TYPE_WIZARD, i, Spells[i][CurrentIndex][0]) >= 0:
+ if Spellbook.HasSpell (pc, IE_SPELL_TYPE_WIZARD, i, Spells[i][CurrentIndex][0]) >= 0:
del Spells[i][CurrentIndex]
NumDeleted += 1
@@ -214,37 +218,60 @@ def SpellsDonePress ():
If there is not another assignable level, then save all the new spells and
close the window."""
- global SpellBook, SpellLevel, SpellsWindow
+ global SpellBook, SpellLevel, SpellsWindow, MemoBook, Memorization
- # save all the spells
- for i in range (len (Spells[SpellLevel])):
- if SpellBook[i]: # we need to learn this spell
- GemRB.LearnSpell (pc, Spells[SpellLevel][i][0])
-
- # check to see if we need to update again
- for i in range (SpellLevel+1, 9):
- if SpellsSelectPointsLeft[i] > 0:
- # reset the variables
- GemRB.SetVar ("SpellTopIndex", 0)
- SpellLevel = i
- SpellBook = [0]*len(Spells[i])
+ # oops, we were here before, just memorise the spells and exit
+ if sum(MemoBook) > 0:
+ for i in MemoBook:
+ if i:
+ GemRB.MemorizeSpell(pc, IE_SPELL_TYPE_WIZARD, SpellLevel, i-1, 1)
+ SpellBook = []
+ MemoBook = [0]*24
- if (EnhanceGUI):
- # setup the scrollbar
- ScrollBar = SpellsWindow.GetControl (1000)
- if len (Spells[i]) > ( 24 + ExtraSpellButtons() ):
- HideUnhideScrollBar(0)
- if chargen:
- ScrollBar.SetVarAssoc ("SpellTopIndex", GUICommon.ceildiv ( ( len (Spells[i])-24 ) , 6 ) + 1 )
+ # save all the spells
+ if not Memorization:
+ for i in range (len (Spells[SpellLevel])):
+ if SpellBook[i]: # we need to learn this spell
+ GemRB.LearnSpell (pc, Spells[SpellLevel][i][0])
+
+ # check to see if we need to update again
+ for i in range (SpellLevel+1, 9):
+ if SpellsSelectPointsLeft[i] > 0:
+ # reset the variables
+ GemRB.SetVar ("SpellTopIndex", 0)
+ SpellLevel = i
+ if not (chargen and GUICommon.GameIsBG1()):
+ SpellBook = [0]*len(Spells[i])
+
+ if (EnhanceGUI):
+ # setup the scrollbar
+ ScrollBar = SpellsWindow.GetControl (1000)
+ if len (Spells[i]) > ( 24 + ExtraSpellButtons() ):
+ HideUnhideScrollBar(0)
+ if chargen:
+ ScrollBar.SetVarAssoc ("SpellTopIndex", GUICommon.ceildiv ( ( len (Spells[i])-24 ) , 6 ) + 1 )
+ else:
+ ScrollBar.SetVarAssoc ("SpellTopIndex", GUICommon.ceildiv ( ( len (Spells[i])-25 ) , 5 ) + 1 )
else:
- ScrollBar.SetVarAssoc ("SpellTopIndex", GUICommon.ceildiv ( ( len (Spells[i])-25 ) , 5 ) + 1 )
- else:
- ScrollBar.SetVarAssoc ("SpellTopIndex", 0)
- HideUnhideScrollBar(1)
+ ScrollBar.SetVarAssoc ("SpellTopIndex", 0)
+ HideUnhideScrollBar(1)
- # show the spells and set the done button to off
- ShowSpells ()
+ # show the spells and set the done button to off
+ ShowSpells ()
+ DoneButton.SetState (IE_GUI_BUTTON_DISABLED)
+ return
+
+ # bg1 lets you memorize spells too (iwd too, but it does it by itself)
+ # TODO: check iwd2, which is currently lacking all spell handling
+ if chargen and GUICommon.GameIsBG1() and sum(MemoBook) == 0:
+ SpellLevel = 0
+ SpellsSelectPointsLeft[SpellLevel] = 1
+ if KitMask != 0x4000:
+ # specialists get an extra spell per level
+ SpellsSelectPointsLeft[SpellLevel] += 1
DoneButton.SetState (IE_GUI_BUTTON_DISABLED)
+ Memorization = 1
+ ShowKnownSpells()
return
# close our window and update our records
@@ -264,6 +291,86 @@ def SpellsDonePress ():
return
+def ShowKnownSpells ():
+ """Shows the viewable 24 spells."""
+
+ j = RowIndex()
+ Spells[SpellLevel] = Spellbook.GetMageSpells (KitMask, GemRB.GetPlayerStat (pc, IE_ALIGNMENT), SpellLevel+1)
+
+ # reset the title
+ #17224 for priest spells
+ Title = SpellsWindow.GetControl (0x10000000)
+ Title.SetText(17189)
+
+ # we have a grid of 24 spells
+ for i in range (24):
+ # ensure we can learn this many spells
+ SpellButton = SpellsWindow.GetControl (i+SpellStart)
+ if i + j >= len (SpellBook) or not SpellBook[i+j]:
+ SpellButton.SetState (IE_GUI_BUTTON_DISABLED)
+ SpellButton.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
+ continue
+ else:
+ SpellButton.SetState (IE_GUI_BUTTON_ENABLED)
+ SpellButton.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_NAND)
+
+ # fill in the button with the spell data
+ Spell = GemRB.GetSpell (Spells[SpellLevel][i+j][0], 1)
+ SpellButton.SetTooltip(Spell['SpellName'])
+ SpellButton.SetVarAssoc("MemorizePressed", i)
+ SpellButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, MemorizePress)
+ if GUICommon.GameIsBG2():
+ SpellButton.SetSprites("GUIBTBUT",0, 0,1,2,3)
+ else:
+ SpellButton.SetSprites("GUIBTBUT",0, 0,1,24,25)
+ SpellButton.SetBorder (0, 0,0, 0,0, 0,0,0,0, 0,0)
+
+ SpellButton.SetSpellIcon(Spells[SpellLevel][i+j][0], 1)
+ SpellButton.SetFlags(IE_GUI_BUTTON_PICTURE, OP_OR)
+
+ # show which spells are selected
+ ShowSelectedSpells ()
+
+ GemRB.SetToken("number", str(SpellsSelectPointsLeft[SpellLevel]))
+ SpellsTextArea.SetText(17253)
+
+ return
+
+def MemorizePress ():
+ """Toggles the memorisation of the given spell."""
+
+ global SpellsSelectPointsLeft, Spells, SpellBook, MemoBook
+
+ # get our variables
+ j = RowIndex()
+ i = GemRB.GetVar ("MemorizePressed") + j
+
+ # get the spell that's been pushed
+ Spell = GemRB.GetSpell (Spells[SpellLevel][i][0], 1)
+ SpellsTextArea.SetText (Spell["SpellDesc"])
+
+ # make sure we can learn the spell
+ if MemoBook[i]: # already picked -- unselecting
+ SpellsSelectPointsLeft[SpellLevel] = SpellsSelectPointsLeft[SpellLevel] + 1
+ MemoBook[i] = 0
+ DoneButton.SetState (IE_GUI_BUTTON_DISABLED)
+ else: # selecting
+ # we don't have any picks left
+ if SpellsSelectPointsLeft[SpellLevel] == 0:
+ MarkButton (i, 0)
+ return
+
+ # select the spell and change the done state if need be
+ SpellsSelectPointsLeft[SpellLevel] = SpellsSelectPointsLeft[SpellLevel] - 1
+ MemoBook[i] = Spellbook.HasSpell(pc, IE_SPELL_TYPE_WIZARD, SpellLevel, Spells[SpellLevel][i][0]) + 1 # so all values are above 0
+ if SpellsSelectPointsLeft[SpellLevel] == 0:
+ DoneButton.SetState (IE_GUI_BUTTON_ENABLED)
+
+ # show selected spells
+ ShowSelectedSpells ()
+
+ return
+
def ShowSpells ():
"""Shows the viewable 24 spells."""
@@ -307,7 +414,7 @@ def ShowSpells ():
else: # specialist (shouldn't get here)
# use the green border state for matching specialist spells
SpellButton.SetBorder (0, 0,0, 0,0, 0,0,0,0, 0,0)
- SpellButton.SetState (IE_GUI_BUTTON_THIRD)
+ SpellButton.SetState (IE_GUI_BUTTON_FAKEDISABLED)
# show which spells are selected
ShowSelectedSpells ()
@@ -376,7 +483,7 @@ def MarkButton (i, select):
type = IE_GUI_BUTTON_ENABLED
elif Spells[SpellLevel][i][1] == 2:
# specialist spell
- type = IE_GUI_BUTTON_THIRD
+ type = IE_GUI_BUTTON_FAKEDISABLED
else: # can't learn
type = IE_GUI_BUTTON_LOCKED
@@ -394,7 +501,7 @@ def ShowSelectedSpells ():
for j in range (24 + ExtraSpellButtons()):
if j + k >= len (SpellBook): # make sure we don't call unavailable indexes
break
- if SpellBook[j+k]: # selected
+ if (SpellBook[j+k] and not Memorization) or (Memorization and MemoBook[j+k]): # selected
MarkButton (j+k, 1)
else: # not selected
MarkButton (j+k, 0)
@@ -409,7 +516,7 @@ def SpellsCancelPress ():
This is only callable within character generation."""
# remove all learned spells
- GUICommon.RemoveKnownSpells (pc, IE_SPELL_TYPE_WIZARD, 1, 9, 1)
+ Spellbook.RemoveKnownSpells (pc, IE_SPELL_TYPE_WIZARD, 1, 9, 1)
if GUICommon.GameIsBG2():
# unload teh window and go back
diff --git a/gemrb/GUIScripts/LevelUp.py b/gemrb/GUIScripts/LevelUp.py
index 4c0ffd0..88cb77c 100644
--- a/gemrb/GUIScripts/LevelUp.py
+++ b/gemrb/GUIScripts/LevelUp.py
@@ -23,6 +23,7 @@ from GUIDefines import *
from ie_stats import *
from ie_restype import RES_2DA
import GUICommon
+import Spellbook
import CommonTables
import LUSpellSelection
import LUCommon
@@ -128,11 +129,10 @@ def OpenLevelUpWindow():
Class = GemRB.GetPlayerStat (pc, IE_CLASS)
print "Class:",Class,"\tActor Class:",actor.classid
- ClassIndex = CommonTables.Classes.FindValue (5, Class)
SkillTable = GemRB.LoadTable("skills")
# kit
- ClassName = CommonTables.Classes.GetRowName(ClassIndex)
+ ClassName = GUICommon.GetClassRowName (Class, "class")
Kit = GUICommon.GetKitIndex (pc)
print "Kit:", Kit, "\tActor Kit:",actor.KitIndex()
print "ClassName:",ClassName,"\tActor ClassNames:",actor.ClassNames()
@@ -173,7 +173,8 @@ def OpenLevelUpWindow():
if IsDual[0] == 1: # kit
Classes[1] = CommonTables.KitList.GetValue (IsDual[1], 7)
else: # class
- Classes[1] = CommonTables.Classes.GetValue (Classes[1], 5)
+ TmpClassName = GUICommon.GetClassRowName (Classes[1], "class")
+ Classes[1] = CommonTables.Classes.GetValue (TmpClassName, "ID")
# store a boolean for IsDual
IsDual = IsDual[0] > 0
@@ -188,9 +189,9 @@ def OpenLevelUpWindow():
if IsDual:
# convert the classes from indicies to class id's
DualSwap = GUICommon.IsDualSwap (pc)
- ClassName = CommonTables.Classes.GetRowName (Classes[0])
+ ClassName = GUICommon.GetClassRowName (Classes[0], "class")
KitName = ClassName # for simplicity throughout the code
- Classes[0] = CommonTables.Classes.GetValue (Classes[0], 5)
+ Classes[0] = CommonTables.Classes.GetValue (ClassName, "ID")
# Class[1] is taken care of above
# we need the old level as well
@@ -218,10 +219,7 @@ def OpenLevelUpWindow():
# we don't care about the current level, but about the to-be-achieved one
# get the next level
Level[i] = LUCommon.GetNextLevelFromExp (GemRB.GetPlayerStat (pc, IE_XP)/NumClasses, Classes[i])
- TmpIndex = CommonTables.Classes.FindValue (5, Classes[i])
- TmpName = CommonTables.Classes.GetRowName (TmpIndex)
-
-# print "Name:",TmpName
+ TmpClassName = GUICommon.GetClassRowName (Classes[i], "class")
# find the level diff for each classes (3 max, obviously)
if i == 0:
@@ -239,9 +237,9 @@ def OpenLevelUpWindow():
# save our current and next spell amounts
StartLevel = Level[i] - LevelDiff[i]
- DruidTable = CommonTables.ClassSkills.GetValue (Classes[i], 0, 0)
- ClericTable = CommonTables.ClassSkills.GetValue (Classes[i], 1, 0)
- MageTable = CommonTables.ClassSkills.GetValue (Classes[i], 2, 0)
+ DruidTable = CommonTables.ClassSkills.GetValue (TmpClassName, "DRUIDSPELL", 0)
+ ClericTable = CommonTables.ClassSkills.GetValue (TmpClassName, "CLERICSPELL", 0)
+ MageTable = CommonTables.ClassSkills.GetValue (TmpClassName, "MAGESPELL", 0)
# see if we have mage spells
if MageTable != "*":
@@ -287,7 +285,7 @@ def OpenLevelUpWindow():
# setup class bonuses for this class
if IsMulti or IsDual or Kit == 0:
- ABTable = CommonTables.ClassSkills.GetValue (TmpName, "ABILITIES")
+ ABTable = CommonTables.ClassSkills.GetValue (TmpClassName, "ABILITIES")
else: # single-classed with a kit
ABTable = CommonTables.KitList.GetValue (str(Kit), "ABILITIES")
@@ -319,8 +317,7 @@ def OpenLevelUpWindow():
for i in range (NumClasses):
if IsMulti:
# get the row name for lookup ex. MULTI2FIGHTER, MULTI3THIEF
- MultiName = CommonTables.Classes.FindValue (5, Classes[i])
- MultiName = CommonTables.Classes.GetRowName (MultiName)
+ MultiName = GUICommon.GetClassRowName (Classes[i], "class")
MultiName = "MULTI" + str(NumClasses) + MultiName
else:
MultiName = ClassName
@@ -444,8 +441,7 @@ def GetLevelUpNews():
for i in range(NumClasses):
# get the class name
- TmpClassName = CommonTables.Classes.FindValue (5, Classes[i])
- TmpClassName = CommonTables.Classes.GetRowName (TmpClassName)
+ TmpClassName = GUICommon.GetClassRowName (Classes[i], "class")
# backstab
# NOTE: Stalkers and assassins should get the correct mods at the correct levels based
@@ -458,12 +454,12 @@ def GetLevelUpNews():
BackstabMult = BackstabTable.GetValue (0, Level[i])
# lay on hands
- if (CommonTables.ClassSkills.GetValue (Classes[i], 6) != "*"):
+ if (CommonTables.ClassSkills.GetValue (TmpClassName, "LAYHANDS") != "*"):
# inquisitors and undead hunters don't get lay on hands out the chute, whereas cavaliers
# and unkitted paladins do; therefore, we check for the existence of lay on hands to ensure
# the character should get the new value; LoH is defined in GA_SPCL211 if anyone wants to
# make a pally kit with LoH
- if (GUICommon.HasSpell (pc, IE_SPELL_TYPE_INNATE, 0, "SPCL211") >= 0):
+ if (Spellbook.HasSpell (pc, IE_SPELL_TYPE_INNATE, 0, "SPCL211") >= 0):
LOHTable = GemRB.LoadTable ("layhands")
LOHGain = LOHTable.GetValue (0, Level[i]) - LOHTable.GetValue (0, Level[i]-LevelDiff[i])
@@ -605,8 +601,9 @@ def LevelUpDonePress():
# bonus spells don't count in determining if we can use this level
if GemRB.GetMemorizableSpellsCount (pc, IE_SPELL_TYPE_PRIEST, i, 0) > 0: # we can memorize spells of this level
for j in range(NumClasses): # loop through each class
- IsDruid = CommonTables.ClassSkills.GetValue (Classes[j], 0, 0)
- IsCleric = CommonTables.ClassSkills.GetValue (Classes[j], 1, 0)
+ TmpClassName = GUICommon.GetClassRowName (Classes[j], "class")
+ IsDruid = CommonTables.ClassSkills.GetValue (TmpClassName, "DRUIDSPELL", 0)
+ IsCleric = CommonTables.ClassSkills.GetValue (TmpClassName, "CLERICSPELL", 0)
if IsCleric == "*" and IsDruid == "*": # no divine spells (so mage/cleric multis don't screw up)
continue
elif IsCleric == "*": # druid spells
@@ -614,9 +611,9 @@ def LevelUpDonePress():
else: # cleric spells
ClassFlag = 0x4000
- Learnable = GUICommon.GetLearnablePriestSpells(ClassFlag, GemRB.GetPlayerStat (pc, IE_ALIGNMENT), i+1)
+ Learnable = Spellbook.GetLearnablePriestSpells(ClassFlag, GemRB.GetPlayerStat (pc, IE_ALIGNMENT), i+1)
for k in range(len(Learnable)): # loop through all the learnable spells
- if GUICommon.HasSpell (pc, IE_SPELL_TYPE_PRIEST, i, Learnable[k]) < 0: # only write it if we don't yet know it
+ if Spellbook.HasSpell (pc, IE_SPELL_TYPE_PRIEST, i, Learnable[k]) < 0: # only write it if we don't yet know it
GemRB.LearnSpell(pc, Learnable[k])
# hlas
@@ -657,8 +654,8 @@ def ReactivateBaseClass ():
Proficiencies, THACO, saves, spells, and innate abilites,
most noteably."""
- ClassIndex = CommonTables.Classes.FindValue (5, Classes[1])
- ClassName = CommonTables.Classes.GetRowName (ClassIndex)
+ # we construct the Classes array, so that the active class is always first and the base is second
+ ClassName = GUICommon.GetClassRowName (Classes[1], "class")
KitIndex = GUICommon.GetKitIndex (pc)
# reactivate all our proficiencies
@@ -689,7 +686,7 @@ def ReactivateBaseClass ():
GemRB.SetPlayerStat (pc, IE_TOHIT, TmpThaco)
# see if all our saves are lower than our current saves
- SavesTable = CommonTables.Classes.GetValue (ClassIndex, 3, 0)
+ SavesTable = CommonTables.Classes.GetValue (ClassName, "SAVE", 0)
SavesTable = GemRB.LoadTable (SavesTable)
for i in range (5):
# see if this save is lower than our old save
@@ -698,7 +695,7 @@ def ReactivateBaseClass ():
GemRB.SetPlayerStat (pc, IE_SAVEVSDEATH+i, TmpSave)
# see if we're a caster
- SpellTables = [CommonTables.ClassSkills.GetValue (Classes[1], 0, 0), CommonTables.ClassSkills.GetValue (Classes[1], 1, 0), CommonTables.ClassSkills.GetValue (Classes[1], 2, 0)]
+ SpellTables = [CommonTables.ClassSkills.GetValue (ClassName, "DRUIDSPELL", 0), CommonTables.ClassSkills.GetValue (ClassName, "CLERICSPELL", 0), CommonTables.ClassSkills.GetValue (ClassName, "MAGESPELL", 0)]
if SpellTables[2] != "*": # casts mage spells
# set up our memorizations
SpellTable = GemRB.LoadTable (SpellTables[2])
@@ -713,7 +710,7 @@ def ReactivateBaseClass ():
SpellTable = GemRB.LoadTable (SpellTables[1])
ClassMask = 0x4000
else: # druidic spells
- if not GameRB.HasResource(SpellTables[0], RES_2DA):
+ if not GemRB.HasResource(SpellTables[0], RES_2DA):
SpellTables[0] = "MXSPLPRS"
SpellTable = GemRB.LoadTable (SpellTables[0])
ClassMask = 0x8000
@@ -732,9 +729,9 @@ def ReactivateBaseClass ():
# they will now only get druid spells up to the level they could cast
# this should probably be noted somewhere (ranger/cleric multis still function the same,
# but that could be remedied if desired)
- Learnable = GUICommon.GetLearnablePriestSpells(ClassMask, GemRB.GetPlayerStat (pc, IE_ALIGNMENT), i+1)
+ Learnable = Spellbook.GetLearnablePriestSpells(ClassMask, GemRB.GetPlayerStat (pc, IE_ALIGNMENT), i+1)
for k in range (len (Learnable)): # loop through all the learnable spells
- if GUICommon.HasSpell (pc, IE_SPELL_TYPE_PRIEST, i, Learnable[k]) < 0: # only write it if we don't yet know it
+ if Spellbook.HasSpell (pc, IE_SPELL_TYPE_PRIEST, i, Learnable[k]) < 0: # only write it if we don't yet know it
GemRB.LearnSpell(pc, Learnable[k])
# setup class bonuses for this class
diff --git a/gemrb/GUIScripts/Portrait.py b/gemrb/GUIScripts/Portrait.py
new file mode 100644
index 0000000..edf5b49
--- /dev/null
+++ b/gemrb/GUIScripts/Portrait.py
@@ -0,0 +1,98 @@
+# -*-python-*-
+# GemRB - Infinity Engine Emulator
+# Copyright (C) 2003 The GemRB Project
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+
+
+# Portrait.py - scripts to control portrait selection and scrolling
+###################################################
+
+import GemRB
+import GUICommon
+###################################################
+
+PortraitCount = 0
+PortraitsTable = None
+Gender = None
+
+# initializes gender and portrait table
+# PortraitGender: 1 Male
+# 2 Female
+def Init (PortraitGender):
+ global PortraitsTable, PortraitCount, Gender
+
+ if PortraitsTable is None:
+ PortraitsTable = GemRB.LoadTable ("PICTURES")
+
+ PortraitCount = 0
+ Gender = PortraitGender
+
+# sets index to given protraitname
+def Set (PortraitName):
+ global PortraitCount
+
+ # removes the size marking character at the end
+ if GUICommon.GameIsBG2():
+ PortraitName = PortraitName.rstrip ("[ms]")
+ else:
+ PortraitName = PortraitName.rstrip ("[ls]")
+
+ # capitalize PortraitName
+ PortraitName = PortraitName.upper ()
+
+ # search table
+ for i in range(0, PortraitsTable.GetRowCount ()):
+ if PortraitName == PortraitsTable.GetRowName (i).upper ():
+ PortraitCount = i
+ break
+
+ return
+
+# returns next portrait name
+def Next ():
+ global PortraitCount
+
+ while True:
+ PortraitCount = PortraitCount + 1
+ if PortraitCount == PortraitsTable.GetRowCount ():
+ PortraitCount = 0
+ if PortraitsTable.GetValue (PortraitCount, 0) == Gender:
+ return Name ()
+
+# return previous portrait name
+def Previous ():
+ global PortraitCount
+
+ while True:
+ PortraitCount = PortraitCount - 1
+ if PortraitCount < 0:
+ PortraitCount = PortraitsTable.GetRowCount () - 1
+ if PortraitsTable.GetValue (PortraitCount, 0) == Gender:
+ return Name ()
+
+# gets current portrait name
+def Name ():
+ global PortraitCount
+
+ # if portrait matches not current gender, it will be skipped to
+ # the next portrait that matches
+ while PortraitsTable.GetValue (PortraitCount, 0) != Gender:
+ PortraitCount = PortraitCount + 1
+
+ PortraitName = PortraitsTable.GetRowName (PortraitCount)
+ return PortraitName
diff --git a/gemrb/GUIScripts/Spellbook.py b/gemrb/GUIScripts/Spellbook.py
new file mode 100644
index 0000000..83a3a31
--- /dev/null
+++ b/gemrb/GUIScripts/Spellbook.py
@@ -0,0 +1,527 @@
+# -*-python-*-
+# GemRB - Infinity Engine Emulator
+# Copyright (C) 2011 The GemRB Project
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# a library of any functions for spell(book) managment
+
+import GemRB
+import CommonTables
+from GUIDefines import *
+from ie_stats import *
+from ie_action import ACT_LEFT, ACT_RIGHT
+from ie_spells import SP_IDENTIFY, SP_SURGE, LSR_KNOWN, LSR_LEVEL, LSR_STAT
+from ie_restype import RES_2DA
+
+#################################################################
+# this is in the operator module of the standard python lib
+def itemgetter(*items):
+ if len(items) == 1:
+ item = items[0]
+ def g(obj):
+ return obj[item]
+ else:
+ def g(obj):
+ return tuple(obj[item] for item in items)
+ return g
+
+#################################################################
+# routines for the actionbar spell access code
+
+def GetUsableMemorizedSpells(actor, BookType):
+ memorizedSpells = []
+ spellResRefs = []
+ for level in range (9):
+ spellCount = GemRB.GetMemorizedSpellsCount (actor, BookType, level, False)
+ for i in range (spellCount):
+ Spell0 = GemRB.GetMemorizedSpell (actor, BookType, level, i)
+ if not Spell0["Flags"]:
+ # depleted, so skip
+ continue
+ if Spell0["SpellResRef"] in spellResRefs:
+ # add another one, so we can get the count more cheaply later
+ spellResRefs.append (Spell0["SpellResRef"])
+ continue
+ spellResRefs.append (Spell0["SpellResRef"])
+ Spell = GemRB.GetSpell(Spell0["SpellResRef"])
+ Spell['BookType'] = BookType # just another sorting key
+ Spell['SpellIndex'] = GemRB.GetSpelldataIndex (actor, Spell["SpellResRef"], 1<<BookType) # crucial!
+ if Spell['SpellIndex'] == -1:
+ print "Error, memorized spell not found!", Spell["SpellResRef"], 1<<BookType
+ Spell['SpellIndex'] += 1000 * 1<<BookType
+ memorizedSpells.append (Spell)
+
+ if not len(memorizedSpells):
+ return []
+
+ # count and remove the duplicates
+ memorizedSpells2 = []
+ for spell in memorizedSpells:
+ if spell["SpellResRef"] in spellResRefs:
+ spell['MemoCount'] = spellResRefs.count(spell["SpellResRef"])
+ while spell["SpellResRef"] in spellResRefs:
+ spellResRefs.remove(spell["SpellResRef"])
+ memorizedSpells2.append(spell)
+
+ return memorizedSpells2
+
+def GetKnownSpells(actor, BookType):
+ knownSpells = []
+ spellResRefs = []
+ for level in range (9):
+ spellCount = GemRB.GetKnownSpellsCount (actor, BookType, level)
+ for i in range (spellCount):
+ Spell0 = GemRB.GetKnownSpell (actor, BookType, level, i)
+ if Spell0["SpellResRef"] in spellResRefs:
+ continue
+ spellResRefs.append (Spell0["SpellResRef"])
+ Spell = GemRB.GetSpell(Spell0["SpellResRef"])
+ Spell['BookType'] = BookType # just another sorting key
+ Spell['MemoCount'] = 0
+ Spell['SpellIndex'] = 1000 * 1<<BookType # this gets assigned properly later
+ knownSpells.append (Spell)
+
+ return knownSpells
+
+def GetKnownSpellsLevel(actor, BookType, level):
+ knownSpells = []
+ spellResRefs = []
+
+ spellCount = GemRB.GetKnownSpellsCount (actor, BookType, level)
+ for i in range (spellCount):
+ Spell0 = GemRB.GetKnownSpell (actor, BookType, level, i)
+ if Spell0["SpellResRef"] in spellResRefs:
+ continue
+ spellResRefs.append (Spell0["SpellResRef"])
+ Spell = GemRB.GetSpell(Spell0["SpellResRef"])
+ Spell['BookType'] = BookType # just another sorting key
+ knownSpells.append (Spell)
+
+ return knownSpells
+
+def index (list, value):
+ for i in range(len(list)):
+ if list[i]==value:
+ return i
+ return -1
+
+def GetMemorizedSpells(actor, BookType, level):
+ memoSpells = []
+ spellResRefs = []
+
+ spellCount = GemRB.GetMemorizedSpellsCount (actor, BookType, level, False)
+ for i in range (spellCount):
+ Spell0 = GemRB.GetMemorizedSpell (actor, BookType, level, i)
+ pos = index(spellResRefs,Spell0["SpellResRef"])
+ if pos!=-1:
+ memoSpells[pos]['KnownCount']+=1
+ memoSpells[pos]['MemoCount']+=Spell0["Flags"]
+ continue
+
+ spellResRefs.append (Spell0["SpellResRef"])
+ Spell = GemRB.GetSpell(Spell0["SpellResRef"])
+ Spell['KnownCount'] = 1
+ Spell['MemoCount'] = Spell0["Flags"]
+ memoSpells.append (Spell)
+
+ return memoSpells
+
+# direct access to the spellinfo struct
+# SpellIndex is the index of the spell in the struct, but we add a thousandfold of the spell type for later use in SpellPressed
+def GetSpellinfoSpells(actor, BookType):
+ memorizedSpells = []
+ spellResRefs = GemRB.GetSpelldata (actor)
+ i = 0
+ for resref in spellResRefs:
+ Spell = GemRB.GetSpell(resref)
+ Spell['BookType'] = BookType # just another sorting key
+ Spell['SpellIndex'] = i + 1000 * 255 # spoofing the type, so any table would work
+ Spell['MemoCount'] = 1
+ memorizedSpells.append (Spell)
+ i += 1
+
+ return memorizedSpells
+
+def SortUsableSpells(memorizedSpells):
+ # sort it by using the spldisp.2da table
+ layout = CommonTables.SpellDisplay.GetValue ("USE_ROW", "ROWS")
+ layout = CommonTables.SpellDisplay.GetRowName (layout)
+ order = CommonTables.SpellDisplay.GetValue ("DESCENDING", "ROWS")
+ key1 = CommonTables.SpellDisplay.GetValue (layout, "KEY1")
+ key2 = CommonTables.SpellDisplay.GetValue (layout, "KEY2")
+ key3 = CommonTables.SpellDisplay.GetValue (layout, "KEY3")
+ if key1:
+ if key3 and key2:
+ memorizedSpells = sorted(memorizedSpells, key=itemgetter(key1, key2, key3), reverse=order)
+ elif key2:
+ memorizedSpells = sorted(memorizedSpells, key=itemgetter(key1, key2), reverse=order)
+ else:
+ memorizedSpells = sorted(memorizedSpells, key=itemgetter(key1), reverse=order)
+
+ return memorizedSpells
+
+# Sets up all the (12) action buttons for a player character with different spell or innate icons.
+# It also sets up the scroll buttons left and right if needed.
+# If Start is supplied, it will skip the first few items (used when scrolling through the list)
+# BookType is a spellbook type bitfield (1-mage, 2-priest, 4-innate and others in iwd2)
+# Offset is a control ID offset here for iwd2 purposes
+def SetupSpellIcons(Window, BookType, Start=0, Offset=0):
+ actor = GemRB.GameGetFirstSelectedActor ()
+
+ # check if we're dealing with a temporary spellbook
+ if GemRB.GetVar("ActionLevel") == 11:
+ allSpells = GetSpellinfoSpells (actor, BookType)
+ else:
+ # construct the spellbook of usable (not depleted) memorized spells
+ # the getters expect the BookType as: 0 priest, 1 mage, 2 innate
+ if BookType == -1:
+ # Nahal's reckless dweomer can use any known spell
+ allSpells = GetKnownSpells (actor, IE_SPELL_TYPE_WIZARD)
+ else:
+ allSpells = []
+ for i in range(16):
+ if BookType & (1<<i):
+ allSpells += GetUsableMemorizedSpells (actor, i)
+ if not len(allSpells):
+ raise AttributeError ("Error, unknown BookType passed to SetupSpellIcons: %d! Bailing out!" %(BookType))
+ return
+
+ if BookType == -1:
+ memorizedSpells = allSpells
+ # reset Type, so we can choose the surge spell instead of just getting a redraw of the action bar
+ GemRB.SetVar("Type", 3)
+ else:
+ memorizedSpells = SortUsableSpells(allSpells)
+
+ # start creating the controls
+ import GUICommonWindows
+ # TODO: ASCOL, ROWS
+ #AsCol = CommonTables.SpellDisplay.GetValue (layout, "AS_COL")
+ #Rows = CommonTables.SpellDisplay.GetValue (layout, "ROWS")
+ More = len(memorizedSpells) > 12 or Start > 0
+
+ # scroll left button
+ if More:
+ Button = Window.GetControl (Offset)
+ Button.SetText ("")
+ if Start:
+ GUICommonWindows.SetActionIconWorkaround (Button, ACT_LEFT, 0)
+ Button.SetState (IE_GUI_BUTTON_UNPRESSED)
+ else:
+ Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
+ Button.SetTooltip ("")
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+
+ # disable all spells if fx_disable_spellcasting was run with the same type
+ # but only if there are any spells of that type to disable
+ disabled_spellcasting = GemRB.GetPlayerStat(actor, IE_CASTING, 0)
+ actionLevel = GemRB.GetVar ("ActionLevel")
+
+ #order is: mage, cleric, innate, class, song, (defaults to 1, item)
+ spellSections = [2, 4, 8, 16, 16]
+
+ # create the spell icon buttons
+ buttonCount = 12 - More * 2 # GUIBT_COUNT in PCStatsStruct
+ for i in range (buttonCount):
+ Button = Window.GetControl (i+Offset+More)
+ Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, None)
+
+ if i+Start >= len(memorizedSpells):
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+ Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
+ Button.SetText ("")
+ Button.SetTooltip ("")
+ continue
+ Spell = memorizedSpells[i+Start]
+ spellType = Spell['SpellType']
+ if spellType > 4:
+ spellType = 1
+ else:
+ spellType = spellSections[spellType]
+ if BookType == -1:
+ Button.SetVarAssoc ("Spell", Spell['SpellIndex']+i+Start)
+ else:
+ Button.SetVarAssoc ("Spell", Spell['SpellIndex'])
+
+ # disable spells that should be cast from the inventory or can't be cast while silenced or ...
+ # see splspec.2da for all the reasons; silence is handled elsewhere
+ specialSpell = GemRB.CheckSpecialSpell(actor, Spell['SpellResRef'])
+ specialSpell = (specialSpell & SP_IDENTIFY) or ((specialSpell & SP_SURGE) and actionLevel == 5)
+ if specialSpell or (disabled_spellcasting&spellType):
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+ Button.EnableBorder(1, 0)
+ else:
+ Button.SetState (IE_GUI_BUTTON_UNPRESSED)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUICommonWindows.SpellPressed)
+
+ if Spell['SpellResRef']:
+ Button.SetSprites ("guibtbut", 0, 0,1,2,3)
+ Button.SetSpellIcon (Spell['SpellResRef'], 1)
+ Button.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_ALIGN_BOTTOM|IE_GUI_BUTTON_ALIGN_RIGHT, OP_SET)
+ Button.SetTooltip (Spell['SpellName'])
+
+ if Spell['MemoCount'] > 0 and BookType != -1:
+ Button.SetText (str(Spell['MemoCount']))
+ else:
+ Button.SetText ("")
+
+ # scroll right button
+ if More:
+ Button = Window.GetControl (Offset+buttonCount+1)
+ GUICommonWindows.SetActionIconWorkaround (Button, ACT_RIGHT, buttonCount)
+ Button.SetText ("")
+ if len(memorizedSpells) - Start > 10:
+ Button.SetState (IE_GUI_BUTTON_UNPRESSED)
+ else:
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+ Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
+ Button.SetTooltip ("")
+
+#################################################################
+# routines used during character generation and levelup
+#################################################################
+def GetMageSpells (Kit, Alignment, Level):
+ MageSpells = []
+ SpellType = 99
+ v = CommonTables.Aligns.FindValue (3, Alignment)
+ Usability = Kit | CommonTables.Aligns.GetValue(v, 5)
+
+ SpellsTable = GemRB.LoadTable ("spells")
+ for i in range(SpellsTable.GetValue ("MAGE", str(Level), 1) ):
+ SpellName = "SPWI%d%02d"%(Level,i+1)
+ ms = GemRB.GetSpell (SpellName, 1)
+ if ms == None:
+ continue
+
+ if Usability & ms['SpellExclusion']:
+ SpellType = 0
+ else:
+ SpellType = 1
+ if Kit & (1 << ms['SpellSchool']+5): # of matching specialist school
+ SpellType = 2
+ # Wild mage spells are of normal schools, so we have to find them
+ # separately. Generalists can learn any spell but the wild ones, so
+ # we check if the mage is wild and if a generalist wouldn't be able
+ # to learn the spell.
+ if Kit == 0x8000 and (0x4000 & ms['SpellExclusion']):
+ SpellType = 2
+ MageSpells.append ([SpellName, SpellType])
+
+ return MageSpells
+
+def GetLearnableMageSpells (Kit, Alignment, Level):
+ Learnable = []
+
+ for Spell in GetMageSpells (Kit, Alignment, Level):
+ if Spell[1]:
+ Learnable.append (Spell[0])
+ return Learnable
+
+def GetLearnablePriestSpells (Class, Alignment, Level):
+ Learnable =[]
+
+ v = CommonTables.Aligns.FindValue(3, Alignment)
+ #usability is the bitset we look for
+ Usability = CommonTables.Aligns.GetValue(v, 5)
+
+ SpellsTable = GemRB.LoadTable ("spells")
+ for i in range(SpellsTable.GetValue ("PRIEST", str (Level), 1) ):
+ SpellName = "SPPR%d%02d"%(Level,i+1)
+ ms = GemRB.GetSpell(SpellName, 1)
+ if ms == None:
+ continue
+ if Class & ms['SpellDivine']:
+ continue
+ if Usability & ms['SpellExclusion']:
+ continue
+ Learnable.append (SpellName)
+ return Learnable
+
+# there is no separate druid spell table in the originals
+#FIXME: try to do this in a non-hard way?
+def GetPriestSpellTable(tablename):
+ if not GemRB.HasResource (tablename, RES_2DA):
+ if tablename == "MXSPLDRU":
+ return "MXSPLPRS"
+ return tablename
+
+def SetupSpellLevels (pc, TableName, Type, Level):
+ #don't die on a missing reference
+ tmp = GetPriestSpellTable(TableName)
+ if tmp != TableName:
+ SetupSpellLevels (pc, tmp, Type, Level)
+ return
+
+ Table = GemRB.LoadTable (TableName)
+ for i in range(Table.GetColumnCount ()):
+ # do a string lookup since some tables don't have entries for all levels
+ value = Table.GetValue (str(Level), str(i+1), 1)
+ # specialist mages get an extra spell if they already know that level
+ # FIXME: get a general routine to find specialists
+ school = GemRB.GetVar("MAGESCHOOL")
+ if Type == IE_SPELL_TYPE_WIZARD and school != 0:
+ if value > 0:
+ value += 1
+ GemRB.SetMemorizableSpellsCount (pc, value, Type, i)
+ return
+
+def UnsetupSpellLevels (pc, TableName, Type, Level):
+ #don't die on a missing reference
+ tmp = GetPriestSpellTable(TableName)
+ if tmp != TableName:
+ UnsetupSpellLevels (pc, tmp, Type, Level)
+ return
+
+ Table = GemRB.LoadTable (TableName)
+ for i in range(Table.GetColumnCount ()):
+ GemRB.SetMemorizableSpellsCount (pc, 0, Type, i)
+ return
+
+# Returns -1 if not found; otherwise, the index of the spell
+def HasSpell (Actor, SpellType, Level, Ref):
+ # loop through each spell in the spell level and check for a matching ref
+ for i in range (GemRB.GetKnownSpellsCount (Actor, SpellType, Level)):
+ Spell = GemRB.GetKnownSpell(Actor, SpellType, Level, i)
+ if Spell["SpellResRef"].upper() == Ref.upper(): # ensure case is the same
+ return i
+
+ # not found
+ return -1
+
+def CannotLearnSlotSpell ():
+ pc = GemRB.GameGetSelectedPCSingle ()
+
+ # disqualify sorcerers immediately
+ if GemRB.GetPlayerStat (pc, IE_CLASS) == 19:
+ return LSR_STAT
+
+ import GUICommon
+ if GUICommon.GameIsPST():
+ import GUIINV
+ slot, slot_item = GUIINV.ItemHash[GemRB.GetVar ('ItemButton')]
+ else:
+ slot_item = GemRB.GetSlotItem (pc, GemRB.GetVar ("ItemButton"))
+ spell_ref = GemRB.GetItem (slot_item['ItemResRef'], pc)['Spell']
+ spell = GemRB.GetSpell (spell_ref)
+ level = spell['SpellLevel']
+
+ # maybe she already knows this spell
+ if HasSpell (pc, IE_SPELL_TYPE_WIZARD, level-1, spell_ref) != -1:
+ return LSR_KNOWN
+
+ # level check (needs enough intelligence for this level of spell)
+ dumbness = GemRB.GetPlayerStat (pc, IE_INT)
+ if level > GemRB.GetAbilityBonus (IE_INT, 1, dumbness):
+ return LSR_LEVEL
+
+ spell_count = GemRB.GetKnownSpellsCount (pc, IE_SPELL_TYPE_WIZARD, level-1)
+ if spell_count > GemRB.GetAbilityBonus (IE_INT, 2, dumbness):
+ return LSR_FULL
+
+ return 0
+
+def LearnPriestSpells (pc, level, mask):
+ """Learns all the priest spells through the given spell level.
+
+ Mask distinguishes clerical and druidic spells."""
+ if level > 7: # make sure we don't have too high a level
+ level = 7
+
+ # go through each level
+ alignment = GemRB.GetPlayerStat (pc, IE_ALIGNMENT)
+ for i in range (level):
+ learnable = GetLearnablePriestSpells (mask, alignment, i+1)
+
+ for spell in learnable:
+ # if the spell isn't learned, learn it
+ if HasSpell (pc, IE_SPELL_TYPE_PRIEST, i, spell) < 0:
+ GemRB.LearnSpell (pc, spell)
+ return
+
+
+def RemoveKnownSpells (pc, type, level1=1, level2=1, noslots=0, kit=0):
+ """Removes all known spells of a given type between two spell levels.
+
+ If noslots is true, all memorization counts are set to 0.
+ Kit is used to identify the priest spell mask of the spells to be removed;
+ this is only used when removing spells in a dualclass."""
+
+ # choose the correct limit based upon class type
+ if type == IE_SPELL_TYPE_WIZARD:
+ limit = 9
+ elif type == IE_SPELL_TYPE_PRIEST:
+ limit = 7
+
+ # make sure that we get the original kit, if we have one
+ if kit:
+ originalkit = GetKitIndex (pc)
+
+ if originalkit: # kitted; find the class value
+ originalkit = CommonTables.KitList.GetValue (originalkit, 7)
+ else: # just get the class value
+ originalkit = GemRB.GetPlayerStat (pc, IE_CLASS)
+ originalkit = GUICommon.GetClassRowName (originalkit, "class")
+
+ # this is is specifically for dual-classes and will not work to remove only one
+ # spell type from a ranger/cleric multi-class
+ if CommonTables.ClassSkills.GetValue (originalkit, "DRUIDSPELL", 0) != "*": # knows druid spells
+ originalkit = 0x8000
+ elif CommonTables.ClassSkills.GetValue (originalkit, "CLERICSPELL", 0) != "*": # knows cleric spells
+ originalkit = 0x4000
+ else: # don't know any other spells
+ originalkit = 0
+
+ # don't know how this would happen, but better to be safe
+ if originalkit == kit:
+ originalkit = 0
+ elif type == IE_SPELL_TYPE_INNATE:
+ limit = 1
+ else: # can't do anything if an improper spell type is sent
+ return 0
+
+ # make sure we're within parameters
+ if level1 < 1 or level2 > limit or level1 > level2:
+ return 0
+
+ # remove all spells for each level
+ for level in range (level1-1, level2):
+ # we need the count because we remove each spell in reverse order
+ count = GemRB.GetKnownSpellsCount (pc, type, level)
+ mod = count-1
+
+ for spell in range (count):
+ # see if we need to check for kit
+ if type == IE_SPELL_TYPE_PRIEST and kit:
+ # get the spell's ref data
+ ref = GemRB.GetKnownSpell (pc, type, level, mod-spell)
+ ref = GemRB.GetSpell (ref['SpellResRef'], 1)
+
+ # we have to look at the originalkit as well specifically for ranger/cleric dual-classes
+ # we wouldn't want to remove all cleric spells and druid spells if we lost our cleric class
+ # only the cleric ones
+ if kit&ref['SpellDivine'] or (originalkit and not originalkit&ref['SpellDivine']):
+ continue
+
+ # remove the spell
+ GemRB.RemoveSpell (pc, type, level, mod-spell)
+
+ # remove memorization counts if desired
+ if noslots:
+ GemRB.SetMemorizableSpellsCount (pc, 0, type, level)
+
+ # return success
+ return 1
+
diff --git a/gemrb/GUIScripts/TextScreen.py b/gemrb/GUIScripts/TextScreen.py
index bb0ee76..7f82644 100644
--- a/gemrb/GUIScripts/TextScreen.py
+++ b/gemrb/GUIScripts/TextScreen.py
@@ -25,69 +25,94 @@ import GUICommon
TextScreen = None
TextArea = None
Row = 1
-Position = 1
-Chapter = 0
TableName = None
-BGTICKS = 300 # TODO: verify for suitability
-Ticks = IWDTICKS = 200 # TODO: verify for suitability in iwd1
+
+def FindTextRow (Table):
+ global Row
+
+ #this is still not the full implementation, but the original engine never used this stuff
+ Row = Table.GetRowIndex("DEFAULT")
+ if Table.GetValue (Row, 1)== -1:
+ if GemRB.GameGetReputation() >= 100:
+ Row = Table.GetRowIndex("GOOD_REPUTATION")
+ else:
+ Row = Table.GetRowIndex("BAD_REPUTATION")
+ return
def StartTextScreen ():
- global TextScreen, TextArea, Chapter, TableName, Row, Ticks
+ global TextScreen, TextArea, TableName, Row
+
+ GemRB.GamePause (1, 3)
+
+ ID = -1
+ MusicName = "*"
+ Message = 17556 # default: Paused for chapter text
+ TableName = GemRB.GetGameString (STR_TEXTSCREEN)
+
+ #iwd2/bg2 has no separate music
+ if GUICommon.GameIsIWD1():
+ if TableName == "":
+ MusicName = "chap0"
+ else:
+ MusicName = "chap1"
+ TableName = "chapters"
+ elif GUICommon.GameIsIWD2():
+ TableName = "chapters"
+
+ if TableName == "":
+ EndTextScreen ()
+ return
+ else:
+ TextTable = GemRB.LoadTable ("textscrn", 1)
+ if TextTable != None:
+ TxtRow = TextTable.GetRowIndex (TableName)
+ if TxtRow >= 0:
+ ID = TextTable.GetValue (TxtRow, 0)
+ MusicName = TextTable.GetValue (TxtRow, 1)
+ Message = TextTable.GetValue (TxtRow, 2)
+
+ if Message != "*":
+ GemRB.DisplayString (Message, 0xff0000)
if GUICommon.GameIsIWD2():
GemRB.LoadWindowPack ("GUICHAP", 800, 600)
else:
GemRB.LoadWindowPack ("GUICHAP", 640, 480)
- if GUICommon.GameIsBG1() or GUICommon.GameIsBG2():
- Ticks = BGTICKS
- LoadPic = TableName = GemRB.GetGameString (STR_LOADMOS)
- #if there is no preset loadpic, try to determine it from the chapter
- #fixme: we always assume there isn't for non-bg2
if GUICommon.GameIsBG2():
- if TableName == "":
- Chapter = GemRB.GetGameVar ("CHAPTER") & 0x7fffffff
- TableName = "CHPTXT"+str(Chapter)
ID = 62
- else:
- ID = (GemRB.GetGameVar("CHAPTER") + 1) & 0x7fffffff
+ elif ID == -1:
+ #default: try to determine ID from current chapter
+ ID = GemRB.GetGameVar("CHAPTER") & 0x7fffffff
Chapter = ID + 1
- #iwd2/bg2 has no separate music
- if GUICommon.GameIsIWD1():
- if LoadPic == "":
- GemRB.LoadMusicPL ("chap0.mus")
- else:
- GemRB.LoadMusicPL ("chap1.mus")
- TableName = "chapters"
- elif GUICommon.GameIsIWD2():
+ if MusicName != "*":
+ GemRB.LoadMusicPL (MusicName + ".mus")
+ else:
GemRB.HardEndPL ()
- TableName = "chapters"
- elif GUICommon.GameIsBG1() and TableName[:6] == "chptxt":
- GemRB.LoadMusicPL ("chapter.mus")
TextScreen = GemRB.LoadWindow (ID)
TextScreen.SetFrame ()
TextArea = TextScreen.GetControl (2)
TextArea.SetFlags (IE_GUI_TEXTAREA_SMOOTHSCROLL)
- TextArea.SetEvent (IE_GUI_TEXTAREA_OUT_OF_TEXT, FeedScroll)
- #caption
Table = GemRB.LoadTable (TableName)
if GUICommon.GameIsBG1():
#these suckers couldn't use a fix row
- Row = Table.GetRowIndex("DEFAULT")
- Value = Table.GetValue (Row, 0)
+ FindTextRow (Table)
elif GUICommon.GameIsBG2():
LoadPic = Table.GetValue (-1, -1)
if LoadPic != "":
TextScreen.SetPicture (LoadPic)
- # TODO: verify
- Value = 0
+ FindTextRow (Table)
else:
- Value = Table.GetValue (Chapter, 0)
- if Value:
+ Row = Chapter
+
+ #caption
+ Value = Table.GetValue (Row, 0)
+ #don't display the fake -1 string (No caption in toscst.2da)
+ if Value!="NONE" and Value>0 and TextScreen.HasControl(0x10000000):
Label=TextScreen.GetControl (0x10000000)
Label.SetText (Value)
@@ -102,55 +127,44 @@ def StartTextScreen ():
Button.SetText (16510)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, ReplayTextScreen)
+ #if this was opened from somewhere other than game control close that window
+ GUICommon.CloseOtherWindow(None)
GemRB.HideGUI ()
GUICommon.GameWindow.SetVisible(WINDOW_INVISIBLE) #removing the gamecontrol screen
TextScreen.SetVisible (WINDOW_VISIBLE)
- TextArea.Rewind (Ticks)
- GemRB.DisplayString (17556, 0xff0000) #Paused for chapter text
- GemRB.GamePause (1, 1)
- return
-
-def FeedScroll ():
- global TextArea, Position
-
- Table = GemRB.LoadTable (TableName)
- if GUICommon.GameIsBG2():
- #this is a rather primitive selection but works for the games
- Value = Table.GetValue (0, 1)
- if Value == "REPUTATION":
- line = 2
- else:
- line = 1
- Value = Table.GetValue (line, 1)
- elif GUICommon.GameIsBG1():
- Value = Table.GetValue (Row, Position)
- if Value == 'NONE':
- Position = 1
- else:
- Position = Position + 1
- else:
- Value = Table.GetValue (Chapter, 1)
-
- TextArea.Append (Value, -1, 6)
+ ReplayTextScreen()
return
def EndTextScreen ():
global TextScreen
- TextScreen.SetVisible (WINDOW_INVISIBLE)
if TextScreen:
+ TextScreen.SetVisible (WINDOW_INVISIBLE)
TextScreen.Unload ()
GemRB.PlaySound(None, 0, 0, 4)
+
GUICommon.GameWindow.SetVisible(WINDOW_VISIBLE) # enable the gamecontrol screen
GemRB.UnhideGUI ()
- GemRB.GamePause (0, 1)
+ GemRB.GamePause (0, 3)
return
def ReplayTextScreen ():
- global TextArea, Position
+ global TextArea, TableName, Row
+
+ TextArea.Rewind ()
+
+ Table = GemRB.LoadTable (TableName)
+ Count = Table.GetColumnCount (Row)
+
+ #hack for messy chapters.2da in IWD
+ #note: iwd doesn't use TextScreen, only IncrementChapter
+ if GUICommon.GameIsIWD1() or GUICommon.GameIsIWD2():
+ Count = 2
+
+ for i in range(1, Count):
+ TextArea.Append ("\n")
+ # flag value of 14 = IE_STR_SOUND|IE_STR_SPEECH/GEM_SND_SPEECH|GEM_SND_QUEUE
+ TextArea.Append (Table.GetValue (Row, i), -1, 14)
- Position = 1
- TextArea.SetEvent (IE_GUI_TEXTAREA_OUT_OF_TEXT, FeedScroll)
- TextArea.Rewind (Ticks)
return
diff --git a/gemrb/GUIScripts/bg1/CMakeLists.txt b/gemrb/GUIScripts/bg1/CMakeLists.txt
deleted file mode 100644
index 965e7a6..0000000
--- a/gemrb/GUIScripts/bg1/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-FILE( GLOB FILES_TO_INSTALL *.py )
-
-INSTALL( FILES ${FILES_TO_INSTALL} DESTINATION ${DATA_DIR}/GUIScripts/bg1 )
diff --git a/gemrb/GUIScripts/bg1/CharGenGui.py b/gemrb/GUIScripts/bg1/CharGenGui.py
index 17b92cd..22a06e7 100644
--- a/gemrb/GUIScripts/bg1/CharGenGui.py
+++ b/gemrb/GUIScripts/bg1/CharGenGui.py
@@ -1,8 +1,10 @@
import GemRB
from GUIDefines import *
from ie_stats import *
+from ie_restype import RES_2DA
import CharGenCommon
import GUICommon
+import Spellbook
import CommonTables
import LUCommon
import LUProfsSelection
@@ -83,15 +85,13 @@ def unsetAlignment():
GemRB.SetPlayerStat (MyChar, IE_ALIGNMENT,0)
def getAlignment(area):
- AlignmentTable = GemRB.LoadTable("aligns")
-
MyChar = GemRB.GetVar ("Slot")
AllignID = GemRB.GetPlayerStat (MyChar, IE_ALIGNMENT)
area.Append(1049, -1)
area.Append(": ")
- AllignIndex = AlignmentTable.FindValue(3,AllignID)
- AllignCap = AlignmentTable.GetValue(AllignIndex,2)
+ AllignIndex = CommonTables.Aligns.FindValue (3, AllignID)
+ AllignCap = CommonTables.Aligns.GetValue (AllignIndex, 2)
area.Append(AllignCap)
area.Append("\n")
@@ -126,8 +126,7 @@ def unsetHateRace():
def guardHateRace():
MyChar = GemRB.GetVar ("Slot")
- Class = GemRB.GetPlayerStat(MyChar,IE_CLASS)
- ClassName = CommonTables.ClassSkills.GetRowName(Class)
+ ClassName = GUICommon.GetClassRowName (MyChar)
TableName = CommonTables.ClassSkills.GetValue(ClassName, "HATERACE")
return TableName != "*"
@@ -148,12 +147,12 @@ def unsetMageSpells():
print("unsetMageSpells")
MyChar = GemRB.GetVar ("Slot")
- GUICommon.RemoveKnownSpells (MyChar, IE_SPELL_TYPE_WIZARD, 1, 5, 1)
+ Spellbook.RemoveKnownSpells (MyChar, IE_SPELL_TYPE_WIZARD, 1, 5, 1)
def guardMageSpells():
MyChar = GemRB.GetVar ("Slot")
- Class = GemRB.GetPlayerStat(MyChar,IE_CLASS)
- TableName = CommonTables.ClassSkills.GetValue(Class, 2)
+ ClassName = GUICommon.GetClassRowName (MyChar)
+ TableName = CommonTables.ClassSkills.GetValue(ClassName, "MAGESPELL")
return TableName != "*"
def getMageSpells(TextAreaControl):
@@ -180,9 +179,7 @@ def guardSkills():
if Kit != 0: # luckily the first row is a dummy
KitName = CommonTables.KitList.GetValue(Kit, 0) #rowname is just a number
else:
- ClassID = GemRB.GetPlayerStat (MyChar, IE_CLASS)
- ClassIndex = CommonTables.Classes.FindValue(5,ClassID)
- KitName = CommonTables.Classes.GetRowName(ClassIndex)
+ KitName = GUICommon.GetClassRowName (MyChar)
for i in range(RowCount):
SkillName = SkillTable.GetRowName(i+2)
@@ -202,9 +199,7 @@ def getSkills(TextAreaControl):
# thieving and other skills
info = ""
SkillTable = GemRB.LoadTable ("skills")
- ClassID = GemRB.GetPlayerStat (MyChar, IE_CLASS)
- Class = CommonTables.Classes.FindValue (5, ClassID)
- ClassName = CommonTables.Classes.GetRowName(Class)
+ ClassName = GUICommon.GetClassRowName (MyChar)
RangerSkills = CommonTables.ClassSkills.GetValue (ClassName, "RANGERSKILL")
BardSkills = CommonTables.ClassSkills.GetValue (ClassName, "BARDSKILL")
KitName = GUICommon.GetKitIndex (MyChar)
@@ -281,14 +276,12 @@ def getName(TextAreaControl):
def setDivineSpells():
MyChar = GemRB.GetVar ("Slot")
- ClassID = GemRB.GetPlayerStat (MyChar, IE_CLASS)
- Class = CommonTables.Classes.FindValue (5, ClassID)
- ClassName = CommonTables.Classes.GetRowName(Class)
+ ClassName = GUICommon.GetClassRowName (MyChar)
DruidTable = CommonTables.ClassSkills.GetValue (ClassName, "DRUIDSPELL")
ClericTable = CommonTables.ClassSkills.GetValue (ClassName, "CLERICSPELL")
- print("CGG setDivineSpells: CP1",ClassID,Class,ClassName,DruidTable,ClericTable)
+ print("CGG setDivineSpells: CP1", ClassName, DruidTable, ClericTable)
AllignID = GemRB.GetPlayerStat (MyChar, IE_ALIGNMENT)
@@ -301,18 +294,18 @@ def setDivineSpells():
def learnDivine(MyChar,ClassFlag,TableName,AllignID):
#print ("CGG setDivineSpells: CP2",MyChar,ClassFlag,TableName,AllignID )
- GUICommon.SetupSpellLevels(MyChar, TableName, IE_SPELL_TYPE_PRIEST, 1)
- Learnable = GUICommon.GetLearnablePriestSpells( ClassFlag, AllignID, 1)
+ Spellbook.SetupSpellLevels(MyChar, TableName, IE_SPELL_TYPE_PRIEST, 1)
+ Learnable = Spellbook.GetLearnablePriestSpells( ClassFlag, AllignID, 1)
for i in range(len(Learnable) ):
#print ("CGG setDivineSpells: CP3",Learnable[i])
- if -1 == GUICommon.HasSpell(MyChar,IE_SPELL_TYPE_PRIEST,1,Learnable[i]):
+ if -1 == Spellbook.HasSpell(MyChar,IE_SPELL_TYPE_PRIEST,1,Learnable[i]):
#print ("CGG setDivineSpells: CP4",Learnable[i])
GemRB.LearnSpell (MyChar, Learnable[i], 0)
def unsetDivineSpells():
print("unsetDivineSpells")
MyChar = GemRB.GetVar ("Slot")
- GUICommon.RemoveKnownSpells (MyChar, IE_SPELL_TYPE_PRIEST, 1, 1, 1)
+ Spellbook.RemoveKnownSpells (MyChar, IE_SPELL_TYPE_PRIEST, 1, 1, 1)
def getDivineSpells(TextAreaControl):
MyChar = GemRB.GetVar ("Slot")
@@ -333,15 +326,12 @@ def setAccept():
#set my character up
MyChar = GemRB.GetVar ("Slot")
- ClassID = GemRB.GetPlayerStat (MyChar, IE_CLASS)
- Class = CommonTables.Classes.FindValue (5, ClassID)
- ClassName = CommonTables.Classes.GetRowName(Class)
+ ClassName = GUICommon.GetClassRowName (MyChar)
#reputation
AllignID = GemRB.GetPlayerStat (MyChar, IE_ALIGNMENT)
TmpTable=GemRB.LoadTable ("repstart")
- AlignmentTable = GemRB.LoadTable ("aligns")
t = TmpTable.GetValue (AllignID,0) * 10
GemRB.SetPlayerStat (MyChar, IE_REPUTATION, t)
@@ -377,6 +367,27 @@ def setAccept():
#10 is a weapon slot (see slottype.2da row 10)
GemRB.CreateItem (MyChar, "staf01", 10, 1, 0, 0)
GemRB.SetEquippedQuickSlot (MyChar, 0)
+
+ # apply class/kit abilities
+ IsMulti = GUICommon.IsMultiClassed (MyChar, 1)
+ Levels = [GemRB.GetPlayerStat (MyChar, IE_LEVEL), GemRB.GetPlayerStat (MyChar, IE_LEVEL2), \
+ GemRB.GetPlayerStat (MyChar, IE_LEVEL3)]
+ KitIndex = GUICommon.GetKitIndex (MyChar)
+ if IsMulti[0]>1:
+ #get the class abilites for each class
+ for i in range (IsMulti[0]):
+ TmpClassName = GUICommon.GetClassRowName (IsMulti[i+1], "class")
+ ABTable = CommonTables.ClassSkills.GetValue (TmpClassName, "ABILITIES")
+ if ABTable != "*" and GemRB.HasResource (ABTable, RES_2DA, 1):
+ GUICommon.AddClassAbilities (MyChar, ABTable, Levels[i], Levels[i])
+ else:
+ if KitIndex:
+ ABTable = CommonTables.KitList.GetValue (str(KitIndex), "ABILITIES")
+ else:
+ ABTable = CommonTables.ClassSkills.GetValue (ClassName, "ABILITIES")
+ if ABTable != "*" and GemRB.HasResource (ABTable, RES_2DA, 1):
+ GUICommon.AddClassAbilities (MyChar, ABTable, Levels[0], Levels[0])
+
#LETS PLAY!!
playmode = GemRB.GetVar ("PlayMode")
diff --git a/gemrb/GUIScripts/bg1/GUICG10.py b/gemrb/GUIScripts/bg1/GUICG10.py
index a156882..71bc129 100644
--- a/gemrb/GUIScripts/bg1/GUICG10.py
+++ b/gemrb/GUIScripts/bg1/GUICG10.py
@@ -42,7 +42,8 @@ def OnLoad():
j=0
for i in range(1,ClassCount):
- if CommonTables.Classes.GetValue(i-1,4)==0:
+ ClassName = CommonTables.Classes.GetRowName (i-1)
+ if CommonTables.Classes.GetValue (ClassName, "MULTI") == 0:
continue
if j>11:
Button = ClassWindow.GetControl(j+7)
@@ -51,18 +52,19 @@ def OnLoad():
Button.SetState(IE_GUI_BUTTON_DISABLED)
Button.SetFlags(IE_GUI_BUTTON_RADIOBUTTON,OP_OR)
j = j + 1
+
j=0
for i in range(1,ClassCount):
- ClassName = CommonTables.Classes.GetRowName(i-1)
+ ClassName = CommonTables.Classes.GetRowName (i-1)
Allowed = CommonTables.Classes.GetValue(ClassName, RaceName)
- if CommonTables.Classes.GetValue(i-1,4)==0:
+ if CommonTables.Classes.GetValue (ClassName, "MULTI") == 0:
continue
if j>11:
Button = ClassWindow.GetControl(j+7)
else:
Button = ClassWindow.GetControl(j+2)
- t = CommonTables.Classes.GetValue(i-1, 0)
+ t = CommonTables.Classes.GetValue (ClassName, "NAME_REF")
Button.SetText(t )
j=j+1
if Allowed ==0:
@@ -86,15 +88,15 @@ def OnLoad():
return
def ClassPress():
- Class = GemRB.GetVar("Class")-1
- TextAreaControl.SetText(CommonTables.Classes.GetValue(Class,1) )
+ ClassName = GUICommon.GetClassRowName (GemRB.GetVar ("Class")-1, "index")
+ TextAreaControl.SetText (CommonTables.Classes.GetValue (ClassName, "DESC_REF"))
DoneButton.SetState(IE_GUI_BUTTON_ENABLED)
return
def NextPress():
#class
- ClassIndex = GemRB.GetVar ("Class")-1
- Class = CommonTables.Classes.GetValue (ClassIndex, 5)
+ ClassName = GUICommon.GetClassRowName (GemRB.GetVar ("Class")-1, "index")
+ Class = CommonTables.Classes.GetValue (ClassName, "ID")
MyChar = GemRB.GetVar ("Slot")
GemRB.SetPlayerStat (MyChar, IE_CLASS, Class)
CharGenCommon.next()
diff --git a/gemrb/GUIScripts/bg1/GUICG15.py b/gemrb/GUIScripts/bg1/GUICG15.py
index cfcbe55..0b5d56c 100644
--- a/gemrb/GUIScripts/bg1/GUICG15.py
+++ b/gemrb/GUIScripts/bg1/GUICG15.py
@@ -62,9 +62,7 @@ def OnLoad():
GemRB.SetVar ("HatedRace",0)
- ClassRow = GemRB.GetVar("Class")-1
- Class = CommonTables.Classes.GetValue(ClassRow, 5)
- ClassName = CommonTables.ClassSkills.GetRowName(Class)
+ ClassName = GUICommon.GetClassRowName (GemRB.GetVar ("Class")-1, "index")
TableName = CommonTables.ClassSkills.GetValue(ClassName, "HATERACE")
GemRB.LoadWindowPack("GUICG", 640, 480)
diff --git a/gemrb/GUIScripts/bg1/GUICG2.py b/gemrb/GUIScripts/bg1/GUICG2.py
index 60429c4..681345f 100644
--- a/gemrb/GUIScripts/bg1/GUICG2.py
+++ b/gemrb/GUIScripts/bg1/GUICG2.py
@@ -53,7 +53,8 @@ def OnLoad():
#radiobutton groups must be set up before doing anything else to them
for i in range(1,ClassCount):
- if CommonTables.Classes.GetValue(i-1,4):
+ ClassName = CommonTables.Classes.GetRowName (i-1)
+ if CommonTables.Classes.GetValue(ClassName, "MULTI"):
continue
Button = ClassWindow.GetControl(i+1)
@@ -65,14 +66,14 @@ def OnLoad():
for i in range(1,ClassCount):
ClassName = CommonTables.Classes.GetRowName(i-1)
Allowed = CommonTables.Classes.GetValue(ClassName, RaceName)
- if CommonTables.Classes.GetValue(i-1,4):
+ if CommonTables.Classes.GetValue (ClassName, "MULTI"):
if Allowed!=0:
HasMulti = 1
continue
Button = ClassWindow.GetControl(i+1)
- t = CommonTables.Classes.GetValue(i-1, 0)
+ t = CommonTables.Classes.GetValue(ClassName, "NAME_REF")
Button.SetText(t )
if Allowed==2:
@@ -102,12 +103,12 @@ def OnLoad():
TextAreaControl = ClassWindow.GetControl(13)
- Class = GemRB.GetVar("Class")-1
- if Class<0:
+ ClassName = GUICommon.GetClassRowName (GemRB.GetVar ("Class")-1, "index")
+ if ClassName == "":
TextAreaControl.SetText(17242)
DoneButton.SetState(IE_GUI_BUTTON_DISABLED)
else:
- TextAreaControl.SetText(CommonTables.Classes.GetValue(Class,1) )
+ TextAreaControl.SetText (CommonTables.Classes.GetValue (ClassName, "DESC_REF"))
DoneButton.SetState(IE_GUI_BUTTON_ENABLED)
MultiClassButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, MultiClassPress)
@@ -129,18 +130,15 @@ def SpecialistPress():
CharGenCommon.next()
def ClassPress():
- Class = GemRB.GetVar("Class")-1
- TextAreaControl.SetText(CommonTables.Classes.GetValue(Class,1) )
+ ClassName = GUICommon.GetClassRowName (GemRB.GetVar ("Class")-1, "index")
+ TextAreaControl.SetText (CommonTables.Classes.GetValue (ClassName, "DESC_REF") )
DoneButton.SetState(IE_GUI_BUTTON_ENABLED)
return
def NextPress():
# find the class from the class table
- ClassIndex = GemRB.GetVar ("Class") - 1
- Class = CommonTables.Classes.GetValue (ClassIndex, 5)
- #protect against barbarians
- ClassName = CommonTables.Classes.GetRowName (CommonTables.Classes.FindValue (5, Class) )
-
+ ClassName = GUICommon.GetClassRowName (GemRB.GetVar ("Class")-1, "index")
+ Class = CommonTables.Classes.GetValue (ClassName, "ID")
MyChar = GemRB.GetVar ("Slot")
GemRB.SetPlayerStat (MyChar, IE_CLASS, Class)
CharGenCommon.next()
diff --git a/gemrb/GUIScripts/bg1/GUICG22.py b/gemrb/GUIScripts/bg1/GUICG22.py
index 3cffeff..651b6b4 100644
--- a/gemrb/GUIScripts/bg1/GUICG22.py
+++ b/gemrb/GUIScripts/bg1/GUICG22.py
@@ -29,11 +29,11 @@ KitWindow = 0
TextAreaControl = 0
DoneButton = 0
SchoolList = 0
-ClassID = 0
+ClassName = 0
def OnLoad():
global KitWindow, TextAreaControl, DoneButton
- global SchoolList, ClassID
+ global SchoolList, ClassName
if GUICommon.CloseOtherWindow(OnLoad):
if(KitWindow):
@@ -43,9 +43,7 @@ def OnLoad():
GemRB.LoadWindowPack("GUICG", 640, 480)
RaceName = CommonTables.Races.GetRowName(GemRB.GetVar("Race")-1 )
- Class = GemRB.GetVar("Class")-1
- ClassName = CommonTables.Classes.GetRowName(Class)
- ClassID = CommonTables.Classes.GetValue(Class, 5)
+ ClassName = GUICommon.GetClassRowName (GemRB.GetVar ("Class")-1, "index")
KitTable = GemRB.LoadTable("kittable")
KitTableName = KitTable.GetValue(ClassName, RaceName)
KitTable = GemRB.LoadTable(KitTableName,1)
@@ -68,16 +66,16 @@ def OnLoad():
for i in range(RowCount):
Button = KitWindow.GetControl(i+2)
if not KitTable:
- if ClassID == 1:
+ if ClassName == "MAGE":
Kit=GemRB.GetVar("MAGESCHOOL")
KitName = SchoolList.GetValue(i, 0)
else:
Kit = 0
- KitName = CommonTables.Classes.GetValue(GemRB.GetVar("Class")-1, 0)
+ KitName = CommonTables.Classes.GetValue(ClassName, "NAME_REF")
else:
Kit = KitTable.GetValue(i,0)
- if ClassID == 1:
+ if ClassName == "MAGE":
if Kit:
Kit = Kit - 21
KitName = SchoolList.GetValue(Kit, 0)
@@ -85,7 +83,7 @@ def OnLoad():
if Kit:
KitName = CommonTables.KitList.GetValue(Kit, 1)
else:
- KitName = CommonTables.Classes.GetValue(GemRB.GetVar("Class")-1, 0)
+ KitName = CommonTables.Classes.GetValue (ClassName, "NAME_REF")
Button.SetState(IE_GUI_BUTTON_ENABLED)
Button.SetText(KitName)
@@ -101,7 +99,7 @@ def OnLoad():
DoneButton.SetFlags(IE_GUI_BUTTON_DEFAULT,OP_OR)
TextAreaControl = KitWindow.GetControl(11)
- TextAreaControl.SetText(17247)
+ TextAreaControl.SetText(17245)
DoneButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, NextPress)
BackButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, CharGenCommon.BackPress)
@@ -112,9 +110,9 @@ def OnLoad():
def KitPress():
Kit = GemRB.GetVar("Class Kit")
if Kit == 0:
- KitName = CommonTables.Classes.GetValue(GemRB.GetVar("Class")-1, 1)
+ KitName = CommonTables.Classes.GetValue(ClassName, "DESC_REF")
else:
- if ClassID==1:
+ if ClassName == "MAGE":
KitName = SchoolList.GetValue(Kit, 1)
else:
KitName = CommonTables.KitList.GetValue(Kit, 3)
@@ -124,12 +122,11 @@ def KitPress():
def NextPress():
#class
- ClassIndex = GemRB.GetVar ("Class")-1
- Class = CommonTables.Classes.GetValue (ClassIndex, 5)
+ Class = CommonTables.Classes.GetValue (ClassName, "ID")
MyChar = GemRB.GetVar ("Slot")
GemRB.SetPlayerStat (MyChar, IE_CLASS, Class)
KitIndex = GemRB.GetVar ("Class Kit")
- if Class == 1:
+ if ClassName == "MAGE":
GemRB.SetVar("MAGESCHOOL", KitIndex)
#the same as the unusable field
Kit = CommonTables.KitList.GetValue(KitIndex, 6)
diff --git a/gemrb/GUIScripts/bg1/GUICG3.py b/gemrb/GUIScripts/bg1/GUICG3.py
index d15afd0..7c259b4 100644
--- a/gemrb/GUIScripts/bg1/GUICG3.py
+++ b/gemrb/GUIScripts/bg1/GUICG3.py
@@ -28,11 +28,9 @@ import CommonTables
AlignmentWindow = 0
TextAreaControl = 0
DoneButton = 0
-AlignmentTable = 0
def OnLoad():
global AlignmentWindow, TextAreaControl, DoneButton
- global AlignmentTable
if GUICommon.CloseOtherWindow (OnLoad):
if(AlignmentWindow):
@@ -44,21 +42,18 @@ def OnLoad():
GemRB.SetVar("Alignment",-1)
- Class = GemRB.GetPlayerStat (MyChar, IE_CLASS)
- ClassRow = CommonTables.Classes.FindValue(5,Class)
- KitName = CommonTables.Classes.GetRowName(ClassRow)
+ KitName = GUICommon.GetClassRowName (MyChar)
AlignmentOk = GemRB.LoadTable("ALIGNMNT")
GemRB.LoadWindowPack("GUICG", 640, 480)
- AlignmentTable = GemRB.LoadTable("aligns")
AlignmentWindow = GemRB.LoadWindow(3)
for i in range(9):
Button = AlignmentWindow.GetControl(i+2)
Button.SetFlags(IE_GUI_BUTTON_RADIOBUTTON,OP_OR)
Button.SetState(IE_GUI_BUTTON_DISABLED)
- Button.SetText(AlignmentTable.GetValue(i,0) )
+ Button.SetText (CommonTables.Aligns.GetValue (i,0))
# This section enables or disables different alignment selections
# based on Class, and depends on the ALIGNMNT.2DA table
@@ -66,7 +61,7 @@ def OnLoad():
# For now, we just enable all buttons
for i in range(9):
Button = AlignmentWindow.GetControl(i+2)
- if AlignmentOk.GetValue(KitName, AlignmentTable.GetValue(i, 4) ) != 0:
+ if AlignmentOk.GetValue (KitName, CommonTables.Aligns.GetValue (i, 4)) != 0:
Button.SetState(IE_GUI_BUTTON_ENABLED)
else:
Button.SetState(IE_GUI_BUTTON_DISABLED)
@@ -91,9 +86,9 @@ def OnLoad():
def AlignmentPress():
Alignment = GemRB.GetVar("Alignment")
- TextAreaControl.SetText(AlignmentTable.GetValue(Alignment,1) )
+ TextAreaControl.SetText (CommonTables.Aligns.GetValue (Alignment,1))
DoneButton.SetState(IE_GUI_BUTTON_ENABLED)
- GemRB.SetVar("Alignment",AlignmentTable.GetValue(Alignment,3) )
+ GemRB.SetVar ("Alignment", CommonTables.Aligns.GetValue (Alignment,3))
return
def NextPress():
diff --git a/gemrb/GUIScripts/bg1/GUICG4.py b/gemrb/GUIScripts/bg1/GUICG4.py
index 7ec64a1..ad4f269 100644
--- a/gemrb/GUIScripts/bg1/GUICG4.py
+++ b/gemrb/GUIScripts/bg1/GUICG4.py
@@ -125,16 +125,15 @@ def OnLoad():
MyChar = GemRB.GetVar ("Slot")
Kit = GUICommon.GetKitIndex (MyChar)
- Class = GemRB.GetPlayerStat (MyChar, IE_CLASS)
- Class = CommonTables.Classes.FindValue (5, Class)
+ ClassName = GUICommon.GetClassRowName (MyChar)
if Kit == 0:
- KitName = CommonTables.Classes.GetRowName(Class)
+ KitName = ClassName
else:
#rowname is just a number, first value row what we need here
KitName = CommonTables.KitList.GetValue(Kit, 0)
#if the class uses the warrior table for saves, then it may have the extra strength
- if CommonTables.Classes.GetValue(Class, 3)=="SAVEWAR":
+ if CommonTables.Classes.GetValue (ClassName, "SAVE") == "SAVEWAR":
HasStrExtra=1
else:
HasStrExtra=0
diff --git a/gemrb/GUIScripts/bg1/GUICG7.py b/gemrb/GUIScripts/bg1/GUICG7.py
index a0559ab..eb1cab9 100644
--- a/gemrb/GUIScripts/bg1/GUICG7.py
+++ b/gemrb/GUIScripts/bg1/GUICG7.py
@@ -22,17 +22,19 @@ import GemRB
from GUIDefines import *
from ie_stats import *
import GUICommon
+import Spellbook
import CommonTables
import LUSpellSelection
def OnLoad():
Slot = GemRB.GetVar ("Slot")
Class = GemRB.GetPlayerStat (Slot, IE_CLASS)
- TableName = CommonTables.ClassSkills.GetValue(Class, 2)
+ ClassName = GUICommon.GetClassRowName (Class, "class")
+ TableName = CommonTables.ClassSkills.GetValue(ClassName, "MAGESPELL")
# make sure we have a correct table
if Class == 19:
- # sorcerer's need their known not max table
+ # sorcerers need their known not max table or they would progress too slowly
TableName = "SPLSRCKN"
# get our kit
@@ -44,10 +46,11 @@ def OnLoad():
Level = GemRB.GetPlayerStat (Slot, IE_LEVEL)
if IsMulti[0]>1:
for i in range (1, IsMulti[0]):
- if CommonTables.ClassSkills.GetValue (IsMulti[i], 2, 0) != "*":
+ ClassName = GUICommon.GetClassRowName (IsMulti[i], "class")
+ if CommonTables.ClassSkills.GetValue (ClassName, "MAGESPELL", 0) != "*":
Level = GemRB.GetPlayerStat (Slot, IE_LEVEL2+i-1)
break
- GUICommon.SetupSpellLevels(Slot, TableName, IE_SPELL_TYPE_WIZARD, 1)
+ Spellbook.SetupSpellLevels(Slot, TableName, IE_SPELL_TYPE_WIZARD, 1)
LUSpellSelection.OpenSpellsWindow (Slot, TableName, Level, Level, KitValue, 1,False)
return
diff --git a/gemrb/GUIScripts/bg1/GUICommonWindows.py b/gemrb/GUIScripts/bg1/GUICommonWindows.py
deleted file mode 100644
index 8475bff..0000000
--- a/gemrb/GUIScripts/bg1/GUICommonWindows.py
+++ /dev/null
@@ -1,866 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-# GUICommonWindows.py - functions to open common
-# windows in lower part of the screen
-###################################################
-
-import GemRB
-from GUIDefines import *
-from ie_stats import *
-from ie_modal import *
-from ie_action import *
-import GUICommon
-import LUCommon
-import InventoryCommon
-
-# needed for all the Open*Window callbacks in the OptionsWindow
-import GUIJRNL
-import GUIMA
-import GUIMG
-import GUIINV
-import GUIOPT
-import GUIPR
-import GUIREC
-
-FRAME_PC_SELECTED = 0
-FRAME_PC_TARGET = 1
-
-PortraitWindow = None
-OptionsWindow = None
-ActionsWindow = None
-DraggedPortrait = None
-
-def SetupMenuWindowControls (Window, Gears, ReturnToGame):
- """Sets up all of the basic control windows."""
- global OptionsWindow
-
- OptionsWindow = Window
- # FIXME: add "(key)" to tooltips!
-
- # Return to Game
- Button = Window.GetControl (0)
- Button.SetTooltip (16313)
- #Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- # enabled BAM isn't present in .chu, defining it here
- Button.SetSprites ("GUILSOP", 0,16,17,28,16)
- Button.SetVarAssoc ("SelectedWindow", 0)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, ReturnToGame)
- Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- # Map
- Button = Window.GetControl (1)
- Button.SetTooltip (16310)
- #Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- Button.SetSprites ("GUILSOP", 0,0,1,20,0)
- Button.SetVarAssoc ("SelectedWindow", 1)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIMA.OpenMapWindow)
-
- # Journal
- Button = Window.GetControl (2)
- Button.SetTooltip (16308)
- #Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- Button.SetSprites ("GUILSOP", 0,4,5,22,4)
- Button.SetVarAssoc ("SelectedWindow", 2)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIJRNL.OpenJournalWindow)
-
- # Inventory
- Button = Window.GetControl (3)
- Button.SetTooltip (16307)
- #Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- Button.SetSprites ("GUILSOP", 0,2,3,21,2)
- Button.SetVarAssoc ("SelectedWindow", 3)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIINV.OpenInventoryWindow)
-
- # Records
- Button = Window.GetControl (4)
- Button.SetTooltip (16306)
- #Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- Button.SetSprites ("GUILSOP", 0,6,7,23,6)
- Button.SetVarAssoc ("SelectedWindow", 4)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIREC.OpenRecordsWindow)
-
- # Mage
- Button = Window.GetControl (5)
- Button.SetTooltip (16309)
- #Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- Button.SetSprites ("GUILSOP", 0,8,9,24,8)
- Button.SetVarAssoc ("SelectedWindow", 5)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIMG.OpenMageWindow)
-
- # Priest
- Button = Window.GetControl (6)
- Button.SetTooltip (14930)
- #Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- Button.SetSprites ("GUILSOP", 0,10,11,25,10)
- Button.SetVarAssoc ("SelectedWindow", 6)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIPR.OpenPriestWindow)
-
- # Options
- Button = Window.GetControl (7)
- Button.SetTooltip (16311)
- #Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- Button.SetSprites ("GUILSOP", 0,12,13,26,12)
- Button.SetVarAssoc ("SelectedWindow", 7)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIOPT.OpenOptionsWindow)
-
- # Party mgmt
- Button = Window.GetControl (8)
- Button.SetTooltip (16312)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, None) #TODO: OpenPartyWindow
-
- #gears
- if Gears:
- # Pendulum, gears, sun/moon dial (time)
- # FIXME: display all animations: CPEN, CGEAR, CDIAL
- Button = Window.GetControl (9)
- Button.SetAnimation ("CGEAR")
- Button.SetState (IE_GUI_BUTTON_ENABLED)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_ANIMATED|IE_GUI_BUTTON_NORMAL, OP_SET)
- Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, GUICommon.GearsClicked)
- GUICommon.SetGamedaysAndHourToken()
- Button.SetTooltip(16041)
-
- MarkMenuButton (Window)
-
- return
-
-def MarkMenuButton (WindowIndex):
- Pressed = WindowIndex.GetControl( GemRB.GetVar ("SelectedWindow") )
-
- for button in range (9):
- Button = WindowIndex.GetControl (button)
- Button.SetState (IE_GUI_BUTTON_ENABLED)
-
- if Pressed:
- Button = Pressed
- else: # highlight return to game
- Button = WindowIndex.GetControl (0)
-
- Button.SetState (IE_GUI_BUTTON_SELECTED)
-
-def AIPress ():
- Button = PortraitWindow.GetControl (6)
- AI = GemRB.GetMessageWindowSize () & GS_PARTYAI
-
- if AI:
- GemRB.GameSetScreenFlags (GS_PARTYAI, OP_NAND)
- Button.SetTooltip (15918)
- else:
- GemRB.GameSetScreenFlags (GS_PARTYAI, OP_OR)
- Button.SetTooltip (15917)
- return
-
-def EmptyControls ():
- global ActionsWindow
-
- GemRB.SetVar ("ActionLevel", 0)
- Window = ActionsWindow
- for i in range (12):
- Button = Window.GetControl (i)
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- Button.SetPicture ("")
- Button.SetText ("")
- Button.SetActionIcon (globals(), -1)
- return
-
-def SelectFormationPreset ():
- """Choose the default formation."""
- GemRB.GameSetFormation (GemRB.GetVar ("Value"), GemRB.GetVar ("Formation") )
- GroupControls ()
- return
-
-def SetupFormation ():
- """Opens the formation selection section."""
- global ActionsWindow
-
- Window = ActionsWindow
- for i in range (12):
- Button = Window.GetControl (i)
- Button.SetFlags (IE_GUI_BUTTON_NORMAL, OP_SET)
- Button.SetSprites ("GUIBTBUT",0,0,1,2,3)
- Button.SetBAM ("FORM%x"%i,0,0,-1)
- Button.SetVarAssoc ("Value", i)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SelectFormationPreset)
- return
-
-def GroupControls ():
- """Sections that control group actions."""
-
- global ActionsWindow
-
- GemRB.SetVar ("ActionLevel", 0)
- Window = ActionsWindow
- Button = Window.GetControl (0)
- Button.SetActionIcon (globals(), 14)
- Button = Window.GetControl (1)
- Button.SetActionIcon (globals(), 7)
- Button = Window.GetControl (2)
- Button.SetActionIcon (globals(), 15)
- Button = Window.GetControl (3)
- Button.SetActionIcon (globals(), 21)
- Button = Window.GetControl (4)
- Button.SetActionIcon (globals(), -1)
- Button = Window.GetControl (5)
- Button.SetActionIcon (globals(), -1)
- Button = Window.GetControl (6)
- Button.SetActionIcon (globals(), -1)
- GemRB.SetVar ("Formation", GemRB.GameGetFormation ())
- for i in range (5):
- Button = Window.GetControl (7+i)
- Button.SetState (IE_GUI_BUTTON_ENABLED)
- idx = GemRB.GameGetFormation (i)
- Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON|IE_GUI_BUTTON_NORMAL, OP_SET)
- Button.SetSprites ("GUIBTBUT",0,0,1,2,3)
- Button.SetBAM ("FORM%x"%idx,0,0,-1)
- Button.SetVarAssoc ("Formation", i)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUICommon.SelectFormation)
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, SetupFormation)
- str = GemRB.GetString (4935)
- Button.SetTooltip ("F%d - %s"%(8+i,str) )
- return
-
-def OpenActionsWindowControls (Window):
- global ActionsWindow
-
- ActionsWindow = Window
- # Gears (time) when options pane is down
- #Button = Window.GetControl (62)
- #Button.SetAnimation ("CGEAR")
- #Button.SetFlags (IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_ANIMATED, OP_SET)
- #Button.SetState (IE_GUI_BUTTON_LOCKED)
- UpdateActionsWindow ()
- return
-
-def SelectItemAbility():
- pc = GemRB.GameGetFirstSelectedActor ()
- slot = GemRB.GetVar ("Slot")
- ability = GemRB.GetVar ("Ability")
- GemRB.SetupQuickSlot (pc, 0, slot, ability, 1)
- GemRB.SetVar ("ActionLevel", 0)
- return
-
-def SetupItemAbilities(pc, slot):
- Window = ActionsWindow
-
- slot_item = GemRB.GetSlotItem(pc, slot, 1)
- item = GemRB.GetItem (slot_item["ItemResRef"])
- Tips = item["Tooltips"]
-
- for i in range (12):
- Button = Window.GetControl (i)
- Button.SetPicture ("")
- if i<len(Tips):
- Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON|IE_GUI_BUTTON_NORMAL, OP_SET)
- Button.SetSprites ("GUIBTBUT",0,0,1,2,3)
- Button.SetItemIcon (slot_item['ItemResRef'], i+6)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SelectItemAbility)
- Button.SetVarAssoc ("Ability", i)
-
- Button.SetTooltip ("F%d - %s"%(i+1,GemRB.GetString(Tips[i])) )
- else:
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- return
-
-def UpdateActionsWindow ():
- global ActionsWindow
- global level, TopIndex
-
- if ActionsWindow == -1:
- return
-
- if ActionsWindow == None:
- return
-
- Selected = GemRB.GetSelectedSize()
-
- #setting up the disabled button overlay (using the second border slot)
- for i in range (12):
- Button = ActionsWindow.GetControl (i)
- Button.SetBorder (0,6,6,4,4,0,254,0,255)
- Button.SetBorder (1, 0, 0, 0, 0, 50,30,10,120, 0, 1)
- Button.SetFont ("NUMBER")
- Button.SetText ("")
-
- if Selected == 0:
- EmptyControls ()
- return
- if Selected > 1:
- GroupControls ()
- return
-
- #we are sure there is only one actor selected
- pc = GemRB.GameGetFirstSelectedActor ()
-
- level = GemRB.GetVar ("ActionLevel")
- TopIndex = GemRB.GetVar ("TopIndex")
- if level == 0:
- #this is based on class
- ActionsWindow.SetupControls (globals(), pc, 0, 1)
- elif level == 1:
- ActionsWindow.SetupEquipmentIcons(globals(), pc, TopIndex, 0, 1)
- elif level == 2: #spells
- GemRB.SetVar ("Type", 3)
- ActionsWindow.SetupSpellIcons(globals(), pc, 3, TopIndex, 0, 1)
- elif level == 3: #innates
- GemRB.SetVar ("Type", 4)
- ActionsWindow.SetupSpellIcons(globals(), pc, 4, TopIndex, 0, 1)
- elif level == 4: #quick weapon/item ability selection
- SetupItemAbilities(pc, GemRB.GetVar("Slot") )
- return
-
-def ActionQWeaponPressed (which):
- """Selects the given quickslot weapon if possible."""
-
- pc = GemRB.GameGetFirstSelectedActor ()
- qs = GemRB.GetEquippedQuickSlot (pc, 1, 1)
-
- #38 is the magic slot
- if ((qs==which) or (qs==38)) and GemRB.GameControlGetTargetMode() != TARGET_MODE_ATTACK:
- GemRB.GameControlSetTargetMode (TARGET_MODE_ATTACK, GA_NO_DEAD|GA_NO_SELF|GA_NO_HIDDEN)
- else:
- GemRB.GameControlSetTargetMode (TARGET_MODE_NONE)
- GemRB.SetEquippedQuickSlot (pc, which, -1, 1)
-
- ActionsWindow.SetupControls (globals(), pc, 0, 1)
- UpdateActionsWindow ()
- return
-
-def ActionQWeapon1Pressed ():
- ActionQWeaponPressed(0)
-
-def ActionQWeapon2Pressed ():
- ActionQWeaponPressed(1)
-
-def ActionQWeapon3Pressed ():
- ActionQWeaponPressed(2)
-
-def ActionQWeapon4Pressed ():
- ActionQWeaponPressed(3)
-
-#no check needed because the button wouldn't be drawn if illegal
-def ActionLeftPressed ():
- """Scrolls the actions window left.
-
- Used primarily for spell selection."""
-
- TopIndex = GemRB.GetVar ("TopIndex")
- if TopIndex>10:
- TopIndex -= 10
- else:
- TopIndex = 0
- GemRB.SetVar ("TopIndex", TopIndex)
- UpdateActionsWindow ()
- return
-
-#no check needed because the button wouldn't be drawn if illegal
-def ActionRightPressed ():
- """Scrolls the action window right.
-
- Used primarily for spell selection."""
-
- pc = GemRB.GameGetFirstSelectedActor ()
- TopIndex = GemRB.GetVar ("TopIndex")
- Type = GemRB.GetVar ("Type")
- #Type is a bitfield if there is no level given
- #This is to make sure cleric/mages get all spells listed
- Max = GemRB.GetMemorizedSpellsCount(pc, Type, -1, 1)
- TopIndex += 10
- if TopIndex > Max - 10:
- if Max>10:
- TopIndex = Max-10
- else:
- TopIndex = 0
-
- GemRB.SetVar ("TopIndex", TopIndex)
- UpdateActionsWindow ()
- return
-
-def ActionBardSongPressed ():
- """Toggles the battle song."""
- pc = GemRB.GameGetFirstSelectedActor ()
- GemRB.SetModalState (pc, MS_BATTLESONG, 1)
- GemRB.PlaySound ("act_01")
- UpdateActionsWindow ()
- return
-
-def ActionSearchPressed ():
- """Toggles detect traps."""
- pc = GemRB.GameGetFirstSelectedActor ()
- GemRB.SetModalState (pc, MS_DETECTTRAPS, 1)
- UpdateActionsWindow ()
- return
-
-def ActionStealthPressed ():
- """Toggles stealth."""
- pc = GemRB.GameGetFirstSelectedActor ()
- GemRB.SetModalState (pc, MS_STEALTH, 1)
- GemRB.PlaySound ("act_07")
- UpdateActionsWindow ()
- return
-
-def ActionTurnPressed ():
- """Toggles turn undead."""
- pc = GemRB.GameGetFirstSelectedActor ()
- GemRB.SetModalState (pc, MS_TURNUNDEAD, 1)
- GemRB.PlaySound ("act_06")
- UpdateActionsWindow ()
- return
-
-def ActionUseItemPressed ():
- GemRB.SetVar ("TopIndex", 0)
- GemRB.SetVar ("ActionLevel", 1)
- UpdateActionsWindow ()
- return
-
-def ActionCastPressed ():
- """Opens the spell choice scrollbar."""
- GemRB.SetVar ("TopIndex", 0)
- GemRB.SetVar ("ActionLevel", 2)
- UpdateActionsWindow ()
- return
-
-def ActionQItemPressed (action):
- """Uses the given quick item."""
- pc = GemRB.GameGetFirstSelectedActor ()
- #quick slot
- GemRB.UseItem (pc, -2, action, -1, 1)
- return
-
-def ActionQItem1Pressed ():
- ActionQItemPressed (ACT_QSLOT1)
- return
-
-def ActionQItem2Pressed ():
- ActionQItemPressed (ACT_QSLOT2)
- return
-
-def ActionQItem3Pressed ():
- ActionQItemPressed (ACT_QSLOT3)
- return
-
-def ActionQItem4Pressed ():
- ActionQItemPressed (ACT_QSLOT4)
- return
-
-def ActionQItem5Pressed ():
- ActionQItemPressed (ACT_QSLOT5)
- return
-
-def ActionQItemRightPressed (action):
- """Selects the used ability of the quick item."""
- pc = GemRB.GameGetFirstSelectedActor ()
- GemRB.SetVar ("Slot", action)
- GemRB.SetVar ("ActionLevel", 4)
- UpdateActionsWindow ()
- return
-
-def ActionQItem1RightPressed ():
- ActionQItemRightPressed (19)
-
-def ActionQItem2RightPressed ():
- ActionQItemRightPressed (20)
-
-def ActionQItem3RightPressed ():
- ActionQItemRightPressed (21)
-
-def ActionQItem4RightPressed ():
- ActionQItemRightPressed (22)
-
-def ActionQItem5RightPressed ():
- ActionQItemRightPressed (23)
-
-def ActionQWeapon1RightPressed ():
- ActionQItemRightPressed (10)
-
-def ActionQWeapon2RightPressed ():
- ActionQItemRightPressed (11)
-
-def ActionQWeapon3RightPressed ():
- ActionQItemRightPressed (12)
-
-def ActionQWeapon4RightPressed ():
- ActionQItemRightPressed (13)
-
-def ActionInnatePressed ():
- """Opens the innate spell scrollbar."""
- GemRB.SetVar ("TopIndex", 0)
- GemRB.SetVar ("ActionLevel", 3)
- UpdateActionsWindow ()
- return
-
-def SpellPressed ():
- """Prepares a spell to be cast."""
-
- pc = GemRB.GameGetFirstSelectedActor ()
-
- GemRB.GameControlSetTargetMode (TARGET_MODE_CAST)
- Spell = GemRB.GetVar ("Spell")
- Type = GemRB.GetVar ("Type")
- GemRB.SpellCast (pc, Type, Spell, 1)
- GemRB.SetVar ("ActionLevel", 0)
- UpdateActionsWindow ()
- return
-
-def EquipmentPressed ():
- pc = GemRB.GameGetFirstSelectedActor ()
-
- GemRB.GameControlSetTargetMode (TARGET_MODE_CAST)
- Item = GemRB.GetVar ("Equipment")
- #equipment index
- GemRB.UseItem (pc, -1, Item, -1, 1)
- GemRB.SetVar ("ActionLevel", 0)
- UpdateActionsWindow ()
- return
-
-SelectionChangeHandler = None
-
-def SetSelectionChangeHandler (handler):
- """Updates the selection handler."""
-
- global SelectionChangeHandler
-
- # Switching from walking to non-walking environment:
- # set the first selected PC in walking env as a selected
- # in nonwalking env
- #if (not SelectionChangeHandler) and handler:
- if (not SelectionChangeHandler) and handler and (not GUICommon.NextWindowFn):
- sel = GemRB.GameGetFirstSelectedPC ()
- if not sel:
- sel = 1
- GemRB.GameSelectPCSingle (sel)
-
- SelectionChangeHandler = handler
-
- # redraw selection on change main selection | single selection
- SelectionChanged ()
- return
-
-def RunSelectionChangeHandler ():
- if SelectionChangeHandler:
- SelectionChangeHandler ()
- return
-
-def OpenPortraitWindow (needcontrols):
- global PortraitWindow
-
- PortraitWindow = Window = GemRB.LoadWindow (1)
-
- if needcontrols:
- #Button=Window.GetControl (8)
- #Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, MinimizePortraits)
-
- # AI
- Button = Window.GetControl (6)
- GSFlags = GemRB.GetMessageWindowSize ()&GS_PARTYAI
- Button.SetFlags (IE_GUI_BUTTON_CHECKBOX, OP_OR)
- #this control is crippled
- Button.SetSprites ("GUIBTACT", 0, 46, 47, 48, 49)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, AIPress)
- Button.SetVarAssoc ("", GSFlags)
- if GSFlags:
- Button.SetTooltip (15917)
- else:
- Button.SetTooltip (15918)
-
- #Select All
- Button = Window.GetControl (7)
- Button.SetTooltip (10485)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUICommon.SelectAllOnPress)
- else:
- #Rest
- Button = Window.GetControl (6)
- Button.SetTooltip (11942)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUICommon.RestPress)
-
- for i in range (PARTY_SIZE):
- Button = Window.GetControl (i)
- Button.SetFont ("STATES2")
- Button.SetVarAssoc ("PressedPortrait", i+1)
-
- if (needcontrols):
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, GUIINV.OpenInventoryWindowClick)
- else:
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, PortraitButtonOnPress)
-
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, PortraitButtonOnPress)
- Button.SetEvent (IE_GUI_BUTTON_ON_SHIFT_PRESS, PortraitButtonOnShiftPress)
- Button.SetEvent (IE_GUI_BUTTON_ON_DRAG_DROP, InventoryCommon.OnDropItemToPC)
- Button.SetEvent (IE_GUI_BUTTON_ON_DRAG_DROP_PORTRAIT, OnDropPortraitToPC)
- Button.SetEvent (IE_GUI_BUTTON_ON_DRAG, PortraitButtonOnDrag)
- Button.SetEvent (IE_GUI_MOUSE_ENTER_BUTTON, PortraitButtonOnMouseEnter)
- Button.SetEvent (IE_GUI_MOUSE_LEAVE_BUTTON, PortraitButtonOnMouseLeave)
-
- Button.SetBorder (FRAME_PC_SELECTED, 1, 1, 2, 2, 0, 255, 0, 255)
- Button.SetBorder (FRAME_PC_TARGET, 3, 3, 4, 4, 255, 255, 0, 255)
-
- UpdatePortraitWindow ()
- SelectionChanged ()
- return Window
-
-def UpdatePortraitWindow ():
- """Updates all of the portraits."""
-
- Window = PortraitWindow
-
- pc = GemRB.GameGetSelectedPCSingle ()
- Inventory = GemRB.GetVar ("Inventory")
-
- for portid in range (PARTY_SIZE):
- Button = Window.GetControl (portid)
- pic = GemRB.GetPlayerPortrait (portid+1, 1)
- if Inventory and pc != portid+1:
- pic = None
-
- if pic and GemRB.GetPlayerStat(portid+1, IE_STATE_ID) & STATE_DEAD:
- import GUISTORE
- # dead pcs are hidden in all stores but temples
- if GUISTORE.StoreWindow and not GUISTORE.StoreHealWindow:
- pic = None
-
- if not pic:
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- Button.SetText ("")
- Button.SetTooltip ("")
- continue
-
- Button.SetFlags (IE_GUI_BUTTON_PICTURE| IE_GUI_BUTTON_HORIZONTAL| \
- IE_GUI_BUTTON_ALIGN_LEFT| IE_GUI_BUTTON_ALIGN_TOP| \
- IE_GUI_BUTTON_DRAGGABLE|IE_GUI_BUTTON_MULTILINE, OP_SET)
-
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- Button.SetPicture (pic, "NOPORTSM")
- GUICommon.SetupDamageInfo (portid+1, Button)
-
- #add effects on the portrait
- effects = GemRB.GetPlayerStates (portid+1)
- states = ""
- for col in range(len(effects)):
- states = effects[col:col+1] + states
- if col % 3 == 2: states = "\n" + states
- for x in range(3 - (len(effects)/3)):
- states = "\n" + states
- states = "\n" + states
-
- # character - 1 == bam cycle
- # blank space
- flag = blank = chr(33)
-
- # shopping icon
- if pc==portid+1:
- if GemRB.GetStore()!=None:
- flag = chr(37)
- # talk icon
- if GemRB.GameGetSelectedPCSingle(1)==portid+1:
- flag = chr(37)
-
- if LUCommon.CanLevelUp (portid+1):
- states = flag+blank+chr(255) + states
- else:
- states = flag+blank+blank + states
- Button.SetText(states)
- return
-
-def PortraitButtonOnDrag ():
- global DraggedPortrait
-
- #they start from 1
- DraggedPortrait = GemRB.GetVar ("PressedPortrait")
- GemRB.DragItem (DraggedPortrait, -1, "")
- return
-
-def PortraitButtonOnPress ():
- """Selects the portrait individually."""
-
- i = GemRB.GetVar ("PressedPortrait")
-
- if not i:
- return
-
- if GemRB.GameControlGetTargetMode() != TARGET_MODE_NONE:
- GemRB.ActOnPC (i)
- return
-
- if (not SelectionChangeHandler):
- if GemRB.GameIsPCSelected (i):
- GemRB.GameControlSetScreenFlags (SF_CENTERONACTOR, OP_OR)
- GemRB.GameSelectPC (i, True, SELECT_REPLACE)
- else:
- GemRB.GameSelectPCSingle (i)
- SelectionChanged ()
- RunSelectionChangeHandler ()
- return
-
-def PortraitButtonOnShiftPress ():
- """Handles selecting multiple portaits with shift."""
-
- i = GemRB.GetVar ("PressedPortrait")
-
- if not i:
- return
-
- if (not SelectionChangeHandler):
- sel = GemRB.GameIsPCSelected (i)
- sel = not sel
- GemRB.GameSelectPC (i, sel)
- else:
- GemRB.GameSelectPCSingle (i)
- SelectionChanged ()
- RunSelectionChangeHandler ()
- return
-
-def SelectionChanged ():
- """Ran by the Game class when a PC selection is changed."""
-
- global PortraitWindow
-
- if not PortraitWindow:
- return
-
- GemRB.SetVar ("ActionLevel", 0)
- if (not SelectionChangeHandler):
- UpdateActionsWindow ()
- for i in range (PARTY_SIZE):
- Button = PortraitWindow.GetControl (i)
- Button.EnableBorder (FRAME_PC_SELECTED, GemRB.GameIsPCSelected (i + 1))
- else:
- sel = GemRB.GameGetSelectedPCSingle ()
-
- for i in range (PARTY_SIZE):
- Button = PortraitWindow.GetControl (i)
- Button.EnableBorder (FRAME_PC_SELECTED, i + 1 == sel)
- import CommonWindow
- CommonWindow.CloseContainerWindow()
- return
-
-def PortraitButtonOnMouseEnter ():
- global DraggedPortrait
-
- i = GemRB.GetVar ("PressedPortrait")
-
- GemRB.GameControlSetLastActor( i )
- if GemRB.IsDraggingItem()==2:
- if DraggedPortrait != None:
- GemRB.SwapPCs (DraggedPortrait, i)
- GemRB.SetVar ("PressedPortrait", DraggedPortrait)
- DraggedPortrait = i
- GemRB.SetTimedEvent (CheckDragging, 1)
- else:
- OnDropPortraitToPC()
- return
-
- if GemRB.IsDraggingItem ():
- Button = PortraitWindow.GetControl (i)
- Button.EnableBorder (FRAME_PC_TARGET, 1)
- return
-
-def OnDropPortraitToPC ():
- GemRB.SetVar ("PressedPortrait",0)
- GemRB.DragItem (0, -1, "")
- DraggedPortrait = None
- return
-
-def CheckDragging():
- """Contains portrait dragging in case of mouse out-of-range."""
-
- global DraggedPortrait
-
- i = GemRB.GetVar ("PressedPortrait")
- if not i:
- GemRB.DragItem (0, -1, "")
-
- if GemRB.IsDraggingItem()!=2:
- DraggedPortrait = None
- return
-
-def PortraitButtonOnMouseLeave ():
- i = GemRB.GetVar ("PressedPortrait")
- if not i:
- return
-
- Button = PortraitWindow.GetControl (i-1)
- Button.EnableBorder (FRAME_PC_TARGET, 0)
- GemRB.SetVar ("PressedPortrait", 0)
- GemRB.SetTimedEvent (CheckDragging, 1)
- return
-
-def ActionStopPressed ():
- for i in GemRB.GetSelectedActors():
- GemRB.ClearActions (i, 1)
- return
-
-def ActionTalkPressed ():
- GemRB.GameControlSetTargetMode (TARGET_MODE_TALK,GA_NO_DEAD|GA_NO_ENEMY|GA_NO_HIDDEN)
-
-def ActionAttackPressed ():
- GemRB.GameControlSetTargetMode (TARGET_MODE_ATTACK,GA_NO_DEAD|GA_NO_SELF|GA_NO_HIDDEN)
-
-def ActionDefendPressed ():
- GemRB.GameControlSetTargetMode (TARGET_MODE_DEFEND,GA_NO_SELF|GA_NO_ENEMY|GA_NO_HIDDEN)
-
-def ActionThievingPressed ():
- GemRB.GameControlSetTargetMode (TARGET_MODE_PICK, GA_NO_DEAD|GA_NO_SELF|GA_NO_ENEMY|GA_NO_HIDDEN)
-
-def OpenWaitForDiscWindow ():
- global DiscWindow
-
- if DiscWindow:
- GemRB.HideGUI ()
- if DiscWindow:
- DiscWindow.Unload ()
- GemRB.SetVar ("OtherWindow", -1)
- # ...LoadWindowPack()
- EnableAnimatedWindows ()
- DiscWindow = None
- GemRB.UnhideGUI ()
- return
-
- try:
- GemRB.HideGUI ()
- except:
- pass
-
- GemRB.LoadWindowPack ("GUIID")
- DiscWindow = Window = GemRB.LoadWindow (0)
- GemRB.SetVar ("OtherWindow", Window.ID)
- label = DiscWindow.GetControl (0)
-
- disc_num = GemRB.GetVar ("WaitForDisc")
- #disc_path = GemRB.GetVar ("WaitForDiscPath")
- disc_path = 'XX:'
-
- text = GemRB.GetString (31483) + " " + str (disc_num) + " " + GemRB.GetString (31569) + " " + disc_path + "\n" + GemRB.GetString (49152)
- label.SetText (text)
- DisableAnimatedWindows ()
- # 31483 - Please place PS:T disc number
- # 31568 - Please place the PS:T DVD
- # 31569 - in drive
- # 31570 - Wrong disc in drive
- # 31571 - There is no disc in drive
- # 31578 - No disc could be found in drive. Please place Disc 1 in drive.
- # 49152 - To quit the game, press Alt-F4
-
- try:
- GemRB.UnhideGUI ()
- except:
- DiscWindow.SetVisible (WINDOW_VISIBLE)
-
-def CheckLevelUp(pc):
- GemRB.SetVar ("CheckLevelUp"+str(pc), LUCommon.CanLevelUp (pc))
diff --git a/gemrb/GUIScripts/bg1/GUIINV.py b/gemrb/GUIScripts/bg1/GUIINV.py
index 2da0863..37531f4 100644
--- a/gemrb/GUIScripts/bg1/GUIINV.py
+++ b/gemrb/GUIScripts/bg1/GUIINV.py
@@ -102,7 +102,8 @@ def OpenInventoryWindow ():
Button.SetEvent (IE_GUI_MOUSE_ENTER_BUTTON, InventoryCommon.MouseEnterGround)
Button.SetEvent (IE_GUI_MOUSE_LEAVE_BUTTON, InventoryCommon.MouseLeaveGround)
Button.SetVarAssoc ("GroundItemButton", i)
- Button.SetSprites ("STONSLOT",0,0,2,4,3)
+ #This IS different from BG2
+ Button.SetSprites ("STONSLOT",0,0,1,2,3)
Button.SetFont ("NUMBER")
Button.SetBorder (0,0,0,0,0,128,128,255,64,0,1)
Button.SetBorder (1,2,2,2,2,32,32,255,0,0,0)
@@ -127,8 +128,12 @@ def OpenInventoryWindow ():
Button.SetEvent (IE_GUI_BUTTON_ON_DRAG_DROP, InventoryCommon.OnAutoEquip)
#encumbrance
- Label = Window.CreateLabel (0x10000043, 14,375,60,20,"NUMBER","0:",IE_FONT_ALIGN_LEFT|IE_FONT_ALIGN_TOP)
- Label = Window.CreateLabel (0x10000044, 8,445,60,20,"NUMBER","0:",IE_FONT_ALIGN_RIGHT|IE_FONT_ALIGN_TOP)
+ Button = Window.GetControl (67)
+ r = Button.GetRect ()
+ Label = Window.CreateLabel (0x10000043, r["X"],r["Y"],r["Width"],20,
+ "NUMBER","0:",IE_FONT_ALIGN_LEFT|IE_FONT_ALIGN_TOP)
+ Label = Window.CreateLabel (0x10000044, r["X"],r["Y"]+r["Height"]-20,r["Width"],20,
+ "NUMBER","0:",IE_FONT_ALIGN_RIGHT|IE_FONT_ALIGN_BOTTOM)
#armor class
Label = Window.GetControl (0x10000038)
@@ -156,12 +161,12 @@ def OpenInventoryWindow ():
Button.SetVarAssoc ("ItemButton", slot+1)
#keeping 1 in the original place, because it is how
#the gui resource has it, but setting the other cycles
+ #This IS different from BG2
Button.SetSprites ("STONSLOT",0,0,1,2,3)
Button.SetFont ("NUMBER")
Button.SetBorder (0,0,0,0,0,128,128,255,64,0,1)
Button.SetBorder (1,2,2,2,2,32,32,255,0,0,0)
Button.SetBorder (2,0,0,0,0,255,128,128,64,0,1)
- Button.SetFlags (IE_GUI_BUTTON_ALIGN_RIGHT | IE_GUI_BUTTON_ALIGN_TOP | IE_GUI_BUTTON_PICTURE, OP_OR)
GemRB.SetVar ("TopIndex", 0)
GUICommonWindows.SetSelectionChangeHandler (UpdateInventoryWindow)
@@ -181,9 +186,7 @@ def UpdateInventoryWindow ():
pc = GemRB.GameGetSelectedPCSingle ()
Container = GemRB.GetContainer (pc, 1)
ScrollBar = Window.GetControl (66)
- Count = Container['ItemCount']
- if Count<1:
- Count=1
+ Count = max (0, Container['ItemCount'] - 5)
ScrollBar.SetVarAssoc ("TopIndex", Count)
RefreshInventoryWindow ()
#populate inventory slot controls
@@ -204,53 +207,57 @@ def RefreshInventoryWindow ():
#portrait
Button = Window.GetControl (50)
- Color1 = GemRB.GetPlayerStat (pc, IE_METAL_COLOR)
- Color2 = GemRB.GetPlayerStat (pc, IE_MINOR_COLOR)
- Color3 = GemRB.GetPlayerStat (pc, IE_MAJOR_COLOR)
- Color4 = GemRB.GetPlayerStat (pc, IE_SKIN_COLOR)
- Color5 = GemRB.GetPlayerStat (pc, IE_LEATHER_COLOR)
- Color6 = GemRB.GetPlayerStat (pc, IE_ARMOR_COLOR)
- Color7 = GemRB.GetPlayerStat (pc, IE_HAIR_COLOR)
- Button.SetPLT (GUICommon.GetActorPaperDoll (pc),
- Color1, Color2, Color3, Color4, Color5, Color6, Color7, 0, 0)
anim_id = GemRB.GetPlayerStat (pc, IE_ANIMATION_ID)
row = "0x%04X" %anim_id
size = CommonTables.Pdolls.GetValue (row, "SIZE")
- #Weapon
- slot_item = GemRB.GetSlotItem (pc, GemRB.GetEquippedQuickSlot (pc) )
- if slot_item:
- item = GemRB.GetItem (slot_item["ItemResRef"])
- if (item['AnimationType'] != ''):
- Button.SetPLT("WP" + size + item['AnimationType'] + "INV", Color1, Color2, Color3, Color4, Color5, Color6, Color7, 0, 1)
-
- #Shield
- slot_item = GemRB.GetSlotItem (pc, 3)
- if slot_item:
- itemname = slot_item["ItemResRef"]
- item = GemRB.GetItem (itemname)
- if (item['AnimationType'] != ''):
- if (GemRB.CanUseItemType (SLOT_WEAPON, itemname)):
- #off-hand weapon
- Button.SetPLT("WP" + size + item['AnimationType'] + "OIN", Color1, Color2, Color3, Color4, Color5, Color6, Color7, 0, 2)
- else:
- #shield
- Button.SetPLT("WP" + size + item['AnimationType'] + "INV", Color1, Color2, Color3, Color4, Color5, Color6, Color7, 0, 2)
-
- #Helmet
- slot_item = GemRB.GetSlotItem (pc, 1)
- if slot_item:
- item = GemRB.GetItem (slot_item["ItemResRef"])
- if (item['AnimationType'] != ''):
- Button.SetPLT("WP" + size + item['AnimationType'] + "INV", Color1, Color2, Color3, Color4, Color5, Color6, Color7, 0, 3)
+ if size == "*":
+ Button.SetPLT (GUICommon.GetActorPaperDoll (pc),
+ -1, 0, 0, 0, 0, 0, 0, 0, 0)
+ else:
+ Color1 = GemRB.GetPlayerStat (pc, IE_METAL_COLOR)
+ Color2 = GemRB.GetPlayerStat (pc, IE_MINOR_COLOR)
+ Color3 = GemRB.GetPlayerStat (pc, IE_MAJOR_COLOR)
+ Color4 = GemRB.GetPlayerStat (pc, IE_SKIN_COLOR)
+ Color5 = GemRB.GetPlayerStat (pc, IE_LEATHER_COLOR)
+ Color6 = GemRB.GetPlayerStat (pc, IE_ARMOR_COLOR)
+ Color7 = GemRB.GetPlayerStat (pc, IE_HAIR_COLOR)
+ Button.SetPLT (GUICommon.GetActorPaperDoll (pc),
+ Color1, Color2, Color3, Color4, Color5, Color6, Color7, 0, 0)
+
+ #Weapon
+ slot_item = GemRB.GetSlotItem (pc, GemRB.GetEquippedQuickSlot (pc) )
+ if slot_item:
+ item = GemRB.GetItem (slot_item["ItemResRef"])
+ if (item['AnimationType'] != ''):
+ Button.SetPLT("WP" + size + item['AnimationType'] + "INV", Color1, Color2, Color3, Color4, Color5, Color6, Color7, 0, 1)
+
+ #Shield
+ slot_item = GemRB.GetSlotItem (pc, 3)
+ if slot_item:
+ itemname = slot_item["ItemResRef"]
+ item = GemRB.GetItem (itemname)
+ if (item['AnimationType'] != ''):
+ if (GemRB.CanUseItemType (SLOT_WEAPON, itemname)):
+ #off-hand weapon
+ Button.SetPLT("WP" + size + item['AnimationType'] + "OIN", Color1, Color2, Color3, Color4, Color5, Color6, Color7, 0, 2)
+ else:
+ #shield
+ Button.SetPLT("WP" + size + item['AnimationType'] + "INV", Color1, Color2, Color3, Color4, Color5, Color6, Color7, 0, 2)
+
+ #Helmet
+ slot_item = GemRB.GetSlotItem (pc, 1)
+ if slot_item:
+ item = GemRB.GetItem (slot_item["ItemResRef"])
+ if (item['AnimationType'] != ''):
+ Button.SetPLT("WP" + size + item['AnimationType'] + "INV", Color1, Color2, Color3, Color4, Color5, Color6, Color7, 0, 3)
#encumbrance
GUICommon.SetEncumbranceLabels ( Window, 0x10000043, 0x10000044, pc)
#armor class
ac = GemRB.GetPlayerStat (pc, IE_ARMORCLASS)
- ac += GemRB.GetAbilityBonus (IE_DEX, 2, GemRB.GetPlayerStat (pc, IE_DEX) )
Label = Window.GetControl (0x10000038)
Label.SetText (str (ac))
@@ -287,7 +294,7 @@ def RefreshInventoryWindow ():
for i in range (5):
Button = Window.GetControl (i+68)
if GemRB.IsDraggingItem ()==1:
- Button.SetState (IE_GUI_BUTTON_SECOND)
+ Button.SetState (IE_GUI_BUTTON_FAKEPRESSED)
else:
Button.SetState (IE_GUI_BUTTON_ENABLED)
Button.SetEvent (IE_GUI_BUTTON_ON_DRAG_DROP, InventoryCommon.OnDragItemGround)
@@ -305,11 +312,7 @@ def RefreshInventoryWindow ():
GUICommon.UpdateInventorySlot (pc, Button, Slot, "ground")
#making window visible/shaded depending on the pc's state
- held = GemRB.GetPlayerStat (pc, IE_HELD) + GemRB.GetPlayerStat (pc, IE_CASTERHOLD)
- if held == 0 and GemRB.GetPlayerStat (pc, IE_STATE_ID) & STATE_DEAD == 0:
- Window.SetVisible (WINDOW_VISIBLE)
- else:
- Window.SetVisible (WINDOW_GRAYED)
+ GUICommon.AdjustWindowVisibility (Window, pc, False)
return
###################################################
diff --git a/gemrb/GUIScripts/bg1/GUILOAD.py b/gemrb/GUIScripts/bg1/GUILOAD.py
deleted file mode 100644
index 316ec84..0000000
--- a/gemrb/GUIScripts/bg1/GUILOAD.py
+++ /dev/null
@@ -1,176 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-
-# GUILOAD.py - Load window
-
-###################################################
-
-import GemRB
-import LoadScreen
-from GUIDefines import *
-
-LoadWindow = 0
-TextAreaControl = 0
-Games = ()
-ScrollBar = 0
-
-def OnLoad ():
- global LoadWindow, TextAreaControl, Games, ScrollBar
-
- GemRB.LoadWindowPack ("GUILOAD", 640, 480)
- LoadWindow = GemRB.LoadWindow (0)
- LoadWindow.SetFrame ()
-
- CancelButton=LoadWindow.GetControl (34)
- CancelButton.SetText (13727)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CancelPress)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- GemRB.SetVar ("LoadIdx",0)
- for i in range (4):
- Button = LoadWindow.GetControl (26+i)
- Button.SetText (15590)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, LoadGamePress)
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- Button.SetVarAssoc ("LoadIdx",i)
-
- Button = LoadWindow.GetControl (30+i)
- Button.SetText (13957)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, DeleteGamePress)
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- Button.SetVarAssoc ("LoadIdx",i)
-
- #area previews
- Button = LoadWindow.GetControl (1+i)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE|IE_GUI_BUTTON_PICTURE,OP_SET)
-
- #PC portraits
- for j in range (PARTY_SIZE):
- Button = LoadWindow.GetControl (40 + i*PARTY_SIZE + j)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE|IE_GUI_BUTTON_PICTURE,OP_SET)
-
- ScrollBar=LoadWindow.GetControl (25)
- ScrollBar.SetEvent (IE_GUI_SCROLLBAR_ON_CHANGE, ScrollBarPress)
- Games=GemRB.GetSaveGames ()
- TopIndex = max (0, len(Games) - 4)
- GemRB.SetVar ("TopIndex",TopIndex)
- ScrollBar.SetVarAssoc ("TopIndex", TopIndex+1)
- ScrollBarPress ()
- LoadWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def ScrollBarPress ():
- #draw load game portraits
- Pos = GemRB.GetVar ("TopIndex")
- for i in range (4):
- ActPos = Pos + i
-
- Button1 = LoadWindow.GetControl (26+i)
- Button2 = LoadWindow.GetControl (30+i)
- if ActPos<len(Games):
- Button1.SetState (IE_GUI_BUTTON_ENABLED)
- Button2.SetState (IE_GUI_BUTTON_ENABLED)
- else:
- Button1.SetState (IE_GUI_BUTTON_DISABLED)
- Button2.SetState (IE_GUI_BUTTON_DISABLED)
-
- if ActPos<len(Games):
- Slotname = Games[ActPos].GetName()
- else:
- Slotname = ""
- Label = LoadWindow.GetControl (0x10000008+i)
- Label.SetText (Slotname)
-
- if ActPos<len(Games):
- Slotname = Games[ActPos].GetDate()
- else:
- Slotname = ""
- Label = LoadWindow.GetControl (0x10000010+i)
- Label.SetText (Slotname)
-
- Button=LoadWindow.GetControl (1+i)
- if ActPos<len(Games):
- Button.SetSprite2D(Games[ActPos].GetPreview())
- else:
- Button.SetPicture ("")
- for j in range (PARTY_SIZE):
- Button=LoadWindow.GetControl (40 + i*PARTY_SIZE + j)
- if ActPos<len(Games):
- Button.SetSprite2D(Games[ActPos].GetPortrait(j))
- else:
- Button.SetPicture ("")
- return
-
-def LoadGamePress ():
- if LoadWindow:
- LoadWindow.Unload ()
- Pos = GemRB.GetVar ("TopIndex")+GemRB.GetVar ("LoadIdx")
- LoadScreen.StartLoadScreen()
- GemRB.LoadGame (Games[Pos]) #loads and enters savegame
- GemRB.EnterGame ()
- return
-
-def DeleteGameConfirm():
- global Games
-
- TopIndex = GemRB.GetVar ("TopIndex")
- Pos = TopIndex +GemRB.GetVar ("LoadIdx")
- GemRB.DeleteSaveGame(Games[Pos])
- if TopIndex>0:
- GemRB.SetVar ("TopIndex",TopIndex-1)
- del Games[Pos]
- ScrollBar.SetVarAssoc ("TopIndex", len(Games))
- ScrollBarPress ()
- if ConfirmWindow:
- ConfirmWindow.Unload ()
- LoadWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def DeleteGameCancel ():
- if ConfirmWindow:
- ConfirmWindow.Unload ()
- LoadWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def DeleteGamePress ():
- global ConfirmWindow
-
- LoadWindow.SetVisible (WINDOW_INVISIBLE)
- ConfirmWindow=GemRB.LoadWindow (1)
- Text=ConfirmWindow.GetControl (0)
- Text.SetText (15305)
- DeleteButton=ConfirmWindow.GetControl (1)
- DeleteButton.SetText (13957)
- DeleteButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DeleteGameConfirm)
- CancelButton=ConfirmWindow.GetControl (2)
- CancelButton.SetText (13727)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DeleteGameCancel)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- ConfirmWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def CancelPress ():
- if LoadWindow:
- LoadWindow.Unload ()
- GemRB.SetNextScript ("Start")
- return
diff --git a/gemrb/GUIScripts/bg1/GUIMA.py b/gemrb/GUIScripts/bg1/GUIMA.py
index cd98f51..8294ce1 100644
--- a/gemrb/GUIScripts/bg1/GUIMA.py
+++ b/gemrb/GUIScripts/bg1/GUIMA.py
@@ -201,25 +201,30 @@ def MoveToNewArea ():
global WorldMapWindow, WorldMapControl
tmp = WorldMapControl.GetDestinationArea (1)
- if tmp["Distance"]==-1:
+ CloseWorldMapWindow ()
+
+ if tmp["Destination"].lower() == GemRB.GetGameString(STR_AREANAME).lower():
+ return
+ elif tmp["Distance"] == -1:
print "Invalid target", tmp
return
- CloseWorldMapWindow ()
GemRB.CreateMovement (tmp["Destination"], tmp["Entrance"], tmp["Direction"])
+ # distance is stored in hours, but the action needs seconds
+ GemRB.ExecuteString ("AdvanceTime(%d)"%(tmp["Distance"]*300))
return
def ChangeTooltip ():
global WorldMapWindow, WorldMapControl
- global str
- tmp = WorldMapControl.GetDestinationArea ()
- if (tmp):
- str = "%s: %d"%(GemRB.GetString(23084),tmp["Distance"])
- else:
- str=""
+ tt = ""
+ area = WorldMapControl.GetDestinationArea ()
+ if area and area["Distance"] >= 0:
+ str = GemRB.GetString(23084)
+ if (str):
+ tt = "%s: %d"%(str,area["Distance"])
- WorldMapControl.SetTooltip (str)
+ WorldMapControl.SetTooltip (tt)
return
def CloseWorldMapWindow ():
@@ -280,6 +285,7 @@ def WorldMapWindowCommon (Travel):
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseWorldMapWindow)
Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
Window.SetVisible (WINDOW_VISIBLE)
+ WorldMapControl.SetStatus (IE_GUI_CONTROL_FOCUSED)
return
def MapN():
diff --git a/gemrb/GUIScripts/bg1/GUIMG.py b/gemrb/GUIScripts/bg1/GUIMG.py
index ca0ab10..076b226 100644
--- a/gemrb/GUIScripts/bg1/GUIMG.py
+++ b/gemrb/GUIScripts/bg1/GUIMG.py
@@ -89,9 +89,6 @@ def OpenMageWindow ():
## Button = Window.GetControl (56 + i)
## Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, RefreshMageLevel)
## Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
-
-## for i in range (9):
-## Button = Window.GetControl (56 + i)
## Button.SetVarAssoc ("MageSpellLevel", i)
# Setup memorized spells buttons
@@ -99,13 +96,13 @@ def OpenMageWindow ():
Button = Window.GetControl (3 + i)
Button.SetBorder (0,0,0,0,0,0,0,0,64,0,1)
Button.SetSprites ("SPELFRAM",0,0,0,0,0)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_OR)
+ Button.SetFlags (IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_PLAYONCE, OP_OR)
Button.SetState (IE_GUI_BUTTON_LOCKED)
# Setup book spells buttons
for i in range (20):
Button = Window.GetControl (27 + i)
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_OR)
+ Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE | IE_GUI_BUTTON_PLAYONCE, OP_OR)
Button.SetState (IE_GUI_BUTTON_LOCKED)
GUICommonWindows.SetSelectionChangeHandler (UpdateMageWindow)
@@ -137,14 +134,14 @@ def UpdateMageWindow ():
Label = Window.GetControl (0x10000035)
Label.SetText (Name)
- mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level)
+ mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level, False)
for i in range (12):
Button = Window.GetControl (3 + i)
if i < mem_cnt:
ms = GemRB.GetMemorizedSpell (pc, type, level, i)
Button.SetSpellIcon (ms['SpellResRef'], 0)
Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_NAND)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_OR)
+ Button.SetFlags (IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_PLAYONCE, OP_OR)
if ms['Flags']:
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenMageSpellUnmemorizeWindow)
else:
@@ -157,7 +154,7 @@ def UpdateMageWindow ():
Button.EnableBorder (0, ms['Flags'] == 0)
else:
if i < max_mem_cnt:
- Button.SetFlags (IE_GUI_BUTTON_NORMAL, OP_SET)
+ Button.SetFlags (IE_GUI_BUTTON_NORMAL | IE_GUI_BUTTON_PLAYONCE, OP_SET)
else:
Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, None)
@@ -186,11 +183,8 @@ def UpdateMageWindow ():
Button.SetTooltip ('')
Button.EnableBorder (0, 0)
- if (CommonTables.ClassSkills.GetValue (GemRB.GetPlayerStat (pc, IE_CLASS), 2)=="*") or \
- GemRB.GetPlayerStat (pc, IE_STATE_ID) & STATE_DEAD:
- Window.SetVisible (WINDOW_GRAYED)
- else:
- Window.SetVisible (WINDOW_VISIBLE)
+ CantCast = CommonTables.ClassSkills.GetValue (GUICommon.GetClassRowName(pc), "MAGESPELL") == "*"
+ GUICommon.AdjustWindowVisibility (Window, pc, CantCast)
return
def MagePrevLevelPress ():
@@ -263,6 +257,12 @@ def OnMageMemorizeSpell ():
if GemRB.MemorizeSpell (pc, type, level, index):
UpdateMageWindow ()
+ GemRB.PlaySound ("GAM_24")
+ Button = MageWindow.GetControl(index + 27)
+ Button.SetAnimation ("FLASH",0,1)
+ mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level, False)
+ Button = MageWindow.GetControl(mem_cnt + 2)
+ Button.SetAnimation ("FLASH",0,1)
return
def CloseMageSpellUnmemorizeWindow ():
@@ -333,6 +333,9 @@ def OnMageUnmemorizeSpell ():
if GemRB.UnmemorizeSpell (pc, type, level, index):
UpdateMageWindow ()
+ GemRB.PlaySound ("GAM_44")
+ Button = MageWindow.GetControl(index + 3)
+ Button.SetAnimation ("FLASH",0,1)
return
#def OnMageRemoveSpell ():
diff --git a/gemrb/GUIScripts/bg1/GUIOPT.py b/gemrb/GUIScripts/bg1/GUIOPT.py
deleted file mode 100644
index 59b7057..0000000
--- a/gemrb/GUIScripts/bg1/GUIOPT.py
+++ /dev/null
@@ -1,733 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-# GUIOPT.py - scripts to control options windows mostly from the GUIOPT winpack:
-# 0 - Main options window (peacock tail)
-# 1 - Video options window
-# 2 - msg win with 1 button
-# 3 - msg win with 2 buttons
-# 4 - msg win with 3 buttons
-# 5 - Audio options window
-# 6 - Gameplay options window
-# 8 - Feedback options window
-# 9 - Autopause options window
-
-###################################################
-import GemRB
-import GUICommon
-import GUICommonWindows
-import GUISAVE
-from GUIDefines import *
-
-###################################################
-OptionsWindow = None
-SubOptionsWindow = None
-SubSubOptionsWindow = None
-GameOptionsWindow = None
-OldOptionsWindow = None
-MoviesWindow = None
-KeysWindow = None
-HelpTextArea = None
-
-LoadMsgWindow = None
-QuitMsgWindow = None
-hideflag = None
-
-###################################################
-def CloseOptionsWindow ():
- global GameOptionsWindow, OptionsWindow
- global OldOptionsWindow
-
- if GameOptionsWindow == None:
- return
-
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- if OptionsWindow:
- OptionsWindow.Unload ()
-
- GameOptionsWindow = None
- GUICommonWindows.SetSelectionChangeHandler (None)
- GemRB.SetVar ("OtherWindow", -1)
- GUICommon.GameWindow.SetVisible(WINDOW_VISIBLE)
- GUICommonWindows.OptionsWindow = OldOptionsWindow
- OldOptionsWindow = None
- return
-
-###################################################
-def OpenOptionsWindow ():
- """Open main options window"""
- global GameOptionsWindow, OptionsWindow
- global OldOptionsWindow
-
- if GUICommon.CloseOtherWindow (OpenOptionsWindow):
- CloseOptionsWindow()
- return
-
- #hideflag = GemRB.HideGUI ()
- GUICommon.GameWindow.SetVisible(WINDOW_INVISIBLE)
- GUICommonWindows.SetSelectionChangeHandler (None)
-
- GemRB.LoadWindowPack ("GUIOPT", 640, 480)
- GameOptionsWindow = Window = GemRB.LoadWindow (2)
- GemRB.SetVar ("OtherWindow", GameOptionsWindow.ID)
- if OldOptionsWindow == None:
- OldOptionsWindow = GUICommonWindows.OptionsWindow
- OptionsWindow = GemRB.LoadWindow (0)
- GUICommonWindows.SetupMenuWindowControls (OptionsWindow, 0, OpenOptionsWindow)
- OptionsWindow.SetFrame ()
-
- # Return to Game
- Button = Window.GetControl (11)
- Button.SetText (10308)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenOptionsWindow)
-
- # Quit Game
- Button = Window.GetControl (10)
- Button.SetText (13731)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenQuitMsgWindow)
-
- # Load Game
- Button = Window.GetControl (5)
- Button.SetText (13729)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenLoadMsgWindow)
-
- # Save Game
- Button = Window.GetControl (6)
- Button.SetText (13730)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenSaveMsgWindow)
-
- # Video Options
- Button = Window.GetControl (7)
- Button.SetText (17162)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenVideoOptionsWindow)
-
- # Audio Options
- Button = Window.GetControl (8)
- Button.SetText (17164)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenAudioOptionsWindow)
-
- # Gameplay Options
- Button = Window.GetControl (9)
- Button.SetText (17165)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenGameplayOptionsWindow)
-
- # game version, e.g. v1.1.0000
- Label = Window.GetControl (0x1000000b)
- Label.SetText (GEMRB_VERSION)
-
- OptionsWindow.SetVisible (WINDOW_VISIBLE)
- Window.SetVisible (WINDOW_VISIBLE)
- GUICommonWindows.PortraitWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-###################################################
-
-def CloseVideoOptionsWindow ():
- global SubOptionsWindow
-
- if SubOptionsWindow:
- SubOptionsWindow.Unload()
- SubOptionsWindow = None
- return
-
-def OpenVideoOptionsWindow ():
- """Open video options window"""
- global SubOptionsWindow, HelpTextArea
-
- if SubOptionsWindow:
- if SubOptionsWindow:
- SubOptionsWindow.Unload()
- SubOptionsWindow = None
-
- SubOptionsWindow = Window = GemRB.LoadWindow (6)
-
- HelpTextArea = OptHelpText ('VideoOptions', Window, 33, 18038)
-
- OptDone ('VideoOptions', Window, 21)
- OptCancel ('VideoOptions', Window, 32)
-
- OptSlider ('Brightness', Window, 3, 'Brightness Correction', 4)
- OptSlider ('Contrast', Window, 22, 'Gamma Correction', 1)
-
- OptRadio ('BPP', Window, 5, 37, 'BitsPerPixel', 16)
- OptRadio ('BPP', Window, 6, 37, 'BitsPerPixel', 24)
- OptRadio ('BPP', Window, 7, 37, 'BitsPerPixel', 32)
-
- OptCheckbox ('FullScreen', Window, 9, 38, 'Full Screen', 1)
-
- OptCheckbox ('TransShadow', Window, 51, 50, 'Translucent Shadows', 1)
- OptCheckbox ('SoftMirrBlt', Window, 40, 44, 'SoftMirrorBlt' ,1)
- OptCheckbox ('SoftTransBlt', Window, 41, 46, 'SoftSrcKeyBlt' ,1)
- OptCheckbox ('SoftStandBlt', Window, 42, 48, 'SoftBltFast' ,1)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DisplayHelpFullScreen ():
- HelpTextArea.SetText (18000)
- GemRB.SetFullScreen (GemRB.GetVar("Full Screen"))
-
-def DisplayHelpBPP ():
- HelpTextArea.SetText (17205)
-
-def DisplayHelpBrightness ():
- HelpTextArea.SetText (17203)
- GemRB.SetGamma (GemRB.GetVar("Brightness Correction"),GemRB.GetVar("Gamma Correction")/2)
-
-def DisplayHelpContrast ():
- HelpTextArea.SetText (17204)
- GemRB.SetGamma (GemRB.GetVar("Brightness Correction"),GemRB.GetVar("Gamma Correction")/2)
-
-def DisplayHelpSoftMirrBlt ():
- HelpTextArea.SetText (18004)
-
-def DisplayHelpSoftTransBlt ():
- HelpTextArea.SetText (18006)
-
-def DisplayHelpSoftStandBlt ():
- HelpTextArea.SetText (18007)
-
-def DisplayHelpTransShadow ():
- HelpTextArea.SetText (20620)
-
-
-###################################################
-
-def CloseAudioOptionsWindow ():
- global SubOptionsWindow
-
- if SubOptionsWindow:
- SubOptionsWindow.Unload()
- SubOptionsWindow = None
- return
-
-def OpenAudioOptionsWindow ():
- """Open audio options window"""
- global SubOptionsWindow, HelpTextArea
-
- if SubOptionsWindow:
- if SubOptionsWindow:
- SubOptionsWindow.Unload ()
- SubOptionsWindow = None
-
- SubOptionsWindow = Window = GemRB.LoadWindow (7)
-
- HelpTextArea = OptHelpText ('AudioOptions', Window, 14, 18040)
-
- OptDone ('AudioOptions', Window, 24)
- OptCancel ('AudioOptions', Window, 25)
- OptButton ('CharacterSounds', Window, 13, 17778)
-
- OptSlider ('AmbientVolume', Window, 1, 'Volume Ambients', 10)
- OptSlider ('SoundFXVolume', Window, 2, 'Volume SFX', 10)
- OptSlider ('VoiceVolume', Window, 3, 'Volume Voices', 10)
- OptSlider ('MusicVolume', Window, 4, 'Volume Music', 10)
- OptSlider ('MovieVolume', Window, 22, 'Volume Movie', 10)
-
- OptCheckbox ('CreativeEAX', Window, 26, 28, 'Environmental Audio', 1)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DisplayHelpAmbientVolume ():
- HelpTextArea.SetText (18008)
- GemRB.UpdateAmbientsVolume ()
-
-def DisplayHelpSoundFXVolume ():
- HelpTextArea.SetText (18009)
-
-def DisplayHelpVoiceVolume ():
- HelpTextArea.SetText (18010)
-
-def DisplayHelpMusicVolume ():
- HelpTextArea.SetText (18011)
- GemRB.UpdateMusicVolume ()
-
-def DisplayHelpMovieVolume ():
- HelpTextArea.SetText (18012)
-
-def DisplayHelpCreativeEAX ():
- HelpTextArea.SetText (18022)
-
-###################################################
-
-def CloseCharacterSoundsWindow ():
- global SubSubOptionsWindow
-
- if SubSubOptionsWindow:
- SubSubOptionsWindow.Unload ()
- SubSubOptionsWindow = None
- return
-
-def OpenCharacterSoundsWindow ():
- """Open character sounds window"""
- global SubSubOptionsWindow, HelpTextArea
-
- if SubSubOptionsWindow:
- if SubSubOptionsWindow:
- SubSubOptionsWindow.Unload ()
- SubSubOptionsWindow = None
-
- SubSubOptionsWindow = Window = GemRB.LoadWindow (12)
-
- HelpTextArea = OptHelpText ('CharacterSounds', Window, 16, 18041)
-
- OptDone ('CharacterSounds', Window, 24)
- OptCancel ('CharacterSounds', Window, 25)
-
- OptCheckbox ('Subtitles', Window, 5, 20, 'Subtitles', 1)
- OptCheckbox ('AttackSounds', Window, 6, 18, 'Attack Sounds', 1)
- OptCheckbox ('Footsteps', Window, 7, 19, 'Footsteps', 1)
- OptRadio ('CommandSounds', Window, 8, 21, 'Command Sounds Frequency', 1)
- OptRadio ('CommandSounds', Window, 9, 21, 'Command Sounds Frequency', 2)
- OptRadio ('CommandSounds', Window, 10, 21, 'Command Sounds Frequency', 3)
- OptRadio ('SelectionSounds', Window, 58, 57, 'Selection Sounds Frequency', 1)
- OptRadio ('SelectionSounds', Window, 59, 57, 'Selection Sounds Frequency', 2)
- OptRadio ('SelectionSounds', Window, 60, 57, 'Selection Sounds Frequency', 3)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
-
-def DisplayHelpSubtitles ():
- HelpTextArea.SetText (18015)
-
-def DisplayHelpAttackSounds ():
- HelpTextArea.SetText (18013)
-
-def DisplayHelpFootsteps ():
- HelpTextArea.SetText (18014)
-
-def DisplayHelpCommandSounds ():
- HelpTextArea.SetText (18016)
-
-def DisplayHelpSelectionSounds ():
- HelpTextArea.SetText (11352)
-
-###################################################
-
-def CloseGameplayOptionsWindow ():
- global SubOptionsWindow
-
- if SubOptionsWindow:
- SubOptionsWindow.Unload()
- SubOptionsWindow = None
- return
-
-def OpenGameplayOptionsWindow ():
- """Open gameplay options window"""
- global SubOptionsWindow, HelpTextArea
-
- if SubOptionsWindow:
- if SubOptionsWindow:
- SubOptionsWindow.Unload ()
- SubOptionsWindow = None
-
- SubOptionsWindow = Window = GemRB.LoadWindow (8)
-
- HelpTextArea = OptHelpText ('GameplayOptions', Window, 40, 18042)
-
- OptDone ('GameplayOptions', Window, 7)
- OptCancel ('GameplayOptions', Window, 20)
-
- OptSlider ('TooltipDelay', Window, 1, 'Tooltips', TOOLTIP_DELAY_FACTOR)
- OptSlider ('MouseScrollingSpeed', Window, 2, 'Mouse Scroll Speed', 5)
- OptSlider ('KeyboardScrollingSpeed', Window, 3, 'Keyboard Scroll Speed', 5)
- OptSlider ('Difficulty', Window, 12, 'Difficulty Level', 0)
-
- OptCheckbox ('DitherAlways', Window, 14, 25, 'Always Dither', 1)
- OptCheckbox ('Gore', Window, 19, 27, 'Gore', 1)
- OptCheckbox ('Infravision', Window, 42, 44, 'Infravision', 1)
- OptCheckbox ('Weather', Window, 47, 46, 'Weather', 1)
- if GUICommon.GameIsBG2():
- OptCheckbox ('RestUntilHealed', Window, 50, 48, 'Heal Party on Rest', 1)
-
- OptButton ('FeedbackOptions', Window, 5, 17163)
- OptButton ('AutopauseOptions', Window, 6, 17166)
- if GUICommon.GameIsBG2():
- OptButton ('HotkeyOptions', Window, 51, 816)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DisplayHelpTooltipDelay ():
- HelpTextArea.SetText (18017)
- GemRB.SetTooltipDelay (GemRB.GetVar ("Tooltips") )
-
-def DisplayHelpMouseScrollingSpeed ():
- HelpTextArea.SetText (18018)
- GemRB.SetMouseScrollSpeed (GemRB.GetVar ("Mouse Scroll Speed") )
-
-def DisplayHelpKeyboardScrollingSpeed ():
- HelpTextArea.SetText (18019)
-
-def DisplayHelpDifficulty ():
- HelpTextArea.SetText (18020)
-
-def DisplayHelpDitherAlways ():
- HelpTextArea.SetText (18021)
-
-def DisplayHelpGore ():
- HelpTextArea.SetText (18023)
-
-def DisplayHelpInfravision ():
- HelpTextArea.SetText (11797)
-
-def DisplayHelpWeather ():
- HelpTextArea.SetText (20619)
-
-def DisplayHelpRestUntilHealed ():
- HelpTextArea.SetText (2242)
-
-###################################################
-
-def CloseFeedbackOptionsWindow ():
- global SubSubOptionsWindow
-
- if SubSubOptionsWindow:
- SubSubOptionsWindow.Unload ()
- SubSubOptionsWindow = None
- return
-
-def OpenFeedbackOptionsWindow ():
- """Open feedback options window"""
- global SubSubOptionsWindow, HelpTextArea
-
- if SubSubOptionsWindow:
- if SubSubOptionsWindow:
- SubSubOptionsWindow.Unload ()
- SubSubOptionsWindow = None
-
- SubSubOptionsWindow = Window = GemRB.LoadWindow (9)
-
- HelpTextArea = OptHelpText ('FeedbackOptions', Window, 28, 18043)
-
- OptDone ('FeedbackOptions', Window, 26)
- OptCancel ('FeedbackOptions', Window, 27)
-
- OptSlider ('MarkerFeedback', Window, 8, 'GUI Feedback Level', 1)
- OptSlider ('LocatorFeedback', Window, 9, 'Locator Feedback Level', 1)
-
- OptCheckbox ('ToHitRolls', Window, 10, 32, 'Rolls', 1)
- OptCheckbox ('CombatInfo', Window, 11, 33, 'Combat Info', 1)
- OptCheckbox ('Actions', Window, 12, 34, 'Actions', 1)
- OptCheckbox ('States', Window, 13, 35, 'State Changes', 1)
- OptCheckbox ('Selection', Window, 14, 36, 'Selection Text', 1)
- OptCheckbox ('Miscellaneous', Window, 15, 37, 'Miscellaneous Text', 1)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DisplayHelpMarkerFeedback ():
- HelpTextArea.SetText (18024)
-
-def DisplayHelpLocatorFeedback ():
- HelpTextArea.SetText (18025)
-
-def DisplayHelpToHitRolls ():
- HelpTextArea.SetText (18026)
-
-def DisplayHelpCombatInfo ():
- HelpTextArea.SetText (18027)
-
-def DisplayHelpActions ():
- HelpTextArea.SetText (18028)
-
-def DisplayHelpStates ():
- HelpTextArea.SetText (18029)
-
-def DisplayHelpSelection ():
- HelpTextArea.SetText (18030)
-
-def DisplayHelpMiscellaneous ():
- HelpTextArea.SetText (18031)
-
-###################################################
-
-def CloseAutopauseOptionsWindow ():
- global SubSubOptionsWindow
-
- if SubSubOptionsWindow:
- SubSubOptionsWindow.Unload ()
- SubSubOptionsWindow = None
- return
-
-def OpenAutopauseOptionsWindow ():
- """Open autopause options window"""
- global SubSubOptionsWindow, HelpTextArea
-
- if SubSubOptionsWindow:
- if SubSubOptionsWindow:
- SubSubOptionsWindow.Unload ()
- SubSubOptionsWindow = None
-
- SubSubOptionsWindow = Window = GemRB.LoadWindow (10)
-
- HelpTextArea = OptHelpText ('AutopauseOptions', Window, 15, 18044)
-
- OptDone ('AutopauseOptions', Window, 11)
- OptCancel ('AutopauseOptions', Window, 14)
-
- OptCheckbox ('CharacterHit', Window, 1, 17, 'Auto Pause State', 1)
- OptCheckbox ('CharacterInjured', Window, 2, 18, 'Auto Pause State', 2)
- OptCheckbox ('CharacterDead', Window, 3, 19, 'Auto Pause State', 4)
- OptCheckbox ('CharacterAttacked', Window, 4, 20, 'Auto Pause State', 8)
- OptCheckbox ('WeaponUnusable', Window, 5, 21, 'Auto Pause State', 16)
- OptCheckbox ('TargetGone', Window, 13, 22, 'Auto Pause State', 32)
- OptCheckbox ('EndOfRound', Window, 25, 24, 'Auto Pause State', 64)
- if Window.HasControl(26, IE_GUI_BUTTON):
- OptCheckbox ('EnemySighted', Window, 26, 27, 'Auto Pause State', 128)
- if GUICommon.GameIsBG2():
- OptCheckbox ('SpellCast', Window, 34, 30, 'Auto Pause State', 256)
- OptCheckbox ('TrapFound', Window, 31, 33, 'Auto Pause State', 512)
- OptCheckbox ('CenterOnActor', Window, 31, 33, 'Auto Pause Center', 1)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DisplayHelpCharacterHit ():
- HelpTextArea.SetText (18032)
-
-def DisplayHelpCharacterInjured ():
- HelpTextArea.SetText (18033)
-
-def DisplayHelpCharacterDead ():
- HelpTextArea.SetText (18034)
-
-def DisplayHelpCharacterAttacked ():
- HelpTextArea.SetText (18035)
-
-def DisplayHelpWeaponUnusable ():
- HelpTextArea.SetText (18036)
-
-def DisplayHelpTargetGone ():
- HelpTextArea.SetText (18037)
-
-def DisplayHelpEndOfRound ():
- HelpTextArea.SetText (10640)
-
-def DisplayHelpEnemySighted ():
- HelpTextArea.SetText (23514)
-
-def DisplayHelpSpellCast ():
- HelpTextArea.SetText (58171)
-
-def DisplayHelpTrapFound ():
- HelpTextArea.SetText (31872)
-
-def DisplayHelpCenterOnActor ():
- HelpTextArea.SetText (10571)
-
-###################################################
-
-def OpenSaveMsgWindow ():
- GemRB.SetVar("QuitAfterSave",0)
- GUISAVE.OpenSaveWindow ()
- #save the game without quitting
- return
-
-###################################################
-
-def OpenLoadMsgWindow ():
- global LoadMsgWindow
-
- if LoadMsgWindow:
- return
-
- LoadMsgWindow = Window = GemRB.LoadWindow (4)
-
- # Load
- Button = Window.GetControl (0)
- Button.SetText (15590)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, LoadGamePress)
-
- # Cancel
- Button = Window.GetControl (1)
- Button.SetText (13727)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseLoadMsgWindow)
-
- # Loading a game will destroy ...
- Text = Window.GetControl (3)
- Text.SetText (19531)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def CloseLoadMsgWindow ():
- global LoadMsgWindow
-
- if LoadMsgWindow:
- LoadMsgWindow.Unload ()
- LoadMsgWindow = None
- #OptionsWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def LoadGamePress ():
- global LoadMsgWindow
-
- if LoadMsgWindow:
- LoadMsgWindow.Unload ()
- LoadMsgWindow = None
- GemRB.QuitGame ()
- OpenOptionsWindow()
- GemRB.SetNextScript ("GUILOAD")
- return
-
-#save game AND quit
-def SaveGamePress ():
- global QuitMsgWindow
-
- if QuitMsgWindow:
- QuitMsgWindow.Unload ()
- QuitMsgWindow = None
- #we need to set a state: quit after save
- GemRB.SetVar("QuitAfterSave",1)
- OpenOptionsWindow()
- GUISAVE.OpenSaveWindow ()
- return
-
-def QuitGamePress ():
- global QuitMsgWindow
-
- if QuitMsgWindow:
- QuitMsgWindow.Unload ()
- QuitMsgWindow = None
- GemRB.QuitGame ()
- OpenOptionsWindow()
- GemRB.SetNextScript ("Start")
- return
-
-###################################################
-
-def OpenQuitMsgWindow ():
- global QuitMsgWindow
-
- if QuitMsgWindow:
- return
-
- QuitMsgWindow = Window = GemRB.LoadWindow (5)
-
- # Save
- Button = Window.GetControl (0)
- Button.SetText (15589)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SaveGamePress)
-
- # Quit Game
- Button = Window.GetControl (1)
- Button.SetText (15417)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, QuitGamePress)
-
- # Cancel
- Button = Window.GetControl (2)
- Button.SetText (13727)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseQuitMsgWindow)
-
- # Do you wish to save the game ....
- Text = Window.GetControl (3)
- Text.SetText (16456)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def CloseQuitMsgWindow ():
- global QuitMsgWindow
-
- if QuitMsgWindow:
- QuitMsgWindow.Unload ()
- QuitMsgWindow = None
- OptionsWindow.SetVisible (WINDOW_VISIBLE)
-###################################################
-#TODO
-def OpenHotkeyOptionsWindow ():
- return
-
-def CloseHotkeyOptionsWindow ():
- return
-
-###################################################
-# These functions help to setup controls found
-# in Video, Audio, Gameplay, Feedback and Autopause
-# options windows
-
-# These controls are usually made from an active
-# control (button, slider ...) and a label
-
-
-def OptSlider (name, window, slider_id, variable, value):
- """Standard slider for option windows"""
- slider = window.GetControl (slider_id)
- slider.SetVarAssoc (variable, value)
- slider.SetEvent (IE_GUI_SLIDER_ON_CHANGE, eval("DisplayHelp" + name))
- return slider
-
-def OptRadio (name, window, button_id, label_id, variable, value):
- """Standard radio button for option windows"""
-
- button = window.GetControl (button_id)
- button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- button.SetEvent (IE_GUI_BUTTON_ON_PRESS, eval("DisplayHelp" + name))
- button.SetVarAssoc (variable, value)
-
- label = window.GetControl (label_id)
- label.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- label.SetState (IE_GUI_BUTTON_LOCKED)
-
- return button
-
-def OptCheckbox (name, window, button_id, label_id, variable, value):
- """Standard checkbox for option windows"""
-
- button = window.GetControl (button_id)
- button.SetFlags (IE_GUI_BUTTON_CHECKBOX, OP_OR)
- button.SetEvent (IE_GUI_BUTTON_ON_PRESS, eval("DisplayHelp" + name))
- button.SetVarAssoc (variable, value)
-
- label = window.GetControl (label_id)
- label.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- label.SetState (IE_GUI_BUTTON_LOCKED)
-
- return button
-
-def OptButton (name, window, button_id, button_strref):
- """Standard subwindow button for option windows"""
- button = window.GetControl (button_id)
- button.SetEvent (IE_GUI_BUTTON_ON_PRESS, eval("Open%sWindow" %name))
- button.SetText (button_strref)
-
-def OptDone (name, window, button_id):
- """Standard `Done' button for option windows"""
- button = window.GetControl (button_id)
- button.SetText (11973) # Done
- button.SetEvent (IE_GUI_BUTTON_ON_PRESS, eval("Close%sWindow" %name))
- button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
-def OptCancel (name, window, button_id):
- """Standard `Cancel' button for option windows"""
- button = window.GetControl (button_id)
- button.SetText (13727) # Cancel
- button.SetEvent (IE_GUI_BUTTON_ON_PRESS, eval("Close%sWindow" %name))
- button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
-def OptHelpText (name, window, text_id, text_strref):
- """Standard textarea with context help for option windows"""
- text = window.GetControl (text_id)
- text.SetText (text_strref)
- return text
-
-###################################################
-# End of file GUIOPT.py
diff --git a/gemrb/GUIScripts/bg1/GUIPR.py b/gemrb/GUIScripts/bg1/GUIPR.py
deleted file mode 100644
index c247b9f..0000000
--- a/gemrb/GUIScripts/bg1/GUIPR.py
+++ /dev/null
@@ -1,359 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-
-# GUIPR.py - scripts to control priest spells windows from GUIPR winpack
-
-###################################################
-
-import GemRB
-import GUICommon
-import CommonTables
-import GUICommonWindows
-from GUIDefines import *
-from ie_stats import *
-from ie_action import ACT_CAST
-
-PriestWindow = None
-PriestSpellInfoWindow = None
-PriestSpellLevel = 0
-PriestSpellUnmemorizeWindow = None
-OldOptionsWindow = None
-PortraitWindow = None
-OldPortraitWindow = None
-
-
-def OpenPriestWindow ():
- global PriestWindow, OptionsWindow
- global OldOptionsWindow, PortraitWindow, OldPortraitWindow
-
-
- if GUICommon.CloseOtherWindow (OpenPriestWindow):
- if PriestWindow:
- PriestWindow.Unload ()
- if OptionsWindow:
- OptionsWindow.Unload ()
- if PortraitWindow:
- PortraitWindow.Unload ()
- PriestWindow = None
- GemRB.SetVar ("OtherWindow", -1)
- GUICommon.GameWindow.SetVisible(WINDOW_VISIBLE)
- GemRB.UnhideGUI ()
- OptionsWindow = OldOptionsWindow
- OldOptionsWindow = None
- GUICommonWindows.PortraitWindow = OldPortraitWindow
- OldPortraitWindow = None
- GUICommonWindows.SetSelectionChangeHandler(None)
- return
-
- GemRB.HideGUI ()
- GUICommon.GameWindow.SetVisible(WINDOW_INVISIBLE)
-
- GemRB.LoadWindowPack ("GUIPR", 640, 480)
- PriestWindow = Window = GemRB.LoadWindow (2)
- GemRB.SetVar ("OtherWindow", PriestWindow.ID)
- OldOptionsWindow = GUICommonWindows.OptionsWindow
- OptionsWindow = GemRB.LoadWindow (0)
- GUICommonWindows.SetupMenuWindowControls (OptionsWindow, 0, OpenPriestWindow)
- OldPortraitWindow = GUICommonWindows.PortraitWindow
- PortraitWindow = GUICommonWindows.OpenPortraitWindow (0)
- OptionsWindow.SetFrame ()
-
- Button = Window.GetControl (1)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, PriestPrevLevelPress)
-
- Button = Window.GetControl (2)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, PriestNextLevelPress)
-
-## #setup level buttons
-## for i in range (7):
-## Button = Window.GetControl (55 + i)
-## Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, RefreshPriestLevel)
-## Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
-
-## for i in range (7):
-## Button = Window.GetControl (55 + i)
-## Button.SetVarAssoc ("PriestSpellLevel", i)
-
- # Setup memorized spells buttons
- for i in range (12):
- Button = Window.GetControl (3 + i)
- Button.SetBorder (0,0,0,0,0,0,0,0,64,0,1)
- Button.SetSprites ("SPELFRAM",0,0,0,0,0)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_OR)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
-
- # Setup book spells buttons
- for i in range (20):
- Button = Window.GetControl (27 + i)
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_OR)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
-
- GUICommonWindows.SetSelectionChangeHandler (UpdatePriestWindow)
- UpdatePriestWindow ()
-
- OptionsWindow.SetVisible (WINDOW_VISIBLE)
- Window.SetVisible (WINDOW_FRONT)
- PortraitWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-
-def UpdatePriestWindow ():
- global PriestMemorizedSpellList, PriestKnownSpellList
-
- PriestMemorizedSpellList = []
- PriestKnownSpellList = []
-
- Window = PriestWindow
- pc = GemRB.GameGetSelectedPCSingle ()
- Type = IE_SPELL_TYPE_PRIEST
- level = PriestSpellLevel
- max_mem_cnt = GemRB.GetMemorizableSpellsCount (pc, Type, level)
-
- Label = Window.GetControl (0x10000032)
- GemRB.SetToken ('LEVEL', str (level + 1))
- Label.SetText (12137)
-
- Name = GemRB.GetPlayerName (pc, 0)
- Label = Window.GetControl (0x10000035)
- Label.SetText (Name)
-
- mem_cnt = GemRB.GetMemorizedSpellsCount (pc, Type, level)
- for i in range (12):
- Button = Window.GetControl (3 + i)
- if i < mem_cnt:
- ms = GemRB.GetMemorizedSpell (pc, Type, level, i)
- Button.SetSpellIcon (ms['SpellResRef'])
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_NAND)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_OR)
- if ms['Flags']:
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenPriestSpellUnmemorizeWindow)
- else:
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OnPriestUnmemorizeSpell)
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, OpenPriestSpellInfoWindow)
- spell = GemRB.GetSpell (ms['SpellResRef'])
- Button.SetTooltip (spell['SpellName'])
- PriestMemorizedSpellList.append (ms['SpellResRef'])
- Button.SetVarAssoc ("SpellButton", i)
- Button.EnableBorder (0, ms['Flags'] == 0)
- else:
- if i < max_mem_cnt:
- Button.SetFlags (IE_GUI_BUTTON_NORMAL, OP_SET)
- else:
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, None)
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, None)
- Button.SetTooltip ('')
- Button.EnableBorder (0, 0)
-
-
- known_cnt = GemRB.GetKnownSpellsCount (pc, Type, level)
- for i in range (20):
- Button = Window.GetControl (27 + i)
- if i < known_cnt:
- ks = GemRB.GetKnownSpell (pc, Type, level, i)
- Button.SetSpellIcon (ks['SpellResRef'])
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_NAND)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OnPriestMemorizeSpell)
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, OpenPriestSpellInfoWindow)
- spell = GemRB.GetSpell (ks['SpellResRef'])
- Button.SetTooltip (spell['SpellName'])
- PriestKnownSpellList.append (ks['SpellResRef'])
- Button.SetVarAssoc ("SpellButton", 100 + i)
-
- else:
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_OR)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_NAND)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, None)
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, None)
- Button.SetTooltip ('')
- Button.EnableBorder (0, 0)
-
- Class = GemRB.GetPlayerStat (pc, IE_CLASS)
- DivineCaster = CommonTables.ClassSkills.GetValue (Class, 1)
- if DivineCaster == "*":
- # also check the DRUIDSPELL column
- DivineCaster = CommonTables.ClassSkills.GetValue (Class, 0)
- CantCast = DivineCaster == "*" or GemRB.GetPlayerStat(pc, IE_DISABLEDBUTTON)&(1<<ACT_CAST)
- if CantCast or GemRB.GetPlayerStat (pc, IE_STATE_ID) & STATE_DEAD:
- Window.SetVisible (WINDOW_GRAYED)
- else:
- Window.SetVisible (WINDOW_VISIBLE)
- return
-
-def PriestPrevLevelPress ():
- global PriestSpellLevel
-
- if PriestSpellLevel > 0:
- PriestSpellLevel = PriestSpellLevel - 1
- UpdatePriestWindow ()
- return
-
-def PriestNextLevelPress ():
- global PriestSpellLevel
-
- if PriestSpellLevel < 6:
- PriestSpellLevel = PriestSpellLevel + 1
- UpdatePriestWindow ()
- return
-
-def RefreshPriestLevel ():
- global PriestSpellLevel
-
- PriestSpellLevel = GemRB.GetVar ("PriestSpellLevel")
- UpdatePriestWindow ()
- return
-
-def OpenPriestSpellInfoWindow ():
- global PriestSpellInfoWindow
-
- if PriestSpellInfoWindow != None:
- if PriestSpellInfoWindow:
- PriestSpellInfoWindow.Unload ()
- PriestSpellInfoWindow = None
- return
-
- PriestSpellInfoWindow = Window = GemRB.LoadWindow (3)
-
- #back
- Button = Window.GetControl (5)
- Button.SetText (15416)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenPriestSpellInfoWindow)
-
- index = GemRB.GetVar ("SpellButton")
- if index < 100:
- ResRef = PriestMemorizedSpellList[index]
- else:
- ResRef = PriestKnownSpellList[index - 100]
-
- spell = GemRB.GetSpell (ResRef)
-
- #Label = Window.GetControl (0x0fffffff)
- #Label.SetText (spell['SpellName'])
-
- Label = Window.GetControl (0x10000000)
- Label.SetText (spell['SpellName'])
-
- Button = Window.GetControl (2)
- Button.SetSpellIcon (ResRef, 1)
-
- Text = Window.GetControl (3)
- Text.SetText (spell['SpellDesc'])
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def OnPriestMemorizeSpell ():
- pc = GemRB.GameGetSelectedPCSingle ()
- level = PriestSpellLevel
- Type = IE_SPELL_TYPE_PRIEST
-
- index = GemRB.GetVar ("SpellButton") - 100
-
- if GemRB.MemorizeSpell (pc, Type, level, index):
- UpdatePriestWindow ()
- return
-
-def OpenPriestSpellRemoveWindow ():
- global PriestSpellUnmemorizeWindow
-
- PriestSpellUnmemorizeWindow = Window = GemRB.LoadWindow (5)
-
- # "Are you sure you want to ....?"
- TextArea = Window.GetControl (3)
- TextArea.SetText (11824)
-
- # Remove
- Button = Window.GetControl (0)
- Button.SetText (17507)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OnPriestRemoveSpell)
- Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- # Cancel
- Button = Window.GetControl (1)
- Button.SetText (13727)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenPriestSpellRemoveWindow)
- Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def ClosePriestSpellUnmemorizeWindow ():
- global PriestSpellUnmemorizeWindow
-
- if PriestSpellUnmemorizeWindow:
- PriestSpellUnmemorizeWindow.Unload ()
- PriestSpellUnmemorizeWindow = None
- return
-
-def OpenPriestSpellUnmemorizeWindow ():
- global PriestSpellUnmemorizeWindow
-
- PriestSpellUnmemorizeWindow = Window = GemRB.LoadWindow (5)
-
- # "Are you sure you want to ....?"
- TextArea = Window.GetControl (3)
- TextArea.SetText (11824)
-
- # Remove
- Button = Window.GetControl (0)
- Button.SetText (17507)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OnPriestUnmemorizeSpell)
- Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- # Cancel
- Button = Window.GetControl (1)
- Button.SetText (13727)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, ClosePriestSpellUnmemorizeWindow)
- Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def OnPriestUnmemorizeSpell ():
- if PriestSpellUnmemorizeWindow:
- ClosePriestSpellUnmemorizeWindow ()
-
- pc = GemRB.GameGetSelectedPCSingle ()
- level = PriestSpellLevel
- Type = IE_SPELL_TYPE_PRIEST
-
- index = GemRB.GetVar ("SpellButton")
-
- if GemRB.UnmemorizeSpell (pc, Type, level, index):
- UpdatePriestWindow ()
- return
-
-def OnPriestRemoveSpell ():
- ClosePriestSpellUnmemorizeWindow()
- OpenPriestSpellInfoWindow()
-
- pc = GemRB.GameGetSelectedPCSingle ()
- level = PriestSpellLevel
- Type = IE_SPELL_TYPE_PRIEST
-
- index = GemRB.GetVar ("SpellButton")-100
-
- #remove spell from memory
- GemRB.RemoveSpell (pc, Type, level, index)
- UpdatePriestWindow ()
- return
-
-###################################################
-# End of file GUIPR.py
diff --git a/gemrb/GUIScripts/bg1/GUIREC.py b/gemrb/GUIScripts/bg1/GUIREC.py
deleted file mode 100644
index 6174578..0000000
--- a/gemrb/GUIScripts/bg1/GUIREC.py
+++ /dev/null
@@ -1,1449 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003-2009 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-
-# GUIREC.py - scripts to control stats/records windows from the GUIREC winpack
-###################################################
-import GemRB
-import GUICommon
-import CommonTables
-from GUIDefines import *
-from ie_stats import *
-from ie_restype import *
-import LUCommon
-import LevelUp
-import GUIWORLD
-import GUICG19
-import DualClass
-###################################################
-RecordsWindow = None
-InformationWindow = None
-BiographyWindow = None
-OptionsWindow = None
-CustomizeWindow = None
-OldOptionsWindow = None
-ExportDoneButton = None
-ExportFileName = ""
-PortraitsTable = None
-ScriptsTable = None
-ColorTable = None
-ColorIndex = None
-ScriptTextArea = None
-SelectedTextArea = None
-PortraitWindow = None
-OldPortraitWindow = None
-OldVoiceSet = None
-
-# the available sounds
-SoundSequence = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', \
- 'm', 's', 't', 'u', 'v', '_', 'x', 'y', 'z', '0', '1', '2', \
- '3', '4', '5', '6', '7', '8', '9']
-SoundIndex = 0
-
-###################################################
-def OpenRecordsWindow ():
- import GUICommonWindows
- global RecordsWindow, OptionsWindow
- global OldOptionsWindow, PortraitWindow, OldPortraitWindow
-
- if GUICommon.CloseOtherWindow (OpenRecordsWindow):
- if InformationWindow: OpenInformationWindow ()
-
- if RecordsWindow:
- RecordsWindow.Unload ()
- if OptionsWindow:
- OptionsWindow.Unload ()
- if PortraitWindow:
- PortraitWindow.Unload ()
- RecordsWindow = None
- GemRB.SetVar ("OtherWindow", -1)
- GUICommon.GameWindow.SetVisible(WINDOW_VISIBLE)
- GemRB.UnhideGUI ()
- GUICommonWindows.OptionsWindow = OldOptionsWindow
- OldOptionsWindow = None
- GUICommonWindows.PortraitWindow = OldPortraitWindow
- GUICommonWindows.UpdatePortraitWindow ()
- OldPortraitWindow = None
- GUICommonWindows.SetSelectionChangeHandler (None)
- return
-
- GemRB.HideGUI ()
- GUICommon.GameWindow.SetVisible(WINDOW_INVISIBLE)
-
- GemRB.LoadWindowPack ("GUIREC", 640, 480)
- RecordsWindow = Window = GemRB.LoadWindow (2)
- GemRB.SetVar ("OtherWindow", RecordsWindow.ID)
- # saving the original portrait window
- OldOptionsWindow = GUICommonWindows.OptionsWindow
- OptionsWindow = GemRB.LoadWindow (0)
- GUICommonWindows.SetupMenuWindowControls (OptionsWindow, 0, OpenRecordsWindow)
- OldPortraitWindow = GUICommonWindows.PortraitWindow
- PortraitWindow = GUICommonWindows.OpenPortraitWindow (0)
- OptionsWindow.SetFrame ()
-
- # dual class
- Button = Window.GetControl (0)
- Button.SetText (7174)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, DualClass.DualClassWindow)
-
- # levelup
- Button = Window.GetControl (37)
- Button.SetText (7175)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, LevelUp.OpenLevelUpWindow)
-
- # information
- Button = Window.GetControl (1)
- Button.SetText (11946)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenInformationWindow)
-
- # reform party
- Button = Window.GetControl (51)
- Button.SetText (16559)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenRecReformPartyWindow)
-
- # customize
- Button = Window.GetControl (50)
- Button.SetText (10645)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenCustomizeWindow)
-
- # export
- Button = Window.GetControl (36)
- Button.SetText (13956)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenExportWindow)
-
-## # kit info
-## Button = Window.GetControl (52)
-## Button.SetText (61265)
-## Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, KitInfoWindow)
-
- GUICommonWindows.SetSelectionChangeHandler (UpdateRecordsWindow)
- UpdateRecordsWindow ()
-
- OptionsWindow.SetVisible (WINDOW_VISIBLE)
- Window.SetVisible (WINDOW_VISIBLE)
- PortraitWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-#original returns to game before continuing...
-def OpenRecReformPartyWindow ():
- OpenRecordsWindow ()
- GemRB.SetTimedEvent (GUIWORLD.OpenReformPartyWindow, 1)
- return
-
-def UpdateRecordsWindow ():
- global stats_overview, alignment_help
-
- Window = RecordsWindow
- if not RecordsWindow:
- print "SelectionChange handler points to non existing window\n"
- return
-
- pc = GemRB.GameGetSelectedPCSingle ()
-
- # exportable
- Button = Window.GetControl (36)
- if GemRB.GetPlayerStat (pc, IE_MC_FLAGS)&MC_EXPORTABLE:
- Button.SetState (IE_GUI_BUTTON_ENABLED)
- else:
- Button.SetState (IE_GUI_BUTTON_DISABLED)
-
- # dual-classable
- Button = Window.GetControl (0)
- if GUICommon.CanDualClass (pc):
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- Button.SetState (IE_GUI_BUTTON_ENABLED)
-
- # levelup
- Button = Window.GetControl (37)
- if LUCommon.CanLevelUp (pc):
- Button.SetState (IE_GUI_BUTTON_ENABLED)
- else:
- Button.SetState (IE_GUI_BUTTON_DISABLED)
-
- # name
- Label = Window.GetControl (0x1000000e)
- Label.SetText (GemRB.GetPlayerName (pc, 0))
-
- # portrait
- Button = Window.GetControl (2)
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE | IE_GUI_BUTTON_PICTURE, OP_SET)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- Button.SetPicture (GemRB.GetPlayerPortrait (pc,0), "NOPORTLG")
-
- # armorclass
- Label = Window.GetControl (0x10000028)
- ac = GemRB.GetPlayerStat (pc, IE_ARMORCLASS)
- ac += GemRB.GetAbilityBonus (IE_DEX, 2, GemRB.GetPlayerStat (pc, IE_DEX) )
- Label.SetText (str (ac))
- Label.SetTooltip (17183)
-
- # hp now
- Label = Window.GetControl (0x10000029)
- Label.SetText (str (GemRB.GetPlayerStat (pc, IE_HITPOINTS)))
- Label.SetTooltip (17184)
-
- # hp max
- Label = Window.GetControl (0x1000002a)
- Label.SetText (str (GemRB.GetPlayerStat (pc, IE_MAXHITPOINTS)))
- Label.SetTooltip (17378)
-
- # stats
-
- sstr = GemRB.GetPlayerStat (pc, IE_STR)
- sstrx = GemRB.GetPlayerStat (pc, IE_STREXTRA)
- cstr = GetStatColor (pc, IE_STR)
- if sstrx > 0 and sstr==18:
- sstr = "%d/%02d" %(sstr, sstrx % 100)
- else:
- sstr = str (sstr)
-
- sint = str (GemRB.GetPlayerStat (pc, IE_INT))
- cint = GetStatColor (pc, IE_INT)
- swis = str (GemRB.GetPlayerStat (pc, IE_WIS))
- cwis = GetStatColor (pc, IE_WIS)
- sdex = str (GemRB.GetPlayerStat (pc, IE_DEX))
- cdex = GetStatColor (pc, IE_DEX)
- scon = str (GemRB.GetPlayerStat (pc, IE_CON))
- ccon = GetStatColor (pc, IE_CON)
- schr = str (GemRB.GetPlayerStat (pc, IE_CHR))
- cchr = GetStatColor (pc, IE_CHR)
-
- Label = Window.GetControl (0x1000002f)
- Label.SetText (sstr)
- Label.SetTextColor (cstr[0], cstr[1], cstr[2])
-
- Label = Window.GetControl (0x10000009)
- Label.SetText (sdex)
- Label.SetTextColor (cdex[0], cdex[1], cdex[2])
-
- Label = Window.GetControl (0x1000000a)
- Label.SetText (scon)
- Label.SetTextColor (ccon[0], ccon[1], ccon[2])
-
- Label = Window.GetControl (0x1000000b)
- Label.SetText (sint)
- Label.SetTextColor (cint[0], cint[1], cint[2])
-
- Label = Window.GetControl (0x1000000c)
- Label.SetText (swis)
- Label.SetTextColor (cwis[0], cwis[1], cwis[2])
-
- Label = Window.GetControl (0x1000000d)
- Label.SetText (schr)
- Label.SetTextColor (cchr[0], cchr[1], cchr[2])
-
- # class
- ClassTitle = GUICommon.GetActorClassTitle (pc)
- Label = Window.GetControl (0x10000030)
- Label.SetText (ClassTitle)
-
- # race
- text = CommonTables.Races.GetValue (CommonTables.Races.FindValue (3, GemRB.GetPlayerStat (pc, IE_RACE)) ,
- 0)
-
- Label = Window.GetControl (0x1000000f)
- Label.SetText (text)
-
- Table = GemRB.LoadTable ("aligns")
-
- text = Table.GetValue (Table.FindValue ( 3, GemRB.GetPlayerStat (pc, IE_ALIGNMENT) ), 0)
- Label = Window.GetControl (0x10000010)
- Label.SetText (text)
-
- Label = Window.GetControl (0x10000011)
- if GemRB.GetPlayerStat (pc, IE_SEX) == 1:
- Label.SetText (7198)
- else:
- Label.SetText (7199)
-
- # help, info textarea
- stats_overview = GetStatOverview (pc)
- Text = Window.GetControl (45)
- Text.SetText (stats_overview)
- #TODO: making window visible/shaded depending on the pc's state
- Window.SetVisible (WINDOW_VISIBLE)
- return
-
-def GetStatColor (pc, stat):
- a = GemRB.GetPlayerStat (pc, stat)
- b = GemRB.GetPlayerStat (pc, stat, 1)
- if a==b:
- return (255,255,255)
- if a<b:
- return (255,255,0)
- return (0,255,0)
-
-# GemRB.GetPlayerStat wrapper that only returns nonnegative values
-def GSNN (pc, stat):
- val = GemRB.GetPlayerStat (pc, stat)
- if val >= 0:
- return val
- else:
- return 0
-
-# LevelDiff is used only from the level up code and holds the level
-# difference for each class
-def GetStatOverview (pc, LevelDiff=[0,0,0]):
- StateTable = GemRB.LoadTable ("statdesc")
-
- GS = lambda s, pc=pc: GemRB.GetPlayerStat (pc, s)
- GB = lambda s, pc=pc: GemRB.GetPlayerStat (pc, s, 1)
- GA = lambda s, col, pc=pc: GemRB.GetAbilityBonus (s, col, GS (s) )
-
- stats = []
- # class levels
- # 16480 <CLASS>: Level <LEVEL>
- # Experience: <EXPERIENCE>
- # Next Level: <NEXTLEVEL>
-
- # collecting tokens for stat overview
- ClassTitle = GUICommon.GetActorClassTitle (pc)
- GemRB.SetToken ("CLASS", ClassTitle)
- Class = GemRB.GetPlayerStat (pc, IE_CLASS)
- Class = CommonTables.Classes.FindValue (5, Class)
- Class = CommonTables.Classes.GetRowName (Class)
- Dual = GUICommon.IsDualClassed (pc, 1)
- Multi = GUICommon.IsMultiClassed (pc, 1)
- XP = GemRB.GetPlayerStat (pc, IE_XP)
- LevelDrain = GS (IE_LEVELDRAIN)
-
- if GS (IE_STATE_ID) & STATE_DEAD:
- stats.append ( (11829,1,'c') ) # DEAD
- stats.append (None)
-
- if Multi[0] > 1: # we're multiclassed
- print "\tMulticlassed"
- Levels = [GemRB.GetPlayerStat (pc, IE_LEVEL), GemRB.GetPlayerStat (pc, IE_LEVEL2), GemRB.GetPlayerStat (pc, IE_LEVEL3)]
-
- stats.append ( (19721,1,'c') )
- stats.append (None)
- for i in range (Multi[0]):
- ClassIndex = CommonTables.Classes.FindValue (5, Multi[i+1])
- ClassTitle = GemRB.GetString (CommonTables.Classes.GetValue (ClassIndex, 2))
- GemRB.SetToken ("CLASS", ClassTitle)
- Class = CommonTables.Classes.GetRowName (ClassIndex)
- GemRB.SetToken ("LEVEL", str (Levels[i]+LevelDiff[i]-int(LevelDrain/Multi[0])) )
- GemRB.SetToken ("EXPERIENCE", str (XP/Multi[0]) )
- if LevelDrain:
- stats.append ( (GemRB.GetString (19720),1,'d') )
- stats.append ( (GemRB.GetString (57435),1,'d') ) # LEVEL DRAINED
- else:
- GemRB.SetToken ("NEXTLEVEL", LUCommon.GetNextLevelExp (Levels[i]+LevelDiff[i], Class) )
- stats.append ( (GemRB.GetString (16480),"",'d') )
- stats.append (None)
- print "\t\tClass (Level):",Class,"(",Levels[i],")"
-
- elif Dual[0] > 0: # dual classed; first show the new class
- print "\tDual classed"
- stats.append ( (19722,1,'c') )
- stats.append (None)
-
- Levels = [GemRB.GetPlayerStat (pc, IE_LEVEL), GemRB.GetPlayerStat (pc, IE_LEVEL2), GemRB.GetPlayerStat (pc, IE_LEVEL3)]
-
- # the levels are stored in the class order (eg. FIGHTER_MAGE)
- # the current active class does not matter!
- if GUICommon.IsDualSwap (pc):
- Levels = [Levels[1], Levels[0], Levels[2]]
-
- Levels[0] += LevelDiff[0]
-
- ClassTitle = GemRB.GetString (CommonTables.Classes.GetValue (Dual[2], 2))
- GemRB.SetToken ("CLASS", ClassTitle)
- GemRB.SetToken ("LEVEL", str (Levels[0]-LevelDrain))
- Class = CommonTables.Classes.GetRowName (Dual[2])
- XP2 = GemRB.GetPlayerStat (pc, IE_XP)
- GemRB.SetToken ("EXPERIENCE", str (XP2) )
- if LevelDrain:
- stats.append ( (GemRB.GetString (19720),1,'d') )
- stats.append ( (GemRB.GetString (57435),1,'d') ) # LEVEL DRAINED
- else:
- GemRB.SetToken ("NEXTLEVEL", LUCommon.GetNextLevelExp (Levels[0], Class) )
- stats.append ( (GemRB.GetString (16480),"",'d') )
- stats.append (None)
- # the first class (shown second)
- if Dual[0] == 1:
- ClassTitle = GemRB.GetString (CommonTables.KitList.GetValue (Dual[1], 2))
- elif Dual[0] == 2:
- ClassTitle = GemRB.GetString (CommonTables.Classes.GetValue (Dual[1], 2))
- GemRB.SetToken ("CLASS", ClassTitle)
- GemRB.SetToken ("LEVEL", str (Levels[1]) )
-
- # the xp table contains only classes, so we have to determine the base class for kits
- if Dual[0] == 2:
- BaseClass = CommonTables.Classes.GetRowName (Dual[1])
- else:
- BaseClass = GUICommon.GetKitIndex (pc)
- BaseClass = CommonTables.KitList.GetValue (BaseClass, 7)
- BaseClass = CommonTables.Classes.FindValue (5, BaseClass)
- BaseClass = CommonTables.Classes.GetRowName (BaseClass)
- # the first class' XP is discarded and set to the minimum level
- # requirement, so if you don't dual class right after a levelup,
- # the game would eat some of your XP
- XP1 = CommonTables.NextLevel.GetValue (BaseClass, str (Levels[1]))
- GemRB.SetToken ("EXPERIENCE", str (XP1) )
-
- # inactive until the new class SURPASSES the former
- if Levels[0] <= Levels[1]:
- # inactive
- stats.append ( (19719,1,'c') )
- else:
- stats.append ( (19720,1,'c') )
- stats.append (None)
- else: # single classed
- print "\tSingle classed"
- Level = GemRB.GetPlayerStat (pc, IE_LEVEL) + LevelDiff[0]
- GemRB.SetToken ("LEVEL", str (Level-LevelDrain))
- GemRB.SetToken ("EXPERIENCE", str (XP) )
- if LevelDrain:
- stats.append ( (19720,1,'c') )
- stats.append ( (57435,1,'c') ) # LEVEL DRAINED
- else:
- GemRB.SetToken ("NEXTLEVEL", LUCommon.GetNextLevelExp (Level, Class) )
- stats.append ( (16480,1,'c') )
- stats.append (None)
- print "\t\tClass (Level):",Class,"(",Level,")"
-
- # check to see if we have a level diff anywhere
- if sum (LevelDiff) == 0:
- effects = GemRB.GetPlayerStates (pc)
- if len (effects):
- for c in effects:
- tmp = StateTable.GetValue (ord(c)-66, 0)
- stats.append ( (tmp,c,'a') )
- stats.append (None)
-
- stats.append (None)
-
- #proficiencies
- stats.append ( (8442,1,'c') )
-
- stats.append ( (9457, str(GS (IE_TOHIT))+" ("+str(GemRB.GetCombatDetails(pc, 0)["ToHit"])+")", '0') )
- tmp = GS (IE_NUMBEROFATTACKS)
- if (tmp&1):
- tmp2 = str (tmp/2) + chr (188)
- else:
- tmp2 = str (tmp/2)
- stats.append ( (9458, tmp2, '') )
- stats.append ( (9459, GSNN (pc, IE_LORE), '0') )
- stats.append ( (19224, GS (IE_RESISTMAGIC), '') )
-
- # party's reputation
- reptxt = GetReputation (GemRB.GameGetReputation ()/10)
- stats.append ( (9465, reptxt, '') )
- stats.append ( (9460, GSNN (pc, IE_LOCKPICKING), '') )
- stats.append ( (9462, GSNN (pc, IE_TRAPS), '') )
- stats.append ( (9463, GSNN (pc, IE_PICKPOCKET), '') )
- stats.append ( (9461, GSNN (pc, IE_STEALTH), '') )
- HatedRace = GS (IE_HATEDRACE)
- if HatedRace:
- HateTable = GemRB.LoadTable ("haterace")
- Racist = HateTable.FindValue (1, HatedRace)
- if Racist != -1:
- HatedRace = HateTable.GetValue (Racist, 0)
- stats.append ( (15982, GemRB.GetString (HatedRace), '') )
-
- #stats.append ( (34120, GSNN (pc, IE_HIDEINSHADOWS), '') )
- #stats.append ( (34121, GSNN (pc, IE_DETECTILLUSIONS), '') )
- #stats.append ( (34122, GSNN (pc, IE_SETTRAPS), '') )
- stats.append ( (12128, GS (IE_BACKSTABDAMAGEMULTIPLIER), 'x') )
- stats.append ( (12126, GS (IE_TURNUNDEADLEVEL), '') )
-
- #this hack only displays LOH if we know the spell
- #TODO: the core should just not set LOH if the paladin can't learn it
- if (GUICommon.HasSpell (pc, IE_SPELL_TYPE_INNATE, 0, "SPCL211") >= 0):
- stats.append ( (12127, GS (IE_LAYONHANDSAMOUNT), '') )
-
- #script
- aiscript = GemRB.GetPlayerScript (pc )
- stats.append ( (2078, aiscript, '') )
- stats.append (None)
-
- # 17379 Saving throws
- stats.append (17379)
- # 17380 Paralyze/Poison/Death
- stats.append ( (17380, IE_SAVEVSDEATH, 's') )
- # 17381 Rod/Staff/Wand
- stats.append ( (17381, IE_SAVEVSWANDS, 's') )
- # 17382 Petrify/Polymorph
- stats.append ( (17382, IE_SAVEVSPOLY, 's') )
- # 17383 Breath weapon
- stats.append ( (17383, IE_SAVEVSBREATH, 's') )
- # 17384 Spells
- stats.append ( (17384, IE_SAVEVSSPELL, 's') )
- stats.append (None)
-
- # 9466 Weapon proficiencies
- stats.append (9466)
- table = GemRB.LoadTable ("weapprof")
- RowCount = table.GetRowCount ()
- for i in range (RowCount):
- text = table.GetValue (i, 1)
- stat = table.GetValue (i, 0) + IE_PROFICIENCYBASTARDSWORD
- stats.append ( (text, GS (stat)&0x07, '+') )
- stats.append (None)
-
- # 11766 AC Bonuses
- stats.append (11766)
- # 11770 AC vs. Crushing
- stats.append ((11770, GS (IE_ACCRUSHINGMOD), ''))
- # 11767 AC vs. Missile
- stats.append ((11767, GS (IE_ACMISSILEMOD), ''))
- # 11769 AC vs. Piercing
- stats.append ((11769, GS (IE_ACPIERCINGMOD), ''))
- # 11768 AC vs. Slashing
- stats.append ((11768, GS (IE_ACSLASHINGMOD), ''))
- stats.append (None)
-
- # 10315 Ability bonuses
- stats.append (10315)
- value = GemRB.GetPlayerStat (pc, IE_STR)
- ex = GemRB.GetPlayerStat (pc, IE_STREXTRA)
- # 10332 to hit
- stats.append ( (10332, GemRB.GetAbilityBonus (IE_STR,0,value,ex), '0') )
- # 10336 damage
- stats.append ( (10336, GemRB.GetAbilityBonus (IE_STR,1,value,ex), '0') )
- # 10337 open doors (bend bars lift gates)
- stats.append ( (10337, GemRB.GetAbilityBonus (IE_STR,2,value,ex), '0') )
- # 10338 weight allowance
- stats.append ( (10338, GemRB.GetAbilityBonus (IE_STR,3,value,ex), '0') )
- # 10339 AC
- stats.append ( (10339, GA (IE_DEX,2), '0') )
- # 10340 Missile adjustment
- stats.append ( (10340, GA (IE_DEX,1), '0') )
- # 10341 Reaction adjustment
- stats.append ( (10341, GA (IE_DEX,0), '0') )
- # 10342 CON HP Bonus/Level
- stats.append ( (10342, GA (IE_CON,0), 'p') )
- # 10343 Chance To Learn spell
- if GemRB.GetMemorizableSpellsCount (pc, IE_SPELL_TYPE_WIZARD, 0, 0)>0:
- stats.append ( (10343, GA (IE_INT,0), '%' ) )
- # 10347 Reaction
- stats.append ( (10347, GA (IE_REPUTATION,0), '0') )
- stats.append (None)
-
- # 10344 Bonus Priest spells
- if GemRB.GetMemorizableSpellsCount (pc, IE_SPELL_TYPE_PRIEST, 0, 0)>0:
- stats.append (10344)
- for level in range (7):
- GemRB.SetToken ("SPELLLEVEL", str (level+1) )
- #get the bonus spell count
- base = GemRB.GetMemorizableSpellsCount (pc, IE_SPELL_TYPE_PRIEST, level, 0)
- if base:
- count = GemRB.GetMemorizableSpellsCount (pc, IE_SPELL_TYPE_PRIEST, level)
- stats.append ( (GemRB.GetString (10345), count-base, 'b') )
- stats.append (None)
-
- res = []
- lines = 0
- for s in stats:
- try:
- strref, val, type = s
- if val == 0 and type != '0':
- continue
- if type == '+': #pluses
- res.append ("[capital=0]"+GemRB.GetString (strref) + ' '+ '+' * val)
- elif type == 'p': #a plus prefix if positive
- if val > 0:
- res.append ("[capital=0]" + GemRB.GetString (strref) + ' +' + str (val) )
- else:
- res.append ("[capital=0]" + GemRB.GetString (strref) + ' ' + str (val) )
- elif type == 's': #both base and (modified) stat, but only if they differ
- base = str (GB (val))
- stat = str (GS (val))
- if base == stat:
- res.append ("[capital=0]" + GemRB.GetString (strref) + ': ' + base)
- else:
- res.append ("[capital=0]" + GemRB.GetString (strref) + ': ' + base + " (" + stat + ")")
- elif type == 'x': #x character before value
- res.append ("[capital=0]"+GemRB.GetString (strref) +': x' + str (val) )
- elif type == 'a': #value (portrait icon) + string
- res.append ("[capital=2]"+val+" "+GemRB.GetString (strref))
- elif type == 'b': #strref is an already resolved string
- res.append ("[capital=0]"+strref+": "+str (val))
- elif type == 'c': #normal string
- res.append ("[capital=0]"+GemRB.GetString (strref))
- elif type == 'd': #strref is an already resolved string
- res.append ("[capital=0]"+strref)
- elif type == '0': #normal value
- res.append (GemRB.GetString (strref) + ': ' + str (val))
- else: #normal value + type character, for example percent sign
- res.append ("[capital=0]"+GemRB.GetString (strref) + ': ' + str (val) + type)
- lines = 1
- except:
- if s != None:
- res.append ( GemRB.GetString (s) )
- lines = 0
- else:
- if lines:
- res.append ("")
- lines = 0
-
- return "\n".join (res)
-
-def GetReputation (repvalue):
- table = GemRB.LoadTable ("reptxt")
- if repvalue>20:
- repvalue=20
- txt = GemRB.GetString (table.GetValue (repvalue, 0) )
- return txt+"("+str (repvalue)+")"
-
-def OpenInformationWindow ():
- global InformationWindow
-
- if InformationWindow != None:
- if BiographyWindow: OpenBiographyWindow ()
-
- return
-
- InformationWindow = Window = GemRB.LoadWindow (4)
-
- # Biography
- Button = Window.GetControl (26)
- Button.SetText (18003)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenBiographyWindow)
-
- # Done
- Button = Window.GetControl (24)
- Button.SetText (11973)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseInformationWindow)
-
- TotalPartyExp = 0
- ChapterPartyExp = 0
- TotalCount = 0
- ChapterCount = 0
- for i in range (1, GemRB.GetPartySize () + 1):
- stat = GemRB.GetPCStats(i)
- TotalPartyExp = TotalPartyExp + stat['KillsTotalXP']
- ChapterPartyExp = ChapterPartyExp + stat['KillsChapterXP']
- TotalCount = TotalCount + stat['KillsTotalCount']
- ChapterCount = ChapterCount + stat['KillsChapterCount']
-
- # These are used to get the stats
- pc = GemRB.GameGetSelectedPCSingle ()
- stat = GemRB.GetPCStats (pc)
-
- Label = Window.GetControl (0x10000000)
- Label.SetText (GemRB.GetPlayerName (pc, 1))
- # class
- ClassTitle = GUICommon.GetActorClassTitle (pc)
- Label = Window.GetControl (0x10000018)
- Label.SetText (ClassTitle)
-
- #most powerful vanquished
- Label = Window.GetControl (0x10000005)
- #we need getstring, so -1 will translate to empty string
- Label.SetText (GemRB.GetString (stat['BestKilledName']))
-
- # NOTE: currentTime is in seconds, joinTime is in seconds * 15
- # (script updates???). In each case, there are 60 seconds
- # in a minute, 24 hours in a day, but ONLY 5 minutes in an hour!!
- # Hence currentTime (and joinTime after div by 15) has
- # 7200 secs a day (60 * 5 * 24)
- currentTime = GemRB.GetGameTime ()
- joinTime = stat['JoinDate'] - stat['AwayTime']
-
- party_time = currentTime - (joinTime / 15)
- days = party_time / 7200
- hours = (party_time % 7200) / 300
-
- GemRB.SetToken ('GAMEDAYS', str (days))
- GemRB.SetToken ('HOUR', str (hours))
- Label = Window.GetControl (0x10000006)
- #actually it is 16043 <DURATION>, but duration is translated to
- #16041, hopefully this won't cause problem with international version
- Label.SetText (16041)
-
- #favourite spell
- Label = Window.GetControl (0x10000007)
- Label.SetText (stat['FavouriteSpell'])
-
- #favourite weapon
- Label = Window.GetControl (0x10000008)
- #actually it is 10479 <WEAPONNAME>, but weaponname is translated to
- #the real weapon name (which we should set using SetToken)
- #there are other strings like bow+wname/xbow+wname/sling+wname
- #are they used?
- Label.SetText (stat['FavouriteWeapon'])
-
- #total party xp
- Label = Window.GetControl (0x10000013)
- if TotalPartyExp != 0:
- PartyExp = int ((stat['KillsTotalXP'] * 100) / TotalPartyExp)
- Label.SetText (str (PartyExp) + '%')
- else:
- Label.SetText ("0%")
-
- # chapter party xp
- Label = Window.GetControl (0x1000000f)
- if ChapterPartyExp != 0:
- PartyExp = int ((stat['KillsChapterXP'] * 100) / ChapterPartyExp)
- Label.SetText (str (PartyExp) + '%')
- else:
- Label.SetText ("0%")
-
- #total xp
- Label = Window.GetControl (0x10000014)
- if TotalCount != 0:
- PartyExp = int ((stat['KillsTotalCount'] * 100) / TotalCount)
- Label.SetText (str (PartyExp) + '%')
- else:
- Label.SetText ("0%")
-
- # chapter xp
- Label = Window.GetControl (0x10000010)
- if ChapterCount != 0:
- PartyExp = int ((stat['KillsChapterCount'] * 100) / ChapterCount)
- Label.SetText (str (PartyExp) + '%')
- else:
- Label.SetText ("0%")
-
- Label = Window.GetControl (0x10000011)
- Label.SetText (str (stat['KillsChapterXP']))
- Label = Window.GetControl (0x10000015)
- Label.SetText (str (stat['KillsTotalXP']))
-
- #count of kills in chapter/game
- Label = Window.GetControl (0x10000012)
- Label.SetText (str (stat['KillsChapterCount']))
- Label = Window.GetControl (0x10000016)
- Label.SetText (str (stat['KillsTotalCount']))
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def CloseInformationWindow ():
- import GUICommonWindows
- global InformationWindow
-
- if InformationWindow:
- InformationWindow.Unload ()
- InformationWindow = None
- OptionsWindow.SetVisible (WINDOW_VISIBLE)
- RecordsWindow.SetVisible (WINDOW_VISIBLE)
- PortraitWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def OpenBiographyWindow ():
- global BiographyWindow
-
- if BiographyWindow != None:
- return
-
- BiographyWindow = Window = GemRB.LoadWindow (12)
- GemRB.SetVar ("FloatWindow", BiographyWindow.ID)
-
- TextArea = Window.GetControl (0)
- pc = GemRB.GameGetSelectedPCSingle ()
- TextArea.SetText (GemRB.GetPlayerString (pc, 74) )
-
- # Done
- Button = Window.GetControl (2)
- Button.SetText (11973)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseBiographyWindow)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def CloseBiographyWindow ():
- global BiographyWindow
-
- if BiographyWindow:
- BiographyWindow.Unload ()
- BiographyWindow = None
- InformationWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def OpenExportWindow ():
- global ExportWindow, NameField, ExportDoneButton
-
- ExportWindow = GemRB.LoadWindow (13)
-
- TextArea = ExportWindow.GetControl (2)
- TextArea.SetText (10962)
-
- TextArea = ExportWindow.GetControl (0)
- TextArea.GetCharacters ()
-
- ExportDoneButton = ExportWindow.GetControl (4)
- ExportDoneButton.SetText (11973)
- ExportDoneButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- CancelButton = ExportWindow.GetControl (5)
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- NameField = ExportWindow.GetControl (6)
-
- ExportDoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, ExportDonePress)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, ExportCancelPress)
- NameField.SetEvent (IE_GUI_EDIT_ON_CHANGE, ExportEditChanged)
- ExportWindow.ShowModal (MODAL_SHADOW_GRAY)
- NameField.SetStatus (IE_GUI_CONTROL_FOCUSED)
- return
-
-def ExportDonePress():
- if ExportWindow:
- ExportWindow.Unload()
- #save file under name from EditControl
- return
-
-def ExportCancelPress():
- if ExportWindow:
- ExportWindow.Unload()
- return
-
-def ExportEditChanged():
- ExportFileName = NameField.QueryText ()
- if ExportFileName == "":
- ExportDoneButton.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- ExportDoneButton.SetState (IE_GUI_BUTTON_ENABLED)
- return
-
-def OpenCustomizeWindow ():
- global CustomizeWindow
- global PortraitsTable, ScriptsTable, ColorTable
-
- pc = GemRB.GameGetSelectedPCSingle ()
- if GemRB.GetPlayerStat (pc, IE_MC_FLAGS)&MC_EXPORTABLE:
- Exportable = 1
- else:
- Exportable = 0
-
- PortraitsTable = GemRB.LoadTable ("PICTURES")
- ScriptsTable = GemRB.LoadTable ("SCRPDESC")
- ColorTable = GemRB.LoadTable ("CLOWNCOL")
- CustomizeWindow = GemRB.LoadWindow (17)
-
- PortraitSelectButton = CustomizeWindow.GetControl (0)
- PortraitSelectButton.SetText (11961)
- if not Exportable:
- PortraitSelectButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- SoundButton = CustomizeWindow.GetControl (1)
- SoundButton.SetText (10647)
- if not Exportable:
- SoundButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- ColorButton = CustomizeWindow.GetControl (2)
- ColorButton.SetText (10646)
- if not Exportable:
- ColorButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- ScriptButton = CustomizeWindow.GetControl (3)
- ScriptButton.SetText (17111)
-
- #This button exists only in bg2/iwd, theoretically we could create it here
- #BiographyButton = CustomizeWindow.GetControl (9)
- #BiographyButton.SetText (18003)
- #if not Exportable:
- # BiographyButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- TextArea = CustomizeWindow.GetControl (5)
- TextArea.SetText (11327)
-
- CustomizeDoneButton = CustomizeWindow.GetControl (7)
- CustomizeDoneButton.SetText (11973)
- CustomizeDoneButton.SetState (IE_GUI_BUTTON_ENABLED)
-
- CancelButton = CustomizeWindow.GetControl (8);
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- PortraitSelectButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenPortraitSelectWindow)
- SoundButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenSoundWindow)
- ColorButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenColorWindow)
- ScriptButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenScriptWindow)
- #BiographyButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenBiographyEditWindow)
- CustomizeDoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CustomizeDonePress)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CustomizeCancelPress)
-
- CustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def CustomizeDonePress ():
- CloseCustomizeWindow ()
- UpdateRecordsWindow ()
- return
-
-def CustomizeCancelPress ():
- CloseCustomizeWindow ()
- UpdateRecordsWindow ()
- return
-
-def CloseCustomizeWindow ():
- global CustomizeWindow
-
- if CustomizeWindow:
- CustomizeWindow.Unload ()
- CustomizeWindow = None
- return
-
-def OpenPortraitSelectWindow ():
- global SubCustomizeWindow
- global PortraitButton
- global Gender, LastPortrait
-
- SubCustomizeWindow = GemRB.LoadWindow (18)
- pc = GemRB.GameGetSelectedPCSingle ()
- Gender = GemRB.GetPlayerStat (pc, IE_SEX, 1)
- PortraitName = GemRB.GetPlayerPortrait (pc, 0)
- LastPortrait = PortraitsTable.GetRowIndex (PortraitName[0:len(PortraitName)-1])
-
- PortraitButton = SubCustomizeWindow.GetControl (0)
- PortraitButton.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_NO_IMAGE,OP_SET)
- PortraitButton.SetState (IE_GUI_BUTTON_LOCKED)
-
- LeftButton = SubCustomizeWindow.GetControl (1)
- RightButton = SubCustomizeWindow.GetControl (2)
-
- DoneButton = SubCustomizeWindow.GetControl (3)
- DoneButton.SetText (11973)
- DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- CancelButton = SubCustomizeWindow.GetControl (4)
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- CustomPortraitButton = SubCustomizeWindow.GetControl (5)
- CustomPortraitButton.SetText (17545)
-
- LeftButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, PortraitLeftPress)
- RightButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, PortraitRightPress)
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, PortraitDonePress)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSubCustomizeWindow)
- CustomPortraitButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenCustomPortraitWindow)
- SubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
-
- while True:
- if PortraitsTable.GetValue (LastPortrait, 0) == Gender:
- UpdatePortrait ()
- break
- LastPortrait = LastPortrait + 1
-
- return
-
-def PortraitDonePress ():
- pc = GemRB.GameGetSelectedPCSingle ()
- Name = PortraitsTable.GetRowName (LastPortrait)
- GemRB.FillPlayerInfo (pc, Name + "L", Name + "S")
- CloseSubCustomizeWindow ()
- return
-
-def PortraitRightPress():
- global LastPortrait
-
- while True:
- LastPortrait = LastPortrait + 1
- if LastPortrait >= PortraitsTable.GetRowCount ():
- LastPortrait = 0
- if PortraitsTable.GetValue (LastPortrait, 0) == Gender:
- UpdatePortrait ()
- return
-
- return
-
-def PortraitLeftPress():
- global LastPortrait
-
- while True:
- LastPortrait = LastPortrait - 1
- if LastPortrait < 0:
- LastPortrait = PortraitsTable.GetRowCount ()-1
- if PortraitsTable.GetValue (LastPortrait, 0) == Gender:
- UpdatePortrait ()
- return
-
- return
-
-def UpdatePortrait ():
- PortraitName = PortraitsTable.GetRowName (LastPortrait)+"G"
- PortraitButton.SetPicture (PortraitName, "NOPORTLG")
- return
-
-def OpenCustomPortraitWindow ():
- global SubSubCustomizeWindow
- global PortraitList1, PortraitList2
- global RowCount1, RowCount2
-
- SubSubCustomizeWindow = GemRB.LoadWindow (19)
-
- SmallPortraitButton = SubSubCustomizeWindow.GetControl (1)
- SmallPortraitButton.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_NO_IMAGE,OP_SET)
-
- LargePortraitButton = SubSubCustomizeWindow.GetControl (0)
- LargePortraitButton.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_NO_IMAGE,OP_SET)
-
- DoneButton = SubSubCustomizeWindow.GetControl (10)
- DoneButton.SetText (11973)
- DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
- DoneButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- CancelButton = SubSubCustomizeWindow.GetControl (11)
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- # Portrait List Large
- PortraitList1 = SubSubCustomizeWindow.GetControl (2)
- RowCount1 = PortraitList1.GetPortraits (0)
- PortraitList1.SetEvent (IE_GUI_TEXTAREA_ON_CHANGE, LargeCustomPortrait)
- GemRB.SetVar ("Row1", RowCount1)
- PortraitList1.SetVarAssoc ("Row1",RowCount1)
-
- # Portrait List Small
- PortraitList2 = SubSubCustomizeWindow.GetControl (3)
- RowCount2 = PortraitList2.GetPortraits (1)
- PortraitList2.SetEvent (IE_GUI_TEXTAREA_ON_CHANGE, SmallCustomPortrait)
- GemRB.SetVar ("Row2", RowCount2)
- PortraitList2.SetVarAssoc ("Row2",RowCount2)
-
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CustomPortraitDonePress)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSubSubCustomizeWindow)
-
- SubSubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def CustomPortraitDonePress ():
- pc = GemRB.GameGetSelectedPCSingle ()
- GemRB.FillPlayerInfo (pc, PortraitList1.QueryText () , PortraitList2.QueryText ())
-
- CloseSubSubCustomizeWindow ()
- #closing the generic portraits, because we just set a custom one
- CloseSubCustomizeWindow ()
- return
-
-def LargeCustomPortrait ():
- Window = SubSubCustomizeWindow
-
- Portrait = PortraitList1.QueryText ()
- #small hack
- if GemRB.GetVar ("Row1") == RowCount1:
- return
-
- Label = Window.GetControl (0x10000007)
- Label.SetText (Portrait)
-
- Button = Window.GetControl (10)
- if Portrait=="":
- Portrait = "NOPORTMD"
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- if PortraitList2.QueryText ()!="":
- Button.SetState (IE_GUI_BUTTON_ENABLED)
-
- Button = Window.GetControl (0)
- Button.SetPicture (Portrait, "NOPORTMD")
- return
-
-def SmallCustomPortrait ():
- Window = SubSubCustomizeWindow
-
- Portrait = PortraitList2.QueryText ()
- #small hack
- if GemRB.GetVar ("Row2") == RowCount2:
- return
-
- Label = Window.GetControl (0x10000008)
- Label.SetText (Portrait)
-
- Button = Window.GetControl (10)
- if Portrait=="":
- Portrait = "NOPORTSM"
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- if PortraitList1.QueryText ()!="":
- Button.SetState (IE_GUI_BUTTON_ENABLED)
-
- Button = Window.GetControl (1)
- Button.SetPicture (Portrait, "NOPORTSM")
- return
-
-def OpenSoundWindow ():
- global SubCustomizeWindow
- global VoiceList
- global Gender
- global OldVoiceSet
-
- pc = GemRB.GameGetSelectedPCSingle ()
- OldVoiceSet = GemRB.GetPlayerSound (pc)
- SubCustomizeWindow = GemRB.LoadWindow (20)
-
- VoiceList = SubCustomizeWindow.GetControl (5)
- VoiceList.SetFlags (IE_GUI_TEXTAREA_SELECTABLE)
- Gender = GemRB.GetPlayerStat (pc, IE_SEX, 1)
-
- VoiceList.SetVarAssoc ("Selected", 0)
- VoiceList.GetCharSounds()
- VoiceList.SelectText (OldVoiceSet)
-
- PlayButton = SubCustomizeWindow.GetControl (7)
- PlayButton.SetText (17318)
-
- TextArea = SubCustomizeWindow.GetControl (8)
- TextArea.SetText (11315)
-
- DoneButton = SubCustomizeWindow.GetControl (10)
- DoneButton.SetText (11973)
- DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- CancelButton = SubCustomizeWindow.GetControl (11)
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- PlayButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, PlaySoundPressed)
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DoneSoundWindow)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSoundWindow)
-
- SubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def CloseSoundWindow ():
- pc = GemRB.GameGetSelectedPCSingle ()
- GemRB.SetPlayerSound (pc, OldVoiceSet)
- CloseSubCustomizeWindow ()
- return
-
-def DoneSoundWindow ():
- pc = GemRB.GameGetSelectedPCSingle ()
- CharSound = VoiceList.QueryText ()
- GemRB.SetPlayerSound (pc, CharSound)
-
- CloseSubCustomizeWindow ()
- return
-
-def PlaySoundPressed():
- global CharSoundWindow, SoundIndex, SoundSequence
-
- CharSound = VoiceList.QueryText ()
- tmp = SoundIndex
- while (not GemRB.HasResource (CharSound + SoundSequence[SoundIndex], RES_WAV)):
- NextSound()
- if SoundIndex == tmp:
- break
- else:
- NextSound()
- GemRB.PlaySound (CharSound + SoundSequence[SoundIndex], 0, 0, 5)
- return
-
-def NextSound():
- global SoundIndex, SoundSequence
- SoundIndex += 1
- if SoundIndex >= len(SoundSequence):
- SoundIndex = 0
- return
-
-def OpenColorWindow ():
- global SubCustomizeWindow
- global PortraitWindow
- global PortraitButton
- global HairButton, SkinButton, MajorButton, MinorButton
- global HairColor, SkinColor, MajorColor, MinorColor
-
- pc = GemRB.GameGetSelectedPCSingle ()
- MinorColor = GemRB.GetPlayerStat (pc, IE_MINOR_COLOR)
- MajorColor = GemRB.GetPlayerStat (pc, IE_MAJOR_COLOR)
- SkinColor = GemRB.GetPlayerStat (pc, IE_SKIN_COLOR)
- HairColor = GemRB.GetPlayerStat (pc, IE_HAIR_COLOR)
- SubCustomizeWindow = GemRB.LoadWindow (21)
-
- PortraitButton = SubCustomizeWindow.GetControl (0)
- PortraitButton.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_NO_IMAGE,OP_SET)
- PortraitButton.SetState (IE_GUI_BUTTON_LOCKED)
-
- HairButton = SubCustomizeWindow.GetControl (3)
- SkinButton = SubCustomizeWindow.GetControl (4)
- MajorButton = SubCustomizeWindow.GetControl (5)
- MinorButton = SubCustomizeWindow.GetControl (6)
-
- DoneButton = SubCustomizeWindow.GetControl (12)
- DoneButton.SetText (11973)
- DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- CancelButton = SubCustomizeWindow.GetControl (13)
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- HairButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, SetHairColor)
- SkinButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, SetSkinColor)
- MajorButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, SetMajorColor)
- MinorButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, SetMinorColor)
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DoneColorWindow)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSubCustomizeWindow)
- UpdatePaperDoll ()
-
- SubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DoneColorWindow ():
- pc = GemRB.GameGetSelectedPCSingle ()
- GemRB.SetPlayerStat (pc, IE_MINOR_COLOR, MinorColor)
- GemRB.SetPlayerStat (pc, IE_MAJOR_COLOR, MajorColor)
- GemRB.SetPlayerStat (pc, IE_SKIN_COLOR, SkinColor)
- GemRB.SetPlayerStat (pc, IE_HAIR_COLOR, HairColor)
- CloseSubCustomizeWindow ()
- return
-
-def UpdatePaperDoll ():
- pc = GemRB.GameGetSelectedPCSingle ()
- Color1 = GemRB.GetPlayerStat (pc, IE_METAL_COLOR)
- MinorButton.SetBAM ("COLGRAD", 0, 0, MinorColor&0xff)
- MajorButton.SetBAM ("COLGRAD", 0, 0, MajorColor&0xff)
- SkinButton.SetBAM ("COLGRAD", 0, 0, SkinColor&0xff)
- Color5 = GemRB.GetPlayerStat (pc, IE_LEATHER_COLOR)
- Color6 = GemRB.GetPlayerStat (pc, IE_ARMOR_COLOR)
- HairButton.SetBAM ("COLGRAD", 0, 0, HairColor&0xff)
- PortraitButton.SetPLT (GUICommon.GetActorPaperDoll (pc),
- Color1, MinorColor, MajorColor, SkinColor, Color5, Color6, HairColor, 0, 0)
- return
-
-def SetHairColor ():
- global ColorIndex, PickedColor
-
- ColorIndex = 0
- PickedColor = HairColor
- OpenColorPicker ()
- return
-
-def SetSkinColor ():
- global ColorIndex, PickedColor
-
- ColorIndex = 1
- PickedColor = SkinColor
- OpenColorPicker ()
- return
-
-def SetMinorColor ():
- global ColorIndex, PickedColor
-
- ColorIndex = 2
- PickedColor = MinorColor
- OpenColorPicker ()
- return
-
-def SetMajorColor ():
- global ColorIndex, PickedColor
-
- ColorIndex = 3
- PickedColor = MajorColor
- OpenColorPicker ()
- return
-
-def OpenColorPicker ():
- global SubSubCustomizeWindow
- #global Selected
-
- SubSubCustomizeWindow = GemRB.LoadWindow (22)
-
- GemRB.SetVar ("Selected",-1)
- for i in range (1,35):
- Button = SubSubCustomizeWindow.GetControl (i)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE,OP_OR)
-
- #Selected = -1
- for i in range (34):
- MyColor = ColorTable.GetValue (ColorIndex, i)
- if MyColor == "*":
- break
- Button = SubSubCustomizeWindow.GetControl (i+1)
- Button.SetBAM("COLGRAD", 2, 0, MyColor)
- if PickedColor == MyColor:
- GemRB.SetVar ("Selected",i)
- #Selected = i
- Button.SetState (IE_GUI_BUTTON_ENABLED)
- Button.SetVarAssoc("Selected",i)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, DonePress)
-
- SubSubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DonePress():
- global HairColor, SkinColor, MajorColor, MinorColor
- global PickedColor
-
- CloseSubSubCustomizeWindow ()
- PickedColor=ColorTable.GetValue (ColorIndex, GemRB.GetVar ("Selected"))
- if ColorIndex==0:
- HairColor=PickedColor
- UpdatePaperDoll ()
- return
- if ColorIndex==1:
- SkinColor=PickedColor
- UpdatePaperDoll ()
- return
- if ColorIndex==2:
- MinorColor=PickedColor
- UpdatePaperDoll ()
- return
-
- MajorColor=PickedColor
- UpdatePaperDoll ()
- return
-
-def OpenScriptWindow ():
- global SubCustomizeWindow
- global ScriptTextArea, SelectedTextArea
-
- SubCustomizeWindow = GemRB.LoadWindow (11)
-
- ScriptTextArea = SubCustomizeWindow.GetControl (2)
- ScriptTextArea.SetFlags (IE_GUI_TEXTAREA_SELECTABLE)
- FillScriptList ()
- pc = GemRB.GameGetSelectedPCSingle ()
- script = GemRB.GetPlayerScript (pc)
- scriptindex = ScriptsTable.GetRowIndex (script)
- GemRB.SetVar ("Selected", scriptindex)
- ScriptTextArea.SetVarAssoc ("Selected", scriptindex)
-
- SelectedTextArea = SubCustomizeWindow.GetControl (4)
- UpdateScriptSelection ()
-
- DoneButton = SubCustomizeWindow.GetControl (5)
- DoneButton.SetText (11973)
- DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- CancelButton = SubCustomizeWindow.GetControl (6)
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DoneScriptWindow)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSubCustomizeWindow)
- ScriptTextArea.SetEvent (IE_GUI_TEXTAREA_ON_CHANGE, UpdateScriptSelection)
-
- SubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def FillScriptList ():
- ScriptTextArea.Clear ()
- row = ScriptsTable.GetRowCount ()
- for i in range (row):
- GemRB.SetToken ("script", ScriptsTable.GetRowName (i) )
- title = ScriptsTable.GetValue (i,0)
- if title!=-1:
- desc = ScriptsTable.GetValue (i,1)
- txt = GemRB.GetString (title)
-
- if (desc!=-1):
- txt += GemRB.GetString (desc)
-
- ScriptTextArea.Append (txt+"\n", -1)
-
- else:
- ScriptTextArea.Append (ScriptsTable.GetRowName (i)+"\n" ,-1)
-
- return
-
-def DoneScriptWindow ():
- pc = GemRB.GameGetSelectedPCSingle ()
- script = ScriptsTable.GetRowName (GemRB.GetVar ("Selected") )
- GemRB.SetPlayerScript (pc, script)
- CloseSubCustomizeWindow ()
- return
-
-def UpdateScriptSelection():
- text = ScriptTextArea.QueryText ()
- SelectedTextArea.SetText (text)
- return
-
-def OpenBiographyEditWindow ():
- global SubCustomizeWindow
- global BioStrRef
- global TextArea
-
- Changed = 0
- pc = GemRB.GameGetSelectedPCSingle ()
- BioStrRef = GemRB.GetPlayerString (pc, 74)
- if BioStrRef != 33347:
- Changed = 1
-
- SubCustomizeWindow = GemRB.LoadWindow (23)
-
- ClearButton = SubCustomizeWindow.GetControl (5)
- ClearButton.SetText (34881)
-
- DoneButton = SubCustomizeWindow.GetControl (1)
- DoneButton.SetText (11973)
- DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- RevertButton = SubCustomizeWindow.GetControl (3)
- RevertButton.SetText (2240)
- if not Changed:
- RevertButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- CancelButton = SubCustomizeWindow.GetControl (2)
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- TextArea = SubCustomizeWindow.GetControl (4)
- TextArea.SetBufferLength (65535)
- TextArea.SetText (BioStrRef)
-
- ClearButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, ClearBiography)
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DoneBiographyWindow)
- RevertButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, RevertBiography)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSubCustomizeWindow)
-
- SubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def ClearBiography():
- pc = GemRB.GameGetSelectedPCSingle ()
- BioStrRef = 62015+pc
- #GemRB.CreateString (BioStrRef, "")
- TextArea.SetText ("")
- return
-
-def DoneBiographyWindow ():
- global BioStrRef
-
- #TODO set bio
- pc = GemRB.GameGetSelectedPCSingle ()
- #pc is 1 based
- BioStrRef = 62015+pc
- GemRB.CreateString (BioStrRef, TextArea.QueryText())
- GemRB.SetPlayerString (pc, 74, BioStrRef)
- CloseSubCustomizeWindow ()
- return
-
-def RevertBiography():
- global BioStrRef
-
- BioStrRef = 33347
- TextArea.SetText (33347)
- return
-
-def CloseSubCustomizeWindow ():
- global SubCustomizeWindow
-
- if SubCustomizeWindow:
- SubCustomizeWindow.Unload ()
- SubCustomizeWindow = None
- return
-
-def CloseSubSubCustomizeWindow ():
- global SubSubCustomizeWindow
-
- if SubSubCustomizeWindow:
- SubSubCustomizeWindow.Unload ()
- SubSubCustomizeWindow = None
- return
-
-###################################################
-# End of file GUIREC.py
diff --git a/gemrb/GUIScripts/bg1/GUISAVE.py b/gemrb/GUIScripts/bg1/GUISAVE.py
deleted file mode 100644
index d5673e7..0000000
--- a/gemrb/GUIScripts/bg1/GUISAVE.py
+++ /dev/null
@@ -1,279 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-
-# GUISAVE.py - Save window
-
-###################################################
-
-import GemRB
-import GUICommon
-import LoadScreen
-from GUIDefines import *
-
-SaveWindow = 0
-ConfirmWindow = 0
-NameField = 0
-SaveButton = 0
-TextAreaControl = 0
-Games = ()
-ScrollBar = 0
-
-def OpenSaveWindow ():
- global SaveWindow, TextAreaControl, Games, ScrollBar
-
- if GUICommon.CloseOtherWindow (OpenSaveWindow):
- CloseSaveWindow ()
- return
-
- GemRB.HideGUI ()
- GUICommon.GameWindow.SetVisible(WINDOW_INVISIBLE)
-
- GemRB.LoadWindowPack ("GUISAVE", 640, 480)
- Window = SaveWindow = GemRB.LoadWindow (0)
- Window.SetFrame ()
- CancelButton=Window.GetControl (34)
- CancelButton.SetText (13727)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenSaveWindow)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
- GemRB.SetVar ("LoadIdx",0)
-
- for i in range(4):
- Button = Window.GetControl (26+i)
- Button.SetText (15588)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SavePress)
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- Button.SetVarAssoc ("LoadIdx",i)
-
- Button = Window.GetControl (30+i)
- Button.SetText (13957)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, DeleteGamePress)
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- Button.SetVarAssoc ("LoadIdx",i)
-
- #area previews
- Button = Window.GetControl (1+i)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- Button.SetFlags(IE_GUI_BUTTON_NO_IMAGE|IE_GUI_BUTTON_PICTURE,OP_SET)
-
- #PC portraits
- for j in range(PARTY_SIZE):
- Button = Window.GetControl (40+i*PARTY_SIZE+j)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- Button.SetFlags(IE_GUI_BUTTON_NO_IMAGE|IE_GUI_BUTTON_PICTURE,OP_SET)
-
- ScrollBar=Window.GetControl (25)
- ScrollBar.SetEvent (IE_GUI_SCROLLBAR_ON_CHANGE, ScrollBarPress)
- Games=GemRB.GetSaveGames ()
- TopIndex = max (0, len(Games) - 4 + 1) #one more for the 'new game'
- GemRB.SetVar ("TopIndex",TopIndex)
- ScrollBar.SetVarAssoc ("TopIndex", TopIndex+1)
- ScrollBar.SetDefaultScrollBar ()
- ScrollBarPress ()
- Window.SetVisible (WINDOW_VISIBLE)
- return
-
-def ScrollBarPress():
- Window = SaveWindow
-
- #draw load game portraits
- Pos = GemRB.GetVar ("TopIndex")
- for i in range(4):
- ActPos = Pos + i
-
- Button1 = Window.GetControl (26+i)
- Button2 = Window.GetControl (30+i)
- if ActPos<=len(Games):
- Button1.SetState (IE_GUI_BUTTON_ENABLED)
- else:
- Button1.SetState (IE_GUI_BUTTON_DISABLED)
-
- if ActPos<len(Games):
- Slotname = Games[ActPos].GetName()
- Button2.SetState (IE_GUI_BUTTON_ENABLED)
- elif ActPos == len(Games):
- Slotname = 15304
- Button2.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- Slotname = ""
- Button2.SetState (IE_GUI_BUTTON_DISABLED)
-
- Label = Window.GetControl (0x10000008+i)
- Label.SetText (Slotname)
-
- if ActPos<len(Games):
- Slotname = Games[ActPos].GetGameDate()
- else:
- Slotname = ""
- Label = Window.GetControl (0x10000010+i)
- Label.SetText (Slotname)
-
- Button=Window.GetControl (1+i)
- if ActPos<len(Games):
- Button.SetSprite2D(Games[ActPos].GetPreview())
- else:
- Button.SetPicture("")
- for j in range(PARTY_SIZE):
- Button=Window.GetControl (40+i*PARTY_SIZE+j)
- if ActPos<len(Games):
- Button.SetSprite2D(Games[ActPos].GetPortrait(j))
- else:
- Button.SetPicture("")
- return
-
-def AbortedSaveGame():
- if ConfirmWindow:
- ConfirmWindow.Unload ()
- SaveWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def ConfirmedSaveGame():
- global ConfirmWindow
-
- Pos = GemRB.GetVar ("TopIndex")+GemRB.GetVar ("LoadIdx")
- Label = ConfirmWindow.GetControl (3)
- Slotname = Label.QueryText ()
- LoadScreen.StartLoadScreen()
- if Pos<len(Games):
- GemRB.SaveGame(Games[Pos], Slotname)
- else:
- GemRB.SaveGame(None, Slotname)
- if ConfirmWindow:
- ConfirmWindow.Unload ()
- OpenSaveWindow() # close window
- return
-
-def SavePress():
- global ConfirmWindow, NameField, SaveButton
-
- Pos = GemRB.GetVar ("TopIndex")+GemRB.GetVar ("LoadIdx")
- ConfirmWindow = GemRB.LoadWindow (1)
-
- #slot name
- if Pos<len(Games):
- Slotname = Games[Pos].GetName()
- save_strref = 15306
- else:
- Slotname = ""
- save_strref = 15588
- NameField = ConfirmWindow.GetControl (3)
- NameField.SetText (Slotname)
- NameField.SetEvent (IE_GUI_EDIT_ON_CHANGE, EditChange)
-
- #game hours (should be generated from game)
- if Pos<len(Games):
- Slotname = Games[Pos].GetGameDate()
- else:
- Slotname = ""
- Label = ConfirmWindow.GetControl (0x10000004)
- Label.SetText (Slotname)
-
- #areapreview
- Button=ConfirmWindow.GetControl (0)
- if Pos<len(Games):
- Button.SetSprite2D(Games[Pos].GetPreview())
- else:
- Button.SetPicture("")
-
- #portraits
- for j in range(PARTY_SIZE):
- Button=ConfirmWindow.GetControl (40+j)
- if Pos<len(Games):
- Button.SetSprite2D(Games[Pos].GetPortrait(j))
- else:
- Button.SetPicture("")
-
- #save
- SaveButton=ConfirmWindow.GetControl (7)
- SaveButton.SetText (save_strref)
- SaveButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, ConfirmedSaveGame)
- SaveButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
- #SaveButton.SetState (IE_GUI_BUTTON_DISABLED)
- if Slotname == "":
- SaveButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- #cancel
- CancelButton=ConfirmWindow.GetControl (8)
- CancelButton.SetText (13727)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, AbortedSaveGame)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- ConfirmWindow.SetVisible (WINDOW_VISIBLE)
- NameField.SetStatus (IE_GUI_CONTROL_FOCUSED)
- return
-
-def EditChange():
- Name = NameField.QueryText ()
- if len(Name)==0:
- SaveButton.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- SaveButton.SetState (IE_GUI_BUTTON_ENABLED)
- return
-
-def DeleteGameConfirm():
- global Games
-
- TopIndex = GemRB.GetVar ("TopIndex")
- Pos = TopIndex +GemRB.GetVar ("LoadIdx")
- GemRB.DeleteSaveGame(Games[Pos])
- if TopIndex>0:
- GemRB.SetVar ("TopIndex",TopIndex-1)
- del Games[pos]
- ScrollBar.SetVarAssoc ("TopIndex", len(Games))
- ScrollBarPress()
- if ConfirmWindow:
- ConfirmWindow.Unload ()
- SaveWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def DeleteGameCancel():
- if ConfirmWindow:
- ConfirmWindow.Unload ()
- SaveWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def DeleteGamePress():
- global ConfirmWindow
-
- SaveWindow.SetVisible (WINDOW_INVISIBLE)
- ConfirmWindow=GemRB.LoadWindow (2)
- Text=ConfirmWindow.GetControl (0)
- Text.SetText (15305)
- DeleteButton=ConfirmWindow.GetControl (1)
- DeleteButton.SetText (13957)
- DeleteButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DeleteGameConfirm)
- CancelButton=ConfirmWindow.GetControl (2)
- CancelButton.SetText (13727)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DeleteGameCancel)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- ConfirmWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def CloseSaveWindow ():
- if SaveWindow:
- SaveWindow.Unload ()
- if GemRB.GetVar ("QuitAfterSave"):
- GemRB.QuitGame ()
- GemRB.SetNextScript ("Start")
- return
-
- GUICommon.GameWindow.SetVisible(WINDOW_VISIBLE) #enabling the game control screen
- GemRB.UnhideGUI () #enabling the other windows
- return
diff --git a/gemrb/GUIScripts/bg1/GUIWORLD.py b/gemrb/GUIScripts/bg1/GUIWORLD.py
deleted file mode 100644
index dbe8bf8..0000000
--- a/gemrb/GUIScripts/bg1/GUIWORLD.py
+++ /dev/null
@@ -1,336 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-
-# GUIW.py - scripts to control some windows from GUIWORLD winpack
-# except of Actions, Portrait, Options and Dialog windows
-#################################################################
-
-import GemRB
-import GUICommon
-import GUICommonWindows
-import GUIClasses
-from GUIDefines import *
-from ie_stats import *
-from ie_restype import *
-import MessageWindow
-import CommonWindow
-
-FRAME_PC_SELECTED = 0
-FRAME_PC_TARGET = 1
-
-ContinueWindow = None
-ReformPartyWindow = None
-OldActionsWindow = None
-OldMessageWindow = None
-
-removable_pcs = []
-
-def DialogStarted ():
- global ContinueWindow, OldActionsWindow
-
- # try to force-close anything which is open
- GUICommon.CloseOtherWindow(None)
- CommonWindow.CloseContainerWindow()
-
- # we need GUI for dialogs
- GemRB.UnhideGUI()
-
- # opening control size to maximum, enabling dialog window
- GemRB.GameSetScreenFlags(GS_HIDEGUI, OP_NAND)
- GemRB.GameSetScreenFlags(GS_DIALOG, OP_OR)
-
- if GUICommonWindows.PortraitWindow:
- GUICommonWindows.UpdatePortraitWindow ()
-
- # we want this to happen before we start fiddling with the GUI
- MessageWindow.UpdateControlStatus()
-
- GemRB.LoadWindowPack (GUICommon.GetWindowPack())
- ContinueWindow = Window = GemRB.LoadWindow (9)
-
- GUICommonWindows.EmptyControls()
- OldActionsWindow = GUICommonWindows.ActionsWindow
- #GUICommonWindows.ActionsWindow = None
- OldActionsWindow.SetVisible(WINDOW_INVISIBLE)
- GemRB.SetVar ("ActionsWindow", -1)
-
-def DialogEnded ():
- global ContinueWindow, OldActionsWindow
-
- # TODO: why is this being called at game start?!
- if not ContinueWindow:
- return
-
- #GUICommonWindows.ActionsWindow = OldActionsWindow
- OldActionsWindow.SetVisible(WINDOW_VISIBLE)
- GemRB.SetVar ("ActionsWindow", OldActionsWindow.ID)
- GUICommonWindows.UpdateActionsWindow()
-
- ContinueWindow.Unload ()
- ContinueWindow = None
- OldActionsWindow = None
-
- if GUICommonWindows.PortraitWindow:
- GUICommonWindows.UpdatePortraitWindow ()
-
-def CloseContinueWindow ():
- # don't close the actual window now to avoid flickering: we might still want it open
- GemRB.SetVar ("DialogChoose", GemRB.GetVar ("DialogOption"))
-
-def NextDialogState ():
- if not ContinueWindow:
- return
-
- ContinueWindow.SetVisible(WINDOW_INVISIBLE)
- OldActionsWindow.SetVisible(WINDOW_VISIBLE)
-
- MessageWindow.TMessageTA.SetStatus (IE_GUI_CONTROL_FOCUSED)
-
-def OpenEndMessageWindow ():
- ContinueWindow.SetVisible(WINDOW_VISIBLE)
- OldActionsWindow.SetVisible(WINDOW_INVISIBLE)
- Button = ContinueWindow.GetControl (0)
- Button.SetText (9371)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseContinueWindow)
- Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
- Button.SetStatus (IE_GUI_CONTROL_FOCUSED)
-
-def OpenContinueMessageWindow ():
- ContinueWindow.SetVisible(WINDOW_VISIBLE)
- OldActionsWindow.SetVisible(WINDOW_INVISIBLE)
- #continue
- Button = ContinueWindow.GetControl (0)
- Button.SetText (9372)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseContinueWindow)
- Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
- Button.SetStatus (IE_GUI_CONTROL_FOCUSED)
-
-def UpdateReformWindow ():
- Window = ReformPartyWindow
-
- select = GemRB.GetVar ("Selected")
-
- need_to_drop = GemRB.GetPartySize ()-PARTY_SIZE
- if need_to_drop<0:
- need_to_drop = 0
-
- #excess player number
- Label = Window.GetControl (0x1000000f)
- Label.SetText (str(need_to_drop) )
-
- #done
- Button = Window.GetControl (8)
- if need_to_drop:
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- Button.SetState (IE_GUI_BUTTON_ENABLED)
-
- #remove
- Button = Window.GetControl (15)
- if select:
- Button.SetState (IE_GUI_BUTTON_ENABLED)
- else:
- Button.SetState (IE_GUI_BUTTON_DISABLED)
-
- for i in range (PARTY_SIZE+1):
- Button = Window.GetControl (i)
- if i+1 not in removable_pcs:
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- continue
-
- for i in removable_pcs:
- Button = Window.GetControl (removable_pcs.index(i))
- Button.EnableBorder (FRAME_PC_SELECTED, select == i )
- pic = GemRB.GetPlayerPortrait (i, 1)
- if not pic:
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- continue
- Button.SetState (IE_GUI_BUTTON_ENABLED)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_ALIGN_BOTTOM|IE_GUI_BUTTON_ALIGN_LEFT, OP_SET)
- Button.SetPicture (pic, "NOPORTSM")
- GUICommonWindows.UpdatePortraitWindow ()
- return
-
-def RemovePlayer ():
- global ReformPartyWindow
-
- hideflag = GemRB.HideGUI ()
-
- GemRB.LoadWindowPack (GUICommon.GetWindowPack())
- if ReformPartyWindow:
- ReformPartyWindow.Unload ()
- ReformPartyWindow = Window = GemRB.LoadWindow (25)
- GemRB.SetVar ("OtherWindow", Window.ID)
-
- #are you sure
- Label = Window.GetControl (0x0fffffff)
- Label.SetText (17518)
-
- #confirm
- Button = Window.GetControl (1)
- Button.SetText (17507)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, RemovePlayerConfirm)
- Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- #cancel
- Button = Window.GetControl (2)
- Button.SetText (13727)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, RemovePlayerCancel)
- Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- GemRB.SetVar ("OtherWindow", Window.ID)
- GemRB.SetVar ("ActionsWindow", -1)
- if hideflag:
- GemRB.UnhideGUI ()
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def RemovePlayerConfirm ():
- slot = GemRB.GetVar("Selected")
- if GemRB.GetPlayerStat(slot, IE_HITPOINTS) > 0:
- GemRB.ExecuteString("Dialogue([PC])", slot)
- GemRB.LeaveParty (slot, 1)
- OpenReformPartyWindow ()
- return
-
-def RemovePlayerCancel ():
- #Once for getting rid of the confirmation window
- OpenReformPartyWindow ()
- #and once for reopening the reform party window
- OpenReformPartyWindow ()
- return
-
-def OpenReformPartyWindow ():
- global ReformPartyWindow, OldActionsWindow, OldMessageWindow
- global removable_pcs
-
- GemRB.SetVar ("Selected", 0)
- hideflag = GemRB.HideGUI ()
-
- if ReformPartyWindow:
- ReformPartyWindow.Unload ()
- GemRB.SetVar ("ActionsWindow", OldActionsWindow.ID)
- GemRB.SetVar ("MessageWindow", OldMessageWindow.ID)
- GemRB.SetVar ("OtherWindow", -1)
-
- OldActionsWindow = None
- OldMessageWindow = None
- ReformPartyWindow = None
-
- #GemRB.LoadWindowPack (GUICommon.GetWindowPack())
- if hideflag:
- GemRB.UnhideGUI ()
- #re-enabling party size control
- GemRB.GameSetPartySize (PARTY_SIZE)
- GUICommonWindows.UpdatePortraitWindow()
- return
-
- GemRB.LoadWindowPack (GUICommon.GetWindowPack())
- ReformPartyWindow = Window = GemRB.LoadWindow (24)
- GemRB.SetVar ("OtherWindow", Window.ID)
-
- # skip exportable party members (usually only the protagonist)
- removable_pcs = []
- for i in range (1, GemRB.GetPartySize()+1):
- if not GemRB.GetPlayerStat (i, IE_MC_FLAGS)&MC_EXPORTABLE:
- removable_pcs.append(i)
-
- #PC portraits
- for j in range (PARTY_SIZE+1):
- Button = Window.GetControl (j)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON|IE_GUI_BUTTON_NO_IMAGE|IE_GUI_BUTTON_PICTURE,OP_SET)
- Button.SetBorder (FRAME_PC_SELECTED, 1, 1, 2, 2, 0, 255, 0, 255)
- if j < len(removable_pcs):
- Button.SetVarAssoc ("Selected", removable_pcs[j])
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, UpdateReformWindow)
-
- # Remove
- Button = Window.GetControl (15)
- Button.SetText (17507)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, RemovePlayer)
-
- # Done
- Button = Window.GetControl (8)
- Button.SetText (11973)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenReformPartyWindow)
-
- OldActionsWindow = GUIClasses.GWindow( GemRB.GetVar ("ActionsWindow") )
- OldMessageWindow = GUIClasses.GWindow( GemRB.GetVar ("MessageWindow") )
- GemRB.SetVar ("ActionsWindow", -1)
- GemRB.SetVar ("MessageWindow", -1)
-
- # if nobody can be removed, just close the window
- if not removable_pcs:
- OpenReformPartyWindow ()
- if hideflag:
- GemRB.UnhideGUI ()
- return
-
- UpdateReformWindow ()
- if hideflag:
- GemRB.UnhideGUI ()
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DeathWindow ():
- GemRB.HideGUI ()
- GemRB.SetTimedEvent (DeathWindowEnd, 10)
- return
-
-def DeathWindowEnd ():
- #playing death movie before continuing
- GemRB.PlayMovie ("deathand",1)
- GemRB.GamePause (1,1)
-
- GemRB.LoadWindowPack (GUICommon.GetWindowPack())
- Window = GemRB.LoadWindow (17)
-
- #reason for death
- Label = Window.GetControl (0x0fffffff)
- Label.SetText (16498)
-
- #load
- Button = Window.GetControl (1)
- Button.SetText (15590)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, LoadPress)
-
- #quit
- Button = Window.GetControl (2)
- Button.SetText (15417)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, QuitPress)
-
- GemRB.HideGUI ()
- GemRB.SetVar ("MessageWindow", -1)
- GemRB.UnhideGUI ()
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def QuitPress():
- GemRB.QuitGame ()
- GemRB.SetNextScript ("Start")
- return
-
-def LoadPress():
- GemRB.QuitGame ()
- GemRB.SetNextScript ("GUILOAD")
- return
diff --git a/gemrb/GUIScripts/bg1/MessageWindow.py b/gemrb/GUIScripts/bg1/MessageWindow.py
index 59c4a89..72fc027 100644
--- a/gemrb/GUIScripts/bg1/MessageWindow.py
+++ b/gemrb/GUIScripts/bg1/MessageWindow.py
@@ -23,6 +23,7 @@ import GUICommonWindows
import CommonWindow
import GUIClasses
from GUIDefines import *
+from ie_restype import RES_2DA
MessageWindow = 0
PortraitWindow = 0
@@ -147,3 +148,15 @@ def UpdateControlStatus():
if hideflag:
GemRB.UnhideGUI()
+#upgrade savegame to next version
+#this is not necessary if TotSC was already installed before starting the game
+def GameExpansion():
+ if not HasTOTSC():
+ return
+
+ #reload world map if it doesn't have AR1000
+ GemRB.UpdateWorldMap("WORLDMAP", "AR1000")
+ return
+
+def HasTOTSC ():
+ return GemRB.HasResource ("toscst", RES_2DA)
diff --git a/gemrb/GUIScripts/bg1/Start.py b/gemrb/GUIScripts/bg1/Start.py
index ecdf9c3..b553a99 100644
--- a/gemrb/GUIScripts/bg1/Start.py
+++ b/gemrb/GUIScripts/bg1/Start.py
@@ -118,6 +118,7 @@ def LoadSingle():
if QuitWindow:
QuitWindow.Unload()
GemRB.SetVar("PlayMode",0)
+ GemRB.SetVar("SaveDir",0)
GemRB.SetNextScript("GUILOAD")
return
@@ -126,7 +127,8 @@ def MissionPack():
StartWindow.Unload()
if QuitWindow:
QuitWindow.Unload()
- GemRB.SetVar("PlayMode",3) #use mpsave for saved games
+ GemRB.SetVar("PlayMode",1)
+ GemRB.SetVar("SaveDir",1) #use mpsave for saved games
GemRB.SetNextScript("GUILOAD")
return
diff --git a/gemrb/GUIScripts/bg2/CMakeLists.txt b/gemrb/GUIScripts/bg2/CMakeLists.txt
deleted file mode 100644
index 577d1c2..0000000
--- a/gemrb/GUIScripts/bg2/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-FILE( GLOB FILES_TO_INSTALL *.py )
-
-INSTALL( FILES ${FILES_TO_INSTALL} DESTINATION ${DATA_DIR}/GUIScripts/bg2 )
diff --git a/gemrb/GUIScripts/bg2/CharGen6.py b/gemrb/GUIScripts/bg2/CharGen6.py
index bab6376..edf2705 100644
--- a/gemrb/GUIScripts/bg2/CharGen6.py
+++ b/gemrb/GUIScripts/bg2/CharGen6.py
@@ -19,6 +19,7 @@
# character generation - ability; next skills/profs/spells (CharGen6)
import GemRB
import GUICommon
+import Spellbook
import CommonTables
import CharGenCommon
import LUSkillsSelection
@@ -48,17 +49,17 @@ def OnLoad():
print "CharGen6 output:"
#remove all known spells and nullify the memorizable counts
- GUICommon.RemoveKnownSpells (MyChar, IE_SPELL_TYPE_WIZARD, 1,9, 1)
- GUICommon.RemoveKnownSpells (MyChar, IE_SPELL_TYPE_PRIEST, 1,7, 1)
+ Spellbook.RemoveKnownSpells (MyChar, IE_SPELL_TYPE_WIZARD, 1,9, 1)
+ Spellbook.RemoveKnownSpells (MyChar, IE_SPELL_TYPE_PRIEST, 1,7, 1)
# learn divine spells if appropriate
- Class = GemRB.GetPlayerStat (MyChar, IE_CLASS)
- TableName = CommonTables.ClassSkills.GetValue (Class, 1, 0) # cleric spells
+ ClassName = GUICommon.GetClassRowName (MyChar)
+ TableName = CommonTables.ClassSkills.GetValue (ClassName, "CLERICSPELL", 0) # cleric spells
if TableName == "*": # only druid spells or no spells at all
- TableName = CommonTables.ClassSkills.GetValue (Class, 0, 0)
+ TableName = CommonTables.ClassSkills.GetValue (ClassName, "DRUIDSPELL", 0)
ClassFlag = 0x8000
- elif CommonTables.ClassSkills.GetValue (Class, 0, 0) != "*": # cleric and druid spells
+ elif CommonTables.ClassSkills.GetValue (ClassName, "DRUIDSPELL", 0) != "*": # cleric and druid spells
ClassFlag = 0
else: # only cleric spells
ClassFlag = 0x4000
@@ -77,7 +78,7 @@ def OnLoad():
#be looked at first in Cleric/Ranger multi's, which is correct
foundindex = 0
for i in range (IsMulti[0]):
- ClassName = CommonTables.Classes.GetRowName (CommonTables.Classes.FindValue (5, IsMulti[i+1]) )
+ ClassName = GUICommon.GetClassRowName (IsMulti[i+1], "class")
for table in "CLERICSPELL", "DRUIDSPELL":
if CommonTables.ClassSkills.GetValue (ClassName, table) != "*":
index = i
@@ -87,12 +88,12 @@ def OnLoad():
break
#set our memorizable counts
- GUICommon.SetupSpellLevels (MyChar, TableName, IE_SPELL_TYPE_PRIEST, Levels[index])
+ Spellbook.SetupSpellLevels (MyChar, TableName, IE_SPELL_TYPE_PRIEST, Levels[index])
#learn all our priest spells up to the level we can learn
for level in range (8):
if GemRB.GetMemorizableSpellsCount (MyChar, IE_SPELL_TYPE_PRIEST, level, 0) <= 0:
- GUICommon.LearnPriestSpells (MyChar, level, ClassFlag)
+ Spellbook.LearnPriestSpells (MyChar, level, ClassFlag)
break
CharGenCommon.DisplayOverview (6)
return
diff --git a/gemrb/GUIScripts/bg2/CharGenCommon.py b/gemrb/GUIScripts/bg2/CharGenCommon.py
index dbf1d3b..f0734a4 100644
--- a/gemrb/GUIScripts/bg2/CharGenCommon.py
+++ b/gemrb/GUIScripts/bg2/CharGenCommon.py
@@ -124,7 +124,6 @@ def DisplayOverview(step):
###
# Stat overview
###
- AlignmentTable = GemRB.LoadTable ("aligns")
AbilityTable = GemRB.LoadTable ("ability")
MyChar = GemRB.GetVar ("Slot")
@@ -163,13 +162,12 @@ def DisplayOverview(step):
TextAreaControl.Append (1049, -1)
TextAreaControl.Append (": ")
stat = GemRB.GetPlayerStat (MyChar, IE_ALIGNMENT)
- v = AlignmentTable.FindValue (3, stat)
- TextAreaControl.Append (AlignmentTable.GetValue (v,2))
+ v = CommonTables.Aligns.FindValue (3, stat)
+ TextAreaControl.Append (CommonTables.Aligns.GetValue (v,2))
elif part == 6:
TextAreaControl.Append ("\n")
- ClassID = GemRB.GetPlayerStat (MyChar, IE_CLASS)
- Class = CommonTables.Classes.FindValue (5, ClassID)
- hasextra = CommonTables.Classes.GetValue (Class, 3)=="SAVEWAR"
+ ClassName = GUICommon.GetClassRowName (MyChar)
+ hasextra = CommonTables.Classes.GetValue (ClassName, "SAVE") == "SAVEWAR"
strextra = GemRB.GetPlayerStat (MyChar, IE_STREXTRA)
for i in range(6):
v = AbilityTable.GetValue (i, 2)
@@ -185,9 +183,6 @@ def DisplayOverview(step):
# thieving and other skills
info = ""
SkillTable = GemRB.LoadTable ("skills")
- ClassID = GemRB.GetPlayerStat (MyChar, IE_CLASS)
- Class = CommonTables.Classes.FindValue (5, ClassID)
- ClassName = CommonTables.Classes.GetRowName (Class)
RangerSkills = CommonTables.ClassSkills.GetValue (ClassName, "RANGERSKILL")
BardSkills = CommonTables.ClassSkills.GetValue (ClassName, "BARDSKILL")
KitName = GUICommon.GetKitIndex (MyChar)
diff --git a/gemrb/GUIScripts/bg2/CharGenEnd.py b/gemrb/GUIScripts/bg2/CharGenEnd.py
index 65a4d72..f59e05d 100644
--- a/gemrb/GUIScripts/bg2/CharGenEnd.py
+++ b/gemrb/GUIScripts/bg2/CharGenEnd.py
@@ -19,6 +19,7 @@
# character generation end
import GemRB
import GUICommon
+import Spellbook
import CommonTables
import LUCommon
from GUIDefines import *
@@ -31,9 +32,7 @@ def OnLoad():
# Lay on hands, turn undead and backstab multiplier get set by the core
# set my character up
MyChar = GemRB.GetVar ("Slot")
- Class = GemRB.GetPlayerStat (MyChar, IE_CLASS)
- ClassIndex = CommonTables.Classes.FindValue (5, Class)
- ClassName = CommonTables.Classes.GetRowName (ClassIndex)
+ ClassName = GUICommon.GetClassRowName (MyChar)
IsMulti = GUICommon.IsMultiClassed (MyChar, 1)
Levels = [GemRB.GetPlayerStat (MyChar, IE_LEVEL), GemRB.GetPlayerStat (MyChar, IE_LEVEL2), \
GemRB.GetPlayerStat (MyChar, IE_LEVEL3)]
@@ -52,23 +51,24 @@ def OnLoad():
LUCommon.SetupHP (MyChar)
# mage spells
- TableName = CommonTables.ClassSkills.GetValue (Class, 2, 0)
+ TableName = CommonTables.ClassSkills.GetValue (ClassName, "MAGESPELL", 0)
if TableName != "*":
index = 0
if IsMulti[0]>1:
#find out which class gets mage spells
for i in range (IsMulti[0]):
- if CommonTables.ClassSkills.GetValue (IsMulti[i+1], 2, 0) != "*":
+ TmpClassName = GUICommon.GetClassRowName (IsMulti[i+1], "class")
+ if CommonTables.ClassSkills.GetValue (TmpClassName, "MAGESPELL", 0) != "*":
index = i
break
- GUICommon.SetupSpellLevels(MyChar, TableName, IE_SPELL_TYPE_WIZARD, Levels[index])
+ Spellbook.SetupSpellLevels(MyChar, TableName, IE_SPELL_TYPE_WIZARD, Levels[index])
# apply class/kit abilities
KitIndex = GUICommon.GetKitIndex (MyChar)
if IsMulti[0]>1:
#get the class abilites for each class
for i in range (IsMulti[0]):
- TmpClassName = CommonTables.Classes.GetRowName (CommonTables.Classes.FindValue (5, IsMulti[i+1]) )
+ TmpClassName = GUICommon.GetClassRowName (IsMulti[i+1], "class")
ABTable = CommonTables.ClassSkills.GetValue (TmpClassName, "ABILITIES")
if ABTable != "*" and GemRB.HasResource (ABTable, RES_2DA, 1):
GUICommon.AddClassAbilities (MyChar, ABTable, Levels[i], Levels[i])
@@ -82,14 +82,13 @@ def OnLoad():
# apply starting (alignment dictated) abilities
# pc, table, new level, level diff, alignment
- AlignmentTable = GemRB.LoadTable ("aligns")
- AlignmentAbbrev = AlignmentTable.FindValue (3, GemRB.GetPlayerStat (MyChar, IE_ALIGNMENT))
+ AlignmentAbbrev = CommonTables.Aligns.FindValue (3, GemRB.GetPlayerStat (MyChar, IE_ALIGNMENT))
GUICommon.AddClassAbilities (MyChar, "abstart", 6,6, AlignmentAbbrev)
# setup starting gold (uses a roll dictated by class
TmpTable = GemRB.LoadTable ("strtgold")
- temp = GemRB.Roll (TmpTable.GetValue (Class, 1),TmpTable.GetValue (Class, 0), TmpTable.GetValue (Class, 2))
- GemRB.SetPlayerStat (MyChar, IE_GOLD, temp * TmpTable.GetValue (Class, 3))
+ temp = GemRB.Roll (TmpTable.GetValue (ClassName, "ROLLS"), TmpTable.GetValue (ClassName, "SIDES"), TmpTable.GetValue (ClassName, "MODIFIER"))
+ GemRB.SetPlayerStat (MyChar, IE_GOLD, temp * TmpTable.GetValue (ClassName, "MULTIPLIER"))
# save the appearance
GUICommon.SetColorStat (MyChar, IE_HAIR_COLOR, GemRB.GetVar ("HairColor") )
@@ -110,8 +109,11 @@ def OnLoad():
GemRB.FillPlayerInfo (MyChar, LargePortrait, SmallPortrait)
if GUICommon.GameIsTOB():
- # add the starting inventory for tob
- GiveEquipment(MyChar, ClassName, KitIndex)
+ # will also add the starting inventory for tob
+ GemRB.GameSetExpansion (4)
+ # no torture, let's refresh all the spells, at least for sorcerers
+ # TODO: autopick memorisations for mages? Did they have a memorisation choice step like in bg1?
+ GemRB.ChargeSpells (MyChar)
playmode = GemRB.GetVar ("PlayMode")
if playmode >=0:
@@ -121,9 +123,6 @@ def OnLoad():
GemRB.EnterGame()
GemRB.ExecuteString ("EquipMostDamagingMelee()", MyChar)
else:
- #leaving multi player pregen
- if CharGenWindow:
- CharGenWindow.Unload ()
#when export is done, go to start
if GUICommon.HasTOB():
GemRB.SetToken ("NextScript","Start2")
@@ -191,6 +190,9 @@ def GiveEquipment(MyChar, ClassName, KitIndex):
SlotType = GemRB.GetSlotType (targetslot, MyChar)
i = 1
item = GemRB.GetItem (item_resref)
+ if not item:
+ print "Error: could not find item", item_resref, "that is listed in 25stweap.2da"
+ continue
if inventory_exclusion & item['Exclusion']:
# oops, too many magic items to equip, so just dump it to the inventory
diff --git a/gemrb/GUIScripts/bg2/DemoEnd.py b/gemrb/GUIScripts/bg2/DemoEnd.py
new file mode 100644
index 0000000..ed9172f
--- /dev/null
+++ b/gemrb/GUIScripts/bg2/DemoEnd.py
@@ -0,0 +1,61 @@
+# -*-python-*-
+# GemRB - Infinity Engine Emulator
+# Copyright (C) 2007 The GemRB Project
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+# DemoEnd.py - display DemoEnd pictures
+
+###################################################
+
+import GemRB
+
+Picture = None
+Table = None
+Window = None
+
+def OnLoad ():
+ global Table, Picture, Window
+
+ GemRB.LoadWindowPack("demoend", 640, 480)
+ Window = GemRB.LoadWindow(0)
+ Window.SetFrame()
+ Picture = 0
+ Table = GemRB.LoadTable ("splashsc")
+ resref = Table.GetValue (Picture,0)
+ Button = Window.GetControl (0)
+ Button.SetFlags (IE_GUI_BUTTON_DEFAULT|IE_GUI_BUTTON_CANCEL|IE_GUI_BUTTON_NO_IMAGE|IE_GUI_BUTTON_PICTURE, OP_SET)
+ Button.SetState (IE_GUI_BUTTON_LOCKED)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, NextPress)
+ Button.SetPicture (resref)
+ Window.SetVisible (WINDOW_VISIBLE)
+ return
+
+def NextPress ():
+ global Picture
+
+ Picture = Picture + 1
+ if Table.GetRowCount()<=Picture:
+ DemoEnd()
+ else:
+ resref = Table.GetValue (Picture,0)
+ Button = Window.GetControl (0)
+ Button.SetPicture (resref)
+ return
+
+def DemoEnd ():
+ GemRB.SetNextScript ("Start")
+ return
diff --git a/gemrb/GUIScripts/bg2/GUICG10.py b/gemrb/GUIScripts/bg2/GUICG10.py
index 130474a..b71e02a 100644
--- a/gemrb/GUIScripts/bg2/GUICG10.py
+++ b/gemrb/GUIScripts/bg2/GUICG10.py
@@ -18,6 +18,7 @@
#
#character generation, multi-class (GUICG10)
import GemRB
+import GUICommon
import CommonTables
from ie_stats import *
from GUIDefines import *
@@ -27,9 +28,11 @@ ClassWindow = 0
TextAreaControl = 0
DoneButton = 0
MyChar = 0
+ButtonCount = 0
+MCRowIndices = []
def OnLoad():
- global ClassWindow, TextAreaControl, DoneButton, MyChar
+ global ClassWindow, TextAreaControl, DoneButton, MyChar, ButtonCount, MCRowIndices
GemRB.LoadWindowPack("GUICG", 640, 480)
ClassWindow = GemRB.LoadWindow(10)
@@ -39,36 +42,32 @@ def OnLoad():
Race = GemRB.GetPlayerStat (MyChar, IE_RACE)
RaceName = CommonTables.Races.GetRowName(CommonTables.Races.FindValue (3, Race) )
- j=0
- for i in range(1,ClassCount):
- if CommonTables.Classes.GetValue(i-1,4)==0:
- continue
- if j>11:
- Button = ClassWindow.GetControl(j+7)
- else:
- Button = ClassWindow.GetControl(j+2)
- Button.SetState(IE_GUI_BUTTON_DISABLED)
- Button.SetFlags(IE_GUI_BUTTON_RADIOBUTTON,OP_OR)
- j = j + 1
- j=0
+ MCRowIndices = []
for i in range(1,ClassCount):
ClassName = CommonTables.Classes.GetRowName(i-1)
Allowed = CommonTables.Classes.GetValue(ClassName, RaceName)
- if CommonTables.Classes.GetValue(i-1,4)==0:
+ if CommonTables.Classes.GetValue (ClassName, "MULTI") == 0:
+ # not a multiclass
continue
- if j>11:
- Button = ClassWindow.GetControl(j+7)
- else:
- Button = ClassWindow.GetControl(j+2)
+ MCRowIndices.append((i-1, Allowed))
- t = CommonTables.Classes.GetValue(i-1, 0)
- Button.SetText(t )
- j=j+1
- if Allowed ==0:
- continue
- Button.SetState(IE_GUI_BUTTON_ENABLED)
- Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, ClassPress)
- Button.SetVarAssoc("Class", i) #multiclass, actually
+ ButtonCount = 10
+ if len(MCRowIndices) > 10:
+ # add another button, there's another slot left
+ ClassWindow.CreateButton (15, 18, 250, 271, 20)
+ extramc = ClassWindow.GetControl(15)
+ extramc.SetState(IE_GUI_BUTTON_DISABLED)
+ extramc.SetFlags(IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
+ extramc.SetSprites("GUICGBC",0, 0,1,2,3)
+ ButtonCount = 11
+ if len(MCRowIndices) > 11:
+ # bah, also add a scrollbar
+ ClassWindow.CreateScrollBar(1000, 290, 50, 16, 220)
+ ScrollBar = ClassWindow.GetControl (1000)
+ ScrollBar.SetSprites("GUISCRCW", 0, 0,1,2,3,5,4)
+ ScrollBar.SetVarAssoc("TopIndex", len(MCRowIndices)-10)
+ ScrollBar.SetEvent(IE_GUI_SCROLLBAR_ON_CHANGE, RedrawMCs)
+ ScrollBar.SetDefaultScrollBar()
BackButton = ClassWindow.GetControl(14)
BackButton.SetText(15416)
@@ -83,13 +82,14 @@ def OnLoad():
DoneButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, NextPress)
BackButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, BackPress)
DoneButton.SetState(IE_GUI_BUTTON_DISABLED)
+ RedrawMCs()
ClassWindow.SetVisible(WINDOW_VISIBLE)
return
def ClassPress():
GUICG2.SetClass()
- Class = GemRB.GetVar("Class")-1
- TextAreaControl.SetText(CommonTables.Classes.GetValue(Class,1) )
+ ClassName = GUICommon.GetClassRowName (GemRB.GetVar ("Class")-1, "index")
+ TextAreaControl.SetText (CommonTables.Classes.GetValue (ClassName, "DESC_REF"))
DoneButton.SetState(IE_GUI_BUTTON_ENABLED)
return
@@ -106,11 +106,29 @@ def NextPress():
ClassWindow.Unload()
# find the class from the class table
- ClassIndex = GemRB.GetVar ("Class") - 1
- Class = CommonTables.Classes.GetValue (ClassIndex, 5)
- #protect against barbarians
- ClassName = CommonTables.Classes.GetRowName (CommonTables.Classes.FindValue (5, Class) )
+ ClassName = GUICommon.GetClassRowName (GemRB.GetVar ("Class")-1, "index")
+ Class = CommonTables.Classes.GetValue (ClassName, "ID")
GemRB.SetPlayerStat (MyChar, IE_CLASS, Class)
GemRB.SetNextScript("CharGen4") #alignment
return
+
+#TODO: deal with the potential scrollbar
+def RedrawMCs():
+ for i in range (2, 2+ButtonCount): # loop over the available buttons
+ if i == 12:
+ Button = ClassWindow.GetControl(15) # the extra button
+ else:
+ Button = ClassWindow.GetControl(i)
+ Button.SetState(IE_GUI_BUTTON_ENABLED)
+ Button.SetFlags(IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
+
+ t = GUICommon.GetClassRowName (MCRowIndices[i-2][0], "index")
+ t = CommonTables.Classes.GetValue(t, "NAME_REF")
+ Button.SetText(t )
+ if not MCRowIndices[i-2][1]:
+ Button.SetState(IE_GUI_BUTTON_DISABLED)
+ continue
+ Button.SetState(IE_GUI_BUTTON_ENABLED)
+ Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, ClassPress)
+ Button.SetVarAssoc("Class", MCRowIndices[i-2][0]+1) #multiclass, actually; just a wierd system
diff --git a/gemrb/GUIScripts/bg2/GUICG15.py b/gemrb/GUIScripts/bg2/GUICG15.py
index 5f98247..f6d3dec 100644
--- a/gemrb/GUIScripts/bg2/GUICG15.py
+++ b/gemrb/GUIScripts/bg2/GUICG15.py
@@ -19,6 +19,7 @@
#character generation, racial enemy (GUICG15)
import GemRB
import CommonTables
+import GUICommon
from GUIDefines import *
from ie_stats import *
@@ -54,9 +55,7 @@ def OnLoad():
global RaceTable, RaceCount, TopIndex, MyChar
MyChar = GemRB.GetVar ("Slot")
- Class = GemRB.GetPlayerStat (MyChar, IE_CLASS)
- Class = CommonTables.Classes.FindValue (5, Class)
- ClassName = CommonTables.Classes.GetRowName(Class)
+ ClassName = GUICommon.GetClassRowName (MyChar)
TableName = CommonTables.ClassSkills.GetValue(ClassName, "HATERACE")
if TableName == "*":
GemRB.SetNextScript("GUICG7")
diff --git a/gemrb/GUIScripts/bg2/GUICG2.py b/gemrb/GUIScripts/bg2/GUICG2.py
index 6373d38..9481681 100644
--- a/gemrb/GUIScripts/bg2/GUICG2.py
+++ b/gemrb/GUIScripts/bg2/GUICG2.py
@@ -44,7 +44,8 @@ def OnLoad():
j = 0
#radiobutton groups must be set up before doing anything else to them
for i in range(1,ClassCount):
- if CommonTables.Classes.GetValue(i-1,4):
+ ClassName = CommonTables.Classes.GetRowName (i-1)
+ if CommonTables.Classes.GetValue (ClassName, "MULTI"):
continue
if j>7:
Button = ClassWindow.GetControl(j+7)
@@ -60,7 +61,7 @@ def OnLoad():
for i in range(1,ClassCount):
ClassName = CommonTables.Classes.GetRowName(i-1)
Allowed = CommonTables.Classes.GetValue(ClassName, RaceName)
- if CommonTables.Classes.GetValue(i-1,4):
+ if CommonTables.Classes.GetValue (ClassName, "MULTI"):
if Allowed!=0:
HasMulti = 1
continue
@@ -69,7 +70,7 @@ def OnLoad():
else:
Button = ClassWindow.GetControl(j+2)
j = j+1
- t = CommonTables.Classes.GetValue(i-1, 0)
+ t = CommonTables.Classes.GetValue(ClassName, "NAME_REF")
Button.SetText(t )
if Allowed==0:
@@ -94,12 +95,12 @@ def OnLoad():
TextAreaControl = ClassWindow.GetControl(13)
- Class = GemRB.GetVar("Class")-1
- if Class<0:
+ ClassName = GUICommon.GetClassRowName (GemRB.GetVar ("Class")-1, "index")
+ if ClassName == "":
TextAreaControl.SetText(17242)
DoneButton.SetState(IE_GUI_BUTTON_DISABLED)
else:
- TextAreaControl.SetText(CommonTables.Classes.GetValue(Class,1) )
+ TextAreaControl.SetText (CommonTables.Classes.GetValue (ClassName, "DESC_REF"))
DoneButton.SetState(IE_GUI_BUTTON_ENABLED)
MultiClassButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, MultiClassPress)
@@ -118,13 +119,24 @@ def BackPress():
def SetClass():
# find the class from the class table
ClassIndex = GemRB.GetVar ("Class") - 1
- Class = CommonTables.Classes.GetValue (ClassIndex, 5)
+ ClassName = GUICommon.GetClassRowName (ClassIndex, "index")
+ Class = CommonTables.Classes.GetValue (ClassName, "ID")
GemRB.SetPlayerStat (MyChar, IE_CLASS, Class)
- ClassName = CommonTables.Classes.GetRowName (CommonTables.Classes.FindValue (5, Class))
+ KitIndex = GemRB.GetVar ("Class Kit")
+ MageSchool = GemRB.GetVar ("MAGESCHOOL")
+ #multiclassed gnomes
+ if MageSchool and not KitIndex:
+ SchoolTable = GemRB.LoadTable ("magesch")
+ KitIndex = CommonTables.KitList.FindValue (6, SchoolTable.GetValue (MageSchool, 3) )
+ KitValue = (0x4000 + KitIndex)
+ GemRB.SetPlayerStat (MyChar, IE_KIT, KitValue)
+
# protect against barbarians; this stat will be overwritten later
GemRB.SetPlayerStat (MyChar, IE_HITPOINTS, ClassIndex)
#assign the correct XP
+ if ClassName == "BARBARIAN":
+ ClassName = "FIGHTER"
if GUICommon.GameIsTOB():
GemRB.SetPlayerStat (MyChar, IE_XP, CommonTables.ClassSkills.GetValue (ClassName, "STARTXP2"))
else:
diff --git a/gemrb/GUIScripts/bg2/GUICG22.py b/gemrb/GUIScripts/bg2/GUICG22.py
index d0e4920..c83d056 100644
--- a/gemrb/GUIScripts/bg2/GUICG22.py
+++ b/gemrb/GUIScripts/bg2/GUICG22.py
@@ -27,18 +27,18 @@ KitWindow = 0
TextAreaControl = 0
DoneButton = 0
SchoolList = 0
-ClassID = 0
+ClassName = 0
TopIndex = 0
RowCount = 10
KitTable = 0
Init = 0
MyChar = 0
KitSelected = 0 #store clicked kit on redraw as number within RowCount
-EnhanceGUI = GemRB.GetVar("GUIEnhancements") #extra kit button and scroll bar toggle
+EnhanceGUI = GemRB.GetVar("GUIEnhancements")&GE_SCROLLBARS #extra kit button and scroll bar toggle
def OnLoad():
global KitWindow, TextAreaControl, DoneButton
- global SchoolList, ClassID
+ global SchoolList, ClassName
global RowCount, TopIndex, KitTable, Init, MyChar
GemRB.LoadWindowPack("GUICG", 640, 480)
@@ -46,7 +46,6 @@ def OnLoad():
Race = GemRB.GetPlayerStat (MyChar, IE_RACE)
RaceName = CommonTables.Races.GetRowName(CommonTables.Races.FindValue (3, Race) )
- ClassID = GemRB.GetPlayerStat (MyChar, IE_CLASS)
ClassName = CommonTables.Classes.GetRowName (GemRB.GetPlayerStat (MyChar, IE_HITPOINTS)) # barbarian hack
KitTable = GemRB.LoadTable("kittable")
@@ -58,7 +57,7 @@ def OnLoad():
#there is a specialist mage window, but it is easier to use
#the class kit window for both
KitWindow = GemRB.LoadWindow(22)
- if ClassID == 1:
+ if ClassName == "MAGE":
Label = KitWindow.GetControl(0xfffffff)
Label.SetText(595)
@@ -73,7 +72,7 @@ def OnLoad():
if not KitTable: # sorcerer or monk
RowCount = 1
else:
- if ClassID == 1: # mages
+ if ClassName == "MAGE": # mages
RowCount = SchoolList.GetRowCount()
else:
RowCount = KitTable.GetRowCount()
@@ -137,17 +136,17 @@ def RedrawKits():
Button = KitWindow.GetControl(i+5)
Button.SetState(IE_GUI_BUTTON_DISABLED)
if not KitTable:
- if ClassID == 1:
+ if ClassName == "MAGE":
# TODO: check if this is ever reached
Kit = GemRB.GetVar("MAGESCHOOL")
KitName = SchoolList.GetValue(i+TopIndex, 0)
Kit = SchoolList.GetValue (Kit, 3)
else:
Kit = 0
- KitName = CommonTables.Classes.GetValue(GemRB.GetVar("Class")-1, 0)
+ KitName = CommonTables.Classes.GetValue (ClassName, "NAME_REF")
else:
Kit = KitTable.GetValue (i+TopIndex,0)
- if ClassID == 1:
+ if ClassName == "MAGE":
KitName = SchoolList.GetValue (i+TopIndex, 0)
if Kit == 0:
KitName = SchoolList.GetValue (0, 0)
@@ -162,7 +161,7 @@ def RedrawKits():
if Kit:
KitName = CommonTables.KitList.GetValue(Kit, 1)
else:
- KitName = CommonTables.Classes.GetValue(GemRB.GetVar("Class")-1, 0)
+ KitName = CommonTables.Classes.GetValue (ClassName, "NAME_REF")
Button.SetText(KitName)
if not EnabledButtons or i+TopIndex in EnabledButtons:
Button.SetState(IE_GUI_BUTTON_ENABLED)
@@ -190,7 +189,7 @@ def KitPress():
ButtonPressed=GemRB.GetVar("ButtonPressed")
KitSelected = ButtonPressed + TopIndex
if not KitTable:
- if ClassID == 1:
+ if ClassName == "MAGE":
# TODO: this seems to be never reached
Kit = GemRB.GetVar("MAGESCHOOL")
Kit = SchoolList.GetValue (Kit, 3)
@@ -198,19 +197,19 @@ def KitPress():
Kit = 0
else:
Kit = KitTable.GetValue (ButtonPressed+TopIndex, 0)
- if ClassID == 1:
+ if ClassName == "MAGE":
if ButtonPressed + TopIndex == 0:
Kit = 0
else:
Kit = ButtonPressed + TopIndex + 21
- if ClassID == 1 and Kit != 0:
+ if ClassName == "MAGE" and Kit != 0:
GemRB.SetVar("MAGESCHOOL", Kit-21) # hack: -21 to make the generalist 0
else:
GemRB.SetVar("MAGESCHOOL", 0) # so bards don't get schools
if Kit == 0:
- KitDescription = CommonTables.Classes.GetValue(GemRB.GetVar("Class")-1, 1)
+ KitDescription = CommonTables.Classes.GetValue (ClassName, "DESC_REF")
else:
KitDescription = CommonTables.KitList.GetValue(Kit, 3)
diff --git a/gemrb/GUIScripts/bg2/GUICG3.py b/gemrb/GUIScripts/bg2/GUICG3.py
index bc1886e..643d714 100644
--- a/gemrb/GUIScripts/bg2/GUICG3.py
+++ b/gemrb/GUIScripts/bg2/GUICG3.py
@@ -26,19 +26,16 @@ from GUIDefines import *
AlignmentWindow = 0
TextAreaControl = 0
DoneButton = 0
-AlignmentTable = 0
MyChar = 0
def OnLoad():
global AlignmentWindow, TextAreaControl, DoneButton
- global AlignmentTable, MyChar
+ global MyChar
MyChar = GemRB.GetVar ("Slot")
Kit = GUICommon.GetKitIndex (MyChar)
- Class = GemRB.GetPlayerStat (MyChar, IE_CLASS)
- Class = CommonTables.Classes.FindValue (5, Class)
if Kit == 0:
- KitName = CommonTables.Classes.GetRowName(Class)
+ KitName = GUICommon.GetClassRowName (MyChar)
else:
#rowname is just a number, first value row what we need here
KitName = CommonTables.KitList.GetValue(Kit, 0)
@@ -46,18 +43,18 @@ def OnLoad():
AlignmentOk = GemRB.LoadTable("ALIGNMNT")
GemRB.LoadWindowPack("GUICG", 640, 480)
- AlignmentTable = GemRB.LoadTable("aligns")
+ CommonTables.Aligns = CommonTables.Aligns
AlignmentWindow = GemRB.LoadWindow(3)
for i in range(9):
Button = AlignmentWindow.GetControl(i+2)
Button.SetFlags(IE_GUI_BUTTON_RADIOBUTTON,OP_OR)
Button.SetState(IE_GUI_BUTTON_DISABLED)
- Button.SetText(AlignmentTable.GetValue(i,0) )
+ Button.SetText (CommonTables.Aligns.GetValue (i,0))
for i in range(9):
Button = AlignmentWindow.GetControl(i+2)
- if AlignmentOk.GetValue(KitName, AlignmentTable.GetValue(i, 4) ) != 0:
+ if AlignmentOk.GetValue(KitName, CommonTables.Aligns.GetValue (i, 4)) != 0:
Button.SetState(IE_GUI_BUTTON_ENABLED)
Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, AlignmentPress)
Button.SetVarAssoc("Alignment", i)
@@ -80,9 +77,9 @@ def OnLoad():
def AlignmentPress():
Alignment = GemRB.GetVar("Alignment")
- TextAreaControl.SetText(AlignmentTable.GetValue(Alignment,1) )
+ TextAreaControl.SetText (CommonTables.Aligns.GetValue (Alignment, 1))
DoneButton.SetState(IE_GUI_BUTTON_ENABLED)
- GemRB.SetVar("Alignment",AlignmentTable.GetValue(Alignment,3) )
+ GemRB.SetVar ("Alignment", CommonTables.Aligns.GetValue (Alignment, 3))
return
def BackPress():
@@ -100,12 +97,11 @@ def NextPress():
# reputation
# alignment abilities
Alignment = GemRB.GetVar ("Alignment")
- AlignmentTable = GemRB.LoadTable ("aligns")
GemRB.SetPlayerStat (MyChar, IE_ALIGNMENT, Alignment)
# use the alignment to apply starting reputation
RepTable = GemRB.LoadTable ("repstart")
- AlignmentAbbrev = AlignmentTable.FindValue (3, Alignment)
+ AlignmentAbbrev = CommonTables.Aligns.FindValue (3, Alignment)
Rep = RepTable.GetValue (AlignmentAbbrev, 0) * 10
GemRB.SetPlayerStat (MyChar, IE_REPUTATION, Rep)
diff --git a/gemrb/GUIScripts/bg2/GUICG4.py b/gemrb/GUIScripts/bg2/GUICG4.py
index 5b4ab7f..6d1ae42 100644
--- a/gemrb/GUIScripts/bg2/GUICG4.py
+++ b/gemrb/GUIScripts/bg2/GUICG4.py
@@ -123,16 +123,15 @@ def OnLoad():
MyChar = GemRB.GetVar ("Slot")
Kit = GUICommon.GetKitIndex (MyChar)
- Class = GemRB.GetPlayerStat (MyChar, IE_CLASS)
- Class = CommonTables.Classes.FindValue (5, Class)
+ ClassName = GUICommon.GetClassRowName (MyChar)
if Kit == 0:
- KitName = CommonTables.Classes.GetRowName(Class)
+ KitName = ClassName
else:
#rowname is just a number, first value row what we need here
KitName = CommonTables.KitList.GetValue(Kit, 0)
#if the class uses the warrior table for saves, then it may have the extra strength
- if CommonTables.Classes.GetValue(Class, 3)=="SAVEWAR":
+ if CommonTables.Classes.GetValue(ClassName, "SAVE") == "SAVEWAR":
HasStrExtra=1
else:
HasStrExtra=0
diff --git a/gemrb/GUIScripts/bg2/GUICG7.py b/gemrb/GUIScripts/bg2/GUICG7.py
index 5e5a501..7fd3a3a 100644
--- a/gemrb/GUIScripts/bg2/GUICG7.py
+++ b/gemrb/GUIScripts/bg2/GUICG7.py
@@ -29,14 +29,15 @@ def OnLoad():
KitTable = GemRB.LoadTable("magesch")
Slot = GemRB.GetVar ("Slot")
Class = GemRB.GetPlayerStat (Slot, IE_CLASS)
- TableName = CommonTables.ClassSkills.GetValue(Class, 2)
+ ClassName = GUICommon.GetClassRowName (Class, "class")
+ TableName = CommonTables.ClassSkills.GetValue(ClassName, "MAGESPELL")
# make sure we have a correct table
if TableName == "*":
GemRB.SetNextScript("GUICG6")
return
if Class == 19:
- # sorcerer's need their known not max table
+ # sorcerers need their known not max table or they would progress too slowly
TableName = "SPLSRCKN"
# get our kit index
@@ -56,7 +57,8 @@ def OnLoad():
Level = GemRB.GetPlayerStat (Slot, IE_LEVEL)
if IsMulti[0]>1:
for i in range (1, IsMulti[0]):
- if CommonTables.ClassSkills.GetValue (IsMulti[i], 2, 0) != "*":
+ ClassName = GUICommon.GetClassRowName (IsMulti[i], "class")
+ if CommonTables.ClassSkills.GetValue (ClassName, "MAGESPELL", 0) != "*":
Level = GemRB.GetPlayerStat (Slot, IE_LEVEL2+i-1)
break
diff --git a/gemrb/GUIScripts/bg2/GUICG9.py b/gemrb/GUIScripts/bg2/GUICG9.py
index 3d7c7ff..ed5c99b 100644
--- a/gemrb/GUIScripts/bg2/GUICG9.py
+++ b/gemrb/GUIScripts/bg2/GUICG9.py
@@ -54,8 +54,8 @@ def OnLoad():
DoneButton.SetText(11973)
DoneButton.SetFlags(IE_GUI_BUTTON_DEFAULT,OP_OR)
DoneButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, NextPress)
- DoneButton.SetState(IE_GUI_BUTTON_DISABLED)
+ RedrawSkills()
SkillWindow.SetVisible(WINDOW_VISIBLE)
return
diff --git a/gemrb/GUIScripts/bg2/GUICommonWindows.py b/gemrb/GUIScripts/bg2/GUICommonWindows.py
deleted file mode 100644
index b8ca28c..0000000
--- a/gemrb/GUIScripts/bg2/GUICommonWindows.py
+++ /dev/null
@@ -1,903 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003-2004 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-
-# GUICommonWindows.py - functions to open common
-# windows in lower part of the screen
-###################################################
-
-import GemRB
-from GUIDefines import *
-from ie_stats import IE_MAXHITPOINTS, IE_STATE_ID, IE_HITPOINTS, STATE_DEAD
-from ie_modal import *
-from ie_action import *
-import GUICommon
-import CommonTables
-import LUCommon
-import InventoryCommon
-
-# needed for all the Open*Window callbacks in the OptionsWindow
-import GUIJRNL
-import GUIMA
-import GUIMG
-import GUIINV
-import GUIOPT
-import GUIPR
-import GUIREC
-
-FRAME_PC_SELECTED = 0
-FRAME_PC_TARGET = 1
-
-PortraitWindow = None
-OptionsWindow = None
-ActionsWindow = None
-DraggedPortrait = None
-
-def SetupMenuWindowControls (Window, Gears, ReturnToGame):
- """Sets up all of the basic control windows."""
-
- global OptionsWindow
-
- OptionsWindow = Window
- # Return to Game
- Button = Window.GetControl (0)
- Button.SetTooltip (16313)
- Button.SetVarAssoc ("SelectedWindow", 0)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, ReturnToGame)
- Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- # Map
- Button = Window.GetControl (1)
- Button.SetTooltip (16310)
- Button.SetVarAssoc ("SelectedWindow", 1)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIMA.OpenMapWindow)
-
- # Journal
- Button = Window.GetControl (2)
- Button.SetTooltip (16308)
- Button.SetVarAssoc ("SelectedWindow", 2)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIJRNL.OpenJournalWindow)
-
- # Inventory
- Button = Window.GetControl (3)
- Button.SetTooltip (16307)
- Button.SetVarAssoc ("SelectedWindow", 3)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIINV.OpenInventoryWindow)
-
- # Records
- Button = Window.GetControl (4)
- Button.SetTooltip (16306)
- Button.SetVarAssoc ("SelectedWindow", 4)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIREC.OpenRecordsWindow)
-
- # Mage
- Button = Window.GetControl (5)
- Button.SetTooltip (16309)
- Button.SetVarAssoc ("SelectedWindow", 5)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIMG.OpenMageWindow)
-
- # Priest
- Button = Window.GetControl (6)
- Button.SetTooltip (14930)
- Button.SetVarAssoc ("SelectedWindow", 6)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIPR.OpenPriestWindow)
-
- # Options
- Button = Window.GetControl (7)
- Button.SetTooltip (16311)
- Button.SetVarAssoc ("SelectedWindow", 7)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIOPT.OpenOptionsWindow)
-
- # Multi player team setup?
- Button = Window.GetControl (8)
- Button.SetTooltip (13902)
-
- if Gears:
- # Pendulum, gears, sun/moon dial (time)
- # FIXME: display all animations: CPEN, CGEAR, CDIAL
- Button = Window.GetControl (9)
- Label = Button.CreateLabelOnButton (0x10000009, "NORMAL", 0)
-
- Label.SetAnimation ("CPEN")
- Button.SetAnimation ("CGEAR")
- Button.SetBAM ("CDIAL", 0, 0)
- Button.SetState (IE_GUI_BUTTON_ENABLED)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_ANIMATED|IE_GUI_BUTTON_NORMAL, OP_SET)
- Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, GUICommon.GearsClicked)
- GUICommon.SetGamedaysAndHourToken()
- Button.SetTooltip(16041)
- rb = 11
- else:
- rb = 9
-
- # Rest
- Button = Window.GetControl (rb)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUICommon.RestPress)
- Button.SetTooltip (11942)
-
- if PortraitWindow:
- UpdatePortraitWindow ()
-
-def MarkMenuButton (WindowIndex):
- Pressed = WindowIndex.GetControl( GemRB.GetVar ("SelectedWindow") )
-
- for button in range (9):
- Button = WindowIndex.GetControl (button)
- Button.SetState (IE_GUI_BUTTON_ENABLED)
-
- if Pressed: # don't draw the selection when returning to the game
- Pressed.SetState (IE_GUI_BUTTON_SELECTED)
-
-def AIPress ():
- """Toggles the party AI."""
-
- Button = PortraitWindow.GetControl (6)
- AI = GemRB.GetMessageWindowSize () & GS_PARTYAI
-
- if AI:
- GemRB.GameSetScreenFlags (GS_PARTYAI, OP_NAND)
- Button.SetTooltip (15918)
- GemRB.SetVar ("AI", 0)
- else:
- GemRB.GameSetScreenFlags (GS_PARTYAI, OP_OR)
- Button.SetTooltip (15917)
- GemRB.SetVar ("AI", GS_PARTYAI)
- return
-
-def EmptyControls ():
- global ActionsWindow
-
- Selected = GemRB.GetSelectedSize()
- if Selected==1:
- pc = GemRB.GameGetFirstSelectedActor ()
- #init spell list
- GemRB.SpellCast (pc, -1, 0, 1)
-
- GemRB.SetVar ("ActionLevel", 0)
- Window = ActionsWindow
- for i in range (12):
- Button = Window.GetControl (i)
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- Button.SetPicture ("")
- Button.SetText ("")
- Button.SetActionIcon (globals(), -1)
- return
-
-def SelectFormationPreset ():
- """Choose the default formation."""
- GemRB.GameSetFormation (GemRB.GetVar ("Value"), GemRB.GetVar ("Formation") )
- GroupControls ()
- return
-
-def SetupFormation ():
- """Opens the formation selection section."""
- global ActionsWindow
-
- Window = ActionsWindow
- for i in range (12):
- Button = Window.GetControl (i)
- Button.SetFlags (IE_GUI_BUTTON_NORMAL, OP_SET)
- Button.SetSprites ("GUIBTBUT",0,0,1,2,3)
- Button.SetBAM ("FORM%x"%i,0,0,-1)
- Button.SetVarAssoc ("Value", i)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SelectFormationPreset)
- return
-
-def GroupControls ():
- """Sections that control group actions."""
-
- global ActionsWindow
-
- GemRB.SetVar ("ActionLevel", 0)
- Window = ActionsWindow
- Button = Window.GetControl (0)
- Button.SetActionIcon (globals(), 7)
- Button = Window.GetControl (1)
- Button.SetActionIcon (globals(), 15)
- Button = Window.GetControl (2)
- Button.SetActionIcon (globals(), 21)
- Button = Window.GetControl (3)
- Button.SetActionIcon (globals(), -1)
- Button = Window.GetControl (4)
- Button.SetActionIcon (globals(), -1)
- Button = Window.GetControl (5)
- Button.SetActionIcon (globals(), -1)
- Button = Window.GetControl (6)
- Button.SetActionIcon (globals(), -1)
- GemRB.SetVar ("Formation", GemRB.GameGetFormation ())
- for i in range (5):
- Button = Window.GetControl (7+i)
- Button.SetState (IE_GUI_BUTTON_ENABLED)
- idx = GemRB.GameGetFormation (i)
- Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON|IE_GUI_BUTTON_NORMAL, OP_SET)
- Button.SetSprites ("GUIBTBUT",0,0,1,2,3)
- Button.SetBAM ("FORM%x"%idx,0,0,-1)
- Button.SetVarAssoc ("Formation", i)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUICommon.SelectFormation)
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, SetupFormation)
- str = GemRB.GetString (4935)
- Button.SetTooltip ("F%d - %s"%(8+i,str) )
- return
-
-def OpenActionsWindowControls (Window):
- global ActionsWindow
-
- ActionsWindow = Window
- # Gears (time) when options pane is down
- Button = Window.GetControl (62)
- Label = Button.CreateLabelOnButton (0x1000003e, "NORMAL", 0)
-
- # FIXME: display all animations
- Label.SetAnimation ("CPEN")
- Button.SetAnimation ("CGEAR")
- Button.SetBAM ("CDIAL", 0, 0)
- Button.SetState (IE_GUI_BUTTON_ENABLED)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_ANIMATED|IE_GUI_BUTTON_NORMAL, OP_SET)
- Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, GUICommon.GearsClicked)
- GUICommon.SetGamedaysAndHourToken()
- Button.SetTooltip(16041)
- UpdateActionsWindow ()
- return
-
-def SelectItemAbility():
- pc = GemRB.GameGetFirstSelectedActor ()
- slot = GemRB.GetVar ("Slot")
- ability = GemRB.GetVar ("Ability")
- GemRB.SetupQuickSlot (pc, 0, slot, ability, 1)
- GemRB.SetVar ("ActionLevel", 0)
- return
-
-def SetupItemAbilities(pc, slot):
- Window = ActionsWindow
-
- slot_item = GemRB.GetSlotItem(pc, slot, 1)
- item = GemRB.GetItem (slot_item["ItemResRef"])
- Tips = item["Tooltips"]
-
- for i in range (12):
- Button = Window.GetControl (i)
- Button.SetPicture ("")
- if i<len(Tips):
- Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON|IE_GUI_BUTTON_NORMAL, OP_SET)
- Button.SetSprites ("GUIBTBUT",0,0,1,2,3)
- Button.SetItemIcon (slot_item['ItemResRef'], i+6)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SelectItemAbility)
- Button.SetVarAssoc ("Ability", i)
-
- Button.SetTooltip ("F%d - %s"%(i+1,GemRB.GetString(Tips[i])) )
- else:
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- return
-
-def UpdateActionsWindow ():
- """Redraws the actions section of the window."""
-
- global ActionsWindow, PortraitWindow, OptionsWindow
- global level, TopIndex
-
- if ActionsWindow == -1:
- return
-
- if ActionsWindow == None:
- return
-
- #fully redraw the side panes to cover the actions window
- #do this only when there is no 'otherwindow'
- if GemRB.GetVar ("OtherWindow") == -1:
- if PortraitWindow:
- PortraitWindow.Invalidate ()
- if OptionsWindow:
- OptionsWindow.Invalidate ()
-
- Selected = GemRB.GetSelectedSize()
-
- #setting up the disabled button overlay (using the second border slot)
- for i in range (12):
- Button = ActionsWindow.GetControl (i)
- Button.SetBorder (1, 0, 0, 0, 0, 50,30,10,120, 0, 1)
- Button.SetFont ("NUMBER")
- Button.SetText ("")
-
- if Selected == 0:
- EmptyControls ()
- return
- if Selected > 1:
- GroupControls ()
- return
-
- #we are sure there is only one actor selected
- pc = GemRB.GameGetFirstSelectedActor ()
-
- level = GemRB.GetVar ("ActionLevel")
- TopIndex = GemRB.GetVar ("TopIndex")
- if level == 0:
- #this is based on class
- ActionsWindow.SetupControls (globals(), pc, 0, 1)
- elif level == 1:
- ActionsWindow.SetupEquipmentIcons(globals(), pc, TopIndex, 0, 1)
- elif level == 2: #spells
- GemRB.SetVar ("Type", 3)
- ActionsWindow.SetupSpellIcons(globals(), pc, 3, TopIndex, 0, 1)
- elif level == 3: #innates
- GemRB.SetVar ("Type", 4)
- ActionsWindow.SetupSpellIcons(globals(), pc, 4, TopIndex, 0, 1)
- elif level == 4: #quick weapon/item ability selection
- SetupItemAbilities(pc, GemRB.GetVar("Slot") )
- elif level == 5: #all known mage spells
- GemRB.SetVar ("Type", -1)
- ActionsWindow.SetupSpellIcons(globals(), pc, -1, TopIndex, 0, 1)
- return
-
-def ActionQWeaponPressed (which):
- """Selects the given quickslot weapon if possible."""
-
- pc = GemRB.GameGetFirstSelectedActor ()
- qs = GemRB.GetEquippedQuickSlot (pc, 1, 1)
-
- #38 is the magic slot
- if ((qs==which) or (qs==38)) and GemRB.GameControlGetTargetMode() != TARGET_MODE_ATTACK:
- GemRB.GameControlSetTargetMode (TARGET_MODE_ATTACK, GA_NO_DEAD|GA_NO_SELF|GA_NO_HIDDEN)
- else:
- GemRB.GameControlSetTargetMode (TARGET_MODE_NONE)
- GemRB.SetEquippedQuickSlot (pc, which, -1, 1)
-
- ActionsWindow.SetupControls (globals(), pc, 0, 1)
- UpdateActionsWindow ()
- return
-
-def ActionQWeapon1Pressed ():
- ActionQWeaponPressed(0)
-
-def ActionQWeapon2Pressed ():
- ActionQWeaponPressed(1)
-
-def ActionQWeapon3Pressed ():
- ActionQWeaponPressed(2)
-
-def ActionQWeapon4Pressed ():
- ActionQWeaponPressed(3)
-
-#no check needed because the button wouldn't be drawn if illegal
-def ActionLeftPressed ():
- """Scrolls the actions window left.
-
- Used primarily for spell selection."""
-
- TopIndex = GemRB.GetVar ("TopIndex")
- if TopIndex>10:
- TopIndex -= 10
- else:
- TopIndex = 0
- GemRB.SetVar ("TopIndex", TopIndex)
- UpdateActionsWindow ()
- return
-
-#no check needed because the button wouldn't be drawn if illegal
-def ActionRightPressed ():
- """Scrolls the action window right.
-
- Used primarily for spell selection."""
-
- pc = GemRB.GameGetFirstSelectedActor ()
- TopIndex = GemRB.GetVar ("TopIndex")
- Type = GemRB.GetVar ("Type")
- #Type is a bitfield if there is no level given
- #This is to make sure cleric/mages get all spells listed
- if Type&128:
- Max = GemRB.GetKnownSpellsCount(pc, Type&127, -1, 1)
- else:
- Max = GemRB.GetMemorizedSpellsCount(pc, Type, -1, 1)
- TopIndex += 10
- if TopIndex > Max - 10:
- if Max>10:
- TopIndex = Max-10
- else:
- TopIndex = 0
- GemRB.SetVar ("TopIndex", TopIndex)
- UpdateActionsWindow ()
- return
-
-def ActionBardSongPressed ():
- """Toggles the battle song."""
- pc = GemRB.GameGetFirstSelectedActor ()
- GemRB.SetModalState (pc, MS_BATTLESONG, 1)
- GemRB.PlaySound ("act_01")
- UpdateActionsWindow ()
- return
-
-def ActionSearchPressed ():
- """Toggles detect traps."""
- pc = GemRB.GameGetFirstSelectedActor ()
- GemRB.SetModalState (pc, MS_DETECTTRAPS, 1)
- UpdateActionsWindow ()
- return
-
-def ActionStealthPressed ():
- """Toggles stealth."""
- pc = GemRB.GameGetFirstSelectedActor ()
- GemRB.SetModalState (pc, MS_STEALTH, 1)
- GemRB.PlaySound ("act_07")
- UpdateActionsWindow ()
- return
-
-def ActionTurnPressed ():
- """Toggles turn undead."""
- pc = GemRB.GameGetFirstSelectedActor ()
- GemRB.SetModalState (pc, MS_TURNUNDEAD, 1)
- GemRB.PlaySound ("act_06")
- UpdateActionsWindow ()
- return
-
-def ActionUseItemPressed ():
- GemRB.SetVar ("TopIndex", 0)
- GemRB.SetVar ("ActionLevel", 1)
- UpdateActionsWindow ()
- return
-
-def ActionCastPressed ():
- """Opens the spell choice scrollbar."""
- GemRB.SetVar ("TopIndex", 0)
- GemRB.SetVar ("ActionLevel", 2)
- UpdateActionsWindow ()
- return
-
-def ActionQItemPressed (action):
- """Uses the given quick item."""
- pc = GemRB.GameGetFirstSelectedActor ()
- #quick slot
- GemRB.UseItem (pc, -2, action, -1, 1)
- return
-
-def ActionQItem1Pressed ():
- ActionQItemPressed (ACT_QSLOT1)
- return
-
-def ActionQItem2Pressed ():
- ActionQItemPressed (ACT_QSLOT2)
- return
-
-def ActionQItem3Pressed ():
- ActionQItemPressed (ACT_QSLOT3)
- return
-
-def ActionQItem4Pressed ():
- ActionQItemPressed (ACT_QSLOT4)
- return
-
-def ActionQItem5Pressed ():
- ActionQItemPressed (ACT_QSLOT5)
- return
-
-def ActionQItemRightPressed (action):
- """Selects the used ability of the quick item."""
- pc = GemRB.GameGetFirstSelectedActor ()
- GemRB.SetVar ("Slot", action)
- GemRB.SetVar ("ActionLevel", 4)
- UpdateActionsWindow ()
- return
-
-def ActionQItem1RightPressed ():
- ActionQItemRightPressed (19)
-
-def ActionQItem2RightPressed ():
- ActionQItemRightPressed (20)
-
-def ActionQItem3RightPressed ():
- ActionQItemRightPressed (21)
-
-def ActionQItem4RightPressed ():
- ActionQItemRightPressed (22)
-
-def ActionQItem5RightPressed ():
- ActionQItemRightPressed (23)
-
-def ActionQWeapon1RightPressed ():
- ActionQItemRightPressed (10)
-
-def ActionQWeapon2RightPressed ():
- ActionQItemRightPressed (11)
-
-def ActionQWeapon3RightPressed ():
- ActionQItemRightPressed (12)
-
-def ActionQWeapon4RightPressed ():
- ActionQItemRightPressed (13)
-
-def ActionInnatePressed ():
- """Opens the innate spell scrollbar."""
- GemRB.SetVar ("TopIndex", 0)
- GemRB.SetVar ("ActionLevel", 3)
- UpdateActionsWindow ()
- return
-
-def SpellPressed ():
- """Prepares a spell to be cast."""
-
- pc = GemRB.GameGetFirstSelectedActor ()
-
- GemRB.GameControlSetTargetMode (TARGET_MODE_CAST)
- Spell = GemRB.GetVar ("Spell")
- Type = GemRB.GetVar ("Type")
- if Type==-1:
- GemRB.SetVar ("ActionLevel", 0)
- GemRB.SetVar("Type", 0)
- GemRB.SpellCast (pc, Type, Spell, 1)
- if GemRB.GetVar ("Type")!=-1:
- GemRB.SetVar ("ActionLevel", 0)
- #init spell list
- GemRB.SpellCast (pc, -1, 0, 1)
- GemRB.SetVar ("TopIndex", 0)
- UpdateActionsWindow ()
- return
-
-def EquipmentPressed ():
- pc = GemRB.GameGetFirstSelectedActor ()
-
- GemRB.GameControlSetTargetMode (TARGET_MODE_CAST)
- Item = GemRB.GetVar ("Equipment")
- #equipment index
- GemRB.UseItem (pc, -1, Item, -1, 1)
- GemRB.SetVar ("ActionLevel", 0)
- UpdateActionsWindow ()
- return
-
-SelectionChangeHandler = None
-
-def SetSelectionChangeHandler (handler):
- """Updates the selection handler."""
-
- global SelectionChangeHandler
-
- # Switching from walking to non-walking environment:
- # set the first selected PC in walking env as a selected
- # in nonwalking env
- #if (not SelectionChangeHandler) and handler:
- if (not SelectionChangeHandler) and handler and (not GUICommon.NextWindowFn):
- sel = GemRB.GameGetFirstSelectedPC ()
- if not sel:
- sel = 1
- GemRB.GameSelectPCSingle (sel)
-
- SelectionChangeHandler = handler
-
- # redraw selection on change main selection | single selection
- SelectionChanged ()
- return
-
-def RunSelectionChangeHandler ():
- if SelectionChangeHandler:
- SelectionChangeHandler ()
- return
-
-def OpenPortraitWindow (needcontrols):
- global PortraitWindow
-
- PortraitWindow = Window = GemRB.LoadWindow (1)
-
- if needcontrols:
- Button=Window.GetControl (8)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, MinimizePortraits)
-
- # AI
- Button = Window.GetControl (6)
- #fixing a gui bug, and while we are at it, hacking it to be easier
- Button.SetSprites ("GUIBTACT", 0, 48, 47, 46, 49)
- GSFlags = GemRB.GetMessageWindowSize ()&GS_PARTYAI
-
- GemRB.SetVar ("AI", GSFlags)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, AIPress)
- Button.SetFlags (IE_GUI_BUTTON_CHECKBOX, OP_OR)
- Button.SetVarAssoc ("AI", 1)
- if GSFlags:
- Button.SetTooltip (15917)
- else:
- Button.SetTooltip (15918)
-
- #Select All
- Button = Window.GetControl (7)
- Button.SetTooltip (10485)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUICommon.SelectAllOnPress)
-
- for i in range (PARTY_SIZE):
- Button = Window.GetControl (i)
- Button.SetFont ("STATES2")
- Button.SetVarAssoc ("PressedPortrait", i+1)
-
- if (needcontrols):
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, GUIINV.OpenInventoryWindowClick)
- else:
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, PortraitButtonOnPress)
-
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, PortraitButtonOnPress)
- Button.SetEvent (IE_GUI_BUTTON_ON_SHIFT_PRESS, PortraitButtonOnShiftPress)
- Button.SetEvent (IE_GUI_BUTTON_ON_DRAG_DROP, InventoryCommon.OnDropItemToPC)
- Button.SetEvent (IE_GUI_BUTTON_ON_DRAG_DROP_PORTRAIT, OnDropPortraitToPC)
- Button.SetEvent (IE_GUI_BUTTON_ON_DRAG, PortraitButtonOnDrag)
- Button.SetEvent (IE_GUI_MOUSE_ENTER_BUTTON, PortraitButtonOnMouseEnter)
- Button.SetEvent (IE_GUI_MOUSE_LEAVE_BUTTON, PortraitButtonOnMouseLeave)
-
- Button.SetBorder (FRAME_PC_SELECTED, 1, 1, 2, 2, 0, 255, 0, 255)
- Button.SetBorder (FRAME_PC_TARGET, 3, 3, 4, 4, 255, 255, 0, 255)
-
- UpdatePortraitWindow ()
- SelectionChanged ()
- return Window
-
-def UpdatePortraitWindow ():
- """Updates all of the portraits."""
-
- Window = PortraitWindow
-
- pc = GemRB.GameGetSelectedPCSingle ()
- Inventory = GemRB.GetVar ("Inventory")
-
- for portid in range (PARTY_SIZE):
- Button = Window.GetControl (portid)
- pic = GemRB.GetPlayerPortrait (portid+1, 1)
- if Inventory and pc != portid+1:
- pic = None
-
- if pic and GemRB.GetPlayerStat(portid+1, IE_STATE_ID) & STATE_DEAD:
- import GUISTORE
- # dead pcs are hidden in all stores but temples
- if GUISTORE.StoreWindow and not GUISTORE.StoreHealWindow:
- pic = None
-
- if not pic:
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- Button.SetText ("")
- Button.SetTooltip ("")
- continue
-
- Button.SetFlags (IE_GUI_BUTTON_PICTURE| IE_GUI_BUTTON_HORIZONTAL| \
- IE_GUI_BUTTON_ALIGN_LEFT| IE_GUI_BUTTON_ALIGN_TOP| \
- IE_GUI_BUTTON_DRAGGABLE|IE_GUI_BUTTON_MULTILINE, OP_SET)
-
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- Button.SetPicture (pic, "NOPORTSM")
- GUICommon.SetupDamageInfo (portid+1, Button)
-
- #add effects on the portrait
- effects = GemRB.GetPlayerStates (portid+1)
- states = ""
- for col in range(len(effects)):
- states = effects[col:col+1] + states
- if col % 3 == 2: states = "\n" + states
- for x in range(3 - (len(effects)/3)):
- states = "\n" + states
- states = "\n" + states
-
- # blank space
- flag = blank = chr(238)
-
- # shopping icon
- if pc==portid+1:
- if GemRB.GetStore()!=None:
- flag = chr(155)
- # talk icon
- if GemRB.GameGetSelectedPCSingle(1)==portid+1:
- flag = chr(154)
-
- if LUCommon.CanLevelUp (portid+1):
- states = flag+blank+chr(255) + states
- else:
- states = flag+blank+blank + states
- Button.SetText(states)
- return
-
-def PortraitButtonOnDrag ():
- global DraggedPortrait
-
- #they start from 1
- DraggedPortrait = GemRB.GetVar ("PressedPortrait")
- GemRB.DragItem (DraggedPortrait, -1, "")
- return
-
-def PortraitButtonOnPress ():
- """Selects the portrait individually."""
-
- i = GemRB.GetVar ("PressedPortrait")
-
- if not i:
- return
-
- if GemRB.GameControlGetTargetMode() != TARGET_MODE_NONE:
- GemRB.ActOnPC (i)
- return
-
- if (not SelectionChangeHandler):
- if GemRB.GameIsPCSelected (i):
- GemRB.GameControlSetScreenFlags (SF_CENTERONACTOR, OP_OR)
- GemRB.GameSelectPC (i, True, SELECT_REPLACE)
- else:
- GemRB.GameSelectPCSingle (i)
- SelectionChanged ()
- RunSelectionChangeHandler ()
- return
-
-def PortraitButtonOnShiftPress ():
- """Handles selecting multiple portaits with shift."""
-
- i = GemRB.GetVar ("PressedPortrait")
-
- if not i:
- return
-
- if (not SelectionChangeHandler):
- sel = GemRB.GameIsPCSelected (i)
- sel = not sel
- GemRB.GameSelectPC (i, sel)
- else:
- GemRB.GameSelectPCSingle (i)
- SelectionChanged ()
- RunSelectionChangeHandler ()
- return
-
-def SelectionChanged ():
- """Ran by the Game class when a PC selection is changed."""
-
- global PortraitWindow
-
- if not PortraitWindow:
- return
-
- GemRB.SetVar ("ActionLevel", 0)
- if (not SelectionChangeHandler):
- UpdateActionsWindow ()
- for i in range (PARTY_SIZE):
- Button = PortraitWindow.GetControl (i)
- Button.EnableBorder (FRAME_PC_SELECTED, GemRB.GameIsPCSelected (i + 1))
- else:
- sel = GemRB.GameGetSelectedPCSingle ()
-
- #update mage school
- GemRB.SetVar ("MAGESCHOOL", 0)
- Kit = GUICommon.GetKitIndex (sel)
- if Kit and CommonTables.KitList.GetValue (Kit, 7) == 1:
- MageTable = GemRB.LoadTable ("magesch")
- GemRB.SetVar ("MAGESCHOOL", MageTable.FindValue (3, CommonTables.KitList.GetValue (Kit, 6) ) )
-
- for i in range (PARTY_SIZE):
- Button = PortraitWindow.GetControl (i)
- Button.EnableBorder (FRAME_PC_SELECTED, i + 1 == sel)
- import CommonWindow
- CommonWindow.CloseContainerWindow()
- return
-
-def PortraitButtonOnMouseEnter ():
- global DraggedPortrait
-
- i = GemRB.GetVar ("PressedPortrait")
-
- if not i:
- return
-
- GemRB.GameControlSetLastActor( i )
- if GemRB.IsDraggingItem()==2:
- if DraggedPortrait != None:
- GemRB.SwapPCs (DraggedPortrait, i)
- GemRB.SetVar ("PressedPortrait", DraggedPortrait)
- DraggedPortrait = i
- GemRB.SetTimedEvent (CheckDragging, 1)
- else:
- OnDropPortraitToPC()
- return
-
- if GemRB.IsDraggingItem ():
- Button = PortraitWindow.GetControl (i-1)
- Button.EnableBorder (FRAME_PC_TARGET, 1)
- return
-
-def OnDropPortraitToPC ():
- GemRB.SetVar ("PressedPortrait",0)
- GemRB.DragItem (0, -1, "")
- DraggedPortrait = None
- return
-
-def CheckDragging():
- """Contains portrait dragging in case of mouse out-of-range."""
-
- global DraggedPortrait
-
- i = GemRB.GetVar ("PressedPortrait")
- if not i:
- GemRB.DragItem (0, -1, "")
-
- if GemRB.IsDraggingItem()!=2:
- DraggedPortrait = None
- return
-
-def PortraitButtonOnMouseLeave ():
- i = GemRB.GetVar ("PressedPortrait")
- if not i:
- return
-
- Button = PortraitWindow.GetControl (i-1)
- Button.EnableBorder (FRAME_PC_TARGET, 0)
- GemRB.SetVar ("PressedPortrait", 0)
- GemRB.SetTimedEvent (CheckDragging, 1)
- return
-
-def ActionStopPressed ():
- for i in GemRB.GetSelectedActors():
- GemRB.ClearActions (i, 1)
- return
-
-def ActionTalkPressed ():
- GemRB.GameControlSetTargetMode (TARGET_MODE_TALK,GA_NO_DEAD|GA_NO_ENEMY|GA_NO_HIDDEN)
-
-def ActionAttackPressed ():
- GemRB.GameControlSetTargetMode (TARGET_MODE_ATTACK,GA_NO_DEAD|GA_NO_SELF|GA_NO_HIDDEN)
-
-def ActionDefendPressed ():
- GemRB.GameControlSetTargetMode (TARGET_MODE_DEFEND,GA_NO_SELF|GA_NO_ENEMY|GA_NO_HIDDEN)
-
-def ActionThievingPressed ():
- GemRB.GameControlSetTargetMode (TARGET_MODE_PICK, GA_NO_DEAD|GA_NO_SELF|GA_NO_ENEMY|GA_NO_HIDDEN)
-
-def MinimizePortraits():
- GemRB.GameSetScreenFlags(GS_PORTRAITPANE, OP_OR)
-
-def OpenWaitForDiscWindow ():
- global DiscWindow
-
- if DiscWindow:
- GemRB.HideGUI ()
- if DiscWindow:
- DiscWindow.Unload ()
- GemRB.SetVar ("OtherWindow", -1)
- # ...LoadWindowPack()
- EnableAnimatedWindows ()
- DiscWindow = None
- GemRB.UnhideGUI ()
- return
-
- try:
- GemRB.HideGUI ()
- except:
- pass
-
- GemRB.LoadWindowPack ("GUIID")
- DiscWindow = Window = GemRB.LoadWindow (0)
- GemRB.SetVar ("OtherWindow", Window.ID)
- label = DiscWindow.GetControl (0)
-
- disc_num = GemRB.GetVar ("WaitForDisc")
- #disc_path = GemRB.GetVar ("WaitForDiscPath")
- disc_path = 'XX:'
-
- text = GemRB.GetString (31483) + " " + str (disc_num) + " " + GemRB.GetString (31569) + " " + disc_path + "\n" + GemRB.GetString (49152)
- label.SetText (text)
- DisableAnimatedWindows ()
- # 31483 - Please place PS:T disc number
- # 31568 - Please place the PS:T DVD
- # 31569 - in drive
- # 31570 - Wrong disc in drive
- # 31571 - There is no disc in drive
- # 31578 - No disc could be found in drive. Please place Disc 1 in drive.
- # 49152 - To quit the game, press Alt-F4
-
- try:
- GemRB.UnhideGUI ()
- except:
- DiscWindow.SetVisible (WINDOW_VISIBLE)
-
-def CheckLevelUp(pc):
- GemRB.SetVar ("CheckLevelUp"+str(pc), LUCommon.CanLevelUp (pc))
diff --git a/gemrb/GUIScripts/bg2/GUIINV.py b/gemrb/GUIScripts/bg2/GUIINV.py
index 633584b..026039a 100644
--- a/gemrb/GUIScripts/bg2/GUIINV.py
+++ b/gemrb/GUIScripts/bg2/GUIINV.py
@@ -129,8 +129,12 @@ def OpenInventoryWindow ():
Button.SetEvent (IE_GUI_BUTTON_ON_DRAG_DROP, InventoryCommon.OnAutoEquip)
#encumbrance
- Label = Window.CreateLabel (0x10000043, 5,385,60,20,"NUMBER","0:",IE_FONT_ALIGN_LEFT|IE_FONT_ALIGN_TOP)
- Label = Window.CreateLabel (0x10000044, 5,455,60,20,"NUMBER","0:",IE_FONT_ALIGN_RIGHT|IE_FONT_ALIGN_TOP)
+ Button = Window.GetControl (67)
+ r = Button.GetRect ()
+ Label = Window.CreateLabel (0x10000043, r["X"],r["Y"],r["Width"],20,
+ "NUMBER","0:",IE_FONT_ALIGN_LEFT|IE_FONT_ALIGN_TOP)
+ Label = Window.CreateLabel (0x10000044, r["X"],r["Y"]+r["Height"]-20,r["Width"],20,
+ "NUMBER","0:",IE_FONT_ALIGN_RIGHT|IE_FONT_ALIGN_BOTTOM)
#armor class
Label = Window.GetControl (0x10000038)
@@ -176,9 +180,7 @@ def UpdateInventoryWindow ():
pc = GemRB.GameGetSelectedPCSingle ()
Container = GemRB.GetContainer (pc, 1)
ScrollBar = Window.GetControl (66)
- Count = Container['ItemCount']
- if Count<1:
- Count=1
+ Count = max (0, Container['ItemCount'] - 5)
ScrollBar.SetVarAssoc ("TopIndex", Count)
RefreshInventoryWindow ()
#populate inventory slot controls
@@ -247,9 +249,6 @@ def RefreshInventoryWindow ():
#armor class
ac = GemRB.GetPlayerStat (pc, IE_ARMORCLASS)
- #temporary solution, the dexterity bonus should be handled by the core
- #some ac bonuses are not cummulative with this AC bonus!
- ac += GemRB.GetAbilityBonus (IE_DEX, 2, GemRB.GetPlayerStat (pc, IE_DEX) )
Label = Window.GetControl (0x10000038)
Label.SetText (str (ac))
Label.SetTooltip (10339)
@@ -289,7 +288,7 @@ def RefreshInventoryWindow ():
for i in range (5):
Button = Window.GetControl (i+68)
if GemRB.IsDraggingItem ()==1:
- Button.SetState (IE_GUI_BUTTON_SECOND)
+ Button.SetState (IE_GUI_BUTTON_FAKEPRESSED)
else:
Button.SetState (IE_GUI_BUTTON_ENABLED)
Button.SetEvent (IE_GUI_BUTTON_ON_DRAG_DROP, InventoryCommon.OnDragItemGround)
@@ -307,11 +306,7 @@ def RefreshInventoryWindow ():
GUICommon.UpdateInventorySlot (pc, Button, Slot, "ground")
#making window visible/shaded depending on the pc's state
- held = GemRB.GetPlayerStat (pc, IE_HELD) + GemRB.GetPlayerStat (pc, IE_CASTERHOLD)
- if held or GemRB.GetPlayerStat (pc, IE_STATE_ID) & STATE_DEAD:
- Window.SetVisible (WINDOW_GRAYED)
- else:
- Window.SetVisible (WINDOW_VISIBLE)
+ GUICommon.AdjustWindowVisibility (Window, pc, False)
return
###################################################
diff --git a/gemrb/GUIScripts/bg2/GUILOAD.py b/gemrb/GUIScripts/bg2/GUILOAD.py
deleted file mode 100644
index 12049ee..0000000
--- a/gemrb/GUIScripts/bg2/GUILOAD.py
+++ /dev/null
@@ -1,173 +0,0 @@
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-#
-#load window
-import GemRB
-import LoadScreen
-
-LoadWindow = 0
-TextAreaControl = 0
-Games = ()
-ScrollBar = 0
-
-def OnLoad():
- global LoadWindow, TextAreaControl, Games, ScrollBar
-
- GemRB.LoadWindowPack("GUILOAD", 640, 480)
- LoadWindow = GemRB.LoadWindow(0)
- LoadWindow.SetFrame ()
- CancelButton=LoadWindow.GetControl(34)
- CancelButton.SetText(13727)
- CancelButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, CancelPress)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
- GemRB.SetVar("LoadIdx",0)
-
- for i in range(4):
- Button = LoadWindow.GetControl(26+i)
- Button.SetText(15590)
- Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, LoadGamePress)
- Button.SetState(IE_GUI_BUTTON_DISABLED)
- Button.SetVarAssoc("LoadIdx",i)
-
- Button = LoadWindow.GetControl(30+i)
- Button.SetText(13957)
- Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, DeleteGamePress)
- Button.SetState(IE_GUI_BUTTON_DISABLED)
- Button.SetVarAssoc("LoadIdx",i)
-
- #area previews
- Button = LoadWindow.GetControl(1+i)
- Button.SetState(IE_GUI_BUTTON_LOCKED)
- Button.SetFlags(IE_GUI_BUTTON_NO_IMAGE|IE_GUI_BUTTON_PICTURE,OP_SET)
-
- #PC portraits
- for j in range(PARTY_SIZE):
- Button = LoadWindow.GetControl(40+i*PARTY_SIZE+j)
- Button.SetState(IE_GUI_BUTTON_LOCKED)
- Button.SetFlags(IE_GUI_BUTTON_NO_IMAGE|IE_GUI_BUTTON_PICTURE,OP_SET)
-
- ScrollBar=LoadWindow.GetControl(25)
- ScrollBar.SetEvent(IE_GUI_SCROLLBAR_ON_CHANGE, ScrollBarPress)
- Games=GemRB.GetSaveGames()
- TopIndex = max (0, len(Games) - 4)
- GemRB.SetVar ("TopIndex",TopIndex)
- ScrollBar.SetVarAssoc ("TopIndex", TopIndex+1)
- ScrollBarPress ()
- LoadWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def ScrollBarPress():
- #draw load game portraits
- Pos = GemRB.GetVar("TopIndex")
- for i in range(4):
- ActPos = Pos + i
-
- Button1 = LoadWindow.GetControl(26+i)
- Button2 = LoadWindow.GetControl(30+i)
- if ActPos<len(Games):
- Button1.SetState(IE_GUI_BUTTON_ENABLED)
- Button2.SetState(IE_GUI_BUTTON_ENABLED)
- else:
- Button1.SetState(IE_GUI_BUTTON_DISABLED)
- Button2.SetState(IE_GUI_BUTTON_DISABLED)
-
- if ActPos<len(Games):
- Slotname = Games[ActPos].GetName()
- else:
- Slotname = ""
- Label = LoadWindow.GetControl(0x10000008+i)
- Label.SetText(Slotname)
-
- if ActPos<len(Games):
- Slotname = Games[ActPos].GetGameDate()
- else:
- Slotname = ""
- Label = LoadWindow.GetControl(0x10000010+i)
- Label.SetText(Slotname)
-
- Button=LoadWindow.GetControl(1+i)
- if ActPos<len(Games):
- Button.SetSprite2D(Games[ActPos].GetPreview())
- else:
- Button.SetPicture("")
- for j in range(PARTY_SIZE):
- Button=LoadWindow.GetControl(40+i*PARTY_SIZE+j)
- if ActPos<len(Games):
- Button.SetSprite2D(Games[ActPos].GetPortrait(j))
- else:
- Button.SetPicture("")
- return
-
-def LoadGamePress():
- if LoadWindow:
- LoadWindow.Unload()
- Pos = GemRB.GetVar("TopIndex")+GemRB.GetVar("LoadIdx")
- LoadScreen.StartLoadScreen()
- #loads savegame
- GemRB.LoadGame(Games[Pos])
- #performs conversion to ToB
- if (GemRB.GetVar("oldgame")==0) and GemRB.GetVar("expansion")==1:
- GemRB.GameSetExpansion()
-
- #enters game
- GemRB.EnterGame() #it will close windows, including the loadscreen
- return
-
-def DeleteGameConfirm():
- global Games
-
- TopIndex = GemRB.GetVar("TopIndex")
- Pos = TopIndex +GemRB.GetVar("LoadIdx")
- GemRB.DeleteSaveGame(Games[Pos])
- if TopIndex>0:
- GemRB.SetVar("TopIndex",TopIndex-1)
- del Games[Pos]
- ScrollBar.SetVarAssoc("TopIndex", len(Games))
- ScrollBarPress()
- if ConfirmWindow:
- ConfirmWindow.Unload()
- LoadWindow.SetVisible(WINDOW_VISIBLE)
- return
-
-def DeleteGameCancel():
- if ConfirmWindow:
- ConfirmWindow.Unload()
- LoadWindow.SetVisible(WINDOW_VISIBLE)
- return
-
-def DeleteGamePress():
- global ConfirmWindow
-
- LoadWindow.SetVisible(WINDOW_INVISIBLE)
- ConfirmWindow=GemRB.LoadWindow(1)
- Text=ConfirmWindow.GetControl(0)
- Text.SetText(15305)
- DeleteButton=ConfirmWindow.GetControl(1)
- DeleteButton.SetText(13957)
- DeleteButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, DeleteGameConfirm)
- CancelButton=ConfirmWindow.GetControl(2)
- CancelButton.SetText(13727)
- CancelButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, DeleteGameCancel)
- ConfirmWindow.SetVisible(WINDOW_VISIBLE)
- return
-
-def CancelPress():
- if LoadWindow:
- LoadWindow.Unload()
- GemRB.SetNextScript("Start")
- return
diff --git a/gemrb/GUIScripts/bg2/GUIMA.py b/gemrb/GUIScripts/bg2/GUIMA.py
index d4ccd1b..36439e4 100644
--- a/gemrb/GUIScripts/bg2/GUIMA.py
+++ b/gemrb/GUIScripts/bg2/GUIMA.py
@@ -130,7 +130,7 @@ def ShowMap ():
OptionsWindow.SetVisible (WINDOW_FRONT)
PortraitWindow.SetVisible (WINDOW_FRONT)
Window.SetVisible (WINDOW_FRONT)
- Map.SetStatus (IE_GUI_CONTROL_FOCUSED)
+ Map.SetStatus (IE_GUI_CONTROL_FOCUSED| IE_GUI_MAP_REVEAL_MAP)
GemRB.GamePause (0,0)
return
@@ -198,7 +198,7 @@ def OpenMapWindow ():
OptionsWindow.SetVisible (WINDOW_VISIBLE)
Window.SetVisible (WINDOW_VISIBLE)
PortraitWindow.SetVisible (WINDOW_VISIBLE)
- Map.SetStatus (IE_GUI_CONTROL_FOCUSED)
+ Map.SetStatus (IE_GUI_CONTROL_FOCUSED | IE_GUI_MAP_VIEW_NOTES)
return
def LeftDoublePressMap ():
@@ -287,12 +287,17 @@ def MoveToNewArea ():
global WorldMapWindow, WorldMapControl
tmp = WorldMapControl.GetDestinationArea (1)
- if tmp["Distance"]==-1:
+ CloseWorldMapWindow ()
+
+ if tmp["Destination"].lower() == GemRB.GetGameString(STR_AREANAME).lower():
+ return
+ elif tmp["Distance"] == -1:
print "Invalid target", tmp
return
- CloseWorldMapWindow ()
GemRB.CreateMovement (tmp["Destination"], tmp["Entrance"], tmp["Direction"])
+ # distance is stored in hours, but the action needs seconds
+ GemRB.ExecuteString ("AdvanceTime(%d)"%(tmp["Distance"]*300))
return
def ChangeTooltip ():
@@ -300,7 +305,7 @@ def ChangeTooltip ():
global str
tmp = WorldMapControl.GetDestinationArea ()
- if (tmp):
+ if tmp and tmp["Distance"] >= 0:
str = "%s: %d"%(GemRB.GetString(23084),tmp["Distance"])
else:
str=""
@@ -392,6 +397,7 @@ def WorldMapWindowCommon (Travel):
Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
Window.SetVisible (WINDOW_VISIBLE)
MapC()
+ WorldMapControl.SetStatus (IE_GUI_CONTROL_FOCUSED)
return
def MapN():
diff --git a/gemrb/GUIScripts/bg2/GUIMG.py b/gemrb/GUIScripts/bg2/GUIMG.py
index 4299be0..ec176a7 100644
--- a/gemrb/GUIScripts/bg2/GUIMG.py
+++ b/gemrb/GUIScripts/bg2/GUIMG.py
@@ -92,8 +92,9 @@ def SetupMageWindow ():
global BookType
pc = GemRB.GameGetSelectedPCSingle ()
+ ClassName = GUICommon.GetClassRowName (pc)
BookType = 0
- if (CommonTables.ClassSkills.GetValue (GemRB.GetPlayerStat (pc, IE_CLASS), 8)==2):
+ if CommonTables.ClassSkills.GetValue (ClassName, "BOOKTYPE") == 2:
BookType = 1
if MageWindow:
@@ -121,9 +122,6 @@ def SetupMageWindow ():
Button = Window.GetControl (56 + i)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, RefreshMageLevel)
Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
-
- for i in range (9):
- Button = Window.GetControl (56 + i)
Button.SetVarAssoc ("MageSpellLevel", i)
# Setup memorized spells buttons
@@ -132,13 +130,13 @@ def SetupMageWindow ():
Button = Window.GetControl (3 + i)
Button.SetBorder (0,0,0,0,0,0,0,0,64,0,1)
Button.SetSprites ("SPELFRAM",0,0,0,0,0)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_OR)
+ Button.SetFlags (IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_PLAYONCE, OP_OR)
Button.SetState (IE_GUI_BUTTON_LOCKED)
# Setup book spells buttons
for i in range (24):
Button = Window.GetControl (27 + i)
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_OR)
+ Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE | IE_GUI_BUTTON_PLAYONCE, OP_OR)
Button.SetState (IE_GUI_BUTTON_LOCKED)
UpdateMageWindow ()
@@ -169,7 +167,8 @@ def UpdateMageWindow ():
Label.SetText (Name)
known_cnt = GemRB.GetKnownSpellsCount (pc, type, level)
- mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level)
+ mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level, False)
+ true_mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level, True)
if not BookType:
for i in range (12):
Button = Window.GetControl (3 + i)
@@ -177,20 +176,23 @@ def UpdateMageWindow ():
ms = GemRB.GetMemorizedSpell (pc, type, level, i)
Button.SetSpellIcon (ms['SpellResRef'], 0)
Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_NAND)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_OR)
+ Button.SetFlags (IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_PLAYONCE, OP_OR)
if ms['Flags']:
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenMageSpellUnmemorizeWindow)
else:
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OnMageUnmemorizeSpell)
Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, OpenMageSpellInfoWindow)
- spell = GemRB.GetSpell (ms['SpellResRef'])
- Button.SetTooltip (spell['SpellName'])
MageMemorizedSpellList.append (ms['SpellResRef'])
Button.SetVarAssoc ("SpellButton", i)
Button.EnableBorder (0, ms['Flags'] == 0)
+ spell = GemRB.GetSpell (ms['SpellResRef'])
+ if not spell:
+ print "Missing memorised spell!", ms['SpellResRef']
+ continue
+ Button.SetTooltip (spell['SpellName'])
else:
if i < max_mem_cnt:
- Button.SetFlags (IE_GUI_BUTTON_NORMAL, OP_SET)
+ Button.SetFlags (IE_GUI_BUTTON_NORMAL | IE_GUI_BUTTON_PLAYONCE, OP_SET)
else:
Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, None)
@@ -201,7 +203,7 @@ def UpdateMageWindow ():
label = Window.GetControl (0x10000040)
if known_cnt:
# we give sorcerers all charges for all the spells, so some extra math is needed
- label.SetText (GemRB.GetString(61256) + " " + str(mem_cnt/known_cnt) + "/" + str(max_mem_cnt))
+ label.SetText (GemRB.GetString(61256) + " " + str(true_mem_cnt/known_cnt) + "/" + str(max_mem_cnt))
else:
label.SetText ("")
@@ -212,10 +214,13 @@ def UpdateMageWindow ():
Button.SetSpellIcon (ks['SpellResRef'], 0)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OnMageMemorizeSpell)
Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, OpenMageSpellInfoWindow)
- spell = GemRB.GetSpell (ks['SpellResRef'])
- Button.SetTooltip (spell['SpellName'])
MageKnownSpellList.append (ks['SpellResRef'])
Button.SetVarAssoc ("SpellButton", 100 + i)
+ spell = GemRB.GetSpell (ks['SpellResRef'])
+ if not spell:
+ print "Missing known spell!", ms['SpellResRef']
+ continue
+ Button.SetTooltip (spell['SpellName'])
else:
Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_NAND)
@@ -224,11 +229,8 @@ def UpdateMageWindow ():
Button.SetTooltip ('')
Button.EnableBorder (0, 0)
- if (CommonTables.ClassSkills.GetValue (GemRB.GetPlayerStat (pc, IE_CLASS), 2)=="*") or \
- GemRB.GetPlayerStat (pc, IE_STATE_ID) & STATE_DEAD:
- Window.SetVisible (WINDOW_GRAYED)
- else:
- Window.SetVisible (WINDOW_VISIBLE)
+ CantCast = CommonTables.ClassSkills.GetValue (GUICommon.GetClassRowName(pc), "MAGESPELL") == "*"
+ GUICommon.AdjustWindowVisibility (Window, pc, CantCast)
return
def MagePrevLevelPress ():
@@ -308,6 +310,12 @@ def OnMageMemorizeSpell ():
if GemRB.MemorizeSpell (pc, type, level, index):
UpdateMageWindow ()
+ GemRB.PlaySound ("GAM_24")
+ Button = MageWindow.GetControl(index + 27)
+ Button.SetAnimation ("FLASH")
+ mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level, False)
+ Button = MageWindow.GetControl(mem_cnt + 2)
+ Button.SetAnimation ("FLASH")
return
def CloseMageSpellUnmemorizeWindow ():
@@ -378,6 +386,9 @@ def OnMageUnmemorizeSpell ():
if GemRB.UnmemorizeSpell (pc, type, level, index):
UpdateMageWindow ()
+ GemRB.PlaySound ("GAM_44")
+ Button = MageWindow.GetControl(index + 3)
+ Button.SetAnimation ("FLASH")
return
def OnMageRemoveSpell ():
@@ -434,6 +445,7 @@ def OpenSequencerWindow ():
Spell3 = ""
#the target player (who receives the contingency or sequencer)
pc = GemRB.GetVar("P0")
+ ClassName = GUICommon.GetClassRowName (pc)
#maximum spell level
MaxLevel = GemRB.GetVar("P1")
#target 0 - any, 1 - caster only, 2 - sequencer
@@ -477,8 +489,8 @@ def OpenSequencerWindow ():
TypeButton = Window.GetControl (8)
#no cleric spells available
- if (CommonTables.ClassSkills.GetValue (GemRB.GetPlayerStat (pc, IE_CLASS), 0)=="*" and
- CommonTables.ClassSkills.GetValue (GemRB.GetPlayerStat (pc, IE_CLASS), 1)=="*"):
+ if CommonTables.ClassSkills.GetValue (ClassName, "DRUIDSPELL") == "*" and\
+ CommonTables.ClassSkills.GetValue (ClassName, "CLERICSPELL") == "*":
TypeButton.SetState (IE_GUI_BUTTON_DISABLED)
if Target == 2:
@@ -606,7 +618,8 @@ def ContingencyOk ():
else:
GemRB.ApplyEffect (pc, "CastSpellOnCondition", 0, GemRB.GetVar ("ContCond"), Spell1, Spell2, Spell3, Source)
#set the innate
- GemRB.LearnSpell (pc, Source+"d", LS_MEMO)
+ if GemRB.LearnSpell (pc, Source+"d", LS_MEMO):
+ print "EEEEK! Failed to learn sequencer/contingency!\n\n"
OtherWindow.Unload()
return
@@ -700,7 +713,7 @@ def BuildSpellList (pc, type, level):
SpellList = {}
dummy = [Spell1,Spell2,Spell3]
- mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level)
+ mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level, False)
for i in range(mem_cnt):
ms = GemRB.GetMemorizedSpell (pc, type, level, i)
diff --git a/gemrb/GUIScripts/bg2/GUIOPT.py b/gemrb/GUIScripts/bg2/GUIOPT.py
deleted file mode 100644
index 444925d..0000000
--- a/gemrb/GUIScripts/bg2/GUIOPT.py
+++ /dev/null
@@ -1,737 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-# GUIOPT.py - scripts to control options windows mostly from the GUIOPT winpack:
-# 0 - Main options window (peacock tail)
-# 1 - Video options window
-# 2 - msg win with 1 button
-# 3 - msg win with 2 buttons
-# 4 - msg win with 3 buttons
-# 5 - Audio options window
-# 6 - Gameplay options window
-# 8 - Feedback options window
-# 9 - Autopause options window
-
-###################################################
-import GemRB
-import GUICommon
-import GUISAVE
-from GUIDefines import *
-
-###################################################
-GameOptionsWindow = None
-PortraitWindow = None
-OldPortraitWindow = None
-OptionsWindow = None
-OldOptionsWindow = None
-HelpTextArea = None
-
-LoadMsgWindow = None
-QuitMsgWindow = None
-
-###################################################
-def CloseOptionsWindow ():
- import GUICommonWindows
- global GameOptionsWindow, OptionsWindow, PortraitWindow
- global OldPortraitWindow, OldOptionsWindow
-
- if GameOptionsWindow == None:
- return
-
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- if OptionsWindow:
- OptionsWindow.Unload ()
- if PortraitWindow:
- PortraitWindow.Unload ()
-
- GameOptionsWindow = None
- GemRB.SetVar ("OtherWindow", -1)
- GUICommon.GameWindow.SetVisible(WINDOW_VISIBLE)
- GemRB.UnhideGUI ()
- GUICommonWindows.OptionsWindow = OldOptionsWindow
- OldOptionsWindow = None
- GUICommonWindows.PortraitWindow = OldPortraitWindow
- OldPortraitWindow = None
- return
-
-###################################################
-def OpenOptionsWindow ():
- """Open main options window"""
- import GUICommonWindows
- global GameOptionsWindow, OptionsWindow, PortraitWindow
- global OldPortraitWindow, OldOptionsWindow
-
- if GUICommon.CloseOtherWindow (OpenOptionsWindow):
- CloseOptionsWindow()
- return
-
- hideflag = GemRB.HideGUI ()
- GUICommon.GameWindow.SetVisible(WINDOW_INVISIBLE)
-
- GemRB.LoadWindowPack ("GUIOPT", 640, 480)
- GameOptionsWindow = Window = GemRB.LoadWindow (2)
- GemRB.SetVar ("OtherWindow", GameOptionsWindow.ID)
- #saving the original portrait window
- if OldPortraitWindow == None:
- OldOptionsWindow = GUICommonWindows.OptionsWindow
- OptionsWindow = GemRB.LoadWindow (0)
- GUICommonWindows.MarkMenuButton (OptionsWindow)
- GUICommonWindows.SetupMenuWindowControls (OptionsWindow, 0, OpenOptionsWindow)
- OptionsWindow.SetFrame ()
- OldPortraitWindow = GUICommonWindows.PortraitWindow
- PortraitWindow = GUICommonWindows.OpenPortraitWindow (0)
-
- # Return to Game
- Button = Window.GetControl (11)
- Button.SetText (10308)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenOptionsWindow)
-
- # Quit Game
- Button = Window.GetControl (10)
- Button.SetText (13731)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenQuitMsgWindow)
-
- # Load Game
- Button = Window.GetControl (5)
- Button.SetText (13729)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenLoadMsgWindow)
-
- # Save Game
- Button = Window.GetControl (6)
- Button.SetText (13730)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenSaveMsgWindow)
-
- # Video Options
- Button = Window.GetControl (7)
- Button.SetText (17162)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenVideoOptionsWindow)
-
- # Audio Options
- Button = Window.GetControl (8)
- Button.SetText (17164)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenAudioOptionsWindow)
-
- # Gameplay Options
- Button = Window.GetControl (9)
- Button.SetText (17165)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenGameplayOptionsWindow)
-
- # game version, e.g. v1.1.0000
- Label = Window.GetControl (0x1000000b)
- Label.SetText (GEMRB_VERSION)
-
- OptionsWindow.SetVisible (WINDOW_VISIBLE)
- Window.SetVisible (WINDOW_VISIBLE)
- PortraitWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-###################################################
-
-def CloseVideoOptionsWindow ():
- OpenOptionsWindow ()
- OpenOptionsWindow ()
-
-def OpenVideoOptionsWindow ():
- """Open video options window"""
- global GameOptionsWindow, HelpTextArea
-
- if GameOptionsWindow:
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
-
- GameOptionsWindow = Window = GemRB.LoadWindow (6)
-
- HelpTextArea = OptHelpText ('VideoOptions', Window, 33, 18038)
-
- OptDone ('VideoOptions', Window, 21)
- OptCancel ('VideoOptions', Window, 32)
-
- OptSlider ('Brightness', Window, 3, 'Brightness Correction', 4)
- OptSlider ('Contrast', Window, 22, 'Gamma Correction', 1)
-
- OptRadio ('BPP', Window, 5, 37, 'BitsPerPixel', 16)
- OptRadio ('BPP', Window, 6, 37, 'BitsPerPixel', 24)
- OptRadio ('BPP', Window, 7, 37, 'BitsPerPixel', 32)
-
- OptCheckbox ('FullScreen', Window, 9, 38, 'Full Screen', 1)
-
- OptCheckbox ('TransShadow', Window, 51, 50, 'Translucent Shadows', 1)
- OptCheckbox ('SoftMirrBlt', Window, 40, 44, 'SoftMirrorBlt' ,1)
- OptCheckbox ('SoftTransBlt', Window, 41, 46, 'SoftSrcKeyBlt' ,1)
- OptCheckbox ('SoftStandBlt', Window, 42, 48, 'SoftBltFast' ,1)
-
- GameOptionsWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DisplayHelpFullScreen ():
- HelpTextArea.SetText (18000)
- GemRB.SetFullScreen (GemRB.GetVar("Full Screen"))
-
-def DisplayHelpBPP ():
- HelpTextArea.SetText (17205)
-
-def DisplayHelpBrightness ():
- HelpTextArea.SetText (17203)
- GemRB.SetGamma (GemRB.GetVar("Brightness Correction"),GemRB.GetVar("Gamma Correction"))
-
-def DisplayHelpContrast ():
- HelpTextArea.SetText (17204)
- GemRB.SetGamma (GemRB.GetVar("Brightness Correction"),GemRB.GetVar("Gamma Correction"))
-
-def DisplayHelpSoftMirrBlt ():
- HelpTextArea.SetText (18004)
-
-def DisplayHelpSoftTransBlt ():
- HelpTextArea.SetText (18006)
-
-def DisplayHelpSoftStandBlt ():
- HelpTextArea.SetText (18007)
-
-def DisplayHelpTransShadow ():
- HelpTextArea.SetText (20620)
-
-
-###################################################
-
-def CloseAudioOptionsWindow ():
- OpenOptionsWindow ()
- OpenOptionsWindow ()
-
-def OpenAudioOptionsWindow ():
- """Open audio options window"""
- global GameOptionsWindow, HelpTextArea
-
- if GameOptionsWindow:
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
-
- GameOptionsWindow = Window = GemRB.LoadWindow (7)
-
- HelpTextArea = OptHelpText ('AudioOptions', Window, 14, 18040)
-
- OptDone ('AudioOptions', Window, 24)
- OptCancel ('AudioOptions', Window, 25)
- OptButton ('CharacterSounds', Window, 13, 17778)
-
- OptSlider ('AmbientVolume', Window, 1, 'Volume Ambients', 10)
- OptSlider ('SoundFXVolume', Window, 2, 'Volume SFX', 10)
- OptSlider ('VoiceVolume', Window, 3, 'Volume Voices', 10)
- OptSlider ('MusicVolume', Window, 4, 'Volume Music', 10)
- OptSlider ('MovieVolume', Window, 22, 'Volume Movie', 10)
-
- OptCheckbox ('CreativeEAX', Window, 26, 28, 'Environmental Audio', 1)
- GameOptionsWindow.ShowModal (MODAL_SHADOW_GRAY)
-
-
-def DisplayHelpAmbientVolume ():
- HelpTextArea.SetText (18008)
- GemRB.UpdateAmbientsVolume ()
-
-def DisplayHelpSoundFXVolume ():
- HelpTextArea.SetText (18009)
-
-def DisplayHelpVoiceVolume ():
- HelpTextArea.SetText (18010)
-
-def DisplayHelpMusicVolume ():
- HelpTextArea.SetText (18011)
- GemRB.UpdateMusicVolume ()
-
-def DisplayHelpMovieVolume ():
- HelpTextArea.SetText (18012)
-
-def DisplayHelpCreativeEAX ():
- HelpTextArea.SetText (18022)
-
-###################################################
-
-def CloseCharacterSoundsWindow ():
- global GameOptionsWindow
-
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
- OpenGameplayOptionsWindow ()
- return
-
-def OpenCharacterSoundsWindow ():
- """Open character sounds window"""
- global GameOptionsWindow, HelpTextArea
-
- if GameOptionsWindow:
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
-
- GameOptionsWindow = Window = GemRB.LoadWindow (12)
-
- HelpTextArea = OptHelpText ('CharacterSounds', Window, 16, 18041)
-
- OptDone ('CharacterSounds', Window, 24)
- OptCancel ('CharacterSounds', Window, 25)
-
- OptCheckbox ('Subtitles', Window, 5, 20, 'Subtitles', 1)
- OptCheckbox ('AttackSounds', Window, 6, 18, 'Attack Sounds', 1)
- OptCheckbox ('Footsteps', Window, 7, 19, 'Footsteps', 1)
- OptRadio ('CommandSounds', Window, 8, 21, 'Command Sounds Frequency', 1)
- OptRadio ('CommandSounds', Window, 9, 21, 'Command Sounds Frequency', 2)
- OptRadio ('CommandSounds', Window, 10, 21, 'Command Sounds Frequency', 3)
- OptRadio ('SelectionSounds', Window, 58, 57, 'Selection Sounds Frequency', 1)
- OptRadio ('SelectionSounds', Window, 59, 57, 'Selection Sounds Frequency', 2)
- OptRadio ('SelectionSounds', Window, 60, 57, 'Selection Sounds Frequency', 3)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
-
-def DisplayHelpSubtitles ():
- HelpTextArea.SetText (18015)
-
-def DisplayHelpAttackSounds ():
- HelpTextArea.SetText (18013)
-
-def DisplayHelpFootsteps ():
- HelpTextArea.SetText (18014)
-
-def DisplayHelpCommandSounds ():
- HelpTextArea.SetText (18016)
-
-def DisplayHelpSelectionSounds ():
- HelpTextArea.SetText (11352)
-
-###################################################
-
-def CloseGameplayOptionsWindow ():
- OpenOptionsWindow ()
- OpenOptionsWindow ()
-
-def OpenGameplayOptionsWindow ():
- """Open gameplay options window"""
- global GameOptionsWindow, HelpTextArea
-
- if GameOptionsWindow:
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
-
- #gameplayoptions
- GameOptionsWindow = Window = GemRB.LoadWindow (8)
-
-
- HelpTextArea = OptHelpText ('GameplayOptions', Window, 40, 18042)
-
- OptDone ('GameplayOptions', Window, 7)
- OptCancel ('GameplayOptions', Window, 20)
-
- OptSlider ('TooltipDelay', Window, 1, 'Tooltips', TOOLTIP_DELAY_FACTOR)
- OptSlider ('MouseScrollingSpeed', Window, 2, 'Mouse Scroll Speed', 5)
- OptSlider ('KeyboardScrollingSpeed', Window, 3, 'Keyboard Scroll Speed', 5)
- OptSlider ('Difficulty', Window, 12, 'Difficulty Level', 0)
-
- OptCheckbox ('DitherAlways', Window, 14, 25, 'Always Dither', 1)
- OptCheckbox ('Gore', Window, 19, 27, 'Gore', 1)
- OptCheckbox ('Infravision', Window, 42, 44, 'Infravision', 1)
- OptCheckbox ('Weather', Window, 47, 46, 'Weather', 1)
- if GUICommon.GameIsBG2():
- OptCheckbox ('RestUntilHealed', Window, 50, 48, 'Heal Party on Rest', 1)
-
- OptButton ('FeedbackOptions', Window, 5, 17163)
- OptButton ('AutopauseOptions', Window, 6, 17166)
- if GUICommon.GameIsBG2():
- OptButton ('HotkeyOptions', Window, 51, 816)
-
- GameOptionsWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DisplayHelpTooltipDelay ():
- HelpTextArea.SetText (18017)
- GemRB.SetTooltipDelay (GemRB.GetVar ("Tooltips") )
-
-def DisplayHelpMouseScrollingSpeed ():
- HelpTextArea.SetText (18018)
- GemRB.SetMouseScrollSpeed (GemRB.GetVar ("Mouse Scroll Speed") )
-
-def DisplayHelpKeyboardScrollingSpeed ():
- HelpTextArea.SetText (18019)
-
-def DisplayHelpDifficulty ():
- HelpTextArea.SetText (18020)
-
-def DisplayHelpDitherAlways ():
- HelpTextArea.SetText (18021)
-
-def DisplayHelpGore ():
- HelpTextArea.SetText (18023)
-
-def DisplayHelpInfravision ():
- HelpTextArea.SetText (11797)
-
-def DisplayHelpWeather ():
- HelpTextArea.SetText (20619)
-
-def DisplayHelpRestUntilHealed ():
- HelpTextArea.SetText (2242)
-
-###################################################
-
-def CloseFeedbackOptionsWindow ():
- global GameOptionsWindow
-
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
- OpenGameplayOptionsWindow ()
-
-
-def OpenFeedbackOptionsWindow ():
- """Open feedback options window"""
- global GameOptionsWindow, HelpTextArea
-
- if GameOptionsWindow:
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
-
- #feedback
- GameOptionsWindow = Window = GemRB.LoadWindow (9)
-
- HelpTextArea = OptHelpText ('FeedbackOptions', Window, 28, 18043)
-
- OptDone ('FeedbackOptions', Window, 26)
- OptCancel ('FeedbackOptions', Window, 27)
-
- OptSlider ('MarkerFeedback', Window, 8, 'GUI Feedback Level', 1)
- OptSlider ('LocatorFeedback', Window, 9, 'Locator Feedback Level', 1)
-
- OptCheckbox ('ToHitRolls', Window, 10, 32, 'Rolls', 1)
- OptCheckbox ('CombatInfo', Window, 11, 33, 'Combat Info', 1)
- OptCheckbox ('Actions', Window, 12, 34, 'Actions', 1)
- OptCheckbox ('States', Window, 13, 35, 'State Changes', 1)
- OptCheckbox ('Selection', Window, 14, 36, 'Selection Text', 1)
- OptCheckbox ('Miscellaneous', Window, 15, 37, 'Miscellaneous Text', 1)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DisplayHelpMarkerFeedback ():
- HelpTextArea.SetText (18024)
-
-def DisplayHelpLocatorFeedback ():
- HelpTextArea.SetText (18025)
-
-def DisplayHelpToHitRolls ():
- HelpTextArea.SetText (18026)
-
-def DisplayHelpCombatInfo ():
- HelpTextArea.SetText (18027)
-
-def DisplayHelpActions ():
- HelpTextArea.SetText (18028)
-
-def DisplayHelpStates ():
- HelpTextArea.SetText (18029)
-
-def DisplayHelpSelection ():
- HelpTextArea.SetText (18030)
-
-def DisplayHelpMiscellaneous ():
- HelpTextArea.SetText (18031)
-
-###################################################
-
-def CloseAutopauseOptionsWindow ():
- global GameOptionsWindow
-
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
- OpenGameplayOptionsWindow ()
- return
-
-def OpenAutopauseOptionsWindow ():
- """Open autopause options window"""
- global GameOptionsWindow, HelpTextArea
-
- if GameOptionsWindow:
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
-
- GameOptionsWindow = Window = GemRB.LoadWindow (10)
-
- HelpTextArea = OptHelpText ('AutopauseOptions', Window, 15, 18044)
-
- OptDone ('AutopauseOptions', Window, 11)
- OptCancel ('AutopauseOptions', Window, 14)
-
- OptCheckbox ('CharacterHit', Window, 1, 17, 'Auto Pause State', 1)
- OptCheckbox ('CharacterInjured', Window, 2, 18, 'Auto Pause State', 2)
- OptCheckbox ('CharacterDead', Window, 3, 19, 'Auto Pause State', 4)
- OptCheckbox ('CharacterAttacked', Window, 4, 20, 'Auto Pause State', 8)
- OptCheckbox ('WeaponUnusable', Window, 5, 21, 'Auto Pause State', 16)
- OptCheckbox ('TargetGone', Window, 13, 22, 'Auto Pause State', 32)
- OptCheckbox ('EndOfRound', Window, 25, 24, 'Auto Pause State', 64)
- if Window.HasControl(26, IE_GUI_BUTTON):
- OptCheckbox ('EnemySighted', Window, 26, 27, 'Auto Pause State', 128)
- if GUICommon.GameIsBG2():
- OptCheckbox ('SpellCast', Window, 34, 30, 'Auto Pause State', 256)
- OptCheckbox ('TrapFound', Window, 31, 33, 'Auto Pause State', 512)
- OptCheckbox ('CenterOnActor', Window, 31, 33, 'Auto Pause Center', 1)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DisplayHelpCharacterHit ():
- HelpTextArea.SetText (18032)
-
-def DisplayHelpCharacterInjured ():
- HelpTextArea.SetText (18033)
-
-def DisplayHelpCharacterDead ():
- HelpTextArea.SetText (18034)
-
-def DisplayHelpCharacterAttacked ():
- HelpTextArea.SetText (18035)
-
-def DisplayHelpWeaponUnusable ():
- HelpTextArea.SetText (18036)
-
-def DisplayHelpTargetGone ():
- HelpTextArea.SetText (18037)
-
-def DisplayHelpEndOfRound ():
- HelpTextArea.SetText (10640)
-
-def DisplayHelpEnemySighted ():
- HelpTextArea.SetText (23514)
-
-def DisplayHelpSpellCast ():
- HelpTextArea.SetText (58171)
-
-def DisplayHelpTrapFound ():
- HelpTextArea.SetText (31872)
-
-def DisplayHelpCenterOnActor ():
- HelpTextArea.SetText (10571)
-
-###################################################
-
-def OpenSaveMsgWindow ():
- GemRB.SetVar("QuitAfterSave",0)
- GUISAVE.OpenSaveWindow ()
- #save the game without quitting
- return
-
-###################################################
-
-def OpenLoadMsgWindow ():
- global LoadMsgWindow
-
- if LoadMsgWindow:
- return
-
- LoadMsgWindow = Window = GemRB.LoadWindow (4)
-
- # Load
- Button = Window.GetControl (0)
- Button.SetText (15590)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, LoadGamePress)
-
- # Cancel
- Button = Window.GetControl (1)
- Button.SetText (13727)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseLoadMsgWindow)
-
- # Loading a game will destroy ...
- Text = Window.GetControl (3)
- Text.SetText (19531)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def CloseLoadMsgWindow ():
- global LoadMsgWindow
-
- if LoadMsgWindow:
- LoadMsgWindow.Unload ()
- LoadMsgWindow = None
- OptionsWindow.SetVisible (WINDOW_VISIBLE)
- GameOptionsWindow.SetVisible (WINDOW_VISIBLE)
- PortraitWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def LoadGamePress ():
- global LoadMsgWindow
-
- if LoadMsgWindow:
- LoadMsgWindow.Unload ()
- LoadMsgWindow = None
- GemRB.QuitGame ()
- OpenOptionsWindow()
- GemRB.SetNextScript ("GUILOAD")
- return
-
-#save game AND quit
-def SaveGamePress ():
- global QuitMsgWindow
-
- if QuitMsgWindow:
- QuitMsgWindow.Unload ()
- QuitMsgWindow = None
- #we need to set a state: quit after save
- GemRB.SetVar("QuitAfterSave",1)
- OpenOptionsWindow()
- GUISAVE.OpenSaveWindow ()
- return
-
-def QuitGamePress ():
- global QuitMsgWindow
-
- if QuitMsgWindow:
- QuitMsgWindow.Unload ()
- QuitMsgWindow = None
- GemRB.QuitGame ()
- OpenOptionsWindow()
- GemRB.SetNextScript ("Start")
- return
-
-###################################################
-
-def OpenQuitMsgWindow ():
- global QuitMsgWindow
-
- if QuitMsgWindow:
- return
-
- QuitMsgWindow = Window = GemRB.LoadWindow (5)
-
- # Save
- Button = Window.GetControl (0)
- Button.SetText (15589)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SaveGamePress)
-
- # Quit Game
- Button = Window.GetControl (1)
- Button.SetText (15417)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, QuitGamePress)
-
- # Cancel
- Button = Window.GetControl (2)
- Button.SetText (13727)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseQuitMsgWindow)
-
- # Do you wish to save the game ....
- Text = Window.GetControl (3)
- Text.SetText (16456)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def CloseQuitMsgWindow ():
- global QuitMsgWindow
-
- if QuitMsgWindow:
- QuitMsgWindow.Unload ()
- QuitMsgWindow = None
- OptionsWindow.SetVisible (WINDOW_VISIBLE)
- GameOptionsWindow.SetVisible (WINDOW_VISIBLE)
- PortraitWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-###################################################
-#TODO
-def OpenHotkeyOptionsWindow ():
- return
-
-def CloseHotkeyOptionsWindow ():
- return
-
-###################################################
-# These functions help to setup controls found
-# in Video, Audio, Gameplay, Feedback and Autopause
-# options windows
-
-# These controls are usually made from an active
-# control (button, slider ...) and a label
-
-
-def OptSlider (name, window, slider_id, variable, value):
- """Standard slider for option windows"""
- slider = window.GetControl (slider_id)
- slider.SetVarAssoc (variable, value)
- slider.SetEvent (IE_GUI_SLIDER_ON_CHANGE, eval("DisplayHelp" + name))
- return slider
-
-def OptRadio (name, window, button_id, label_id, variable, value):
- """Standard radio button for option windows"""
-
- button = window.GetControl (button_id)
- button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- button.SetEvent (IE_GUI_BUTTON_ON_PRESS, eval("DisplayHelp" + name))
- button.SetVarAssoc (variable, value)
-
- label = window.GetControl (label_id)
- label.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- label.SetState (IE_GUI_BUTTON_LOCKED)
-
- return button
-
-def OptCheckbox (name, window, button_id, label_id, variable, value):
- """Standard checkbox for option windows"""
-
- button = window.GetControl (button_id)
- button.SetFlags (IE_GUI_BUTTON_CHECKBOX, OP_OR)
- button.SetEvent (IE_GUI_BUTTON_ON_PRESS, eval("DisplayHelp" + name))
- button.SetVarAssoc (variable, value)
-
- label = window.GetControl (label_id)
- label.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- label.SetState (IE_GUI_BUTTON_LOCKED)
-
- return button
-
-def OptButton (name, window, button_id, button_strref):
- """Standard subwindow button for option windows"""
- button = window.GetControl (button_id)
- button.SetEvent (IE_GUI_BUTTON_ON_PRESS, eval("Open%sWindow" %name))
- button.SetText (button_strref)
-
-def OptDone (name, window, button_id):
- """Standard `Done' button for option windows"""
- button = window.GetControl (button_id)
- button.SetText (11973) # Done
- button.SetEvent (IE_GUI_BUTTON_ON_PRESS, eval("Close%sWindow" %name))
- button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
-def OptCancel (name, window, button_id):
- """Standard `Cancel' button for option windows"""
- button = window.GetControl (button_id)
- button.SetText (13727) # Cancel
- button.SetEvent (IE_GUI_BUTTON_ON_PRESS, eval("Close%sWindow" %name))
- button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
-def OptHelpText (name, window, text_id, text_strref):
- """Standard textarea with context help for option windows"""
- text = window.GetControl (text_id)
- text.SetText (text_strref)
- return text
-
-###################################################
-# End of file GUIOPT.py
diff --git a/gemrb/GUIScripts/bg2/GUIOPT10.py b/gemrb/GUIScripts/bg2/GUIOPT10.py
deleted file mode 100644
index 2accde3..0000000
--- a/gemrb/GUIScripts/bg2/GUIOPT10.py
+++ /dev/null
@@ -1,188 +0,0 @@
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-#
-#autopause
-import GemRB
-
-def OnLoad():
- global AutoPauseWindow, TextAreaControl
-
- GemRB.LoadWindowPack("GUIOPT", 640, 480)
-
- AutoPauseWindow = GemRB.LoadWindow(10)
- TextAreaControl = AutoPauseWindow.GetControl(15)
-
- ChHitButton = AutoPauseWindow.GetControl(17)
- ChHitButtonB = AutoPauseWindow.GetControl(1)
-
- ChInjured = AutoPauseWindow.GetControl(18)
- ChInjuredB = AutoPauseWindow.GetControl(2)
-
- ChDeath = AutoPauseWindow.GetControl(19)
- ChDeathB = AutoPauseWindow.GetControl(3)
-
- ChAttacked = AutoPauseWindow.GetControl(20)
- ChAttackedB = AutoPauseWindow.GetControl(4)
-
- WeaponUnusable = AutoPauseWindow.GetControl(21)
- WeaponUnusableB = AutoPauseWindow.GetControl(5)
-
- TargetDestroyed = AutoPauseWindow.GetControl(22)
- TargetDestroyedB = AutoPauseWindow.GetControl(13)
-
- EndOfRound = AutoPauseWindow.GetControl(24)
- EndOfRoundB = AutoPauseWindow.GetControl(25)
-
- EnemySighted = AutoPauseWindow.GetControl(27)
- EnemySightedB = AutoPauseWindow.GetControl(26)
-
- SpellCast = AutoPauseWindow.GetControl(30)
- SpellCastB = AutoPauseWindow.GetControl(34)
-
- TrapFound = AutoPauseWindow.GetControl(33)
- TrapFoundB = AutoPauseWindow.GetControl(31)
-
- AutopauseCenter = AutoPauseWindow.GetControl(36)
- AutopauseCenterB = AutoPauseWindow.GetControl(37)
-
- OkButton = AutoPauseWindow.GetControl(11)
- CancelButton = AutoPauseWindow.GetControl(14)
- TextAreaControl.SetText(18044)
- OkButton.SetText(11973)
- CancelButton.SetText(13727)
-
- ChHitButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, ChHitButtonPress)
- ChHitButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- ChHitButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, ChHitButtonPress)
-
- ChInjured.SetEvent(IE_GUI_BUTTON_ON_PRESS, ChInjuredPress)
- ChInjuredB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- ChInjuredB.SetEvent(IE_GUI_BUTTON_ON_PRESS, ChInjuredPress)
-
- ChDeath.SetEvent(IE_GUI_BUTTON_ON_PRESS, ChDeathPress)
- ChDeathB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- ChDeathB.SetEvent(IE_GUI_BUTTON_ON_PRESS, ChDeathPress)
-
- ChAttacked.SetEvent(IE_GUI_BUTTON_ON_PRESS, ChAttackedPress)
- ChAttackedB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- ChAttackedB.SetEvent(IE_GUI_BUTTON_ON_PRESS, ChAttackedPress)
-
- WeaponUnusable.SetEvent(IE_GUI_BUTTON_ON_PRESS, WeaponUnusablePress)
- WeaponUnusableB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- WeaponUnusableB.SetEvent(IE_GUI_BUTTON_ON_PRESS, WeaponUnusablePress)
-
- TargetDestroyed.SetEvent(IE_GUI_BUTTON_ON_PRESS, TargetDestroyedPress)
- TargetDestroyedB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- TargetDestroyedB.SetEvent(IE_GUI_BUTTON_ON_PRESS, TargetDestroyedPress)
-
- EndOfRound.SetEvent(IE_GUI_BUTTON_ON_PRESS, EndOfRoundPress)
- EndOfRoundB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- EndOfRoundB.SetEvent(IE_GUI_BUTTON_ON_PRESS, EndOfRoundPress)
-
- EnemySighted.SetEvent(IE_GUI_BUTTON_ON_PRESS, EnemySightedPress)
- EnemySightedB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- EnemySightedB.SetEvent(IE_GUI_BUTTON_ON_PRESS, EnemySightedPress)
-
- SpellCast.SetEvent(IE_GUI_BUTTON_ON_PRESS, SpellCastPress)
- SpellCastB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- SpellCastB.SetEvent(IE_GUI_BUTTON_ON_PRESS, SpellCastPress)
-
- TrapFound.SetEvent(IE_GUI_BUTTON_ON_PRESS, TrapFoundPress)
- TrapFoundB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- TrapFoundB.SetEvent(IE_GUI_BUTTON_ON_PRESS, TrapFoundPress)
-
- AutopauseCenter.SetEvent(IE_GUI_BUTTON_ON_PRESS, AutopauseCenterPress)
- AutopauseCenterB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- AutopauseCenterB.SetEvent(IE_GUI_BUTTON_ON_PRESS, AutopauseCenterPress)
-
- OkButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, OkPress)
- OkButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
- CancelButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, CancelPress)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- AutopauseCenterB.SetVarAssoc("Auto Pause Center",1)
-
- ChHitButtonB.SetVarAssoc("Auto Pause State",1)
- ChInjuredB.SetVarAssoc("Auto Pause State",2)
- ChDeathB.SetVarAssoc("Auto Pause State",4)
- ChAttackedB.SetVarAssoc("Auto Pause State",8)
- WeaponUnusableB.SetVarAssoc("Auto Pause State",16)
- TargetDestroyedB.SetVarAssoc("Auto Pause State",32)
- EndOfRoundB.SetVarAssoc("Auto Pause State",64)
- EnemySightedB.SetVarAssoc("Auto Pause State",128)
- SpellCastB.SetVarAssoc("Auto Pause State",256)
- TrapFoundB.SetVarAssoc("Auto Pause State",512)
-
- AutoPauseWindow.SetVisible(WINDOW_VISIBLE)
- return
-
-def ChHitButtonPress():
- TextAreaControl.SetText(18032)
- return
-
-def ChInjuredPress():
- TextAreaControl.SetText(18033)
- return
-
-def ChDeathPress():
- TextAreaControl.SetText(18034)
- return
-
-def ChAttackedPress():
- TextAreaControl.SetText(18035)
- return
-
-def WeaponUnusablePress():
- TextAreaControl.SetText(18036)
- return
-
-def TargetDestroyedPress():
- TextAreaControl.SetText(18037)
- return
-
-def EndOfRoundPress():
- TextAreaControl.SetText(10640)
- return
-
-def EnemySightedPress():
- TextAreaControl.SetText(23514)
- return
-
-def SpellCastPress():
- TextAreaControl.SetText(58171)
- return
-
-def TrapFoundPress():
- TextAreaControl.SetText(31872)
- return
-
-def AutopauseCenterPress():
- TextAreaControl.SetText(10571)
- return
-
-def OkPress():
- if AutoPauseWindow:
- AutoPauseWindow.Unload()
- GemRB.SetNextScript("GUIOPT8")
- return
-
-def CancelPress():
- if AutoPauseWindow:
- AutoPauseWindow.Unload()
- GemRB.SetNextScript("GUIOPT8")
- return
diff --git a/gemrb/GUIScripts/bg2/GUIOPT12.py b/gemrb/GUIScripts/bg2/GUIOPT12.py
deleted file mode 100644
index fcd31ff..0000000
--- a/gemrb/GUIScripts/bg2/GUIOPT12.py
+++ /dev/null
@@ -1,127 +0,0 @@
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-#
-#character sounds
-import GemRB
-
-SoundWindow = 0
-TextAreaControl = 0
-
-def OnLoad():
- global SoundWindow, TextAreaControl
- GemRB.LoadWindowPack("GUIOPT", 640, 480)
- SoundWindow = GemRB.LoadWindow(12)
- TextAreaControl = SoundWindow.GetControl(16)
- SubtitleButton = SoundWindow.GetControl(20)
- SubtitleButtonB = SoundWindow.GetControl(5)
- WarCryButton = SoundWindow.GetControl(18)
- WarCryButtonB = SoundWindow.GetControl(6)
- StepsButton = SoundWindow.GetControl(19)
- StepsButtonB = SoundWindow.GetControl(7)
- ActionButton = SoundWindow.GetControl(21)
- ActionButtonB1 = SoundWindow.GetControl(8)
- ActionButtonB2 = SoundWindow.GetControl(9)
- ActionButtonB3 = SoundWindow.GetControl(10)
- SelectionButton = SoundWindow.GetControl(57)
- SelectionButtonB1 = SoundWindow.GetControl(58)
- SelectionButtonB2 = SoundWindow.GetControl(59)
- SelectionButtonB3 = SoundWindow.GetControl(60)
- OkButton = SoundWindow.GetControl(24)
- CancelButton = SoundWindow.GetControl(25)
- TextAreaControl.SetText(18041)
- OkButton.SetText(11973)
- CancelButton.SetText(13727)
- SubtitleButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, SubtitlePress)
- SubtitleButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, SubtitlePress)
- SubtitleButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- SubtitleButtonB.SetVarAssoc("Subtitles",1)
-
- WarCryButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, WarCryPress)
- WarCryButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, WarCryPress)
- WarCryButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- WarCryButtonB.SetVarAssoc("Attack Sounds",1)
-
- StepsButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, StepsPress)
- StepsButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, StepsPress)
- StepsButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- StepsButtonB.SetVarAssoc("Footsteps",1)
-
- ActionButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, ActionPress)
- ActionButtonB1.SetEvent(IE_GUI_BUTTON_ON_PRESS, ActionPress)
- ActionButtonB1.SetFlags(IE_GUI_BUTTON_RADIOBUTTON,OP_OR)
- ActionButtonB1.SetVarAssoc("Command Sounds Frequency",1)
-
- ActionButtonB2.SetEvent(IE_GUI_BUTTON_ON_PRESS, ActionPress)
- ActionButtonB2.SetFlags(IE_GUI_BUTTON_RADIOBUTTON,OP_OR)
- ActionButtonB2.SetVarAssoc("Command Sounds Frequency",2)
-
- ActionButtonB3.SetEvent(IE_GUI_BUTTON_ON_PRESS, ActionPress)
- ActionButtonB3.SetFlags(IE_GUI_BUTTON_RADIOBUTTON,OP_OR)
- ActionButtonB3.SetVarAssoc("Command Sounds Frequency",3)
-
- SelectionButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, SelectionPress)
- SelectionButtonB1.SetEvent(IE_GUI_BUTTON_ON_PRESS, SelectionPress)
- SelectionButtonB1.SetFlags(IE_GUI_BUTTON_RADIOBUTTON,OP_OR)
- SelectionButtonB1.SetVarAssoc("Selection Sounds Frequency",1)
-
- SelectionButtonB2.SetEvent(IE_GUI_BUTTON_ON_PRESS, SelectionPress)
- SelectionButtonB2.SetFlags(IE_GUI_BUTTON_RADIOBUTTON,OP_OR)
- SelectionButtonB2.SetVarAssoc("Selection Sounds Frequency",2)
-
- SelectionButtonB3.SetEvent(IE_GUI_BUTTON_ON_PRESS, SelectionPress)
- SelectionButtonB3.SetFlags(IE_GUI_BUTTON_RADIOBUTTON,OP_OR)
- SelectionButtonB3.SetVarAssoc("Selection Sounds Frequency",3)
-
- OkButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, OkPress)
- OkButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
- CancelButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, CancelPress)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
- SoundWindow.SetVisible(WINDOW_VISIBLE)
- return
-
-def SubtitlePress():
- TextAreaControl.SetText(18015)
- return
-
-def WarCryPress():
- TextAreaControl.SetText(18013)
- return
-
-def StepsPress():
- TextAreaControl.SetText(18014)
- return
-
-def ActionPress():
- TextAreaControl.SetText(18016)
- return
-
-def SelectionPress():
- TextAreaControl.SetText(11352)
- return
-
-def OkPress():
- if SoundWindow:
- SoundWindow.Unload()
- GemRB.SetNextScript("GUIOPT7")
- return
-
-def CancelPress():
- if SoundWindow:
- SoundWindow.Unload()
- GemRB.SetNextScript("GUIOPT7")
- return
diff --git a/gemrb/GUIScripts/bg2/GUIOPT6.py b/gemrb/GUIScripts/bg2/GUIOPT6.py
deleted file mode 100644
index fcd090d..0000000
--- a/gemrb/GUIScripts/bg2/GUIOPT6.py
+++ /dev/null
@@ -1,149 +0,0 @@
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-#
-#graphics options
-import GemRB
-
-GraphicsWindow = 0
-TextAreaControl = 0
-
-def OnLoad():
- global GraphicsWindow, TextAreaControl
- GemRB.LoadWindowPack("GUIOPT", 640, 480)
- GraphicsWindow = GemRB.LoadWindow(6)
- TextAreaControl = GraphicsWindow.GetControl(33)
- BrightnessButton = GraphicsWindow.GetControl(35)
- BrightnessSlider = GraphicsWindow.GetControl(3)
- BrightnessSlider.SetVarAssoc("Brightness Correction",4)
-
- ContrastButton = GraphicsWindow.GetControl(36)
- ContrastSlider = GraphicsWindow.GetControl(22)
- ContrastSlider.SetVarAssoc("Gamma Correction",1)
-
- BppButton = GraphicsWindow.GetControl(37)
- BppButtonB1 = GraphicsWindow.GetControl(5)
- BppButtonB2 = GraphicsWindow.GetControl(6)
- BppButtonB3 = GraphicsWindow.GetControl(7)
- BppButtonB1.SetFlags(IE_GUI_BUTTON_RADIOBUTTON,OP_OR)
- BppButtonB2.SetFlags(IE_GUI_BUTTON_RADIOBUTTON,OP_OR)
- BppButtonB3.SetFlags(IE_GUI_BUTTON_RADIOBUTTON,OP_OR)
- BppButtonB1.SetVarAssoc("BitsPerPixel",16)
- BppButtonB2.SetVarAssoc("BitsPerPixel",24)
- BppButtonB3.SetVarAssoc("BitsPerPixel",32)
-
- FullScreenButton = GraphicsWindow.GetControl(38)
- FullScreenButtonB = GraphicsWindow.GetControl(9)
- FullScreenButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- FullScreenButtonB.SetVarAssoc("Full Screen",1)
-
- SoftMirrBltButton = GraphicsWindow.GetControl(44)
- SoftMirrBltButtonB = GraphicsWindow.GetControl(40)
- SoftMirrBltButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- SoftMirrBltButtonB.SetVarAssoc("SoftMirrorBlt",1)
-
- SoftTransBltButton = GraphicsWindow.GetControl(46)
- SoftTransBltButtonB = GraphicsWindow.GetControl(41)
- SoftTransBltButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- SoftTransBltButtonB.SetVarAssoc("SoftSrcKeyBlt",1)
-
- SoftStandBltButton = GraphicsWindow.GetControl(48)
- SoftStandBltButtonB = GraphicsWindow.GetControl(42)
- SoftStandBltButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- SoftStandBltButtonB.SetVarAssoc("SoftBltFast",1)
-
- TransShadowButton = GraphicsWindow.GetControl(50)
- TransShadowButtonB = GraphicsWindow.GetControl(51)
- TransShadowButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- TransShadowButtonB.SetVarAssoc("Translucent Shadows",1)
-
- OkButton = GraphicsWindow.GetControl(21)
- CancelButton = GraphicsWindow.GetControl(32)
- TextAreaControl.SetText(18038)
- OkButton.SetText(11973)
- CancelButton.SetText(13727)
- BrightnessButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, BrightnessPress)
- BrightnessSlider.SetEvent(IE_GUI_SLIDER_ON_CHANGE, BrightnessPress)
- ContrastButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, ContrastPress)
- ContrastSlider.SetEvent(IE_GUI_SLIDER_ON_CHANGE, ContrastPress)
- BppButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, BppPress)
- BppButtonB1.SetEvent(IE_GUI_BUTTON_ON_PRESS, BppPress)
- BppButtonB2.SetEvent(IE_GUI_BUTTON_ON_PRESS, BppPress)
- BppButtonB3.SetEvent(IE_GUI_BUTTON_ON_PRESS, BppPress)
- FullScreenButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, FullScreenPress)
- FullScreenButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, FullScreenPress)
- TransShadowButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, TransShadowPress)
- TransShadowButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, TransShadowPress)
- SoftMirrBltButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, SoftMirrBltPress)
- SoftMirrBltButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, SoftMirrBltPress)
- SoftTransBltButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, SoftTransBltPress)
- SoftTransBltButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, SoftTransBltPress)
- SoftStandBltButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, SoftStandBltPress)
- SoftStandBltButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, SoftStandBltPress)
- OkButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, OkPress)
- OkButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
- CancelButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, CancelPress)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
- GraphicsWindow.ShowModal()
- return
-
-def BrightnessPress():
- TextAreaControl.SetText(17203)
- GemRB.SetGamma (GemRB.GetVar("Brightness Correction"),GemRB.GetVar("Gamma Correction"))
- return
-
-def ContrastPress():
- TextAreaControl.SetText(17204)
- GemRB.SetGamma (GemRB.GetVar("Brightness Correction"),GemRB.GetVar("Gamma Correction"))
- return
-
-def BppPress():
- TextAreaControl.SetText(17205)
- return
-
-def FullScreenPress():
- TextAreaControl.SetText(18000)
- GemRB.SetFullScreen (GemRB.GetVar("Full Screen"))
- return
-
-def TransShadowPress():
- TextAreaControl.SetText(20620)
- return
-
-def SoftMirrBltPress():
- TextAreaControl.SetText(18004)
- return
-
-def SoftTransBltPress():
- TextAreaControl.SetText(18006)
- return
-
-def SoftStandBltPress():
- TextAreaControl.SetText(18007)
- return
-
-def OkPress():
- if GraphicsWindow:
- GraphicsWindow.Unload()
- GemRB.SetNextScript("StartOpt")
- return
-
-def CancelPress():
- if GraphicsWindow:
- GraphicsWindow.Unload()
- GemRB.SetNextScript("StartOpt")
- return
diff --git a/gemrb/GUIScripts/bg2/GUIOPT7.py b/gemrb/GUIScripts/bg2/GUIOPT7.py
deleted file mode 100644
index 93a887a..0000000
--- a/gemrb/GUIScripts/bg2/GUIOPT7.py
+++ /dev/null
@@ -1,125 +0,0 @@
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-#
-#sound options
-import GemRB
-
-SoundWindow = 0
-TextAreaControl = 0
-
-def OnLoad():
- global SoundWindow, TextAreaControl
-
- GemRB.LoadWindowPack("GUIOPT", 640, 480)
- SoundWindow = GemRB.LoadWindow(7)
- TextAreaControl = SoundWindow.GetControl(14)
- AmbientButton = SoundWindow.GetControl(16)
- AmbientSlider = SoundWindow.GetControl(1)
- SoundEffectsButton = SoundWindow.GetControl(17)
- SoundEffectsSlider = SoundWindow.GetControl(2)
- DialogueButton = SoundWindow.GetControl(18)
- DialogueSlider = SoundWindow.GetControl(3)
- MusicButton = SoundWindow.GetControl(19)
- MusicSlider = SoundWindow.GetControl(4)
- MoviesButton = SoundWindow.GetControl(20)
- MoviesSlider = SoundWindow.GetControl(22)
- EnvironmentalButton = SoundWindow.GetControl(28)
- EnvironmentalButtonB = SoundWindow.GetControl(26)
- CharacterSoundButton = SoundWindow.GetControl(13)
- OkButton = SoundWindow.GetControl(24)
- CancelButton = SoundWindow.GetControl(25)
- TextAreaControl.SetText(18040)
- CharacterSoundButton.SetText(17778)
- OkButton.SetText(11973)
- CancelButton.SetText(13727)
- AmbientButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, AmbientPress)
- AmbientSlider.SetEvent(IE_GUI_SLIDER_ON_CHANGE, AmbientPress)
- AmbientSlider.SetVarAssoc("Volume Ambients",10)
-
- SoundEffectsButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, SoundEffectsPress)
- SoundEffectsSlider.SetEvent(IE_GUI_SLIDER_ON_CHANGE, SoundEffectsPress)
- SoundEffectsSlider.SetVarAssoc("Volume SFX",10)
-
- DialogueButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, DialoguePress)
- DialogueSlider.SetEvent(IE_GUI_SLIDER_ON_CHANGE, DialoguePress)
- DialogueSlider.SetVarAssoc("Volume Voices",10)
-
- MusicButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, MusicPress)
- MusicSlider.SetEvent(IE_GUI_SLIDER_ON_CHANGE, MusicPress)
- MusicSlider.SetVarAssoc("Volume Music",10)
-
- MoviesButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, MoviesPress)
- MoviesSlider.SetEvent(IE_GUI_SLIDER_ON_CHANGE, MoviesPress)
- MoviesSlider.SetVarAssoc("Volume Movie",10)
-
- EnvironmentalButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, EnvironmentalPress)
- EnvironmentalButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, EnvironmentalPress)
- EnvironmentalButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- EnvironmentalButtonB.SetVarAssoc("Environmental Audio",1)
-
- CharacterSoundButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, CharacterSoundPress)
- OkButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, OkPress)
- OkButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
- CancelButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, CancelPress)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
- SoundWindow.SetVisible(WINDOW_VISIBLE)
- return
-
-def AmbientPress():
- TextAreaControl.SetText(18008)
- GemRB.UpdateAmbientsVolume ()
- return
-
-def SoundEffectsPress():
- TextAreaControl.SetText(18009)
- return
-
-def DialoguePress():
- TextAreaControl.SetText(18010)
- return
-
-def MusicPress():
- TextAreaControl.SetText(18011)
- GemRB.UpdateMusicVolume ()
- return
-
-def MoviesPress():
- TextAreaControl.SetText(18012)
- return
-
-def EnvironmentalPress():
- TextAreaControl.SetText(18022)
- return
-
-def CharacterSoundPress():
- if SoundWindow:
- SoundWindow.Unload()
- GemRB.SetNextScript("GUIOPT12")
- return
-
-def OkPress():
- if SoundWindow:
- SoundWindow.Unload()
- GemRB.SetNextScript("StartOpt")
- return
-
-def CancelPress():
- if SoundWindow:
- SoundWindow.Unload()
- GemRB.SetNextScript("StartOpt")
- return
diff --git a/gemrb/GUIScripts/bg2/GUIOPT8.py b/gemrb/GUIScripts/bg2/GUIOPT8.py
deleted file mode 100644
index 106fc53..0000000
--- a/gemrb/GUIScripts/bg2/GUIOPT8.py
+++ /dev/null
@@ -1,176 +0,0 @@
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-#
-#gameplay
-import GemRB
-
-GamePlayWindow = 0
-TextAreaControl = 0
-
-def OnLoad():
- global GamePlayWindow, TextAreaControl
- GemRB.LoadWindowPack("GUIOPT", 640, 480)
- GamePlayWindow = GemRB.LoadWindow(8)
- TextAreaControl = GamePlayWindow.GetControl(40)
- DelayButton = GamePlayWindow.GetControl(21)
- DelaySlider = GamePlayWindow.GetControl(1)
- MouseSpdButton = GamePlayWindow.GetControl(22)
- MouseSpdSlider = GamePlayWindow.GetControl(2)
- KeySpdButton = GamePlayWindow.GetControl(23)
- KeySpdSlider = GamePlayWindow.GetControl(3)
- DifficultyButton = GamePlayWindow.GetControl(24)
- DifficultySlider = GamePlayWindow.GetControl(12)
- BloodButton = GamePlayWindow.GetControl(27)
- BloodButtonB = GamePlayWindow.GetControl(19)
- DitherButton = GamePlayWindow.GetControl(25)
- DitherButtonB = GamePlayWindow.GetControl(14)
- InfravisionButton = GamePlayWindow.GetControl(44)
- InfravisionButtonB = GamePlayWindow.GetControl(42)
- WeatherButton = GamePlayWindow.GetControl(46)
- WeatherButtonB = GamePlayWindow.GetControl(47)
- HealButton = GamePlayWindow.GetControl(48)
- HealButtonB = GamePlayWindow.GetControl(50)
- HotKeyButton = GamePlayWindow.GetControl(51)
- FeedbackButton = GamePlayWindow.GetControl(5)
- AutoPauseButton = GamePlayWindow.GetControl(6)
- OkButton = GamePlayWindow.GetControl(7)
- CancelButton = GamePlayWindow.GetControl(20)
- TextAreaControl.SetText(18042)
- OkButton.SetText(11973)
- CancelButton.SetText(13727)
- HotKeyButton.SetText(816)
- FeedbackButton.SetText(17163)
- AutoPauseButton.SetText(17166)
- DelayButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, DelayPress)
- DelaySlider.SetEvent(IE_GUI_SLIDER_ON_CHANGE, DelayPress)
- DelaySlider.SetVarAssoc("Tooltips",0)
-
- KeySpdButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, KeySpdPress)
- KeySpdSlider.SetEvent(IE_GUI_SLIDER_ON_CHANGE, KeySpdPress)
- KeySpdSlider.SetVarAssoc("Keyboard Scroll Speed",0)
-
- MouseSpdButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, MouseSpdPress)
- MouseSpdSlider.SetEvent(IE_GUI_SLIDER_ON_CHANGE, MouseSpdPress)
- MouseSpdSlider.SetVarAssoc("Mouse Scroll Speed",0)
-
- DifficultyButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, DifficultyPress)
- DifficultySlider.SetEvent(IE_GUI_SLIDER_ON_CHANGE, DifficultyPress)
- DifficultySlider.SetVarAssoc("Difficulty Level",0)
-
- BloodButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, BloodPress)
- BloodButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, BloodPress)
- BloodButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- BloodButtonB.SetVarAssoc("Gore",1)
-
- DitherButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, DitherPress)
- DitherButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, DitherPress)
- DitherButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- DitherButtonB.SetVarAssoc("Always Dither",1)
-
- InfravisionButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, InfravisionPress)
- InfravisionButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, InfravisionPress)
- InfravisionButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- InfravisionButtonB.SetVarAssoc("Infravision",1)
-
- WeatherButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, WeatherPress)
- WeatherButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, WeatherPress)
- WeatherButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- WeatherButtonB.SetVarAssoc("Weather",1)
-
- HealButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, HealPress)
- HealButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, HealPress)
- HealButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- HealButtonB.SetVarAssoc("Heal Party on Rest",1)
-
- HotKeyButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, HotKeyPress)
- FeedbackButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, FeedbackPress)
- AutoPauseButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, AutoPausePress)
- OkButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, OkPress)
- OkButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
- CancelButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, CancelPress)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
- GamePlayWindow.SetVisible(WINDOW_VISIBLE)
- return
-
-def DelayPress():
- TextAreaControl.SetText(18017)
- return
-
-def KeySpdPress():
- TextAreaControl.SetText(18019)
- return
-
-def MouseSpdPress():
- TextAreaControl.SetText(18018)
- return
-
-def DifficultyPress():
- TextAreaControl.SetText(18020)
- return
-
-def BloodPress():
- TextAreaControl.SetText(18023)
- return
-
-def DitherPress():
- TextAreaControl.SetText(18021)
- return
-
-def InfravisionPress():
- TextAreaControl.SetText(11797)
- return
-
-def WeatherPress():
- TextAreaControl.SetText(20619)
- return
-
-def HealPress():
- TextAreaControl.SetText(2242)
- return
-
-def HotKeyPress():
- #TextAreaControl.SetText(18016)
- return
-
-def FeedbackPress():
- GamePlayWindow.SetVisible(WINDOW_INVISIBLE)
- if GamePlayWindow:
- GamePlayWindow.Unload()
- GemRB.SetNextScript("GUIOPT9")
- return
-
-def AutoPausePress():
- GamePlayWindow.SetVisible(WINDOW_INVISIBLE)
- if GamePlayWindow:
- GamePlayWindow.Unload()
- GemRB.SetNextScript("GUIOPT10")
- return
-
-def OkPress():
- GamePlayWindow.SetVisible(WINDOW_INVISIBLE)
- if GamePlayWindow:
- GamePlayWindow.Unload()
- GemRB.SetNextScript("StartOpt")
- return
-
-def CancelPress():
- GamePlayWindow.SetVisible(WINDOW_INVISIBLE)
- if GamePlayWindow:
- GamePlayWindow.Unload()
- GemRB.SetNextScript("StartOpt")
- return
diff --git a/gemrb/GUIScripts/bg2/GUIOPT9.py b/gemrb/GUIScripts/bg2/GUIOPT9.py
deleted file mode 100644
index ba5b750..0000000
--- a/gemrb/GUIScripts/bg2/GUIOPT9.py
+++ /dev/null
@@ -1,176 +0,0 @@
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-#
-#feedback
-import GemRB
-
-FeedbackWindow = 0
-TextAreaControl = 0
-
-def OnLoad():
- global FeedbackWindow, TextAreaControl
-
- GemRB.LoadWindowPack("GUIOPT", 640, 480)
- FeedbackWindow = GemRB.LoadWindow(9)
-
- MarkerSlider = FeedbackWindow.GetControl(30)
- MarkerSliderS = FeedbackWindow.GetControl(8)
-
- LocatorSlider = FeedbackWindow.GetControl(31)
- LocatorSliderS = FeedbackWindow.GetControl(9)
-
- THac0Rolls = FeedbackWindow.GetControl(32)
- THac0RollsB = FeedbackWindow.GetControl(10)
-
- CombatInfo = FeedbackWindow.GetControl(33)
- CombatInfoB = FeedbackWindow.GetControl(11)
-
- Actions = FeedbackWindow.GetControl(34)
- ActionsB = FeedbackWindow.GetControl(12)
-
- StateChanges = FeedbackWindow.GetControl(35)
- StateChangesB = FeedbackWindow.GetControl(13)
-
- SelectionText = FeedbackWindow.GetControl(36)
- SelectionTextB = FeedbackWindow.GetControl(14)
-
- Miscellaneous = FeedbackWindow.GetControl(37)
- MiscellaneousB = FeedbackWindow.GetControl(15)
- OkButton = FeedbackWindow.GetControl(26)
- CancelButton = FeedbackWindow.GetControl(27)
- TextAreaControl = FeedbackWindow.GetControl(28)
-
- TextAreaControl.SetText(18043)
- OkButton.SetText(11973)
- CancelButton.SetText(13727)
-
- MarkerSlider.SetEvent(IE_GUI_BUTTON_ON_PRESS, MarkerSliderPress)
- MarkerSliderS.SetEvent(IE_GUI_SLIDER_ON_CHANGE, MarkerSliderPress)
- MarkerSliderS.SetVarAssoc("GUI Feedback Level",1)
-
- LocatorSlider.SetEvent(IE_GUI_BUTTON_ON_PRESS, LocatorSliderPress)
- LocatorSliderS.SetEvent(IE_GUI_SLIDER_ON_CHANGE, LocatorSliderPress)
- LocatorSliderS.SetVarAssoc("Locator Feedback Level",1)
-
- THac0Rolls.SetEvent(IE_GUI_BUTTON_ON_PRESS, THac0RollsPress)
- THac0RollsB.SetEvent(IE_GUI_BUTTON_ON_PRESS, THac0RollsBPress)
- THac0RollsB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- THac0RollsB.SetVarAssoc("Rolls",1)
-
- CombatInfo.SetEvent(IE_GUI_BUTTON_ON_PRESS, CombatInfoPress)
- CombatInfoB.SetEvent(IE_GUI_BUTTON_ON_PRESS, CombatInfoBPress)
- CombatInfoB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- CombatInfoB.SetVarAssoc("Combat Info",1)
-
- Actions.SetEvent(IE_GUI_BUTTON_ON_PRESS, ActionsPress)
- ActionsB.SetEvent(IE_GUI_BUTTON_ON_PRESS, ActionsBPress)
- ActionsB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- ActionsB.SetVarAssoc("Actions",1)
-
- StateChanges.SetEvent(IE_GUI_BUTTON_ON_PRESS, StateChangesPress)
- StateChangesB.SetEvent(IE_GUI_BUTTON_ON_PRESS, StateChangesBPress)
- StateChangesB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- StateChangesB.SetVarAssoc("State Changes",1)
-
- SelectionText.SetEvent(IE_GUI_BUTTON_ON_PRESS, SelectionTextPress)
- SelectionTextB.SetEvent(IE_GUI_BUTTON_ON_PRESS, SelectionTextBPress)
- SelectionTextB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- SelectionTextB.SetVarAssoc("Selection Text",1)
-
- Miscellaneous.SetEvent(IE_GUI_BUTTON_ON_PRESS, MiscellaneousPress)
- MiscellaneousB.SetEvent(IE_GUI_BUTTON_ON_PRESS, MiscellaneousBPress)
- MiscellaneousB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- MiscellaneousB.SetVarAssoc("Miscellaneous Text",1)
-
- OkButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, OkPress)
- OkButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
- CancelButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, CancelPress)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
- FeedbackWindow.SetVisible(WINDOW_VISIBLE)
- return
-
-def MarkerSliderPress():
- TextAreaControl.SetText(18024)
- return
-
-def LocatorSliderPress():
- TextAreaControl.SetText(18025)
- return
-
-def THac0RollsPress():
- TextAreaControl.SetText(18026)
- return
-
-def THac0RollsBPress():
- #TODO: TextAreaControl.SetText()
- return
-
-def CombatInfoPress():
- TextAreaControl.SetText(18027)
- return
-
-def CombatInfoBPress():
- #TODO: TextAreaControl.SetText()
- return
-
-def ActionsPress():
- TextAreaControl.SetText(18028)
- return
-
-def ActionsBPress():
- #TODO: TextAreaControl.SetText(18028)
- return
-
-
-def StateChangesPress():
- TextAreaControl.SetText(18029)
- return
-
-def StateChangesBPress():
- #TODO: TextAreaControl.SetText(18029)
- return
-
-def SelectionTextPress():
- TextAreaControl.SetText(18030)
- return
-
-def SelectionTextBPress():
- #TODO: TextAreaControl.SetText(18030)
- return
-
-def MiscellaneousPress():
- TextAreaControl.SetText(18031)
- return
-
-def MiscellaneousBPress():
- #TODO: TextAreaControl.SetText(18031)
- return
-
-
-def OkPress():
- if FeedbackWindow:
- FeedbackWindow.Unload()
- GemRB.SetNextScript("GUIOPT8")
- return
-
-def CancelPress():
- if FeedbackWindow:
- FeedbackWindow.Unload()
- GemRB.SetNextScript("GUIOPT8")
- return
-
diff --git a/gemrb/GUIScripts/bg2/GUIPR.py b/gemrb/GUIScripts/bg2/GUIPR.py
deleted file mode 100644
index cbf2748..0000000
--- a/gemrb/GUIScripts/bg2/GUIPR.py
+++ /dev/null
@@ -1,356 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003-2004 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-
-# GUIPR.py - scripts to control the priest spells windows from the GUIPR winpack
-
-###################################################
-
-import GemRB
-import GUICommon
-import CommonTables
-from GUIDefines import *
-from ie_stats import *
-from ie_action import ACT_CAST
-
-PriestWindow = None
-PriestSpellInfoWindow = None
-PriestSpellLevel = 0
-PriestSpellUnmemorizeWindow = None
-PortraitWindow = None
-OptionsWindow = None
-OldPortraitWindow = None
-OldOptionsWindow = None
-
-def OpenPriestWindow ():
- import GUICommonWindows
- global PriestWindow, OptionsWindow, PortraitWindow
- global OldPortraitWindow, OldOptionsWindow
-
- if GUICommon.CloseOtherWindow (OpenPriestWindow):
- if PriestWindow:
- PriestWindow.Unload ()
- if OptionsWindow:
- OptionsWindow.Unload ()
- if PortraitWindow:
- PortraitWindow.Unload ()
-
- PriestWindow = None
- GemRB.SetVar ("OtherWindow", -1)
- GUICommon.GameWindow.SetVisible(WINDOW_VISIBLE)
- GemRB.UnhideGUI ()
- GUICommonWindows.PortraitWindow = OldPortraitWindow
- OldPortraitWindow = None
- GUICommonWindows.OptionsWindow = OldOptionsWindow
- OldOptionsWindow = None
- GUICommonWindows.SetSelectionChangeHandler (None)
- return
-
- GemRB.HideGUI ()
- GUICommon.GameWindow.SetVisible(WINDOW_INVISIBLE)
-
- GemRB.LoadWindowPack ("GUIPR", 640, 480)
- PriestWindow = Window = GemRB.LoadWindow (2)
- GemRB.SetVar ("OtherWindow", PriestWindow.ID)
- #saving the original portrait window
- OldOptionsWindow = GUICommonWindows.OptionsWindow
- OptionsWindow = GemRB.LoadWindow (0)
- GUICommonWindows.MarkMenuButton (OptionsWindow)
- GUICommonWindows.SetupMenuWindowControls (OptionsWindow, 0, OpenPriestWindow)
- OptionsWindow.SetFrame ()
- OldPortraitWindow = GUICommonWindows.PortraitWindow
- PortraitWindow = GUICommonWindows.OpenPortraitWindow (0)
-
- Button = Window.GetControl (1)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, PriestPrevLevelPress)
-
- Button = Window.GetControl (2)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, PriestNextLevelPress)
-
- #setup level buttons
- for i in range (7):
- Button = Window.GetControl (55 + i)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, RefreshPriestLevel)
- Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
-
- for i in range (7):
- Button = Window.GetControl (55 + i)
- Button.SetVarAssoc ("PriestSpellLevel", i)
-
- # Setup memorized spells buttons
- for i in range (12):
- Button = Window.GetControl (3 + i)
- Button.SetBorder (0,0,0,0,0,0,0,0,64,0,1)
- Button.SetSprites ("SPELFRAM",0,0,0,0,0)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_OR)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
-
- # Setup book spells buttons
- for i in range (24):
- Button = Window.GetControl (27 + i)
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_OR)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
-
- GUICommonWindows.SetSelectionChangeHandler (UpdatePriestWindow)
- UpdatePriestWindow ()
- OptionsWindow.SetVisible (WINDOW_VISIBLE)
- #bringing window front
- Window.SetVisible (WINDOW_FRONT)
- PortraitWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def UpdatePriestWindow ():
- global PriestMemorizedSpellList, PriestKnownSpellList
-
- PriestMemorizedSpellList = []
- PriestKnownSpellList = []
-
- Window = PriestWindow
- pc = GemRB.GameGetSelectedPCSingle ()
- type = IE_SPELL_TYPE_PRIEST
- level = PriestSpellLevel
- max_mem_cnt = GemRB.GetMemorizableSpellsCount (pc, type, level)
-
- Label = Window.GetControl (0x10000032)
- GemRB.SetToken("SPELLLEVEL", str(level+1) )
- Label.SetText (10345)
-
- Name = GemRB.GetPlayerName (pc, 0)
- Label = Window.GetControl (0x10000035)
- Label.SetText (Name)
-
- mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level)
- for i in range (12):
- Button = Window.GetControl (3 + i)
- if i < mem_cnt:
- ms = GemRB.GetMemorizedSpell (pc, type, level, i)
- Button.SetSpellIcon (ms['SpellResRef'], 0)
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_NAND)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_OR)
- if ms['Flags']:
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenPriestSpellUnmemorizeWindow)
- else:
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OnPriestUnmemorizeSpell)
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, OpenPriestSpellInfoWindow)
- spell = GemRB.GetSpell (ms['SpellResRef'])
- Button.SetTooltip (spell['SpellName'])
- PriestMemorizedSpellList.append (ms['SpellResRef'])
- Button.SetVarAssoc ("SpellButton", i)
- Button.EnableBorder (0, ms['Flags'] == 0)
- else:
- if i < max_mem_cnt:
- Button.SetFlags (IE_GUI_BUTTON_NORMAL, OP_SET)
- else:
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, None)
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, None)
- Button.SetTooltip ('')
- Button.EnableBorder (0, 0)
-
-
- known_cnt = GemRB.GetKnownSpellsCount (pc, type, level)
- for i in range (24):
- Button = Window.GetControl (27 + i)
- if i < known_cnt:
- ks = GemRB.GetKnownSpell (pc, type, level, i)
- Button.SetSpellIcon (ks['SpellResRef'], 0)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OnPriestMemorizeSpell)
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, OpenPriestSpellInfoWindow)
- spell = GemRB.GetSpell (ks['SpellResRef'])
- Button.SetTooltip (spell['SpellName'])
- PriestKnownSpellList.append (ks['SpellResRef'])
- Button.SetVarAssoc ("SpellButton", 100 + i)
-
- else:
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_OR)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_NAND)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, None)
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, None)
- Button.SetTooltip ('')
- Button.EnableBorder (0, 0)
-
- Class = GemRB.GetPlayerStat (pc, IE_CLASS)
- DivineCaster = CommonTables.ClassSkills.GetValue (Class, 1)
- if DivineCaster == "*":
- # also check the DRUIDSPELL column
- DivineCaster = CommonTables.ClassSkills.GetValue (Class, 0)
- CantCast = DivineCaster == "*" or GemRB.GetPlayerStat(pc, IE_DISABLEDBUTTON)&(1<<ACT_CAST)
- if CantCast or GemRB.GetPlayerStat (pc, IE_STATE_ID) & STATE_DEAD:
- Window.SetVisible (WINDOW_GRAYED)
- else:
- Window.SetVisible (WINDOW_VISIBLE)
- return
-
-def PriestPrevLevelPress ():
- global PriestSpellLevel
-
- if PriestSpellLevel > 0:
- PriestSpellLevel = PriestSpellLevel - 1
- UpdatePriestWindow ()
- return
-
-def PriestNextLevelPress ():
- global PriestSpellLevel
-
- if PriestSpellLevel < 6:
- PriestSpellLevel = PriestSpellLevel + 1
- UpdatePriestWindow ()
- return
-
-def RefreshPriestLevel ():
- global PriestSpellLevel
-
- PriestSpellLevel = GemRB.GetVar ("PriestSpellLevel")
- UpdatePriestWindow ()
- return
-
-def OpenPriestSpellInfoWindow ():
- global PriestSpellInfoWindow
-
- if PriestSpellInfoWindow != None:
- if PriestSpellInfoWindow:
- PriestSpellInfoWindow.Unload ()
- PriestSpellInfoWindow = None
- return
-
- PriestSpellInfoWindow = Window = GemRB.LoadWindow (3)
-
- #back
- Button = Window.GetControl (5)
- Button.SetText (15416)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenPriestSpellInfoWindow)
-
- index = GemRB.GetVar ("SpellButton")
- if index < 100:
- ResRef = PriestMemorizedSpellList[index]
- else:
- ResRef = PriestKnownSpellList[index - 100]
-
- spell = GemRB.GetSpell (ResRef)
-
- Label = Window.GetControl (0x0fffffff)
- Label.SetText (spell['SpellName'])
-
- Button = Window.GetControl (2)
- Button.SetSpellIcon (ResRef, 1)
-
- Text = Window.GetControl (3)
- Text.SetText (spell['SpellDesc'])
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def OnPriestMemorizeSpell ():
- pc = GemRB.GameGetSelectedPCSingle ()
- level = PriestSpellLevel
- type = IE_SPELL_TYPE_PRIEST
-
- index = GemRB.GetVar ("SpellButton") - 100
-
- if GemRB.MemorizeSpell (pc, type, level, index):
- UpdatePriestWindow ()
- return
-
-def OpenPriestSpellRemoveWindow ():
- global PriestSpellUnmemorizeWindow
-
- PriestSpellUnmemorizeWindow = Window = GemRB.LoadWindow (5)
-
- # "Are you sure you want to ....?"
- TextArea = Window.GetControl (3)
- TextArea.SetText (11824)
-
- # Remove
- Button = Window.GetControl (0)
- Button.SetText (17507)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OnPriestRemoveSpell)
- Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- # Cancel
- Button = Window.GetControl (1)
- Button.SetText (13727)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, ClosePriestSpellUnmemorizeWindow)
- Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def ClosePriestSpellUnmemorizeWindow ():
- global PriestSpellUnmemorizeWindow
-
- if PriestSpellUnmemorizeWindow:
- PriestSpellUnmemorizeWindow.Unload ()
- PriestSpellUnmemorizeWindow = None
- return
-
-def OpenPriestSpellUnmemorizeWindow ():
- global PriestSpellUnmemorizeWindow
-
- PriestSpellUnmemorizeWindow = Window = GemRB.LoadWindow (5)
-
- # "Are you sure you want to ....?"
- TextArea = Window.GetControl (3)
- TextArea.SetText (11824)
-
- # Remove
- Button = Window.GetControl (0)
- Button.SetText (17507)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OnPriestUnmemorizeSpell)
- Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- # Cancel
- Button = Window.GetControl (1)
- Button.SetText (13727)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, ClosePriestSpellUnmemorizeWindow)
- Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def OnPriestUnmemorizeSpell ():
- if PriestSpellUnmemorizeWindow:
- ClosePriestSpellUnmemorizeWindow ()
-
- pc = GemRB.GameGetSelectedPCSingle ()
- level = PriestSpellLevel
- type = IE_SPELL_TYPE_PRIEST
-
- index = GemRB.GetVar ("SpellButton")
-
- if GemRB.UnmemorizeSpell (pc, type, level, index):
- UpdatePriestWindow ()
- return
-
-def OnPriestRemoveSpell ():
- ClosePriestSpellUnmemorizeWindow()
- OpenPriestSpellInfoWindow()
-
- pc = GemRB.GameGetSelectedPCSingle ()
- level = PriestSpellLevel
- type = IE_SPELL_TYPE_PRIEST
-
- index = GemRB.GetVar ("SpellButton") - 100
-
- #remove spell from book
- GemRB.RemoveSpell (pc, type, level, index)
- UpdatePriestWindow ()
- return
-
-###################################################
-# End of file GUIPR.py
diff --git a/gemrb/GUIScripts/bg2/GUIREC.py b/gemrb/GUIScripts/bg2/GUIREC.py
deleted file mode 100644
index c13fdc9..0000000
--- a/gemrb/GUIScripts/bg2/GUIREC.py
+++ /dev/null
@@ -1,1567 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003-2009 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-
-# GUIREC.py - scripts to control stats/records windows from the GUIREC winpack
-
-###################################################
-import GemRB
-import GUICommon
-import CommonTables
-import LUCommon
-import GUIWORLD
-import DualClass
-import LevelUp
-from GUIDefines import *
-from ie_stats import *
-from ie_restype import *
-
-###################################################
-RecordsWindow = None
-InformationWindow = None
-BiographyWindow = None
-PortraitWindow = None
-OptionsWindow = None
-CustomizeWindow = None
-SubCustomizeWindow = None
-SubSubCustomizeWindow = None
-OldPortraitWindow = None
-OldOptionsWindow = None
-ExportWindow = None
-KitInfoWindow = None
-ExportDoneButton = None
-ExportFileName = ""
-PortraitsTable = None
-ScriptsTable = None
-ColorTable = None
-ColorIndex = None
-ScriptTextArea = None
-OldVoiceSet = None
-
-# the available sounds
-SoundSequence = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', \
- 'm', 's', 't', 'u', 'v', '_', 'x', 'y', 'z', '0', '1', '2', \
- '3', '4', '5', '6', '7', '8', '9']
-SoundIndex = 0
-
-###################################################
-def OpenRecordsWindow ():
- import GUICommonWindows
-
- global RecordsWindow, OptionsWindow, PortraitWindow
- global OldPortraitWindow, OldOptionsWindow
-
- if GUICommon.CloseOtherWindow (OpenRecordsWindow):
- if InformationWindow: OpenInformationWindow ()
-
- if RecordsWindow:
- RecordsWindow.Unload ()
- if OptionsWindow:
- OptionsWindow.Unload ()
- if PortraitWindow:
- PortraitWindow.Unload ()
-
- RecordsWindow = None
- GemRB.SetVar ("OtherWindow", -1)
- GUICommon.GameWindow.SetVisible(WINDOW_VISIBLE)
- GemRB.UnhideGUI ()
- GUICommonWindows.PortraitWindow = OldPortraitWindow
- OldPortraitWindow = None
- GUICommonWindows.OptionsWindow = OldOptionsWindow
- OldOptionsWindow = None
- GUICommonWindows.SetSelectionChangeHandler (None)
- return
-
- GemRB.HideGUI ()
- GUICommon.GameWindow.SetVisible(WINDOW_INVISIBLE)
-
- GemRB.LoadWindowPack ("GUIREC", 640, 480)
- RecordsWindow = Window = GemRB.LoadWindow (2)
- GemRB.SetVar ("OtherWindow", RecordsWindow.ID)
- #saving the original portrait window
- OldOptionsWindow = GUICommonWindows.OptionsWindow
- OptionsWindow = GemRB.LoadWindow (0)
- GUICommonWindows.MarkMenuButton (OptionsWindow)
- GUICommonWindows.SetupMenuWindowControls (OptionsWindow, 0, OpenRecordsWindow)
- OptionsWindow.SetFrame ()
- OldPortraitWindow = GUICommonWindows.PortraitWindow
- PortraitWindow = GUICommonWindows.OpenPortraitWindow (0)
-
- # dual class
- Button = Window.GetControl (0)
- Button.SetText (7174)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, DualClass.DualClassWindow)
-
- # levelup
- Button = Window.GetControl (37)
- Button.SetText (7175)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, LevelUp.OpenLevelUpWindow)
-
- # information
- Button = Window.GetControl (1)
- Button.SetText (11946)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenInformationWindow)
-
- # reform party
- Button = Window.GetControl (51)
- Button.SetText (16559)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenRecReformPartyWindow)
-
- # customize
- Button = Window.GetControl (50)
- Button.SetText (10645)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenCustomizeWindow)
-
- # export
- Button = Window.GetControl (36)
- Button.SetText (13956)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenExportWindow)
-
- # kit info
- Button = Window.GetControl (52)
- Button.SetText (61265)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenKitInfoWindow)
-
- GUICommonWindows.SetSelectionChangeHandler (UpdateRecordsWindow)
- UpdateRecordsWindow ()
- OptionsWindow.SetVisible (WINDOW_VISIBLE)
- Window.SetVisible (WINDOW_FRONT)
- PortraitWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-#original returns to game before continuing...
-def OpenRecReformPartyWindow ():
- OpenRecordsWindow ()
- GemRB.SetTimedEvent (GUIWORLD.OpenReformPartyWindow, 1)
- return
-
-def UpdateRecordsWindow ():
- global stats_overview, alignment_help
-
- Window = RecordsWindow
- if not RecordsWindow:
- print "SelectionChange handler points to non existing window\n"
- return
-
- pc = GemRB.GameGetSelectedPCSingle ()
-
- #update mage school
- GemRB.SetVar ("MAGESCHOOL", 0)
- Kit = GUICommon.GetKitIndex (pc)
- if Kit and CommonTables.KitList.GetValue (Kit, 7) == 1:
- MageTable = GemRB.LoadTable ("magesch")
- GemRB.SetVar ("MAGESCHOOL", MageTable.FindValue (3, CommonTables.KitList.GetValue (Kit, 6) ) )
-
- # exportable
- Button = Window.GetControl (36)
- if GemRB.GetPlayerStat (pc, IE_MC_FLAGS)&MC_EXPORTABLE:
- Button.SetState (IE_GUI_BUTTON_ENABLED)
- else:
- Button.SetState (IE_GUI_BUTTON_DISABLED)
-
- # dual-classable
- Button = Window.GetControl (0)
- if GUICommon.CanDualClass (pc):
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- Button.SetState (IE_GUI_BUTTON_ENABLED)
-
- # levelup
- Button = Window.GetControl (37)
- if LUCommon.CanLevelUp (pc):
- Button.SetState (IE_GUI_BUTTON_ENABLED)
- else:
- Button.SetState (IE_GUI_BUTTON_DISABLED)
-
- # name
- Label = Window.GetControl (0x1000000e)
- Label.SetText (GemRB.GetPlayerName (pc, 0))
-
- # portrait
- Button = Window.GetControl (2)
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE | IE_GUI_BUTTON_PICTURE, OP_SET)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- Button.SetPicture (GemRB.GetPlayerPortrait (pc,0), "NOPORTMD")
-
- # armorclass
- Label = Window.GetControl (0x10000028)
- ac = GemRB.GetPlayerStat (pc, IE_ARMORCLASS)
- #This is a temporary solution, the core engine should set the stat correctly!
- ac += GemRB.GetAbilityBonus (IE_DEX, 2, GemRB.GetPlayerStat (pc, IE_DEX) )
- Label.SetText (str (ac))
- Label.SetTooltip (17183)
-
- # hp now
- Label = Window.GetControl (0x10000029)
- Label.SetText (str (GemRB.GetPlayerStat (pc, IE_HITPOINTS)))
- Label.SetTooltip (17184)
-
- # hp max
- Label = Window.GetControl (0x1000002a)
- Label.SetText (str (GemRB.GetPlayerStat (pc, IE_MAXHITPOINTS)))
- Label.SetTooltip (17378)
-
- # stats
-
- sstr = GemRB.GetPlayerStat (pc, IE_STR)
- cstr = GetStatColor (pc, IE_STR)
- sstrx = GemRB.GetPlayerStat (pc, IE_STREXTRA)
-
- if sstrx > 0 and sstr==18:
- sstr = "%d/%02d" %(sstr, sstrx % 100)
- else:
- sstr = str (sstr)
- sint = str (GemRB.GetPlayerStat (pc, IE_INT))
- cint = GetStatColor (pc, IE_INT)
- swis = str (GemRB.GetPlayerStat (pc, IE_WIS))
- cwis = GetStatColor (pc, IE_WIS)
- sdex = str (GemRB.GetPlayerStat (pc, IE_DEX))
- cdex = GetStatColor (pc, IE_DEX)
- scon = str (GemRB.GetPlayerStat (pc, IE_CON))
- ccon = GetStatColor (pc, IE_CON)
- schr = str (GemRB.GetPlayerStat (pc, IE_CHR))
- cchr = GetStatColor (pc, IE_CHR)
-
- Label = Window.GetControl (0x1000002f)
- Label.SetText (sstr)
- Label.SetTextColor (cstr[0], cstr[1], cstr[2])
-
- Label = Window.GetControl (0x10000009)
- Label.SetText (sdex)
- Label.SetTextColor (cdex[0], cdex[1], cdex[2])
-
- Label = Window.GetControl (0x1000000a)
- Label.SetText (scon)
- Label.SetTextColor (ccon[0], ccon[1], ccon[2])
-
- Label = Window.GetControl (0x1000000b)
- Label.SetText (sint)
- Label.SetTextColor (cint[0], cint[1], cint[2])
-
- Label = Window.GetControl (0x1000000c)
- Label.SetText (swis)
- Label.SetTextColor (cwis[0], cwis[1], cwis[2])
-
- Label = Window.GetControl (0x1000000d)
- Label.SetText (schr)
- Label.SetTextColor (cchr[0], cchr[1], cchr[2])
-
- # class
- ClassTitle = GUICommon.GetActorClassTitle (pc)
- Label = Window.GetControl (0x10000030)
- Label.SetText (ClassTitle)
-
- # race
- text = CommonTables.Races.GetValue (CommonTables.Races.FindValue (3, GemRB.GetPlayerStat (pc, IE_RACE)) , 0)
-
- Label = Window.GetControl (0x1000000f)
- Label.SetText (text)
-
- Table = GemRB.LoadTable ("aligns")
-
- text = Table.GetValue (Table.FindValue ( 3, GemRB.GetPlayerStat (pc, IE_ALIGNMENT) ), 0)
- Label = Window.GetControl (0x10000010)
- Label.SetText (text)
-
- Label = Window.GetControl (0x10000011)
- if GemRB.GetPlayerStat (pc, IE_SEX) == 1:
- Label.SetText (7198)
- else:
- Label.SetText (7199)
-
- # help, info textarea
- stats_overview = GetStatOverview (pc)
- Text = Window.GetControl (45)
- Text.SetText (stats_overview)
- #making window visible/shaded depending on the pc's state
- Window.SetVisible (WINDOW_VISIBLE)
- return
-
-def GetStatColor (pc, stat):
- a = GemRB.GetPlayerStat (pc, stat)
- b = GemRB.GetPlayerStat (pc, stat, 1)
- if a==b:
- return (255,255,255)
- if a<b:
- return (255,255,0)
- return (0,255,0)
-
-# GemRB.GetPlayerStat wrapper that only returns nonnegative values
-def GSNN (pc, stat):
- val = GemRB.GetPlayerStat (pc, stat)
- if val >= 0:
- return val
- else:
- return 0
-
-# LevelDiff is used only from the level up code and holds the level
-# difference for each class
-def GetStatOverview (pc, LevelDiff=[0,0,0]):
- StateTable = GemRB.LoadTable ("statdesc")
- str_None = GemRB.GetString (61560)
-
- GS = lambda s, pc=pc: GemRB.GetPlayerStat (pc, s)
- GB = lambda s, pc=pc: GemRB.GetPlayerStat (pc, s, 1)
- GA = lambda s, col, pc=pc: GemRB.GetAbilityBonus (s, col, GS (s) )
-
- stats = []
- # class levels
- # 16480 <CLASS>: Level <LEVEL>
- # Experience: <EXPERIENCE>
- # Next Level: <NEXTLEVEL>
-
- # collecting tokens for stat overview
- ClassTitle = GUICommon.GetActorClassTitle (pc)
- GemRB.SetToken ("CLASS", ClassTitle)
- Class = GemRB.GetPlayerStat (pc, IE_CLASS)
- Class = CommonTables.Classes.FindValue (5, Class)
- Class = CommonTables.Classes.GetRowName (Class)
- Dual = GUICommon.IsDualClassed (pc, 1)
- Multi = GUICommon.IsMultiClassed (pc, 1)
- XP = GemRB.GetPlayerStat (pc, IE_XP)
- LevelDrain = GS (IE_LEVELDRAIN)
-
- if GS (IE_STATE_ID) & STATE_DEAD:
- stats.append ( (11829,1,'c') ) # DEAD
- stats.append (None)
-
- if Multi[0] > 1: # we're multiclassed
- print "\tMulticlassed"
- Levels = [GemRB.GetPlayerStat (pc, IE_LEVEL), GemRB.GetPlayerStat (pc, IE_LEVEL2), GemRB.GetPlayerStat (pc, IE_LEVEL3)]
-
- stats.append ( (19721,1,'c') )
- stats.append (None)
- for i in range (Multi[0]):
- ClassIndex = CommonTables.Classes.FindValue (5, Multi[i+1])
- ClassTitle = GemRB.GetString (CommonTables.Classes.GetValue (ClassIndex, 2))
- GemRB.SetToken ("CLASS", ClassTitle)
- Class = CommonTables.Classes.GetRowName (ClassIndex)
- GemRB.SetToken ("LEVEL", str (Levels[i]+LevelDiff[i]-int(LevelDrain/Multi[0])) )
- GemRB.SetToken ("EXPERIENCE", str (XP/Multi[0]) )
- if LevelDrain:
- stats.append ( (GemRB.GetString (19720),1,'d') )
- stats.append ( (GemRB.GetString (57435),1,'d') ) # LEVEL DRAINED
- else:
- GemRB.SetToken ("NEXTLEVEL", LUCommon.GetNextLevelExp (Levels[i]+LevelDiff[i], Class) )
- stats.append ( (GemRB.GetString (16480),"",'d') )
- stats.append (None)
- print "\t\tClass (Level):",Class,"(",Levels[i],")"
-
- elif Dual[0] > 0: # dual classed; first show the new class
- print "\tDual classed"
- stats.append ( (19722,1,'c') )
- stats.append (None)
-
- Levels = [GemRB.GetPlayerStat (pc, IE_LEVEL), GemRB.GetPlayerStat (pc, IE_LEVEL2), GemRB.GetPlayerStat (pc, IE_LEVEL3)]
-
- # the levels are stored in the class order (eg. FIGHTER_MAGE)
- # the current active class does not matter!
- if GUICommon.IsDualSwap (pc):
- Levels = [Levels[1], Levels[0], Levels[2]]
-
- Levels[0] += LevelDiff[0]
-
- ClassTitle = GemRB.GetString (CommonTables.Classes.GetValue (Dual[2], 2))
- GemRB.SetToken ("CLASS", ClassTitle)
- GemRB.SetToken ("LEVEL", str (Levels[0]-LevelDrain))
- Class = CommonTables.Classes.GetRowName (Dual[2])
- XP2 = GemRB.GetPlayerStat (pc, IE_XP)
- GemRB.SetToken ("EXPERIENCE", str (XP2) )
- if LevelDrain:
- stats.append ( (GemRB.GetString (19720),1,'d') )
- stats.append ( (GemRB.GetString (57435),1,'d') ) # LEVEL DRAINED
- else:
- GemRB.SetToken ("NEXTLEVEL", LUCommon.GetNextLevelExp (Levels[0], Class) )
- stats.append ( (GemRB.GetString (16480),"",'d') )
- stats.append (None)
-
- # the first class (shown second)
- if Dual[0] == 1:
- ClassTitle = GemRB.GetString (CommonTables.KitList.GetValue (Dual[1], 2))
- elif Dual[0] == 2:
- ClassTitle = GemRB.GetString (CommonTables.Classes.GetValue (Dual[1], 2))
- GemRB.SetToken ("CLASS", ClassTitle)
- GemRB.SetToken ("LEVEL", str (Levels[1]) )
-
- # the xp table contains only classes, so we have to determine the base class for kits
- if Dual[0] == 2:
- BaseClass = CommonTables.Classes.GetRowName (Dual[1])
- else:
- BaseClass = GUICommon.GetKitIndex (pc)
- BaseClass = CommonTables.KitList.GetValue (BaseClass, 7)
- BaseClass = CommonTables.Classes.FindValue (5, BaseClass)
- BaseClass = CommonTables.Classes.GetRowName (BaseClass)
- # the first class' XP is discarded and set to the minimum level
- # requirement, so if you don't dual class right after a levelup,
- # the game would eat some of your XP
- XP1 = CommonTables.NextLevel.GetValue (BaseClass, str (Levels[1]))
- GemRB.SetToken ("EXPERIENCE", str (XP1) )
-
- # inactive until the new class SURPASSES the former
- if Levels[0] <= Levels[1]:
- # inactive
- stats.append ( (19719,1,'c') )
- else:
- stats.append ( (19720,1,'c') )
- stats.append (None)
- else: # single classed
- print "\tSingle classed"
- Level = GemRB.GetPlayerStat (pc, IE_LEVEL) + LevelDiff[0]
- GemRB.SetToken ("LEVEL", str (Level-LevelDrain))
- GemRB.SetToken ("EXPERIENCE", str (XP) )
- if LevelDrain:
- stats.append ( (19720,1,'c') )
- stats.append ( (57435,1,'c') ) # LEVEL DRAINED
- else:
- GemRB.SetToken ("NEXTLEVEL", LUCommon.GetNextLevelExp (Level, Class) )
- stats.append ( (16480,1,'c') )
- stats.append (None)
- print "\t\tClass (Level):",Class,"(",Level,")"
-
- # check to see if we have a level diff anywhere
- if sum (LevelDiff) == 0:
- effects = GemRB.GetPlayerStates (pc)
- if len (effects):
- for c in effects:
- tmp = StateTable.GetValue (ord(c)-66, 0)
- stats.append ( (tmp,c,'a') )
- stats.append (None)
-
- #proficiencies
- stats.append ( (8442,1,'c') )
-
- stats.append ( (61932, GS (IE_TOHIT), '0') )
- if (GemRB.IsDualWielding(pc)):
- stats.append ( (56911, GemRB.GetCombatDetails(pc, 0)["ToHit"], '0') )
- stats.append ( (56910, GemRB.GetCombatDetails(pc, 1)["ToHit"], '0') )
- else:
- stats.append ( (9457, GemRB.GetCombatDetails(pc, 0)["ToHit"], '0') )
- tmp = GS (IE_NUMBEROFATTACKS)
- if (tmp&1):
- tmp2 = str (tmp/2) + chr (188)
- else:
- tmp2 = str (tmp/2)
- stats.append ( (9458, tmp2, '') )
- stats.append ( (9459, GSNN (pc, IE_LORE), '0') )
-
- #reputation
- reptxt = GetReputation (GemRB.GameGetReputation ()/10)
- stats.append ( (9465, reptxt, '') )
- stats.append ( (9460, GSNN (pc, IE_LOCKPICKING), '') )
- stats.append ( (9462, GSNN (pc, IE_TRAPS), '') )
- stats.append ( (9463, GSNN (pc, IE_PICKPOCKET), '') )
- stats.append ( (9461, GSNN (pc, IE_STEALTH), '') )
- HatedRace = GS (IE_HATEDRACE)
- if HatedRace:
- HateTable = GemRB.LoadTable ("haterace")
- Racist = HateTable.FindValue (1, HatedRace)
- if Racist != -1:
- HatedRace = HateTable.GetValue (Racist, 0)
- stats.append ( (15982, GemRB.GetString (HatedRace), '') )
-
- stats.append ( (34120, GSNN (pc, IE_HIDEINSHADOWS), '') )
- stats.append ( (34121, GSNN (pc, IE_DETECTILLUSIONS), '') )
- stats.append ( (34122, GSNN (pc, IE_SETTRAPS), '') )
- stats.append ( (12128, GS (IE_BACKSTABDAMAGEMULTIPLIER), 'x') )
- stats.append ( (12126, GS (IE_TURNUNDEADLEVEL), '') )
-
- #this hack only displays LOH if we know the spell
- #TODO: the core should just not set LOH if the paladin can't learn it
- if (GUICommon.HasSpell (pc, IE_SPELL_TYPE_INNATE, 0, "SPCL211") >= 0):
- stats.append ( (12127, GS (IE_LAYONHANDSAMOUNT), '') )
- #script
- aiscript = GemRB.GetPlayerScript (pc )
- stats.append ( (2078, aiscript, '') )
- stats.append (None)
-
- # 17379 Saving throws
- stats.append (17379)
- # 17380 Paralyze/Poison/Death
- stats.append ( (17380, IE_SAVEVSDEATH, 's') )
- # 17381 Rod/Staff/Wand
- stats.append ( (17381, IE_SAVEVSWANDS, 's') )
- # 17382 Petrify/Polymorph
- stats.append ( (17382, IE_SAVEVSPOLY, 's') )
- # 17383 Breath weapon
- stats.append ( (17383, IE_SAVEVSBREATH, 's') )
- # 17384 Spells
- stats.append ( (17384, IE_SAVEVSSPELL, 's') )
- stats.append (None)
-
- # 9466 Weapon proficiencies
- stats.append (9466)
- table = GemRB.LoadTable ("weapprof")
- RowCount = table.GetRowCount ()
- # the first 7 profs are foobared
- for i in range (8,RowCount):
- text = table.GetValue (i, 1)
- stat = table.GetValue (i, 0)
- stats.append ( (text, GS (stat)&0x07, '+') )
- stats.append (None)
-
- # 11766 AC bonuses
- stats.append (11766)
- # 11770 AC vs. Crushing
- stats.append ((11770, GS (IE_ACCRUSHINGMOD), 'p'))
- # 11767 AC vs. Missile
- stats.append ((11767, GS (IE_ACMISSILEMOD), 'p'))
- # 11769 AC vs. Piercing
- stats.append ((11769, GS (IE_ACPIERCINGMOD), 'p'))
- # 11768 AC vs. Slashing
- stats.append ((11768, GS (IE_ACSLASHINGMOD), 'p'))
- stats.append (None)
-
- # 10315 Ability bonuses
- stats.append (10315)
- value = GemRB.GetPlayerStat (pc, IE_STR)
- ex = GemRB.GetPlayerStat (pc, IE_STREXTRA)
- # 10332 to hit
- stats.append ( (10332, GemRB.GetAbilityBonus (IE_STR,0,value,ex), 'p') )
- # 10336 damage
- stats.append ( (10336, GemRB.GetAbilityBonus (IE_STR,1,value,ex), 'p') )
- # 10337 open doors (bend bars lift gates)
- stats.append ( (10337, GemRB.GetAbilityBonus (IE_STR,2,value,ex), '0') )
- # 10338 weight allowance
- stats.append ( (10338, GemRB.GetAbilityBonus (IE_STR,3,value,ex), '0') )
- # 10339 AC
- stats.append ( (10339, GA (IE_DEX,2), '0') )
- # 10340 Missile adjustment
- stats.append ( (10340, GA (IE_DEX,1), 'p') )
- # 10341 Reaction adjustment
- stats.append ( (10341, GA (IE_DEX,0), 'p') )
- # 10342 CON HP Bonus/Level
- stats.append ( (10342, GA (IE_CON,0), 'p') )
- # 10343 Chance To Learn spell
- if GemRB.GetMemorizableSpellsCount (pc, IE_SPELL_TYPE_WIZARD, 0, 0)>0:
- stats.append ( (10343, GA (IE_INT,0), '%' ) )
- # 10347 Reaction
- stats.append ( (10347, GA (IE_REPUTATION,0), '0') )
- stats.append (None)
-
- #Bonus spells
- if GemRB.GetMemorizableSpellsCount (pc, IE_SPELL_TYPE_PRIEST, 0, 0)>0:
- stats.append (10344)
- for level in range (7):
- GemRB.SetToken ("SPELLLEVEL", str (level+1) )
- #get the bonus spell count
- base = GemRB.GetMemorizableSpellsCount (pc, IE_SPELL_TYPE_PRIEST, level, 0)
- if base:
- count = GemRB.GetMemorizableSpellsCount (pc, IE_SPELL_TYPE_PRIEST, level)
- stats.append ( (GemRB.GetString (10345), count-base, 'r') )
- stats.append (None)
-
- # 32204 Resistances
- stats.append (32204)
- # 32213 Normal Fire
- stats.append ((32213, GS (IE_RESISTFIRE), '%'))
- # 32222 Magic Fire
- stats.append ((32222, GS (IE_RESISTMAGICFIRE), '%'))
- # 32214 Normal Cold
- stats.append ((32214, GS (IE_RESISTCOLD), '%'))
- # 32223 Magic Cold
- stats.append ((32223, GS (IE_RESISTMAGICCOLD), '%'))
- # 32220 Electricity
- stats.append ((32220, GS (IE_RESISTELECTRICITY), '%'))
- # 32221 Acid
- stats.append ((32221, GS (IE_RESISTACID), '%'))
- # Magic
- stats.append ((62146, GS (IE_RESISTMAGIC), '%'))
- # Magic Damage
- stats.append ((32233, GS (IE_MAGICDAMAGERESISTANCE), '%'))
- # Missile
- stats.append ((11767, GS (IE_RESISTMISSILE), '%'))
- # Slashing
- stats.append ((11768, GS (IE_RESISTSLASHING), '%'))
- # Piercing
- stats.append ((11769, GS (IE_RESISTPIERCING), '%'))
- # Crushing
- stats.append ((11770, GS (IE_RESISTCRUSHING), '%'))
- # Poison
- stats.append ((14017, GS (IE_RESISTPOISON), '%'))
- stats.append (None)
-
- #Weapon Style bonuses
- stats.append (32131)
- wstyle = GemRB.GetCombatDetails (pc, 0)["Style"] # equipped weapon style + 1000 * proficiency level
- profcount = wstyle / 1000
- if profcount:
- wstyletables = { IE_PROFICIENCY2WEAPON:"wstwowpn", IE_PROFICIENCY2HANDED:"wstwohnd", IE_PROFICIENCYSINGLEWEAPON:"wssingle", IE_PROFICIENCYSWORDANDSHIELD:"wsshield" }
- bonusrefs = { "THAC0BONUSRIGHT":56911, "THAC0BONUSLEFT":56910, "DAMAGEBONUS":10336, "CRITICALHITBONUS":32140, "PHYSICALSPEED":32141, "AC":10339, "ACVSMISSLE":10340 }
- WStyleTable = GemRB.LoadTable (wstyletables[wstyle%1000])
- for col in range(WStyleTable.GetColumnCount()):
- value = WStyleTable.GetValue (profcount, col)
- stats.append ((bonusrefs[WStyleTable.GetColumnName(col)], value, ''))
- stats.append (None)
-
- res = []
- lines = 0
- for s in stats:
- try:
- strref, val, type = s
- if val == 0 and type != '0':
- continue
- if type == '+': #pluses
- res.append ("[capital=0]"+GemRB.GetString (strref) + ' '+ '+' * val)
- elif type == 'p': #a plus prefix if positive
- if val > 0:
- res.append ("[capital=0]" + GemRB.GetString (strref) + ' +' + str (val) )
- else:
- res.append ("[capital=0]" + GemRB.GetString (strref) + ' ' + str (val) )
- elif type == 'r': #a plus prefix if positive, strref is an already resolved string
- if val > 0:
- res.append ("[capital=0]" + strref + ' +' + str (val) )
- else:
- res.append ("[capital=0]" + strref + ' ' + str (val) )
- elif type == 's': #both base and (modified) stat, but only if they differ
- base = GB (val)
- stat = GS (val)
- base_str = "[capital=0]" + GemRB.GetString (strref) + ': ' + str(stat)
- if base == stat:
- res.append (base_str)
- else:
- res.append (base_str + " (" + str(stat-base) + ")")
- elif type == 'x': #x character before value
- res.append ("[capital=0]"+GemRB.GetString (strref)+': x' + str (val) )
- elif type == 'a': #value (portrait icon) + string
- res.append ("[capital=2]"+val+" "+GemRB.GetString (strref) )
- elif type == 'b': #strref is an already resolved string
- res.append ("[capital=0]"+strref+": "+str (val) )
- elif type == 'c': #normal string
- res.append ("[capital=0]"+GemRB.GetString (strref) )
- elif type == 'd': #strref is an already resolved string
- res.append ("[capital=0]"+strref)
- elif type == '0': #normal value
- res.append (GemRB.GetString (strref) + ': ' + str (val) )
- else: #normal value + type character, for example percent sign
- res.append (GemRB.GetString (strref) + ': ' + str (val) + type)
- lines = 1
- except:
- if s != None:
- res.append ("[capital=0]"+ GemRB.GetString (s) )
- lines = 0
- else:
- if not lines:
- res.append (str_None)
- res.append ("")
- lines = 0
-
- return "\n".join (res)
-
-
-def GetReputation (repvalue):
- table = GemRB.LoadTable ("reptxt")
- if repvalue>20:
- repvalue=20
- txt = GemRB.GetString (table.GetValue (repvalue, 0) )
- return txt+" ("+str (repvalue)+")"
-
-
-def OpenInformationWindow ():
- global InformationWindow
-
- if InformationWindow != None:
- if BiographyWindow:
- OpenBiographyWindow ()
-
- if InformationWindow:
- InformationWindow.Unload ()
- OptionsWindow.SetVisible (WINDOW_FRONT)
- RecordsWindow.SetVisible (WINDOW_FRONT)
- PortraitWindow.SetVisible (WINDOW_FRONT)
- InformationWindow = None
-
- return
-
- InformationWindow = Window = GemRB.LoadWindow (4)
-
- # Biography
- Button = Window.GetControl (26)
- Button.SetText (18003)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenBiographyWindow)
-
- # Done
- Button = Window.GetControl (24)
- Button.SetText (11973)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenInformationWindow)
-
- TotalPartyExp = 0
- ChapterPartyExp = 0
- TotalCount = 0
- ChapterCount = 0
- for i in range (1, GemRB.GetPartySize () + 1):
- stat = GemRB.GetPCStats(i)
- TotalPartyExp = TotalPartyExp + stat['KillsTotalXP']
- ChapterPartyExp = ChapterPartyExp + stat['KillsChapterXP']
- TotalCount = TotalCount + stat['KillsTotalCount']
- ChapterCount = ChapterCount + stat['KillsChapterCount']
-
- # These are used to get the stats
- pc = GemRB.GameGetSelectedPCSingle ()
- stat = GemRB.GetPCStats (pc)
-
- Label = Window.GetControl (0x10000000)
- Label.SetText (GemRB.GetPlayerName (pc, 1))
- # class
- ClassTitle = GUICommon.GetActorClassTitle (pc)
- Label = Window.GetControl (0x10000018)
- Label.SetText (ClassTitle)
-
- #most powerful vanquished
- Label = Window.GetControl (0x10000005)
- #we need getstring, so -1 will translate to empty string
- Label.SetText (GemRB.GetString (stat['BestKilledName']))
-
- # NOTE: currentTime is in seconds, joinTime is in seconds * 15
- # (script updates???). In each case, there are 60 seconds
- # in a minute, 24 hours in a day, but ONLY 5 minutes in an hour!!
- # Hence currentTime (and joinTime after div by 15) has
- # 7200 secs a day (60 * 5 * 24)
- currentTime = GemRB.GetGameTime ()
- joinTime = stat['JoinDate'] - stat['AwayTime']
-
- party_time = currentTime - (joinTime / 15)
- print "CurrentTime",currentTime
- days = party_time / 7200
- hours = (party_time % 7200) / 300
-
- GemRB.SetToken ('GAMEDAY', str (days))
- GemRB.SetToken ('HOUR', str (hours))
- Label = Window.GetControl (0x10000006)
- #actually it is 16043 <DURATION>, but duration is translated to
- #16041, hopefully this won't cause problem with international version
- Label.SetText (16041)
-
- #favourite spell
- Label = Window.GetControl (0x10000007)
- Label.SetText (stat['FavouriteSpell'])
-
- #favourite weapon
- Label = Window.GetControl (0x10000008)
- #actually it is 10479 <WEAPONNAME>, but weaponname is translated to
- #the real weapon name (which we should set using SetToken)
- #there are other strings like bow+wname/xbow+wname/sling+wname
- #are they used?
- Label.SetText (stat['FavouriteWeapon'])
-
- #total party xp
- Label = Window.GetControl (0x10000013)
- if TotalPartyExp != 0:
- PartyExp = int ((stat['KillsTotalXP'] * 100) / TotalPartyExp)
- Label.SetText (str (PartyExp) + '%')
- else:
- Label.SetText ("0%")
-
- #chapter party xp
- Label = Window.GetControl (0x1000000f)
- if ChapterPartyExp != 0:
- PartyExp = int ((stat['KillsChapterXP'] * 100) / ChapterPartyExp)
- Label.SetText (str (PartyExp) + '%')
- else:
- Label.SetText ("0%")
-
- #total xp
- Label = Window.GetControl (0x10000014)
- if TotalCount != 0:
- PartyExp = int ((stat['KillsTotalCount'] * 100) / TotalCount)
- Label.SetText (str (PartyExp) + '%')
- else:
- Label.SetText ("0%")
-
- #chapter xp
- Label = Window.GetControl (0x10000010)
- if ChapterCount != 0:
- PartyExp = int ((stat['KillsChapterCount'] * 100) / ChapterCount)
- Label.SetText (str (PartyExp) + '%')
- else:
- Label.SetText ("0%")
-
- Label = Window.GetControl (0x10000011)
- Label.SetText (str (stat['KillsChapterXP']))
- Label = Window.GetControl (0x10000015)
- Label.SetText (str (stat['KillsTotalXP']))
-
- #count of kills in chapter/game
- Label = Window.GetControl (0x10000012)
- Label.SetText (str (stat['KillsChapterCount']))
- Label = Window.GetControl (0x10000016)
- Label.SetText (str (stat['KillsTotalCount']))
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def OpenBiographyWindow ():
- global BiographyWindow
-
- if BiographyWindow != None:
- if BiographyWindow:
- BiographyWindow.Unload ()
- BiographyWindow = None
- InformationWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
- BiographyWindow = Window = GemRB.LoadWindow (12)
-
- TextArea = Window.GetControl (0)
- pc = GemRB.GameGetSelectedPCSingle ()
- TextArea.SetText (GemRB.GetPlayerString (pc, 74) )
-
- # Done
- Button = Window.GetControl (2)
- Button.SetText (11973)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenBiographyWindow)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
-
- return
-
-def OpenExportWindow ():
- global ExportWindow, NameField, ExportDoneButton
-
- ExportWindow = GemRB.LoadWindow (13)
-
- TextArea = ExportWindow.GetControl (2)
- TextArea.SetText (10962)
-
- TextArea = ExportWindow.GetControl (0)
- TextArea.GetCharacters ()
-
- ExportDoneButton = ExportWindow.GetControl (4)
- ExportDoneButton.SetText (11973)
- ExportDoneButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- CancelButton = ExportWindow.GetControl (5)
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- NameField = ExportWindow.GetControl (6)
-
- ExportDoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, ExportDonePress)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, ExportCancelPress)
- NameField.SetEvent (IE_GUI_EDIT_ON_CHANGE, ExportEditChanged)
- ExportWindow.ShowModal (MODAL_SHADOW_GRAY)
- NameField.SetStatus (IE_GUI_CONTROL_FOCUSED)
- return
-
-def ExportDonePress():
- if ExportWindow:
- ExportWindow.Unload()
- #save file under name from EditControl
- pc = GemRB.GameGetSelectedPCSingle ()
- GemRB.SaveCharacter (pc, ExportFileName)
- return
-
-def ExportCancelPress():
- if ExportWindow:
- ExportWindow.Unload()
- return
-
-def ExportEditChanged():
- global ExportFileName
-
- ExportFileName = NameField.QueryText ()
- if ExportFileName == "":
- ExportDoneButton.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- ExportDoneButton.SetState (IE_GUI_BUTTON_ENABLED)
- return
-
-def OpenKitInfoWindow ():
- global KitInfoWindow
-
- KitInfoWindow = GemRB.LoadWindow (24)
-
- #back button (setting first, to be less error prone)
- DoneButton = KitInfoWindow.GetControl (2)
- DoneButton.SetText (11973)
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, KitDonePress)
-
- #kit or class description
- TextArea = KitInfoWindow.GetControl (0)
-
- pc = GemRB.GameGetSelectedPCSingle ()
- Class = GemRB.GetPlayerStat (pc, IE_CLASS)
- ClassIndex = CommonTables.Classes.FindValue (5, Class)
- Multi = CommonTables.Classes.GetValue (ClassIndex, 4)
- Dual = GUICommon.IsDualClassed (pc, 1)
-
- if Multi and Dual[0] == 0: # true multi class
- text = CommonTables.Classes.GetValue (ClassIndex, 1)
- TextArea.SetText (text)
- KitInfoWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
- KitIndex = GUICommon.GetKitIndex (pc)
-
- if Dual[0]: # dual class
- # first (previous) kit or class of the dual class
- if Dual[0] == 1:
- text = CommonTables.KitList.GetValue (Dual[1], 3)
- elif Dual[0] == 2:
- text = CommonTables.Classes.GetValue (Dual[1], 1)
-
- TextArea.SetText (text)
- TextArea.Append ("\n\n")
- text = CommonTables.Classes.GetValue (Dual[2], 1)
-
- else: # ordinary class or kit
- if KitIndex:
- text = CommonTables.KitList.GetValue (KitIndex, 3)
- else:
- text = CommonTables.Classes.GetValue (ClassIndex, 1)
-
- TextArea.Append (text)
-
- KitInfoWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def KitDonePress():
- if KitInfoWindow:
- KitInfoWindow.Unload()
- return
-
-def OpenCustomizeWindow ():
- global CustomizeWindow
- global PortraitsTable, ScriptsTable, ColorTable
-
- pc = GemRB.GameGetSelectedPCSingle ()
- if GemRB.GetPlayerStat (pc, IE_MC_FLAGS)&MC_EXPORTABLE:
- Exportable = 1
- else:
- Exportable = 0
-
- PortraitsTable = GemRB.LoadTable ("PICTURES")
- ScriptsTable = GemRB.LoadTable ("SCRPDESC")
- ColorTable = GemRB.LoadTable ("CLOWNCOL")
- CustomizeWindow = GemRB.LoadWindow (17)
-
- AppearanceButton = CustomizeWindow.GetControl (0)
- AppearanceButton.SetText (11961)
- if not Exportable:
- AppearanceButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- SoundButton = CustomizeWindow.GetControl (1)
- SoundButton.SetText (10647)
- if not Exportable:
- SoundButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- ColorButton = CustomizeWindow.GetControl (2)
- ColorButton.SetText (10646)
- if not Exportable:
- ColorButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- ScriptButton = CustomizeWindow.GetControl (3)
- ScriptButton.SetText (17111)
-
- BiographyButton = CustomizeWindow.GetControl (9)
- BiographyButton.SetText (18003)
- if not Exportable:
- BiographyButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- TextArea = CustomizeWindow.GetControl (5)
- TextArea.SetText (11327)
-
- DoneButton = CustomizeWindow.GetControl (7)
- DoneButton.SetText (11973)
- DoneButton.SetState (IE_GUI_BUTTON_ENABLED)
-
- CancelButton = CustomizeWindow.GetControl (8);
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- AppearanceButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenAppearanceWindow)
- SoundButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenSoundWindow)
- ColorButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenColorWindow)
- ScriptButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenScriptWindow)
- BiographyButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenBiographyEditWindow)
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CustomizeDonePress)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CustomizeCancelPress)
-
- CustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def CustomizeDonePress ():
- global CustomizeWindow
-
- if CustomizeWindow:
- CustomizeWindow.Unload ()
- CustomizeWindow = None
-
- UpdateRecordsWindow ()
- return
-
-def CustomizeCancelPress ():
- global CustomizeWindow
-
- if CustomizeWindow:
- CustomizeWindow.Unload ()
- CustomizeWindow = None
-
- UpdateRecordsWindow ()
- return
-
-def OpenAppearanceWindow ():
- global SubCustomizeWindow
- global PortraitButton
- global Gender, LastPortrait
-
- SubCustomizeWindow = GemRB.LoadWindow (18)
- pc = GemRB.GameGetSelectedPCSingle ()
- Gender = GemRB.GetPlayerStat (pc, IE_SEX, 1)
- PortraitName = GemRB.GetPlayerPortrait (pc, 0)
- LastPortrait = PortraitsTable.GetRowIndex (PortraitName[0:len(PortraitName)-1])
-
- PortraitButton = SubCustomizeWindow.GetControl (0)
- PortraitButton.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_NO_IMAGE,OP_SET)
- PortraitButton.SetState (IE_GUI_BUTTON_LOCKED)
-
- LeftButton = SubCustomizeWindow.GetControl (1)
- RightButton = SubCustomizeWindow.GetControl (2)
-
- DoneButton = SubCustomizeWindow.GetControl (3)
- DoneButton.SetText (11973)
- DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- CancelButton = SubCustomizeWindow.GetControl (4)
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- CustomPortraitButton = SubCustomizeWindow.GetControl (5)
- CustomPortraitButton.SetText (17545)
-
- LeftButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, PortraitLeftPress)
- RightButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, PortraitRightPress)
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DonePortraitWindow)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSubCustomizeWindow)
- CustomPortraitButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenCustomPortraitWindow)
- SubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
-
- while True:
- if PortraitsTable.GetValue (LastPortrait, 0) == Gender:
- UpdatePortrait ()
- break
- LastPortrait = LastPortrait + 1
-
- return
-
-def DonePortraitWindow ():
- pc = GemRB.GameGetSelectedPCSingle ()
- Name = PortraitsTable.GetRowName (LastPortrait)
- GemRB.FillPlayerInfo (pc, Name + "M", Name + "S")
- CloseSubCustomizeWindow ()
- return
-
-def PortraitRightPress():
- global LastPortrait
-
- while True:
- LastPortrait = LastPortrait + 1
- if LastPortrait >= PortraitsTable.GetRowCount ():
- LastPortrait = 0
- if PortraitsTable.GetValue (LastPortrait, 0) == Gender:
- UpdatePortrait ()
- return
-
- return
-
-def PortraitLeftPress():
- global LastPortrait
-
- while True:
- LastPortrait = LastPortrait - 1
- if LastPortrait < 0:
- LastPortrait = PortraitsTable.GetRowCount ()-1
- if PortraitsTable.GetValue (LastPortrait, 0) == Gender:
- UpdatePortrait ()
- return
-
- return
-
-def UpdatePortrait ():
- PortraitName = PortraitsTable.GetRowName (LastPortrait)+"L"
- PortraitButton.SetPicture (PortraitName, "NOPORTLG")
- return
-
-def OpenCustomPortraitWindow ():
- global SubSubCustomizeWindow
- global PortraitList1, PortraitList2
- global RowCount1, RowCount2
-
- SubSubCustomizeWindow = GemRB.LoadWindow (19)
-
- SmallPortraitButton = SubSubCustomizeWindow.GetControl (1)
- SmallPortraitButton.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_NO_IMAGE,OP_SET)
-
- LargePortraitButton = SubSubCustomizeWindow.GetControl (0)
- LargePortraitButton.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_NO_IMAGE,OP_SET)
-
- DoneButton = SubSubCustomizeWindow.GetControl (10)
- DoneButton.SetText (11973)
- DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
- DoneButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- CancelButton = SubSubCustomizeWindow.GetControl (11)
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- # Portrait List Large
- PortraitList1 = SubSubCustomizeWindow.GetControl (2)
- RowCount1 = PortraitList1.GetPortraits (0)
- PortraitList1.SetEvent (IE_GUI_TEXTAREA_ON_CHANGE, LargeCustomPortrait)
- GemRB.SetVar ("Row1", RowCount1)
- PortraitList1.SetVarAssoc ("Row1",RowCount1)
-
- # Portrait List Small
- PortraitList2 = SubSubCustomizeWindow.GetControl (3)
- RowCount2 = PortraitList2.GetPortraits (1)
- PortraitList2.SetEvent (IE_GUI_TEXTAREA_ON_CHANGE, SmallCustomPortrait)
- GemRB.SetVar ("Row2", RowCount2)
- PortraitList2.SetVarAssoc ("Row2",RowCount2)
-
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DonePortraitCustomizeWindow)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSubSubCustomizeWindow)
-
- SubSubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DonePortraitCustomizeWindow ():
- pc = GemRB.GameGetSelectedPCSingle ()
- GemRB.FillPlayerInfo (pc, PortraitList1.QueryText () , PortraitList2.QueryText ())
- CloseSubSubCustomizeWindow ()
- #closing the generic portraits, because we just set a custom one
- CloseSubCustomizeWindow ()
- return
-
-def LargeCustomPortrait ():
- Window = SubSubCustomizeWindow
-
- Portrait = PortraitList1.QueryText ()
- #small hack
- if GemRB.GetVar ("Row1") == RowCount1:
- return
-
- Label = Window.GetControl (0x10000007)
- Label.SetText (Portrait)
-
- Button = Window.GetControl (10)
- if Portrait=="":
- Portrait = "NOPORTMD"
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- if PortraitList2.QueryText ()!="":
- Button.SetState (IE_GUI_BUTTON_ENABLED)
-
- Button = Window.GetControl (0)
- Button.SetPicture (Portrait, "NOPORTMD")
- return
-
-def SmallCustomPortrait ():
- Window = SubSubCustomizeWindow
-
- Portrait = PortraitList2.QueryText ()
- #small hack
- if GemRB.GetVar ("Row2") == RowCount2:
- return
-
- Label = Window.GetControl (0x10000008)
- Label.SetText (Portrait)
-
- Button = Window.GetControl (10)
- if Portrait=="":
- Portrait = "NOPORTSM"
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- if PortraitList1.QueryText ()!="":
- Button.SetState (IE_GUI_BUTTON_ENABLED)
-
- Button = Window.GetControl (1)
- Button.SetPicture (Portrait, "NOPORTSM")
- return
-
-def OpenSoundWindow ():
- global SubCustomizeWindow
- global VoiceList
- global Gender
- global OldVoiceSet
-
- pc = GemRB.GameGetSelectedPCSingle ()
- OldVoiceSet = GemRB.GetPlayerSound (pc)
- SubCustomizeWindow = GemRB.LoadWindow (20)
-
- VoiceList = SubCustomizeWindow.GetControl (5)
- VoiceList.SetFlags (IE_GUI_TEXTAREA_SELECTABLE)
- Gender = GemRB.GetPlayerStat (pc, IE_SEX, 1)
-
- VoiceList.SetVarAssoc ("Selected", 0)
- RowCount=VoiceList.GetCharSounds()
- VoiceList.SelectText (OldVoiceSet)
-
- PlayButton = SubCustomizeWindow.GetControl (7)
- PlayButton.SetText (17318)
-
- TextArea = SubCustomizeWindow.GetControl (8)
- TextArea.SetText (11315)
-
- DoneButton = SubCustomizeWindow.GetControl (10)
- DoneButton.SetText (11973)
- DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- CancelButton = SubCustomizeWindow.GetControl (11)
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- PlayButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, PlaySoundPressed)
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DoneSoundWindow)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSoundWindow)
-
- SubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def CloseSoundWindow ():
- pc = GemRB.GameGetSelectedPCSingle ()
- GemRB.SetPlayerSound (pc, OldVoiceSet)
- CloseSubCustomizeWindow ()
- return
-
-def DoneSoundWindow ():
- pc = GemRB.GameGetSelectedPCSingle ()
- CharSound = VoiceList.QueryText ()
- GemRB.SetPlayerSound (pc, CharSound)
-
- CloseSubCustomizeWindow ()
- return
-
-def PlaySoundPressed():
- global CharSoundWindow, SoundIndex, SoundSequence
-
- CharSound = VoiceList.QueryText ()
- tmp = SoundIndex
- while (not GemRB.HasResource (CharSound + SoundSequence[SoundIndex], RES_WAV)):
- NextSound()
- if SoundIndex == tmp:
- break
- else:
- NextSound()
- GemRB.PlaySound (CharSound + SoundSequence[SoundIndex], 0, 0, 5)
- return
-
-def NextSound():
- global SoundIndex, SoundSequence
- SoundIndex += 1
- if SoundIndex >= len(SoundSequence):
- SoundIndex = 0
- return
-
-def OpenColorWindow ():
- global SubCustomizeWindow
- global PortraitWindow
- global PortraitButton
- global HairButton, SkinButton, MajorButton, MinorButton
- global HairColor, SkinColor, MajorColor, MinorColor
-
- pc = GemRB.GameGetSelectedPCSingle ()
- MinorColor = GemRB.GetPlayerStat (pc, IE_MINOR_COLOR)
- MajorColor = GemRB.GetPlayerStat (pc, IE_MAJOR_COLOR)
- SkinColor = GemRB.GetPlayerStat (pc, IE_SKIN_COLOR)
- HairColor = GemRB.GetPlayerStat (pc, IE_HAIR_COLOR)
- SubCustomizeWindow = GemRB.LoadWindow (21)
-
- PortraitButton = SubCustomizeWindow.GetControl (0)
- PortraitButton.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_NO_IMAGE,OP_SET)
- PortraitButton.SetState (IE_GUI_BUTTON_LOCKED)
-
- HairButton = SubCustomizeWindow.GetControl (3)
- SkinButton = SubCustomizeWindow.GetControl (4)
- MajorButton = SubCustomizeWindow.GetControl (5)
- MinorButton = SubCustomizeWindow.GetControl (6)
-
- DoneButton = SubCustomizeWindow.GetControl (12)
- DoneButton.SetText (11973)
- DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- CancelButton = SubCustomizeWindow.GetControl (13)
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- HairButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, SetHairColor)
- SkinButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, SetSkinColor)
- MajorButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, SetMajorColor)
- MinorButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, SetMinorColor)
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DoneColorWindow)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSubCustomizeWindow)
- UpdatePaperDoll ()
-
- SubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DoneColorWindow ():
- pc = GemRB.GameGetSelectedPCSingle ()
- GemRB.SetPlayerStat (pc, IE_MINOR_COLOR, MinorColor)
- GemRB.SetPlayerStat (pc, IE_MAJOR_COLOR, MajorColor)
- GemRB.SetPlayerStat (pc, IE_SKIN_COLOR, SkinColor)
- GemRB.SetPlayerStat (pc, IE_HAIR_COLOR, HairColor)
- CloseSubCustomizeWindow ()
- return
-
-def UpdatePaperDoll ():
- pc = GemRB.GameGetSelectedPCSingle ()
- Color1 = GemRB.GetPlayerStat (pc, IE_METAL_COLOR)
- MinorButton.SetBAM ("COLGRAD", 0, 0, MinorColor&0xff)
- MajorButton.SetBAM ("COLGRAD", 0, 0, MajorColor&0xff)
- SkinButton.SetBAM ("COLGRAD", 0, 0, SkinColor&0xff)
- Color5 = GemRB.GetPlayerStat (pc, IE_LEATHER_COLOR)
- Color6 = GemRB.GetPlayerStat (pc, IE_ARMOR_COLOR)
- HairButton.SetBAM ("COLGRAD", 0, 0, HairColor&0xff)
- PortraitButton.SetPLT (GUICommon.GetActorPaperDoll (pc),
- Color1, MinorColor, MajorColor, SkinColor, Color5, Color6, HairColor, 0, 0)
- return
-
-def SetHairColor ():
- global ColorIndex, PickedColor
-
- ColorIndex = 0
- PickedColor = HairColor
- OpenColorPicker ()
- return
-
-def SetSkinColor ():
- global ColorIndex, PickedColor
-
- ColorIndex = 1
- PickedColor = SkinColor
- OpenColorPicker ()
- return
-
-def SetMinorColor ():
- global ColorIndex, PickedColor
-
- ColorIndex = 2
- PickedColor = MinorColor
- OpenColorPicker ()
- return
-
-def SetMajorColor ():
- global ColorIndex, PickedColor
-
- ColorIndex = 3
- PickedColor = MajorColor
- OpenColorPicker ()
- return
-
-def OpenColorPicker ():
- global SubSubCustomizeWindow
- #global Selected
-
- SubSubCustomizeWindow = GemRB.LoadWindow (22)
-
- GemRB.SetVar ("Selected",-1)
- for i in range (1,35):
- Button = SubSubCustomizeWindow.GetControl (i)
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_RADIOBUTTON,OP_OR)
-
- #Selected = -1
- for i in range (34):
- MyColor = ColorTable.GetValue (ColorIndex, i)
- if MyColor == "*":
- break
- Button = SubSubCustomizeWindow.GetControl (i+1)
- Button.SetBAM("COLGRAD", 2, 0, MyColor)
- if PickedColor == MyColor:
- GemRB.SetVar ("Selected",i)
- #Selected = i
- Button.SetState (IE_GUI_BUTTON_ENABLED)
- Button.SetVarAssoc("Selected",i)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, DonePress)
-
- SubSubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DonePress():
- global HairColor, SkinColor, MajorColor, MinorColor
- global PickedColor
-
- CloseSubSubCustomizeWindow ()
- PickedColor=ColorTable.GetValue (ColorIndex, GemRB.GetVar ("Selected"))
- if ColorIndex==0:
- HairColor=PickedColor
- UpdatePaperDoll ()
- return
- if ColorIndex==1:
- SkinColor=PickedColor
- UpdatePaperDoll ()
- return
- if ColorIndex==2:
- MinorColor=PickedColor
- UpdatePaperDoll ()
- return
-
- MajorColor=PickedColor
- UpdatePaperDoll ()
- return
-
-def OpenScriptWindow ():
- global SubCustomizeWindow
- global ScriptTextArea, SelectedTextArea
-
- SubCustomizeWindow = GemRB.LoadWindow (11)
-
- ScriptTextArea = SubCustomizeWindow.GetControl (2)
- ScriptTextArea.SetFlags (IE_GUI_TEXTAREA_SELECTABLE)
- FillScriptList ()
- pc = GemRB.GameGetSelectedPCSingle ()
- script = GemRB.GetPlayerScript (pc)
- scriptindex = ScriptsTable.GetRowIndex (script)
- GemRB.SetVar ("Selected", scriptindex)
- ScriptTextArea.SetVarAssoc ("Selected", scriptindex)
-
- SelectedTextArea = SubCustomizeWindow.GetControl (4)
- UpdateScriptSelection ()
-
- DoneButton = SubCustomizeWindow.GetControl (5)
- DoneButton.SetText (11973)
- DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- CancelButton = SubCustomizeWindow.GetControl (6)
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DoneScriptWindow)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSubCustomizeWindow)
- ScriptTextArea.SetEvent (IE_GUI_TEXTAREA_ON_CHANGE, UpdateScriptSelection)
-
- SubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def FillScriptList ():
- ScriptTextArea.Clear ()
- row = ScriptsTable.GetRowCount ()
- for i in range (row):
- GemRB.SetToken ("script", ScriptsTable.GetRowName (i) )
- title = ScriptsTable.GetValue (i,0)
- if title!=-1:
- desc = ScriptsTable.GetValue (i,1)
- txt = GemRB.GetString (title)
-
- if (desc!=-1):
- txt += GemRB.GetString (desc)
-
- ScriptTextArea.Append (txt+"\n", -1)
-
- else:
- ScriptTextArea.Append (ScriptsTable.GetRowName (i)+"\n" ,-1)
-
- return
-
-def DoneScriptWindow ():
- pc = GemRB.GameGetSelectedPCSingle ()
- script = ScriptsTable.GetRowName (GemRB.GetVar ("Selected") )
- GemRB.SetPlayerScript (pc, script)
- CloseSubCustomizeWindow ()
- return
-
-def UpdateScriptSelection():
- text = ScriptTextArea.QueryText ()
- SelectedTextArea.SetText (text)
- return
-
-def OpenBiographyEditWindow ():
- global SubCustomizeWindow
- global BioStrRef
- global TextArea
-
- Changed = 0
- pc = GemRB.GameGetSelectedPCSingle ()
- BioStrRef = GemRB.GetPlayerString (pc, 74)
- if BioStrRef != 33347:
- Changed = 1
-
- SubCustomizeWindow = GemRB.LoadWindow (23)
-
- ClearButton = SubCustomizeWindow.GetControl (5)
- ClearButton.SetText (34881)
-
- DoneButton = SubCustomizeWindow.GetControl (1)
- DoneButton.SetText (11973)
- DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- RevertButton = SubCustomizeWindow.GetControl (3)
- RevertButton.SetText (2240)
- if not Changed:
- RevertButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- CancelButton = SubCustomizeWindow.GetControl (2)
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- TextArea = SubCustomizeWindow.GetControl (4)
- TextArea.SetBufferLength (65535)
- TextArea.SetText (BioStrRef)
-
- ClearButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, ClearBiography)
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DoneBiographyWindow)
- RevertButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, RevertBiography)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSubCustomizeWindow)
-
- SubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def ClearBiography():
- pc = GemRB.GameGetSelectedPCSingle ()
- BioStrRef = 62015+pc
- #GemRB.CreateString (BioStrRef, "")
- TextArea.SetText ("")
- return
-
-def DoneBiographyWindow ():
- global BioStrRef
-
- #TODO set bio
- pc = GemRB.GameGetSelectedPCSingle ()
- #pc is 1 based
- BioStrRef = 62015+pc
- GemRB.CreateString (BioStrRef, TextArea.QueryText())
- GemRB.SetPlayerString (pc, 74, BioStrRef)
- CloseSubCustomizeWindow ()
- return
-
-def RevertBiography():
- global BioStrRef
-
- BioStrRef = 33347
- TextArea.SetText (33347)
- return
-
-def CloseSubCustomizeWindow ():
- global SubCustomizeWindow
-
- if SubCustomizeWindow:
- SubCustomizeWindow.Unload ()
- SubCustomizeWindow = None
- return
-
-def CloseSubSubCustomizeWindow ():
- global SubSubCustomizeWindow
-
- if SubSubCustomizeWindow:
- SubSubCustomizeWindow.Unload ()
- SubSubCustomizeWindow = None
- return
-
-###################################################
-# End of file GUIREC.py
diff --git a/gemrb/GUIScripts/bg2/GUISAVE.py b/gemrb/GUIScripts/bg2/GUISAVE.py
deleted file mode 100644
index 5f3d0f3..0000000
--- a/gemrb/GUIScripts/bg2/GUISAVE.py
+++ /dev/null
@@ -1,281 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-
-# GUISAVE.py - Save window
-
-###################################################
-
-import GemRB
-import GUICommon
-import LoadScreen
-from GUIDefines import *
-
-SaveWindow = 0
-ConfirmWindow = 0
-NameField = 0
-SaveButton = 0
-TextAreaControl = 0
-Games = ()
-ScrollBar = 0
-str_chapter = (48007, 48006, 16205, 16206, 16207, 16208, 16209, 71020, 71021, 71022)
-
-def OpenSaveWindow ():
- global SaveWindow, TextAreaControl, Games, ScrollBar
-
- if GUICommon.CloseOtherWindow (OpenSaveWindow):
- CloseSaveWindow ()
- return
-
- GemRB.HideGUI ()
- GUICommon.GameWindow.SetVisible(WINDOW_INVISIBLE)
-
- GemRB.LoadWindowPack ("GUISAVE", 640, 480)
- Window = SaveWindow = GemRB.LoadWindow (0)
- Window.SetFrame ()
- CancelButton=Window.GetControl (34)
- CancelButton.SetText (13727)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenSaveWindow)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
- GemRB.SetVar ("LoadIdx",0)
-
- for i in range(4):
- Button = Window.GetControl (26+i)
- Button.SetText (15588)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SavePress)
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- Button.SetVarAssoc ("LoadIdx",i)
-
- Button = Window.GetControl (30+i)
- Button.SetText (13957)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, DeleteGamePress)
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- Button.SetVarAssoc ("LoadIdx",i)
-
- #area previews
- Button = Window.GetControl (1+i)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- Button.SetFlags(IE_GUI_BUTTON_NO_IMAGE|IE_GUI_BUTTON_PICTURE,OP_SET)
-
- #PC portraits
- for j in range(PARTY_SIZE):
- Button = Window.GetControl (40+i*PARTY_SIZE+j)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- Button.SetFlags(IE_GUI_BUTTON_NO_IMAGE|IE_GUI_BUTTON_PICTURE,OP_SET)
-
- ScrollBar=Window.GetControl (25)
- ScrollBar.SetEvent (IE_GUI_SCROLLBAR_ON_CHANGE, ScrollBarPress)
- Games=GemRB.GetSaveGames ()
- TopIndex = max (0, len(Games) - 4 + 1) #one more for the 'new game'
- GemRB.SetVar ("TopIndex",TopIndex)
- ScrollBar.SetVarAssoc ("TopIndex", TopIndex+1)
- ScrollBar.SetDefaultScrollBar ()
- ScrollBarPress ()
- Window.SetVisible (WINDOW_VISIBLE)
- return
-
-def ScrollBarPress():
- Window = SaveWindow
-
- #draw load game portraits
- Pos = GemRB.GetVar ("TopIndex")
- for i in range(4):
- ActPos = Pos + i
-
- Button1 = Window.GetControl (26+i)
- Button2 = Window.GetControl (30+i)
- if ActPos<=len(Games):
- Button1.SetState (IE_GUI_BUTTON_ENABLED)
- else:
- Button1.SetState (IE_GUI_BUTTON_DISABLED)
-
- if ActPos<len(Games):
- Slotname = Games[ActPos].GetName()
- Button2.SetState (IE_GUI_BUTTON_ENABLED)
- elif ActPos == len(Games):
- Slotname = 15304
- Button2.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- Slotname = ""
- Button2.SetState (IE_GUI_BUTTON_DISABLED)
-
- Label = Window.GetControl (0x10000008+i)
- Label.SetText (Slotname)
-
- if ActPos<len(Games):
- Slotname = Games[ActPos].GetGameDate()
- else:
- Slotname = ""
- Label = Window.GetControl (0x10000010+i)
- Label.SetText (Slotname)
-
- Button=Window.GetControl (1+i)
- if ActPos<len(Games):
- Button.SetSprite2D(Games[ActPos].GetPreview())
- else:
- Button.SetPicture("")
- for j in range(PARTY_SIZE):
- Button=Window.GetControl (40+i*PARTY_SIZE+j)
- if ActPos<len(Games):
- Button.SetSprite2D(Games[ActPos].GetPortrait(j))
- else:
- Button.SetPicture("")
- return
-
-def AbortedSaveGame():
- if ConfirmWindow:
- ConfirmWindow.Unload ()
- SaveWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def ConfirmedSaveGame():
- global ConfirmWindow
-
- Pos = GemRB.GetVar ("TopIndex")+GemRB.GetVar ("LoadIdx")
- Label = ConfirmWindow.GetControl (3)
- Slotname = Label.QueryText ()
- LoadScreen.StartLoadScreen()
- if Pos < len(Games):
- GemRB.SaveGame(Games[Pos], Slotname)
- else:
- GemRB.SaveGame(None, Slotname)
- if ConfirmWindow:
- ConfirmWindow.Unload ()
- OpenSaveWindow() # close window
- return
-
-def SavePress():
- global ConfirmWindow, NameField, SaveButton
-
- Pos = GemRB.GetVar ("TopIndex")+GemRB.GetVar ("LoadIdx")
- ConfirmWindow = GemRB.LoadWindow (1)
-
- #slot name
- if Pos<len(Games):
- Slotname = Games[Pos].GetName();
- save_strref = 15306
- else:
- Slotname = ""
- save_strref = 15588
- NameField = ConfirmWindow.GetControl (3)
- NameField.SetText (Slotname)
- NameField.SetEvent (IE_GUI_EDIT_ON_CHANGE, EditChange)
-
- #game hours (should be generated from game)
- if Pos<len(Games):
- Chapter = GemRB.GetGameVar ("CHAPTER") & 0x7fffffff
- Slotname = GemRB.GetString(str_chapter[Chapter-1]) + " " + Games[Pos].GetGameDate()
- else:
- Slotname = ""
- Label = ConfirmWindow.GetControl (0x10000004)
- Label.SetText (Slotname)
-
- #areapreview
- Button=ConfirmWindow.GetControl (0)
- if Pos<len(Games):
- Button.SetSprite2D(Games[Pos].GetPreview())
- else:
- Button.SetPicture("")
-
- #portraits
- for j in range(PARTY_SIZE):
- Button=ConfirmWindow.GetControl (40+j)
- if Pos<len(Games):
- Button.SetSprite2D(Games[Pos].GetPortrait(j))
- else:
- Button.SetPicture("")
-
- #save
- SaveButton=ConfirmWindow.GetControl (7)
- SaveButton.SetText (save_strref)
- SaveButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, ConfirmedSaveGame)
- SaveButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
- #SaveButton.SetState (IE_GUI_BUTTON_DISABLED)
- if Slotname == "":
- SaveButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- #cancel
- CancelButton=ConfirmWindow.GetControl (8)
- CancelButton.SetText (13727)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, AbortedSaveGame)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- ConfirmWindow.SetVisible (WINDOW_VISIBLE)
- NameField.SetStatus (IE_GUI_CONTROL_FOCUSED)
- return
-
-def EditChange():
- Name = NameField.QueryText ()
- if len(Name)==0:
- SaveButton.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- SaveButton.SetState (IE_GUI_BUTTON_ENABLED)
- return
-
-def DeleteGameConfirm():
- global Games
-
- TopIndex = GemRB.GetVar ("TopIndex")
- Pos = TopIndex +GemRB.GetVar ("LoadIdx")
- GemRB.DeleteSaveGame(Games[Pos])
- del Games[Pos]
- if TopIndex>0:
- GemRB.SetVar ("TopIndex",TopIndex-1)
- ScrollBar.SetVarAssoc ("TopIndex", len(Games))
- ScrollBarPress()
- if ConfirmWindow:
- ConfirmWindow.Unload ()
- SaveWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def DeleteGameCancel():
- if ConfirmWindow:
- ConfirmWindow.Unload ()
- SaveWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def DeleteGamePress():
- global ConfirmWindow
-
- SaveWindow.SetVisible (WINDOW_INVISIBLE)
- ConfirmWindow=GemRB.LoadWindow (2)
- Text=ConfirmWindow.GetControl (0)
- Text.SetText (15305)
- DeleteButton=ConfirmWindow.GetControl (1)
- DeleteButton.SetText (13957)
- DeleteButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DeleteGameConfirm)
- CancelButton=ConfirmWindow.GetControl (2)
- CancelButton.SetText (13727)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DeleteGameCancel)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- ConfirmWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def CloseSaveWindow ():
- if SaveWindow:
- SaveWindow.Unload ()
- if GemRB.GetVar ("QuitAfterSave"):
- GemRB.QuitGame ()
- GemRB.SetNextScript ("Start")
- return
-
- GUICommon.GameWindow.SetVisible(WINDOW_VISIBLE) #enabling the game control screen
- GemRB.UnhideGUI () #enabling the other windows
- return
diff --git a/gemrb/GUIScripts/bg2/GUIWORLD.py b/gemrb/GUIScripts/bg2/GUIWORLD.py
deleted file mode 100644
index e9f207b..0000000
--- a/gemrb/GUIScripts/bg2/GUIWORLD.py
+++ /dev/null
@@ -1,335 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-
-# GUIW.py - scripts to control some windows from the GUIWORLD winpack
-# except of Actions, Portrait, Options and Dialog windows
-#################################################################
-
-import GemRB
-from GUIDefines import *
-import GUICommon
-import GUICommonWindows
-import GUIClasses
-from ie_stats import *
-import MessageWindow
-import CommonWindow
-
-FRAME_PC_SELECTED = 0
-FRAME_PC_TARGET = 1
-
-EmptyWindow = None
-ContinueWindow = None
-ReformPartyWindow = None
-OldActionsWindow = None
-OldMessageWindow = None
-
-removable_pcs = []
-
-def DialogStarted ():
- global ContinueWindow, OldActionsWindow
-
- # try to force-close anything which is open
- GUICommon.CloseOtherWindow(None)
- CommonWindow.CloseContainerWindow()
-
- # we need GUI for dialogs
- GemRB.UnhideGUI()
-
- # opening control size to maximum, enabling dialog window
- GemRB.GameSetScreenFlags(GS_HIDEGUI, OP_NAND)
- GemRB.GameSetScreenFlags(GS_DIALOG, OP_OR)
-
- if GUICommonWindows.PortraitWindow:
- GUICommonWindows.UpdatePortraitWindow ()
-
- # we want this to happen before we start fiddling with the GUI
- MessageWindow.UpdateControlStatus()
-
- GemRB.LoadWindowPack (GUICommon.GetWindowPack())
- ContinueWindow = Window = GemRB.LoadWindow (9)
-
- GUICommonWindows.EmptyControls()
- OldActionsWindow = GUICommonWindows.ActionsWindow
- #GUICommonWindows.ActionsWindow = None
- OldActionsWindow.SetVisible(WINDOW_INVISIBLE)
- GemRB.SetVar ("ActionsWindow", -1)
-
-def DialogEnded ():
- global ContinueWindow, OldActionsWindow
-
- # TODO: why is this being called at game start?!
- if not ContinueWindow:
- return
-
- #GUICommonWindows.ActionsWindow = OldActionsWindow
- OldActionsWindow.SetVisible(WINDOW_VISIBLE)
- GemRB.SetVar ("ActionsWindow", OldActionsWindow.ID)
- GUICommonWindows.UpdateActionsWindow()
-
- ContinueWindow.Unload ()
- ContinueWindow = None
- OldActionsWindow = None
-
- if GUICommonWindows.PortraitWindow:
- GUICommonWindows.UpdatePortraitWindow ()
-
-def CloseContinueWindow ():
- # don't close the actual window now to avoid flickering: we might still want it open
- GemRB.SetVar ("DialogChoose", GemRB.GetVar ("DialogOption"))
-
-def NextDialogState ():
- if not ContinueWindow:
- return
-
- ContinueWindow.SetVisible(WINDOW_INVISIBLE)
- OldActionsWindow.SetVisible(WINDOW_VISIBLE)
-
- MessageWindow.TMessageTA.SetStatus (IE_GUI_CONTROL_FOCUSED)
-
-def OpenEndMessageWindow ():
- ContinueWindow.SetVisible(WINDOW_VISIBLE)
- OldActionsWindow.SetVisible(WINDOW_INVISIBLE)
- Button = ContinueWindow.GetControl (0)
- Button.SetText (9371)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseContinueWindow)
- Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
- Button.SetStatus (IE_GUI_CONTROL_FOCUSED)
-
-def OpenContinueMessageWindow ():
- ContinueWindow.SetVisible(WINDOW_VISIBLE)
- OldActionsWindow.SetVisible(WINDOW_INVISIBLE)
- #continue
- Button = ContinueWindow.GetControl (0)
- Button.SetText (9372)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseContinueWindow)
- Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
- Button.SetStatus (IE_GUI_CONTROL_FOCUSED)
-
-def UpdateReformWindow ():
- Window = ReformPartyWindow
-
- select = GemRB.GetVar ("Selected")
-
- need_to_drop = GemRB.GetPartySize ()-PARTY_SIZE
- if need_to_drop<0:
- need_to_drop = 0
-
- #excess player number
- Label = Window.GetControl (0x1000000f)
- Label.SetText (str(need_to_drop) )
-
- #done
- Button = Window.GetControl (8)
- if need_to_drop:
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- Button.SetState (IE_GUI_BUTTON_ENABLED)
-
- #remove
- Button = Window.GetControl (15)
- if select:
- Button.SetState (IE_GUI_BUTTON_ENABLED)
- else:
- Button.SetState (IE_GUI_BUTTON_DISABLED)
-
- for i in range (PARTY_SIZE+1):
- Button = Window.GetControl (i)
- if i+1 not in removable_pcs:
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- continue
-
- for i in removable_pcs:
- Button = Window.GetControl (removable_pcs.index(i))
- Button.EnableBorder (FRAME_PC_SELECTED, select == i )
- pic = GemRB.GetPlayerPortrait (i, 1)
- if not pic:
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- continue
- Button.SetState (IE_GUI_BUTTON_ENABLED)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_ALIGN_BOTTOM|IE_GUI_BUTTON_ALIGN_LEFT, OP_SET)
- Button.SetPicture (pic, "NOPORTSM")
- GUICommonWindows.UpdatePortraitWindow ()
- return
-
-def RemovePlayer ():
- global ReformPartyWindow
-
- hideflag = GemRB.HideGUI ()
-
- GemRB.LoadWindowPack (GUICommon.GetWindowPack())
- if ReformPartyWindow:
- ReformPartyWindow.Unload ()
- ReformPartyWindow = Window = GemRB.LoadWindow (25)
- GemRB.SetVar ("OtherWindow", Window.ID)
-
- #are you sure
- Label = Window.GetControl (0x0fffffff)
- Label.SetText (17518)
-
- #confirm
- Button = Window.GetControl (1)
- Button.SetText (17507)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, RemovePlayerConfirm)
- Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- #cancel
- Button = Window.GetControl (2)
- Button.SetText (13727)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, RemovePlayerCancel)
- Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- GemRB.SetVar ("OtherWindow", Window.ID)
- GemRB.SetVar ("ActionsWindow", -1)
- if hideflag:
- GemRB.UnhideGUI ()
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def RemovePlayerConfirm ():
- slot = GemRB.GetVar ("Selected")
- GemRB.LeaveParty (slot, 2)
- OpenReformPartyWindow ()
- return
-
-def RemovePlayerCancel ():
- #Once for getting rid of the confirmation window
- OpenReformPartyWindow ()
- #and once for reopening the reform party window
- OpenReformPartyWindow ()
- return
-
-def OpenReformPartyWindow ():
- global ReformPartyWindow, OldActionsWindow, OldMessageWindow
- global removable_pcs
-
- GemRB.SetVar ("Selected", 0)
- hideflag = GemRB.HideGUI ()
-
- if ReformPartyWindow:
- if ReformPartyWindow:
- ReformPartyWindow.Unload ()
-
- GemRB.SetVar ("ActionsWindow", OldActionsWindow.ID)
- GemRB.SetVar ("MessageWindow", OldMessageWindow.ID)
- GemRB.SetVar ("OtherWindow", -1)
-
- OldActionsWindow = None
- OldMessageWindow = None
- ReformPartyWindow = None
- if hideflag:
- GemRB.UnhideGUI ()
- #re-enabling party size control
- GemRB.GameSetPartySize (PARTY_SIZE)
- GUICommonWindows.UpdatePortraitWindow()
- return
-
- GemRB.LoadWindowPack (GUICommon.GetWindowPack())
- ReformPartyWindow = Window = GemRB.LoadWindow (24)
- GemRB.SetVar ("OtherWindow", Window.ID)
-
- # skip exportable party members (usually only the protagonist)
- removable_pcs = []
- for i in range (1, GemRB.GetPartySize()+1):
- if not GemRB.GetPlayerStat (i, IE_MC_FLAGS)&MC_EXPORTABLE:
- removable_pcs.append(i)
-
- #PC portraits
- for j in range (PARTY_SIZE+1):
- Button = Window.GetControl (j)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON|IE_GUI_BUTTON_NO_IMAGE|IE_GUI_BUTTON_PICTURE,OP_SET)
- Button.SetBorder (FRAME_PC_SELECTED, 1, 1, 2, 2, 0, 255, 0, 255)
- if j < len(removable_pcs):
- Button.SetVarAssoc ("Selected", removable_pcs[j])
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, UpdateReformWindow)
-
- # Remove
- Button = Window.GetControl (15)
- Button.SetText (17507)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, RemovePlayer)
-
- # Done
- Button = Window.GetControl (8)
- Button.SetText (11973)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenReformPartyWindow)
-
- OldActionsWindow = GUIClasses.GWindow( GemRB.GetVar ("ActionsWindow") )
- OldMessageWindow = GUIClasses.GWindow( GemRB.GetVar ("MessageWindow") )
- GemRB.SetVar ("ActionsWindow", -1)
- GemRB.SetVar ("MessageWindow", -1)
-
- # if nobody can be removed, just close the window
- if not removable_pcs:
- OpenReformPartyWindow ()
- if hideflag:
- GemRB.UnhideGUI ()
- return
-
- UpdateReformWindow ()
- if hideflag:
- GemRB.UnhideGUI ()
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DeathWindow ():
- GemRB.HideGUI ()
- GemRB.SetTimedEvent (DeathWindowEnd, 10)
- return
-
-def DeathWindowEnd ():
- #playing death movie before continuing
- GemRB.PlayMovie ("deathand",1)
- GemRB.GamePause (1,1)
-
- GemRB.LoadWindowPack (GUICommon.GetWindowPack())
- Window = GemRB.LoadWindow (17)
-
- #reason for death
- Label = Window.GetControl (0x0fffffff)
- Label.SetText (16498)
-
- #load
- Button = Window.GetControl (1)
- Button.SetText (15590)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, LoadPress)
-
- #quit
- Button = Window.GetControl (2)
- Button.SetText (15417)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, QuitPress)
-
- GemRB.HideGUI ()
- GemRB.SetVar ("MessageWindow", -1)
- GemRB.UnhideGUI ()
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def QuitPress():
- GemRB.QuitGame ()
- GemRB.SetNextScript ("Start")
- return
-
-def LoadPress():
- GemRB.QuitGame ()
- GemRB.SetNextScript ("GUILOAD")
- return
-
diff --git a/gemrb/GUIScripts/bg2/ImportFile.py b/gemrb/GUIScripts/bg2/ImportFile.py
index ed4d579..2c0cf4a 100644
--- a/gemrb/GUIScripts/bg2/ImportFile.py
+++ b/gemrb/GUIScripts/bg2/ImportFile.py
@@ -72,5 +72,5 @@ def DonePress():
def CancelPress():
if ImportWindow:
ImportWindow.Unload()
- GemRB.SetNextScript(GemRB.GetToken("NextScript"))
+ GemRB.SetNextScript("CharGen")
return
diff --git a/gemrb/GUIScripts/bg2/LUHLASelection.py b/gemrb/GUIScripts/bg2/LUHLASelection.py
index 5b335f1..24660f8 100644
--- a/gemrb/GUIScripts/bg2/LUHLASelection.py
+++ b/gemrb/GUIScripts/bg2/LUHLASelection.py
@@ -20,7 +20,9 @@
import GemRB
from GUIDefines import *
from ie_stats import *
+from ie_spells import LS_MEMO
import GUICommon
+import Spellbook
import CommonTables
# HLA selection
@@ -43,7 +45,7 @@ def OpenHLAWindow (actor, numclasses, classes, levels):
global EnhanceGUI
#enhance GUI?
- if (GemRB.GetVar("GUIEnhancements")):
+ if (GemRB.GetVar("GUIEnhancements")&GE_SCROLLBARS):
EnhanceGUI = 1
# save our variables
@@ -124,9 +126,9 @@ def HLADonePress ():
GemRB.ApplySpell(pc, HLARef[3:])
elif HLARef[:2] == "GA":
# make sure it isn't already learned
- SpellIndex = GUICommon.HasSpell (pc, HLAType, HLALevel, HLARef[3:])
+ SpellIndex = Spellbook.HasSpell (pc, HLAType, HLALevel, HLARef[3:])
if SpellIndex < 0: # gotta learn it
- GemRB.LearnSpell (pc, HLARef[3:], 8)
+ GemRB.LearnSpell (pc, HLARef[3:], LS_MEMO)
else: # memorize it again
GemRB.MemorizeSpell (pc, HLAType, HLALevel, SpellIndex)
@@ -310,8 +312,7 @@ def GetHLAs ():
# get all the HLAs for each class
for i in range (NumClasses):
- ClassIndex = CommonTables.Classes.FindValue (5, Classes[i])
- ClassName = CommonTables.Classes.GetRowName (ClassIndex)
+ ClassName = GUICommon.GetClassRowName (Classes[i], "class")
CurrentLevel = Level[i]
if Kit != 0 and NumClasses == 1 and not IsDual: # kitted single-class
diff --git a/gemrb/GUIScripts/bg2/MessageWindow.py b/gemrb/GUIScripts/bg2/MessageWindow.py
index b91da9c..39ec8f3 100644
--- a/gemrb/GUIScripts/bg2/MessageWindow.py
+++ b/gemrb/GUIScripts/bg2/MessageWindow.py
@@ -52,17 +52,20 @@ def OnLoad():
GUICommonWindows.SetupMenuWindowControls (OptionsWindow, 1, None)
PortraitWindow = GUICommonWindows.OpenPortraitWindow(1)
- Button=OptionsWindow.GetControl(10)
- Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, MinimizeOptions)
- Button=PortraitWindow.GetControl(8)
- Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, GUICommonWindows.MinimizePortraits)
+ # 1280 and higher don't have this control
+ if OptionsWindow.HasControl (10):
+ Button = OptionsWindow.GetControl (10)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, MinimizeOptions)
+ Button = PortraitWindow.GetControl (8)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUICommonWindows.MinimizePortraits)
ActionsWindow = GemRB.LoadWindow(3)
GUICommonWindows.OpenActionsWindowControls (ActionsWindow)
- Button=ActionsWindow.GetControl(60)
- Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, MaximizeOptions)
- Button=ActionsWindow.GetControl(61)
- Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, MaximizePortraits)
+ if ActionsWindow.HasControl (60):
+ Button=ActionsWindow.GetControl(60)
+ Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, MaximizeOptions)
+ Button=ActionsWindow.GetControl(61)
+ Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, MaximizePortraits)
GemRB.SetVar("PortraitWindow", PortraitWindow.ID)
GemRB.SetVar("ActionsWindow", ActionsWindow.ID)
@@ -90,9 +93,6 @@ def MaximizeOptions():
def MaximizePortraits():
GemRB.GameSetScreenFlags(GS_PORTRAITPANE, OP_NAND)
-def TogglePartyAI():
- GemRB.GameSetScreenFlags(GS_PARTYAI, OP_XOR)
-
def UpdateControlStatus():
global MessageWindow, ExpandButton, ContractButton, TMessageTA
@@ -185,13 +185,53 @@ def FixAnomen( idx):
#do all the stuff not done yet
def FixProtagonist( idx):
- Class = GemRB.GetPlayerStat (idx, IE_CLASS)
- ClassIndex = CommonTables.Classes.FindValue (5, Class)
- ClassName = CommonTables.Classes.GetRowName (ClassIndex)
+ ClassName = GUICommon.GetClassRowName (idx)
KitIndex = GUICommon.GetKitIndex (idx)
- GiveEquipment(idx, ClassName, KitIndex)
+ # only give a few items for transitions from soa
+ if GemRB.GetVar("oldgame"):
+ # give the Amulet of Seldarine to the pc's first empty inventory slot
+ invslot = GemRB.GetSlots (idx, -1, -1)[0]
+ GemRB.CreateItem(idx, "AMUL27", invslot, 1, 0, 0)
+ GemRB.ChangeItemFlag (idx, invslot, IE_INV_ITEM_IDENTIFIED, OP_OR)
+ # TODO: give bag19/bag19a (.../19e?) based on the experience
+ invslot = GemRB.GetSlots (idx, -1, -1)[0]
+ GemRB.CreateItem(idx, "BAG19A", invslot, 1, 0, 0)
+ GemRB.ChangeItemFlag (idx, invslot, IE_INV_ITEM_IDENTIFIED, OP_OR)
+
+ # adjust the XP to the minimum if it is lower and set a difficulty variable to the difference
+ xp = GemRB.GetPlayerStat(idx, IE_XP)
+ # FIXME: not fair for disabled dual-classes (should take the inactive level xp into account)
+ xp2 = CommonTables.ClassSkills.GetValue (ClassName, "STARTXP2")
+ if xp2 > xp:
+ GemRB.SetPlayerStat(idx, IE_XP, xp2)
+ GemRB.SetGlobal("XPGIVEN","GLOBAL", xp2-xp)
+
+ FixFamiliar()
+ FixInnates()
+ else:
+ GiveEquipment(idx, ClassName, KitIndex)
return
+# TODO: replace the familiar with the improved version
+def FixFamiliar():
+ # famcat->famcat25
+ # famdust->famdus25
+ # famfair->famfai25
+ # famfer->famfer25
+ # famimp->famimp25
+ # fampsd->fampsd25
+ # famquas->famqua25
+ # famrab->famrab25
+ # resummon the familiar? Make sure the marker effect is there, so death would incur the constitution penalty
+ pass
+
+# TODO: replace bhaal powers with the improved versions (cross-check with chargen; powers are removed during soa)
+def FixInnates():
+ # removes the spells: SPIN101, SPIN102, SPIN103, SPIN104, SPIN105, SPIN106, SPIN822
+ # adds the spell: SPIN822 (slayer change), check if this is needed (two uses), since we add it during chargen
+ #adds the spell: SPIN200, SPIN201, SPIN103, SPIN202, SPIN203, SPIN106
+ pass
+
#upgrade savegame to next version
def GameExpansion():
@@ -202,7 +242,7 @@ def GameExpansion():
if not GUICommon.HasTOB():
return
- if GemRB.GetVar("oldgame"):
+ if version < 5 and not GemRB.GetVar("PlayMode") and GemRB.GetVar("oldgame"):
#upgrade SoA to ToB/SoA
if GemRB.GameSetExpansion(4):
GemRB.AddNewArea("xnewarea")
@@ -212,6 +252,7 @@ def GameExpansion():
return
#upgrade to ToB only
+ GemRB.SetVar ("SaveDir", 1)
GemRB.SetMasterScript("BALDUR25","WORLDM25")
GemRB.SetGlobal("INTOB","GLOBAL",1)
GemRB.SetGlobal("HADELLESIMEDREAM1","GLOBAL", 1)
@@ -221,9 +262,13 @@ def GameExpansion():
GemRB.SetGlobal("HADJONDREAM1","GLOBAL", 1)
GemRB.SetGlobal("HADJONDREAM2","GLOBAL", 1)
idx = GemRB.GetPartySize()
+ PDialogTable = GemRB.LoadTable ("pdialog")
while idx:
name = GemRB.GetPlayerName(idx, 2) #scripting name
+ # change the override script to the new one
+ newScript = PDialogTable.GetValue ("25OVERRIDE_SCRIPT_FILE", name.upper())
+ SetPlayerScript (idx, newScript, 0) # 0 is SCR_OVERRIDE, the override script slot
if name == "yoshimo":
RemoveYoshimo(idx)
elif name == "imoen":
diff --git a/gemrb/GUIScripts/bg2/QuitGame.py b/gemrb/GUIScripts/bg2/QuitGame.py
index 0c3e95d..e7659f6 100644
--- a/gemrb/GUIScripts/bg2/QuitGame.py
+++ b/gemrb/GUIScripts/bg2/QuitGame.py
@@ -26,4 +26,9 @@ import GemRB
def OnLoad ():
GemRB.HideGUI ()
GemRB.QuitGame ()
- GemRB.SetNextScript("Start")
+ which = GemRB.GetVar ("QuitGame3")
+ if which==-1:
+ GemRB.SetNextScript("DemoEnd")
+ else:
+ GemRB.SetNextScript("Start")
+ return
diff --git a/gemrb/GUIScripts/bg2/Start.py b/gemrb/GUIScripts/bg2/Start.py
index 5f29358..6e25d01 100644
--- a/gemrb/GUIScripts/bg2/Start.py
+++ b/gemrb/GUIScripts/bg2/Start.py
@@ -20,12 +20,31 @@
import GemRB
import GUICommon
+try:
+ import os
+except ImportError:
+ print "No os module, skipping test"
+ os = None
+
StartWindow = 0
+def EndTest():
+ GemRB.QuitGame()
+ GemRB.Quit()
+ print "Game test completed"
+
def OnLoad():
global StartWindow, skip_videos
- GemRB.EnableCheatKeys(1)
+ # check if we're just running the game-entering test
+ if os and os.getenv('GEMRB_TEST', "0") != "0":
+ import threading
+ print "\nStarting game test"
+ GemRB.LoadGame(None)
+ GemRB.EnterGame()
+ # with delayed execution, more of the game files get loaded
+ threading.Timer(1, EndTest).start() # the 1s varies!
+
skip_videos = GemRB.GetVar ("SkipIntroVideos")
if not skip_videos and not GemRB.GetVar ("SeenIntroVideos"):
GemRB.PlayMovie ("BISLOGO", 1)
diff --git a/gemrb/GUIScripts/bg2/Start2.py b/gemrb/GUIScripts/bg2/Start2.py
index bfc6385..79f55be 100644
--- a/gemrb/GUIScripts/bg2/Start2.py
+++ b/gemrb/GUIScripts/bg2/Start2.py
@@ -180,7 +180,7 @@ def PregenPress():
TutorialWindow.Unload()
#do not start game after chargen
GemRB.SetVar("PlayMode",-1) #will allow export
- GemRB.SetVar("Slot",0)
+ GemRB.SetVar("Slot",1)
GemRB.LoadGame(None)
GemRB.SetNextScript ("CharGen")
return
diff --git a/gemrb/GUIScripts/bg2/StartOpt.py b/gemrb/GUIScripts/bg2/StartOpt.py
index 966dfa8..e7d91b6 100644
--- a/gemrb/GUIScripts/bg2/StartOpt.py
+++ b/gemrb/GUIScripts/bg2/StartOpt.py
@@ -17,6 +17,7 @@
#
#
import GemRB
+import GUIOPT
OptionsWindow = 0
@@ -37,32 +38,14 @@ def OnLoad():
GameButton.SetText(17165)
GraphicButton.SetText(17162)
BackButton.SetText(10308)
- SoundButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, SoundPress)
- GameButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, GamePress)
- GraphicButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, GraphicPress)
+ SoundButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIOPT.OpenAudioOptionsWindow )
+ GameButton.SetEvent( IE_GUI_BUTTON_ON_PRESS, GUIOPT.OpenGameplayOptionsWindow)
+ GraphicButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIOPT.OpenVideoOptionsWindow)
BackButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, BackPress)
BackButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
OptionsWindow.SetVisible(WINDOW_VISIBLE)
return
-def SoundPress():
- if OptionsWindow:
- OptionsWindow.Unload()
- GemRB.SetNextScript("GUIOPT7")
- return
-
-def GamePress():
- if OptionsWindow:
- OptionsWindow.Unload()
- GemRB.SetNextScript("GUIOPT8")
- return
-
-def GraphicPress():
- if OptionsWindow:
- OptionsWindow.Unload()
- GemRB.SetNextScript("GUIOPT6")
- return
-
def BackPress():
if OptionsWindow:
OptionsWindow.Unload()
diff --git a/gemrb/GUIScripts/demo/GUIINV.py b/gemrb/GUIScripts/demo/GUIINV.py
new file mode 100644
index 0000000..e69de29
diff --git a/gemrb/GUIScripts/demo/GUIJRNL.py b/gemrb/GUIScripts/demo/GUIJRNL.py
new file mode 100644
index 0000000..e69de29
diff --git a/gemrb/GUIScripts/demo/GUIMA.py b/gemrb/GUIScripts/demo/GUIMA.py
new file mode 100644
index 0000000..e69de29
diff --git a/gemrb/GUIScripts/demo/GUIMG.py b/gemrb/GUIScripts/demo/GUIMG.py
new file mode 100644
index 0000000..e69de29
diff --git a/gemrb/GUIScripts/demo/GUIOPT.py b/gemrb/GUIScripts/demo/GUIOPT.py
new file mode 100644
index 0000000..2f1e19e
--- /dev/null
+++ b/gemrb/GUIScripts/demo/GUIOPT.py
@@ -0,0 +1,5 @@
+import GemRB
+
+def OpenQuitMsgWindow():
+ GemRB.QuitGame()
+ GemRB.Quit()
diff --git a/gemrb/GUIScripts/demo/GUIPR.py b/gemrb/GUIScripts/demo/GUIPR.py
new file mode 100644
index 0000000..e69de29
diff --git a/gemrb/GUIScripts/demo/LoadScreen.py b/gemrb/GUIScripts/demo/LoadScreen.py
new file mode 100644
index 0000000..7f13305
--- /dev/null
+++ b/gemrb/GUIScripts/demo/LoadScreen.py
@@ -0,0 +1,5 @@
+def StartLoadScreen():
+ pass
+
+def SetLoadScreen():
+ pass
diff --git a/gemrb/GUIScripts/demo/MessageWindow.py b/gemrb/GUIScripts/demo/MessageWindow.py
new file mode 100644
index 0000000..106cf46
--- /dev/null
+++ b/gemrb/GUIScripts/demo/MessageWindow.py
@@ -0,0 +1,96 @@
+import GemRB
+import GUICommon
+import GUICommonWindows
+import CommonWindow
+import GUIClasses
+from GUIDefines import *
+
+MessageWindow = 0
+#PortraitWindow = 0
+#OptionsWindow = 0
+TMessageTA = 0 # for dialog code
+
+def OnLoad():
+# global PortraitWindow, OptionsWindow
+
+ GemRB.GameSetPartySize(PARTY_SIZE)
+ GemRB.GameSetProtagonistMode(1)
+ GemRB.LoadWindowPack(GUICommon.GetWindowPack())
+
+# GUICommonWindows.PortraitWindow = None
+# GUICommonWindows.ActionsWindow = None
+# GUICommonWindows.OptionsWindow = None
+
+# ActionsWindow = GemRB.LoadWindow(3)
+# OptionsWindow = GemRB.LoadWindow(0)
+# PortraitWindow = GUICommonWindows.OpenPortraitWindow(1)
+
+# GemRB.SetVar("PortraitWindow", PortraitWindow.ID)
+# GemRB.SetVar("ActionsWindow", ActionsWindow.ID)
+# GemRB.SetVar("OptionsWindow", OptionsWindow.ID)
+ GemRB.SetVar("TopWindow", -1)
+ GemRB.SetVar("OtherWindow", -1)
+ GemRB.SetVar("FloatWindow", -1)
+ GemRB.SetVar("PortraitPosition", 2) #Right
+ GemRB.SetVar("ActionsPosition", 4) #BottomAdded
+ GemRB.SetVar("OptionsPosition", 0) #Left
+ GemRB.SetVar("MessagePosition", 4) #BottomAdded
+ GemRB.SetVar("OtherPosition", 5) #Inactivating
+ GemRB.SetVar("TopPosition", 5) #Inactivating
+
+# GUICommonWindows.OpenActionsWindowControls (ActionsWindow)
+# GUICommonWindows.SetupMenuWindowControls (OptionsWindow, 1, None)
+
+## GUICommon.GameWindow.SetVisible (WINDOW_VISIBLE)
+
+ UpdateControlStatus()
+
+def ScrollUp ():
+ TMessageWindow = GemRB.GetVar("MessageWindow")
+ TMessageTA = GUIClasses.GTextArea(TMessageWindow,GemRB.GetVar("MessageTextArea"))
+ TMessageTA.Scroll(-1)
+
+def ScrollDown ():
+ TMessageWindow = GemRB.GetVar("MessageWindow")
+ TMessageTA = GUIClasses.GTextArea(TMessageWindow,GemRB.GetVar("MessageTextArea"))
+ TMessageTA.Scroll(1)
+
+def UpdateControlStatus():
+ global MessageWindow, TMessageTA
+
+ TMessageWindow = 0
+ TMessageTA = 0
+ GSFlags = GemRB.GetMessageWindowSize()
+ Expand = GS_LARGEDIALOG
+ GSFlags = GSFlags-Expand
+ Override = GSFlags&GS_DIALOG
+
+ MessageWindow = GemRB.GetVar("MessageWindow")
+
+ GemRB.LoadWindowPack(GUICommon.GetWindowPack())
+
+ if Expand == GS_LARGEDIALOG:
+ TMessageWindow = GemRB.LoadWindow(0)
+ TMessageTA = TMessageWindow.GetControl(0)
+
+ TMessageTA.SetFlags(IE_GUI_TEXTAREA_AUTOSCROLL)
+ TMessageTA.SetHistory(100)
+
+ hideflag = GemRB.HideGUI()
+ MessageTA = GUIClasses.GTextArea(MessageWindow,GemRB.GetVar("MessageTextArea"))
+ if MessageWindow>0 and MessageWindow!=TMessageWindow.ID:
+ MessageTA.MoveText(TMessageTA)
+ GUIClasses.GWindow(MessageWindow).Unload()
+
+ TMessageTA.SetText("DEMO "*150)
+
+ GemRB.SetVar("MessageWindow", TMessageWindow.ID)
+ GemRB.SetVar("MessageTextArea", TMessageTA.ID)
+ if Override:
+ TMessageTA.SetStatus (IE_GUI_CONTROL_FOCUSED)
+ else:
+ GUICommon.GameControl.SetStatus(IE_GUI_CONTROL_FOCUSED)
+
+ if hideflag:
+ GemRB.UnhideGUI()
+
diff --git a/gemrb/GUIScripts/demo/README b/gemrb/GUIScripts/demo/README
new file mode 100644
index 0000000..0e078f7
--- /dev/null
+++ b/gemrb/GUIScripts/demo/README
@@ -0,0 +1,5 @@
+The empty files are temporary here to:
+ - override shared code,
+ - satisfy global dependencies
+ - squash missing function errors (noop functions)
+
diff --git a/gemrb/GUIScripts/demo/SetupGame.py b/gemrb/GUIScripts/demo/SetupGame.py
new file mode 100644
index 0000000..ae7281e
--- /dev/null
+++ b/gemrb/GUIScripts/demo/SetupGame.py
@@ -0,0 +1,7 @@
+import GemRB
+
+def OnLoad():
+ # skipping chargen
+ GemRB.CreatePlayer ("protagon", 1|0x8000) # exportable
+
+ GemRB.EnterGame()
diff --git a/gemrb/GUIScripts/demo/Start.py b/gemrb/GUIScripts/demo/Start.py
new file mode 100644
index 0000000..f249de8
--- /dev/null
+++ b/gemrb/GUIScripts/demo/Start.py
@@ -0,0 +1,9 @@
+import GemRB
+
+def OnLoad():
+ GemRB.LoadGame(None)
+
+ # this is needed, so the game loop runs and the load happens
+ # before other code (eg. CreatePlayer) depending on it is run
+ GemRB.SetNextScript("SetupGame")
+
diff --git a/gemrb/GUIScripts/ie_feats.py b/gemrb/GUIScripts/ie_feats.py
new file mode 100644
index 0000000..d3cde78
--- /dev/null
+++ b/gemrb/GUIScripts/ie_feats.py
@@ -0,0 +1,96 @@
+# -*-python-*-
+# GemRB - Infinity Engine Emulator
+# Copyright (C) 2011 The GemRB Project
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# a listing of iwd2 feat indices
+
+# KEEP SYNCHRONISED WITH gemrb/includes/ie_feats.h !!!
+FEAT_AEGIS_OF_RIME = 0
+FEAT_AMBIDEXTERITY = 1
+FEAT_AQUA_MORTIS = 2
+FEAT_ARMOUR_PROFICIENCY = 3
+FEAT_ARMORED_ARCANA = 4
+FEAT_ARTERIAL_STRIKE = 5
+FEAT_BLIND_FIGHT = 6
+FEAT_BULLHEADED = 7
+FEAT_CLEAVE = 8
+FEAT_COMBAT_CASTING = 9
+FEAT_COURTEOUS_MAGOCRACY = 10
+FEAT_CRIPPLING_STRIKE = 11
+FEAT_DASH = 12
+FEAT_DEFLECT_ARROWS = 13
+FEAT_DIRTY_FIGHTING = 14
+FEAT_DISCIPLINE = 15
+FEAT_DODGE = 16
+FEAT_ENVENOM_WEAPON = 17
+FEAT_EXOTIC_BASTARD = 18
+FEAT_EXPERTISE = 19
+FEAT_EXTRA_RAGE = 20
+FEAT_EXTRA_SHAPESHIFTING = 21
+FEAT_EXTRA_SMITING = 22
+FEAT_EXTRA_TURNING = 23
+FEAT_FIENDSLAYER = 24
+FEAT_FORESTER = 25
+FEAT_GREAT_FORTITUDE = 26
+FEAT_HAMSTRING = 27
+FEAT_HERETICS_BANE = 28
+FEAT_HEROIC_INSPIRATION = 29
+FEAT_IMPROVED_CRITICAL = 30
+FEAT_IMPROVED_EVASION = 31
+FEAT_IMPROVED_INITIATIVE = 32
+FEAT_IMPROVED_TURNING = 33
+FEAT_IRON_WILL = 34
+FEAT_LIGHTNING_REFLEXES = 35
+FEAT_LINGERING_SONG = 36
+FEAT_LUCK_OF_HEROES = 37
+FEAT_MARTIAL_AXE = 38
+FEAT_MARTIAL_BOW = 39
+FEAT_MARTIAL_FLAIL = 40
+FEAT_MARTIAL_GREATSWORD = 41
+FEAT_MARTIAL_HAMMER = 42
+FEAT_MARTIAL_LARGESWORD = 43
+FEAT_MARTIAL_POLEARM = 44
+FEAT_MAXIMIZED_ATTACKS = 45
+FEAT_MERCANTILE_BACKGROUND = 46
+FEAT_POWER_ATTACK = 47
+FEAT_PRECISE_SHOT = 48
+FEAT_RAPID_SHOT = 49
+FEAT_RESIST_POISON = 50
+FEAT_SCION_OF_STORMS = 51
+FEAT_SHIELD_PROF = 52
+FEAT_SIMPLE_CROSSBOW = 53
+FEAT_SIMPLE_MACE = 54
+FEAT_SIMPLE_MISSILE = 55
+FEAT_SIMPLE_QUARTERSTAFF = 56
+FEAT_SIMPLE_SMALLBLADE = 57
+FEAT_SLIPPERY_MIND = 58
+FEAT_SNAKE_BLOOD = 59
+FEAT_SPELL_FOCUS_ENCHANTMENT = 60
+FEAT_SPELL_FOCUS_EVOCATION = 61
+FEAT_SPELL_FOCUS_NECROMANCY = 62
+FEAT_SPELL_FOCUS_TRANSMUTE = 63
+FEAT_SPELL_PENETRATION = 64
+FEAT_SPIRIT_OF_FLAME = 65
+FEAT_STRONG_BACK = 66
+FEAT_STUNNING_FIST = 67
+FEAT_SUBVOCAL_CASTING = 68
+FEAT_TOUGHNESS = 69
+FEAT_TWO_WEAPON_FIGHTING = 70
+FEAT_WEAPON_FINESSE = 71
+FEAT_WILDSHAPE_BOAR = 72
+FEAT_WILDSHAPE_PANTHER = 73
+FEAT_WILDSHAPE_SHAMBLER = 74
diff --git a/gemrb/GUIScripts/ie_sounds.py b/gemrb/GUIScripts/ie_sounds.py
new file mode 100644
index 0000000..bf8422a
--- /dev/null
+++ b/gemrb/GUIScripts/ie_sounds.py
@@ -0,0 +1,22 @@
+#predefined sound indices
+
+DEF_OPEN = 0
+DEF_CLOSE = 1
+DEF_HOPEN = 2
+DEF_HCLOSE = 3
+DEF_BUTTON1 = 4
+DEF_BUTTON2 = 5
+DEF_BUTTON3 = 6
+DEF_OPENFAIL = 7
+DEF_CLOSEFAIL = 8
+DEF_ITEM_GONE = 9
+DEF_SECRET = 10
+DEF_PICKLOCK = 11
+#reserved 12-24
+DEF_SOLD = 25
+DEF_STOLEN = 26
+DEF_DRUNK = 27
+DEF_DONATE1 = 28
+DEF_DONATE2 = 29
+DEF_IDENTIFY = 30
+DEF_GOTXP = 31
diff --git a/gemrb/GUIScripts/ie_spells.py b/gemrb/GUIScripts/ie_spells.py
index 21ee9e1..81d0470 100644
--- a/gemrb/GUIScripts/ie_spells.py
+++ b/gemrb/GUIScripts/ie_spells.py
@@ -15,3 +15,8 @@ LSR_FAILED = 3 #failed stat roll
LSR_STAT = 4 #insufficient stat (can't learn the spell due to low stat)
LSR_LEVEL = 5 #insufficient level (low mage, etc level)
LSR_FULL = 6 #can't learn more spells of this level (due to level)
+
+# CheckSpecialSpell return values (see Interface.h)
+SP_IDENTIFY = 1 # any spell that cannot be cast from the menu
+SP_SILENCE = 2 # any spell that can be cast in silence
+SP_SURGE = 4 # any spell that cannot be cast during a wild surge
diff --git a/gemrb/GUIScripts/ie_stats.py b/gemrb/GUIScripts/ie_stats.py
index f4e04e9..6625b73 100644
--- a/gemrb/GUIScripts/ie_stats.py
+++ b/gemrb/GUIScripts/ie_stats.py
@@ -43,6 +43,7 @@ CHARMEDPC = 254
ENEMY = 255
# state bits (IE_STATE)
+STATE_BERSERK = 2
STATE_PANIC = 4
STATE_HELPLESS = 1 + 32
STATE_PETRIFIED = 8 + 64 + 128
@@ -63,7 +64,7 @@ MC_EXPORTABLE = 0x800
MC_PLOT_CRITICAL = 0x2000
MC_BEENINPARTY = 0x8000
-MC_HIDDEN = 0x10000
+MC_SEENPARTY = 0x10000
# stats
IE_HITPOINTS = 0
@@ -322,7 +323,7 @@ IE_HAIR_COLOR = 214
IE_MC_FLAGS = 215
IE_CLASSLEVELSUM = 216
IE_ALIGNMENT = 217
-IE_UNSELECTABLE = 218
+IE_CASTING = 218
IE_ARMOR_TYPE = 219
IE_TEAM = 220
IE_FACTION = 221
@@ -352,7 +353,7 @@ IE_LEVELDRUID = 243
IE_LEVELMONK = 244
IE_LEVELPALADIN = 245
IE_LEVELRANGER = 246
-IE_LEVELSORCEROR = 247
+IE_LEVELSORCERER = 247
#248 IE_LEVELCLASS12
#249 IE_LEVELCLASS13
#the remaining six stats are spell states
diff --git a/gemrb/GUIScripts/include.py b/gemrb/GUIScripts/include.py
index adb76e6..6c3ed98 100644
--- a/gemrb/GUIScripts/include.py
+++ b/gemrb/GUIScripts/include.py
@@ -1,2 +1,25 @@
# this file is executed at gemrb startup, for the Console
from ie_stats import *
+from GUIDefines import *
+
+# /handy/ shorthand forms
+def gps(stat, base=0):
+ print GemRB.GetPlayerStat(GemRB.GameGetFirstSelectedPC(), stat, base)
+
+def sps(stat, value, pcf=1):
+ GemRB.SetPlayerStat(GemRB.GameGetFirstSelectedPC(), stat, value, pcf)
+
+def mta(area):
+ GemRB.MoveToArea(area)
+
+def debug(level):
+ GemRB.MessageWindowDebug(level)
+
+def cc(cre, px=-1, py=-1):
+ GemRB.CreateCreature(GemRB.GameGetFirstSelectedPC(), cre, px, py)
+
+def ci(item, slot=-1, c0=1, c1=0, c2=0):
+ GemRB.CreateItem(GemRB.GameGetFirstSelectedPC(), item, slot, c0, c1, c2)
+
+def cv(var, context="GLOBAL"):
+ GemRB.CheckVar(var, context)
diff --git a/gemrb/GUIScripts/iwd/CMakeLists.txt b/gemrb/GUIScripts/iwd/CMakeLists.txt
deleted file mode 100644
index afd062e..0000000
--- a/gemrb/GUIScripts/iwd/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-FILE( GLOB FILES_TO_INSTALL *.py )
-
-INSTALL( FILES ${FILES_TO_INSTALL} DESTINATION ${DATA_DIR}/GUIScripts/iwd )
diff --git a/gemrb/GUIScripts/iwd/CharGen.py b/gemrb/GUIScripts/iwd/CharGen.py
index eee6add..5e4e60c 100644
--- a/gemrb/GUIScripts/iwd/CharGen.py
+++ b/gemrb/GUIScripts/iwd/CharGen.py
@@ -27,6 +27,7 @@ from GUIDefines import *
from ie_stats import *
from ie_spells import LS_MEMO
import GUICommon
+import Spellbook
import CommonTables
import LUSkillsSelection
@@ -66,7 +67,6 @@ KitDoneButton = 0
AlignmentButton = 0
AlignmentWindow = 0
-AlignmentTable = 0
AlignmentTextArea = 0
AlignmentDoneButton = 0
@@ -149,18 +149,18 @@ SoundIndex = 0
VerbalConstants = None
HasStrExtra = 0
MyChar = 0
+ImportedChar = 0
def OnLoad():
global CharGenWindow, CharGenState, TextArea, PortraitButton, AcceptButton
global GenderButton, RaceButton, ClassButton, AlignmentButton
global AbilitiesButton, SkillsButton, AppearanceButton, BiographyButton, NameButton
- global KitTable, ProficienciesTable, AlignmentTable, RacialEnemyTable
+ global KitTable, ProficienciesTable, RacialEnemyTable
global AbilitiesTable, SkillsTable, PortraitsTable
- global MyChar
+ global MyChar, ImportedChar
KitTable = GemRB.LoadTable ("magesch")
ProficienciesTable = GemRB.LoadTable ("weapprof")
- AlignmentTable = GemRB.LoadTable ("aligns")
RacialEnemyTable = GemRB.LoadTable ("haterace")
AbilitiesTable = GemRB.LoadTable ("ability")
SkillsTable = GemRB.LoadTable ("skills")
@@ -170,6 +170,7 @@ def OnLoad():
CharGenWindow.SetFrame ()
CharGenState = 0
MyChar = GemRB.GetVar ("Slot")
+ ImportedChar = 0
GenderButton = CharGenWindow.GetControl (0)
GenderButton.SetState (IE_GUI_BUTTON_ENABLED)
@@ -313,27 +314,30 @@ def AcceptPress():
#mage spells
Kit = GemRB.GetPlayerStat (MyChar, IE_KIT)
KitIndex = KitTable.FindValue (3, Kit)
- Class = GemRB.GetPlayerStat (MyChar, IE_CLASS)
+ ClassName = GUICommon.GetClassRowName (MyChar)
t = GemRB.GetPlayerStat (MyChar, IE_ALIGNMENT)
- TableName = CommonTables.ClassSkills.GetValue (Class, 2, 0)
+ TableName = CommonTables.ClassSkills.GetValue (ClassName, "MAGESPELL", 0)
if TableName != "*":
#todo: set up ALL spell levels not just level 1
- GUICommon.SetupSpellLevels (MyChar, TableName, IE_SPELL_TYPE_WIZARD, 1)
- Learnable = GUICommon.GetLearnableMageSpells (KitIndex, t, 1)
+ Spellbook.SetupSpellLevels (MyChar, TableName, IE_SPELL_TYPE_WIZARD, 1)
+ Learnable = Spellbook.GetLearnableMageSpells (KitIndex, t, 1)
SpellBook = GemRB.GetVar ("MageSpellBook")
MemoBook = GemRB.GetVar ("MageMemorized")
j=1
for i in range (len(Learnable) ):
if SpellBook & j:
if MemoBook & j:
- memorize = 8
+ memorize = LS_MEMO
else:
memorize = 0
GemRB.LearnSpell (MyChar, Learnable[i], memorize)
j=j<<1
#priest spells
- TableName = CommonTables.ClassSkills.GetValue (Class, 1, 0)
+ TableName = CommonTables.ClassSkills.GetValue (ClassName, "CLERICSPELL", 0)
+ # druids and rangers have a column of their own
+ if TableName == "*":
+ TableName = CommonTables.ClassSkills.GetValue (ClassName, "DRUIDSPELL", 0)
if TableName != "*":
if TableName == "MXSPLPRS" or TableName == "MXSPLPAL":
ClassFlag = 0x8000
@@ -346,21 +350,26 @@ def AcceptPress():
else:
ClassFlag = 0
#todo: set up ALL spell levels not just level 1
- GUICommon.SetupSpellLevels (MyChar, TableName, IE_SPELL_TYPE_PRIEST, 1)
- Learnable = GUICommon.GetLearnablePriestSpells (ClassFlag, t, 1)
+ Spellbook.SetupSpellLevels (MyChar, TableName, IE_SPELL_TYPE_PRIEST, 1)
+ Learnable = Spellbook.GetLearnablePriestSpells (ClassFlag, t, 1)
+ PriestMemorized = GemRB.GetVar ("PriestMemorized")
+ j = 1
+ while (PriestMemorized and PriestMemorized != 1<<(j-1)):
+ j = j + 1
for i in range (len(Learnable) ):
GemRB.LearnSpell (MyChar, Learnable[i], 0)
+ GemRB.MemorizeSpell (MyChar, IE_SPELL_TYPE_PRIEST, 0, j, 1)
# ranger tracking is a hardcoded innate
if GUICommon.HasHOW():
- if CommonTables.ClassSkills.GetValue (GemRB.GetPlayerStat (MyChar, IE_CLASS), 0) != "*":
+ if CommonTables.ClassSkills.GetValue (ClassName, "DRUIDSPELL") != "*":
GemRB.LearnSpell (MyChar, "spin139", LS_MEMO)
# save all the skills
LUSkillsSelection.SkillsSave (MyChar)
TmpTable = GemRB.LoadTable ("repstart")
- t = AlignmentTable.FindValue (3, t)
+ t = CommonTables.Aligns.FindValue (3, t)
t = TmpTable.GetValue (t, 0) * 10
GemRB.SetPlayerStat (MyChar, IE_REPUTATION, t)
# set the party rep if this in the main char
@@ -369,11 +378,11 @@ def AcceptPress():
print "Reputation", t
TmpTable = GemRB.LoadTable ("strtgold")
- a = TmpTable.GetValue (Class, 1) #number of dice
- b = TmpTable.GetValue (Class, 0) #size
- c = TmpTable.GetValue (Class, 2) #adjustment
- d = TmpTable.GetValue (Class, 3) #external multiplier
- e = TmpTable.GetValue (Class, 4) #level bonus rate
+ a = TmpTable.GetValue (ClassName, "ROLLS") #number of dice
+ b = TmpTable.GetValue (ClassName, "SIDES") #size
+ c = TmpTable.GetValue (ClassName, "MODIFIER") #adjustment
+ d = TmpTable.GetValue (ClassName, "MULTIPLIER") #external multiplier
+ e = TmpTable.GetValue (ClassName, "BONUS_PER_LEVEL") #level bonus rate (iwd only!)
t = GemRB.GetPlayerStat (MyChar, IE_LEVEL) #FIXME: calculate multiclass average
if t>1:
e=e*(t-1)
@@ -398,7 +407,9 @@ def AcceptPress():
GemRB.SetPlayerName (MyChar, GemRB.GetToken ("CHARNAME"), 0)
GemRB.SetToken ("CHARNAME","")
- GemRB.SetPlayerStat (MyChar, IE_XP, CommonTables.ClassSkills.GetValue (Class, 3) )
+ # don't reset imported char's xp back to start
+ if not ImportedChar:
+ GemRB.SetPlayerStat (MyChar, IE_XP, CommonTables.ClassSkills.GetValue (ClassName, "STARTXP"))
GUICommon.SetColorStat (MyChar, IE_SKIN_COLOR, GemRB.GetVar ("SkinColor") )
GUICommon.SetColorStat (MyChar, IE_HAIR_COLOR, GemRB.GetVar ("HairColor") )
@@ -440,14 +451,14 @@ def SetCharacterDescription():
else:
TextArea.Append (1051)
if CharGenState > 2:
- Class = CommonTables.Classes.FindValue (5, GemRB.GetPlayerStat (MyChar, IE_CLASS) )
+ ClassName = GUICommon.GetClassRowName (MyChar)
TextArea.Append (12136, -1)
TextArea.Append (": ")
#this is only mage school in iwd
Kit = GemRB.GetPlayerStat (MyChar, IE_KIT)
KitIndex = KitTable.FindValue (3, Kit)
if KitIndex <= 0:
- ClassTitle = CommonTables.Classes.GetValue (Class, 2)
+ ClassTitle = CommonTables.Classes.GetValue (ClassName, "CAP_REF")
else:
ClassTitle = KitTable.GetValue (KitIndex, 2)
TextArea.Append (ClassTitle)
@@ -461,8 +472,8 @@ def SetCharacterDescription():
if CharGenState > 3:
TextArea.Append (1049, -1)
TextArea.Append (": ")
- Alignment = AlignmentTable.FindValue (3, GemRB.GetPlayerStat(MyChar, IE_ALIGNMENT) )
- TextArea.Append (AlignmentTable.GetValue (Alignment, 2) )
+ Alignment = CommonTables.Aligns.FindValue (3, GemRB.GetPlayerStat(MyChar, IE_ALIGNMENT))
+ TextArea.Append (CommonTables.Aligns.GetValue (Alignment, 2))
if CharGenState > 4:
strextra = GemRB.GetPlayerStat (MyChar, IE_STREXTRA)
TextArea.Append ("", -1)
@@ -476,13 +487,11 @@ def SetCharacterDescription():
else:
TextArea.Append (str(stat) )
if CharGenState > 5:
- ClassName = CommonTables.Classes.GetRowName (Class)
- Row = CommonTables.Classes.GetValue (Class, 5)
- IsRanger = CommonTables.ClassSkills.GetValue (Row, 0)
- IsArcane = CommonTables.ClassSkills.GetValue (Row, 1)
- IsMage = CommonTables.ClassSkills.GetValue (Row, 2)
- IsBard = CommonTables.ClassSkills.GetValue (Row, 4)
- IsThief = CommonTables.ClassSkills.GetValue (Row, 5)
+ DruidSpell = CommonTables.ClassSkills.GetValue (ClassName, "DRUIDSPELL")
+ PriestSpell = CommonTables.ClassSkills.GetValue (ClassName, "CLERICSPELL")
+ MageSpell = CommonTables.ClassSkills.GetValue (ClassName, "MAGESPELL")
+ IsBard = CommonTables.ClassSkills.GetValue (ClassName, "BARDSKILL")
+ IsThief = CommonTables.ClassSkills.GetValue (ClassName, "THIEFSKILL")
if IsThief!="*":
TextArea.Append ("", -1)
@@ -493,7 +502,7 @@ def SetCharacterDescription():
TextArea.Append (": " )
TextArea.Append (str(GemRB.GetPlayerStat (MyChar, StatID)) )
TextArea.Append ("%" )
- elif IsRanger!="*":
+ elif DruidSpell!="*":
TextArea.Append ("", -1)
TextArea.Append (8442, -1)
for i in range (4):
@@ -534,12 +543,12 @@ def SetCharacterDescription():
TextArea.Append ("+")
j = j + 1
- if IsMage !="*":
+ if MageSpell !="*":
TextArea.Append ("", -1)
TextArea.Append (11027, -1)
TextArea.Append (": " )
t = GemRB.GetPlayerStat (MyChar, IE_ALIGNMENT)
- Learnable = GUICommon.GetLearnableMageSpells (GemRB.GetPlayerStat (MyChar, IE_KIT), t,1)
+ Learnable = Spellbook.GetLearnableMageSpells (GemRB.GetPlayerStat (MyChar, IE_KIT), t,1)
MageSpellBook = GemRB.GetVar ("MageSpellBook")
MageMemorized = GemRB.GetVar ("MageMemorized")
for i in range (len(Learnable)):
@@ -550,19 +559,21 @@ def SetCharacterDescription():
TextArea.Append (" +")
TextArea.Append (" ")
- if IsArcane!="*":
+ if PriestSpell == "*":
+ PriestSpell = DruidSpell
+ if PriestSpell!="*":
TextArea.Append ("", -1)
TextArea.Append (11028, -1)
TextArea.Append (": " )
t = GemRB.GetPlayerStat (MyChar, IE_ALIGNMENT)
- if IsArcane == "MXSPLPRS" or IsArcane == "MXSPLPAL":
+ if PriestSpell == "MXSPLPRS" or PriestSpell == "MXSPLPAL":
ClassFlag = 0x4000
- elif IsArcane == "MXSPLDRU" or IsArcane == "MXSPLRAN":
+ elif PriestSpell == "MXSPLDRU" or PriestSpell == "MXSPLRAN":
ClassFlag = 0x8000
else:
ClassFlag = 0
- Learnable = GUICommon.GetLearnablePriestSpells( ClassFlag, t, 1)
+ Learnable = Spellbook.GetLearnablePriestSpells( ClassFlag, t, 1)
PriestMemorized = GemRB.GetVar ("PriestMemorized")
for i in range (len(Learnable)):
if (1 << i) & PriestMemorized:
@@ -961,8 +972,9 @@ def ClassPress():
HasMulti = 0
j = 2
for i in range (ClassCount):
- Allowed = CommonTables.Classes.GetValue (CommonTables.Classes.GetRowName (i), RaceName)
- if CommonTables.Classes.GetValue (i, 4):
+ ClassRowName = CommonTables.Classes.GetRowName (i)
+ Allowed = CommonTables.Classes.GetValue (ClassRowName, RaceName)
+ if CommonTables.Classes.GetValue (ClassRowName, "MULTI"):
if Allowed != 0:
HasMulti = 1
else:
@@ -973,7 +985,7 @@ def ClassPress():
else:
ClassSelectButton.SetState (IE_GUI_BUTTON_DISABLED)
ClassSelectButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, ClassSelectPress)
- ClassSelectButton.SetText (CommonTables.Classes.GetValue (i, 0) )
+ ClassSelectButton.SetText (CommonTables.Classes.GetValue (ClassRowName, "NAME_REF"))
ClassSelectButton.SetVarAssoc ("Class", i + 1)
ClassMultiButton = ClassWindow.GetControl (10)
@@ -1015,8 +1027,8 @@ def ClassPress():
def ClassSelectPress():
global ClassWindow, ClassTextArea, ClassDoneButton
- Class = GemRB.GetVar ("Class") - 1
- ClassTextArea.SetText (CommonTables.Classes.GetValue (Class, 1) )
+ ClassName = GUICommon.GetClassRowName (GemRB.GetVar ("Class")-1, "index")
+ ClassTextArea.SetText (CommonTables.Classes.GetValue (ClassName, "DESC_REF"))
ClassDoneButton.SetState (IE_GUI_BUTTON_ENABLED)
return
@@ -1045,7 +1057,7 @@ def ClassMultiPress():
else:
ClassMultiSelectButton.SetState (IE_GUI_BUTTON_DISABLED)
ClassMultiSelectButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, ClassMultiSelectPress)
- ClassMultiSelectButton.SetText (CommonTables.Classes.GetValue (i, 0) )
+ ClassMultiSelectButton.SetText (CommonTables.Classes.GetValue (ClassName, "NAME_REF"))
ClassMultiSelectButton.SetVarAssoc ("Class", i + 1)
ClassMultiTextArea = ClassMultiWindow.GetControl (12)
@@ -1069,8 +1081,8 @@ def ClassMultiPress():
def ClassMultiSelectPress():
global ClassMultiWindow, ClassMultiTextArea, ClassMultiDoneButton
- Class = GemRB.GetVar ("Class") - 1
- ClassMultiTextArea.SetText (CommonTables.Classes.GetValue (Class, 1) )
+ ClassName = GUICommon.GetClassRowName (GemRB.GetVar ("Class")-1, "index")
+ ClassMultiTextArea.SetText (CommonTables.Classes.GetValue (ClassName, "DESC_REF"))
ClassMultiDoneButton.SetState (IE_GUI_BUTTON_ENABLED)
return
@@ -1161,8 +1173,8 @@ def ClassDonePress():
AlignmentButton.SetState (IE_GUI_BUTTON_ENABLED)
AlignmentButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
- ClassIndex = GemRB.GetVar ("Class")-1
- Class = CommonTables.Classes.GetValue (ClassIndex, 5)
+ ClassName = GUICommon.GetClassRowName (GemRB.GetVar ("Class")-1, "index")
+ Class = CommonTables.Classes.GetValue (ClassName, "ID")
GemRB.SetPlayerStat (MyChar, IE_CLASS, Class)
Kit = KitTable.GetValue (GemRB.GetVar ("MAGESCHOOL"), 3 )
@@ -1192,9 +1204,7 @@ def AlignmentPress():
CharGenWindow.SetVisible (WINDOW_INVISIBLE)
AlignmentWindow = GemRB.LoadWindow (3)
ClassAlignmentTable = GemRB.LoadTable ("alignmnt")
- Class = GemRB.GetPlayerStat (MyChar, IE_CLASS)
- ClassIndex = CommonTables.Classes.FindValue (5, Class)
- ClassName = CommonTables.Classes.GetRowName (ClassIndex)
+ ClassName = GUICommon.GetClassRowName (MyChar)
GemRB.SetVar ("Alignment", 0)
for i in range (2, 11):
@@ -1203,12 +1213,12 @@ def AlignmentPress():
for i in range (9):
AlignmentSelectButton = AlignmentWindow.GetControl (i + 2)
- if ClassAlignmentTable.GetValue (ClassName, AlignmentTable.GetValue(i, 4)) == 0:
+ if ClassAlignmentTable.GetValue (ClassName, CommonTables.Aligns.GetValue(i, 4)) == 0:
AlignmentSelectButton.SetState (IE_GUI_BUTTON_DISABLED)
else:
AlignmentSelectButton.SetState (IE_GUI_BUTTON_ENABLED)
AlignmentSelectButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, AlignmentSelectPress)
- AlignmentSelectButton.SetText (AlignmentTable.GetValue (i, 0) )
+ AlignmentSelectButton.SetText (CommonTables.Aligns.GetValue (i, 0))
AlignmentSelectButton.SetVarAssoc ("Alignment", i + 1)
AlignmentTextArea = AlignmentWindow.GetControl (11)
@@ -1233,7 +1243,7 @@ def AlignmentSelectPress():
global AlignmentWindow, AlignmentTextArea, AlignmentDoneButton
Alignment = GemRB.GetVar ("Alignment") - 1
- AlignmentTextArea.SetText (AlignmentTable.GetValue (Alignment, 1))
+ AlignmentTextArea.SetText (CommonTables.Aligns.GetValue (Alignment, 1))
AlignmentDoneButton.SetState (IE_GUI_BUTTON_ENABLED)
return
@@ -1248,7 +1258,7 @@ def AlignmentDonePress():
AbilitiesButton.SetState (IE_GUI_BUTTON_ENABLED)
AbilitiesButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
- Alignment = AlignmentTable.GetValue (GemRB.GetVar ("Alignment")-1, 3)
+ Alignment = CommonTables.Aligns.GetValue (GemRB.GetVar ("Alignment")-1, 3)
GemRB.SetPlayerStat (MyChar, IE_ALIGNMENT, Alignment )
CharGenState = 4
@@ -1282,9 +1292,8 @@ def AbilitiesPress():
PointsLeftLabel = AbilitiesWindow.GetControl (0x10000002)
PointsLeftLabel.SetUseRGB (1)
- Class = GemRB.GetPlayerStat (MyChar, IE_CLASS)
- Class = CommonTables.Classes.FindValue (5, Class)
- HasStrExtra = CommonTables.Classes.GetValue (Class, 3)=="SAVEWAR"
+ ClassName = GUICommon.GetClassRowName (MyChar)
+ HasStrExtra = CommonTables.Classes.GetValue (ClassName, "SAVE") == "SAVEWAR"
for i in range (6):
AbilitiesLabelButton = AbilitiesWindow.GetControl (30 + i)
@@ -1350,8 +1359,7 @@ def AbilitiesCalcLimits(Index):
AbilitiesMaximum = AbilitiesRaceReqTable.GetValue (Race, Index * 2 + 1)
AbilitiesModifier = AbilitiesRaceAddTable.GetValue (Race, Index)
- Class = CommonTables.Classes.FindValue (5, GemRB.GetPlayerStat (MyChar, IE_CLASS) )
- ClassName = CommonTables.Classes.GetRowName (Class)
+ ClassName = GUICommon.GetClassRowName (MyChar)
ClassIndex = AbilitiesClassReqTable.GetRowIndex (ClassName)
Min = AbilitiesClassReqTable.GetValue (ClassIndex, Index)
if Min > 0 and AbilitiesMinimum < Min:
@@ -1540,34 +1548,23 @@ def SkillsPress():
Level = 1
SpellLevel = 1
- Class = GemRB.GetPlayerStat (MyChar, IE_CLASS)
- IsRanger = CommonTables.ClassSkills.GetValue (Class, 0)
- IsArcane = CommonTables.ClassSkills.GetValue (Class, 1)
- IsMage = CommonTables.ClassSkills.GetValue (Class, 2)
- IsBard = CommonTables.ClassSkills.GetValue (Class, 4)
- IsThief = CommonTables.ClassSkills.GetValue (Class, 5)
+ ClassName = GUICommon.GetClassRowName (MyChar)
+ DruidSpell = CommonTables.ClassSkills.GetValue (ClassName, "DRUIDSPELL")
+ PriestSpell = CommonTables.ClassSkills.GetValue (ClassName, "CLERICSPELL")
+ MageSpell = CommonTables.ClassSkills.GetValue (ClassName, "MAGESPELL")
+ IsBard = CommonTables.ClassSkills.GetValue (ClassName, "BARDSKILL")
+ IsThief = CommonTables.ClassSkills.GetValue (ClassName, "THIEFSKILL")
if SkillsState == 0:
GemRB.SetVar ("HatedRace", 0)
- RaceName = CommonTables.Races.GetRowName (GemRB.GetPlayerStat (MyChar, IE_RACE) - 1)
if IsThief!="*":
SkillsSelect()
- elif IsRanger!="*":
- SkillRaceTable = GemRB.LoadTable ("SKILLRAC")
- SkillDexterityTable = GemRB.LoadTable ("SKILLDEX")
- Dexterity = str(GemRB.GetPlayerStat (MyChar, IE_DEX) )
- Skill = SkillRaceTable.GetValue (RaceName, "STEALTH")
- Skill = Skill + SkillDexterityTable.GetValue(Dexterity, "STEALTH")
- Skill = Skill + GemRB.LoadTable("SKILLRNG").GetValue(str(Level), "STEALTH")
+ elif DruidSpell!="*":
+ Skill = GemRB.LoadTable("SKILLRNG").GetValue(str(Level), "STEALTH")
GemRB.SetPlayerStat (MyChar, IE_STEALTH, Skill)
RacialEnemySelect()
elif IsBard!="*":
- SkillRaceTable = GemRB.LoadTable ("SKILLRAC")
- SkillDexterityTable = GemRB.LoadTable ("SKILLDEX")
- Dexterity = str(GemRB.GetPlayerStat (MyChar, IE_DEX) )
- Skill = SkillRaceTable.GetValue (RaceName, "PICK_POCKETS")
- Skill = Skill + SkillDexterityTable.GetValue(Dexterity, "PICK_POCKETS")
- Skill = Skill + GemRB.LoadTable(IsBard).GetValue(str(Level), "PICK_POCKETS")
+ Skill = GemRB.LoadTable(IsBard).GetValue(str(Level), "PICK_POCKETS")
GemRB.SetPlayerStat (MyChar, IE_PICKPOCKET, Skill)
SkillsState = 1
else:
@@ -1577,27 +1574,27 @@ def SkillsPress():
ProficienciesSelect()
if SkillsState == 2:
- if IsMage!="*":
- MageSpellsSelect(IsMage, Level, SpellLevel)
+ if MageSpell!="*":
+ MageSpellsSelect(MageSpell, Level, SpellLevel)
else:
SkillsState = 3
if SkillsState == 3:
- if IsMage!="*":
- MageSpellsMemorize(IsMage, Level, SpellLevel)
+ if MageSpell!="*":
+ MageSpellsMemorize(MageSpell, Level, SpellLevel)
else:
SkillsState = 4
if SkillsState == 4:
- if IsArcane=="MXSPLPRS" or IsArcane =="MXSPLPAL":
+ if PriestSpell=="MXSPLPRS" or PriestSpell =="MXSPLPAL":
ClassFlag = 0x4000
- PriestSpellsMemorize(IsArcane, Level, SpellLevel)
- elif IsArcane=="MXSPLDRU" or IsArcane =="MXSPLRAN":
+ PriestSpellsMemorize(PriestSpell, Level, SpellLevel)
+ elif DruidSpell=="MXSPLDRU" or DruidSpell =="MXSPLRAN":
#no separate spell progression
- if IsArcane == "MXSPLDRU":
- IsArcane = "MXSPLPRS"
+ if DruidSpell == "MXSPLDRU":
+ DruidSpell = "MXSPLPRS"
ClassFlag = 0x8000
- PriestSpellsMemorize(IsArcane, Level, SpellLevel)
+ PriestSpellsMemorize(DruidSpell, Level, SpellLevel)
else:
SkillsState = 5
@@ -1625,10 +1622,6 @@ def SkillsSelect():
CharGenWindow.SetVisible (WINDOW_INVISIBLE)
SkillsWindow = GemRB.LoadWindow (6)
- RaceName = CommonTables.Races.GetRowName (GemRB.GetPlayerStat (MyChar, IE_RACE) - 1)
- Dexterity = str(GetPlayerStat (MyChar, IE_DEX) )
- SkillRaceTable = GemRB.LoadTable ("SKILLRAC")
- SkillDexterityTable = GemRB.LoadTable ("SKILLDEX")
Levels = [GemRB.GetPlayerStat (MyChar, IE_LEVEL), \
GemRB.GetPlayerStat (MyChar, IE_LEVEL2), \
@@ -1781,11 +1774,8 @@ def ProficienciesSelect():
ProfsMaxTable = GemRB.LoadTable ("profsmax")
ClassWeaponsTable = GemRB.LoadTable ("clasweap")
- Class = GemRB.GetPlayerStat (MyChar, IE_CLASS)
- ClassIndex = CommonTables.Classes.FindValue (5, Class)
- ClassName = CommonTables.Classes.GetRowName (ClassIndex)
- Class = ProfsTable.GetRowIndex (ClassName)
- ProficienciesPointsLeft = ProfsTable.GetValue (Class, 0)
+ ClassName = GUICommon.GetClassRowName (MyChar)
+ ProficienciesPointsLeft = ProfsTable.GetValue (ClassName, "FIRST_LEVEL")
PointsLeftLabel = ProficienciesWindow.GetControl (0x10000009)
PointsLeftLabel.SetUseRGB (1)
PointsLeftLabel.SetText (str(ProficienciesPointsLeft))
@@ -1889,11 +1879,8 @@ def ProficienciesPlusPress():
ProficienciesIndex = GemRB.GetVar ("ProficienciesIndex") - 1
ProficienciesValue = GemRB.GetVar ("Proficiency" + str(ProficienciesIndex) )
- Class = GemRB.GetPlayerStat (MyChar, IE_CLASS)
- ClassIndex = CommonTables.Classes.FindValue (5, Class)
- ClassName = CommonTables.Classes.GetRowName (ClassIndex)
- Class = ProfsMaxTable.GetRowIndex (ClassName)
- if ProficienciesPointsLeft > 0 and ProficienciesValue < ProfsMaxTable.GetValue (Class, 0):
+ ClassName = GUICommon.GetClassRowName (MyChar)
+ if ProficienciesPointsLeft > 0 and ProficienciesValue < ProfsMaxTable.GetValue (ClassName, "FIRST_LEVEL"):
ProficienciesPointsLeft = ProficienciesPointsLeft - 1
PointsLeftLabel = ProficienciesWindow.GetControl (0x10000009)
PointsLeftLabel.SetText (str(ProficienciesPointsLeft))
@@ -1964,7 +1951,7 @@ def MageSpellsSelect(SpellTable, Level, SpellLevel):
#kit (school), alignment, level
k = GemRB.GetPlayerStat (MyChar, IE_KIT)
t = GemRB.GetPlayerStat (MyChar, IE_ALIGNMENT)
- Learnable = GUICommon.GetLearnableMageSpells(k, t, SpellLevel)
+ Learnable = Spellbook.GetLearnableMageSpells(k, t, SpellLevel)
GemRB.SetVar ("MageSpellBook", 0)
GemRB.SetVar ("SpellMask", 0)
@@ -2202,8 +2189,8 @@ def PriestSpellsMemorize(SpellTable, Level, SpellLevel):
CharGenWindow.SetVisible (WINDOW_INVISIBLE)
PriestMemorizeWindow = GemRB.LoadWindow (17)
- t = AlignmentTable.GetValue ( GemRB.GetVar ("Alignment")-1, 3)
- Learnable = GUICommon.GetLearnablePriestSpells( ClassFlag, t, SpellLevel)
+ t = CommonTables.Aligns.GetValue (GemRB.GetVar ("Alignment")-1, 3)
+ Learnable = Spellbook.GetLearnablePriestSpells( ClassFlag, t, SpellLevel)
MaxSpellsPriestTable = GemRB.LoadTable (SpellTable)
GemRB.SetVar ("PriestMemorized", 0)
@@ -2387,8 +2374,7 @@ def DrawAvatar():
lookup = CommonTables.Races.GetRowName (lookup)
AvatarID = AvatarID+table.GetValue (lookup, "RACE")
table = GemRB.LoadTable ("avprefc")
- lookup = CommonTables.Classes.FindValue (5, GemRB.GetPlayerStat(MyChar, IE_CLASS))
- lookup = CommonTables.Classes.GetRowName (lookup)
+ lookup = GUICommon.GetClassRowName (MyChar)
AvatarID = AvatarID+table.GetValue (lookup, "PREFIX")
table = GemRB.LoadTable ("avprefg")
AvatarID = AvatarID+table.GetValue (GemRB.GetPlayerStat(MyChar,IE_SEX),0)
@@ -2575,6 +2561,7 @@ def BiographyPress():
BiographyField = BiographyWindow.GetControl (4)
BiographyField.SetText (19423)
+ BiographyField.SetBackground("")
BiographyClearButton = BiographyWindow.GetControl (5)
BiographyClearButton.SetState (IE_GUI_BUTTON_ENABLED)
@@ -2714,7 +2701,7 @@ def ImportPress():
def ImportDonePress():
global CharGenWindow, ImportWindow, CharImportList
- global CharGenState, SkillsState, Portrait
+ global CharGenState, SkillsState, Portrait, ImportedChar
# Import the character from the chosen name
GemRB.CreatePlayer (CharImportList.QueryText(), MyChar|0x8000, 1)
@@ -2726,6 +2713,7 @@ def ImportDonePress():
PortraitButton.SetPicture (PortraitName)
Portrait = -1
+ ImportedChar = 1
CharGenState = 7
SkillsState = 5
SetCharacterDescription ()
diff --git a/gemrb/GUIScripts/iwd/GUICommonWindows.py b/gemrb/GUIScripts/iwd/GUICommonWindows.py
deleted file mode 100644
index 0cb7e0f..0000000
--- a/gemrb/GUIScripts/iwd/GUICommonWindows.py
+++ /dev/null
@@ -1,843 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-# GUICommonWindows.py - functions to open common
-# windows in lower part of the screen
-###################################################
-
-import GemRB
-from GUIDefines import *
-from ie_stats import *
-from ie_modal import *
-from ie_action import *
-import GUICommon
-import LUCommon
-import InventoryCommon
-
-# needed for all the Open*Window callbacks in the OptionsWindow
-import GUIJRNL
-import GUIMA
-import GUIMG
-import GUIINV
-import GUIOPT
-import GUIPR
-import GUIREC
-
-FRAME_PC_SELECTED = 0
-FRAME_PC_TARGET = 1
-
-PortraitWindow = None
-OptionsWindow = None
-ActionsWindow = None
-DraggedPortrait = None
-
-def SetupMenuWindowControls (Window, Gears, ReturnToGame):
- # FIXME: add "(key)" to tooltips!
-
- # Return to Game
- Button = Window.GetControl (0)
- Button.SetTooltip (16313)
- #Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- Button.SetVarAssoc ("SelectedWindow", 0)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, ReturnToGame)
- Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- # Map
- Button = Window.GetControl (1)
- Button.SetTooltip (16310)
- #Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- Button.SetVarAssoc ("SelectedWindow", 1)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIMA.OpenMapWindow)
-
- # Journal
- Button = Window.GetControl (2)
- Button.SetTooltip (16308)
- #Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- Button.SetVarAssoc ("SelectedWindow", 2)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIJRNL.OpenJournalWindow)
-
- # Inventory
- Button = Window.GetControl (3)
- Button.SetTooltip (16307)
- #Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- Button.SetVarAssoc ("SelectedWindow", 3)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIINV.OpenInventoryWindow)
-
- # Records
- Button = Window.GetControl (4)
- Button.SetTooltip (16306)
- #Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- Button.SetVarAssoc ("SelectedWindow", 4)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIREC.OpenRecordsWindow)
-
- # Mage
- Button = Window.GetControl (5)
- Button.SetTooltip (16309)
- #Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- Button.SetVarAssoc ("SelectedWindow", 5)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIMG.OpenMageWindow)
- # Priest
- Button = Window.GetControl (6)
- Button.SetTooltip (14930)
- #Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- Button.SetVarAssoc ("SelectedWindow", 6)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIPR.OpenPriestWindow)
-
- # Options
- Button = Window.GetControl (7)
- Button.SetTooltip (16311)
- #Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- Button.SetVarAssoc ("SelectedWindow", 7)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIOPT.OpenOptionsWindow)
-
- # Party mgmt
- Button = Window.GetControl (8)
- Button.SetTooltip (16312)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, None)
-
- if Gears:
- # Gears (time), how doesn't have this in the right place
- if GUICommon.HasHOW():
- pos = GemRB.GetSystemVariable (SV_HEIGHT)-71
- Window.CreateButton (9, 6, pos, 64, 71)
- Button = Window.GetControl (9)
- Button.SetAnimation ("CGEAR")
- Button.SetState (IE_GUI_BUTTON_ENABLED)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_ANIMATED|IE_GUI_BUTTON_NORMAL, OP_SET)
- Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, GUICommon.GearsClicked)
- GUICommon.SetGamedaysAndHourToken()
- Button.SetTooltip(16041)
-
- MarkMenuButton (Window)
- return
-
-def MarkMenuButton (WindowIndex):
- Pressed = WindowIndex.GetControl( GemRB.GetVar ("SelectedWindow") )
-
- for button in range (9):
- Button = WindowIndex.GetControl (button)
- Button.SetState (IE_GUI_BUTTON_ENABLED)
-
- if Pressed:
- Button = Pressed
- else: # highlight return to game
- Button = WindowIndex.GetControl (0)
-
- Button.SetState (IE_GUI_BUTTON_PRESSED)
-
-def AIPress ():
- Button = PortraitWindow.GetControl (6)
- AI = GemRB.GetMessageWindowSize () & GS_PARTYAI
- if AI:
- GemRB.GameSetScreenFlags (GS_PARTYAI, OP_NAND)
- Button.SetTooltip (15918)
- else:
- GemRB.GameSetScreenFlags (GS_PARTYAI, OP_OR)
- Button.SetTooltip (15917)
- return
-
-def EmptyControls ():
- global ActionsWindow
-
- GemRB.SetVar ("ActionLevel", 0)
- Window = ActionsWindow
- for i in range (12):
- Button = Window.GetControl (i)
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- Button.SetPicture ("")
- Button.SetText ("")
- Button.SetActionIcon (globals(), -1)
- return
-
-def SelectFormationPreset ():
- """Choose the default formation."""
- GemRB.GameSetFormation (GemRB.GetVar ("Value"), GemRB.GetVar ("Formation") )
- GroupControls ()
- return
-
-def SetupFormation ():
- """Opens the formation selection section."""
- global ActionsWindow
-
- Window = ActionsWindow
- for i in range (12):
- Button = Window.GetControl (i)
- Button.SetFlags (IE_GUI_BUTTON_NORMAL, OP_SET)
- Button.SetSprites ("GUIBTBUT",0,0,1,2,3)
- Button.SetBAM ("FORM%x"%i,0,0,-1)
- Button.SetVarAssoc ("Value", i)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SelectFormationPreset)
- return
-
-def GroupControls ():
- """Sections that control group actions."""
-
- global ActionsWindow
-
- GemRB.SetVar ("ActionLevel", 0)
- Window = ActionsWindow
- Button = Window.GetControl (0)
- Button.SetActionIcon (globals(), 7)
- Button = Window.GetControl (1)
- Button.SetActionIcon (globals(), 15)
- Button = Window.GetControl (2)
- Button.SetActionIcon (globals(), 21)
- Button = Window.GetControl (3)
- Button.SetActionIcon (globals(), -1)
- Button = Window.GetControl (4)
- Button.SetActionIcon (globals(), -1)
- Button = Window.GetControl (5)
- Button.SetActionIcon (globals(), -1)
- Button = Window.GetControl (6)
- Button.SetActionIcon (globals(), -1)
- GemRB.SetVar ("Formation", GemRB.GameGetFormation ())
- for i in range (5):
- Button = Window.GetControl (7+i)
- Button.SetState (IE_GUI_BUTTON_ENABLED)
- idx = GemRB.GameGetFormation (i)
- Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON|IE_GUI_BUTTON_NORMAL, OP_SET)
- Button.SetSprites ("GUIBTBUT",0,i*2,i*2+1,i*2+24,i*2+25)
- Button.SetBAM ("FORM%x"%idx,0,0,-1)
- Button.SetVarAssoc ("Formation", i)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUICommon.SelectFormation)
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, SetupFormation)
- str = GemRB.GetString (4935)
- Button.SetTooltip ("F%d - %s"%(8+i,str) )
- return
-
-def OpenActionsWindowControls (Window):
- global ActionsWindow
-
- ActionsWindow = Window
- UpdateActionsWindow ()
- return
-
-def SelectItemAbility():
- pc = GemRB.GameGetFirstSelectedActor ()
- slot = GemRB.GetVar ("Slot")
- ability = GemRB.GetVar ("Ability")
- GemRB.SetupQuickSlot (pc, 0, slot, ability, 1)
- GemRB.SetVar ("ActionLevel", 0)
- return
-
-def SetupItemAbilities(pc, slot):
- Window = ActionsWindow
-
- slot_item = GemRB.GetSlotItem(pc, slot, 1)
- item = GemRB.GetItem (slot_item["ItemResRef"])
- Tips = item["Tooltips"]
-
- for i in range (12):
- Button = Window.GetControl (i)
- Button.SetPicture ("")
- if i<len(Tips):
- Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON|IE_GUI_BUTTON_NORMAL, OP_SET)
- Button.SetSprites ("GUIBTBUT",0,0,1,2,3)
- Button.SetItemIcon (slot_item['ItemResRef'], i+6)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SelectItemAbility)
- Button.SetVarAssoc ("Ability", i)
-
- Button.SetTooltip ("F%d - %s"%(i+1,GemRB.GetString(Tips[i])) )
- else:
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- return
-
-def UpdateActionsWindow ():
- """Redraws the actions section of the window."""
-
- global ActionsWindow, PortraitWindow, OptionsWindow
- global level, TopIndex
-
- if ActionsWindow == -1:
- return
-
- if ActionsWindow == None:
- return
-
- #fully redraw the side panes to cover the actions window
- #do this only when there is no 'otherwindow'
- if GemRB.GetVar ("OtherWindow") == -1:
- if PortraitWindow:
- PortraitWindow.Invalidate ()
- if OptionsWindow:
- OptionsWindow.Invalidate ()
-
- Selected = GemRB.GetSelectedSize()
-
- #setting up the disabled button overlay (using the second border slot)
- for i in range (12):
- Button = ActionsWindow.GetControl (i)
- Button.SetBorder (1, 0, 0, 0, 0, 50,30,10,120, 0, 1)
- Button.SetFont ("NUMBER")
- Button.SetText ("")
-
- if Selected == 0:
- EmptyControls ()
- return
- if Selected > 1:
- GroupControls ()
- return
-
- #we are sure there is only one actor selected
- pc = GemRB.GameGetFirstSelectedActor ()
-
- level = GemRB.GetVar ("ActionLevel")
- TopIndex = GemRB.GetVar ("TopIndex")
- if level == 0:
- #this is based on class
- ActionsWindow.SetupControls (globals(), pc, 0, 1)
- elif level == 1:
- ActionsWindow.SetupEquipmentIcons(globals(), pc, TopIndex, 0, 1)
- elif level == 2: #spells
- GemRB.SetVar ("Type", 3)
- ActionsWindow.SetupSpellIcons(globals(), pc, 3, TopIndex, 0, 1)
- elif level == 3: #innates
- GemRB.SetVar ("Type", 4)
- ActionsWindow.SetupSpellIcons(globals(), pc, 4, TopIndex, 0, 1)
- elif level == 4: #quick weapon/item ability selection
- SetupItemAbilities(pc, GemRB.GetVar("Slot") )
- return
-
-def ActionQWeaponPressed (which):
- """Selects the given quickslot weapon if possible."""
-
- pc = GemRB.GameGetFirstSelectedActor ()
- qs = GemRB.GetEquippedQuickSlot (pc, 1, 1)
-
- #38 is the magic slot
- if ((qs==which) or (qs==38)) and GemRB.GameControlGetTargetMode() != TARGET_MODE_ATTACK:
- GemRB.GameControlSetTargetMode (TARGET_MODE_ATTACK, GA_NO_DEAD|GA_NO_SELF|GA_NO_HIDDEN)
- else:
- GemRB.GameControlSetTargetMode (TARGET_MODE_NONE)
- GemRB.SetEquippedQuickSlot (pc, which, -1, 1)
-
- ActionsWindow.SetupControls (globals(), pc, 0, 1)
- UpdateActionsWindow ()
- return
-
-def ActionQWeapon1Pressed ():
- ActionQWeaponPressed(0)
-
-def ActionQWeapon2Pressed ():
- ActionQWeaponPressed(1)
-
-def ActionQWeapon3Pressed ():
- ActionQWeaponPressed(2)
-
-def ActionQWeapon4Pressed ():
- ActionQWeaponPressed(3)
-
-#no check needed because the button wouldn't be drawn if illegal
-def ActionLeftPressed ():
- """Scrolls the actions window left.
-
- Used primarily for spell selection."""
-
- TopIndex = GemRB.GetVar ("TopIndex")
- if TopIndex>10:
- TopIndex -= 10
- else:
- TopIndex = 0
- GemRB.SetVar ("TopIndex", TopIndex)
- UpdateActionsWindow ()
- return
-
-#no check needed because the button wouldn't be drawn if illegal
-def ActionRightPressed ():
- """Scrolls the action window right.
-
- Used primarily for spell selection."""
-
- pc = GemRB.GameGetFirstSelectedActor ()
- TopIndex = GemRB.GetVar ("TopIndex")
- Type = GemRB.GetVar ("Type")
- #Type is a bitfield if there is no level given
- #This is to make sure cleric/mages get all spells listed
- Max = GemRB.GetMemorizedSpellsCount(pc, Type, -1, 1)
- TopIndex += 10
- if TopIndex > Max - 10:
- if Max>10:
- TopIndex = Max-10
- else:
- TopIndex = 0
-
- GemRB.SetVar ("TopIndex", TopIndex)
- UpdateActionsWindow ()
- return
-
-def ActionBardSongPressed ():
- """Toggles the battle song."""
- pc = GemRB.GameGetFirstSelectedActor ()
- GemRB.SetModalState (pc, MS_BATTLESONG, 1)
- GemRB.PlaySound ("act_01")
- UpdateActionsWindow ()
- return
-
-def ActionSearchPressed ():
- """Toggles detect traps."""
- pc = GemRB.GameGetFirstSelectedActor ()
- GemRB.SetModalState (pc, MS_DETECTTRAPS, 1)
- UpdateActionsWindow ()
- return
-
-def ActionStealthPressed ():
- """Toggles stealth."""
- pc = GemRB.GameGetFirstSelectedActor ()
- GemRB.SetModalState (pc, MS_STEALTH, 1)
- GemRB.PlaySound ("act_07")
- UpdateActionsWindow ()
- return
-
-def ActionTurnPressed ():
- """Toggles turn undead."""
- pc = GemRB.GameGetFirstSelectedActor ()
- GemRB.SetModalState (pc, MS_TURNUNDEAD, 1)
- GemRB.PlaySound ("act_06")
- UpdateActionsWindow ()
- return
-
-def ActionUseItemPressed ():
- GemRB.SetVar ("TopIndex", 0)
- GemRB.SetVar ("ActionLevel", 1)
- UpdateActionsWindow ()
- return
-
-def ActionCastPressed ():
- """Opens the spell choice scrollbar."""
- GemRB.SetVar ("TopIndex", 0)
- GemRB.SetVar ("ActionLevel", 2)
- UpdateActionsWindow ()
- return
-
-def ActionQItemPressed (action):
- """Uses the given quick item."""
- pc = GemRB.GameGetFirstSelectedActor ()
- #quick slot
- GemRB.UseItem (pc, -2, action, -1, 1)
- return
-
-def ActionQItem1Pressed ():
- ActionQItemPressed (ACT_QSLOT1)
- return
-
-def ActionQItem2Pressed ():
- ActionQItemPressed (ACT_QSLOT2)
- return
-
-def ActionQItem3Pressed ():
- ActionQItemPressed (ACT_QSLOT3)
- return
-
-def ActionQItem4Pressed ():
- ActionQItemPressed (ACT_QSLOT4)
- return
-
-def ActionQItem5Pressed ():
- ActionQItemPressed (ACT_QSLOT5)
- return
-
-def ActionQItemRightPressed (action):
- """Selects the used ability of the quick item."""
- pc = GemRB.GameGetFirstSelectedActor ()
- GemRB.SetVar ("Slot", action)
- GemRB.SetVar ("ActionLevel", 4)
- UpdateActionsWindow ()
- return
-
-def ActionQItem1RightPressed ():
- ActionQItemRightPressed (19)
-
-def ActionQItem2RightPressed ():
- ActionQItemRightPressed (20)
-
-def ActionQItem3RightPressed ():
- ActionQItemRightPressed (21)
-
-def ActionQItem4RightPressed ():
- ActionQItemRightPressed (22)
-
-def ActionQItem5RightPressed ():
- ActionQItemRightPressed (23)
-
-def ActionQWeapon1RightPressed ():
- ActionQItemRightPressed (10)
-
-def ActionQWeapon2RightPressed ():
- ActionQItemRightPressed (11)
-
-def ActionQWeapon3RightPressed ():
- ActionQItemRightPressed (12)
-
-def ActionQWeapon4RightPressed ():
- ActionQItemRightPressed (13)
-
-def ActionInnatePressed ():
- """Opens the innate spell scrollbar."""
- GemRB.SetVar ("TopIndex", 0)
- GemRB.SetVar ("ActionLevel", 3)
- UpdateActionsWindow ()
- return
-
-def SpellPressed ():
- """Prepares a spell to be cast."""
-
- pc = GemRB.GameGetFirstSelectedActor ()
-
- GemRB.GameControlSetTargetMode (TARGET_MODE_CAST)
- Spell = GemRB.GetVar ("Spell")
- Type = GemRB.GetVar ("Type")
- GemRB.SpellCast (pc, Type, Spell, 1)
- GemRB.SetVar ("ActionLevel", 0)
- UpdateActionsWindow ()
- return
-
-def EquipmentPressed ():
- pc = GemRB.GameGetFirstSelectedActor ()
-
- GemRB.GameControlSetTargetMode (TARGET_MODE_CAST)
- Item = GemRB.GetVar ("Equipment")
- #equipment index
- GemRB.UseItem (pc, -1, Item, -1, 1)
- GemRB.SetVar ("ActionLevel", 0)
- UpdateActionsWindow ()
- return
-
-SelectionChangeHandler = None
-
-def SetSelectionChangeHandler (handler):
- """Updates the selection handler."""
-
- global SelectionChangeHandler
-
- # Switching from walking to non-walking environment:
- # set the first selected PC in walking env as a selected
- # in nonwalking env
- #if (not SelectionChangeHandler) and handler:
- if (not SelectionChangeHandler) and handler and (not GUICommon.NextWindowFn):
- sel = GemRB.GameGetFirstSelectedPC ()
- if not sel:
- sel = 1
- GemRB.GameSelectPCSingle (sel)
-
- SelectionChangeHandler = handler
-
- # redraw selection on change main selection | single selection
- SelectionChanged ()
- return
-
-def RunSelectionChangeHandler ():
- if SelectionChangeHandler:
- SelectionChangeHandler ()
- return
-
-def OpenPortraitWindow (needcontrols):
- global PortraitWindow
-
- #take care, this window is different in how/iwd
- if GUICommon.HasHOW() and needcontrols:
- PortraitWindow = Window = GemRB.LoadWindow (26)
- else:
- PortraitWindow = Window = GemRB.LoadWindow (1)
-
- if needcontrols:
- if GUICommon.HasHOW():
- # Rest (how)
- pos = GemRB.GetSystemVariable (SV_HEIGHT) - 37
- Window.CreateButton (8, 6, pos, 55, 37)
- Button = Window.GetControl (8)
- Button.SetSprites ("GUIRSBUT", 0,0,1,0,0)
- Button.SetTooltip (11942)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUICommon.RestPress)
-
- pos = pos - 37
- Window.CreateButton (6, 6, pos, 27, 36)
- # AI
- Button = Window.GetControl (6)
- #fixing a gui bug, and while we are at it, hacking it to be easier
- Button.SetSprites ("GUIBTACT", 0, 46, 47, 48, 49)
- GSFlags = GemRB.GetMessageWindowSize ()&GS_PARTYAI
-
- GemRB.SetVar ("AI", GSFlags)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, AIPress)
- Button.SetFlags (IE_GUI_BUTTON_CHECKBOX, OP_OR)
- Button.SetVarAssoc ("AI", 1)
- if GSFlags:
- Button.SetTooltip (15917)
- else:
- Button.SetTooltip (15918)
-
- #Select All
- if GUICommon.HasHOW():
- Window.CreateButton (7, 33, pos, 27, 36)
- Button = Window.GetControl (7)
- Button.SetSprites ("GUIBTACT", 0, 50, 51, 50, 51)
- Button.SetTooltip (10485)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUICommon.SelectAllOnPress)
- if not GUICommon.HasHOW():
- # Rest (iwd)
- Button = PortraitWindow.GetControl (8)
- Button.SetTooltip (11942)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUICommon.RestPress)
-
- pc = GemRB.GameGetSelectedPCSingle ()
- Inventory = GemRB.GetVar ("Inventory")
-
- for i in range (PARTY_SIZE):
- Button = Window.GetControl (i)
- Button.SetFont ("STATES")
- Button.SetVarAssoc ("PressedPortrait", i+1)
-
- if (needcontrols):
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, GUIINV.OpenInventoryWindowClick)
- else:
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, PortraitButtonOnPress)
-
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, PortraitButtonOnPress)
- Button.SetEvent (IE_GUI_BUTTON_ON_SHIFT_PRESS, PortraitButtonOnShiftPress)
- Button.SetEvent (IE_GUI_BUTTON_ON_DRAG_DROP, InventoryCommon.OnDropItemToPC)
- Button.SetEvent (IE_GUI_BUTTON_ON_DRAG_DROP_PORTRAIT, OnDropPortraitToPC)
- Button.SetEvent (IE_GUI_BUTTON_ON_DRAG, PortraitButtonOnDrag)
- Button.SetEvent (IE_GUI_MOUSE_ENTER_BUTTON, PortraitButtonOnMouseEnter)
- Button.SetEvent (IE_GUI_MOUSE_LEAVE_BUTTON, PortraitButtonOnMouseLeave)
- if Inventory and pc != i+1:
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- Button.SetText ("")
- Button.SetTooltip ("")
-
- # overlay a label, so we can display the hp with the correct font
- Button.CreateLabelOnButton(100+i, "NUMFONT", IE_GUI_BUTTON_ALIGN_TOP|IE_GUI_BUTTON_ALIGN_LEFT)
-
- Button.SetBorder (FRAME_PC_SELECTED, 1, 1, 2, 2, 0, 255, 0, 255)
- Button.SetBorder (FRAME_PC_TARGET, 3, 3, 4, 4, 255, 255, 0, 255)
-
- UpdatePortraitWindow ()
- SelectionChanged ()
- return Window
-
-def UpdatePortraitWindow ():
- """Updates all of the portraits."""
-
- Window = PortraitWindow
-
- pc = GemRB.GameGetSelectedPCSingle ()
- Inventory = GemRB.GetVar ("Inventory")
-
- for portid in range (PARTY_SIZE):
- Button = Window.GetControl (portid)
- pic = GemRB.GetPlayerPortrait (portid+1, 1)
- if Inventory and pc != portid+1:
- pic = None
-
- if not pic:
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- Button.SetText ("")
- Button.SetTooltip ("")
- continue
-
- sel = GemRB.GameGetSelectedPCSingle () == portid + 1
- Button.SetFlags (IE_GUI_BUTTON_PICTURE| \
- IE_GUI_BUTTON_HORIZONTAL| \
- IE_GUI_BUTTON_ALIGN_LEFT| IE_GUI_BUTTON_ALIGN_TOP| \
- IE_GUI_BUTTON_DRAGGABLE|IE_GUI_BUTTON_MULTILINE, OP_SET)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- Button.SetPicture (pic, "NOPORTSM")
-
- ratio_str = GUICommon.SetupDamageInfo (portid+1, Button)
-
- #add effects on the portrait
- #http://img.jeuxvideo.fr/00002663-photo-icewind-dale-heart-of-winter.jpg
- effects = GemRB.GetPlayerStates (portid+1)
- states = ""
- for col in range(len(effects)):
- states = effects[col:col+1] + states
- if col % 3 == 2: states = "\n" + states
- for x in range(2 - (len(effects)/3)):
- states = "\n" + states
- states = "\n" + states
-
- # blank space
- # TODO: missing, maybe add another string tag to make glyphs 100% transparent?
- flag = blank = chr(238)
-
- # these two are missing too
- ## shopping icon
- #if pc==portid+1:
- #if GemRB.GetStore()!=None:
- #flag = chr(155)
- ## talk icon
- #if GemRB.GameGetSelectedPCSingle(1)==portid+1:
- #flag = chr(154)
-
- if LUCommon.CanLevelUp (portid+1):
- states = flag+blank+chr(255) + states
- else:
- #states = flag+blank+blank + states
- #states = "\n" + states
- pass
- Button.SetText(states)
-
- HPLabel = Window.GetControl (100+portid)
- HPLabel.SetText (ratio_str) # TODO: color depending on the ratio
-
- #Button.EnableBorder (FRAME_PC_SELECTED, sel)
- return
-
-def PortraitButtonOnDrag ():
- global DraggedPortrait
-
- #they start from 1
- DraggedPortrait = GemRB.GetVar ("PressedPortrait")
- GemRB.DragItem (DraggedPortrait, -1, "")
- return
-
-def PortraitButtonOnPress ():
- """Selects the portrait individually."""
-
- i = GemRB.GetVar ("PressedPortrait")
-
- if not i:
- return
-
- if GemRB.GameControlGetTargetMode() != TARGET_MODE_NONE:
- GemRB.ActOnPC (i)
- return
-
- if (not SelectionChangeHandler):
- if GemRB.GameIsPCSelected (i):
- GemRB.GameControlSetScreenFlags (SF_CENTERONACTOR, OP_OR)
- GemRB.GameSelectPC (i, True, SELECT_REPLACE)
- else:
- GemRB.GameSelectPCSingle (i)
- SelectionChanged ()
- RunSelectionChangeHandler ()
- return
-
-def PortraitButtonOnShiftPress ():
- """Handles selecting multiple portaits with shift."""
-
- i = GemRB.GetVar ("PressedPortrait")
-
- if not i:
- return
-
- if (not SelectionChangeHandler):
- sel = GemRB.GameIsPCSelected (i)
- sel = not sel
- GemRB.GameSelectPC (i, sel)
- else:
- GemRB.GameSelectPCSingle (i)
- SelectionChanged ()
- RunSelectionChangeHandler ()
- return
-
-def SelectionChanged ():
- """Ran by the Game class when a PC selection is changed."""
-
- global PortraitWindow
-
- if not PortraitWindow:
- return
-
- GemRB.SetVar ("ActionLevel", 0)
- if (not SelectionChangeHandler):
- UpdateActionsWindow ()
- for i in range (PARTY_SIZE):
- Button = PortraitWindow.GetControl (i)
- Button.EnableBorder (FRAME_PC_SELECTED, GemRB.GameIsPCSelected (i + 1))
- else:
- sel = GemRB.GameGetSelectedPCSingle ()
- for i in range (PARTY_SIZE):
- Button = PortraitWindow.GetControl (i)
- Button.EnableBorder (FRAME_PC_SELECTED, i + 1 == sel)
- import CommonWindow
- CommonWindow.CloseContainerWindow()
- return
-
-def PortraitButtonOnMouseEnter ():
- global DraggedPortrait
-
- i = GemRB.GetVar ("PressedPortrait")
-
- GemRB.GameControlSetLastActor( i )
- if GemRB.IsDraggingItem()==2:
- if DraggedPortrait != None:
- GemRB.SwapPCs (DraggedPortrait, i)
- GemRB.SetVar ("PressedPortrait", DraggedPortrait)
- DraggedPortrait = i
- GemRB.SetTimedEvent (CheckDragging, 1)
- else:
- OnDropPortraitToPC()
- return
-
- if GemRB.IsDraggingItem ():
- Button = PortraitWindow.GetControl (i)
- Button.EnableBorder (FRAME_PC_TARGET, 1)
- return
-
-def OnDropPortraitToPC ():
- GemRB.SetVar ("PressedPortrait",0)
- GemRB.DragItem (0, -1, "")
- DraggedPortrait = None
- return
-
-def CheckDragging():
- """Contains portrait dragging in case of mouse out-of-range."""
-
- global DraggedPortrait
-
- i = GemRB.GetVar ("PressedPortrait")
- if not i:
- GemRB.DragItem (0, -1, "")
-
- if GemRB.IsDraggingItem()!=2:
- DraggedPortrait = None
- return
-
-def PortraitButtonOnMouseLeave ():
- i = GemRB.GetVar ("PressedPortrait")
- if not i:
- return
-
- Button = PortraitWindow.GetControl (i-1)
- Button.EnableBorder (FRAME_PC_TARGET, 0)
- GemRB.SetVar ("PressedPortrait", 0)
- GemRB.SetTimedEvent (CheckDragging, 1)
- return
-
-def ActionStopPressed ():
- for i in GemRB.GetSelectedActors():
- GemRB.ClearActions (i, 1)
- return
-
-def ActionTalkPressed ():
- GemRB.GameControlSetTargetMode (TARGET_MODE_TALK,GA_NO_DEAD|GA_NO_ENEMY|GA_NO_HIDDEN)
-
-def ActionAttackPressed ():
- GemRB.GameControlSetTargetMode (TARGET_MODE_ATTACK,GA_NO_DEAD|GA_NO_SELF|GA_NO_HIDDEN)
-
-def ActionDefendPressed ():
- GemRB.GameControlSetTargetMode (TARGET_MODE_DEFEND,GA_NO_SELF|GA_NO_ENEMY|GA_NO_HIDDEN)
-
-def ActionThievingPressed ():
- GemRB.GameControlSetTargetMode (TARGET_MODE_PICK, GA_NO_DEAD|GA_NO_SELF|GA_NO_ENEMY|GA_NO_HIDDEN)
-
-def CheckLevelUp(pc):
- GemRB.SetVar ("CheckLevelUp"+str(pc), LUCommon.CanLevelUp (pc))
diff --git a/gemrb/GUIScripts/iwd/GUIINV.py b/gemrb/GUIScripts/iwd/GUIINV.py
index 01b8f43..0446816 100644
--- a/gemrb/GUIScripts/iwd/GUIINV.py
+++ b/gemrb/GUIScripts/iwd/GUIINV.py
@@ -121,8 +121,12 @@ def OpenInventoryWindow ():
Button.SetEvent (IE_GUI_BUTTON_ON_DRAG_DROP, InventoryCommon.OnAutoEquip)
#encumbrance
- Label = Window.CreateLabel (0x10000043, 5,385,60,15,"NUMBER","0:",IE_FONT_ALIGN_LEFT|IE_FONT_ALIGN_TOP)
- Label = Window.CreateLabel (0x10000044, 5,455,80,15,"NUMBER","0:",IE_FONT_ALIGN_RIGHT|IE_FONT_ALIGN_TOP)
+ Button = Window.GetControl (67)
+ r = Button.GetRect ()
+ Label = Window.CreateLabel (0x10000043, r["X"],r["Y"],r["Width"],15,
+ "NUMBER","0:",IE_FONT_ALIGN_LEFT|IE_FONT_ALIGN_TOP)
+ Label = Window.CreateLabel (0x10000044, r["X"],r["Y"]+r["Height"]-15,r["Width"],15,
+ "NUMBER","0:",IE_FONT_ALIGN_RIGHT|IE_FONT_ALIGN_BOTTOM)
#armor class
Label = Window.GetControl (0x10000038)
@@ -235,7 +239,6 @@ def RefreshInventoryWindow ():
#armor class
Label = Window.GetControl (0x10000038)
ac = GemRB.GetPlayerStat (pc, IE_ARMORCLASS)
- ac += GemRB.GetAbilityBonus (IE_DEX, 2, GemRB.GetPlayerStat (pc, IE_DEX) )
Label.SetText (str (ac))
Label.SetTooltip (10339)
@@ -274,7 +277,7 @@ def RefreshInventoryWindow ():
for i in range (5):
Button = Window.GetControl (i+68)
if GemRB.IsDraggingItem ()==1:
- Button.SetState (IE_GUI_BUTTON_SECOND)
+ Button.SetState (IE_GUI_BUTTON_FAKEPRESSED)
else:
Button.SetState (IE_GUI_BUTTON_ENABLED)
Button.SetEvent (IE_GUI_BUTTON_ON_DRAG_DROP, InventoryCommon.OnDragItemGround)
@@ -292,11 +295,7 @@ def RefreshInventoryWindow ():
GUICommon.UpdateInventorySlot (pc, Button, Slot, "ground")
#making window visible/shaded depending on the pc's state
- held = GemRB.GetPlayerStat (pc, IE_HELD) + GemRB.GetPlayerStat (pc, IE_CASTERHOLD)
- if held or GemRB.GetPlayerStat (pc, IE_STATE_ID) & STATE_DEAD:
- Window.SetVisible (WINDOW_GRAYED)
- else:
- Window.SetVisible (WINDOW_VISIBLE)
+ GUICommon.AdjustWindowVisibility (Window, pc, False)
return
###################################################
diff --git a/gemrb/GUIScripts/iwd/GUILOAD.py b/gemrb/GUIScripts/iwd/GUILOAD.py
deleted file mode 100644
index f8d10bd..0000000
--- a/gemrb/GUIScripts/iwd/GUILOAD.py
+++ /dev/null
@@ -1,177 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-
-# GUILOAD.py - Load window
-
-###################################################
-
-import GemRB
-import LoadScreen
-from GUIDefines import *
-
-LoadWindow = 0
-TextAreaControl = 0
-Games = ()
-ScrollBar = 0
-
-def OnLoad ():
- global LoadWindow, TextAreaControl, Games, ScrollBar
-
- GemRB.SetVar ("PlayMode",0) #iwd is always using 'mpsave'
- GemRB.SetVar ("SaveDir",1) #iwd is always using 'mpsave'
- GemRB.LoadWindowPack ("GUILOAD", 640, 480)
- LoadWindow = GemRB.LoadWindow (0)
- LoadWindow.SetFrame ()
- CancelButton=LoadWindow.GetControl (34)
- CancelButton.SetText (13727)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CancelPress)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- GemRB.SetVar ("LoadIdx",0)
- for i in range (4):
- Button = LoadWindow.GetControl (26+i)
- Button.SetText (15590)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, LoadGamePress)
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- Button.SetVarAssoc ("LoadIdx",i)
-
- Button = LoadWindow.GetControl (30+i)
- Button.SetText (13957)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, DeleteGamePress)
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- Button.SetVarAssoc ("LoadIdx",i)
-
- #area previews
- Button = LoadWindow.GetControl (1+i)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE|IE_GUI_BUTTON_PICTURE,OP_SET)
-
- #PC portraits
- for j in range (PARTY_SIZE):
- Button = LoadWindow.GetControl (40 + i*PARTY_SIZE + j)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE|IE_GUI_BUTTON_PICTURE,OP_SET)
-
- ScrollBar=LoadWindow.GetControl (25)
- ScrollBar.SetEvent (IE_GUI_SCROLLBAR_ON_CHANGE, ScrollBarPress)
- Games=GemRB.GetSaveGames ()
- TopIndex = max (0, len(Games) - 4)
- GemRB.SetVar ("TopIndex",TopIndex)
- ScrollBar.SetVarAssoc ("TopIndex", TopIndex+1)
- ScrollBarPress ()
- LoadWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def ScrollBarPress ():
- #draw load game portraits
- Pos = GemRB.GetVar ("TopIndex")
- for i in range (4):
- ActPos = Pos + i
-
- Button1 = LoadWindow.GetControl (26+i)
- Button2 = LoadWindow.GetControl (30+i)
- if ActPos<len(Games):
- Button1.SetState (IE_GUI_BUTTON_ENABLED)
- Button2.SetState (IE_GUI_BUTTON_ENABLED)
- else:
- Button1.SetState (IE_GUI_BUTTON_DISABLED)
- Button2.SetState (IE_GUI_BUTTON_DISABLED)
-
- if ActPos<len(Games):
- Slotname = Games[ActPos].GetName()
- else:
- Slotname = ""
- Label = LoadWindow.GetControl (0x10000008+i)
- Label.SetText (Slotname)
-
- if ActPos<len(Games):
- Slotname = Games[ActPos].GetGameDate()
- else:
- Slotname = ""
- Label = LoadWindow.GetControl (0x10000010+i)
- Label.SetText (Slotname)
-
- Button=LoadWindow.GetControl (1+i)
- if ActPos<len(Games):
- Button.SetSprite2D(Games[ActPos].GetPreview())
- else:
- Button.SetPicture ("")
- for j in range (PARTY_SIZE):
- Button=LoadWindow.GetControl (40 + i*PARTY_SIZE + j)
- if ActPos<len(Games):
- Button.SetSprite2D(Games[ActPos].GetPortrait(j))
- else:
- Button.SetPicture ("")
- return
-
-def LoadGamePress ():
- if LoadWindow:
- LoadWindow.Unload ()
- Pos = GemRB.GetVar ("TopIndex")+GemRB.GetVar ("LoadIdx")
- LoadScreen.StartLoadScreen()
- GemRB.LoadGame(Games[Pos]) #loads and enters savegame
- GemRB.SetNextScript ("PartyFormation")
- return
-
-def DeleteGameConfirm():
- global Games
-
- TopIndex = GemRB.GetVar ("TopIndex")
- Pos = TopIndex +GemRB.GetVar ("LoadIdx")
- GemRB.DeleteSaveGame(Games[Pos])
- if TopIndex>0:
- GemRB.SetVar ("TopIndex",TopIndex-1)
- del Games[Pos]
- ScrollBar.SetVarAssoc ("TopIndex", len(Games))
- ScrollBarPress ()
- if ConfirmWindow:
- ConfirmWindow.Unload ()
- LoadWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def DeleteGameCancel ():
- if ConfirmWindow:
- ConfirmWindow.Unload ()
- LoadWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def DeleteGamePress ():
- global ConfirmWindow
-
- LoadWindow.SetVisible (WINDOW_INVISIBLE)
- ConfirmWindow=GemRB.LoadWindow (1)
- Text=ConfirmWindow.GetControl (0)
- Text.SetText (15305)
- DeleteButton=ConfirmWindow.GetControl (1)
- DeleteButton.SetText (13957)
- DeleteButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DeleteGameConfirm)
- CancelButton=ConfirmWindow.GetControl (2)
- CancelButton.SetText (13727)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DeleteGameCancel)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- ConfirmWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def CancelPress ():
- if LoadWindow:
- LoadWindow.Unload ()
- GemRB.SetNextScript ("Start")
- return
diff --git a/gemrb/GUIScripts/iwd/GUIMA.py b/gemrb/GUIScripts/iwd/GUIMA.py
index 2352005..5aee929 100644
--- a/gemrb/GUIScripts/iwd/GUIMA.py
+++ b/gemrb/GUIScripts/iwd/GUIMA.py
@@ -207,7 +207,11 @@ def MoveToNewArea ():
tmp = WorldMapControl.GetDestinationArea (1)
CloseWorldMapWindow ()
- GemRB.CreateMovement (tmp["Destination"], tmp["Entrance"], tmp["Direction"])
+
+ if tmp["Destination"].lower() != GemRB.GetGameString(STR_AREANAME).lower():
+ GemRB.CreateMovement (tmp["Destination"], tmp["Entrance"], tmp["Direction"])
+ # distance is stored in hours, but the action needs seconds
+ GemRB.ExecuteString ("AdvanceTime(%d)"%(tmp["Distance"]*300))
return
def ChangeTooltip ():
@@ -215,7 +219,7 @@ def ChangeTooltip ():
global str
tmp = WorldMapControl.GetDestinationArea ()
- if (tmp):
+ if tmp and tmp["Distance"] >= 0:
str = "%s: %d"%(GemRB.GetString(23084),tmp["Distance"])
else:
str=""
@@ -280,6 +284,7 @@ def WorldMapWindowCommon (Travel):
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseWorldMapWindow)
Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
Window.SetVisible (WINDOW_VISIBLE)
+ WorldMapControl.SetStatus (IE_GUI_CONTROL_FOCUSED)
return
def MapN():
diff --git a/gemrb/GUIScripts/iwd/GUIMG.py b/gemrb/GUIScripts/iwd/GUIMG.py
index c062efb..5645bc7 100644
--- a/gemrb/GUIScripts/iwd/GUIMG.py
+++ b/gemrb/GUIScripts/iwd/GUIMG.py
@@ -92,9 +92,6 @@ def OpenMageWindow ():
## Button = Window.GetControl (56 + i)
## Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, RefreshMageLevel)
## Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
-
-## for i in range (9):
-## Button = Window.GetControl (56 + i)
## Button.SetVarAssoc ("MageSpellLevel", i)
@@ -103,13 +100,13 @@ def OpenMageWindow ():
Button = Window.GetControl (3 + i)
Button.SetBorder (0,0,0,0,0,0,0,0,64,0,1)
Button.SetSprites ("SPELFRAM",0,0,0,0,0)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_OR)
+ Button.SetFlags (IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_PLAYONCE, OP_OR)
Button.SetState (IE_GUI_BUTTON_LOCKED)
# Setup book spells buttons
- for i in range (GUICommon.GetIWDSpellButtonCount()):
+ for i in range (GUICommon.GetGUISpellButtonCount()):
Button = Window.GetControl (27 + i)
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_OR)
+ Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE | IE_GUI_BUTTON_PLAYONCE, OP_OR)
Button.SetState (IE_GUI_BUTTON_LOCKED)
GUICommonWindows.SetSelectionChangeHandler (UpdateMageWindow)
@@ -139,14 +136,14 @@ def UpdateMageWindow ():
Name = GemRB.GetPlayerName (pc, 0)
Label = Window.GetControl (0x10000035)
Label.SetText (Name)
- mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level)
+ mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level, False)
for i in range (12):
Button = Window.GetControl (3 + i)
if i < mem_cnt:
ms = GemRB.GetMemorizedSpell (pc, type, level, i)
Button.SetSpellIcon (ms['SpellResRef'], 0)
Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_NAND)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_OR)
+ Button.SetFlags (IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_PLAYONCE, OP_OR)
if ms['Flags']:
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenMageSpellUnmemorizeWindow)
else:
@@ -159,7 +156,7 @@ def UpdateMageWindow ():
Button.EnableBorder (0, ms['Flags'] == 0)
else:
if i < max_mem_cnt:
- Button.SetFlags (IE_GUI_BUTTON_NORMAL, OP_SET)
+ Button.SetFlags (IE_GUI_BUTTON_NORMAL | IE_GUI_BUTTON_PLAYONCE, OP_SET)
else:
Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, None)
@@ -169,7 +166,7 @@ def UpdateMageWindow ():
known_cnt = GemRB.GetKnownSpellsCount (pc, type, level)
- for i in range (GUICommon.GetIWDSpellButtonCount()):
+ for i in range (GUICommon.GetGUISpellButtonCount()):
Button = Window.GetControl (27 + i)
if i < known_cnt:
ks = GemRB.GetKnownSpell (pc, type, level, i)
@@ -188,11 +185,8 @@ def UpdateMageWindow ():
Button.SetTooltip ('')
Button.EnableBorder (0, 0)
- if (CommonTables.ClassSkills.GetValue (GemRB.GetPlayerStat (pc, IE_CLASS), 2)=="*") or \
- GemRB.GetPlayerStat (pc, IE_STATE_ID) & STATE_DEAD:
- Window.SetVisible (WINDOW_GRAYED)
- else:
- Window.SetVisible (WINDOW_VISIBLE)
+ CantCast = CommonTables.ClassSkills.GetValue (GUICommon.GetClassRowName (pc), "MAGESPELL") == "*"
+ GUICommon.AdjustWindowVisibility (Window, pc, CantCast)
return
def MagePrevLevelPress ():
@@ -227,6 +221,12 @@ def OnMageMemorizeSpell ():
if GemRB.MemorizeSpell (pc, type, level, index):
UpdateMageWindow ()
+ GemRB.PlaySound ("GAM_24")
+ Button = MageWindow.GetControl(index + 27)
+ Button.SetAnimation ("FLASH",0,1)
+ mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level, False)
+ Button = MageWindow.GetControl(mem_cnt + 2)
+ Button.SetAnimation ("FLASH",0,1)
return
def OpenMageSpellInfoWindow ():
@@ -335,6 +335,9 @@ def OnMageUnmemorizeSpell ():
if GemRB.UnmemorizeSpell (pc, type, level, index):
UpdateMageWindow ()
+ GemRB.PlaySound ("GAM_44")
+ Button = MageWindow.GetControl(index + 3)
+ Button.SetAnimation ("FLASH",0,1)
return
def OnMageRemoveSpell ():
diff --git a/gemrb/GUIScripts/iwd/GUIOPT.py b/gemrb/GUIScripts/iwd/GUIOPT.py
deleted file mode 100644
index ee8e21b..0000000
--- a/gemrb/GUIScripts/iwd/GUIOPT.py
+++ /dev/null
@@ -1,724 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-
-# GUIOPT.py - scripts to control options windows mostly from GUIOPT winpack
-
-# GUIOPT:
-# 0 - Main options window (peacock tail)
-# 1 - Video options window
-# 2 - msg win with 1 button
-# 3 - msg win with 2 buttons
-# 4 - msg win with 3 buttons
-# 5 - Audio options window
-# 6 - Gameplay options window
-# 8 - Feedback options window
-# 9 - Autopause options window
-
-
-###################################################
-import GemRB
-import GUICommon
-import GUISAVE
-import GUICommonWindows
-from GUIDefines import *
-
-###################################################
-BackgroundWindow = None
-GameOptionsWindow = None
-PortraitWindow = None
-OldPortraitWindow = None
-OptionsWindow = None
-OldOptionsWindow = None
-HelpTextArea = None
-
-LoadMsgWindow = None
-QuitMsgWindow = None
-
-###################################################
-def CloseOptionsWindow ():
- global BackgroundWindow, OptionsWindow, PortraitWindow
- global OldPortraitWindow, OldOptionsWindow
-
- if BackgroundWindow == None:
- return
-
- if BackgroundWindow:
- BackgroundWindow.Unload ()
- if OptionsWindow:
- OptionsWindow.Unload ()
- if PortraitWindow:
- PortraitWindow.Unload ()
-
- BackgroundWindow = None
- GemRB.SetVar ("OtherWindow", -1)
- GUICommon.GameWindow.SetVisible(WINDOW_VISIBLE)
- GemRB.UnhideGUI ()
- GUICommonWindows.OptionsWindow = OldOptionsWindow
- OldOptionsWindow = None
- GUICommonWindows.PortraitWindow = OldPortraitWindow
- OldPortraitWindow = None
- return
-
-def OpenOptionsWindow ():
- """Open main options window"""
- global BackgroundWindow, OptionsWindow, PortraitWindow
- global OldPortraitWindow, OldOptionsWindow
-
- if GUICommon.CloseOtherWindow(OpenOptionsWindow):
- CloseOptionsWindow()
- return
-
- hideflag = GemRB.HideGUI ()
- GUICommon.GameWindow.SetVisible(WINDOW_INVISIBLE)
-
- GemRB.LoadWindowPack ("GUIOPT", 640, 480)
- BackgroundWindow = Window = GemRB.LoadWindow (2)
- GemRB.SetVar ("OtherWindow", BackgroundWindow.ID)
- #saving the original portrait window
- if OldPortraitWindow == None:
- OldOptionsWindow = GUICommonWindows.OptionsWindow
- OptionsWindow = GemRB.LoadWindow (0)
- GUICommonWindows.SetupMenuWindowControls (OptionsWindow, 0, OpenOptionsWindow)
- OptionsWindow.SetFrame ()
- OldPortraitWindow = GUICommonWindows.PortraitWindow
- PortraitWindow = GUICommonWindows.OpenPortraitWindow (0)
-
- # Return to Game
- Button = Window.GetControl (11)
- Button.SetText (10308)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenOptionsWindow)
-
- # Quit Game
- Button = Window.GetControl (10)
- Button.SetText (13731)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenQuitMsgWindow)
-
- # Load Game
- Button = Window.GetControl (5)
- Button.SetText (13729)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenLoadMsgWindow)
-
- # Save Game
- Button = Window.GetControl (6)
- Button.SetText (13730)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenSaveMsgWindow)
-
- # Graphics
- Button = Window.GetControl (7)
- Button.SetText (17162)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenVideoOptionsWindow)
-
- # Audio
- Button = Window.GetControl (8)
- Button.SetText (17164)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenAudioOptionsWindow)
-
- # Gameplay
- Button = Window.GetControl (9)
- Button.SetText (17165)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenGameplayOptionsWindow)
-
- # game version, e.g. v1.1.0000
- Label = Window.GetControl (0x1000000b)
- Label.SetText (GEMRB_VERSION)
-
- OptionsWindow.SetVisible (WINDOW_VISIBLE)
- Window.SetVisible (WINDOW_VISIBLE)
- PortraitWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-
-###################################################
-def CloseVideoOptionsWindow ():
- global GameOptionsWindow
-
- if GameOptionsWindow:
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
-
-def OpenVideoOptionsWindow ():
- """Open video options window"""
- global GameOptionsWindow, HelpTextArea
-
- GameOptionsWindow = Window = GemRB.LoadWindow (6)
-
- HelpTextArea = OptHelpText ('VideoOptions', Window, 33, 18038)
-
- OptDone ('VideoOptions', Window, 21)
- OptCancel ('VideoOptions', Window, 32)
-
- OptSlider ('Brightness', Window, 3, 'Brightness Correction', 0)
- OptSlider ('Contrast', Window, 22, 'Gamma Correction', 0)
-
- OptRadio ('BPP', Window, 5, 37, 'BitsPerPixel', 16)
- OptRadio ('BPP', Window, 6, 37, 'BitsPerPixel', 24)
- OptRadio ('BPP', Window, 7, 37, 'BitsPerPixel', 32)
- OptCheckbox ('FullScreen', Window, 9, 38, 'Full Screen', 1)
-
- OptCheckbox ('TransShadow', Window, 51, 50, 'Translucent Shadows', 1)
- OptCheckbox ('SoftMirrBlt', Window, 40, 44, 'SoftMirrorBlt' ,1)
- OptCheckbox ('SoftTransBlt', Window, 41, 46, 'SoftSrcKeyBlt' ,1)
- OptCheckbox ('SoftStandBlt', Window, 42, 48, 'SoftBltFast' ,1)
- OptCheckbox ('TransBlt', Window, 56, 52, 'Translucent Blts' ,1)
- OptCheckbox ('StaticAnim', Window, 57, 54, 'Static Animations' ,1)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
-
-def DisplayHelpFullScreen ():
- HelpTextArea.SetText (18000)
- GemRB.SetFullScreen (GemRB.GetVar("Full Screen"))
-
-def DisplayHelpBPP ():
- HelpTextArea.SetText (17205)
-
-def DisplayHelpBrightness ():
- HelpTextArea.SetText (17203)
- GemRB.SetGamma (GemRB.GetVar("Brightness Correction"),GemRB.GetVar("Gamma Correction"))
-
-def DisplayHelpContrast ():
- HelpTextArea.SetText (17204)
- GemRB.SetGamma (GemRB.GetVar("Brightness Correction"),GemRB.GetVar("Gamma Correction"))
-
-def DisplayHelpTransShadow ():
- HelpTextArea.SetText (20620)
-
-def DisplayHelpSoftMirrBlt ():
- HelpTextArea.SetText (15135)
-
-def DisplayHelpSoftTransBlt ():
- HelpTextArea.SetText (18006)
-
-def DisplayHelpSoftStandBlt ():
- HelpTextArea.SetText (18007)
-
-def DisplayHelpTransBlt ():
- HelpTextArea.SetText (15141)
-
-def DisplayHelpStaticAnim ():
- HelpTextArea.SetText (18004)
-
-###################################################
-
-def CloseAudioOptionsWindow ():
- global GameOptionsWindow
-
- if GameOptionsWindow:
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
-
-def OpenAudioOptionsWindow ():
- """Open audio options window"""
- global GameOptionsWindow, HelpTextArea
-
- GameOptionsWindow = Window = GemRB.LoadWindow (7)
-
- HelpTextArea = OptHelpText ('AudioOptions', Window, 14, 18040)
-
- OptDone ('AudioOptions', Window, 24)
- OptCancel ('AudioOptions', Window, 25)
- OptButton ('CharacterSounds', Window, 13, 17778)
-
- OptSlider ('AmbientVolume', Window, 1, 'Volume Ambients', 10)
- OptSlider ('SoundFXVolume', Window, 2, 'Volume SFX', 10)
- OptSlider ('VoiceVolume', Window, 3, 'Volume Voices', 10)
- OptSlider ('MusicVolume', Window, 4, 'Volume Music', 10)
- OptSlider ('MovieVolume', Window, 22, 'Volume Movie', 10)
-
- OptCheckbox ('CreativeEAX', Window, 26, 28, 'Environmental Audio', 1)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
-
-def DisplayHelpAmbientVolume ():
- HelpTextArea.SetText (18008)
- GemRB.UpdateAmbientsVolume ()
-
-def DisplayHelpSoundFXVolume ():
- HelpTextArea.SetText (18009)
-
-def DisplayHelpVoiceVolume ():
- HelpTextArea.SetText (18010)
-
-def DisplayHelpMusicVolume ():
- HelpTextArea.SetText (18011)
- GemRB.UpdateMusicVolume ()
-
-def DisplayHelpMovieVolume ():
- HelpTextArea.SetText (18012)
-
-def DisplayHelpCreativeEAX ():
- HelpTextArea.SetText (18022)
-
-###################################################
-
-def CloseGameplayOptionsWindow ():
- global GameOptionsWindow
-
- if GameOptionsWindow:
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
-
-def OpenGameplayOptionsWindow ():
- """Open gameplay options window"""
- global GameOptionsWindow, HelpTextArea
-
- GameOptionsWindow = Window = GemRB.LoadWindow (8)
-
- HelpTextArea = OptHelpText ('GameOptions', Window, 40, 18042)
-
- OptDone ('GameplayOptions', Window, 7)
- OptCancel ('GameplayOptions', Window, 20)
-
- OptSlider ('TooltipDelay', Window, 1, 'Tooltips', 0)
- OptSlider ('MouseScrollingSpeed', Window, 2, 'Mouse Scroll Speed', 0)
- OptSlider ('KeyboardScrollingSpeed', Window, 3, 'Keyboard Scroll Speed', 0)
- OptSlider ('Difficulty', Window, 12, 'Difficulty Level', 0)
-
- OptCheckbox ('DitherAlways', Window, 14, 25, 'Always Dither', 1)
- OptCheckbox ('Gore', Window, 19, 27, 'Gore', 1)
- OptCheckbox ('Infravision', Window, 42, 44, 'Infravision', 1)
- OptCheckbox ('Weather', Window, 47, 46, 'Weather', 1)
- OptCheckbox ('MaxHitPoints', Window, 50, 49, 'Maximum HP', 1)
-
- OptButton ('FeedbackOptions', Window, 5, 17163)
- OptButton ('AutopauseOptions', Window, 6, 17166)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DisplayHelpTooltipDelay ():
- HelpTextArea.SetText (18017)
- GemRB.SetTooltipDelay (GemRB.GetVar ("Tooltips") )
-
-def DisplayHelpMouseScrollingSpeed ():
- HelpTextArea.SetText (18018)
- GemRB.SetMouseScrollSpeed (GemRB.GetVar ("Mouse Scroll Speed") )
-
-def DisplayHelpKeyboardScrollingSpeed ():
- HelpTextArea.SetText (18019)
-
-def DisplayHelpDifficulty ():
- HelpTextArea.SetText (18020)
-
-def DisplayHelpDitherAlways ():
- HelpTextArea.SetText (18021)
-
-def DisplayHelpGore ():
- HelpTextArea.SetText (18023)
-
-def DisplayHelpInfravision ():
- HelpTextArea.SetText (11797)
-
-def DisplayHelpWeather ():
- HelpTextArea.SetText (20619)
-
-def DisplayHelpMaxHitPoints ():
- HelpTextArea.SetText (15136)
-
-###################################################
-def CloseFeedbackOptionsWindow ():
- global GameOptionsWindow
-
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
- OpenGameplayOptionsWindow ()
-
-def OpenFeedbackOptionsWindow ():
- """Open feedback options window"""
- global GameOptionsWindow, HelpTextArea
-
- if GameOptionsWindow:
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
-
-
- GameOptionsWindow = Window = GemRB.LoadWindow (9)
-
- HelpTextArea = OptHelpText ('FeedbackOptions', Window, 28, 18043)
-
- OptDone ('FeedbackOptions', Window, 26)
- OptCancel ('FeedbackOptions', Window, 27)
-
- OptSlider ('MarkerFeedback', Window, 8, 'GUI Feedback Level', 1)
- OptSlider ('LocatorFeedback', Window, 9, 'Locator Feedback Level', 1)
-
- OptCheckbox ('ToHitRolls', Window, 10, 32, 'Rolls', 1)
- OptCheckbox ('CombatInfo', Window, 11, 33, 'Combat Info', 1)
- OptCheckbox ('Actions', Window, 12, 34, 'Actions', 1)
- OptCheckbox ('States', Window, 13, 35, 'State Changes', 1)
- OptCheckbox ('Selection', Window, 14, 36, 'Selection Text', 1)
- OptCheckbox ('Miscellaneous', Window, 15, 37, 'Miscellaneous Text', 1)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
-
-def DisplayHelpMarkerFeedback ():
- HelpTextArea.SetText (18024)
-
-def DisplayHelpLocatorFeedback ():
- HelpTextArea.SetText (18025)
-
-def DisplayHelpToHitRolls ():
- HelpTextArea.SetText (18026)
-
-def DisplayHelpCombatInfo ():
- HelpTextArea.SetText (18027)
-
-def DisplayHelpActions ():
- HelpTextArea.SetText (18028)
-
-def DisplayHelpStates ():
- HelpTextArea.SetText (18029)
-
-def DisplayHelpSelection ():
- HelpTextArea.SetText (18030)
-
-def DisplayHelpMiscellaneous ():
- HelpTextArea.SetText (18031)
-
-###################################################
-def CloseAutopauseOptionsWindow ():
- global GameOptionsWindow
-
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
- OpenGameplayOptionsWindow ()
-
-def OpenAutopauseOptionsWindow ():
- """Open autopause options window"""
- global GameOptionsWindow, HelpTextArea
-
- if GameOptionsWindow:
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
-
- GameOptionsWindow = Window = GemRB.LoadWindow (10)
-
- HelpTextArea = OptHelpText ('AutopauseOptions', Window, 15, 18044)
-
- OptDone ('AutopauseOptions', Window, 11)
- OptCancel ('AutopauseOptions', Window, 14)
-
- OptCheckbox ('CharacterHit', Window, 1, 17, 'Auto Pause State', 1)
- OptCheckbox ('CharacterInjured', Window, 2, 18, 'Auto Pause State', 2)
- OptCheckbox ('CharacterDead', Window, 3, 19, 'Auto Pause State', 4)
- OptCheckbox ('CharacterAttacked', Window, 4, 20, 'Auto Pause State', 8)
- OptCheckbox ('WeaponUnusable', Window, 5, 21, 'Auto Pause State', 16)
- OptCheckbox ('TargetGone', Window, 13, 22, 'Auto Pause State', 32)
- OptCheckbox ('EndOfRound', Window, 25, 24, 'Auto Pause State', 64)
- OptCheckbox ('EnemySighted', Window, 30, 31, 'Auto Pause State', 128)
- OptCheckbox ('SpellCast', Window, 36, 37, 'Auto Pause State', 256)
- OptCheckbox ('TrapFound', Window, 26, 28, 'Auto Pause State', 512)
- OptCheckbox ('CenterOnActor', Window, 33, 34, 'Auto Pause Center', 1)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
-
-def DisplayHelpCharacterHit ():
- HelpTextArea.SetText (18032)
-
-def DisplayHelpCharacterInjured ():
- HelpTextArea.SetText (18033)
-
-def DisplayHelpCharacterDead ():
- HelpTextArea.SetText (18034)
-
-def DisplayHelpCharacterAttacked ():
- HelpTextArea.SetText (18035)
-
-def DisplayHelpWeaponUnusable ():
- HelpTextArea.SetText (18036)
-
-def DisplayHelpTargetGone ():
- HelpTextArea.SetText (18037)
-
-def DisplayHelpEndOfRound ():
- HelpTextArea.SetText (10640)
-
-def DisplayHelpEnemySighted ():
- HelpTextArea.SetText (23514)
-
-def DisplayHelpSpellCast ():
- HelpTextArea.SetText (26311)
-
-def DisplayHelpTrapFound ():
- HelpTextArea.SetText (18560)
-
-def DisplayHelpCenterOnActor ():
- HelpTextArea.SetText (24888)
-
-###################################################
-def CloseCharacterSoundsWindow ():
- global GameOptionsWindow
-
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
- OpenAudioOptionsWindow ()
-
-def OpenCharacterSoundsWindow ():
- """Open character sounds options window"""
- global GameOptionsWindow, HelpTextArea
-
- if GameOptionsWindow:
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
-
- GameOptionsWindow = Window = GemRB.LoadWindow (12)
-
- HelpTextArea = OptHelpText ('CharacterSounds', Window, 16, 18041)
-
- OptDone ('CharacterSounds', Window, 24)
- OptCancel ('CharacterSounds', Window, 25)
-
- OptCheckbox ('Subtitles', Window, 5, 20, 'Subtitles', 1)
- OptCheckbox ('AttackSounds', Window, 6, 18, 'Attack Sounds', 1)
- OptCheckbox ('Footsteps', Window, 7, 19, 'Footsteps', 1)
- OptRadio ('CommandSounds', Window, 8, 21, 'Command Sounds Frequency', 1)
- OptRadio ('CommandSounds', Window, 9, 21, 'Command Sounds Frequency', 2)
- OptRadio ('CommandSounds', Window, 10, 21, 'Command Sounds Frequency', 3)
- OptRadio ('SelectionSounds', Window, 58, 57, 'Selection Sounds Frequency', 1)
- OptRadio ('SelectionSounds', Window, 59, 57, 'Selection Sounds Frequency', 2)
- OptRadio ('SelectionSounds', Window, 60, 57, 'Selection Sounds Frequency', 3)
- Window.ShowModal (MODAL_SHADOW_GRAY)
-
-def DisplayHelpSubtitles ():
- HelpTextArea.SetText (18015)
-
-def DisplayHelpAttackSounds ():
- HelpTextArea.SetText (18013)
-
-def DisplayHelpFootsteps ():
- HelpTextArea.SetText (18014)
-
-def DisplayHelpCommandSounds ():
- HelpTextArea.SetText (18016)
-
-def DisplayHelpSelectionSounds ():
- HelpTextArea.SetText (11352)
-
-###################################################
-
-def OpenSaveMsgWindow ():
- GemRB.SetVar("QuitAfterSave",0)
- GUISAVE.OpenSaveWindow ()
- #save the game without quitting
- return
-
-###################################################
-
-def OpenLoadMsgWindow ():
- global LoadMsgWindow
-
- if LoadMsgWindow:
- return
-
- LoadMsgWindow = Window = GemRB.LoadWindow (4)
-
- # Load
- Button = Window.GetControl (0)
- Button.SetText (15590)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, LoadGamePress)
- Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- # Cancel
- Button = Window.GetControl (1)
- Button.SetText (13727)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseLoadMsgWindow)
- Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- # Current game will be destroyed ...
- Text = Window.GetControl (3)
- Text.SetText (19531)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def CloseLoadMsgWindow ():
- global LoadMsgWindow
-
- if LoadMsgWindow:
- LoadMsgWindow.Unload ()
- LoadMsgWindow = None
- OptionsWindow.SetVisible (WINDOW_VISIBLE)
- BackgroundWindow.SetVisible (WINDOW_VISIBLE)
- PortraitWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def LoadGamePress ():
- global LoadMsgWindow
-
- if LoadMsgWindow:
- LoadMsgWindow.Unload ()
- LoadMsgWindow = None
- GemRB.QuitGame ()
- OpenOptionsWindow()
- GemRB.SetNextScript ("GUILOAD")
- return
-
-#save game AND quit
-def SaveGamePress():
- global QuitMsgWindow
-
- if QuitMsgWindow:
- QuitMsgWindow.Unload ()
- QuitMsgWindow = None
- #we need to set a state: quit after save
- GemRB.SetVar("QuitAfterSave",1)
- OpenOptionsWindow()
- GUISAVE.OpenSaveWindow ()
- return
-
-def QuitGamePress():
- global QuitMsgWindow
-
- if QuitMsgWindow:
- QuitMsgWindow.Unload ()
- QuitMsgWindow = None
- GemRB.QuitGame ()
- OpenOptionsWindow()
- GemRB.SetNextScript ("Start")
- return
-
-###################################################
-
-def OpenQuitMsgWindow ():
- global QuitMsgWindow
-
- if QuitMsgWindow:
- return
-
- QuitMsgWindow = Window = GemRB.LoadWindow (5)
-
- # Save
- Button = Window.GetControl (0)
- Button.SetText (15589)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SaveGamePress)
-
- # Quit Game
- Button = Window.GetControl (1)
- Button.SetText (15417)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, QuitGamePress)
-
- # Cancel
- Button = Window.GetControl (2)
- Button.SetText (13727)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseQuitMsgWindow)
- Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- # Do you wish to save the game ....
- Text = Window.GetControl (3)
- Text.SetText (16456)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def CloseQuitMsgWindow ():
- global QuitMsgWindow
-
- if QuitMsgWindow:
- QuitMsgWindow.Unload ()
- QuitMsgWindow = None
- OptionsWindow.SetVisible (WINDOW_VISIBLE)
- BackgroundWindow.SetVisible (WINDOW_VISIBLE)
- PortraitWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-###################################################
-###################################################
-
-# These functions help to setup controls found
-# in Video, Audio, Gameplay, Feedback and Autopause
-# options windows
-
-# These controls are usually made from an active
-# control (button, slider ...) and a label
-
-
-def OptSlider (name, window, slider_id, variable, value):
- """Standard slider for option windows"""
- slider = window.GetControl (slider_id)
- slider.SetVarAssoc (variable, value)
- slider.SetEvent (IE_GUI_SLIDER_ON_CHANGE, eval("DisplayHelp" + name))
- return slider
-
-def OptRadio (name, window, button_id, label_id, variable, value):
- """Standard radio button for option windows"""
-
- button = window.GetControl (button_id)
- button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- button.SetEvent (IE_GUI_BUTTON_ON_PRESS, eval("DisplayHelp" + name))
- button.SetVarAssoc (variable, value)
-
- label = window.GetControl (label_id)
- label.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- label.SetState (IE_GUI_BUTTON_LOCKED)
-
- return button
-
-def OptCheckbox (name, window, button_id, label_id, variable, value):
- """Standard checkbox for option windows"""
-
- button = window.GetControl (button_id)
- button.SetFlags (IE_GUI_BUTTON_CHECKBOX, OP_OR)
- button.SetSprites ("GMPPARBC",3, 1,2,3,5)
- button.SetEvent (IE_GUI_BUTTON_ON_PRESS, eval("DisplayHelp" + name))
- button.SetVarAssoc (variable, value)
-
- label = window.GetControl (label_id)
- label.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- label.SetState (IE_GUI_BUTTON_LOCKED)
-
- return button
-
-def OptButton (name, window, button_id, label_strref):
- """Standard subwindow button for option windows"""
- button = window.GetControl (button_id)
- button.SetEvent (IE_GUI_BUTTON_ON_PRESS, eval("Open%sWindow" %name))
- button.SetText (label_strref)
-
-def OptDone (name, window, button_id):
- """Standard `Done' button for option windows"""
- button = window.GetControl (button_id)
- button.SetText (11973) # Done
- button.SetEvent (IE_GUI_BUTTON_ON_PRESS, eval("Close%sWindow" %name))
- button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
-def OptCancel (name, window, button_id):
- """Standard `Cancel' button for option windows"""
- button = window.GetControl (button_id)
- button.SetText (13727) # Cancel
- button.SetEvent (IE_GUI_BUTTON_ON_PRESS, eval("Close%sWindow" %name))
- button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
-def OptHelpText (name, window, text_id, text_strref):
- """Standard textarea with context help for option windows"""
- text = window.GetControl (text_id)
- text.SetText (text_strref)
- return text
-
-
-###################################################
-# End of file GUIOPT.py
diff --git a/gemrb/GUIScripts/iwd/GUIPR.py b/gemrb/GUIScripts/iwd/GUIPR.py
deleted file mode 100644
index ff4f5a7..0000000
--- a/gemrb/GUIScripts/iwd/GUIPR.py
+++ /dev/null
@@ -1,349 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-
-# GUIPR.py - scripts to control the priest spells windows from the GUIPR winpack
-
-###################################################
-
-import GemRB
-import GUICommon
-import CommonTables
-from GUIDefines import *
-from ie_stats import *
-from ie_action import ACT_CAST
-
-PriestWindow = None
-PriestSpellInfoWindow = None
-PriestSpellLevel = 0
-PriestSpellUnmemorizeWindow = None
-PortraitWindow = None
-OptionsWindow = None
-OldPortraitWindow = None
-OldOptionsWindow = None
-
-def OpenPriestWindow ():
- import GUICommonWindows
- global PriestWindow, OptionsWindow, PortraitWindow
- global OldPortraitWindow, OldOptionsWindow
-
- if GUICommon.CloseOtherWindow (OpenPriestWindow):
- if PriestWindow:
- PriestWindow.Unload ()
- if OptionsWindow:
- OptionsWindow.Unload ()
- if PortraitWindow:
- PortraitWindow.Unload ()
-
- PriestWindow = None
- GemRB.SetVar ("OtherWindow", -1)
- GUICommon.GameWindow.SetVisible(WINDOW_VISIBLE)
- GemRB.UnhideGUI ()
- GUICommonWindows.PortraitWindow = OldPortraitWindow
- OldPortraitWindow = None
- GUICommonWindows.OptionsWindow = OldOptionsWindow
- OldOptionsWindow = None
- GUICommonWindows.SetSelectionChangeHandler (None)
- return
-
- GemRB.HideGUI ()
- GUICommon.GameWindow.SetVisible(WINDOW_INVISIBLE)
-
- GemRB.LoadWindowPack ("GUIPR", 640, 480)
- PriestWindow = Window = GemRB.LoadWindow (2)
- GemRB.SetVar ("OtherWindow", PriestWindow.ID)
- #saving the original portrait window
- OldOptionsWindow = GUICommonWindows.OptionsWindow
- OptionsWindow = GemRB.LoadWindow (0)
- GUICommonWindows.MarkMenuButton (OptionsWindow)
- GUICommonWindows.SetupMenuWindowControls (OptionsWindow, 0, OpenPriestWindow)
- OptionsWindow.SetFrame ()
- OldPortraitWindow = GUICommonWindows.PortraitWindow
- PortraitWindow = GUICommonWindows.OpenPortraitWindow (0)
-
- Button = Window.GetControl (1)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, PriestPrevLevelPress)
-
- Button = Window.GetControl (2)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, PriestNextLevelPress)
-
- # Setup memorized spells buttons
- for i in range (12):
- Button = Window.GetControl (3 + i)
- Button.SetBorder (0,0,0,0,0,0,0,0,64,0,1)
- Button.SetSprites ("SPELFRAM",0,0,0,0,0)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_OR)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
-
- # Setup book spells buttons
- for i in range (GUICommon.GetIWDSpellButtonCount()):
- Button = Window.GetControl (27 + i)
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_OR)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
-
- GUICommonWindows.SetSelectionChangeHandler (UpdatePriestWindow)
- UpdatePriestWindow ()
- OptionsWindow.SetVisible (WINDOW_VISIBLE)
- #bringing window front
- Window.SetVisible (WINDOW_FRONT)
- PortraitWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def UpdatePriestWindow ():
- global PriestMemorizedSpellList, PriestKnownSpellList
-
- PriestMemorizedSpellList = []
- PriestKnownSpellList = []
-
- Window = PriestWindow
- pc = GemRB.GameGetSelectedPCSingle ()
- type = IE_SPELL_TYPE_PRIEST
- level = PriestSpellLevel
- max_mem_cnt = GemRB.GetMemorizableSpellsCount (pc, type, level)
-
- Label = Window.GetControl (0x10000032)
- GemRB.SetToken ('LEVEL', str (level + 1))
- Label.SetText (12137)
-
- Name = GemRB.GetPlayerName (pc, 0)
- Label = Window.GetControl (0x10000035)
- Label.SetText (Name)
-
- mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level)
- for i in range (12):
- Button = Window.GetControl (3 + i)
- if i < mem_cnt:
- ms = GemRB.GetMemorizedSpell (pc, type, level, i)
- Button.SetSpellIcon (ms['SpellResRef'], 0)
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_NAND)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_OR)
- if ms['Flags']:
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenPriestSpellUnmemorizeWindow)
- else:
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OnPriestUnmemorizeSpell)
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, OpenPriestSpellInfoWindow)
- spell = GemRB.GetSpell (ms['SpellResRef'])
- Button.SetTooltip (spell['SpellName'])
- PriestMemorizedSpellList.append (ms['SpellResRef'])
- Button.SetVarAssoc ("SpellButton", i)
- Button.EnableBorder (0, ms['Flags'] == 0)
- else:
- if i < max_mem_cnt:
- Button.SetFlags (IE_GUI_BUTTON_NORMAL, OP_SET)
- else:
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, None)
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, None)
- Button.SetTooltip ('')
- Button.EnableBorder (0, 0)
-
-
- known_cnt = GemRB.GetKnownSpellsCount (pc, type, level)
- for i in range (GUICommon.GetIWDSpellButtonCount()):
- Button = Window.GetControl (27 + i)
- if i < known_cnt:
- ks = GemRB.GetKnownSpell (pc, type, level, i)
- Button.SetSpellIcon (ks['SpellResRef'], 0)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OnPriestMemorizeSpell)
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, OpenPriestSpellInfoWindow)
- spell = GemRB.GetSpell (ks['SpellResRef'])
- Button.SetTooltip (spell['SpellName'])
- PriestKnownSpellList.append (ks['SpellResRef'])
- Button.SetVarAssoc ("SpellButton", 100 + i)
-
- else:
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_OR)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_NAND)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, None)
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, None)
- Button.SetTooltip ('')
- Button.EnableBorder (0, 0)
-
- Class = GemRB.GetPlayerStat (pc, IE_CLASS)
- DivineCaster = CommonTables.ClassSkills.GetValue (Class, 1)
- if DivineCaster == "*":
- # also check the DRUIDSPELL column
- DivineCaster = CommonTables.ClassSkills.GetValue (Class, 0)
- CantCast = DivineCaster == "*" or GemRB.GetPlayerStat(pc, IE_DISABLEDBUTTON)&(1<<ACT_CAST)
- if CantCast or GemRB.GetPlayerStat (pc, IE_STATE_ID) & STATE_DEAD:
- Window.SetVisible (WINDOW_GRAYED)
- else:
- Window.SetVisible (WINDOW_VISIBLE)
- return
-
-def PriestPrevLevelPress ():
- global PriestSpellLevel
-
- if PriestSpellLevel > 0:
- PriestSpellLevel = PriestSpellLevel - 1
- UpdatePriestWindow ()
- return
-
-def PriestNextLevelPress ():
- global PriestSpellLevel
-
- if PriestSpellLevel < 6:
- PriestSpellLevel = PriestSpellLevel + 1
- UpdatePriestWindow ()
- return
-
-def RefreshPriestLevel ():
- global PriestSpellLevel
-
- PriestSpellLevel = GemRB.GetVar ("PriestSpellLevel")
- UpdatePriestWindow ()
- return
-
-def OpenPriestSpellInfoWindow ():
- global PriestSpellInfoWindow
-
- if PriestSpellInfoWindow != None:
- if PriestSpellInfoWindow:
- PriestSpellInfoWindow.Unload ()
- PriestSpellInfoWindow = None
- return
-
- PriestSpellInfoWindow = Window = GemRB.LoadWindow (3)
-
- #back
- Button = Window.GetControl (5)
- Button.SetText (15416)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenPriestSpellInfoWindow)
-
- index = GemRB.GetVar ("SpellButton")
- if index < 100:
- ResRef = PriestMemorizedSpellList[index]
- else:
- ResRef = PriestKnownSpellList[index - 100]
-
- spell = GemRB.GetSpell (ResRef)
-
- #Label = Window.GetControl (0x0fffffff)
- #Label.SetText (spell['SpellName'])
-
- Label = Window.GetControl (0x10000000)
- Label.SetText (spell['SpellName'])
-
- Button = Window.GetControl (2)
- Button.SetSpellIcon (ResRef, 1)
-
- Text = Window.GetControl (3)
- Text.SetText (spell['SpellDesc'])
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def OnPriestMemorizeSpell ():
- pc = GemRB.GameGetSelectedPCSingle ()
- level = PriestSpellLevel
- type = IE_SPELL_TYPE_PRIEST
-
- index = GemRB.GetVar ("SpellButton") - 100
-
- if GemRB.MemorizeSpell (pc, type, level, index):
- UpdatePriestWindow ()
- return
-
-def OpenPriestSpellRemoveWindow ():
- global PriestSpellUnmemorizeWindow
-
- PriestSpellUnmemorizeWindow = Window = GemRB.LoadWindow (5)
-
- # "Are you sure you want to ....?"
- TextArea = Window.GetControl (3)
- TextArea.SetText (63745)
-
- # Remove
- Button = Window.GetControl (0)
- Button.SetText (17507)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OnPriestRemoveSpell)
- Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- # Cancel
- Button = Window.GetControl (1)
- Button.SetText (13727)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, ClosePriestSpelliUnmemorizeWindow)
- Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def ClosePriestSpellUnmemorizeWindow ():
- global PriestSpellUnmemorizeWindow
-
- if PriestSpellUnmemorizeWindow:
- PriestSpellUnmemorizeWindow.Unload ()
- PriestSpellUnmemorizeWindow = None
- return
-
-def OpenPriestSpellUnmemorizeWindow ():
- global PriestSpellUnmemorizeWindow
-
- PriestSpellUnmemorizeWindow = Window = GemRB.LoadWindow (5)
-
- # "Are you sure you want to ....?"
- TextArea = Window.GetControl (3)
- TextArea.SetText (11824)
-
- # Remove
- Button = Window.GetControl (0)
- Button.SetText (17507)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OnPriestUnmemorizeSpell)
- Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- # Cancel
- Button = Window.GetControl (1)
- Button.SetText (13727)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, ClosePriestSpellUnmemorizeWindow)
- Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def OnPriestUnmemorizeSpell ():
- if PriestSpellUnmemorizeWindow:
- ClosePriestSpellUnmemorizeWindow ()
-
- pc = GemRB.GameGetSelectedPCSingle ()
- level = PriestSpellLevel
- type = IE_SPELL_TYPE_PRIEST
-
- index = GemRB.GetVar ("SpellButton")
-
- if GemRB.UnmemorizeSpell (pc, type, level, index):
- UpdatePriestWindow ()
- return
-
-def OnPriestRemoveSpell ():
- if PriestSpellUnmemorizeWindow:
- ClosePriestSpellRemoveWindow ()
-
- pc = GemRB.GameGetSelectedPCSingle ()
- level = PriestSpellLevel
- type = IE_SPELL_TYPE_PRIEST
-
- index = GemRB.GetVar ("SpellButton") - 100
-
- #remove spell from book
- GemRB.RemoveSpell (pc, type, level, index)
- UpdatePriestWindow ()
- return
-
-###################################################
-# End of file GUIPR.py
diff --git a/gemrb/GUIScripts/iwd/GUIREC.py b/gemrb/GUIScripts/iwd/GUIREC.py
deleted file mode 100644
index 4bb1754..0000000
--- a/gemrb/GUIScripts/iwd/GUIREC.py
+++ /dev/null
@@ -1,1468 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003-2009 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-
-# GUIREC.py - scripts to control stats/records windows from the GUIREC winpack
-###################################################
-import GemRB
-import GUICommon
-import CommonTables
-import GUICommonWindows
-from GUIDefines import *
-from ie_stats import *
-from ie_restype import *
-import LUCommon
-import LevelUp
-import GUIWORLD
-import DualClass
-import Portrait
-
-###################################################
-RecordsWindow = None
-InformationWindow = None
-BiographyWindow = None
-PortraitWindow = None
-CustomPortraitWindow = None
-OptionsWindow = None
-CustomizeWindow = None
-OldPortraitWindow = None
-OldOptionsWindow = None
-ExportDoneButton = None
-ExportFileName = ""
-
-ScriptsTable = None
-ColorTable = None
-ColorIndex = None
-ScriptTextArea = None
-SelectedTextArea = None
-OldVoiceSet = None
-
-# the available sounds
-SoundSequence = [ '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', \
- '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', \
- '25', '26', '27', '28', '29', '30', '31']
-SoundIndex = 0
-
-###################################################
-def OpenRecordsWindow ():
- global RecordsWindow, PortraitWindow, OptionsWindow
- global OldPortraitWindow, OldOptionsWindow
-
- if GUICommon.CloseOtherWindow (OpenRecordsWindow):
- if InformationWindow: OpenInformationWindow ()
-
- if RecordsWindow:
- RecordsWindow.Unload ()
- if OptionsWindow:
- OptionsWindow.Unload ()
- if PortraitWindow:
- PortraitWindow.Unload ()
- if CustomPortraitWindow:
- CustomPortraitWindow.Unload()
- RecordsWindow = None
- GemRB.SetVar ("OtherWindow", -1)
- GUICommon.GameWindow.SetVisible(WINDOW_VISIBLE)
- GemRB.UnhideGUI ()
- GUICommonWindows.PortraitWindow = OldPortraitWindow
- OldPortraitWindow = None
- GUICommonWindows.OptionsWindow = OldOptionsWindow
- OldOptionsWindow = None
- GUICommonWindows.SetSelectionChangeHandler (None)
- return
-
- GemRB.HideGUI ()
- GUICommon.GameWindow.SetVisible(WINDOW_INVISIBLE)
-
- GemRB.LoadWindowPack ("GUIREC", 640, 480) #TODO: remove?
- RecordsWindow = Window = GemRB.LoadWindow (2)
- GemRB.SetVar ("OtherWindow", RecordsWindow.ID)
- # saving the original portrait window
- OldOptionsWindow = GUICommonWindows.OptionsWindow
- OptionsWindow = GemRB.LoadWindow (0)
- GUICommonWindows.SetupMenuWindowControls (OptionsWindow, 0, OpenRecordsWindow)
- OptionsWindow.SetFrame ()
- OldPortraitWindow = GUICommonWindows.PortraitWindow
- PortraitWindow = GUICommonWindows.OpenPortraitWindow (0)
-
- # dual class
- Button = Window.GetControl (0)
- Button.SetText (7174)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, DualClass.DualClassWindow)
-
- # levelup
- Button = Window.GetControl (37)
- Button.SetText (7175)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, LevelUp.OpenLevelUpWindow)
-
- # information
- Button = Window.GetControl (1)
- Button.SetText (11946)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenInformationWindow)
-
- # reform party
- Button = Window.GetControl (51)
- Button.SetText (16559)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIWORLD.OpenReformPartyWindow)
-
- # customize
- Button = Window.GetControl (50)
- Button.SetText (10645)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenCustomizeWindow)
-
- # export
- Button = Window.GetControl (36)
- Button.SetText (13956)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenExportWindow)
-
-## # kit info
-## Button = Window.GetControl (52)
-## Button.SetText (61265)
-## Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, KitInfoWindow)
-
- GUICommonWindows.SetSelectionChangeHandler (UpdateRecordsWindow)
- UpdateRecordsWindow ()
-
- OptionsWindow.SetVisible (WINDOW_VISIBLE)
- Window.SetVisible (WINDOW_FRONT)
- PortraitWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def UpdateRecordsWindow ():
- global stats_overview, alignment_help
-
- Window = RecordsWindow
- if not RecordsWindow:
- print "SelectionChange handler points to non existing window\n"
- return
-
- pc = GemRB.GameGetSelectedPCSingle ()
-
- # exportable
- Button = Window.GetControl (36)
- if GemRB.GetPlayerStat (pc, IE_MC_FLAGS)&MC_EXPORTABLE:
- Button.SetState (IE_GUI_BUTTON_ENABLED)
- else:
- Button.SetState (IE_GUI_BUTTON_DISABLED)
-
- # dual-classable
- Button = Window.GetControl (0)
- if GUICommon.CanDualClass (pc):
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- Button.SetState (IE_GUI_BUTTON_ENABLED)
-
- # levelup
- Button = Window.GetControl (37)
- if LUCommon.CanLevelUp (pc):
- Button.SetState (IE_GUI_BUTTON_ENABLED)
- else:
- Button.SetState (IE_GUI_BUTTON_DISABLED)
-
- # name
- Label = Window.GetControl (0x1000000e)
- Label.SetText (GemRB.GetPlayerName (pc, 0))
-
- # portrait
- Button = Window.GetControl (2)
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE | IE_GUI_BUTTON_PICTURE, OP_SET)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- Button.SetPicture (GemRB.GetPlayerPortrait (pc,0), "NOPORTMD")
-
- # armorclass
- Label = Window.GetControl (0x10000028)
- ac = GemRB.GetPlayerStat (pc, IE_ARMORCLASS)
- ac += GemRB.GetAbilityBonus (IE_DEX, 2, GemRB.GetPlayerStat (pc, IE_DEX) )
- Label.SetText (str (ac))
- Label.SetTooltip (17183)
-
- # hp now
- Label = Window.GetControl (0x10000029)
- Label.SetText (str (GemRB.GetPlayerStat (pc, IE_HITPOINTS)))
- Label.SetTooltip (17184)
-
- # hp max
- Label = Window.GetControl (0x1000002a)
- Label.SetText (str (GemRB.GetPlayerStat (pc, IE_MAXHITPOINTS)))
- Label.SetTooltip (17378)
-
- # stats
-
- sstr = GemRB.GetPlayerStat (pc, IE_STR)
- sstrx = GemRB.GetPlayerStat (pc, IE_STREXTRA)
- cstr = GetStatColor (pc, IE_STR)
- if sstrx > 0 and sstr==18:
- sstr = "%d/%02d" %(sstr, sstrx % 100)
- else:
- sstr = str (sstr)
-
- sint = str (GemRB.GetPlayerStat (pc, IE_INT))
- cint = GetStatColor (pc, IE_INT)
- swis = str (GemRB.GetPlayerStat (pc, IE_WIS))
- cwis = GetStatColor (pc, IE_WIS)
- sdex = str (GemRB.GetPlayerStat (pc, IE_DEX))
- cdex = GetStatColor (pc, IE_DEX)
- scon = str (GemRB.GetPlayerStat (pc, IE_CON))
- ccon = GetStatColor (pc, IE_CON)
- schr = str (GemRB.GetPlayerStat (pc, IE_CHR))
- cchr = GetStatColor (pc, IE_CHR)
-
- Label = Window.GetControl (0x1000002f)
- Label.SetText (sstr)
- Label.SetTextColor (cstr[0], cstr[1], cstr[2])
-
- Label = Window.GetControl (0x10000009)
- Label.SetText (sdex)
- Label.SetTextColor (cdex[0], cdex[1], cdex[2])
-
- Label = Window.GetControl (0x1000000a)
- Label.SetText (scon)
- Label.SetTextColor (ccon[0], ccon[1], ccon[2])
-
- Label = Window.GetControl (0x1000000b)
- Label.SetText (sint)
- Label.SetTextColor (cint[0], cint[1], cint[2])
-
- Label = Window.GetControl (0x1000000c)
- Label.SetText (swis)
- Label.SetTextColor (cwis[0], cwis[1], cwis[2])
-
- Label = Window.GetControl (0x1000000d)
- Label.SetText (schr)
- Label.SetTextColor (cchr[0], cchr[1], cchr[2])
-
- # class
- ClassTitle = GUICommon.GetActorClassTitle (pc)
- Label = Window.GetControl (0x10000030)
- Label.SetText (ClassTitle)
-
- # race
- text = CommonTables.Races.GetValue (CommonTables.Races.FindValue (3, GemRB.GetPlayerStat (pc, IE_RACE)) ,
- 0)
-
- Label = Window.GetControl (0x1000000f)
- Label.SetText (text)
-
- Table = GemRB.LoadTable ("aligns")
-
- text = Table.GetValue (Table.FindValue ( 3, GemRB.GetPlayerStat (pc, IE_ALIGNMENT) ), 0)
- Label = Window.GetControl (0x10000010)
- Label.SetText (text)
-
- Label = Window.GetControl (0x10000011)
- if GemRB.GetPlayerStat (pc, IE_SEX) == 1:
- Label.SetText (7198)
- else:
- Label.SetText (7199)
-
- # help, info textarea
- stats_overview = GetStatOverview (pc)
- Text = Window.GetControl (45)
- Text.SetText (stats_overview)
- #TODO: making window visible/shaded depending on the pc's state
- Window.SetVisible (WINDOW_VISIBLE)
- return
-
-def GetStatColor (pc, stat):
- a = GemRB.GetPlayerStat (pc, stat)
- b = GemRB.GetPlayerStat (pc, stat, 1)
- if a==b:
- return (255,255,255)
- if a<b:
- return (255,255,0)
- return (0,255,0)
-
-# GemRB.GetPlayerStat wrapper that only returns nonnegative values
-def GSNN (pc, stat):
- val = GemRB.GetPlayerStat (pc, stat)
- if val >= 0:
- return val
- else:
- return 0
-
-# LevelDiff is used only from the level up code and holds the level
-# difference for each class
-def GetStatOverview (pc, LevelDiff=[0,0,0]):
- StateTable = GemRB.LoadTable ("statdesc")
-
- GS = lambda s, pc=pc: GemRB.GetPlayerStat (pc, s)
- GB = lambda s, pc=pc: GemRB.GetPlayerStat (pc, s, 1)
- GA = lambda s, col, pc=pc: GemRB.GetAbilityBonus (s, col, GS (s) )
-
- stats = []
- # class levels
- # 16480 <CLASS>: Level <LEVEL>
- # Experience: <EXPERIENCE>
- # Next Level: <NEXTLEVEL>
-
- # collecting tokens for stat overview
- ClassTitle = GUICommon.GetActorClassTitle (pc)
- GemRB.SetToken ("CLASS", ClassTitle)
- Class = GemRB.GetPlayerStat (pc, IE_CLASS)
- Class = CommonTables.Classes.FindValue (5, Class)
- Class = CommonTables.Classes.GetRowName (Class)
- Dual = GUICommon.IsDualClassed (pc, 1)
- Multi = GUICommon.IsMultiClassed (pc, 1)
- XP = GemRB.GetPlayerStat (pc, IE_XP)
- LevelDrain = GS (IE_LEVELDRAIN)
-
- if GS (IE_STATE_ID) & STATE_DEAD:
- stats.append ( (11829,1,'c') ) # DEAD
- stats.append (None)
-
- if Multi[0] > 1: # we're multiclassed
- print "\tMulticlassed"
- Levels = [GemRB.GetPlayerStat (pc, IE_LEVEL), GemRB.GetPlayerStat (pc, IE_LEVEL2), GemRB.GetPlayerStat (pc, IE_LEVEL3)]
-
- stats.append ( (19721,1,'c') )
- stats.append (None)
- for i in range (Multi[0]):
- ClassIndex = CommonTables.Classes.FindValue (5, Multi[i+1])
- ClassTitle = GemRB.GetString (CommonTables.Classes.GetValue (ClassIndex, 2))
- GemRB.SetToken ("CLASS", ClassTitle)
- Class = CommonTables.Classes.GetRowName (ClassIndex)
- GemRB.SetToken ("LEVEL", str (Levels[i]+LevelDiff[i]-int(LevelDrain/Multi[0])) )
- GemRB.SetToken ("EXPERIENCE", str (XP/Multi[0]) )
- if LevelDrain:
- stats.append ( (GemRB.GetString (19720),1,'d') )
- stats.append ( (GemRB.GetString (57435),1,'d') ) # LEVEL DRAINED
- else:
- GemRB.SetToken ("NEXTLEVEL", LUCommon.GetNextLevelExp (Levels[i]+LevelDiff[i], Class) )
- stats.append ( (GemRB.GetString (16480),"",'d') )
- stats.append (None)
- print "\t\tClass (Level):",Class,"(",Levels[i],")"
-
- elif Dual[0] > 0: # dual classed; first show the new class
- print "\tDual classed"
- stats.append ( (19722,1,'c') )
- stats.append (None)
-
- Levels = [GemRB.GetPlayerStat (pc, IE_LEVEL), GemRB.GetPlayerStat (pc, IE_LEVEL2), GemRB.GetPlayerStat (pc, IE_LEVEL3)]
-
- # the levels are stored in the class order (eg. FIGHTER_MAGE)
- # the current active class does not matter!
- if GUICommon.IsDualSwap (pc):
- Levels = [Levels[1], Levels[0], Levels[2]]
-
- Levels[0] += LevelDiff[0]
-
- ClassTitle = GemRB.GetString (CommonTables.Classes.GetValue (Dual[2], 2))
- GemRB.SetToken ("CLASS", ClassTitle)
- GemRB.SetToken ("LEVEL", str (Levels[0]-LevelDrain))
- Class = CommonTables.Classes.GetRowName (Dual[2])
- XP2 = GemRB.GetPlayerStat (pc, IE_XP)
- GemRB.SetToken ("EXPERIENCE", str (XP2) )
- if LevelDrain:
- stats.append ( (GemRB.GetString (19720),1,'d') )
- stats.append ( (GemRB.GetString (57435),1,'d') ) # LEVEL DRAINED
- else:
- GemRB.SetToken ("NEXTLEVEL", LUCommon.GetNextLevelExp (Levels[0], Class) )
- stats.append ( (GemRB.GetString (16480),"",'d') )
- stats.append (None)
- # the first class (shown second)
- if Dual[0] == 1:
- ClassTitle = GemRB.GetString (CommonTables.KitList.GetValue (Dual[1], 2))
- elif Dual[0] == 2:
- ClassTitle = GemRB.GetString (CommonTables.Classes.GetValue (Dual[1], 2))
- GemRB.SetToken ("CLASS", ClassTitle)
- GemRB.SetToken ("LEVEL", str (Levels[1]) )
-
- # the xp table contains only classes, so we have to determine the base class for kits
- if Dual[0] == 2:
- BaseClass = CommonTables.Classes.GetRowName (Dual[1])
- else:
- BaseClass = GUICommon.GetKitIndex (pc)
- BaseClass = CommonTables.KitList.GetValue (BaseClass, 7)
- BaseClass = CommonTables.Classes.FindValue (5, BaseClass)
- BaseClass = CommonTables.Classes.GetRowName (BaseClass)
- # the first class' XP is discarded and set to the minimum level
- # requirement, so if you don't dual class right after a levelup,
- # the game would eat some of your XP
- XP1 = CommonTables.NextLevel.GetValue (BaseClass, str (Levels[1]))
- GemRB.SetToken ("EXPERIENCE", str (XP1) )
-
- # inactive until the new class SURPASSES the former
- if Levels[0] <= Levels[1]:
- # inactive
- stats.append ( (19719,1,'c') )
- else:
- stats.append ( (19720,1,'c') )
- stats.append (None)
- else: # single classed
- print "\tSingle classed"
- Level = GemRB.GetPlayerStat (pc, IE_LEVEL) + LevelDiff[0]
- GemRB.SetToken ("LEVEL", str (Level-LevelDrain))
- GemRB.SetToken ("EXPERIENCE", str (XP) )
- if LevelDrain:
- stats.append ( (19720,1,'c') )
- stats.append ( (57435,1,'c') ) # LEVEL DRAINED
- else:
- GemRB.SetToken ("NEXTLEVEL", LUCommon.GetNextLevelExp (Level, Class) )
- stats.append ( (16480,1,'c') )
- stats.append (None)
- print "\t\tClass (Level):",Class,"(",Level,")"
-
- # check to see if we have a level diff anywhere
- if sum (LevelDiff) == 0:
- effects = GemRB.GetPlayerStates (pc)
- if len (effects):
- for c in effects:
- tmp = StateTable.GetValue (ord(c)-66, 0)
- stats.append ( (tmp,c,'a') )
- stats.append (None)
-
- stats.append (None)
-
- #proficiencies
- stats.append ( (8442,1,'c') )
-
- stats.append ( (9457, str(GS (IE_TOHIT))+" ("+str(GemRB.GetCombatDetails(pc, 0)["ToHit"])+")", '0') )
- tmp = GS (IE_NUMBEROFATTACKS)
- if (tmp&1):
- tmp2 = str (tmp/2) + chr (188)
- else:
- tmp2 = str (tmp/2)
- stats.append ( (9458, tmp2, '') )
- stats.append ( (9459, GSNN (pc, IE_LORE), '0') )
- stats.append ( (19224, GS (IE_RESISTMAGIC), '') )
-
- # party's reputation
- reptxt = GetReputation (GemRB.GameGetReputation ()/10)
- stats.append ( (9465, reptxt, '') )
- stats.append ( (9460, GSNN (pc, IE_LOCKPICKING), '') )
- stats.append ( (9462, GSNN (pc, IE_TRAPS), '') )
- stats.append ( (9463, GSNN (pc, IE_PICKPOCKET), '') )
- stats.append ( (9461, GSNN (pc, IE_STEALTH), '') )
- stats.append ( (34120, GSNN (pc, IE_HIDEINSHADOWS), '') )
- stats.append ( (34121, GSNN (pc, IE_DETECTILLUSIONS), '') )
- stats.append ( (34122, GSNN (pc, IE_SETTRAPS), '') )
-
- HatedRace = GS (IE_HATEDRACE)
- if HatedRace:
- HateTable = GemRB.LoadTable ("haterace")
- Racist = HateTable.FindValue (1, HatedRace)
- if Racist != -1:
- HatedRace = HateTable.GetValue (Racist, 3)
- stats.append ( (15982, GemRB.GetString (HatedRace), '') )
-
- stats.append ( (12128, GS (IE_BACKSTABDAMAGEMULTIPLIER), 'x') )
- stats.append ( (12126, GS (IE_TURNUNDEADLEVEL), '') )
-
- #this hack only displays LOH if we know the spell
- #TODO: the core should just not set LOH if the paladin can't learn it
- if (GUICommon.HasSpell (pc, IE_SPELL_TYPE_INNATE, 0, "SPCL211") >= 0):
- stats.append ( (12127, GS (IE_LAYONHANDSAMOUNT), '') )
-
- #script
- aiscript = GemRB.GetPlayerScript (pc )
- stats.append ( (2078, aiscript, '') )
- stats.append (None)
-
- # 17379 Saving throws
- stats.append (17379)
- # 17380 Paralyze/Poison/Death
- stats.append ( (17380, IE_SAVEVSDEATH, 's') )
- # 17381 Rod/Staff/Wand
- stats.append ( (17381, IE_SAVEVSWANDS, 's') )
- # 17382 Petrify/Polymorph
- stats.append ( (17382, IE_SAVEVSPOLY, 's') )
- # 17383 Breath weapon
- stats.append ( (17383, IE_SAVEVSBREATH, 's') )
- # 17384 Spells
- stats.append ( (17384, IE_SAVEVSSPELL, 's') )
- stats.append (None)
-
- # 9466 Weapon proficiencies
- stats.append (9466)
- table = GemRB.LoadTable ("weapprof")
- RowCount = table.GetRowCount ()
- for i in range (RowCount):
- text = table.GetValue (i, 3)
- stat = table.GetValue (i, 0)
- stats.append ( (text, GS (stat)&0x07, '+') )
- stats.append (None)
-
- # 11766 AC Bonuses
- stats.append (11766)
- # 11770 AC vs. Crushing
- stats.append ((11770, GS (IE_ACCRUSHINGMOD), ''))
- # 11767 AC vs. Missile
- stats.append ((11767, GS (IE_ACMISSILEMOD), ''))
- # 11769 AC vs. Piercing
- stats.append ((11769, GS (IE_ACPIERCINGMOD), ''))
- # 11768 AC vs. Slashing
- stats.append ((11768, GS (IE_ACSLASHINGMOD), ''))
- stats.append (None)
-
- # 10315 Ability bonuses
- stats.append (10315)
- value = GemRB.GetPlayerStat (pc, IE_STR)
- ex = GemRB.GetPlayerStat (pc, IE_STREXTRA)
- # 10332 to hit
- stats.append ( (10332, GemRB.GetAbilityBonus (IE_STR,0,value,ex), '0') )
- # 10336 damage
- stats.append ( (10336, GemRB.GetAbilityBonus (IE_STR,1,value,ex), '0') )
- # 10337 open doors (bend bars lift gates)
- stats.append ( (10337, GemRB.GetAbilityBonus (IE_STR,2,value,ex), '0') )
- # 10338 weight allowance
- stats.append ( (10338, GemRB.GetAbilityBonus (IE_STR,3,value,ex), '0') )
- # 10339 AC
- stats.append ( (10339, GA (IE_DEX,2), '0') )
- # 10340 Missile adjustment
- stats.append ( (10340, GA (IE_DEX,1), '0') )
- # 10341 Reaction adjustment
- stats.append ( (10341, GA (IE_DEX,0), '0') )
- # 10342 CON HP Bonus/Level
- stats.append ( (10342, GA (IE_CON,0), 'p') )
- # 10343 Chance To Learn spell
- if GemRB.GetMemorizableSpellsCount (pc, IE_SPELL_TYPE_WIZARD, 0, 0)>0:
- stats.append ( (10343, GA (IE_INT,0), '%' ) )
- # 10347 Reaction
- stats.append ( (10347, GA (IE_REPUTATION,0), '0') )
- stats.append (None)
-
- # 10344 Bonus Priest spells
- if GemRB.GetMemorizableSpellsCount (pc, IE_SPELL_TYPE_PRIEST, 0, 0)>0:
- stats.append (10344)
- for level in range (7):
- GemRB.SetToken ("SPELLLEVEL", str (level+1) )
- #get the bonus spell count
- base = GemRB.GetMemorizableSpellsCount (pc, IE_SPELL_TYPE_PRIEST, level, 0)
- if base:
- count = GemRB.GetMemorizableSpellsCount (pc, IE_SPELL_TYPE_PRIEST, level)
- stats.append ( (GemRB.GetString (10345), count-base, 'b') )
- stats.append (None)
-
- # 32204 Resistances
- stats.append (15544)
- # 67216 Slashing Attacks
- stats.append ((11768, GS (IE_RESISTSLASHING), '%'))
- # 67217 Piercing Attacks
- stats.append ((11769, GS (IE_RESISTPIERCING), '%'))
- # 67218 Crushing Attacks
- stats.append ((11770, GS (IE_RESISTCRUSHING), '%'))
- # 67219 Missile Attacks
- stats.append ((11767, GS (IE_RESISTMISSILE), '%'))
- # Poison
- stats.append ((14017, GS (IE_RESISTPOISON), '%'))
- stats.append (None)
-
- res = []
- lines = 0
- for s in stats:
- try:
- strref, val, type = s
- if val == 0 and type != '0':
- continue
- if type == '+': #pluses
- res.append ("[capital=0]"+GemRB.GetString (strref) + ' '+ '+' * val)
- elif type == 'p': #a plus prefix if positive
- if val > 0:
- res.append ("[capital=0]" + GemRB.GetString (strref) + ' +' + str (val) )
- else:
- res.append ("[capital=0]" + GemRB.GetString (strref) + ' ' + str (val) )
- elif type == 's': #both base and (modified) stat, but only if they differ
- base = str (GB (val))
- stat = str (GS (val))
- if base == stat:
- res.append ("[capital=0]" + GemRB.GetString (strref) + ': ' + base)
- else:
- res.append ("[capital=0]" + GemRB.GetString (strref) + ': ' + base + " (" + stat + ")")
- elif type == 'x': #x character before value
- res.append ("[capital=0]"+GemRB.GetString (strref) +': x' + str (val) )
- elif type == 'a': #value (portrait icon) + string
- res.append ("[capital=2]"+val+" "+GemRB.GetString (strref))
- elif type == 'b': #strref is an already resolved string
- res.append ("[capital=0]"+strref+": "+str (val))
- elif type == 'c': #normal string
- res.append ("[capital=0]"+GemRB.GetString (strref))
- elif type == 'd': #strref is an already resolved string
- res.append ("[capital=0]"+strref)
- elif type == '0': #normal value
- res.append (GemRB.GetString (strref) + ': ' + str (val))
- else: #normal value + type character, for example percent sign
- res.append ("[capital=0]"+GemRB.GetString (strref) + ': ' + str (val) + type)
- lines = 1
- except:
- if s != None:
- res.append ( GemRB.GetString (s) )
- lines = 0
- else:
- if lines:
- res.append ("")
- lines = 0
-
- return "\n".join (res)
-
-def GetReputation (repvalue):
- table = GemRB.LoadTable ("reptxt")
- if repvalue>20:
- repvalue=20
- txt = GemRB.GetString (table.GetValue (repvalue, 0) )
- return txt+"("+str (repvalue)+")"
-
-def OpenInformationWindow ():
- global InformationWindow
-
- if InformationWindow != None:
- if BiographyWindow: OpenBiographyWindow ()
-
- if InformationWindow:
- InformationWindow.Unload ()
- InformationWindow = None
- GemRB.SetVar ("FloatWindow", -1)
- return
-
- InformationWindow = Window = GemRB.LoadWindow (4)
- GemRB.SetVar ("FloatWindow", InformationWindow.ID)
-
- # Biography
- Button = Window.GetControl (26)
- Button.SetText (18003)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenBiographyWindow)
-
- # Done
- Button = Window.GetControl (24)
- Button.SetText (11973)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenInformationWindow)
-
- TotalPartyExp = 0
- ChapterPartyExp = 0
- TotalCount = 0
- ChapterCount = 0
- for i in range (1, GemRB.GetPartySize () + 1):
- stat = GemRB.GetPCStats(i)
- TotalPartyExp = TotalPartyExp + stat['KillsTotalXP']
- ChapterPartyExp = ChapterPartyExp + stat['KillsChapterXP']
- TotalCount = TotalCount + stat['KillsTotalCount']
- ChapterCount = ChapterCount + stat['KillsChapterCount']
-
- # These are used to get the stats
- pc = GemRB.GameGetSelectedPCSingle ()
- stat = GemRB.GetPCStats (pc)
-
- Label = Window.GetControl (0x10000000)
- Label.SetText (GemRB.GetPlayerName (pc, 1))
- # class
- ClassTitle = GUICommon.GetActorClassTitle (pc)
- Label = Window.GetControl (0x10000018)
- Label.SetText (ClassTitle)
-
- #most powerful vanquished
- Label = Window.GetControl (0x10000005)
- #we need getstring, so -1 will translate to empty string
- Label.SetText (GemRB.GetString (stat['BestKilledName']))
-
- # NOTE: currentTime is in seconds, joinTime is in seconds * 15
- # (script updates???). In each case, there are 60 seconds
- # in a minute, 24 hours in a day, but ONLY 5 minutes in an hour!!
- # Hence currentTime (and joinTime after div by 15) has
- # 7200 secs a day (60 * 5 * 24)
- currentTime = GemRB.GetGameTime ()
- joinTime = stat['JoinDate'] - stat['AwayTime']
-
- party_time = currentTime - (joinTime / 15)
- days = party_time / 7200
- hours = (party_time % 7200) / 300
-
- GemRB.SetToken ('GAMEDAYS', str (days))
- GemRB.SetToken ('HOUR', str (hours))
- Label = Window.GetControl (0x10000006)
- #actually it is 16043 <DURATION>, but duration is translated to
- #16041, hopefully this won't cause problem with international version
- Label.SetText (16041)
-
- #favourite spell
- Label = Window.GetControl (0x10000007)
- Label.SetText (stat['FavouriteSpell'])
-
- #favourite weapon
- Label = Window.GetControl (0x10000008)
- #actually it is 10479 <WEAPONNAME>, but weaponname is translated to
- #the real weapon name (which we should set using SetToken)
- #there are other strings like bow+wname/xbow+wname/sling+wname
- #are they used?
- Label.SetText (stat['FavouriteWeapon'])
-
- #total xp
- Label = Window.GetControl (0x1000000f)
- if TotalPartyExp != 0:
- PartyExp = int ((stat['KillsTotalXP'] * 100) / TotalPartyExp)
- Label.SetText (str (PartyExp) + '%')
- else:
- Label.SetText ("0%")
-
- Label = Window.GetControl (0x10000013)
- if ChapterPartyExp != 0:
- PartyExp = int ((stat['KillsChapterXP'] * 100) / ChapterPartyExp)
- Label.SetText (str (PartyExp) + '%')
- else:
- Label.SetText ("0%")
-
- #total xp
- Label = Window.GetControl (0x10000010)
- if TotalCount != 0:
- PartyExp = int ((stat['KillsTotalCount'] * 100) / TotalCount)
- Label.SetText (str (PartyExp) + '%')
- else:
- Label.SetText ("0%")
-
- Label = Window.GetControl (0x10000014)
- if ChapterCount != 0:
- PartyExp = int ((stat['KillsChapterCount'] * 100) / ChapterCount)
- Label.SetText (str (PartyExp) + '%')
- else:
- Label.SetText ("0%")
-
- Label = Window.GetControl (0x10000011)
- Label.SetText (str (stat['KillsChapterXP']))
- Label = Window.GetControl (0x10000015)
- Label.SetText (str (stat['KillsTotalXP']))
-
- #count of kills in chapter/game
- Label = Window.GetControl (0x10000012)
- Label.SetText (str (stat['KillsChapterCount']))
- Label = Window.GetControl (0x10000016)
- Label.SetText (str (stat['KillsTotalCount']))
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def OpenBiographyWindow ():
- global BiographyWindow
-
- if BiographyWindow != None:
- if BiographyWindow:
- BiographyWindow.Unload ()
- BiographyWindow = None
- GemRB.SetVar ("FloatWindow", InformationWindow.ID)
-
- InformationWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
- BiographyWindow = Window = GemRB.LoadWindow (12)
- GemRB.SetVar ("FloatWindow", BiographyWindow.ID)
-
- TextArea = Window.GetControl (0)
- pc = GemRB.GameGetSelectedPCSingle ()
- TextArea.SetText (GemRB.GetPlayerString (pc, 63) )
-
- # Done
- Button = Window.GetControl (2)
- Button.SetText (11973)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenBiographyWindow)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def OpenExportWindow ():
- global ExportWindow, NameField, ExportDoneButton
-
- ExportWindow = GemRB.LoadWindow (13)
-
- TextArea = ExportWindow.GetControl (2)
- TextArea.SetText (10962)
-
- TextArea = ExportWindow.GetControl (0)
- TextArea.GetCharacters ()
-
- ExportDoneButton = ExportWindow.GetControl (4)
- ExportDoneButton.SetText (11973)
- ExportDoneButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- CancelButton = ExportWindow.GetControl (5)
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- NameField = ExportWindow.GetControl (6)
-
- ExportDoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, ExportDonePress)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, ExportCancelPress)
- NameField.SetEvent (IE_GUI_EDIT_ON_CHANGE, ExportEditChanged)
- ExportWindow.ShowModal (MODAL_SHADOW_GRAY)
- NameField.SetStatus (IE_GUI_CONTROL_FOCUSED)
- return
-
-def ExportDonePress():
- if ExportWindow:
- ExportWindow.Unload()
- #save file under name from EditControl
- return
-
-def ExportCancelPress():
- if ExportWindow:
- ExportWindow.Unload()
- return
-
-def ExportEditChanged():
- ExportFileName = NameField.QueryText ()
- if ExportFileName == "":
- ExportDoneButton.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- ExportDoneButton.SetState (IE_GUI_BUTTON_ENABLED)
- return
-
-def OpenCustomizeWindow ():
- global CustomizeWindow
- global PortraitsTable, ScriptsTable, ColorTable
-
- pc = GemRB.GameGetSelectedPCSingle ()
- if GemRB.GetPlayerStat (pc, IE_MC_FLAGS)&MC_EXPORTABLE:
- Exportable = 1
- else:
- Exportable = 0
-
- PortraitsTable = GemRB.LoadTable ("PICTURES")
- ScriptsTable = GemRB.LoadTable ("SCRPDESC")
- ColorTable = GemRB.LoadTable ("CLOWNCOL")
- CustomizeWindow = GemRB.LoadWindow (17)
-
- PortraitSelectButton = CustomizeWindow.GetControl (0)
- PortraitSelectButton.SetText (11961)
- if not Exportable:
- PortraitSelectButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- SoundButton = CustomizeWindow.GetControl (1)
- SoundButton.SetText (10647)
- if not Exportable:
- SoundButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- ColorButton = CustomizeWindow.GetControl (2)
- ColorButton.SetText (10646)
- if not Exportable:
- ColorButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- ScriptButton = CustomizeWindow.GetControl (3)
- ScriptButton.SetText (17111)
-
- BiographyButton = CustomizeWindow.GetControl (9)
- BiographyButton.SetText (18003)
- if not Exportable:
- BiographyButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- TextArea = CustomizeWindow.GetControl (5)
- TextArea.SetText (11327)
-
- CustomizeDoneButton = CustomizeWindow.GetControl (7)
- CustomizeDoneButton.SetText (11973)
- CustomizeDoneButton.SetState (IE_GUI_BUTTON_ENABLED)
-
- CancelButton = CustomizeWindow.GetControl (8);
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- PortraitSelectButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenPortraitSelectWindow)
- SoundButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenSoundWindow)
- ColorButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenColorWindow)
- ScriptButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenScriptWindow)
- BiographyButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenBiographyEditWindow)
- CustomizeDoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CustomizeDonePress)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CustomizeCancelPress)
-
- CustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def CustomizeDonePress ():
- CloseCustomizeWindow ()
- UpdateRecordsWindow ()
- return
-
-def CustomizeCancelPress ():
- CloseCustomizeWindow ()
- UpdateRecordsWindow ()
- return
-
-def CloseCustomizeWindow ():
- global CustomizeWindow
-
- if CustomizeWindow:
- CustomizeWindow.Unload ()
- CustomizeWindow = None
- return
-
-def OpenSoundWindow ():
- global SubCustomizeWindow
- global VoiceList
- global Gender
- global OldVoiceSet
-
- pc = GemRB.GameGetSelectedPCSingle ()
- OldVoiceSet = GemRB.GetPlayerSound (pc)
- SubCustomizeWindow = GemRB.LoadWindow (20)
-
- VoiceList = SubCustomizeWindow.GetControl (5)
- VoiceList.SetFlags (IE_GUI_TEXTAREA_SELECTABLE)
- Gender = GemRB.GetPlayerStat (pc, IE_SEX, 1)
-
- VoiceList.SetVarAssoc ("Selected", 0)
- VoiceList.GetCharSounds()
- VoiceList.SelectText (OldVoiceSet)
-
- PlayButton = SubCustomizeWindow.GetControl (7)
- PlayButton.SetText (17318)
-
- TextArea = SubCustomizeWindow.GetControl (8)
- TextArea.SetText (11315)
-
- DoneButton = SubCustomizeWindow.GetControl (10)
- DoneButton.SetText (11973)
- DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- CancelButton = SubCustomizeWindow.GetControl (11)
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- PlayButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, PlaySoundPressed)
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DoneSoundWindow)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSoundWindow)
-
- SubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def CloseSoundWindow ():
- pc = GemRB.GameGetSelectedPCSingle ()
- GemRB.SetPlayerSound (pc, OldVoiceSet)
- CloseSubCustomizeWindow ()
- return
-
-def DoneSoundWindow ():
- pc = GemRB.GameGetSelectedPCSingle ()
- CharSound = VoiceList.QueryText ()
- GemRB.SetPlayerSound (pc, CharSound)
-
- CloseSubCustomizeWindow ()
- return
-
-def PlaySoundPressed():
- global CharSoundWindow, SoundIndex, SoundSequence
-
- CharSound = VoiceList.QueryText ()
- pc = GemRB.GameGetSelectedPCSingle ()
- GemRB.SetPlayerSound (pc, CharSound)
- VoiceSet = GemRB.GetPlayerSound (pc, 1)
- tmp = SoundIndex
- while (not GemRB.HasResource (VoiceSet + SoundSequence[SoundIndex], RES_WAV)):
- NextSound()
- if SoundIndex == tmp:
- break
- else:
- NextSound()
-
- GemRB.PlaySound (VoiceSet + SoundSequence[SoundIndex], 0, 0, 5)
- return
-
-def NextSound():
- global SoundIndex, SoundSequence
- SoundIndex += 1
- if SoundIndex >= len(SoundSequence):
- SoundIndex = 0
- return
-
-def OpenColorWindow ():
- global SubCustomizeWindow
- global PortraitWindow
- global PortraitButton
- global HairButton, SkinButton, MajorButton, MinorButton
- global HairColor, SkinColor, MajorColor, MinorColor
-
- pc = GemRB.GameGetSelectedPCSingle ()
- MinorColor = GemRB.GetPlayerStat (pc, IE_MINOR_COLOR)
- MajorColor = GemRB.GetPlayerStat (pc, IE_MAJOR_COLOR)
- SkinColor = GemRB.GetPlayerStat (pc, IE_SKIN_COLOR)
- HairColor = GemRB.GetPlayerStat (pc, IE_HAIR_COLOR)
- SubCustomizeWindow = GemRB.LoadWindow (21)
-
- PortraitButton = SubCustomizeWindow.GetControl (0)
- PortraitButton.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_NO_IMAGE,OP_SET)
- PortraitButton.SetState (IE_GUI_BUTTON_LOCKED)
-
- HairButton = SubCustomizeWindow.GetControl (3)
- SkinButton = SubCustomizeWindow.GetControl (4)
- MajorButton = SubCustomizeWindow.GetControl (5)
- MinorButton = SubCustomizeWindow.GetControl (6)
-
- DoneButton = SubCustomizeWindow.GetControl (12)
- DoneButton.SetText (11973)
- DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- CancelButton = SubCustomizeWindow.GetControl (13)
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- HairButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, SetHairColor)
- SkinButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, SetSkinColor)
- MajorButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, SetMajorColor)
- MinorButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, SetMinorColor)
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DoneColorWindow)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSubCustomizeWindow)
- UpdatePaperDoll ()
-
- SubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DoneColorWindow ():
- pc = GemRB.GameGetSelectedPCSingle ()
- GemRB.SetPlayerStat (pc, IE_MINOR_COLOR, MinorColor)
- GemRB.SetPlayerStat (pc, IE_MAJOR_COLOR, MajorColor)
- GemRB.SetPlayerStat (pc, IE_SKIN_COLOR, SkinColor)
- GemRB.SetPlayerStat (pc, IE_HAIR_COLOR, HairColor)
- CloseSubCustomizeWindow ()
- return
-
-def UpdatePaperDoll ():
- pc = GemRB.GameGetSelectedPCSingle ()
- Color1 = GemRB.GetPlayerStat (pc, IE_METAL_COLOR)
- MinorButton.SetBAM ("COLGRAD", 0, 0, MinorColor&0xff)
- MajorButton.SetBAM ("COLGRAD", 0, 0, MajorColor&0xff)
- SkinButton.SetBAM ("COLGRAD", 0, 0, SkinColor&0xff)
- Color5 = GemRB.GetPlayerStat (pc, IE_LEATHER_COLOR)
- Color6 = GemRB.GetPlayerStat (pc, IE_ARMOR_COLOR)
- HairButton.SetBAM ("COLGRAD", 0, 0, HairColor&0xff)
- PortraitButton.SetPLT (GUICommon.GetActorPaperDoll (pc),
- Color1, MinorColor, MajorColor, SkinColor, Color5, Color6, HairColor, 0, 0)
- return
-
-def SetHairColor ():
- global ColorIndex, PickedColor
-
- ColorIndex = 0
- PickedColor = HairColor
- OpenColorPicker ()
- return
-
-def SetSkinColor ():
- global ColorIndex, PickedColor
-
- ColorIndex = 1
- PickedColor = SkinColor
- OpenColorPicker ()
- return
-
-def SetMinorColor ():
- global ColorIndex, PickedColor
-
- ColorIndex = 2
- PickedColor = MinorColor
- OpenColorPicker ()
- return
-
-def SetMajorColor ():
- global ColorIndex, PickedColor
-
- ColorIndex = 3
- PickedColor = MajorColor
- OpenColorPicker ()
- return
-
-def OpenColorPicker ():
- global SubSubCustomizeWindow
- #global Selected
-
- SubSubCustomizeWindow = GemRB.LoadWindow (22)
-
- GemRB.SetVar ("Selected",-1)
- for i in range (1,35):
- Button = SubSubCustomizeWindow.GetControl (i)
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_RADIOBUTTON,OP_OR)
-
- #Selected = -1
- for i in range (34):
- MyColor = ColorTable.GetValue (ColorIndex, i)
- if MyColor == "*":
- break
- Button = SubSubCustomizeWindow.GetControl (i+1)
- Button.SetBAM("COLGRAD", 2, 0, MyColor)
- if PickedColor == MyColor:
- GemRB.SetVar ("Selected",i)
- #Selected = i
- Button.SetState (IE_GUI_BUTTON_ENABLED)
- Button.SetVarAssoc("Selected",i)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, DonePress)
-
- SubSubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DonePress():
- global HairColor, SkinColor, MajorColor, MinorColor
- global PickedColor
-
- CloseSubSubCustomizeWindow ()
- PickedColor=ColorTable.GetValue (ColorIndex, GemRB.GetVar ("Selected"))
- if ColorIndex==0:
- HairColor=PickedColor
- UpdatePaperDoll ()
- return
- if ColorIndex==1:
- SkinColor=PickedColor
- UpdatePaperDoll ()
- return
- if ColorIndex==2:
- MinorColor=PickedColor
- UpdatePaperDoll ()
- return
-
- MajorColor=PickedColor
- UpdatePaperDoll ()
- return
-
-def OpenScriptWindow ():
- global SubCustomizeWindow
- global ScriptTextArea, SelectedTextArea
-
- SubCustomizeWindow = GemRB.LoadWindow (11)
-
- ScriptTextArea = SubCustomizeWindow.GetControl (2)
- ScriptTextArea.SetFlags (IE_GUI_TEXTAREA_SELECTABLE)
- FillScriptList ()
- pc = GemRB.GameGetSelectedPCSingle ()
- script = GemRB.GetPlayerScript (pc)
- scriptindex = ScriptsTable.GetRowIndex (script)
- GemRB.SetVar ("Selected", scriptindex)
- ScriptTextArea.SetVarAssoc ("Selected", scriptindex)
-
- SelectedTextArea = SubCustomizeWindow.GetControl (4)
- UpdateScriptSelection ()
-
- DoneButton = SubCustomizeWindow.GetControl (5)
- DoneButton.SetText (11973)
- DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- CancelButton = SubCustomizeWindow.GetControl (6)
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DoneScriptWindow)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSubCustomizeWindow)
- ScriptTextArea.SetEvent (IE_GUI_TEXTAREA_ON_CHANGE, UpdateScriptSelection)
-
- SubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def FillScriptList ():
- ScriptTextArea.Clear ()
- row = ScriptsTable.GetRowCount ()
- for i in range (row):
- GemRB.SetToken ("script", ScriptsTable.GetRowName (i) )
- title = ScriptsTable.GetValue (i,0)
- if title!=-1:
- desc = ScriptsTable.GetValue (i,1)
- txt = GemRB.GetString (title)
-
- if (desc!=-1):
- txt += GemRB.GetString (desc)
-
- ScriptTextArea.Append (txt+"\n", -1)
-
- else:
- ScriptTextArea.Append (ScriptsTable.GetRowName (i)+"\n" ,-1)
-
- return
-
-def DoneScriptWindow ():
- pc = GemRB.GameGetSelectedPCSingle ()
- script = ScriptsTable.GetRowName (GemRB.GetVar ("Selected") )
- GemRB.SetPlayerScript (pc, script)
- CloseSubCustomizeWindow ()
- return
-
-def UpdateScriptSelection():
- text = ScriptTextArea.QueryText ()
- SelectedTextArea.SetText (text)
- return
-
-def OpenBiographyEditWindow ():
- global SubCustomizeWindow
- global BioStrRef
- global TextArea
-
- Changed = 0
- pc = GemRB.GameGetSelectedPCSingle ()
- BioStrRef = GemRB.GetPlayerString (pc, 74)
- if BioStrRef != 33347:
- Changed = 1
-
- SubCustomizeWindow = GemRB.LoadWindow (51)
-
- ClearButton = SubCustomizeWindow.GetControl (5)
- ClearButton.SetText (34881)
-
- DoneButton = SubCustomizeWindow.GetControl (1)
- DoneButton.SetText (11973)
- DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- RevertButton = SubCustomizeWindow.GetControl (3)
- RevertButton.SetText (2240)
- if not Changed:
- RevertButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- CancelButton = SubCustomizeWindow.GetControl (2)
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- TextArea = SubCustomizeWindow.GetControl (4)
- TextArea.SetBufferLength (65535)
- TextArea.SetText (BioStrRef)
-
- ClearButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, ClearBiography)
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DoneBiographyWindow)
- RevertButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, RevertBiography)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSubCustomizeWindow)
-
- SubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def ClearBiography():
- pc = GemRB.GameGetSelectedPCSingle ()
- BioStrRef = 62015+pc
- #GemRB.CreateString (BioStrRef, "")
- TextArea.SetText ("")
- return
-
-def DoneBiographyWindow ():
- global BioStrRef
-
- #TODO set bio
- pc = GemRB.GameGetSelectedPCSingle ()
- #pc is 1 based
- BioStrRef = 62015+pc
- GemRB.CreateString (BioStrRef, TextArea.QueryText())
- GemRB.SetPlayerString (pc, 74, BioStrRef)
- CloseSubCustomizeWindow ()
- return
-
-def RevertBiography():
- global BioStrRef
-
- BioStrRef = 33347
- TextArea.SetText (33347)
- return
-
-def CloseSubCustomizeWindow ():
- global SubCustomizeWindow
-
- if SubCustomizeWindow:
- SubCustomizeWindow.Unload ()
- SubCustomizeWindow = None
- return
-
-def CloseSubSubCustomizeWindow ():
- global SubSubCustomizeWindow
-
- if SubSubCustomizeWindow:
- SubSubCustomizeWindow.Unload ()
- SubSubCustomizeWindow = None
- return
-
-def OpenPortraitSelectWindow ():
- global CharGenWindow, PortraitWindow, PortraitPictureButton
-
- PortraitWindow = GemRB.LoadWindow (18)
-
- PortraitPictureButton = PortraitWindow.GetControl (0)
- PortraitPictureButton.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_NO_IMAGE, OP_SET)
-
- PortraitLeftButton = PortraitWindow.GetControl (1)
- PortraitLeftButton.SetState (IE_GUI_BUTTON_ENABLED)
- PortraitLeftButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, PortraitLeftPress)
- PortraitLeftButton.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
-
- PortraitRightButton = PortraitWindow.GetControl (2)
- PortraitRightButton.SetState (IE_GUI_BUTTON_ENABLED)
- PortraitRightButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, PortraitRightPress)
- PortraitRightButton.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
-
- PortraitCustomButton = PortraitWindow.GetControl (5)
- PortraitCustomButton.SetState (IE_GUI_BUTTON_ENABLED)
- PortraitCustomButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenCustomPortraitWindow)
- PortraitCustomButton.SetText (17545)
-
- PortraitDoneButton = PortraitWindow.GetControl (3)
- PortraitDoneButton.SetState (IE_GUI_BUTTON_ENABLED)
- PortraitDoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, PortraitDonePress)
- PortraitDoneButton.SetText (11973)
- PortraitDoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- PortraitCancelButton = PortraitWindow.GetControl (4)
- PortraitCancelButton.SetState (IE_GUI_BUTTON_ENABLED)
- PortraitCancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, PortraitCancelPress)
- PortraitCancelButton.SetText (13727)
- PortraitCancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- # get players gender and portrait
- Pc = GemRB.GameGetSelectedPCSingle ()
- PcGender = GemRB.GetPlayerStat (Pc, IE_SEX)
- PcPortrait = GemRB.GetPlayerPortrait(Pc,0)
-
- # initialize and set portrait
- Portrait.Init (PcGender)
- Portrait.Set (PcPortrait)
- PortraitPictureButton.SetPicture (Portrait.Name () + "G")
-
- PortraitWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def PortraitLeftPress ():
- global PortraitPictureButton
-
- PortraitPictureButton.SetPicture (Portrait.Previous () + "G")
-
-def PortraitRightPress ():
- global PortraitPictureButton
-
- PortraitPictureButton.SetPicture (Portrait.Next () + "G" )
-
-def ClosePortraitSelectWindow ():
- global PortraitWindow
-
- if PortraitWindow:
- PortraitWindow.Unload ()
- PortraitWindow = None
-
- #UpdateRecordsWindow ()
- CustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def PortraitCancelPress ():
- ClosePortraitSelectWindow ()
- return
-
-def PortraitDonePress ():
- pc = GemRB.GameGetSelectedPCSingle ()
- GemRB.FillPlayerInfo (pc, Portrait.Name () + "L", Portrait.Name () + "S")
- ClosePortraitWindow ()
- return
-
-def ClosePortraitWindow ():
- global PortraitWindow
-
- if PortraitWindow:
- PortraitWindow.Unload ()
- PortraitWindow = None
-
- CustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def OpenCustomPortraitWindow ():
- global CustomPortraitWindow
- global PortraitList1, PortraitList2
- global RowCount1, RowCount2
-
- CustomPortraitWindow = GemRB.LoadWindow (19)
-
- CustomPortraitDoneButton = CustomPortraitWindow.GetControl (10)
- CustomPortraitDoneButton.SetState (IE_GUI_BUTTON_DISABLED)
- CustomPortraitDoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CustomPortraitDonePress)
- CustomPortraitDoneButton.SetText (11973)
- CustomPortraitDoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- CustomPortraitCancelButton = CustomPortraitWindow.GetControl (11)
- CustomPortraitCancelButton.SetState (IE_GUI_BUTTON_ENABLED)
- CustomPortraitCancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseCustomPortraitWindow)
- CustomPortraitCancelButton.SetText (13727)
- CustomPortraitCancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- # Portrait List Large
- PortraitList1 = CustomPortraitWindow.GetControl (2)
- RowCount1 = PortraitList1.GetPortraits (0)
- PortraitList1.SetEvent (IE_GUI_TEXTAREA_ON_CHANGE, LargeCustomPortrait)
- GemRB.SetVar ("Row1", RowCount1)
- PortraitList1.SetVarAssoc ("Row1",RowCount1)
-
- # Portrait List Small
- PortraitList2 = CustomPortraitWindow.GetControl (3)
- RowCount2 = PortraitList2.GetPortraits (1)
- PortraitList2.SetEvent (IE_GUI_TEXTAREA_ON_CHANGE, SmallCustomPortrait)
- GemRB.SetVar ("Row2", RowCount2)
- PortraitList2.SetVarAssoc ("Row2",RowCount2)
-
- CustomPortraitWindow.ShowModal (MODAL_SHADOW_GRAY)
-
- return
-
-def CustomPortraitDonePress ():
- pc = GemRB.GameGetSelectedPCSingle ()
- GemRB.FillPlayerInfo (pc, PortraitList1.QueryText () , PortraitList2.QueryText ())
-
- CloseCustomPortraitWindow ()
- ClosePortraitWindow ()
- return
-
-def CloseCustomPortraitWindow ():
- global CustomPortraitWindow
-
- if CustomPortraitWindow:
- CustomPortraitWindow.ShowModal (MODAL_SHADOW_BLACK)
- CustomPortraitWindow.Unload ()
- CustomPortraitWindow = None
-
- return
-
-def LargeCustomPortrait():
- global PortraitList1
-
- Window = CustomPortraitWindow
-
- Portrait = PortraitList1.QueryText ()
- #small hack
- if GemRB.GetVar ("Row1") == RowCount1:
- return
-
- Label = Window.GetControl (0x10000007)
- Label.SetText (Portrait)
-
- Button = Window.GetControl (10)
- if Portrait=="":
- Portrait = "NOPORTMD"
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- if PortraitList2.QueryText ()!="":
- Button.SetState (IE_GUI_BUTTON_ENABLED)
-
- Button = Window.GetControl (0)
- Button.SetPicture (Portrait, "NOPORTMD")
- return
-
-def SmallCustomPortrait():
- global PortraitList2
-
- Window = CustomPortraitWindow
-
- Portrait = PortraitList2.QueryText ()
- #small hack
- if GemRB.GetVar ("Row2") == RowCount2:
- return
-
- Label = Window.GetControl (0x10000008)
- Label.SetText (Portrait)
-
- Button = Window.GetControl (10)
- if Portrait=="":
- Portrait = "NOPORTSM"
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- if PortraitList1.QueryText ()!="":
- Button.SetState (IE_GUI_BUTTON_ENABLED)
-
- Button = Window.GetControl (1)
- Button.SetPicture (Portrait, "NOPORTSM")
- return
-
-
-###################################################
-# End of file GUIREC.py
diff --git a/gemrb/GUIScripts/iwd/GUISAVE.py b/gemrb/GUIScripts/iwd/GUISAVE.py
deleted file mode 100644
index e6a2091..0000000
--- a/gemrb/GUIScripts/iwd/GUISAVE.py
+++ /dev/null
@@ -1,279 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-
-# GUISAVE.py - Save window
-
-###################################################
-
-import GemRB
-import GUICommon
-import LoadScreen
-from GUIDefines import *
-
-SaveWindow = 0
-ConfirmWindow = 0
-NameField = 0
-SaveButton = 0
-TextAreaControl = 0
-Games = ()
-ScrollBar = 0
-
-def OpenSaveWindow ():
- global SaveWindow, TextAreaControl, Games, ScrollBar
-
- if GUICommon.CloseOtherWindow (OpenSaveWindow):
- CloseSaveWindow ()
- return
-
- GemRB.HideGUI ()
- GUICommon.GameWindow.SetVisible(WINDOW_INVISIBLE)
-
- GemRB.LoadWindowPack ("GUISAVE", 640, 480)
- Window = SaveWindow = GemRB.LoadWindow (0)
- Window.SetFrame ()
- CancelButton=Window.GetControl (34)
- CancelButton.SetText (13727)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenSaveWindow)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
- GemRB.SetVar ("LoadIdx",0)
-
- for i in range(4):
- Button = Window.GetControl (26+i)
- Button.SetText (15588)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SavePress)
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- Button.SetVarAssoc ("LoadIdx",i)
-
- Button = Window.GetControl (30+i)
- Button.SetText (13957)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, DeleteGamePress)
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- Button.SetVarAssoc ("LoadIdx",i)
-
- #area previews
- Button = Window.GetControl (1+i)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- Button.SetFlags(IE_GUI_BUTTON_NO_IMAGE|IE_GUI_BUTTON_PICTURE,OP_SET)
-
- #PC portraits
- for j in range(PARTY_SIZE):
- Button = Window.GetControl (40+i*PARTY_SIZE+j)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- Button.SetFlags(IE_GUI_BUTTON_NO_IMAGE|IE_GUI_BUTTON_PICTURE,OP_SET)
-
- ScrollBar=Window.GetControl (25)
- ScrollBar.SetEvent (IE_GUI_SCROLLBAR_ON_CHANGE, ScrollBarPress)
- Games=GemRB.GetSaveGames ()
- TopIndex = max (0, len(Games) - 4 + 1) #one more for the 'new game'
- GemRB.SetVar ("TopIndex",TopIndex)
- ScrollBar.SetVarAssoc ("TopIndex", TopIndex+1)
- ScrollBar.SetDefaultScrollBar ()
- ScrollBarPress ()
- Window.SetVisible (WINDOW_VISIBLE)
- return
-
-def ScrollBarPress():
- Window = SaveWindow
-
- #draw load game portraits
- Pos = GemRB.GetVar ("TopIndex")
- for i in range(4):
- ActPos = Pos + i
-
- Button1 = Window.GetControl (26+i)
- Button2 = Window.GetControl (30+i)
- if ActPos<=len(Games):
- Button1.SetState (IE_GUI_BUTTON_ENABLED)
- else:
- Button1.SetState (IE_GUI_BUTTON_DISABLED)
-
- if ActPos<len(Games):
- Slotname = Games[ActPos].GetName()
- Button2.SetState (IE_GUI_BUTTON_ENABLED)
- elif ActPos == len(Games):
- Slotname = 15304
- Button2.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- Slotname = ""
- Button2.SetState (IE_GUI_BUTTON_DISABLED)
-
- Label = Window.GetControl (0x10000008+i)
- Label.SetText (Slotname)
-
- if ActPos<len(Games):
- Slotname = Games[ActPos].GetGameDate()
- else:
- Slotname = ""
- Label = Window.GetControl (0x10000010+i)
- Label.SetText (Slotname)
-
- Button=Window.GetControl (1+i)
- if ActPos<len(Games):
- Button.SetSprite2D(Games[ActPos].GetPreview())
- else:
- Button.SetPicture("")
- for j in range(PARTY_SIZE):
- Button=Window.GetControl (40+i*PARTY_SIZE+j)
- if ActPos<len(Games):
- Button.SetSprite2D(Games[ActPos].GetPortrait(j))
- else:
- Button.SetPicture("")
- return
-
-def AbortedSaveGame():
- if ConfirmWindow:
- ConfirmWindow.Unload ()
- SaveWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def ConfirmedSaveGame():
- global ConfirmWindow
-
- Pos = GemRB.GetVar ("TopIndex")+GemRB.GetVar ("LoadIdx")
- Label = ConfirmWindow.GetControl (3)
- Slotname = Label.QueryText ()
- LoadScreen.StartLoadScreen()
- if Pos < len(Games):
- GemRB.SaveGame(Games[Pos], Slotname)
- else:
- GemRB.SaveGame(None, Slotname)
- if ConfirmWindow:
- ConfirmWindow.Unload ()
- SaveWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def SavePress():
- global ConfirmWindow, NameField, SaveButton
-
- Pos = GemRB.GetVar ("TopIndex")+GemRB.GetVar ("LoadIdx")
- ConfirmWindow = GemRB.LoadWindow (1)
-
- #slot name
- if Pos<len(Games):
- Slotname = Games[Pos].GetName()
- save_strref = 15306
- else:
- Slotname = ""
- save_strref = 15588
- NameField = ConfirmWindow.GetControl (3)
- NameField.SetText (Slotname)
- NameField.SetEvent (IE_GUI_EDIT_ON_CHANGE, EditChange)
-
- #game hours (should be generated from game)
- if Pos<len(Games):
- Slotname = Games[Pos].GetGameDate()
- else:
- Slotname = ""
- Label = ConfirmWindow.GetControl (0x10000004)
- Label.SetText (Slotname)
-
- #areapreview
- Button=ConfirmWindow.GetControl (0)
- if Pos<len(Games):
- Button.SetSprite2D(Games[Pos].GetPreview())
- else:
- Button.SetPicture("")
-
- #portraits
- for j in range(PARTY_SIZE):
- Button=ConfirmWindow.GetControl (40+j)
- if Pos<len(Games):
- Button.SetSprite2D(Games[Pos].GetPortrait(j))
- else:
- Button.SetPicture("")
-
- #save
- SaveButton=ConfirmWindow.GetControl (7)
- SaveButton.SetText (save_strref)
- SaveButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, ConfirmedSaveGame)
- SaveButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
- #SaveButton.SetState (IE_GUI_BUTTON_DISABLED)
- if Slotname == "":
- SaveButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- #cancel
- CancelButton=ConfirmWindow.GetControl (8)
- CancelButton.SetText (13727)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, AbortedSaveGame)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- ConfirmWindow.SetVisible (WINDOW_VISIBLE)
- NameField.SetStatus (IE_GUI_CONTROL_FOCUSED)
- return
-
-def EditChange():
- Name = NameField.QueryText ()
- if len(Name)==0:
- SaveButton.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- SaveButton.SetState (IE_GUI_BUTTON_ENABLED)
- return
-
-def DeleteGameConfirm():
- global Games
-
- TopIndex = GemRB.GetVar ("TopIndex")
- Pos = TopIndex +GemRB.GetVar ("LoadIdx")
- GemRB.DeleteSaveGame(Games[Pos])
- if TopIndex>0:
- GemRB.SetVar ("TopIndex",TopIndex-1)
- del Games[pos]
- ScrollBar.SetVarAssoc ("TopIndex", len(Games))
- ScrollBarPress()
- if ConfirmWindow:
- ConfirmWindow.Unload ()
- SaveWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def DeleteGameCancel():
- if ConfirmWindow:
- ConfirmWindow.Unload ()
- SaveWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def DeleteGamePress():
- global ConfirmWindow
-
- SaveWindow.SetVisible (WINDOW_INVISIBLE)
- ConfirmWindow=GemRB.LoadWindow (2)
- Text=ConfirmWindow.GetControl (0)
- Text.SetText (15305)
- DeleteButton=ConfirmWindow.GetControl (1)
- DeleteButton.SetText (13957)
- DeleteButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DeleteGameConfirm)
- CancelButton=ConfirmWindow.GetControl (2)
- CancelButton.SetText (13727)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DeleteGameCancel)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- ConfirmWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def CloseSaveWindow ():
- if SaveWindow:
- SaveWindow.Unload ()
- if GemRB.GetVar ("QuitAfterSave"):
- GemRB.QuitGame ()
- GemRB.SetNextScript ("Start")
- return
-
- GUICommon.GameWindow.SetVisible(WINDOW_VISIBLE) #enabling the game control screen
- GemRB.UnhideGUI () #enabling the other windows
- return
diff --git a/gemrb/GUIScripts/iwd/GUIWORLD.py b/gemrb/GUIScripts/iwd/GUIWORLD.py
deleted file mode 100644
index 7b74a6d..0000000
--- a/gemrb/GUIScripts/iwd/GUIWORLD.py
+++ /dev/null
@@ -1,312 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-
-# GUIW.py - scripts to control some windows from GUIWORLD winpack
-# except of Actions, Portrait, Options and Dialog windows
-#################################################################
-
-import GemRB
-from GUIDefines import *
-from ie_restype import *
-import GUICommon
-import GUICommonWindows
-import GUIClasses
-import MessageWindow
-import CommonWindow
-
-FRAME_PC_SELECTED = 0
-FRAME_PC_TARGET = 1
-
-ContinueWindow = None
-ReformPartyWindow = None
-OldActionsWindow = None
-OldMessageWindow = None
-
-def DialogStarted ():
- global ContinueWindow, OldActionsWindow
-
- # try to force-close anything which is open
- GUICommon.CloseOtherWindow(None)
- CommonWindow.CloseContainerWindow()
-
- # we need GUI for dialogs
- GemRB.UnhideGUI()
-
- # opening control size to maximum, enabling dialog window
- GemRB.GameSetScreenFlags(GS_HIDEGUI, OP_NAND)
- GemRB.GameSetScreenFlags(GS_DIALOG, OP_OR)
-
- if GUICommonWindows.PortraitWindow:
- GUICommonWindows.UpdatePortraitWindow ()
-
- # we want this to happen before we start fiddling with the GUI
- MessageWindow.UpdateControlStatus()
-
- GemRB.LoadWindowPack (GUICommon.GetWindowPack())
- ContinueWindow = Window = GemRB.LoadWindow (9)
-
- GUICommonWindows.EmptyControls()
- OldActionsWindow = GUICommonWindows.ActionsWindow
- #GUICommonWindows.ActionsWindow = None
- OldActionsWindow.SetVisible(WINDOW_INVISIBLE)
- GemRB.SetVar ("ActionsWindow", -1)
-
-def DialogEnded ():
- global ContinueWindow, OldActionsWindow
-
- # TODO: why is this being called at game start?!
- if not ContinueWindow:
- return
-
- #GUICommonWindows.ActionsWindow = OldActionsWindow
- OldActionsWindow.SetVisible(WINDOW_VISIBLE)
- GemRB.SetVar ("ActionsWindow", OldActionsWindow.ID)
- GUICommonWindows.UpdateActionsWindow()
-
- ContinueWindow.Unload ()
- ContinueWindow = None
- OldActionsWindow = None
-
- if GUICommonWindows.PortraitWindow:
- GUICommonWindows.UpdatePortraitWindow ()
-
-def CloseContinueWindow ():
- # don't close the actual window now to avoid flickering: we might still want it open
- GemRB.SetVar ("DialogChoose", GemRB.GetVar ("DialogOption"))
-
-def NextDialogState ():
- if not ContinueWindow:
- return
-
- ContinueWindow.SetVisible(WINDOW_INVISIBLE)
- OldActionsWindow.SetVisible(WINDOW_VISIBLE)
-
- MessageWindow.TMessageTA.SetStatus (IE_GUI_CONTROL_FOCUSED)
-
-def OpenEndMessageWindow ():
- ContinueWindow.SetVisible(WINDOW_VISIBLE)
- OldActionsWindow.SetVisible(WINDOW_INVISIBLE)
- Button = ContinueWindow.GetControl (0)
- Button.SetText (9371)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseContinueWindow)
- Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
- Button.SetStatus (IE_GUI_CONTROL_FOCUSED)
-
-def OpenContinueMessageWindow ():
- ContinueWindow.SetVisible(WINDOW_VISIBLE)
- OldActionsWindow.SetVisible(WINDOW_INVISIBLE)
- #continue
- Button = ContinueWindow.GetControl (0)
- Button.SetText (9372)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseContinueWindow)
- Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
- Button.SetStatus (IE_GUI_CONTROL_FOCUSED)
-
-def UpdateReformWindow ():
- Window = ReformPartyWindow
-
- select = GemRB.GetVar ("Selected")
-
- need_to_drop = GemRB.GetPartySize ()-PARTY_SIZE
- if need_to_drop<0:
- need_to_drop = 0
-
- #excess player number
- Label = Window.GetControl (0x1000000f)
- Label.SetText (str(need_to_drop) )
-
- #done
- Button = Window.GetControl (8)
- if need_to_drop:
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- Button.SetState (IE_GUI_BUTTON_ENABLED)
-
- #remove
- Button = Window.GetControl (15)
- if select:
- Button.SetState (IE_GUI_BUTTON_ENABLED)
- else:
- Button.SetState (IE_GUI_BUTTON_DISABLED)
-
- for i in range (PARTY_SIZE+1):
- Button = Window.GetControl (i)
- Button.EnableBorder (FRAME_PC_SELECTED, select == i+2 )
- #+2 because protagonist is skipped
- pic = GemRB.GetPlayerPortrait (i+2,1)
- if not pic:
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- continue
-
- Button.SetState (IE_GUI_BUTTON_ENABLED)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_ALIGN_BOTTOM|IE_GUI_BUTTON_ALIGN_LEFT, OP_SET)
- Button.SetPicture (pic, "NOPORTSM")
- GUICommonWindows.UpdatePortraitWindow ()
- return
-
-def RemovePlayer ():
- global ReformPartyWindow
-
- hideflag = GemRB.HideGUI ()
-
- GemRB.LoadWindowPack (GUICommon.GetWindowPack())
- if ReformPartyWindow:
- ReformPartyWindow.Unload ()
- ReformPartyWindow = Window = GemRB.LoadWindow (25)
- GemRB.SetVar ("OtherWindow", Window.ID)
-
- #are you sure
- Label = Window.GetControl (0x0fffffff)
- Label.SetText (17518)
-
- #confirm
- Button = Window.GetControl (1)
- Button.SetText (17507)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, RemovePlayerConfirm)
- Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- #cancel
- Button = Window.GetControl (2)
- Button.SetText (13727)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, RemovePlayerCancel)
- Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
-def RemovePlayerConfirm ():
- global ReformPartyWindow
-
- hideflag = GemRB.HideGUI ()
- if ReformPartyWindow:
- ReformPartyWindow.Unload ()
- GemRB.SetVar ("OtherWindow", -1)
- #removing selected player
- ReformPartyWindow = None
- if hideflag:
- GemRB.UnhideGUI ()
- GemRB.LeaveParty (GemRB.GetVar("Selected") )
- OpenReformPartyWindow ()
- return
-
-def RemovePlayerCancel ():
- global ReformPartyWindow
-
- hideflag = GemRB.HideGUI ()
- if ReformPartyWindow:
- ReformPartyWindow.Unload ()
- GemRB.SetVar ("OtherWindow", -1)
- ReformPartyWindow = None
- if hideflag:
- GemRB.UnhideGUI ()
- OpenReformPartyWindow ()
- return
-
-def OpenReformPartyWindow ():
- global ReformPartyWindow
-
- GemRB.SetVar ("Selected", 0)
- hideflag = GemRB.HideGUI ()
-
- if ReformPartyWindow:
- if ReformPartyWindow:
- ReformPartyWindow.Unload ()
- ReformPartyWindow = None
-
- GemRB.SetVar ("OtherWindow", -1)
- #GemRB.LoadWindowPack ("GUIREC")
- if hideflag:
- GemRB.UnhideGUI ()
- #re-enabling party size control
- GemRB.GameSetPartySize (PARTY_SIZE)
- return
-
- GemRB.LoadWindowPack (GUICommon.GetWindowPack())
- ReformPartyWindow = Window = GemRB.LoadWindow (24)
- GemRB.SetVar ("OtherWindow", Window.ID)
-
- #PC portraits
- for j in range (PARTY_SIZE+1):
- Button = Window.GetControl (j)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON|IE_GUI_BUTTON_NO_IMAGE|IE_GUI_BUTTON_PICTURE,OP_SET)
- Button.SetBorder (FRAME_PC_SELECTED, 1, 1, 2, 2, 0, 255, 0, 255)
- #protagonist is skipped
- index = j + 2
- Button.SetVarAssoc ("Selected", index)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, UpdateReformWindow)
-
- # Remove
- Button = Window.GetControl (15)
- Button.SetText (17507)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, RemovePlayer)
-
- # Done
- Button = Window.GetControl (8)
- Button.SetText (11973)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenReformPartyWindow)
- GemRB.SetVar ("ActionsWindow", -1)
- UpdateReformWindow ()
- if hideflag:
- GemRB.UnhideGUI ()
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DeathWindow ():
- #no death movie, but music is changed
- GemRB.LoadMusicPL ("Theme.mus",1)
- GemRB.HideGUI ()
- GemRB.SetTimedEvent (DeathWindowEnd, 10)
- return
-
-def DeathWindowEnd ():
- GemRB.GamePause (1,1)
-
- GemRB.LoadWindowPack (GUICommon.GetWindowPack())
- Window = GemRB.LoadWindow (17)
-
- #reason for death
- Label = Window.GetControl (0x0fffffff)
- Label.SetText (16498)
-
- #load
- Button = Window.GetControl (1)
- Button.SetText (15590)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, LoadPress)
-
- #quit
- Button = Window.GetControl (2)
- Button.SetText (15417)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, QuitPress)
-
- GemRB.HideGUI ()
- GemRB.SetVar ("MessageWindow", -1)
- GemRB.UnhideGUI ()
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def QuitPress():
- GemRB.QuitGame ()
- GemRB.SetNextScript ("Start")
- return
-
-def LoadPress():
- GemRB.QuitGame ()
- GemRB.SetNextScript ("GUILOAD")
- return
-
diff --git a/gemrb/GUIScripts/iwd/Portrait.py b/gemrb/GUIScripts/iwd/Portrait.py
deleted file mode 100644
index 709407e..0000000
--- a/gemrb/GUIScripts/iwd/Portrait.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-
-
-# Portrait.py - scripts to control portrait selection and scrolling
-###################################################
-
-import GemRB
-
-###################################################
-
-PortraitCount = 0
-PortraitsTable = None
-Gender = None
-
-# initializes gender and portrait table
-# PortraitGender: 1 Male
-# 2 Female
-def Init (PortraitGender):
- global PortraitsTable, PortraitCount, Gender
-
- if PortraitsTable is None:
- PortraitsTable = GemRB.LoadTable ("PICTURES")
-
- PortraitCount = 0
- Gender = PortraitGender
-
-# sets index to given protraitname
-def Set (PortraitName):
- global PortraitCount
-
- # removes l or s character at the end
- PortraitName = PortraitName.rstrip ("[ls]")
-
- # capitalize PortraitName
- PortraitName = PortraitName.upper ()
-
- # search table
- for i in range(0, PortraitsTable.GetRowCount ()):
- if PortraitName == PortraitsTable.GetRowName (i).upper ():
- PortraitCount = i
- break;
-
- return
-
-# returns next portrait name
-def Next ():
- global PortraitCount
-
- while True:
- PortraitCount = PortraitCount + 1
- if PortraitCount == PortraitsTable.GetRowCount ():
- PortraitCount = 0
- if PortraitsTable.GetValue (PortraitCount, 0) == Gender:
- return Name ()
-
-# return previous portrait name
-def Previous ():
- global PortraitCount
-
- while True:
- PortraitCount = PortraitCount - 1
- if PortraitCount < 0:
- PortraitCount = PortraitsTable.GetRowCount () - 1
- if PortraitsTable.GetValue (PortraitCount, 0) == Gender:
- return Name ()
-
-# gets current portrait name
-def Name ():
- global PortraitCount
-
- # if portrait matches not current gender, it will be skipped to
- # the next portrait that matches
- while PortraitsTable.GetValue (PortraitCount, 0) != Gender:
- PortraitCount = PortraitCount + 1
-
- PortraitName = PortraitsTable.GetRowName (PortraitCount)
- return PortraitName
diff --git a/gemrb/GUIScripts/iwd/Start.py b/gemrb/GUIScripts/iwd/Start.py
index d450262..a1ca940 100644
--- a/gemrb/GUIScripts/iwd/Start.py
+++ b/gemrb/GUIScripts/iwd/Start.py
@@ -145,6 +145,7 @@ def ProtocolPress ():
DoneButton = ProtocolWindow.GetControl (6)
DoneButton.SetText (11973)
DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, ProtocolDonePress)
+ DoneButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
ProtocolWindow.ShowModal (1)
return
diff --git a/gemrb/GUIScripts/iwd2/Alignment.py b/gemrb/GUIScripts/iwd2/Alignment.py
index 356b780..e0db0c6 100644
--- a/gemrb/GUIScripts/iwd2/Alignment.py
+++ b/gemrb/GUIScripts/iwd2/Alignment.py
@@ -24,11 +24,9 @@ import CommonTables
AlignmentWindow = 0
TextAreaControl = 0
DoneButton = 0
-AlignmentTable = 0
def OnLoad():
global AlignmentWindow, TextAreaControl, DoneButton
- global AlignmentTable
Class = GemRB.GetVar("Class")-1
KitName = CommonTables.Classes.GetRowName(Class)
@@ -36,17 +34,16 @@ def OnLoad():
AlignmentOk = GemRB.LoadTable("ALIGNMNT")
GemRB.LoadWindowPack("GUICG", 800, 600)
- AlignmentTable = GemRB.LoadTable("aligns")
AlignmentWindow = GemRB.LoadWindow(3)
for i in range(9):
Button = AlignmentWindow.GetControl(i+2)
Button.SetFlags(IE_GUI_BUTTON_RADIOBUTTON,OP_OR)
Button.SetState(IE_GUI_BUTTON_DISABLED)
- Button.SetText(AlignmentTable.GetValue(i,0) )
+ Button.SetText (CommonTables.Aligns.GetValue (i, 0))
for i in range(9):
Button = AlignmentWindow.GetControl(i+2)
- if AlignmentOk.GetValue(KitName, AlignmentTable.GetValue(i, 4) ) != 0:
+ if AlignmentOk.GetValue (KitName, CommonTables.Aligns.GetValue (i, 4)) != 0:
Button.SetState(IE_GUI_BUTTON_ENABLED)
Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, AlignmentPress)
Button.SetVarAssoc("Alignment", i+1)
@@ -70,7 +67,7 @@ def OnLoad():
def AlignmentPress():
Alignment = GemRB.GetVar("Alignment")-1
- TextAreaControl.SetText(AlignmentTable.GetValue(Alignment,1) )
+ TextAreaControl.SetText (CommonTables.Aligns.GetValue (Alignment, 1))
DoneButton.SetState(IE_GUI_BUTTON_ENABLED)
return
diff --git a/gemrb/GUIScripts/iwd2/AutoPause.py b/gemrb/GUIScripts/iwd2/AutoPause.py
deleted file mode 100644
index 853aad5..0000000
--- a/gemrb/GUIScripts/iwd2/AutoPause.py
+++ /dev/null
@@ -1,206 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-# autopause options using GUIOPT
-
-import GemRB
-from GUIDefines import *
-
-def OnLoad ():
- global AutoPauseWindow, TextAreaControl
-
- GemRB.LoadWindowPack ("GUIOPT", 800, 600)
-
- AutoPauseWindow = GemRB.LoadWindow (10)
- AutoPauseWindow.SetFrame ( )
-
- TextAreaControl = AutoPauseWindow.GetControl (15)
-
- ChHitButton = AutoPauseWindow.GetControl (17)
- ChHitButtonB = AutoPauseWindow.GetControl (1)
- ChHitButtonB.SetSprites ("GBTNOPT4", 0, 0, 1, 2, 3)
-
- ChInjured = AutoPauseWindow.GetControl (18)
- ChInjuredB = AutoPauseWindow.GetControl (2)
- ChInjuredB.SetSprites ("GBTNOPT4", 0, 0, 1, 2, 3)
-
- ChDeath = AutoPauseWindow.GetControl (19)
- ChDeathB = AutoPauseWindow.GetControl (3)
- ChDeathB.SetSprites ("GBTNOPT4", 0, 0, 1, 2, 3)
-
- ChAttacked = AutoPauseWindow.GetControl (20)
- ChAttackedB = AutoPauseWindow.GetControl (4)
- ChAttackedB.SetSprites ("GBTNOPT4", 0, 0, 1, 2, 3)
-
- WeaponUnusable = AutoPauseWindow.GetControl (21)
- WeaponUnusableB = AutoPauseWindow.GetControl (5)
- WeaponUnusableB.SetSprites ("GBTNOPT4", 0, 0, 1, 2, 3)
-
- TargetDestroyed = AutoPauseWindow.GetControl (22)
- TargetDestroyedB = AutoPauseWindow.GetControl (13)
- TargetDestroyedB.SetSprites ("GBTNOPT4", 0, 0, 1, 2, 3)
-
- EndOfRound = AutoPauseWindow.GetControl (24)
- EndOfRoundB = AutoPauseWindow.GetControl (25)
- EndOfRoundB.SetSprites ("GBTNOPT4", 0, 0, 1, 2, 3)
-
- EnemySighted = AutoPauseWindow.GetControl (31)
- EnemySightedB = AutoPauseWindow.GetControl (30)
- EnemySightedB.SetSprites ("GBTNOPT4", 0, 0, 1, 2, 3)
-
- SpellCast = AutoPauseWindow.GetControl (37)
- SpellCastB = AutoPauseWindow.GetControl (36)
- SpellCastB.SetSprites ("GBTNOPT4", 0, 0, 1, 2, 3)
-
- TrapFound = AutoPauseWindow.GetControl (28)
- TrapFoundB = AutoPauseWindow.GetControl (26)
- TrapFoundB.SetSprites ("GBTNOPT4", 0, 0, 1, 2, 3)
-
- AutopauseCenter = AutoPauseWindow.GetControl (34)
- AutopauseCenterB = AutoPauseWindow.GetControl (33)
- AutopauseCenterB.SetSprites ("GBTNOPT4", 0, 0, 1, 2, 3)
-
- OkButton = AutoPauseWindow.GetControl (11)
- CancelButton = AutoPauseWindow.GetControl (14)
-
- TextAreaControl.SetText (18044)
- OkButton.SetText (11973)
- OkButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- ChHitButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, ChHitButtonPress)
- ChHitButtonB.SetFlags (IE_GUI_BUTTON_CHECKBOX, OP_OR)
- ChHitButtonB.SetEvent (IE_GUI_BUTTON_ON_PRESS, ChHitButtonPress)
-
- ChInjured.SetEvent (IE_GUI_BUTTON_ON_PRESS, ChInjuredPress)
- ChInjuredB.SetFlags (IE_GUI_BUTTON_CHECKBOX, OP_OR)
- ChInjuredB.SetEvent (IE_GUI_BUTTON_ON_PRESS, ChInjuredPress)
-
- ChDeath.SetEvent (IE_GUI_BUTTON_ON_PRESS, ChDeathPress)
- ChDeathB.SetFlags (IE_GUI_BUTTON_CHECKBOX, OP_OR)
- ChDeathB.SetEvent (IE_GUI_BUTTON_ON_PRESS, ChDeathPress)
-
- ChAttacked.SetEvent (IE_GUI_BUTTON_ON_PRESS, ChAttackedPress)
- ChAttackedB.SetFlags (IE_GUI_BUTTON_CHECKBOX, OP_OR)
- ChAttackedB.SetEvent (IE_GUI_BUTTON_ON_PRESS, ChAttackedPress)
-
- WeaponUnusable.SetEvent (IE_GUI_BUTTON_ON_PRESS, WeaponUnusablePress)
- WeaponUnusableB.SetFlags (IE_GUI_BUTTON_CHECKBOX, OP_OR)
- WeaponUnusableB.SetEvent (IE_GUI_BUTTON_ON_PRESS, WeaponUnusablePress)
-
- TargetDestroyed.SetEvent (IE_GUI_BUTTON_ON_PRESS, TargetDestroyedPress)
- TargetDestroyedB.SetFlags (IE_GUI_BUTTON_CHECKBOX, OP_OR)
- TargetDestroyedB.SetEvent (IE_GUI_BUTTON_ON_PRESS, TargetDestroyedPress)
-
- EndOfRound.SetEvent (IE_GUI_BUTTON_ON_PRESS, EndOfRoundPress)
- EndOfRoundB.SetFlags (IE_GUI_BUTTON_CHECKBOX, OP_OR)
- EndOfRoundB.SetEvent (IE_GUI_BUTTON_ON_PRESS, EndOfRoundPress)
-
- EnemySighted.SetEvent (IE_GUI_BUTTON_ON_PRESS, EnemySightedPress)
- EnemySightedB.SetFlags (IE_GUI_BUTTON_CHECKBOX, OP_OR)
- EnemySightedB.SetEvent (IE_GUI_BUTTON_ON_PRESS, EnemySightedPress)
-
- SpellCast.SetEvent (IE_GUI_BUTTON_ON_PRESS, SpellCastPress)
- SpellCastB.SetFlags (IE_GUI_BUTTON_CHECKBOX, OP_OR)
- SpellCastB.SetEvent (IE_GUI_BUTTON_ON_PRESS, SpellCastPress)
-
- TrapFound.SetEvent (IE_GUI_BUTTON_ON_PRESS, TrapFoundPress)
- TrapFoundB.SetFlags (IE_GUI_BUTTON_CHECKBOX, OP_OR)
- TrapFoundB.SetEvent (IE_GUI_BUTTON_ON_PRESS, TrapFoundPress)
-
- AutopauseCenter.SetEvent (IE_GUI_BUTTON_ON_PRESS, AutopauseCenterPress)
- AutopauseCenterB.SetFlags (IE_GUI_BUTTON_CHECKBOX, OP_OR)
- AutopauseCenterB.SetEvent (IE_GUI_BUTTON_ON_PRESS, AutopauseCenterPress)
-
- OkButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OkPress)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CancelPress)
-
- AutopauseCenterB.SetVarAssoc ("Auto Pause Center",1)
-
- ChHitButtonB.SetVarAssoc ("Auto Pause State",1)
- ChInjuredB.SetVarAssoc ("Auto Pause State",2)
- ChDeathB.SetVarAssoc ("Auto Pause State",4)
- ChAttackedB.SetVarAssoc ("Auto Pause State",8)
- WeaponUnusableB.SetVarAssoc ("Auto Pause State",16)
- TargetDestroyedB.SetVarAssoc ("Auto Pause State",32)
- EndOfRoundB.SetVarAssoc ("Auto Pause State",64)
- EnemySightedB.SetVarAssoc ("Auto Pause State",128)
- SpellCastB.SetVarAssoc ("Auto Pause State",256)
- TrapFoundB.SetVarAssoc ("Auto Pause State",512)
-
- AutoPauseWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def ChHitButtonPress ():
- TextAreaControl.SetText (18032)
- return
-
-def ChInjuredPress ():
- TextAreaControl.SetText (18033)
- return
-
-def ChDeathPress ():
- TextAreaControl.SetText (18034)
- return
-
-def ChAttackedPress ():
- TextAreaControl.SetText (18035)
- return
-
-def WeaponUnusablePress ():
- TextAreaControl.SetText (18036)
- return
-
-def TargetDestroyedPress ():
- TextAreaControl.SetText (18037)
- return
-
-def EndOfRoundPress ():
- TextAreaControl.SetText (10640)
- return
-
-def EnemySightedPress ():
- TextAreaControl.SetText (23514)
- return
-
-def SpellCastPress ():
- TextAreaControl.SetText (26311)
- return
-
-def TrapFoundPress ():
- TextAreaControl.SetText (18560) #iwd2 has it here
- return
-
-def AutopauseCenterPress ():
- TextAreaControl.SetText (24888) #iwd2 has it here
- return
-
-def OkPress ():
- if AutoPauseWindow:
- AutoPauseWindow.Unload ()
- GemRB.SetNextScript ("GamePlay")
- return
-
-def CancelPress ():
- if AutoPauseWindow:
- AutoPauseWindow.Unload ()
- GemRB.SetNextScript ("GamePlay")
- return
diff --git a/gemrb/GUIScripts/iwd2/CGPortrait.py b/gemrb/GUIScripts/iwd2/CGPortrait.py
new file mode 100644
index 0000000..05dddcb
--- /dev/null
+++ b/gemrb/GUIScripts/iwd2/CGPortrait.py
@@ -0,0 +1,230 @@
+# GemRB - Infinity Engine Emulator
+# Copyright (C) 2003 The GemRB Project
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+#
+#character generation, appearance (GUICG12)
+import GemRB
+from GUIDefines import *
+
+AppearanceWindow = 0
+PortraitButton = 0
+PortraitsTable = 0
+LastPortrait = 0
+Gender = 0
+
+def SetPicture ():
+ global PortraitsTable, LastPortrait
+
+ PortraitName = PortraitsTable.GetRowName (LastPortrait)+"L"
+ PortraitButton.SetPicture (PortraitName)
+ return
+
+def OnLoad ():
+ global AppearanceWindow, PortraitButton, PortraitsTable, LastPortrait
+ global Gender
+
+ Gender=GemRB.GetVar ("Gender")
+
+ GemRB.LoadWindowPack ("GUICG", 800, 600)
+ AppearanceWindow = GemRB.LoadWindow (11)
+ #AppearanceWindow.SetFrame ()
+
+ #Load the Portraits Table
+ PortraitsTable = GemRB.LoadTable ("PICTURES")
+ PortraitsStart = PortraitsTable.FindValue (0, 2)
+ FemaleCount = PortraitsTable.GetRowCount () - PortraitsStart + 1
+ if Gender == 2:
+ LastPortrait = GemRB.Roll (1, FemaleCount, PortraitsStart-1)
+ else:
+ LastPortrait = GemRB.Roll (1, PortraitsTable.GetRowCount()-FemaleCount, 0)
+
+ PortraitButton = AppearanceWindow.GetControl (1)
+ PortraitButton.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_NO_IMAGE,OP_SET)
+ PortraitButton.SetState (IE_GUI_BUTTON_LOCKED)
+
+ LeftButton = AppearanceWindow.GetControl (2)
+ RightButton = AppearanceWindow.GetControl (3)
+
+ BackButton = AppearanceWindow.GetControl (5)
+ BackButton.SetText (15416)
+ BackButton.SetFlags (IE_GUI_BUTTON_CANCEL,OP_OR)
+
+ CustomButton = AppearanceWindow.GetControl (6)
+ CustomButton.SetText (17545)
+
+ DoneButton = AppearanceWindow.GetControl (0)
+ DoneButton.SetText (36789)
+ DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT,OP_OR)
+
+ RightButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, RightPress)
+ LeftButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, LeftPress)
+ BackButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, BackPress)
+ CustomButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CustomPress)
+ DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, NextPress)
+
+ while True:
+ if PortraitsTable.GetValue (LastPortrait, 0) == Gender:
+ SetPicture ()
+ break
+ LastPortrait = LastPortrait + 1
+ AppearanceWindow.SetVisible (WINDOW_VISIBLE)
+ return
+
+def RightPress ():
+ global LastPortrait
+ while True:
+ LastPortrait = LastPortrait + 1
+ if LastPortrait >= PortraitsTable.GetRowCount ():
+ LastPortrait = 0
+ if PortraitsTable.GetValue (LastPortrait, 0) == Gender:
+ SetPicture ()
+ return
+
+def LeftPress ():
+ global LastPortrait
+ while True:
+ LastPortrait = LastPortrait - 1
+ if LastPortrait < 0:
+ LastPortrait = PortraitsTable.GetRowCount ()-1
+ if PortraitsTable.GetValue (LastPortrait, 0) == Gender:
+ SetPicture ()
+ return
+
+def BackPress ():
+ if AppearanceWindow:
+ AppearanceWindow.Unload ()
+ GemRB.SetNextScript ("CharGen")
+ GemRB.SetVar ("Gender",0) #scrapping the gender value
+ return
+
+def CustomDone ():
+ Window = CustomWindow
+
+ Portrait = PortraitList1.QueryText ()
+ GemRB.SetToken ("SmallPortrait", Portrait)
+ Portrait = PortraitList2.QueryText ()
+ GemRB.SetToken ("LargePortrait", Portrait)
+ if Window:
+ Window.Unload ()
+ if AppearanceWindow:
+ AppearanceWindow.Unload ()
+ GemRB.SetNextScript ("CharGen2")
+ return
+
+def CustomAbort ():
+ if CustomWindow:
+ CustomWindow.Unload ()
+ return
+
+def LargeCustomPortrait ():
+ Window = CustomWindow
+
+ Portrait = PortraitList1.QueryText ()
+ #small hack
+ if GemRB.GetVar ("Row1") == RowCount1:
+ return
+
+ Label = Window.GetControl (0x10000007)
+ Label.SetText (Portrait)
+
+ Button = Window.GetControl (6)
+ if Portrait=="":
+ Portrait = "NOPORTMD"
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+ else:
+ if PortraitList2.QueryText ()!="":
+ Button.SetState (IE_GUI_BUTTON_ENABLED)
+
+ Button = Window.GetControl (0)
+ Button.SetPicture (Portrait, "NOPORTMD")
+ return
+
+def SmallCustomPortrait ():
+ Window = CustomWindow
+
+ Portrait = PortraitList2.QueryText ()
+ #small hack
+ if GemRB.GetVar ("Row2") == RowCount2:
+ return
+
+ Label = Window.GetControl (0x10000008)
+ Label.SetText (Portrait)
+
+ Button = Window.GetControl (6)
+ if Portrait=="":
+ Portrait = "NOPORTSM"
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+ else:
+ if PortraitList1.QueryText ()!="":
+ Button.SetState (IE_GUI_BUTTON_ENABLED)
+
+ Button = Window.GetControl (1)
+ Button.SetPicture (Portrait, "NOPORTSM")
+ return
+
+def CustomPress ():
+ global PortraitList1, PortraitList2
+ global RowCount1, RowCount2
+ global CustomWindow
+
+ CustomWindow = Window = GemRB.LoadWindow (18)
+ PortraitList1 = Window.GetControl (2)
+ RowCount1 = PortraitList1.GetPortraits (0)
+ PortraitList1.SetEvent (IE_GUI_TEXTAREA_ON_CHANGE, LargeCustomPortrait)
+ GemRB.SetVar ("Row1", RowCount1)
+ PortraitList1.SetVarAssoc ("Row1",RowCount1)
+
+ PortraitList2 = Window.GetControl (4)
+ RowCount2 = PortraitList2.GetPortraits (1)
+ PortraitList2.SetEvent (IE_GUI_TEXTAREA_ON_CHANGE, SmallCustomPortrait)
+ GemRB.SetVar ("Row2", RowCount2)
+ PortraitList2.SetVarAssoc ("Row2",RowCount2)
+
+ Button = Window.GetControl (6)
+ Button.SetText (11973)
+ Button.SetFlags (IE_GUI_BUTTON_DEFAULT,OP_OR)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CustomDone)
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+
+ Button = Window.GetControl (7)
+ Button.SetText (15416)
+ Button.SetFlags (IE_GUI_BUTTON_CANCEL,OP_OR)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CustomAbort)
+
+ Button = Window.GetControl (0)
+ PortraitName = PortraitsTable.GetRowName (LastPortrait)+"L"
+ Button.SetPicture (PortraitName, "NOPORTMD")
+ Button.SetState (IE_GUI_BUTTON_LOCKED)
+
+ Button = Window.GetControl (1)
+ PortraitName = PortraitsTable.GetRowName (LastPortrait)+"S"
+ Button.SetPicture (PortraitName, "NOPORTSM")
+ Button.SetState (IE_GUI_BUTTON_LOCKED)
+
+ Window.ShowModal (MODAL_SHADOW_NONE)
+ return
+
+def NextPress ():
+ if AppearanceWindow:
+ AppearanceWindow.Unload ()
+ PortraitTable = GemRB.LoadTable ("pictures")
+ PortraitName = PortraitTable.GetRowName (LastPortrait )
+ GemRB.SetToken ("SmallPortrait", PortraitName+"S")
+ GemRB.SetToken ("LargePortrait", PortraitName+"L")
+ #GemRB.SetVar ("PortraitIndex",LastPortrait)
+ GemRB.SetNextScript ("CharGen2") #Before race
+ return
diff --git a/gemrb/GUIScripts/iwd2/CMakeLists.txt b/gemrb/GUIScripts/iwd2/CMakeLists.txt
deleted file mode 100644
index b6ffcaa..0000000
--- a/gemrb/GUIScripts/iwd2/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-FILE( GLOB FILES_TO_INSTALL *.py )
-
-INSTALL( FILES ${FILES_TO_INSTALL} DESTINATION ${DATA_DIR}/GUIScripts/iwd2 )
diff --git a/gemrb/GUIScripts/iwd2/CharGen4.py b/gemrb/GUIScripts/iwd2/CharGen4.py
index a85f2ff..fc11480 100644
--- a/gemrb/GUIScripts/iwd2/CharGen4.py
+++ b/gemrb/GUIScripts/iwd2/CharGen4.py
@@ -25,7 +25,7 @@ import CharOverview
#barbarian, bard, cleric, druid, fighter, monk, paladin, ranger, rogue, sorcerer, wizard
Classes = [IE_LEVELBARBARIAN, IE_LEVELBARD, IE_LEVELCLERIC, IE_LEVELDRUID, \
IE_LEVEL, IE_LEVELMONK, IE_LEVELPALADIN, IE_LEVELRANGER, IE_LEVEL3, \
-IE_LEVELSORCEROR, IE_LEVEL2]
+IE_LEVELSORCERER, IE_LEVEL2]
def OnLoad():
MyChar = GemRB.GetVar ("Slot")
diff --git a/gemrb/GUIScripts/iwd2/CharGen6.py b/gemrb/GUIScripts/iwd2/CharGen6.py
index 3ebf8ab..568fea5 100644
--- a/gemrb/GUIScripts/iwd2/CharGen6.py
+++ b/gemrb/GUIScripts/iwd2/CharGen6.py
@@ -24,11 +24,11 @@ import CharOverview
def OnLoad():
#setting the stats so the feat code will work
MyChar = GemRB.GetVar("Slot")
- GemRB.SetPlayerStat (MyChar, IE_STR, GemRB.GetVar ("Ability 1"))
- GemRB.SetPlayerStat (MyChar, IE_DEX, GemRB.GetVar ("Ability 2"))
- GemRB.SetPlayerStat (MyChar, IE_CON, GemRB.GetVar ("Ability 3"))
- GemRB.SetPlayerStat (MyChar, IE_INT, GemRB.GetVar ("Ability 4"))
- GemRB.SetPlayerStat (MyChar, IE_WIS, GemRB.GetVar ("Ability 5"))
- GemRB.SetPlayerStat (MyChar, IE_CHR, GemRB.GetVar ("Ability 6"))
+ TmpTable = GemRB.LoadTable ("ability")
+ AbilityCount = TmpTable.GetRowCount ()
+ for i in range (AbilityCount):
+ StatID=TmpTable.GetValue (i,3,2)
+ GemRB.SetPlayerStat (MyChar, StatID, GemRB.GetVar ("Ability "+str(i) ) )
+
CharOverview.UpdateOverview(6)
return
diff --git a/gemrb/GUIScripts/iwd2/CharGen9.py b/gemrb/GUIScripts/iwd2/CharGen9.py
index d49bc60..351e298 100644
--- a/gemrb/GUIScripts/iwd2/CharGen9.py
+++ b/gemrb/GUIScripts/iwd2/CharGen9.py
@@ -8,12 +8,12 @@
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
#
#character generation (GUICG 0)
@@ -23,18 +23,21 @@ from ie_stats import *
import GUICommon
import CommonTables
import CharOverview
+import LUCommon
BioWindow = 0
+BioData = 0
+BioStrRef = 0
EditControl = 0
-AlignmentTable = 0
PortraitName = ""
def OnLoad():
CharOverview.UpdateOverview(9)
if CharOverview.CharGenWindow:
CharOverview.PersistButtons['Next'].SetState(IE_GUI_BUTTON_UNPRESSED) # Fixes button being pre-pressed
+ RevertPress()
return
-
+
def SetRaceAbilities(MyChar, racetitle):
ability = GemRB.LoadTable ("racespab")
resource = ability.GetValue (racetitle, "SPECIAL_ABILITIES_FILE")
@@ -63,6 +66,17 @@ def SetRaceResistances(MyChar, racetitle):
GemRB.SetPlayerStat (MyChar, IE_RESISTCRUSHING, resistances.GetValue ( racetitle, "BLUDGEONING") )
GemRB.SetPlayerStat (MyChar, IE_RESISTPIERCING, resistances.GetValue ( racetitle, "PIERCING") )
GemRB.SetPlayerStat (MyChar, IE_RESISTMISSILE, resistances.GetValue ( racetitle, "MISSILE") )
+
+ resistances = GemRB.LoadTable ("raceflag")
+
+ #set infravision and nondetection
+ orig = GemRB.GetPlayerStat (MyChar, IE_STATE_ID, 0)
+ GemRB.SetPlayerStat (MyChar, IE_STATE_ID, orig | resistances.GetValue( racetitle, "FLAG") )
+
+ #set base AC
+ orig = GemRB.GetPlayerStat (MyChar, IE_ARMORCLASS, 0)
+ GemRB.SetPlayerStat (MyChar, IE_ARMORCLASS, orig + resistances.GetValue( racetitle, "AC") )
+
return
def ClearPress():
@@ -73,11 +87,13 @@ def ClearPress():
return
def RevertPress():
+ global BioStrRef
BioTable = GemRB.LoadTable ("bios")
Class = GemRB.GetVar ("BaseClass")
- StrRef = BioTable.GetValue(Class,1)
- GemRB.SetToken ("BIO", GemRB.GetString(StrRef) )
- EditControl.SetText (GemRB.GetToken("BIO") )
+ BioStrRef = BioTable.GetValue(Class,1)
+ GemRB.SetToken ("BIO", GemRB.GetString(BioStrRef) )
+ if type (EditControl) != type (7350): # just some int
+ EditControl.SetText (GemRB.GetToken("BIO") )
return
def BioCancelPress():
@@ -107,11 +123,11 @@ def BioPress():
Button = Window.GetControl (1)
Button.SetText (11962)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, BioDonePress)
-
+
Button = Window.GetControl (2)
Button.SetText (36788)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, BioCancelPress)
-
+
EditControl = Window.GetControl (4)
BioData = GemRB.GetToken("BIO")
if BioData == "":
@@ -138,12 +154,21 @@ def NextPress():
Class=GemRB.GetVar ("BaseClass")
GemRB.SetPlayerStat (MyChar, IE_CLASS, Class)
#kit
- GemRB.SetPlayerStat (MyChar, IE_KIT, GemRB.GetVar ("Class") )
- AlignmentTable = GemRB.LoadTable ("aligns")
+ kitrow = GemRB.GetVar ("Class")-1
+ kit = CommonTables.Classes.GetValue(kitrow, 2)
+ GemRB.SetPlayerStat (MyChar, IE_KIT, kit )
+ if (CommonTables.Classes.GetValue(kitrow, 3) == 0):
+ #baseclass
+ clssname = CommonTables.Classes.GetRowName (Class-1)
+ else:
+ #kit
+ clssname = CommonTables.Classes.GetRowName (kitrow)
+ LUCommon.SetClassResistances( MyChar, clssname )
+
t=GemRB.GetVar ("Alignment")
- GemRB.SetPlayerStat (MyChar, IE_ALIGNMENT, AlignmentTable.GetValue (t, 3) )
+ GemRB.SetPlayerStat (MyChar, IE_ALIGNMENT, CommonTables.Aligns.GetValue (t, 3))
TmpTable=GemRB.LoadTable ("repstart")
- #t=AlignmentTable.FindValue (3,t)
+ #t=CommonTables.Aligns.FindValue (3,t)
t=TmpTable.GetValue (t,0)
GemRB.SetPlayerStat (MyChar, IE_REPUTATION, t)
TmpTable=GemRB.LoadTable ("strtgold")
@@ -152,7 +177,7 @@ def NextPress():
c = TmpTable.GetValue (Class, 2) #adjustment
d = TmpTable.GetValue (Class, 3) #external multiplier
e = TmpTable.GetValue (Class, 4) #level bonus rate
- t = GemRB.GetPlayerStat (MyChar, IE_LEVEL)
+ t = GemRB.GetPlayerStat (MyChar, IE_CLASSLEVELSUM)
if t>1:
e=e*(t-1)
else:
@@ -160,17 +185,7 @@ def NextPress():
t = GemRB.Roll(a,b,c)*d+e
GemRB.SetPlayerStat (MyChar, IE_GOLD, t)
GemRB.SetPlayerStat (MyChar, IE_HATEDRACE, GemRB.GetVar ("HatedRace") )
- TmpTable = GemRB.LoadTable ("ability")
- AbilityCount = TmpTable.GetRowCount ()
- for i in range (AbilityCount):
- StatID=TmpTable.GetValue (i,4)
- GemRB.SetPlayerStat (MyChar, StatID, GemRB.GetVar ("Ability "+str(i) ) )
-
-# TmpTable=GemRB.LoadTable ("weapprof")
-# ProfCount = TmpTable.GetRowCount ()
-# for i in range(ProfCount):
-# StatID=TmpTable.GetValue (i, 0)
-# GemRB.SetPlayerStat (MyChar, StatID, GemRB.GetVar ("Prof "+str(i) ) )
+
GUICommon.SetColorStat (MyChar, IE_HAIR_COLOR, GemRB.GetVar ("Color1") )
GUICommon.SetColorStat (MyChar, IE_SKIN_COLOR, GemRB.GetVar ("Color2") )
GUICommon.SetColorStat (MyChar, IE_MAJOR_COLOR, GemRB.GetVar ("Color4") )
@@ -179,40 +194,33 @@ def NextPress():
GUICommon.SetColorStat (MyChar, IE_LEATHER_COLOR, 0x16 )
GUICommon.SetColorStat (MyChar, IE_ARMOR_COLOR, 0x17 )
GemRB.SetPlayerStat (MyChar, IE_EA, 2 )
- Str=GemRB.GetVar ("Ability 1")
- GemRB.SetPlayerStat (MyChar, IE_STR, Str)
- if Str==18:
- GemRB.SetPlayerStat (MyChar,IE_STREXTRA,GemRB.GetVar ("StrExtra"))
- else:
- GemRB.SetPlayerStat (MyChar, IE_STREXTRA,0)
-
- GemRB.SetPlayerStat (MyChar, IE_DEX, GemRB.GetVar ("Ability 2"))
- GemRB.SetPlayerStat (MyChar, IE_CON, GemRB.GetVar ("Ability 3"))
- GemRB.SetPlayerStat (MyChar, IE_INT, GemRB.GetVar ("Ability 4"))
- GemRB.SetPlayerStat (MyChar, IE_WIS, GemRB.GetVar ("Ability 5"))
- GemRB.SetPlayerStat (MyChar, IE_CHR, GemRB.GetVar ("Ability 6"))
GemRB.SetPlayerName (MyChar, GemRB.GetToken ("CHARNAME"), 0)
- #setting skills
- TmpTable = GemRB.LoadTable ("skillsta")
- SkillCount = TmpTable.GetRowCount ()
- for i in range (SkillCount):
- StatID=TmpTable.GetValue (i, 2)
- GemRB.SetPlayerStat (MyChar, StatID, GemRB.GetVar ("Skill "+str(i) ) )
-
#setting feats
+ TmpTable = GemRB.LoadTable ("featreq")
+ FeatCount = TmpTable.GetRowCount ()
+ ProfOffset = IE_PROFICIENCYBASTARDSWORD
+ for i in range (FeatCount):
+ GemRB.SetFeat (MyChar, i, GemRB.GetVar ("Feat "+str(i) ) )
#does all the rest
LargePortrait = GemRB.GetToken ("LargePortrait")
SmallPortrait = GemRB.GetToken ("SmallPortrait")
- GemRB.FillPlayerInfo(MyChar, LargePortrait, SmallPortrait)
- GemRB.SetNextScript ("SPPartyFormation")
+ GemRB.FillPlayerInfo (MyChar, LargePortrait, SmallPortrait)
+ GemRB.SetNextScript ("SPPartyFormation")
TmpTable = GemRB.LoadTable ("strtxp")
#starting xp is race dependent
xp = TmpTable.GetValue (racename, "VALUE")
- GemRB.SetPlayerStat (MyChar, IE_XP, xp )
+ GemRB.SetPlayerStat (MyChar, IE_XP, xp )
- return
+ BioData = GemRB.GetToken("BIO")
+ if BioData == GemRB.GetString (BioStrRef):
+ NewRef = BioStrRef
+ else:
+ NewRef = GemRB.CreateString (62015+MyChar, BioData)
+ GemRB.SetPlayerString (MyChar, 63, NewRef)
+ LUCommon.ApplyFeats(MyChar)
+ return
diff --git a/gemrb/GUIScripts/iwd2/CharOverview.py b/gemrb/GUIScripts/iwd2/CharOverview.py
index eb6533a..96860aa 100644
--- a/gemrb/GUIScripts/iwd2/CharOverview.py
+++ b/gemrb/GUIScripts/iwd2/CharOverview.py
@@ -40,7 +40,7 @@ GlobalStep = 0
### Utility functions
def AddText(strref, row = False):
- if row: return TextAreaControl.Append(strref, row);
+ if row: return TextAreaControl.Append(strref, row)
return TextAreaControl.Append(strref)
### End utility functions
@@ -170,8 +170,8 @@ def UpdateOverview(CurrentStep):
AddText('[/color]')
ClassColumn = Tables[1].GetValue(GemRB.GetVar('Class') - 1, 3, 1) # Finds base class row id
- if ClassColumn < 1: ClassColumn = GemRB.GetVar('Class') - 1; # If 0 then already a base class so need actual row
- else: ClassColumn -= 1; # 'CLASS' column in classes.2da is out by 1 for some reason
+ if ClassColumn < 1: ClassColumn = GemRB.GetVar('Class') - 1 # If 0 then already a base class so need actual row
+ else: ClassColumn -= 1 # 'CLASS' column in classes.2da is out by 1 for some reason
ClassColumn += 4 # There are 4 columns before the classes in skills.2da
# At the moment only cleric kits get skill bonuses but their column names in skills.2da don't match up
# to their kit names. All classes aren't covered in skills.2da either which is why I have to resort
@@ -290,15 +290,17 @@ def BackPress():
StartOverWindow.Unload()
# Need to clear relevant variables
- if GlobalStep == 2: GemRB.SetVar('Gender', 0);
- elif GlobalStep == 3: GemRB.SetVar('Race', 0);
- elif GlobalStep == 4: GemRB.SetVar('Class', 0);
- elif GlobalStep == 5: GemRB.SetVar('Alignment', 0);
+ if GlobalStep == 2: GemRB.SetVar('Gender', 0)
+ elif GlobalStep == 3: GemRB.SetVar('Race', 0)
+ elif GlobalStep == 4: GemRB.SetVar('Class', 0)
+ elif GlobalStep == 5: GemRB.SetVar('Alignment', 0)
elif GlobalStep == 6:
- for i in range(0, 6): GemRB.SetVar('Ability ' + str(i), 0);
+ for i in range(0, 7):
+ GemRB.SetVar('Ability ' + str(i), 0)
+
elif GlobalStep == 9: GemRB.SetToken('CHARNAME', '')
ScrName = 'CharGen' + str(GlobalStep - 1)
- if GlobalStep == 2: ScrName = 'CharGen';
+ if GlobalStep == 2: ScrName = 'CharGen'
GemRB.SetNextScript(ScrName)
return
diff --git a/gemrb/GUIScripts/iwd2/CharSound.py b/gemrb/GUIScripts/iwd2/CharSound.py
deleted file mode 100644
index 3b14e9a..0000000
--- a/gemrb/GUIScripts/iwd2/CharSound.py
+++ /dev/null
@@ -1,139 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-#Character Sound Options Menu using GUIOPT
-
-import GemRB
-from GUIDefines import *
-
-CSoundWindow = 0
-TextAreaControl = 0
-
-def OnLoad():
- global CSoundWindow, TextAreaControl
-
- GemRB.LoadWindowPack("GUIOPT", 800, 600)
- CSoundWindow = GemRB.LoadWindow(12)
- CSoundWindow.SetFrame( )
- TextAreaControl = CSoundWindow.GetControl(16)
- SubtitlesButton = CSoundWindow.GetControl(20)
- AttackSoundButton = CSoundWindow.GetControl(18)
- MovementSoundButton = CSoundWindow.GetControl(19)
- CommandSoundButton = CSoundWindow.GetControl(21)
- SelectionSoundButton = CSoundWindow.GetControl(57)
- SubtitlesButtonB = CSoundWindow.GetControl(5)
- AttackSoundButtonB = CSoundWindow.GetControl(6)
- MovementSoundButtonB = CSoundWindow.GetControl(7)
- CSAlwaysButtonB = CSoundWindow.GetControl(8)
- CSSeldomButtonB = CSoundWindow.GetControl(9)
- CSNeverButtonB = CSoundWindow.GetControl(10)
- SSAlwaysButtonB = CSoundWindow.GetControl(58)
- SSSeldomButtonB = CSoundWindow.GetControl(59)
- SSNeverButtonB = CSoundWindow.GetControl(60)
- OkButton = CSoundWindow.GetControl(24)
- CancelButton = CSoundWindow.GetControl(25)
- TextAreaControl.SetText(18041)
- OkButton.SetText(11973)
- OkButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- CancelButton.SetText(13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- SubtitlesButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, SubtitlesPress)
- SubtitlesButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, SubtitlesPress)
- SubtitlesButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- SubtitlesButtonB.SetVarAssoc("Subtitles", 1)
- SubtitlesButtonB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- AttackSoundButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, AttackSoundPress)
- AttackSoundButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, AttackSoundPress)
- AttackSoundButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- AttackSoundButtonB.SetVarAssoc("Attack Sound", 1) #can't find the right variable name, this is a dummy name
- AttackSoundButtonB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- MovementSoundButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, MovementSoundPress)
- MovementSoundButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, MovementSoundPress)
- MovementSoundButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- MovementSoundButtonB.SetVarAssoc("Movement Sound", 1) #can't find the right variable name, this is a dummy name
- MovementSoundButtonB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- CommandSoundButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, CommandSoundPress)
- CSAlwaysButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, CommandSoundPress)
- CSAlwaysButtonB.SetFlags(IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- CSAlwaysButtonB.SetVarAssoc("Command Sounds Frequency", 3)
- CSAlwaysButtonB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
- CSSeldomButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, CommandSoundPress)
- CSSeldomButtonB.SetFlags(IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- CSSeldomButtonB.SetVarAssoc("Command Sounds Frequency", 2)
- CSSeldomButtonB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
- CSNeverButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, CommandSoundPress)
- CSNeverButtonB.SetFlags(IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- CSNeverButtonB.SetVarAssoc("Command Sounds Frequency", 1)
- CSNeverButtonB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- SelectionSoundButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, SelectionSoundPress)
- SSAlwaysButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, SelectionSoundPress)
- SSAlwaysButtonB.SetFlags(IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- SSAlwaysButtonB.SetVarAssoc("Selection Sounds Frequency", 3)
- SSAlwaysButtonB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
- SSSeldomButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, SelectionSoundPress)
- SSSeldomButtonB.SetFlags(IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- SSSeldomButtonB.SetVarAssoc("Selection Sounds Frequency", 2)
- SSSeldomButtonB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
- SSNeverButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, SelectionSoundPress)
- SSNeverButtonB.SetFlags(IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- SSNeverButtonB.SetVarAssoc("Selection Sounds Frequency", 1)
- SSNeverButtonB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- OkButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, OkPress)
- CancelButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, CancelPress)
- CSoundWindow.SetVisible(WINDOW_VISIBLE)
- return
-
-def SubtitlesPress():
- TextAreaControl.SetText(18015)
- return
-
-def AttackSoundPress():
- TextAreaControl.SetText(18013)
- return
-
-def MovementSoundPress():
- TextAreaControl.SetText(18014)
- return
-
-def CommandSoundPress():
- TextAreaControl.SetText(18016)
- return
-
-def SelectionSoundPress():
- TextAreaControl.SetText(11352)
- return
-
-def OkPress():
- if CSoundWindow:
- CSoundWindow.Unload()
- GemRB.SetNextScript("Options")
- return
-
-def CancelPress():
- if CSoundWindow:
- CSoundWindow.Unload()
- GemRB.SetNextScript("Options")
- return
diff --git a/gemrb/GUIScripts/iwd2/Class.py b/gemrb/GUIScripts/iwd2/Class.py
index 4eeae5c..d5ea609 100644
--- a/gemrb/GUIScripts/iwd2/Class.py
+++ b/gemrb/GUIScripts/iwd2/Class.py
@@ -19,6 +19,7 @@
#character generation, class (GUICG2)
import GemRB
from GUIDefines import *
+import GUICommon
import CommonTables
ClassWindow = 0
@@ -32,9 +33,8 @@ ClassID = 0
def AdjustTextArea():
global HasSubClass, ClassID
- Class = GemRB.GetVar("Class")-1
- TextAreaControl.SetText(CommonTables.Classes.GetValue(Class,1) )
- ClassName = CommonTables.Classes.GetRowName(Class)
+ ClassName = GUICommon.GetClassRowName (GemRB.GetVar ("Class")-1, "index")
+ TextAreaControl.SetText (CommonTables.Classes.GetValue (ClassName, "DESC_REF"))
ClassID = CommonTables.Classes.GetValue(ClassName, "ID")
#determining if this class has any subclasses
HasSubClass = 0
@@ -158,8 +158,8 @@ def ClassPress():
return
def ClassPress2():
- Class = GemRB.GetVar("Class")-1
- TextAreaControl.SetText(CommonTables.Classes.GetValue(Class,1) )
+ ClassName = GUICommon.GetClassRowName (GemRB.GetVar ("Class")-1, "index")
+ TextAreaControl.SetText (CommonTables.Classes.GetValue (ClassName, "DESC_REF"))
DoneButton.SetState(IE_GUI_BUTTON_ENABLED)
return
@@ -181,10 +181,10 @@ def BackPress():
def NextPress():
#classcolumn is base class
- Class = GemRB.GetVar("Class")
- ClassColumn = CommonTables.Classes.GetValue(Class - 1, 3)
+ ClassName = GUICommon.GetClassRowName (GemRB.GetVar ("Class")-1, "index")
+ ClassColumn = CommonTables.Classes.GetValue (ClassName, "CLASS")
if ClassColumn <= 0: #it was already a base class
- ClassColumn = Class
+ ClassColumn = GemRB.GetVar("Class")
GemRB.SetVar("BaseClass", ClassColumn)
if ClassWindow:
ClassWindow.Unload()
diff --git a/gemrb/GUIScripts/iwd2/Enemy.py b/gemrb/GUIScripts/iwd2/Enemy.py
index 5bbf9c9..f3d38ea 100644
--- a/gemrb/GUIScripts/iwd2/Enemy.py
+++ b/gemrb/GUIScripts/iwd2/Enemy.py
@@ -18,6 +18,7 @@
#
#character generation, racial enemy (GUICG15)
import GemRB
+import GUICommon
import CommonTables
from GUIDefines import *
@@ -51,9 +52,10 @@ def OnLoad():
GemRB.LoadWindowPack("GUICG", 800 ,600)
RaceWindow = GemRB.LoadWindow(15)
-
Class = GemRB.GetVar("BaseClass")
- TableName = CommonTables.ClassSkills.GetValue(Class, 0)
+ ClassName = GUICommon.GetClassRowName (Class, "index")
+ print "TODO: check if class %s really has an ID of %d" %(ClassName, Class)
+ TableName = CommonTables.ClassSkills.GetValue(ClassName, "RANGERSKILL")
if TableName == "*":
GemRB.SetNextScript("Skills")
return
diff --git a/gemrb/GUIScripts/iwd2/Feats.py b/gemrb/GUIScripts/iwd2/Feats.py
index 6b0cdf3..64c7d9e 100644
--- a/gemrb/GUIScripts/iwd2/Feats.py
+++ b/gemrb/GUIScripts/iwd2/Feats.py
@@ -20,6 +20,7 @@
import GemRB
from GUIDefines import *
from ie_stats import *
+import GUICommon
import CommonTables
FeatWindow = 0
@@ -29,7 +30,6 @@ FeatTable = 0
FeatReqTable = 0
TopIndex = 0
Level = 0
-ClassColumn = 0
KitColumn = 0
RaceColumn = 0
FeatsClassColumn = 0
@@ -188,7 +188,7 @@ def OnLoad():
global FeatWindow, TextAreaControl, DoneButton, TopIndex
global FeatTable, FeatReqTable
global KitName, Level, PointsLeft
- global ClassColumn, KitColumn, RaceColumn, FeatsClassColumn
+ global KitColumn, RaceColumn, FeatsClassColumn
GemRB.SetVar("Level",1) #for simplicity
@@ -198,15 +198,16 @@ def OnLoad():
# could use column ID as well, but they tend to change :)
RaceColumn = CommonTables.Races.GetValue(RaceName, "SKILL_COLUMN")
- Class = GemRB.GetVar("Class") - 1
- KitName = CommonTables.Classes.GetRowName(Class)
+ ClassIndex = GemRB.GetVar("Class") - 1
+ ClassName = KitName = GUICommon.GetClassRowName (ClassIndex, "index")
# classcolumn is base class or 0 if it is not a kit
- ClassColumn = CommonTables.Classes.GetValue(Class, 3) - 1
+ ClassColumn = CommonTables.Classes.GetValue(ClassName, "CLASS") - 1
if ClassColumn < 0: #it was already a base class
- ClassColumn = Class
- FeatsClassColumn = CommonTables.Classes.GetValue(Class, 2) + 2
+ ClassColumn = ClassIndex
+ # feats.2da is transposed, but has the same ordering
+ FeatsClassColumn = ClassIndex + 3 # CommonTables.Classes.GetValue (ClassName, "ID") + 2
else:
- FeatsClassColumn = CommonTables.Classes.GetValue(Class, 3) + 2
+ FeatsClassColumn = ClassColumn + 3
FeatTable = GemRB.LoadTable("feats")
RowCount = FeatTable.GetRowCount()
@@ -226,9 +227,9 @@ def OnLoad():
#this one exists only for clerics
# Although it should be made extendable to all kits
# A FEAT_COLUMN is needed in classes.2da or better yet, a whole new 2da
- if CommonTables.Classes.GetValue(Class, 3) == "CLERIC":
- ClassColumn += 3
+ if CommonTables.Classes.GetValue (ClassName, "CLASS") == CommonTables.Classes.GetValue ("CLERIC", "ID"):
if KitColumn:
+ # 3 to get to the class columns (feats.2da) and 11 to get to these cleric kit columns
KitColumn = 3 + KitColumn + 11
#Always raise one level at once
@@ -365,7 +366,7 @@ def Check_AllOfThreeGE(pl, ass, a, bs, b, cs, c, *garbage):
def Check_IsCaster(pl, *garbage):
# CLASSLEVELMAGE is IE_LEVEL2 (pst)
possible_casters = { IE_LEVEL2:1, IE_LEVELCLERIC:1, IE_LEVELDRUID:1,
- IE_LEVELSORCEROR:1, IE_LEVELPALADIN:4, IE_LEVELRANGER:4, IE_LEVELBARD:2 }
+ IE_LEVELSORCERER:1, IE_LEVELPALADIN:4, IE_LEVELRANGER:4, IE_LEVELBARD:2 }
Caster = False
for stat in possible_casters:
diff --git a/gemrb/GUIScripts/iwd2/Feedback.py b/gemrb/GUIScripts/iwd2/Feedback.py
deleted file mode 100644
index 0985fe7..0000000
--- a/gemrb/GUIScripts/iwd2/Feedback.py
+++ /dev/null
@@ -1,184 +0,0 @@
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-#
-#feedback
-import GemRB
-from GUIDefines import *
-
-FeedbackWindow = 0
-TextAreaControl = 0
-
-def OnLoad():
- global FeedbackWindow, TextAreaControl
-
- GemRB.LoadWindowPack("GUIOPT", 800, 600)
- FeedbackWindow = GemRB.LoadWindow(9)
- FeedbackWindow.SetFrame( )
-
- MarkerSlider = FeedbackWindow.GetControl(30)
- MarkerSliderS = FeedbackWindow.GetControl(8)
-
- LocatorSlider = FeedbackWindow.GetControl(31)
- LocatorSliderS = FeedbackWindow.GetControl(9)
-
- THac0Rolls = FeedbackWindow.GetControl(32)
- THac0RollsB = FeedbackWindow.GetControl(10)
- THac0RollsB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- CombatInfo = FeedbackWindow.GetControl(33)
- CombatInfoB = FeedbackWindow.GetControl(11)
- CombatInfoB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- Actions = FeedbackWindow.GetControl(34)
- ActionsB = FeedbackWindow.GetControl(12)
- ActionsB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- StateChanges = FeedbackWindow.GetControl(35)
- StateChangesB = FeedbackWindow.GetControl(13)
- StateChangesB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- SelectionText = FeedbackWindow.GetControl(36)
- SelectionTextB = FeedbackWindow.GetControl(14)
- SelectionTextB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- Miscellaneous = FeedbackWindow.GetControl(37)
- MiscellaneousB = FeedbackWindow.GetControl(15)
- MiscellaneousB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- OkButton = FeedbackWindow.GetControl(26)
- CancelButton = FeedbackWindow.GetControl(27)
- TextAreaControl = FeedbackWindow.GetControl(28)
-
- TextAreaControl.SetText(18043)
- OkButton.SetText(11973)
- OkButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- CancelButton.SetText(13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- MarkerSlider.SetEvent(IE_GUI_BUTTON_ON_PRESS, MarkerSliderPress)
- MarkerSliderS.SetEvent(IE_GUI_SLIDER_ON_CHANGE, MarkerSliderPress)
- MarkerSliderS.SetVarAssoc("GUI Feedback Level",1)
-
- LocatorSlider.SetEvent(IE_GUI_BUTTON_ON_PRESS, LocatorSliderPress)
- LocatorSliderS.SetEvent(IE_GUI_SLIDER_ON_CHANGE, LocatorSliderPress)
- LocatorSliderS.SetVarAssoc("Locator Feedback Level",1)
-
- THac0Rolls.SetEvent(IE_GUI_BUTTON_ON_PRESS, THac0RollsPress)
- THac0RollsB.SetEvent(IE_GUI_BUTTON_ON_PRESS, THac0RollsBPress)
- THac0RollsB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- THac0RollsB.SetVarAssoc("Rolls",1)
-
- CombatInfo.SetEvent(IE_GUI_BUTTON_ON_PRESS, CombatInfoPress)
- CombatInfoB.SetEvent(IE_GUI_BUTTON_ON_PRESS, CombatInfoBPress)
- CombatInfoB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- CombatInfoB.SetVarAssoc("Combat Info",1)
-
- Actions.SetEvent(IE_GUI_BUTTON_ON_PRESS, ActionsPress)
- ActionsB.SetEvent(IE_GUI_BUTTON_ON_PRESS, ActionsBPress)
- ActionsB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- ActionsB.SetVarAssoc("Actions",1)
-
- StateChanges.SetEvent(IE_GUI_BUTTON_ON_PRESS, StateChangesPress)
- StateChangesB.SetEvent(IE_GUI_BUTTON_ON_PRESS, StateChangesBPress)
- StateChangesB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- StateChangesB.SetVarAssoc("State Changes",1)
-
- SelectionText.SetEvent(IE_GUI_BUTTON_ON_PRESS, SelectionTextPress)
- SelectionTextB.SetEvent(IE_GUI_BUTTON_ON_PRESS, SelectionTextBPress)
- SelectionTextB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- SelectionTextB.SetVarAssoc("Selection Text",1)
-
- Miscellaneous.SetEvent(IE_GUI_BUTTON_ON_PRESS, MiscellaneousPress)
- MiscellaneousB.SetEvent(IE_GUI_BUTTON_ON_PRESS, MiscellaneousBPress)
- MiscellaneousB.SetFlags(IE_GUI_BUTTON_CHECKBOX, OP_OR)
- MiscellaneousB.SetVarAssoc("Miscellaneous Text",1)
-
- OkButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, OkPress)
- CancelButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, CancelPress)
- FeedbackWindow.SetVisible(WINDOW_VISIBLE)
- return
-
-def MarkerSliderPress():
- TextAreaControl.SetText(18024)
- return
-
-def LocatorSliderPress():
- TextAreaControl.SetText(18025)
- return
-
-def THac0RollsPress():
- TextAreaControl.SetText(18026)
- return
-
-def THac0RollsBPress():
- TextAreaControl.SetText(18026)
- return
-
-def CombatInfoPress():
- TextAreaControl.SetText(18027)
- return
-
-def CombatInfoBPress():
- TextAreaControl.SetText(18027)
- return
-
-def ActionsPress():
- TextAreaControl.SetText(18028)
- return
-
-def ActionsBPress():
- TextAreaControl.SetText(18028)
- return
-
-def StateChangesPress():
- TextAreaControl.SetText(18029)
- return
-
-def StateChangesBPress():
- TextAreaControl.SetText(18029)
- return
-
-def SelectionTextPress():
- TextAreaControl.SetText(18030)
- return
-
-def SelectionTextBPress():
- TextAreaControl.SetText(18030)
- return
-
-def MiscellaneousPress():
- TextAreaControl.SetText(18031)
- return
-
-def MiscellaneousBPress():
- TextAreaControl.SetText(18031)
- return
-
-def OkPress():
- if FeedbackWindow:
- FeedbackWindow.Unload()
- GemRB.SetNextScript("GamePlay")
- return
-
-def CancelPress():
- if FeedbackWindow:
- FeedbackWindow.Unload()
- GemRB.SetNextScript("GamePlay")
- return
-
diff --git a/gemrb/GUIScripts/iwd2/GUICommonWindows.py b/gemrb/GUIScripts/iwd2/GUICommonWindows.py
deleted file mode 100644
index cd40539..0000000
--- a/gemrb/GUIScripts/iwd2/GUICommonWindows.py
+++ /dev/null
@@ -1,769 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003-2004 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-# GUICommonWindows.py - functions to open common
-# windows in lower part of the screen
-###################################################
-
-import GemRB
-import GUICommon
-import CommonTables
-from GUIDefines import *
-from ie_stats import *
-from ie_modal import *
-from ie_action import *
-
-import GUIINV
-import GUIJRNL
-import GUIMA
-import GUIOPT
-import GUISPL
-import GUIREC
-import LUCommon
-import InventoryCommon
-import LoadScreen
-
-FRAME_PC_SELECTED = 0
-FRAME_PC_TARGET = 1
-
-PortraitWindow = None
-OptionsWindow = None
-DraggedPortrait = None
-
-def SetupMenuWindowControls (Window, Gears, ReturnToGame):
- """Sets up all of the basic control windows."""
-
- global OptionsWindow
-
- OptionsWindow = Window
- #Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, ReturnToGame)
-
- # Spellbook
- Button = Window.GetControl (4)
- Button.SetTooltip (16309)
- Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- Button.SetVarAssoc ("SelectedWindow", 0)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUISPL.OpenSpellBookWindow)
-
- # Inventory
- Button = Window.GetControl (5)
- Button.SetTooltip (16307)
- Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- Button.SetVarAssoc ("SelectedWindow", 1)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIINV.OpenInventoryWindow)
-
- # Journal
- Button = Window.GetControl (6)
- Button.SetTooltip (16308)
- Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- Button.SetVarAssoc ("SelectedWindow", 2)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIJRNL.OpenJournalWindow)
-
- # Map
- Button = Window.GetControl (7)
- Button.SetTooltip (16310)
- Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- Button.SetVarAssoc ("SelectedWindow", 3)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIMA.OpenMapWindow)
-
- # Records
- Button = Window.GetControl (8)
- Button.SetTooltip (16306)
- Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- Button.SetVarAssoc ("SelectedWindow", 4)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIREC.OpenRecordsWindow)
-
- # Options
- Button = Window.GetControl (9)
- Button.SetTooltip (16311)
- Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- Button.SetVarAssoc ("SelectedWindow", 7)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIOPT.OpenOptionsWindow)
-
- # Gears
- Button = Window.GetControl (10)
- Button.SetAnimation ("CGEAR")
- Button.SetFlags (IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_ANIMATED, OP_SET)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
-
- if Gears:
- # Select All
- Button = Window.GetControl (11)
- Button.SetTooltip (10485)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUICommon.SelectAllOnPress)
- # Rest
- Button = Window.GetControl (12)
- Button.SetTooltip (11942)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUICommon.RestPress)
-
- # Character Arbitration
- Button = Window.GetControl (13)
- Button.SetTooltip (16312)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, None) #TODO: CharacterWindow
- return
-
-def AIPress ():
- """Toggles the party AI."""
-
- Button = PortraitWindow.GetControl (6)
- AI = GemRB.GetMessageWindowSize () & GS_PARTYAI
-
- if AI:
- GemRB.GameSetScreenFlags (GS_PARTYAI, OP_NAND)
- Button.SetTooltip (15918)
- GemRB.SetVar ("AI", 0)
- else:
- GemRB.GameSetScreenFlags (GS_PARTYAI, OP_OR)
- Button.SetTooltip (15917)
- GemRB.SetVar ("AI", GS_PARTYAI)
- return
-
-def EmptyControls ():
- global PortraitWindow
-
- Window = PortraitWindow
- for i in range (12):
- Button = Window.GetControl (i+6)
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- Button.SetPicture ("")
- Button.SetText ("")
- Button.SetActionIcon (globals(), -1)
- return
-
-def SelectFormationPreset ():
- """Choose the default formation."""
- GemRB.GameSetFormation (GemRB.GetVar ("Value"), GemRB.GetVar ("Formation") )
- GroupControls ()
- return
-
-def SetupFormation ():
- global PortraitWindow
-
- Window = PortraitWindow
- for i in range (12):
- Button = Window.GetControl (i+6)
- Button.SetFlags (IE_GUI_BUTTON_NORMAL, OP_SET)
- Button.SetSprites ("GUIBTBUT",0,0,1,2,3)
- Button.SetBAM ("FORM%x"%i,0,0,-1)
- Button.SetVarAssoc ("Value", i)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SelectFormationPreset)
- return
-
-def GroupControls ():
- global PortraitWindow
-
- Window = PortraitWindow
- Button = Window.GetControl (6)
- Button.SetActionIcon (globals(), 7)
- Button = Window.GetControl (7)
- Button.SetActionIcon (globals(), 15)
- Button = Window.GetControl (8)
- Button.SetActionIcon (globals(), 21)
- Button = Window.GetControl (9)
- Button.SetActionIcon (globals(), -1)
- Button = Window.GetControl (10)
- Button.SetActionIcon (globals(), -1)
- Button = Window.GetControl (11)
- Button.SetActionIcon (globals(), -1)
- Button = Window.GetControl (12)
- Button.SetActionIcon (globals(), -1)
- GemRB.SetVar ("Formation", GemRB.GameGetFormation ())
- for i in range (5):
- Button = Window.GetControl (13+i)
- Button.SetState (IE_GUI_BUTTON_ENABLED)
- idx = GemRB.GameGetFormation (i)
- Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON|IE_GUI_BUTTON_NORMAL, OP_SET)
- Button.SetSprites ("GUIBTBUT",0,0,1,2,3)
- Button.SetBAM ("FORM%x"%idx,0,0,-1)
- Button.SetVarAssoc ("Formation", i)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUICommon.SelectFormation)
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, SetupFormation)
- str = GemRB.GetString (4935)
- Button.SetTooltip ("F%d - %s"%(8+i,str) )
- return
-
-def UpdateActionsWindow ():
- global PortraitWindow
- global level, TopIndex
-
- if PortraitWindow == -1:
- return
-
- if PortraitWindow == None:
- return
-
- #do this only when there is no 'otherwindow'
- if GemRB.GetVar ("OtherWindow") != -1:
- return
-
- Selected = GemRB.GetSelectedSize()
- if Selected == 0:
- EmptyControls ()
- return
- if Selected > 1:
- GroupControls ()
- return
-
- #we are sure there is only one actor selected
- pc = GemRB.GameGetFirstSelectedActor ()
-
- level = GemRB.GetVar ("ActionLevel")
- TopIndex = GemRB.GetVar ("TopIndex")
- if level == 0:
- PortraitWindow.SetupControls (globals(), pc, 6, 1)
- elif level == 1:
- PortraitWindow.SetupEquipmentIcons (globals(), pc, TopIndex, 6, 1)
- elif level == 2: #spells
- GemRB.SetVar ("Type", 3)
- PortraitWindow.SetupSpellIcons (globals(), pc, 3, TopIndex, 6, 1)
- elif level == 3: #innates
- GemRB.SetVar ("Type", 4)
- PortraitWindow.SetupSpellIcons (globals(), pc, 4, TopIndex, 6, 1)
- return
-
-def ActionQWeaponPressed (which):
- """Selects the given quickslot weapon if possible."""
- global PortraitWindow
-
- pc = GemRB.GameGetFirstSelectedActor ()
- qs = GemRB.GetEquippedQuickSlot (pc, 1, 1)
-
- #38 is the magic slot
- if ((qs==which) or (qs==38)) and GemRB.GameControlGetTargetMode() != TARGET_MODE_ATTACK:
- GemRB.GameControlSetTargetMode (TARGET_MODE_ATTACK, GA_NO_DEAD|GA_NO_SELF|GA_NO_HIDDEN)
- else:
- GemRB.GameControlSetTargetMode (TARGET_MODE_NONE)
- GemRB.SetEquippedQuickSlot (pc, which, -1, 1)
-
- PortraitWindow.SetupControls (globals(), pc, 6)
- UpdateActionsWindow ()
- return
-
-def ActionQWeapon1Pressed ():
- ActionQWeaponPressed (0)
-
-def ActionQWeapon2Pressed ():
- ActionQWeaponPressed (1)
-
-def ActionQWeapon3Pressed ():
- ActionQWeaponPressed (2)
-
-def ActionQWeapon4Pressed ():
- ActionQWeaponPressed (3)
-
-#no check needed because the button wouldn't be drawn if illegal
-def ActionLeftPressed ():
- """Scrolls the actions window left.
-
- Used primarily for spell selection."""
-
- TopIndex = GemRB.GetVar ("TopIndex")
- if TopIndex>10:
- TopIndex -= 10
- else:
- TopIndex = 0
- GemRB.SetVar ("TopIndex", TopIndex)
- UpdateActionsWindow ()
- return
-
-#no check needed because the button wouldn't be drawn if illegal
-def ActionRightPressed ():
- """Scrolls the action window right.
-
- Used primarily for spell selection."""
-
- pc = GemRB.GameGetFirstSelectedActor ()
- TopIndex = GemRB.GetVar ("TopIndex")
- Type = GemRB.GetVar ("Type")
- #Type is a bitfield if there is no level given
- #This is to make sure cleric/mages get all spells listed
- Max = GemRB.GetMemorizedSpellsCount(pc, Type, -1, 1)
- TopIndex += 10
- if TopIndex > Max - 10:
- if Max>10:
- TopIndex = Max-10
- else:
- TopIndex = 0
-
- GemRB.SetVar ("TopIndex", TopIndex)
- UpdateActionsWindow ()
- return
-
-def ActionBardSongPressed ():
- """Toggles the battle song."""
- pc = GemRB.GameGetFirstSelectedActor ()
- GemRB.SetModalState (pc, MS_BATTLESONG, 1)
- GemRB.PlaySound ("act_01")
- UpdateActionsWindow ()
- return
-
-def ActionSearchPressed ():
- """Toggles detect traps."""
- pc = GemRB.GameGetFirstSelectedActor ()
- GemRB.SetModalState (pc, MS_DETECTTRAPS, 1)
- UpdateActionsWindow ()
- return
-
-def ActionStealthPressed ():
- """Toggles stealth."""
- pc = GemRB.GameGetFirstSelectedActor ()
- GemRB.SetModalState (pc, MS_STEALTH, 1)
- GemRB.PlaySound ("act_07")
- UpdateActionsWindow ()
- return
-
-def ActionTurnPressed ():
- """Toggles turn undead."""
- pc = GemRB.GameGetFirstSelectedActor ()
- GemRB.SetModalState (pc, MS_TURNUNDEAD, 1)
- GemRB.PlaySound ("act_06")
- UpdateActionsWindow ()
- return
-
-def ActionUseItemPressed ():
- GemRB.SetVar ("TopIndex", 0)
- GemRB.SetVar ("ActionLevel", 1)
- UpdateActionsWindow ()
- return
-
-def ActionCastPressed ():
- """Opens the spell choice scrollbar."""
- GemRB.SetVar ("TopIndex", 0)
- GemRB.SetVar ("ActionLevel", 2)
- UpdateActionsWindow ()
- return
-
-def ActionQItemPressed (action):
- """Uses the given quick item."""
- pc = GemRB.GameGetFirstSelectedActor ()
- #quick slot
- GemRB.UseItem (pc, -2, action, -1, 1)
- return
-
-def ActionQItem1Pressed ():
- ActionQItemPressed (ACT_QSLOT1)
- return
-
-def ActionQItem2Pressed ():
- ActionQItemPressed (ACT_QSLOT2)
- return
-
-def ActionQItem3Pressed ():
- ActionQItemPressed (ACT_QSLOT3)
- return
-
-def ActionQItem4Pressed ():
- ActionQItemPressed (ACT_QSLOT4)
- return
-
-def ActionQItem5Pressed ():
- ActionQItemPressed (ACT_QSLOT5)
- return
-
-def ActionInnatePressed ():
- GemRB.SetVar ("TopIndex", 0)
- GemRB.SetVar ("ActionLevel", 3)
- UpdateActionsWindow ()
- return
-
-def ActionSkillsPressed ():
- GemRB.SetVar ("TopIndex", 0)
- GemRB.SetVar ("ActionLevel", 4)
- UpdateActionsWindow ()
- return
-
-def SpellPressed ():
- """Prepares a spell to be cast."""
-
- pc = GemRB.GameGetFirstSelectedActor ()
-
- GemRB.GameControlSetTargetMode (TARGET_MODE_CAST)
- Spell = GemRB.GetVar ("Spell")
- Type = GemRB.GetVar ("Type")
- GemRB.SpellCast (pc, Type, Spell, 1)
- GemRB.SetVar ("ActionLevel", 0)
- UpdateActionsWindow ()
- return
-
-def EquipmentPressed ():
- pc = GemRB.GameGetFirstSelectedActor ()
-
- GemRB.GameControlSetTargetMode (TARGET_MODE_CAST)
- Item = GemRB.GetVar ("Equipment")
- #equipment index
- GemRB.UseItem (pc, -1, Item, -1, 1)
- GemRB.SetVar ("ActionLevel", 0)
- UpdateActionsWindow ()
- return
-
-def GetActorRaceTitle (actor):
- RaceID = GemRB.GetPlayerStat (actor, IE_SUBRACE)
- if RaceID:
- RaceID += GemRB.GetPlayerStat (actor, IE_RACE)<<16
- else:
- RaceID = GemRB.GetPlayerStat (actor, IE_RACE)
- row = CommonTables.Races.FindValue (3, RaceID )
- RaceTitle = CommonTables.Races.GetValue (row, 2)
- return RaceTitle
-
-# NOTE: this function is called with the primary classes
-def GetKitIndex (actor, ClassIndex):
- Kit = GemRB.GetPlayerStat (actor, IE_KIT)
-
- KitIndex = -1
- ClassID = CommonTables.Classes.GetValue (ClassIndex, 2)
- # skip the primary classes
- for ci in range (10, CommonTables.Classes.GetRowCount ()):
- BaseClass = CommonTables.Classes.GetValue (ci, 3)
- if BaseClass == ClassID and Kit & CommonTables.Classes.GetValue (ci, 2):
- KitIndex = ci
-
- if KitIndex == -1:
- return 0
-
- return KitIndex
-
-def GetActorClassTitle (actor, ClassIndex):
- ClassTitle = GemRB.GetPlayerStat (actor, IE_TITLE1)
- if ClassTitle:
- return ClassTitle
-
- #Class = GemRB.GetPlayerStat (actor, IE_CLASS)
- KitIndex = GetKitIndex (actor, ClassIndex)
- if KitIndex == 0:
- ClassTitle = CommonTables.Classes.GetValue (ClassIndex, 0)
- else:
- ClassTitle = CommonTables.Classes.GetValue (KitIndex, 0)
-
- if ClassTitle == "*":
- return 0
- return ClassTitle
-
-# overriding the one in GUICommon, since we use a different table and animations
-def GetActorPaperDoll (actor):
- PortraitTable = GemRB.LoadTable ("avatars")
- anim_id = GemRB.GetPlayerStat (actor, IE_ANIMATION_ID)
- level = GemRB.GetPlayerStat (actor, IE_ARMOR_TYPE)
- row = "0x%04X" %anim_id
- which = "AT_%d" %(level+1)
- return PortraitTable.GetValue (row, which)
-
-
-SelectionChangeHandler = None
-
-def SetSelectionChangeHandler (handler):
- """Updates the selection handler."""
-
- global SelectionChangeHandler
-
- # Switching from walking to non-walking environment:
- # set the first selected PC in walking env as a selected
- # in nonwalking env
- #if (not SelectionChangeHandler) and handler:
- if (not SelectionChangeHandler) and handler and (not GUICommon.NextWindowFn):
- sel = GemRB.GameGetFirstSelectedPC ()
- if not sel:
- sel = 1
- GemRB.GameSelectPCSingle (sel)
-
- SelectionChangeHandler = handler
-
- # redraw selection on change main selection | single selection
- SelectionChanged ()
- return
-
-def RunSelectionChangeHandler ():
- if SelectionChangeHandler:
- SelectionChangeHandler ()
- return
-
-def OpenPortraitWindow ():
- global PortraitWindow
-
- PortraitWindow = Window = GemRB.LoadWindow (1)
-
- for i in range (PARTY_SIZE):
- Button = Window.GetControl (i)
- Button.SetFont ("STATES2")
- Button.SetVarAssoc ("PressedPortrait", i+1)
-
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, PortraitButtonOnPress)
- Button.SetEvent (IE_GUI_BUTTON_ON_SHIFT_PRESS, PortraitButtonOnShiftPress)
- Button.SetEvent (IE_GUI_BUTTON_ON_DRAG_DROP, InventoryCommon.OnDropItemToPC)
- Button.SetEvent (IE_GUI_BUTTON_ON_DRAG_DROP_PORTRAIT, OnDropPortraitToPC)
- Button.SetEvent (IE_GUI_BUTTON_ON_DRAG, PortraitButtonOnDrag)
- Button.SetEvent (IE_GUI_MOUSE_ENTER_BUTTON, PortraitButtonOnMouseEnter)
- Button.SetEvent (IE_GUI_MOUSE_LEAVE_BUTTON, PortraitButtonOnMouseLeave)
-
- Button.SetFlags (IE_GUI_BUTTON_ALIGN_TOP|IE_GUI_BUTTON_ALIGN_LEFT|IE_GUI_BUTTON_PICTURE, OP_SET)
-
- Button.SetBorder (FRAME_PC_SELECTED, 1, 1, 2, 2, 0, 255, 0, 255)
- Button.SetBorder (FRAME_PC_TARGET, 3, 3, 4, 4, 255, 255, 0, 255)
-
- UpdatePortraitWindow ()
- SelectionChanged ()
- return Window
-
-def UpdatePortraitWindow ():
- """Updates all of the portraits."""
-
- Window = PortraitWindow
-
- pc = GemRB.GameGetSelectedPCSingle ()
- Inventory = GemRB.GetVar ("Inventory")
-
- for portid in range (PARTY_SIZE):
- Button = Window.GetControl (portid)
- pic = GemRB.GetPlayerPortrait (portid+1, 1)
- if Inventory and pc != portid+1:
- pic = None
-
- if not pic:
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- Button.SetText ("")
- Button.SetTooltip ("")
- continue
-
- Button.SetFlags (IE_GUI_BUTTON_PICTURE| \
- IE_GUI_BUTTON_ALIGN_BOTTOM| \
- IE_GUI_BUTTON_ALIGN_LEFT| \
- IE_GUI_BUTTON_HORIZONTAL| \
- IE_GUI_BUTTON_DRAGGABLE, OP_SET)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- Button.SetPicture (pic, "NOPORTSM")
- GUICommon.SetupDamageInfo (portid+1, Button)
-
- #add effects on the portrait
- effects = GemRB.GetPlayerStates (portid+1)
- states = ""
- for col in range(len(effects)):
- states = effects[col:col+1] + states
- if col % 3 == 2: states = "\n" + states
- for x in range(3 - (len(effects)/3)):
- states = "\n" + states
- states = "\n" + states
-
- # blank space
- flag = blank = chr(238)
-
- # shopping icon
- if pc==portid+1:
- if GemRB.GetStore()!=None:
- flag = chr(155)
- # talk icon
- if GemRB.GameGetSelectedPCSingle(1)==portid+1:
- flag = chr(154)
-
- if LUCommon.CanLevelUp (portid+1):
- states = flag+blank+chr(255) + states
- else:
- states = flag+blank+blank + states
- Button.SetText(states)
- return
-
-def PortraitButtonOnDrag ():
- global DraggedPortrait
-
- #they start from 1
- DraggedPortrait = GemRB.GetVar ("PressedPortrait")
- GemRB.DragItem (DraggedPortrait, -1, "")
- return
-
-def PortraitButtonOnPress ():
- """Selects the portrait individually."""
-
- i = GemRB.GetVar ("PressedPortrait")
-
- if not i:
- return
-
- if GemRB.GameControlGetTargetMode() != TARGET_MODE_NONE:
- GemRB.ActOnPC (i)
- return
-
- if (not SelectionChangeHandler):
- if GemRB.GameIsPCSelected (i):
- GemRB.GameControlSetScreenFlags (SF_CENTERONACTOR, OP_OR)
- GemRB.GameSelectPC (i, True, SELECT_REPLACE)
- else:
- GemRB.GameSelectPCSingle (i)
- SelectionChanged ()
- RunSelectionChangeHandler ()
- return
-
-def PortraitButtonOnShiftPress ():
- """Handles selecting multiple portaits with shift."""
-
- i = GemRB.GetVar ("PressedPortrait")
-
- if not i:
- return
-
- if (not SelectionChangeHandler):
- sel = GemRB.GameIsPCSelected (i)
- sel = not sel
- GemRB.GameSelectPC (i, sel)
- else:
- GemRB.GameSelectPCSingle (i)
- SelectionChanged ()
- RunSelectionChangeHandler ()
- return
-
-def SelectionChanged ():
- """Ran by the Game class when a PC selection is changed."""
-
- global PortraitWindow
-
- if not PortraitWindow:
- return
-
- GemRB.SetVar ("ActionLevel", 0)
- if (not SelectionChangeHandler):
- UpdateActionsWindow ()
- for i in range (PARTY_SIZE):
- Button = PortraitWindow.GetControl (i)
- Button.EnableBorder (FRAME_PC_SELECTED, GemRB.GameIsPCSelected (i + 1))
- else:
- sel = GemRB.GameGetSelectedPCSingle ()
-
- for i in range (PARTY_SIZE):
- Button = PortraitWindow.GetControl (i)
- Button.EnableBorder (FRAME_PC_SELECTED, i + 1 == sel)
- import CommonWindow
- CommonWindow.CloseContainerWindow()
- return
-
-def PortraitButtonOnMouseEnter ():
- global DraggedPortrait
-
- i = GemRB.GetVar ("PressedPortrait")
-
- if not i:
- return
-
- GemRB.GameControlSetLastActor( i )
- if GemRB.IsDraggingItem()==2:
- if DraggedPortrait != None:
- GemRB.SwapPCs (DraggedPortrait, i)
- GemRB.SetVar ("PressedPortrait", DraggedPortrait)
- DraggedPortrait = i
- GemRB.SetTimedEvent (CheckDragging, 1)
- else:
- OnDropPortraitToPC()
- return
-
- if GemRB.IsDraggingItem ():
- Button = PortraitWindow.GetControl (i-1)
- Button.EnableBorder (FRAME_PC_TARGET, 1)
- return
-
-def OnDropPortraitToPC ():
- GemRB.SetVar ("PressedPortrait",0)
- GemRB.DragItem (0, -1, "")
- DraggedPortrait = None
- return
-
-def CheckDragging():
- """Contains portrait dragging in case of mouse out-of-range."""
-
- global DraggedPortrait
-
- i = GemRB.GetVar ("PressedPortrait")
- if not i:
- GemRB.DragItem (0, -1, "")
-
- if GemRB.IsDraggingItem()!=2:
- DraggedPortrait = None
- return
-
-def PortraitButtonOnMouseLeave ():
- i = GemRB.GetVar ("PressedPortrait")
- if not i:
- return
-
- Button = PortraitWindow.GetControl (i-1)
- Button.EnableBorder (FRAME_PC_TARGET, 0)
- GemRB.SetVar ("PressedPortrait", 0)
- GemRB.SetTimedEvent (CheckDragging, 1)
- return
-
-def ActionStopPressed ():
- for i in GemRB.GetSelectedActors():
- GemRB.ClearActions (i, 1)
- return
-
-def ActionTalkPressed ():
- GemRB.GameControlSetTargetMode (TARGET_MODE_TALK,GA_NO_DEAD|GA_NO_ENEMY|GA_NO_HIDDEN)
-
-def ActionAttackPressed ():
- GemRB.GameControlSetTargetMode (TARGET_MODE_ATTACK,GA_NO_DEAD|GA_NO_SELF|GA_NO_HIDDEN)
-
-def ActionDefendPressed ():
- GemRB.GameControlSetTargetMode (TARGET_MODE_DEFEND,GA_NO_SELF|GA_NO_ENEMY|GA_NO_HIDDEN)
-
-def ActionThievingPressed ():
- GemRB.GameControlSetTargetMode (TARGET_MODE_PICK, GA_NO_DEAD|GA_NO_SELF|GA_NO_ENEMY|GA_NO_HIDDEN)
-
-def OpenWaitForDiscWindow ():
- global DiscWindow
-
- if DiscWindow:
- GemRB.HideGUI ()
- if DiscWindow:
- DiscWindow.Unload ()
- GemRB.SetVar ("OtherWindow", -1)
- # ...LoadWindowPack()
- EnableAnimatedWindows ()
- DiscWindow = None
- GemRB.UnhideGUI ()
- return
-
- try:
- GemRB.HideGUI ()
- except:
- pass
-
- GemRB.LoadWindowPack ("GUIID")
- DiscWindow = Window = GemRB.LoadWindow (0)
- GemRB.SetVar ("OtherWindow", Window.ID)
- label = DiscWindow.GetControl (0)
-
- disc_num = GemRB.GetVar ("WaitForDisc")
- #disc_path = GemRB.GetVar ("WaitForDiscPath")
- disc_path = 'XX:'
-
- text = GemRB.GetString (31483) + " " + str (disc_num) + " " + GemRB.GetString (31569) + " " + disc_path + "\n" + GemRB.GetString (49152)
- label.SetText (text)
- DisableAnimatedWindows ()
- # 31483 - Please place PS:T disc number
- # 31568 - Please place the PS:T DVD
- # 31569 - in drive
- # 31570 - Wrong disc in drive
- # 31571 - There is no disc in drive
- # 31578 - No disc could be found in drive. Please place Disc 1 in drive.
- # 49152 - To quit the game, press Alt-F4
-
- try:
- GemRB.UnhideGUI ()
- except:
- DiscWindow.SetVisible (WINDOW_VISIBLE)
-
-def CheckLevelUp(pc):
- GemRB.SetVar ("CheckLevelUp"+str(pc), LUCommon.CanLevelUp (pc))
diff --git a/gemrb/GUIScripts/iwd2/GUIINV.py b/gemrb/GUIScripts/iwd2/GUIINV.py
index 296201c..306752a 100644
--- a/gemrb/GUIScripts/iwd2/GUIINV.py
+++ b/gemrb/GUIScripts/iwd2/GUIINV.py
@@ -37,6 +37,12 @@ OptionsWindow = None
OldPortraitWindow = None
OldOptionsWindow = None
+def OpenInventoryWindowClick ():
+ tmp = GemRB.GetVar ("PressedPortrait")
+ GemRB.GameSelectPC (tmp, True, SELECT_REPLACE)
+ OpenInventoryWindow ()
+ return
+
def OpenInventoryWindow ():
global InventoryWindow, OptionsWindow, PortraitWindow
global OldPortraitWindow, OldOptionsWindow
@@ -160,15 +166,28 @@ def OpenInventoryWindow ():
Button.SetEvent (IE_GUI_MOUSE_LEAVE_BUTTON, InventoryCommon.MouseLeaveSlot)
Button.SetVarAssoc ("ItemButton", slot+1)
Button.SetFont ("NUMFONT")
- Button.SetFlags (IE_GUI_BUTTON_ALIGN_RIGHT | IE_GUI_BUTTON_ALIGN_BOTTOM | IE_GUI_BUTTON_PICTURE, OP_OR)
GemRB.SetVar ("TopIndex", 0)
+
+ for i in range (4):
+ Button = Window.GetControl (109+i)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, ChangeWeaponPressed)
+ Button.SetVarAssoc("Equipped", i)
+ Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
+ #Why they mess up .chu's i don't know
+ Button.SetSprites("INVBUT3", i, 0, 1, 2, 3)
GUICommonWindows.SetSelectionChangeHandler (UpdateInventoryWindow)
UpdateInventoryWindow ()
return
+def ChangeWeaponPressed ():
+ pc = GemRB.GameGetSelectedPCSingle ()
+ Equipped = GemRB.GetVar ("Equipped")
+ GemRB.SetEquippedQuickSlot (pc, Equipped, -1)
+ return
+
#complete update
def UpdateInventoryWindow ():
Window = InventoryWindow
@@ -180,6 +199,11 @@ def UpdateInventoryWindow ():
if Count<1:
Count=1
ScrollBar.SetVarAssoc ("TopIndex", Count)
+ Equipped = GemRB.GetEquippedQuickSlot (pc, 1)
+ GemRB.SetVar ("Equipped", Equipped)
+ for i in range (4):
+ Button = Window.GetControl (109+i)
+ Button.SetVarAssoc("Equipped", i)
RefreshInventoryWindow ()
# populate inventory slot controls
SlotCount = GemRB.GetSlotType (-1)["Count"]
@@ -262,7 +286,7 @@ def RefreshInventoryWindow ():
Button = Window.GetControl (i+76)
if GemRB.IsDraggingItem ()==1:
- Button.SetState (IE_GUI_BUTTON_SECOND)
+ Button.SetState (IE_GUI_BUTTON_FAKEPRESSED)
else:
Button.SetState (IE_GUI_BUTTON_ENABLED)
Button.SetEvent (IE_GUI_BUTTON_ON_DRAG_DROP, InventoryCommon.OnDragItemGround)
@@ -280,11 +304,7 @@ def RefreshInventoryWindow ():
GUICommon.UpdateInventorySlot (pc, Button, Slot, "ground")
#if actor is uncontrollable, make this grayed
- held = GemRB.GetPlayerStat (pc, IE_HELD) + GemRB.GetPlayerStat (pc, IE_CASTERHOLD)
- if held or GemRB.GetPlayerStat (pc, IE_STATE_ID) & STATE_DEAD:
- Window.SetVisible (WINDOW_GRAYED)
- else:
- Window.SetVisible (WINDOW_VISIBLE)
+ GUICommon.AdjustWindowVisibility (Window, pc, False)
PortraitWindow.SetVisible (WINDOW_VISIBLE)
OptionsWindow.SetVisible (WINDOW_VISIBLE)
return
diff --git a/gemrb/GUIScripts/iwd2/GUIMA.py b/gemrb/GUIScripts/iwd2/GUIMA.py
index 55fc4c5..c47693b 100644
--- a/gemrb/GUIScripts/iwd2/GUIMA.py
+++ b/gemrb/GUIScripts/iwd2/GUIMA.py
@@ -299,12 +299,17 @@ def MoveToNewArea ():
global WorldMapWindow, WorldMapControl
tmp = WorldMapControl.GetDestinationArea (1)
- if tmp["Distance"]==-1:
+ CloseWorldMapWindow ()
+
+ if tmp["Destination"].lower() == GemRB.GetGameString(STR_AREANAME).lower():
+ return
+ elif tmp["Distance"] == -1:
print "Invalid target", tmp
return
- CloseWorldMapWindow ()
GemRB.CreateMovement (tmp["Destination"], tmp["Entrance"], tmp["Direction"])
+ # distance is stored in hours, but the action needs seconds
+ GemRB.ExecuteString ("AdvanceTime(%d)"%(tmp["Distance"]*300))
return
def ChangeTooltip ():
@@ -312,7 +317,7 @@ def ChangeTooltip ():
global str
tmp = WorldMapControl.GetDestinationArea ()
- if (tmp):
+ if tmp and tmp["Distance"] >= 0:
str = "%s: %d"%(GemRB.GetString(23084),tmp["Distance"])
else:
str=""
@@ -380,6 +385,7 @@ def WorldMapWindowCommon (Travel):
else:
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenMapWindow)
Window.SetVisible (WINDOW_VISIBLE)
+ WorldMapControl.SetStatus (IE_GUI_CONTROL_FOCUSED)
###################################################
# End of file GUIMA.py
diff --git a/gemrb/GUIScripts/iwd2/GUIOPT.py b/gemrb/GUIScripts/iwd2/GUIOPT.py
deleted file mode 100644
index 45f8f9c..0000000
--- a/gemrb/GUIScripts/iwd2/GUIOPT.py
+++ /dev/null
@@ -1,778 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-# GUIOPT.py - scripts to control options windows mostly from GUIOPT winpack
-# Ingame options
-
-###################################################
-import GemRB
-import GUICommon
-import GUICommonWindows
-import GUISAVE
-from GUIDefines import *
-
-###################################################
-GameOptionsWindow = None
-VideoOptionsWindow = None
-AudioOptionsWindow = None
-GameplayOptionsWindow = None
-FeedbackOptionsWindow = None
-AutopauseOptionsWindow = None
-LoadMsgWindow = None
-SaveMsgWindow = None
-QuitMsgWindow = None
-MovieWindow = None
-KeysWindow = None
-OptionsWindow = None
-PortraitWindow = None
-OldPortraitWindow = None
-OldOptionsWindow = None
-
-###################################################
-def CloseOptionsWindow ():
- global GameOptionsWindow, OptionsWindow, PortraitWindow
- global OldPortraitWindow, OldOptionsWindow
-
- if GameOptionsWindow == None:
- return
-
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- if OptionsWindow:
- OptionsWindow.Unload ()
- if PortraitWindow:
- PortraitWindow.Unload ()
-
- GameOptionsWindow = None
- GemRB.SetVar ("OtherWindow", -1)
- GUICommon.GameWindow.SetVisible(WINDOW_VISIBLE)
- GemRB.UnhideGUI ()
- GUICommonWindows.OptionsWindow = OldOptionsWindow
- OldOptionsWindow = None
- GUICommonWindows.PortraitWindow = OldPortraitWindow
- OldPortraitWindow = None
- return
-
-###################################################
-def OpenOptionsWindow ():
- global GameOptionsWindow, OptionsWindow, PortraitWindow
- global OldPortraitWindow, OldOptionsWindow
-
- if GUICommon.CloseOtherWindow (OpenOptionsWindow):
- CloseOptionsWindow ()
- return
-
- GemRB.HideGUI ()
- GUICommon.GameWindow.SetVisible(WINDOW_INVISIBLE)
-
- GemRB.LoadWindowPack ("GUIOPT", 800, 600)
- GameOptionsWindow = Window = GemRB.LoadWindow (2)
- GemRB.SetVar ("OtherWindow", GameOptionsWindow.ID)
- #saving the original portrait window
- OldPortraitWindow = GUICommonWindows.PortraitWindow
- PortraitWindow = GUICommonWindows.OpenPortraitWindow ()
- OldOptionsWindow = GUICommonWindows.OptionsWindow
- OptionsWindow = GemRB.LoadWindow (0)
- GUICommonWindows.SetupMenuWindowControls (OptionsWindow, 0, OpenOptionsWindow)
- Window.SetFrame ()
-
- LoadButton = Window.GetControl (5)
- SaveButton = Window.GetControl (6)
- QuitButton = Window.GetControl (10)
- GraphicsButton = Window.GetControl (7)
- SoundButton = Window.GetControl (8)
- GamePlayButton = Window.GetControl (9)
- MoviesButton = Window.GetControl (14)
- KeyboardButton = Window.GetControl (13)
- ReturnButton = Window.GetControl (11)
-
- LoadButton.SetText (13729)
- LoadButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenLoadMsgWindow)
- SaveButton.SetText (13730)
- SaveButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenSaveMsgWindow)
- QuitButton.SetText (13731)
- QuitButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenQuitMsgWindow)
- GraphicsButton.SetText (17162)
- GraphicsButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenVideoOptionsWindow)
- SoundButton.SetText (17164)
- SoundButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenAudioOptionsWindow)
- GamePlayButton.SetText (17165)
- GamePlayButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenGameplayOptionsWindow)
- MoviesButton.SetText (15415)
- MoviesButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenMovieWindow)
- KeyboardButton.SetText (33468)
- KeyboardButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, None) #TODO: OpenKeyboardWindow
- ReturnButton.SetText (10308)
- ReturnButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenOptionsWindow)
- ReturnButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- VersionLabel = Window.GetControl (0x1000000B)
- VersionLabel.SetText (GEMRB_VERSION)
-
- Window.SetVisible (WINDOW_VISIBLE)
- OptionsWindow.SetVisible (WINDOW_VISIBLE)
- PortraitWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def CloseVideoOptionsWindow ():
- OpenOptionsWindow ()
- OpenOptionsWindow ()
-
-def OpenVideoOptionsWindow ():
- """Open video options window"""
- global GameOptionsWindow, HelpTextArea
-
- if GameOptionsWindow:
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
-
- GameOptionsWindow = Window = GemRB.LoadWindow (6)
-
- HelpTextArea = OptHelpText ('VideoOptions', Window, 33, 18038)
-
- OptDone ('VideoOptions', Window, 21)
- OptCancel ('VideoOptions', Window, 32)
-
- OptSlider ('Brightness', Window, 3, 'Brightness Correction', 4)
- OptSlider ('Contrast', Window, 22, 'Gamma Correction', 1)
-
- OptRadio ('BPP', Window, 5, 37, 'BitsPerPixel', 16)
- OptRadio ('BPP', Window, 6, 37, 'BitsPerPixel', 24)
- OptRadio ('BPP', Window, 7, 37, 'BitsPerPixel', 32)
- OptCheckbox ('FullScreen', Window, 9, 38, 'Full Screen', 1)
-
- OptCheckbox ('TransShadow', Window, 51, 50, 'Translucent Shadows', 1)
- OptCheckbox ('SoftMirrBlt', Window, 40, 44, 'SoftMirrorBlt' ,1)
- OptCheckbox ('SoftTransBlt', Window, 41, 46, 'SoftSrcKeyBlt' ,1)
- OptCheckbox ('SoftStandBlt', Window, 42, 48, 'SoftBltFast' ,1)
-
- GameOptionsWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DisplayHelpFullScreen ():
- HelpTextArea.SetText (18000)
- GemRB.SetFullScreen (GemRB.GetVar("Full Screen"))
-
-def DisplayHelpBPP ():
- HelpTextArea.SetText (17205)
-
-def DisplayHelpBrightness ():
- HelpTextArea.SetText (17203)
- GemRB.SetGamma (GemRB.GetVar("Brightness Correction"),GemRB.GetVar("Gamma Correction")/2)
- return
-
-def DisplayHelpContrast ():
- HelpTextArea.SetText (17204)
- GemRB.SetGamma (GemRB.GetVar("Brightness Correction"),GemRB.GetVar("Gamma Correction")/2)
- return
-
-def DisplayHelpSoftMirrBlt ():
- HelpTextArea.SetText (18004)
-
-def DisplayHelpSoftTransBlt ():
- HelpTextArea.SetText (18006)
-
-def DisplayHelpSoftStandBlt ():
- HelpTextArea.SetText (18007)
-
-def DisplayHelpTransShadow ():
- HelpTextArea.SetText (20620)
-
-
-###################################################
-
-def CloseAudioOptionsWindow ():
- OpenOptionsWindow ()
- OpenOptionsWindow ()
-
-def OpenAudioOptionsWindow ():
- """Open audio options window"""
- global GameOptionsWindow, HelpTextArea
-
- if GameOptionsWindow:
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
-
- GameOptionsWindow = Window = GemRB.LoadWindow (7)
-
- HelpTextArea = OptHelpText ('AudioOptions', Window, 14, 18040)
-
- OptDone ('AudioOptions', Window, 24)
- OptCancel ('AudioOptions', Window, 25)
- OptButton ('CharacterSounds', Window, 13, 17778)
-
- OptSlider ('AmbientVolume', Window, 1, 'Volume Ambients', 10)
- OptSlider ('SoundFXVolume', Window, 2, 'Volume SFX', 10)
- OptSlider ('VoiceVolume', Window, 3, 'Volume Voices', 10)
- OptSlider ('MusicVolume', Window, 4, 'Volume Music', 10)
- OptSlider ('MovieVolume', Window, 22, 'Volume Movie', 10)
-
- OptCheckbox ('CreativeEAX', Window, 26, 28, 'Environmental Audio', 1)
- GameOptionsWindow.ShowModal (MODAL_SHADOW_GRAY)
-
-
-def DisplayHelpAmbientVolume ():
- HelpTextArea.SetText (18008)
- GemRB.UpdateAmbientsVolume()
-
-def DisplayHelpSoundFXVolume ():
- HelpTextArea.SetText (18009)
-
-def DisplayHelpVoiceVolume ():
- HelpTextArea.SetText (18010)
-
-def DisplayHelpMusicVolume ():
- HelpTextArea.SetText (18011)
- GemRB.UpdateMusicVolume()
-
-def DisplayHelpMovieVolume ():
- HelpTextArea.SetText (18012)
-
-def DisplayHelpCreativeEAX ():
- HelpTextArea.SetText (18022)
-
-
-###################################################
-
-def CloseGameplayOptionsWindow ():
- OpenOptionsWindow ()
- OpenOptionsWindow ()
-
-def OpenGameplayOptionsWindow ():
- """Open gameplay options window"""
- global GameOptionsWindow, HelpTextArea
-
- if GameOptionsWindow:
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
-
- #gameplayoptions
- GameOptionsWindow = Window = GemRB.LoadWindow (8)
-
-
- HelpTextArea = OptHelpText ('GameplayOptions', Window, 40, 18042)
-
- OptDone ('GameplayOptions', Window, 7)
- OptCancel ('GameplayOptions', Window, 20)
-
- OptSlider ('TooltipDelay', Window, 1, 'Tooltips', TOOLTIP_DELAY_FACTOR)
- OptSlider ('MouseScrollingSpeed', Window, 2, 'Mouse Scroll Speed', 5)
- OptSlider ('KeyboardScrollingSpeed', Window, 3, 'Keyboard Scroll Speed', 5)
- OptSlider ('Difficulty', Window, 12, 'Difficulty Level', 0)
-
- OptCheckbox ('DitherAlways', Window, 14, 25, 'Always Dither', 1)
- OptCheckbox ('Gore', Window, 19, 27, 'Gore', 1)
- OptCheckbox ('Infravision', Window, 42, 44, 'Infravision', 1)
- OptCheckbox ('Weather', Window, 47, 46, 'Weather', 1)
- OptCheckbox ('MaxHitpoints', Window, 50, 49, 'Maximum HP', 1)
-
- OptButton ('FeedbackOptions', Window, 5, 17163)
- OptButton ('AutopauseOptions', Window, 6, 17166)
-
- GameOptionsWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DisplayHelpTooltipDelay ():
- HelpTextArea.SetText (18017)
- GemRB.SetTooltipDelay (GemRB.GetVar ("Tooltips") )
-
-def DisplayHelpMouseScrollingSpeed ():
- HelpTextArea.SetText (18018)
- GemRB.SetMouseScrollSpeed (GemRB.GetVar ("Mouse Scroll Speed") )
-
-def DisplayHelpKeyboardScrollingSpeed ():
- HelpTextArea.SetText (18019)
-
-def DisplayHelpDifficulty ():
- HelpTextArea.SetText (18020)
-
-def DisplayHelpDitherAlways ():
- HelpTextArea.SetText (18021)
-
-def DisplayHelpGore ():
- HelpTextArea.SetText (18023)
-
-def DisplayHelpInfravision ():
- HelpTextArea.SetText (11797)
-
-def DisplayHelpWeather ():
- HelpTextArea.SetText (20619)
-
-def DisplayHelpRestUntilHealed ():
- HelpTextArea.SetText (2242)
-
-def DisplayMaxHitpoints ():
- HelpTextArea.SetText (15136)
-
-###################################################
-
-def CloseFeedbackOptionsWindow ():
- global GameOptionsWindow
-
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
- OpenGameplayOptionsWindow ()
-
-
-def OpenFeedbackOptionsWindow ():
- """Open feedback options window"""
- global GameOptionsWindow, HelpTextArea
-
- if GameOptionsWindow:
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
-
- #feedback
- GameOptionsWindow = Window = GemRB.LoadWindow (9)
-
- HelpTextArea = OptHelpText ('FeedbackOptions', Window, 28, 18043)
-
- OptDone ('FeedbackOptions', Window, 26)
- OptCancel ('FeedbackOptions', Window, 27)
-
- OptSlider ('MarkerFeedback', Window, 8, 'GUI Feedback Level', 1)
- OptSlider ('LocatorFeedback', Window, 9, 'Locator Feedback Level', 1)
-
- OptCheckbox ('ToHitRolls', Window, 10, 32, 'Rolls', 1)
- OptCheckbox ('CombatInfo', Window, 11, 33, 'Combat Info', 1)
- OptCheckbox ('Actions', Window, 12, 34, 'Actions', 1)
- OptCheckbox ('States', Window, 13, 35, 'State Changes', 1)
- OptCheckbox ('Selection', Window, 14, 36, 'Selection Text', 1)
- OptCheckbox ('Miscellaneous', Window, 15, 37, 'Miscellaneous Text', 1)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DisplayHelpMarkerFeedback ():
- HelpTextArea.SetText (18024)
-
-def DisplayHelpLocatorFeedback ():
- HelpTextArea.SetText (18025)
-
-def DisplayHelpToHitRolls ():
- HelpTextArea.SetText (18026)
-
-def DisplayHelpCombatInfo ():
- HelpTextArea.SetText (18027)
-
-def DisplayHelpActions ():
- HelpTextArea.SetText (18028)
-
-def DisplayHelpStates ():
- HelpTextArea.SetText (18029)
-
-def DisplayHelpSelection ():
- HelpTextArea.SetText (18030)
-
-def DisplayHelpMiscellaneous ():
- HelpTextArea.SetText (18031)
-
-
-###################################################
-
-def CloseAutopauseOptionsWindow ():
- global GameOptionsWindow
-
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
- OpenGameplayOptionsWindow ()
- return
-
-def OpenAutopauseOptionsWindow ():
- """Open autopause options window"""
- global GameOptionsWindow, HelpTextArea
-
- if GameOptionsWindow:
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
-
- GameOptionsWindow = Window = GemRB.LoadWindow (10)
-
- HelpTextArea = OptHelpText ('AutopauseOptions', Window, 15, 18044)
-
- OptDone ('AutopauseOptions', Window, 11)
- OptCancel ('AutopauseOptions', Window, 14)
-
- OptCheckbox ('CharacterHit', Window, 1, 17, 'Auto Pause State', 1)
- OptCheckbox ('CharacterInjured', Window, 2, 18, 'Auto Pause State', 2)
- OptCheckbox ('CharacterDead', Window, 3, 19, 'Auto Pause State', 4)
- OptCheckbox ('CharacterAttacked', Window, 4, 20, 'Auto Pause State', 8)
- OptCheckbox ('WeaponUnusable', Window, 5, 21, 'Auto Pause State', 16)
- OptCheckbox ('TargetGone', Window, 13, 22, 'Auto Pause State', 32)
- OptCheckbox ('EndOfRound', Window, 25, 24, 'Auto Pause State', 64)
- OptCheckbox ('EnemySighted', Window, 26, 27, 'Auto Pause State', 128)
- OptCheckbox ('SpellCast', Window, 34, 30, 'Auto Pause State', 256)
- OptCheckbox ('TrapFound', Window, 31, 33, 'Auto Pause State', 512)
- OptCheckbox ('CenterOnActor', Window, 31, 33, 'Auto Pause Center', 1)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DisplayHelpCharacterHit ():
- HelpTextArea.SetText (18032)
-
-def DisplayHelpCharacterInjured ():
- HelpTextArea.SetText (18033)
-
-def DisplayHelpCharacterDead ():
- HelpTextArea.SetText (18034)
-
-def DisplayHelpCharacterAttacked ():
- HelpTextArea.SetText (18035)
-
-def DisplayHelpWeaponUnusable ():
- HelpTextArea.SetText (18036)
-
-def DisplayHelpTargetGone ():
- HelpTextArea.SetText (18037)
-
-def DisplayHelpEndOfRound ():
- HelpTextArea.SetText (10640)
-
-def DisplayHelpEnemySighted ():
- HelpTextArea.SetText (23514)
-
-def DisplayHelpSpellCast ():
- HelpTextArea.SetText (58171)
-
-def DisplayHelpTrapFound ():
- HelpTextArea.SetText (31872)
-
-def DisplayHelpCenterOnActor ():
- HelpTextArea.SetText (10571)
-
-###################################################
-
-def CloseCharacterSoundsWindow ():
- global GameOptionsWindow
-
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
- OpenGameplayOptionsWindow ()
- return
-
-def OpenCharacterSoundsWindow ():
- """Open character sounds window"""
- global GameOptionsWindow, HelpTextArea
-
- if GameOptionsWindow:
- if GameOptionsWindow:
- GameOptionsWindow.Unload ()
- GameOptionsWindow = None
-
- GameOptionsWindow = Window = GemRB.LoadWindow (12)
-
- HelpTextArea = OptHelpText ('CharacterSounds', Window, 16, 18041)
-
- OptDone ('CharacterSounds', Window, 24)
- OptCancel ('CharacterSounds', Window, 25)
-
- OptCheckbox ('Subtitles', Window, 5, 20, 'Subtitles', 1)
- OptCheckbox ('AttackSounds', Window, 6, 18, 'Attack Sounds', 1)
- OptCheckbox ('Footsteps', Window, 7, 19, 'Footsteps', 1)
- OptRadio ('CommandSounds', Window, 8, 21, 'Command Sounds Frequency', 1)
- OptRadio ('CommandSounds', Window, 9, 21, 'Command Sounds Frequency', 2)
- OptRadio ('CommandSounds', Window, 10, 21, 'Command Sounds Frequency', 3)
- OptRadio ('SelectionSounds', Window, 58, 57, 'Selection Sounds Frequency', 1)
- OptRadio ('SelectionSounds', Window, 59, 57, 'Selection Sounds Frequency', 2)
- OptRadio ('SelectionSounds', Window, 60, 57, 'Selection Sounds Frequency', 3)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
-
-def DisplayHelpSubtitles ():
- HelpTextArea.SetText (18015)
-
-def DisplayHelpAttackSounds ():
- HelpTextArea.SetText (18013)
-
-def DisplayHelpFootsteps ():
- HelpTextArea.SetText (18014)
-
-def DisplayHelpCommandSounds ():
- HelpTextArea.SetText (18016)
-
-def DisplayHelpSelectionSounds ():
- HelpTextArea.SetText (11352)
-
-def DisplayHelpMaxHitpoints ():
- #TODO
- return
-
-###################################################
-
-def CloseMovieWindow ():
- if MovieWindow:
- MovieWindow.Unload ()
- return
-
-def MoviePlayPress():
- s = GemRB.GetVar("MovieIndex")
- for i in range(0, MoviesTable.GetRowCount() ):
- t = MoviesTable.GetRowName(i)
- if GemRB.GetVar(t)==1:
- if s==0:
- s = MoviesTable.GetRowName(i)
- GemRB.PlayMovie(s, 1)
- MovieWindow.Invalidate()
- return
- s = s - 1
- return
-
-def MovieCreditsPress():
- GemRB.PlayMovie("CREDITS")
- MovieWindow.Invalidate()
- return
-
-def OpenMovieWindow ():
- global MovieWindow, TextAreaControl, MoviesTable
-
- GemRB.LoadWindowPack("GUIMOVIE", 800, 600)
- MovieWindow = Window = GemRB.LoadWindow(2)
- Window.SetFrame ()
- #reloading the guiopt windowpack
- GemRB.LoadWindowPack ("GUIOPT", 800, 600)
- TextAreaControl = Window.GetControl(0)
- TextAreaControl.SetFlags(IE_GUI_TEXTAREA_SELECTABLE)
- PlayButton = Window.GetControl(2)
- CreditsButton = Window.GetControl(3)
- DoneButton = Window.GetControl(4)
- MoviesTable = GemRB.LoadTable("MOVIDESC")
- for i in range(0, MoviesTable.GetRowCount() ):
- t = MoviesTable.GetRowName(i)
- if GemRB.GetVar(t)==1:
- s = MoviesTable.GetValue(i, 0)
- TextAreaControl.Append(s,-1)
- TextAreaControl.SetVarAssoc("MovieIndex",0)
- PlayButton.SetText(17318)
- CreditsButton.SetText(15591)
- DoneButton.SetText(11973)
- PlayButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, MoviePlayPress)
- CreditsButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, MovieCreditsPress)
- DoneButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, CloseMovieWindow)
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-###################################################
-
-def OpenSaveMsgWindow ():
- GemRB.SetVar("QuitAfterSave",0)
- GUISAVE.OpenSaveWindow ()
- #save the game without quitting
- return
-
-###################################################
-
-def OpenLoadMsgWindow ():
- global LoadMsgWindow
-
- if LoadMsgWindow:
- return
-
- LoadMsgWindow = Window = GemRB.LoadWindow (4)
-
- # Load
- Button = Window.GetControl (0)
- Button.SetText (15590)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, LoadGamePress)
- Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- # Cancel
- Button = Window.GetControl (1)
- Button.SetText (13727)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseLoadMsgWindow)
- Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- # Loading a game will destroy ...
- Text = Window.GetControl (3)
- Text.SetText (19531)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def CloseLoadMsgWindow ():
- global LoadMsgWindow
-
- if LoadMsgWindow:
- LoadMsgWindow.Unload ()
- LoadMsgWindow = None
- GameOptionsWindow.SetVisible (WINDOW_VISIBLE)
- OptionsWindow.SetVisible (WINDOW_VISIBLE)
- PortraitWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def LoadGamePress ():
- global LoadMsgWindow
-
- if LoadMsgWindow:
- LoadMsgWindow.Unload ()
- LoadMsgWindow = None
- GemRB.QuitGame ()
- OpenOptionsWindow()
- GemRB.SetNextScript ("GUILOAD")
- return
-
-#save game AND quit
-def SaveGamePress ():
- global QuitMsgWindow
-
- if QuitMsgWindow:
- QuitMsgWindow.Unload ()
- QuitMsgWindow = None
- #we need to set a state: quit after save
- GemRB.SetVar("QuitAfterSave",1)
- OpenOptionsWindow()
- GUISAVE.OpenSaveWindow ()
- return
-
-def QuitGamePress ():
- global QuitMsgWindow
-
- if QuitMsgWindow:
- QuitMsgWindow.Unload ()
- QuitMsgWindow = None
- GemRB.QuitGame ()
- OpenOptionsWindow()
- GemRB.SetNextScript ("Start")
- return
-
-###################################################
-
-def OpenQuitMsgWindow ():
- global QuitMsgWindow
-
- if QuitMsgWindow:
- return
-
- QuitMsgWindow = Window = GemRB.LoadWindow (5)
-
- # Save
- Button = Window.GetControl (0)
- Button.SetText (15589)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SaveGamePress)
-
- # Quit Game
- Button = Window.GetControl (1)
- Button.SetText (15417)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, QuitGamePress)
-
- # Cancel
- Button = Window.GetControl (2)
- Button.SetText (13727)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseQuitMsgWindow)
-
- # The game has not been saved ....
- Text = Window.GetControl (3)
- Text.SetText (16456)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def CloseQuitMsgWindow ():
- global QuitMsgWindow
-
- if QuitMsgWindow:
- QuitMsgWindow.Unload ()
- QuitMsgWindow = None
- GameOptionsWindow.SetVisible (WINDOW_VISIBLE)
- OptionsWindow.SetVisible (WINDOW_VISIBLE)
- PortraitWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-###################################################
-###################################################
-
-# These functions help to setup controls found
-# in Video, Audio, Gameplay, Feedback and Autopause
-# options windows
-
-# These controls are usually made from an active
-# control (button, slider ...) and a label
-
-
-def OptSlider (name, window, slider_id, variable, value):
- """Standard slider for option windows"""
- slider = window.GetControl (slider_id)
- slider.SetVarAssoc (variable, value)
- slider.SetEvent (IE_GUI_SLIDER_ON_CHANGE, eval("DisplayHelp" + name))
- return slider
-
-def OptRadio (name, window, button_id, label_id, variable, value):
- """Standard radio button for option windows"""
-
- button = window.GetControl (button_id)
- button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
- button.SetEvent (IE_GUI_BUTTON_ON_PRESS, eval("DisplayHelp" + name))
- button.SetVarAssoc (variable, value)
- button.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- label = window.GetControl (label_id)
- label.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- label.SetState (IE_GUI_BUTTON_LOCKED)
-
- return button
-
-def OptCheckbox (name, window, button_id, label_id, variable, value):
- """Standard checkbox for option windows"""
-
- button = window.GetControl (button_id)
- button.SetFlags (IE_GUI_BUTTON_CHECKBOX, OP_OR)
- button.SetEvent (IE_GUI_BUTTON_ON_PRESS, eval("DisplayHelp" + name))
- button.SetVarAssoc (variable, value)
- button.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- label = window.GetControl (label_id)
- label.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- label.SetState (IE_GUI_BUTTON_LOCKED)
-
- return button
-
-def OptButton (name, window, button_id, label_strref):
- """Standard subwindow button for option windows"""
- button = window.GetControl (button_id)
- button.SetEvent (IE_GUI_BUTTON_ON_PRESS, eval("Open%sWindow" %name))
- button.SetText (label_strref)
-
-def OptDone (name, window, button_id):
- """Standard `Done' button for option windows"""
- button = window.GetControl (button_id)
- button.SetText (11973) # Done
- button.SetEvent (IE_GUI_BUTTON_ON_PRESS, eval("Close%sWindow" %name))
-
-def OptCancel (name, window, button_id):
- """Standard `Cancel' button for option windows"""
- button = window.GetControl (button_id)
- button.SetText (13727) # Cancel
- button.SetEvent (IE_GUI_BUTTON_ON_PRESS, eval("Close%sWindow" %name))
-
-def OptHelpText (name, window, text_id, text_strref):
- """Standard textarea with context help for option windows"""
- text = window.GetControl (text_id)
- text.SetText (text_strref)
- return text
-
-###################################################
-# End of file GUIOPT.py
diff --git a/gemrb/GUIScripts/iwd2/GUIREC.py b/gemrb/GUIScripts/iwd2/GUIREC.py
index f0bb1a1..040c478 100644
--- a/gemrb/GUIScripts/iwd2/GUIREC.py
+++ b/gemrb/GUIScripts/iwd2/GUIREC.py
@@ -26,9 +26,11 @@ import GemRB
import GUICommon
import CommonTables
import GUICommonWindows
+import GUIRECCommon
from GUIDefines import *
from ie_stats import *
from ie_restype import *
+from ie_feats import FEAT_WEAPON_FINESSE, FEAT_ARMORED_ARCANA
SelectWindow = 0
Topic = None
@@ -39,21 +41,30 @@ RecordsTextArea = None
ItemInfoWindow = None
ItemAmountWindow = None
ItemIdentifyWindow = None
+InformationWindow = None
PortraitWindow = None
-OldPortraitWindow = None
OptionsWindow = None
+OldPortraitWindow = None
OldOptionsWindow = None
-OldVoiceSet = None
+BonusSpellTable = None
+HateRaceTable = None
+
+#barbarian, bard, cleric, druid, fighter, monk, paladin, ranger, rogue, sorcerer, wizard
+Classes = [IE_LEVELBARBARIAN, IE_LEVELBARD, IE_LEVELCLERIC, IE_LEVELDRUID, \
+IE_LEVEL, IE_LEVELMONK, IE_LEVELPALADIN, IE_LEVELRANGER, IE_LEVEL3, \
+IE_LEVELSORCERER, IE_LEVEL2]
-# the available sounds
-SoundSequence = [ '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', \
- '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', \
- '25', '26', '27', '28', '29', '30', '31']
-SoundIndex = 0
+#don't allow exporting polymorphed or dead characters
+def Exportable(pc):
+ if not (GemRB.GetPlayerStat (pc, IE_MC_FLAGS)&MC_EXPORTABLE): return False
+ if GemRB.GetPlayerStat (pc, IE_POLYMORPHED): return False
+ if GemRB.GetPlayerStat (pc, IE_STATE_ID)&STATE_DEAD: return False
+ return True
def OpenRecordsWindow ():
global RecordsWindow, OptionsWindow, PortraitWindow
global OldPortraitWindow, OldOptionsWindow, SelectWindow
+ global BonusSpellTable, HateRaceTable
if GUICommon.CloseOtherWindow (OpenRecordsWindow):
if RecordsWindow:
@@ -88,6 +99,11 @@ def OpenRecordsWindow ():
GUICommonWindows.SetupMenuWindowControls (OptionsWindow, 0, OpenRecordsWindow)
Window.SetFrame ()
+ if not BonusSpellTable:
+ BonusSpellTable = GemRB.LoadTable ("mxsplbon")
+ if not HateRaceTable:
+ HateRaceTable = GemRB.LoadTable ("haterace")
+
#portrait icon
Button = Window.GetControl (2)
Button.SetState (IE_GUI_BUTTON_LOCKED)
@@ -101,17 +117,17 @@ def OpenRecordsWindow ():
#biography
Button = Window.GetControl (59)
Button.SetText (18003)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenBiographyWindow)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIRECCommon.OpenBiographyWindow)
#export
Button = Window.GetControl (36)
Button.SetText (13956)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenExportWindow)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIRECCommon.OpenExportWindow)
#customize
Button = Window.GetControl (50)
Button.SetText (10645)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenCustomizeWindow)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIRECCommon.OpenCustomizeWindow)
#general
GemRB.SetVar ("SelectWindow", 1)
@@ -169,8 +185,45 @@ def ColorDiff2 (Window, Label, diff):
Label.SetTextColor (255, 255, 255)
return
-def HasBonusSpells (pc):
- return False
+def GetBonusSpells (pc):
+ bonusSpells = {}
+ classes = []
+ # cheack each class/kit
+ for i in range(11):
+ level = GemRB.GetPlayerStat (pc, Classes[i])
+ if not level:
+ continue
+
+ ClassTitle = GUICommonWindows.GetActorClassTitle (pc, i)
+ # find the casting stat
+ ClassName = GUICommon.GetClassRowName (i, "index")
+ Stat = CommonTables.ClassSkills.GetValue (ClassName, "CASTING")
+ if Stat == "*":
+ continue
+ Stat = GemRB.GetPlayerStat (pc, Stat)
+ if Stat < 12: # boni start with positive modifiers
+ continue
+
+ # get max spell level we can cast, since only usable boni are displayed
+ # check the relevant mxspl* table
+ SpellTable = CommonTables.ClassSkills.GetValue (ClassName, "CLERICSPELL")
+ if SpellTable == "*":
+ SpellTable = CommonTables.ClassSkills.GetValue (ClassName, "MAGESPELL")
+ SpellTable = GemRB.LoadTable (SpellTable)
+ maxLevel = 0
+ for i in range(SpellTable.GetColumnCount()):
+ spells = SpellTable.GetValue (str(level), str(i+1)) # not all tables start at 1, so use a named lookup
+ if not spells:
+ break
+ maxLevel = i+1
+
+ classes.append(ClassTitle)
+ # check if at casting stat size, there is any bonus spell in BonusSpellTable
+ bonusSpells[ClassTitle] = [0] * maxLevel
+ for level in range (1, maxLevel+1):
+ bonusSpells[ClassTitle][level-1] = BonusSpellTable.GetValue (Stat-12, level-1)
+
+ return bonusSpells, classes
def HasClassFeatures (pc):
#clerics turning
@@ -182,8 +235,27 @@ def HasClassFeatures (pc):
#paladins healing
if GemRB.GetPlayerStat(pc, IE_LAYONHANDSAMOUNT):
return True
+ # wisdom ac bonus, wholeness of body
+ if GemRB.GetPlayerStat (pc, IE_LEVELMONK):
+ return True
return False
+def DisplayFavouredEnemy (pc, RangerLevel, second=-1):
+ RaceID = 0
+ if second == -1:
+ RaceID = GemRB.GetPlayerStat(pc, IE_HATEDRACE)
+ else:
+ RaceID = GemRB.GetPlayerStat(pc, IE_HATEDRACE2+second)
+ if RaceID:
+ FavouredIndex = HateRaceTable.FindValue (1, RaceID)
+ if FavouredIndex == -1:
+ return
+ FavouredName = HateRaceTable.GetValue (FavouredIndex, 0)
+ if second == -1:
+ RecordsTextArea.Append (delimited_txt(FavouredName, ":", PlusMinusStat((RangerLevel+4)/5)))
+ else:
+ RecordsTextArea.Append (delimited_txt(FavouredName, ":", PlusMinusStat((RangerLevel+4)/5-second-1)))
+
def GetFavoredClass (pc, code):
if GemRB.GetPlayerStat (pc, IE_SEX)==1:
code = code&15
@@ -192,23 +264,73 @@ def GetFavoredClass (pc, code):
return code-1
-def GetAbilityBonus (pc, stat):
- Ability = GemRB.GetPlayerStat (pc, stat)
- return Ability//2-5
+# returns the race or subrace
+def GetRace (pc):
+ Race = GemRB.GetPlayerStat (pc, IE_RACE)
+ Subrace = GemRB.GetPlayerStat (pc, IE_SUBRACE)
+ if Subrace:
+ Race = Race<<16 | Subrace
+ return CommonTables.Races.FindValue (3, Race)
+
+# returns the effective character level modifier
+def GetECL (pc):
+ RaceIndex = GetRace (pc)
+ RaceRowName = CommonTables.Races.GetRowName (RaceIndex)
+ return CommonTables.Races.GetValue (RaceRowName, "ECL")
#class is ignored
-def GetNextLevelExp (Level, Adjustment):
+def GetNextLevelExp (Level, Adjustment, string=0):
if Adjustment>5:
Adjustment = 5
if (Level < CommonTables.NextLevel.GetColumnCount (4) - 5):
- return str(CommonTables.NextLevel.GetValue (4, Level + Adjustment ) )
+ if string:
+ return str(CommonTables.NextLevel.GetValue (4, Level + Adjustment))
+ return CommonTables.NextLevel.GetValue (4, Level + Adjustment )
- return GemRB.GetString(24342) #godhood
+ if string:
+ return GemRB.GetString(24342) #godhood
+ return 0
-#barbarian, bard, cleric, druid, fighter, monk, paladin, ranger, rogue, sorcerer, wizard
-Classes = [IE_LEVELBARBARIAN, IE_LEVELBARD, IE_LEVELCLERIC, IE_LEVELDRUID, \
-IE_LEVEL, IE_LEVELMONK, IE_LEVELPALADIN, IE_LEVELRANGER, IE_LEVEL3, \
-IE_LEVELSORCEROR, IE_LEVEL2]
+def DisplayCommon (pc):
+ Window = RecordsWindow
+
+ Value = GemRB.GetPlayerStat(pc,IE_RACE)
+ Value2 = GemRB.GetPlayerStat(pc,IE_SUBRACE)
+ if Value2:
+ Value = Value<<16 | Value2
+ tmp = CommonTables.Races.FindValue (3, Value)
+ Race = CommonTables.Races.GetValue (tmp, 2)
+ Label = Window.GetControl (0x1000000f)
+ Label.SetText (Race)
+
+ Button = Window.GetControl (36)
+ if Exportable (pc):
+ Button.SetState (IE_GUI_BUTTON_ENABLED)
+ else:
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+ return
+
+def DisplaySavingThrows (pc):
+ RecordsTextArea.Append ("\n\n[color=ffff00]")
+ RecordsTextArea.Append (17379)
+ RecordsTextArea.Append ("[/color]\n")
+
+ tmp = GemRB.GetPlayerStat (pc, IE_SAVEFORTITUDE)
+ RecordsTextArea.Append (delimited_txt(17380, ":", PlusMinusStat(tmp)))
+
+ tmp = GemRB.GetPlayerStat (pc, IE_SAVEREFLEX)
+ RecordsTextArea.Append (delimited_txt(17381, ":", PlusMinusStat(tmp)))
+
+ tmp = GemRB.GetPlayerStat (pc, IE_SAVEWILL)
+ RecordsTextArea.Append (delimited_txt(17382, ":", PlusMinusStat(tmp), 0))
+
+# screenshots at http:// lparchive.org/Icewind-Dale-2/Update%2013/
+def GNZS(pc, s1, st, force=False):
+ value = GemRB.GetPlayerStat (pc, st)
+ if value or force:
+ RecordsTextArea.Append (s1, -1)
+ RecordsTextArea.Append (": "+ str(value) )
+ return
def DisplayGeneral (pc):
Window = RecordsWindow
@@ -219,8 +341,8 @@ def DisplayGeneral (pc):
RecordsTextArea.Append (" - ")
RecordsTextArea.Append (40309)
levelsum = GemRB.GetPlayerStat (pc, IE_CLASSLEVELSUM)
- #TODO: get special level penalty for subrace
- adj = 0
+ # get special level penalty for subrace
+ adj = GetECL (pc)
RecordsTextArea.Append (": "+str(levelsum) )
RecordsTextArea.Append ("[/color]")
#the class name for highest
@@ -245,26 +367,18 @@ def DisplayGeneral (pc):
#favoured class
RecordsTextArea.Append (40310,-1)
- AlignTable = GemRB.LoadTable("aligns")
#get the subrace value
- Value = GemRB.GetPlayerStat(pc,IE_RACE)
- Value2 = GemRB.GetPlayerStat(pc,IE_SUBRACE)
- if Value2:
- Value = Value<<16 | Value2
- tmp = CommonTables.Races.FindValue (3, Value)
- Race = CommonTables.Races.GetValue (tmp, 2)
- tmp = CommonTables.Races.GetValue (tmp, 8)
-
- Label = Window.GetControl (0x1000000f)
- Label.SetText (Race)
+ RaceIndex = GetRace (pc)
+ Race = CommonTables.Races.GetValue (RaceIndex, 2)
+ tmp = CommonTables.Races.GetValue (RaceIndex, 8)
if tmp == -1:
tmp = highest
else:
tmp = GetFavoredClass(pc, tmp)
- tmp = CommonTables.Classes.GetValue (tmp, 0)
+ tmp = CommonTables.Classes.GetValue (CommonTables.Classes.GetRowName(tmp), "NAME_REF")
RecordsTextArea.Append (": ")
RecordsTextArea.Append (tmp)
@@ -275,9 +389,9 @@ def DisplayGeneral (pc):
RecordsTextArea.Append (36928,-1)
xp = GemRB.GetPlayerStat (pc, IE_XP)
- RecordsTextArea.Append (": "+str(xp) )
+ RecordsTextArea.Append (str(xp))
RecordsTextArea.Append (17091,-1)
- tmp = GetNextLevelExp (levelsum, adj)
+ tmp = GetNextLevelExp (levelsum, adj, 1)
RecordsTextArea.Append (": "+tmp )
#current effects
@@ -285,13 +399,15 @@ def DisplayGeneral (pc):
if len(effects):
RecordsTextArea.Append ("\n\n[color=ffff00]")
RecordsTextArea.Append (32052)
- RecordsTextArea.Append ("[/color][capital=2]")
+ RecordsTextArea.Append ("[/color]")
StateTable = GemRB.LoadTable ("statdesc")
for c in effects:
- tmp = StateTable.GetValue (ord(c)-66, 0)
- RecordsTextArea.Append (c+" ", -1)
+ tmp = StateTable.GetValue (str(ord(c)-66), "DESCRIPTION")
+ RecordsTextArea.Append ("[capital=2]"+c+" ", -1)
RecordsTextArea.Append (tmp)
+ # TODO: Active Feats (eg. Power attack 4)
+
#race
RecordsTextArea.Append ("\n\n[capital=0][color=ffff00]")
RecordsTextArea.Append (1048)
@@ -303,78 +419,308 @@ def DisplayGeneral (pc):
RecordsTextArea.Append ("\n\n[color=ffff00]")
RecordsTextArea.Append (1049)
RecordsTextArea.Append ("[/color]")
- tmp = AlignTable.FindValue ( 3, GemRB.GetPlayerStat (pc, IE_ALIGNMENT) )
- Align = AlignTable.GetValue (tmp, 2)
+ tmp = CommonTables.Aligns.FindValue (3, GemRB.GetPlayerStat (pc, IE_ALIGNMENT))
+ Align = CommonTables.Aligns.GetValue (tmp, 2)
RecordsTextArea.Append (Align,-1)
#saving throws
- RecordsTextArea.Append ("\n\n[color=ffff00]")
- RecordsTextArea.Append (17379)
- RecordsTextArea.Append ("[/color]")
- tmp = GemRB.GetPlayerStat (pc, IE_SAVEFORTITUDE)
- tmp -= GemRB.GetPlayerStat (pc, IE_SAVEFORTITUDE, 1)
- if tmp<0: stmp = str(tmp)
- else: stmp = "+"+str(tmp)
- RecordsTextArea.Append (17380,-1)
- RecordsTextArea.Append (": "+stmp )
- tmp = GemRB.GetPlayerStat (pc, IE_SAVEREFLEX)
- tmp -= GemRB.GetPlayerStat (pc, IE_SAVEREFLEX, 1)
- if tmp<0: stmp = str(tmp)
- else: stmp = "+"+str(tmp)
- RecordsTextArea.Append (17381,-1)
- RecordsTextArea.Append (": "+stmp )
- tmp = GemRB.GetPlayerStat (pc, IE_SAVEWILL)
- tmp -= GemRB.GetPlayerStat (pc, IE_SAVEWILL, 1)
- if tmp<0: stmp = str(tmp)
- else: stmp = "+"+str(tmp)
- RecordsTextArea.Append (17382,-1)
- RecordsTextArea.Append (": "+stmp )
+ DisplaySavingThrows (pc)
#class features
if HasClassFeatures(pc):
RecordsTextArea.Append ("\n\n[color=ffff00]")
RecordsTextArea.Append (40314)
- RecordsTextArea.Append ("[/color]\n")
+ RecordsTextArea.Append ("[/color]")
tmp = GemRB.GetPlayerStat (pc, IE_TURNUNDEADLEVEL)
if tmp:
- RecordsTextArea.Append (12146,-1)
+ RecordsTextArea.Append (12126,-1)
RecordsTextArea.Append (": "+str(tmp) )
- tmp = GemRB.GetPlayerStat (pc, IE_BACKSTABDAMAGEMULTIPLIER)
+ # 1d6 at level 1 and +1d6 every two extra rogue levels
+ tmp = GemRB.GetPlayerStat (pc, IE_LEVELTHIEF)
if tmp:
+ tmp = (tmp+1)//2
RecordsTextArea.Append (24898,-1)
RecordsTextArea.Append (": "+str(tmp)+"d6" )
tmp = GemRB.GetPlayerStat (pc, IE_LAYONHANDSAMOUNT)
if tmp:
RecordsTextArea.Append (12127,-1)
RecordsTextArea.Append (": "+str(tmp) )
+ MonkLevel = GemRB.GetPlayerStat (pc, IE_LEVELMONK)
+ if MonkLevel:
+ AC = GemRB.GetCombatDetails(pc, 0)["AC"]
+ GemRB.SetToken ("number", PlusMinusStat (AC["Wisdom"]))
+ RecordsTextArea.Append (39431, -1)
+ # wholeness of body
+ RecordsTextArea.Append (39749, -1)
+ RecordsTextArea.Append (": "+str(MonkLevel*2))
+
+ # favoured enemies; eg Goblins: +2 & Harpies: +1
+ RangerLevel = GemRB.GetPlayerStat (pc, IE_LEVELRANGER)
+ if RangerLevel:
+ RecordsTextArea.Append ("\n\n[color=ffff00]")
+ if RangerLevel > 5:
+ RecordsTextArea.Append (15982)
+ else:
+ RecordsTextArea.Append (15897)
+ RecordsTextArea.Append ("[/color]\n")
+ DisplayFavouredEnemy (pc, RangerLevel)
+ for i in range (7):
+ DisplayFavouredEnemy (pc, RangerLevel, i)
#bonus spells
- if HasBonusSpells(pc):
+ bonusSpells, classes = GetBonusSpells(pc)
+ if len(bonusSpells):
RecordsTextArea.Append ("\n\n[color=ffff00]")
RecordsTextArea.Append (10344)
- RecordsTextArea.Append ("[/color]\n")
+ RecordsTextArea.Append ("[/color]")
+ for c in classes:
+ if not len(bonusSpells[c]):
+ continue
+ # class/kit name
+ RecordsTextArea.Append ("\n")
+ RecordsTextArea.Append (c)
+ for level in range(len(bonusSpells[c])):
+ AddIndent()
+ # Level X: +Y
+ RecordsTextArea.Append (delimited_txt(7192, " " + str(level+1)+":", "+" + str(bonusSpells[c][level]), 0))
#ability statistics
RecordsTextArea.Append ("\n\n[color=ffff00]")
RecordsTextArea.Append (40315)
- RecordsTextArea.Append ("[/color]")
+ RecordsTextArea.Append ("[/color]\n")
- RecordsTextArea.Append (10338,-1) #strength
+ # Weight Allowance
tmp = GemRB.GetAbilityBonus( IE_STR, 3, GemRB.GetPlayerStat(pc, IE_STR) )
- RecordsTextArea.Append (": " + str(tmp) )
- tmp = GetAbilityBonus(pc, IE_CON)
- RecordsTextArea.Append (10342,-1)
- RecordsTextArea.Append (": " + str(tmp) ) #con bonus
-
- RecordsTextArea.Append (15581,-1) #spell resistance
- tmp = GemRB.GetPlayerStat (pc, IE_MAGICDAMAGERESISTANCE)
- RecordsTextArea.Append (": "+str(tmp) )
+ RecordsTextArea.Append (delimited_txt (10338, ":", str(tmp) + " lb."))
+ # constitution bonus to hitpoints
+ tmp = GUICommon.GetAbilityBonus(pc, IE_CON)
+ RecordsTextArea.Append (delimited_txt (10342, ":", PlusMinusStat(tmp)))
+
+ # Magic
+ GNZS(pc, 15581, IE_RESISTMAGIC, True)
+ #Fire
+ GNZS(pc, 14012, IE_RESISTFIRE)
+ #Magic Fire
+ GNZS(pc, 14077, IE_RESISTMAGICFIRE)
+ #Cold
+ GNZS(pc, 14014, IE_RESISTCOLD)
+ #Magic Cold
+ GNZS(pc, 14078, IE_RESISTMAGICCOLD)
+ #Electricity
+ GNZS(pc, 14013, IE_RESISTELECTRICITY)
+ #Acid
+ GNZS(pc, 14015, IE_RESISTACID)
+ #Spell
+ GNZS(pc, 40319, IE_MAGICDAMAGERESISTANCE)
+ # Missile
+ GNZS(pc, 11767, IE_RESISTMISSILE)
+ # Slashing
+ GNZS(pc, 11768, IE_RESISTSLASHING)
+ # Piercing
+ GNZS(pc, 11769, IE_RESISTPIERCING)
+ # Crushing
+ GNZS(pc, 11770, IE_RESISTCRUSHING)
+ # Poison
+ GNZS(pc, 14017, IE_RESISTPOISON)
+
+ # Damage Reduction - Spell Effect: Damage Reduction [436] (plain boni are mentioned above as resistances)
+ BaseString = 0
+ DisplayedHeader = 0
+ for damageType in 0, 1:
+ if damageType:
+ # missile
+ BaseString = 11767
+ else:
+ # general (physical)
+ BaseString = 40316
+
+ # cheat a bit and use the reduction at +10 as a modifier to remove from all other values
+ # it will hold all the non-enchantment related resistance (there are no +10 weapons)
+ mod = GemRB.GetDamageReduction (pc, damageType, 10)
+ if mod == -1:
+ mod = 0
+ for enchantment in range(6):
+ damage = GemRB.GetDamageReduction (pc, damageType, enchantment)
+ if damage == -1 or damage-mod <= 0:
+ continue
+ if not DisplayedHeader:
+ RecordsTextArea.Append ("\n\n[capital=0][color=ffff00]")
+ RecordsTextArea.Append (39325)
+ RecordsTextArea.Append ("[/color]\n")
+ DisplayedHeader = 1
+
+ enchantment += 1 # since we were checking what is allowable, not what bypasses it
+ if enchantment:
+ enchantment = "+" + str(enchantment)
+ else:
+ enchantment = "-"
+ reduction = "%d/%s" %(damage-mod, enchantment)
+ RecordsTextArea.Append (delimited_txt(BaseString, ":", reduction, 1))
return
-#FIXME: display only nonzero values except for casting failure
-#TODO: +/- prefix
-#TODO: check if there are any other entries
+# some of the displayed stats are manually indented
+def AddIndent():
+ RecordsTextArea.Append (" ", -1)
+
+def PlusMinusStat(value):
+ if value >= 0:
+ return "+" + str(value)
+ return str(value)
+
+def CascadeToHit(total, ac, apr, slot):
+ cascade = PlusMinusStat(total)
+ babDec = 5
+ if ac["Wisdom"]:
+ if slot == 10: # fist slot - nothing is equipped
+ babDec = 3
+ for i in range(1, apr):
+ if total-i*babDec > 0: # skips negative ones, meaning a lower number of attacks can be displayed
+ cascade = cascade + "/" + PlusMinusStat(total-i*babDec)
+ return cascade
+
+def ToHitOfHand(combatdet, dualwielding, left=0):
+ ac = combatdet["AC"]
+ tohit = combatdet["ToHitStats"]
+
+ # display all the (successive) attack values (+15/+10/+5)
+ if left:
+ apr = 1 # offhand gives just one extra attack
+ hits = CascadeToHit(tohit["Total"], ac, apr, combatdet["Slot"])
+ RecordsTextArea.Append (delimited_txt (733, ":", hits, 0))
+ else:
+ # account for the fact that the total apr contains the one for the other hand too
+ if dualwielding:
+ apr = combatdet["APR"]//2 - 1
+ else:
+ apr = combatdet["APR"]//2
+ hits = CascadeToHit(tohit["Total"], ac, apr, combatdet["Slot"])
+ RecordsTextArea.Append (delimited_txt (734, ":", hits, 0))
+
+ # Base
+ AddIndent()
+ hits = CascadeToHit(tohit["Base"], ac, apr, combatdet["Slot"])
+ RecordsTextArea.Append (delimited_txt (31353, ":", hits, 0))
+ # Weapon bonus
+ if tohit["Weapon"]:
+ AddIndent()
+ RecordsTextArea.Append (delimited_txt (32560 , ":", PlusMinusStat(tohit["Weapon"]), 0))
+ # Proficiency bonus
+ if tohit["Proficiency"]:
+ AddIndent()
+ RecordsTextArea.Append (delimited_txt (32561, ":", PlusMinusStat(tohit["Proficiency"]), 0))
+ # Armor Penalty
+ if tohit["Armor"]:
+ AddIndent()
+ RecordsTextArea.Append (delimited_txt (39816 , ":", PlusMinusStat(tohit["Armor"]), 0))
+ # Shield Penalty (if you don't have the shield proficiency feat)
+ if tohit["Shield"]:
+ AddIndent()
+ RecordsTextArea.Append (delimited_txt (39822 , ":", PlusMinusStat(tohit["Shield"]), 0))
+ # Ability bonus
+ if tohit["Ability"]:
+ AddIndent()
+ RecordsTextArea.Append (delimited_txt (33547, ":", PlusMinusStat(tohit["Ability"]), 0))
+ # Others
+ if tohit["Generic"]:
+ AddIndent()
+ RecordsTextArea.Append (delimited_txt (33548, ":", PlusMinusStat(tohit["Generic"]), 0))
+ RecordsTextArea.Append ("\n\n")
+
+def WeaponOfHand(pc, combatdet, dualwielding, left=0):
+ slot = combatdet["Slot"]
+ slot_item = GemRB.GetSlotItem (pc, slot, 1)
+ if not slot_item:
+ print "ARGHH, no slot item at slot %d, bailing out!" %(combatdet["Slot"])
+ return
+ item = GemRB.GetItem (slot_item["ItemResRef"])
+ ammo = None
+ if not left: # only the main hand can have ranged weapons, even one-handed
+ ammoslot = GemRB.GetEquippedAmmunition (pc)
+ if ammoslot != -1:
+ ammosi = GemRB.GetSlotItem (pc, ammoslot)
+ ammo = GemRB.GetItem (ammosi["ItemResRef"])
+
+ # Main Hand - weapon name
+ # or Ranged - ammo
+ if combatdet["Flags"]&15 == 2 and ammo: # this is basically wi.wflags & WEAPON_STYLEMASK == WEAPON_RANGED
+ RecordsTextArea.Append (delimited_str (41123, " -", ammo["ItemNameIdentified"], 0))
+ else:
+ if dualwielding and left:
+ RecordsTextArea.Append (delimited_str (733, " -", item["ItemNameIdentified"], 0))
+ else:
+ RecordsTextArea.Append (delimited_str (734, " -", item["ItemNameIdentified"], 0))
+
+ # Damage
+ # display the unresolved damage string (2d6)
+ # this is ammo, launcher details come later
+ wdice = combatdet["HitHeaderNumDice"]
+ wsides = combatdet["HitHeaderDiceSides"]
+ wbonus = combatdet["HitHeaderDiceBonus"]
+ AddIndent()
+ if wbonus:
+ RecordsTextArea.Append (delimited_txt (39518, ":", str (wdice)+"d"+str(wsides)+PlusMinusStat(wbonus), 0))
+ else:
+ RecordsTextArea.Append (delimited_txt (39518, ":", str (wdice)+"d"+str(wsides), 0))
+ # any extended headers with damage, eg. Fire: +1d6, which is also computed for the total (00arow08)
+ alldos = combatdet["DamageOpcodes"]
+ dosmin = 0
+ dosmax = 0
+ for dos in alldos:
+ ddice = dos["NumDice"]
+ dsides = dos["DiceSides"]
+ dbonus = dos["DiceBonus"]
+ dchance = dos["Chance"]
+ AddIndent()
+ # only display the chance when it isn't 100%
+ if dchance == 100:
+ dchance = ""
+ dosmin += ddice + dbonus
+ else:
+ dchance = " (%d%%)" % dchance
+ dicestr = ""
+ if ddice:
+ dicestr = "+%dd%d" %(ddice, dsides)
+ if dbonus:
+ RecordsTextArea.Append (dos["TypeName"] + ": " + dicestr + PlusMinusStat(dbonus)+dchance)
+ else:
+ RecordsTextArea.Append (dos["TypeName"] + ": " + dicestr + dchance)
+ dosmax += ddice*dsides + dbonus
+
+ # Strength
+ abonus = combatdet["WeaponStrBonus"]
+ if abonus:
+ AddIndent()
+ RecordsTextArea.Append (delimited_txt (1145, ":", PlusMinusStat (abonus), 0))
+ # Proficiency (bonus)
+ pbonus = combatdet["ProfDmgBon"]
+ if pbonus:
+ AddIndent()
+ RecordsTextArea.Append (delimited_txt (32561, ":", PlusMinusStat(pbonus), 0))
+ # Launcher
+ lbonus = combatdet["LauncherDmgBon"]
+ if lbonus:
+ AddIndent()
+ RecordsTextArea.Append (delimited_txt (41408, ":", PlusMinusStat(lbonus), 0))
+ #TODO: Power Attack has its own row
+ # Damage Potential (2-12)
+ # add any other bonus to the ammo damage calc
+ AddIndent()
+ wmin = wdice + wbonus + abonus + pbonus + lbonus + dosmin
+ wmax = wdice*wsides + wbonus + abonus + pbonus + lbonus + dosmax
+ RecordsTextArea.Append (delimited_txt (41120, ":", str (wmin)+"-"+str(wmax), 0))
+ # Critical Hit (19-20 / x2)
+ crange = combatdet["CriticalRange"]
+ cmulti = combatdet["CriticalMultiplier"]
+ if crange == 20:
+ crange = "20 / x" + str(cmulti)
+ else:
+ crange = str(crange) + "-20 / x" + str(cmulti)
+ AddIndent()
+ RecordsTextArea.Append (delimited_txt (41122, ":", crange, 0))
+ if not left and dualwielding:
+ RecordsTextArea.Append ("\n")
+
def DisplayWeapons (pc):
Window = RecordsWindow
@@ -390,46 +736,28 @@ def DisplayWeapons (pc):
RecordsTextArea.Append ("[/color]\n")
combatdet = GemRB.GetCombatDetails(pc, 0)
+ combatdet2 = combatdet # placeholder for the potential offhand numbers
+ ac = combatdet["AC"]
+ tohit = combatdet["ToHitStats"]
+ dualwielding = GemRB.IsDualWielding(pc)
+ if dualwielding:
+ combatdet2 = GemRB.GetCombatDetails(pc, 1)
# Main Hand
- #TODO: display all the attack values (+15/+10/+5)
- current = combatdet["ToHit"]
- RecordsTextArea.Append (delimited_txt (734, ":", str (current), 0))
- # Base
- RecordsTextArea.Append (" ", -1) # indentation
- RecordsTextArea.Append (delimited_txt (31353, ":", str (GS(IE_TOHIT)), 0))
- # Weapon
- RecordsTextArea.Append (" ", -1)
- RecordsTextArea.Append (delimited_txt (32560 , ":", str (0), 0))
- # Proficiency
- RecordsTextArea.Append (" ", -1)
- RecordsTextArea.Append (delimited_txt (32561, ":", str (0), 0))
- # Armor Penalty
- RecordsTextArea.Append (" ", -1)
- RecordsTextArea.Append (delimited_txt (39816 , ":", str (0), 0))
- #TODO: check if there's also a @39822 = ~Shield Penalty~
-
- # Abilities
- #FIXME: this is different for ranged weapons (dex) or if weapon finese is chosen (dex or str)
- strbon = GA(IE_STR)
- if strbon:
- RecordsTextArea.Append (" ", -1)
- RecordsTextArea.Append (delimited_txt (33547, ":", str (strbon), 0))
- # Others
- RecordsTextArea.Append (" ", -1)
- RecordsTextArea.Append (delimited_txt (33548, ":", str (current - GS(IE_TOHIT) - strbon)))
- RecordsTextArea.Append ("\n")
+ ToHitOfHand (combatdet, dualwielding)
# Off Hand
- if (GemRB.IsDualWielding(pc)):
- RecordsTextArea.Append (delimited_txt (733, ":", str (GemRB.GetCombatDetails(pc, 1)["ToHit"]), 0))
- RecordsTextArea.Append ("\n")
- #TODO: probably all the same categories as above
+ if dualwielding:
+ ToHitOfHand (combatdet2, dualwielding, 1)
###################
# Number of Attacks
- RecordsTextArea.Append (delimited_txt (9458, ":", str (GS (IE_NUMBEROFATTACKS)/2)))
+ if dualwielding:
+ # only one extra offhand attack and it is displayed as eg. 2+1
+ RecordsTextArea.Append (delimited_txt (9458, ":", str (combatdet["APR"]//2-1)+"+1"))
+ else:
+ RecordsTextArea.Append (delimited_txt (9458, ":", str (combatdet["APR"]//2)))
RecordsTextArea.Append ("\n")
###################
@@ -437,33 +765,35 @@ def DisplayWeapons (pc):
RecordsTextArea.Append ("[color=ffff00]")
RecordsTextArea.Append (33553)
RecordsTextArea.Append ("[/color]\n")
- RecordsTextArea.Append (delimited_txt (33553, ":", str (GS(IE_ARMORCLASS)), 0))
+ RecordsTextArea.Append (delimited_txt (33553, ":", str (GS(IE_ARMORCLASS)), 0)) # same as ac["Total"]
# Base
- RecordsTextArea.Append (" ", -1) # indentation
- RecordsTextArea.Append (delimited_txt (31353, ":", str (10), 0))
+ AddIndent()
+ RecordsTextArea.Append (delimited_txt (31353, ":", str (ac["Natural"]), 0))
# Armor
- RecordsTextArea.Append (" ", -1)
- RecordsTextArea.Append (delimited_txt (11997, ":", str (0), 0))
+ if ac["Armor"]:
+ AddIndent()
+ RecordsTextArea.Append (delimited_txt (11997, ":", PlusMinusStat (ac["Armor"]), 0))
# Shield
- RecordsTextArea.Append (" ", -1)
- RecordsTextArea.Append (delimited_txt (6347, ":", str (0), 0))
+ if ac["Shield"]:
+ AddIndent()
+ RecordsTextArea.Append (delimited_txt (6347, ":", PlusMinusStat (ac["Shield"]), 0))
# Deflection
- RecordsTextArea.Append (" ", -1)
- RecordsTextArea.Append (delimited_txt (33551, ":", str (0), 0))
+ if ac["Deflection"]:
+ AddIndent()
+ RecordsTextArea.Append (delimited_txt (33551, ":", PlusMinusStat (ac["Deflection"]), 0))
# Generic
- RecordsTextArea.Append (" ", -1)
- RecordsTextArea.Append (delimited_txt (33552, ":", str (0), 0))
+ if ac["Generic"]:
+ AddIndent()
+ RecordsTextArea.Append (delimited_txt (33552, ":", PlusMinusStat (ac["Generic"]), 0))
# Dexterity
- if GA(IE_DEX):
- RecordsTextArea.Append (" ", -1)
- RecordsTextArea.Append (delimited_txt (1151, ":", str (GA(IE_DEX)), 0))
+ if ac["Dexterity"]:
+ AddIndent()
+ RecordsTextArea.Append (delimited_txt (1151, ":", PlusMinusStat (ac["Dexterity"]), 0))
# Monk Wisdom Bonus: <number> to AC
- if GS(IE_LEVELMONK):
- RecordsTextArea.Append (" ", -1)
- GemRB.SetToken ("number", str (GA(IE_WIS)))
+ if ac["Wisdom"]:
+ GemRB.SetToken ("number", PlusMinusStat (ac["Wisdom"]))
RecordsTextArea.Append (39431, -1)
- #TODO: Dodge?
RecordsTextArea.Append ("\n\n")
@@ -477,39 +807,60 @@ def DisplayWeapons (pc):
# Missile
if GS (IE_ACMISSILEMOD):
- RecordsTextArea.Append (" ", -1) # indentation
- RecordsTextArea.Append (delimited_txt (11767, ":", str (GS (IE_ACMISSILEMOD)), 0))
+ AddIndent()
+ RecordsTextArea.Append (delimited_txt (11767, ":", PlusMinusStat(GS (IE_ACMISSILEMOD)), 0))
# Slashing
if GS (IE_ACSLASHINGMOD):
- RecordsTextArea.Append (" ", -1)
- RecordsTextArea.Append (delimited_txt (11768, ":", str (GS (IE_ACSLASHINGMOD)), 0))
+ AddIndent()
+ RecordsTextArea.Append (delimited_txt (11768, ":", PlusMinusStat (GS (IE_ACSLASHINGMOD)), 0))
# Piercing
if GS (IE_ACPIERCINGMOD):
- RecordsTextArea.Append (" ", -1)
- RecordsTextArea.Append (delimited_txt (11769, ":", str (GS (IE_ACPIERCINGMOD)), 0))
+ AddIndent()
+ RecordsTextArea.Append (delimited_txt (11769, ":", PlusMinusStat (GS (IE_ACPIERCINGMOD)), 0))
# Bludgeoning
if GS (IE_ACCRUSHINGMOD):
- RecordsTextArea.Append (" ", -1)
- RecordsTextArea.Append (delimited_txt (11770, ":", str (GS (IE_ACCRUSHINGMOD))))
+ AddIndent()
+ RecordsTextArea.Append (delimited_txt (11770, ":", PlusMinusStat (GS (IE_ACCRUSHINGMOD))))
- RecordsTextArea.Append ("\n")
+ RecordsTextArea.Append ("\n\n")
###################
# Arcane spell failure
- if GS(IE_LEVELBARD) + GS(IE_LEVELSORCEROR) + GS(IE_LEVELMAGE):
+ if GS(IE_LEVELBARD) + GS(IE_LEVELSORCERER) + GS(IE_LEVELMAGE):
RecordsTextArea.Append ("[color=ffff00]")
RecordsTextArea.Append (41391)
RecordsTextArea.Append ("[/color]\n")
# Casting Failure
- RecordsTextArea.Append (delimited_txt (41390 , ":", str (GS(IE_SPELLFAILUREMAGE)), 0))
- # Armor Penalty
- RecordsTextArea.Append (" ", -1)
- RecordsTextArea.Append (delimited_txt (39816 , ":", str (0), 0))
+ failure = GemRB.GetSpellFailure (pc)
+ total = failure["Total"]
+ arcana = 5*GemRB.HasFeat(pc, FEAT_ARMORED_ARCANA)
+ other = 5*(failure["Armor"] + failure["Shield"]) - arcana
+ # account for armored arcana only if it doesn't cause a negative value (eating into the misc bonus)
+ verbose = 0
+ if other < 0:
+ other = total
+ else:
+ other = total - other
+ verbose = 1
+ if total < 0:
+ total = 0
+ RecordsTextArea.Append (delimited_txt (41390 , ":", str (total)+"%", 0))
+ # Armor Penalty (same as for skills and everything else)
+ if verbose and failure["Armor"]:
+ AddIndent()
+ RecordsTextArea.Append (delimited_txt (39816 , ":", PlusMinusStat(5*failure["Armor"])+"%", 0))
# Shield Penalty
- RecordsTextArea.Append (" ", -1)
- RecordsTextArea.Append (delimited_txt (39822, ":", str (0), 0))
- #TODO: check if there's also the bonus from armored arcana
+ if verbose and failure["Shield"]:
+ AddIndent()
+ RecordsTextArea.Append (delimited_txt (39822, ":", PlusMinusStat(5*failure["Shield"])+"%", 0))
+ if arcana:
+ AddIndent()
+ RecordsTextArea.Append (delimited_txt (36352, ":", PlusMinusStat(arcana)+"%", 0))
+ # Other, just a guess to show the remainder
+ if other:
+ AddIndent()
+ RecordsTextArea.Append (delimited_txt (33548, ":", PlusMinusStat(other)+"%", 0))
RecordsTextArea.Append ("\n\n")
@@ -519,41 +870,15 @@ def DisplayWeapons (pc):
RecordsTextArea.Append (41119)
RecordsTextArea.Append ("[/color]\n")
- slot_item = GemRB.GetSlotItem (pc, GemRB.GetEquippedQuickSlot (pc) )
- if not slot_item:
- print "ARGHH, no slot item, bailing out"
- return
- item = GemRB.GetItem (slot_item["ItemResRef"])
- ##FIXME: display Ranged (41123) + ammo for ranged weapons
- RecordsTextArea.Append (delimited_str (734, " -", item["ItemNameIdentified"], 0))
+ # Main hand
+ WeaponOfHand(pc, combatdet, dualwielding)
- # Damage
- # TODO: display the unresolved damage string (2d6)
- RecordsTextArea.Append (" ", -1)
- RecordsTextArea.Append (delimited_txt (39518, ":", str (0), 0))
- # Strength
- # TODO: check if the weapon takes strength bonus at all
- if GA(IE_STR):
- RecordsTextArea.Append (" ", -1)
- RecordsTextArea.Append (delimited_txt (1145, ":", str (GA(IE_STR)), 0))
- # Launcher
- RecordsTextArea.Append (" ", -1)
- RecordsTextArea.Append (delimited_txt (41408, ":", str (0), 0))
- # Damage Potential
- # TODO: display the unresolved total damage potential (2-12)
- RecordsTextArea.Append (" ", -1)
- RecordsTextArea.Append (delimited_txt (41120, ":", str (0), 0))
- # Critical Hit (19-20 / x2)
- # TODO: display the number of rolls and check if the critical range is already ok
- crange = 20 - combatdet["CriticalBonus"]
- if crange == 20:
- crange = "20 / x" + str(1)
- else:
- crange = str(crange) + "-20 / x" + str(1)
- RecordsTextArea.Append (" ", -1)
- RecordsTextArea.Append (delimited_txt (41122, ":", crange, 0))
+ # Off-hand (if any)
+ if dualwielding:
+ RecordsTextArea.Append ("\n")
+ WeaponOfHand(pc, combatdet2, dualwielding, 1)
- #TODO: probably repeat for the off-hand
+ DisplaySavingThrows (pc)
return
@@ -574,8 +899,10 @@ def DisplaySkills (pc):
stat = SkillTable.GetValue (i, 0, 2)
value = GemRB.GetPlayerStat (pc, stat)
base = GemRB.GetPlayerStat (pc, stat, 1)
+ untrained = SkillName.GetValue (i, 3)
- if value:
+ # only show (modified) skills that either don't require training or had it already
+ if (value and untrained) or (not untrained and base):
skill = SkillName.GetValue (i, 1)
skills.append (GemRB.GetString(skill) + ": " + str(value) + " (" + str(base) + ")\n")
@@ -587,18 +914,15 @@ def DisplaySkills (pc):
FeatName = GemRB.LoadTable ("feats")
rows = FeatTable.GetRowCount ()
#feats
- featbits = [GemRB.GetPlayerStat (pc, IE_FEATS1), GemRB.GetPlayerStat (pc, IE_FEATS2), GemRB.GetPlayerStat (pc, IE_FEATS3)]
RecordsTextArea.Append ("\n\n[color=ffff00]")
RecordsTextArea.Append (36361)
RecordsTextArea.Append ("[/color]\n")
feats = []
for i in range(rows):
- featidx = i/32
- pos = 1<<(i%32)
- if featbits[featidx]&pos:
+ if GemRB.HasFeat(pc, i):
feat = FeatName.GetValue (i, 1)
- stat = FeatTable.GetValue (i, 9, 2)
+ stat = FeatTable.GetValue (i, 0, 2)
if stat:
multi = GemRB.GetPlayerStat (pc, stat)
feats.append (GemRB.GetString(feat) + ": " + str(multi) + "\n")
@@ -658,21 +982,8 @@ def DisplayMisc (pc):
#most powerful vanquished, time spent, xp and kills
RecordsTextArea.Append (delimited_str (11947, ":", stat['BestKilledName']))
- # NOTE: currentTime is in seconds, joinTime is in seconds * 15
- # (script updates???). In each case, there are 60 seconds
- # in a minute, 24 hours in a day, but ONLY 5 minutes in an hour!!
- # Hence currentTime (and joinTime after div by 15) has
- # 7200 secs a day (60 * 5 * 24)
- currentTime = GemRB.GetGameTime()
- joinTime = stat['JoinDate'] - stat['AwayTime']
-
- party_time = currentTime - (joinTime / 15)
- days = party_time / 7200
- hours = (party_time % 7200) / 300
-
- GemRB.SetToken ('GAMEDAYS', str (days))
- GemRB.SetToken ('HOUR', str (hours))
-
+ days, hours = GUICommon.SetCurrentDateTokens (stat)
+ # iwd2 is special here
# construct <GAMEDAYS> days ~and~ ~<HOUR> hours~
if days == 1:
time = GemRB.GetString (10698)
@@ -738,26 +1049,34 @@ def UpdateRecordsWindow ():
Label.SetText (str (GemRB.GetPlayerStat (pc, IE_MAXHITPOINTS)))
Label.SetTooltip (17378)
+ #level up
+ Button = Window.GetControl (37)
+ levelsum = GemRB.GetPlayerStat (pc, IE_CLASSLEVELSUM)
+ if GetNextLevelExp(levelsum, GetECL(pc)) <= GemRB.GetPlayerStat (pc, IE_XP):
+ Button.SetState (IE_GUI_BUTTON_ENABLED)
+ else:
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+
# stats
sstr = GemRB.GetPlayerStat (pc, IE_STR)
dstr = sstr-GemRB.GetPlayerStat (pc, IE_STR,1)
- bstr = GetAbilityBonus (pc, IE_STR)
+ bstr = GUICommon.GetAbilityBonus (pc, IE_STR)
sint = GemRB.GetPlayerStat (pc, IE_INT)
dint = sint-GemRB.GetPlayerStat (pc, IE_INT,1)
- bint = GetAbilityBonus (pc, IE_INT)
+ bint = GUICommon.GetAbilityBonus (pc, IE_INT)
swis = GemRB.GetPlayerStat (pc, IE_WIS)
dwis = swis-GemRB.GetPlayerStat (pc, IE_WIS,1)
- bwis = GetAbilityBonus (pc, IE_WIS)
+ bwis = GUICommon.GetAbilityBonus (pc, IE_WIS)
sdex = GemRB.GetPlayerStat (pc, IE_DEX)
ddex = sdex-GemRB.GetPlayerStat (pc, IE_DEX,1)
- bdex = GetAbilityBonus (pc, IE_DEX)
+ bdex = GUICommon.GetAbilityBonus (pc, IE_DEX)
scon = GemRB.GetPlayerStat (pc, IE_CON)
dcon = scon-GemRB.GetPlayerStat (pc, IE_CON,1)
- bcon = GetAbilityBonus (pc, IE_CON)
+ bcon = GUICommon.GetAbilityBonus (pc, IE_CON)
schr = GemRB.GetPlayerStat (pc, IE_CHR)
dchr = schr-GemRB.GetPlayerStat (pc, IE_CHR,1)
- bchr = GetAbilityBonus (pc, IE_CHR)
+ bchr = GUICommon.GetAbilityBonus (pc, IE_CHR)
Label = Window.GetControl (0x1000002f)
Label.SetText (str(sstr))
@@ -784,33 +1103,35 @@ def UpdateRecordsWindow ():
ColorDiff2 (Window, Label, dchr)
Label = Window.GetControl (0x10000035)
- Label.SetText (str(bstr))
+ Label.SetText (PlusMinusStat(bstr))
ColorDiff (Window, Label, bstr)
Label = Window.GetControl (0x10000036)
- Label.SetText (str(bdex))
+ Label.SetText (PlusMinusStat(bdex))
ColorDiff (Window, Label, bdex)
Label = Window.GetControl (0x10000037)
- Label.SetText (str(bcon))
+ Label.SetText (PlusMinusStat(bcon))
ColorDiff (Window, Label, bcon)
Label = Window.GetControl (0x10000038)
- Label.SetText (str(bint))
+ Label.SetText (PlusMinusStat(bint))
ColorDiff (Window, Label, bint)
Label = Window.GetControl (0x10000039)
- Label.SetText (str(bwis))
+ Label.SetText (PlusMinusStat(bwis))
ColorDiff (Window, Label, bwis)
Label = Window.GetControl (0x1000003a)
- Label.SetText (str(bchr))
+ Label.SetText (PlusMinusStat(bchr))
ColorDiff (Window, Label, bchr)
RecordsTextArea = Window.GetControl (45)
RecordsTextArea.SetText ("")
RecordsTextArea.Append ("[capital=0]")
+ DisplayCommon (pc)
+
SelectWindow = GemRB.GetVar ("SelectWindow")
if SelectWindow == 1:
DisplayGeneral (pc)
@@ -822,16 +1143,17 @@ def UpdateRecordsWindow ():
DisplayMisc (pc)
#if actor is uncontrollable, make this grayed
- Window.SetVisible (WINDOW_VISIBLE)
+ GUICommon.AdjustWindowVisibility (Window, pc, 0)
PortraitWindow.SetVisible (WINDOW_VISIBLE)
OptionsWindow.SetVisible (WINDOW_VISIBLE)
return
def CloseHelpWindow ():
- global DescTable
+ global DescTable, InformationWindow
if InformationWindow:
InformationWindow.Unload ()
+ InformationWindow = None
if DescTable:
DescTable = None
return
@@ -943,571 +1265,9 @@ def RefreshHelpWindow ():
else:
desc = DescTable.GetValue (Selected+startrow, desccol)
- Window = InformationWindow
TextArea = Window.GetControl (2)
TextArea.SetText (desc)
return
-def CloseBiographyWindow ():
- if BiographyWindow:
- BiographyWindow.Unload ()
- return
-
-def OpenBiographyWindow ():
- global BiographyWindow
-
- BiographyWindow = Window = GemRB.LoadWindow (12)
-
- pc = GemRB.GameGetSelectedPCSingle ()
-
- TextArea = Window.GetControl (0)
- TextArea.SetText (GemRB.GetPlayerString(pc, 63) )
-
- # Done
- Button = Window.GetControl (2)
- Button.SetText (11973)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseBiographyWindow)
-
- Window.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def OpenCustomizeWindow ():
- global CustomizeWindow
- global PortraitsTable, ScriptsTable, ColorTable
-
- pc = GemRB.GameGetSelectedPCSingle ()
- if GemRB.GetPlayerStat (pc, IE_MC_FLAGS)&MC_EXPORTABLE:
- Exportable = 1
- else:
- Exportable = 0
- PortraitsTable = GemRB.LoadTable ("PICTURES")
- ScriptsTable = GemRB.LoadTable ("SCRPDESC")
- ColorTable = GemRB.LoadTable ("CLOWNCOL")
- CustomizeWindow = GemRB.LoadWindow (17)
-
- AppearanceButton = CustomizeWindow.GetControl (0)
- AppearanceButton.SetText (11961)
- if not Exportable:
- AppearanceButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- SoundButton = CustomizeWindow.GetControl (1)
- SoundButton.SetText (10647)
- if not Exportable:
- SoundButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- #ColorButton = CustomizeWindow.GetControl (2)
- #ColorButton.SetText (10646)
- #if not Exportable:
- # ColorButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- ScriptButton = CustomizeWindow.GetControl (3)
- ScriptButton.SetText (17111)
-
- BiographyButton = CustomizeWindow.GetControl (9)
- BiographyButton.SetText (18003)
- if not Exportable:
- BiographyButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- TextArea = CustomizeWindow.GetControl (5)
- TextArea.SetText (11327)
-
- DoneButton = CustomizeWindow.GetControl (7)
- DoneButton.SetText (11973)
- DoneButton.SetState (IE_GUI_BUTTON_ENABLED)
-
- CancelButton = CustomizeWindow.GetControl (8);
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- AppearanceButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenAppearanceWindow)
- SoundButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenSoundWindow)
- #ColorButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenColorWindow)
- ScriptButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenScriptWindow)
- BiographyButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenBiographyEditWindow)
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CustomizeDonePress)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CustomizeCancelPress)
-
- CustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def CustomizeDonePress ():
- global CustomizeWindow
-
- if CustomizeWindow:
- CustomizeWindow.Unload ()
- CustomizeWindow = None
-
- UpdateRecordsWindow ()
- return
-
-def CustomizeCancelPress ():
- global CustomizeWindow
-
- if CustomizeWindow:
- CustomizeWindow.Unload ()
- CustomizeWindow = None
-
- UpdateRecordsWindow ()
- return
-
-def OpenAppearanceWindow ():
- global SubCustomizeWindow
- global PortraitButton
- global Gender, LastPortrait
-
- SubCustomizeWindow = GemRB.LoadWindow (18)
- pc = GemRB.GameGetSelectedPCSingle ()
- Gender = GemRB.GetPlayerStat (pc, IE_SEX, 1)
- PortraitName = GemRB.GetPlayerPortrait (pc, 0)
- LastPortrait = PortraitsTable.GetRowIndex (PortraitName[0:len(PortraitName)-1])
-
- PortraitButton = SubCustomizeWindow.GetControl (0)
- PortraitButton.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_NO_IMAGE,OP_SET)
- PortraitButton.SetState (IE_GUI_BUTTON_LOCKED)
-
- LeftButton = SubCustomizeWindow.GetControl (1)
- RightButton = SubCustomizeWindow.GetControl (2)
-
- DoneButton = SubCustomizeWindow.GetControl (3)
- DoneButton.SetText (11973)
- DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- CancelButton = SubCustomizeWindow.GetControl (4)
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- CustomPortraitButton = SubCustomizeWindow.GetControl (5)
- CustomPortraitButton.SetText (17545)
-
- LeftButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, PortraitLeftPress)
- RightButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, PortraitRightPress)
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DonePortraitWindow)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSubCustomizeWindow)
- CustomPortraitButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenCustomPortraitWindow)
- SubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
-
- while True:
- if PortraitsTable.GetValue (LastPortrait, 0) == Gender:
- UpdatePortrait ()
- break
- LastPortrait = LastPortrait + 1
-
- return
-
-def DonePortraitWindow ():
- pc = GemRB.GameGetSelectedPCSingle ()
- Name = PortraitsTable.GetRowName (LastPortrait)
- GemRB.FillPlayerInfo (pc, Name + "M", Name + "S")
- CloseSubCustomizeWindow ()
- return
-
-def PortraitRightPress():
- global LastPortrait
-
- while True:
- LastPortrait = LastPortrait + 1
- if LastPortrait >= PortraitsTable.GetRowCount ():
- LastPortrait = 0
- if PortraitsTable.GetValue (LastPortrait, 0) == Gender:
- UpdatePortrait ()
- return
-
- return
-
-def PortraitLeftPress():
- global LastPortrait
-
- while True:
- LastPortrait = LastPortrait - 1
- if LastPortrait < 0:
- LastPortrait = PortraitsTable.GetRowCount ()-1
- if PortraitsTable.GetValue (LastPortrait, 0) == Gender:
- UpdatePortrait ()
- return
-
- return
-
-def UpdatePortrait ():
- PortraitName = PortraitsTable.GetRowName (LastPortrait)+"L"
- PortraitButton.SetPicture (PortraitName, "NOPORTLG")
- return
-
-def OpenCustomPortraitWindow ():
- global SubSubCustomizeWindow
- global PortraitList1, PortraitList2
- global RowCount1, RowCount2
-
- SubSubCustomizeWindow = GemRB.LoadWindow (19)
-
- SmallPortraitButton = SubSubCustomizeWindow.GetControl (1)
- SmallPortraitButton.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_NO_IMAGE,OP_SET)
-
- LargePortraitButton = SubSubCustomizeWindow.GetControl (0)
- LargePortraitButton.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_NO_IMAGE,OP_SET)
-
- DoneButton = SubSubCustomizeWindow.GetControl (10)
- DoneButton.SetText (11973)
- DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
- DoneButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- CancelButton = SubSubCustomizeWindow.GetControl (11)
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- # Portrait List Large
- PortraitList1 = SubSubCustomizeWindow.GetControl (2)
- RowCount1 = PortraitList1.GetPortraits (0)
- PortraitList1.SetEvent (IE_GUI_TEXTAREA_ON_CHANGE, LargeCustomPortrait)
- GemRB.SetVar ("Row1", RowCount1)
- PortraitList1.SetVarAssoc ("Row1",RowCount1)
-
- # Portrait List Small
- PortraitList2 = SubSubCustomizeWindow.GetControl (3)
- RowCount2 = PortraitList2.GetPortraits (1)
- PortraitList2.SetEvent (IE_GUI_TEXTAREA_ON_CHANGE, SmallCustomPortrait)
- GemRB.SetVar ("Row2", RowCount2)
- PortraitList2.SetVarAssoc ("Row2",RowCount2)
-
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DonePortraitCustomizeWindow)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSubSubCustomizeWindow)
-
- SubSubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def DonePortraitCustomizeWindow ():
- pc = GemRB.GameGetSelectedPCSingle ()
- GemRB.FillPlayerInfo (pc, PortraitList1.QueryText () , PortraitList2.QueryText ())
- CloseSubSubCustomizeWindow ()
- #closing the generic portraits, because we just set a custom one
- CloseSubCustomizeWindow ()
- return
-
-def LargeCustomPortrait ():
- Window = SubSubCustomizeWindow
-
- Portrait = PortraitList1.QueryText ()
- #small hack
- if GemRB.GetVar ("Row1") == RowCount1:
- return
-
- Label = Window.GetControl (0x10000007)
- Label.SetText (Portrait)
-
- Button = Window.GetControl (10)
- if Portrait=="":
- Portrait = "NOPORTMD"
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- if PortraitList2.QueryText ()!="":
- Button.SetState (IE_GUI_BUTTON_ENABLED)
-
- Button = Window.GetControl (0)
- Button.SetPicture (Portrait, "NOPORTMD")
- return
-
-def SmallCustomPortrait ():
- Window = SubSubCustomizeWindow
-
- Portrait = PortraitList2.QueryText ()
- #small hack
- if GemRB.GetVar ("Row2") == RowCount2:
- return
-
- Label = Window.GetControl (0x10000008)
- Label.SetText (Portrait)
-
- Button = Window.GetControl (10)
- if Portrait=="":
- Portrait = "NOPORTSM"
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- if PortraitList1.QueryText ()!="":
- Button.SetState (IE_GUI_BUTTON_ENABLED)
-
- Button = Window.GetControl (1)
- Button.SetPicture (Portrait, "NOPORTSM")
- return
-
-def OpenSoundWindow ():
- global SubCustomizeWindow
- global VoiceList
- global Gender
- global OldVoiceSet
-
- pc = GemRB.GameGetSelectedPCSingle ()
- OldVoiceSet = GemRB.GetPlayerSound (pc)
- SubCustomizeWindow = GemRB.LoadWindow (20)
-
- VoiceList = SubCustomizeWindow.GetControl (5)
- VoiceList.SetFlags (IE_GUI_TEXTAREA_SELECTABLE)
- Gender = GemRB.GetPlayerStat (pc, IE_SEX, 1)
-
- VoiceList.SetVarAssoc ("Selected", 0)
- VoiceList.GetCharSounds()
- VoiceList.SelectText (OldVoiceSet)
-
- PlayButton = SubCustomizeWindow.GetControl (7)
- PlayButton.SetText (17318)
-
- TextArea = SubCustomizeWindow.GetControl (8)
- TextArea.SetText (11315)
-
- DoneButton = SubCustomizeWindow.GetControl (10)
- DoneButton.SetText (11973)
- DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- CancelButton = SubCustomizeWindow.GetControl (11)
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- PlayButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, PlaySoundPressed)
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DoneSoundWindow)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSoundWindow)
-
- SubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def CloseSoundWindow ():
- pc = GemRB.GameGetSelectedPCSingle ()
- GemRB.SetPlayerSound (pc, OldVoiceSet)
- CloseSubCustomizeWindow ()
- return
-
-def DoneSoundWindow ():
- pc = GemRB.GameGetSelectedPCSingle ()
- CharSound = VoiceList.QueryText ()
- GemRB.SetPlayerSound (pc, CharSound)
-
- CloseSubCustomizeWindow ()
- return
-
-def PlaySoundPressed():
- global CharSoundWindow, SoundIndex, SoundSequence
-
- CharSound = VoiceList.QueryText ()
- pc = GemRB.GameGetSelectedPCSingle ()
- GemRB.SetPlayerSound (pc, CharSound)
- VoiceSet = GemRB.GetPlayerSound (pc, 1)
- tmp = SoundIndex
- while (not GemRB.HasResource (VoiceSet + SoundSequence[SoundIndex], RES_WAV)):
- NextSound()
- if SoundIndex == tmp:
- break
- else:
- NextSound()
-
- GemRB.PlaySound (VoiceSet + SoundSequence[SoundIndex], 0, 0, 5)
- return
-
-def NextSound():
- global SoundIndex, SoundSequence
- SoundIndex += 1
- if SoundIndex >= len(SoundSequence):
- SoundIndex = 0
- return
-
-def OpenScriptWindow ():
- global SubCustomizeWindow
- global ScriptTextArea, SelectedTextArea
-
- SubCustomizeWindow = GemRB.LoadWindow (11)
-
- ScriptTextArea = SubCustomizeWindow.GetControl (2)
- ScriptTextArea.SetFlags (IE_GUI_TEXTAREA_SELECTABLE)
- FillScriptList ()
- pc = GemRB.GameGetSelectedPCSingle ()
- script = GemRB.GetPlayerScript (pc)
- scriptindex = ScriptsTable.GetRowIndex (script)
- GemRB.SetVar ("Selected", scriptindex)
- ScriptTextArea.SetVarAssoc ("Selected", scriptindex)
-
- SelectedTextArea = SubCustomizeWindow.GetControl (4)
- UpdateScriptSelection ()
-
- DoneButton = SubCustomizeWindow.GetControl (5)
- DoneButton.SetText (11973)
- DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- CancelButton = SubCustomizeWindow.GetControl (6)
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DoneScriptWindow)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSubCustomizeWindow)
- ScriptTextArea.SetEvent (IE_GUI_TEXTAREA_ON_CHANGE, UpdateScriptSelection)
-
- SubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def FillScriptList ():
- ScriptTextArea.Clear ()
- row = ScriptsTable.GetRowCount ()
- for i in range (row):
- GemRB.SetToken ("script", ScriptsTable.GetRowName (i) )
- title = ScriptsTable.GetValue (i,0)
- if title!=-1:
- desc = ScriptsTable.GetValue (i,1)
- txt = GemRB.GetString (title)
-
- if (desc!=-1):
- txt += GemRB.GetString (desc)
-
- ScriptTextArea.Append (txt+"\n", -1)
-
- else:
- ScriptTextArea.Append (ScriptsTable.GetRowName (i)+"\n" ,-1)
-
- return
-
-def DoneScriptWindow ():
- pc = GemRB.GameGetSelectedPCSingle ()
- script = ScriptsTable.GetRowName (GemRB.GetVar ("Selected") )
- GemRB.SetPlayerScript (pc, script)
- CloseSubCustomizeWindow ()
- return
-
-def UpdateScriptSelection():
- text = ScriptTextArea.QueryText ()
- SelectedTextArea.SetText (text)
- return
-
-def OpenBiographyEditWindow ():
- global SubCustomizeWindow
- global BioStrRef
- global TextArea
-
- Changed = 0
- pc = GemRB.GameGetSelectedPCSingle ()
- BioStrRef = GemRB.GetPlayerString (pc, 74)
- if BioStrRef != 33347:
- Changed = 1
-
- SubCustomizeWindow = GemRB.LoadWindow (51)
-
- ClearButton = SubCustomizeWindow.GetControl (5)
- ClearButton.SetText (18622)
-
- DoneButton = SubCustomizeWindow.GetControl (1)
- DoneButton.SetText (11973)
- DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- RevertButton = SubCustomizeWindow.GetControl (6)
- RevertButton.SetText (2240)
- if not Changed:
- RevertButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- CancelButton = SubCustomizeWindow.GetControl (2)
- CancelButton.SetText (13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- TextArea = SubCustomizeWindow.GetControl (4)
- TextArea.SetBufferLength (65535)
- TextArea.SetText (BioStrRef)
-
- ClearButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, ClearBiography)
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DoneBiographyWindow)
- RevertButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, RevertBiography)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseSubCustomizeWindow)
-
- SubCustomizeWindow.ShowModal (MODAL_SHADOW_GRAY)
- return
-
-def ClearBiography():
- pc = GemRB.GameGetSelectedPCSingle ()
- BioStrRef = 62015+pc
- #GemRB.CreateString (BioStrRef, "")
- TextArea.SetText ("")
- return
-
-def DoneBiographyWindow ():
- global BioStrRef
-
- #TODO set bio
- pc = GemRB.GameGetSelectedPCSingle ()
- #pc is 1 based
- BioStrRef = 62015+pc
- GemRB.CreateString (BioStrRef, TextArea.QueryText())
- GemRB.SetPlayerString (pc, 74, BioStrRef)
- CloseSubCustomizeWindow ()
- return
-
-def RevertBiography():
- global BioStrRef
-
- BioTable = GemRB.LoadTable ("bios")
- pc = GemRB.GameGetSelectedPCSingle ()
- Class = GemRB.GetPlayerStat (pc, IE_CLASS)
- BioStrRef = BioTable.GetValue(Class,1)
- TextArea.SetText (BioStrRef)
- CloseSubCustomizeWindow ()
- return
-
-def CloseSubCustomizeWindow ():
- global SubCustomizeWindow
-
- if SubCustomizeWindow:
- SubCustomizeWindow.Unload ()
- SubCustomizeWindow = None
- return
-
-def CloseSubSubCustomizeWindow ():
- global SubSubCustomizeWindow
-
- if SubSubCustomizeWindow:
- SubSubCustomizeWindow.Unload ()
- SubSubCustomizeWindow = None
- return
-
-def OpenExportWindow ():
- global ExportWindow, NameField, ExportDoneButton
-
- ExportWindow = GemRB.LoadWindow(13)
-
- TextArea = ExportWindow.GetControl(2)
- TextArea.SetText(10962)
-
- TextArea = ExportWindow.GetControl(0)
- TextArea.GetCharacters ()
-
- ExportDoneButton = ExportWindow.GetControl(4)
- ExportDoneButton.SetText(11973)
- ExportDoneButton.SetState(IE_GUI_BUTTON_DISABLED)
-
- CancelButton = ExportWindow.GetControl(5)
- CancelButton.SetText(13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- NameField = ExportWindow.GetControl(6)
-
- ExportDoneButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, ExportDonePress)
- CancelButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, ExportCancelPress)
- NameField.SetEvent(IE_GUI_EDIT_ON_CHANGE, ExportEditChanged)
- ExportWindow.ShowModal (MODAL_SHADOW_GRAY)
- NameField.SetStatus (IE_GUI_CONTROL_FOCUSED)
- return
-
-def ExportDonePress():
- if ExportWindow:
- ExportWindow.Unload()
- #save file under name from EditControl
- pc = GemRB.GameGetSelectedPCSingle ()
- GemRB.SaveCharacter(pc, ExportFileName)
- return
-
-def ExportCancelPress():
- if ExportWindow:
- ExportWindow.Unload()
- return
-
-def ExportEditChanged():
- global ExportFileName
-
- ExportFileName = NameField.QueryText()
- if ExportFileName == "":
- ExportDoneButton.SetState(IE_GUI_BUTTON_DISABLED)
- else:
- ExportDoneButton.SetState(IE_GUI_BUTTON_ENABLED)
- return
-
###################################################
# End of file GUIREC.py
diff --git a/gemrb/GUIScripts/iwd2/GUISAVE.py b/gemrb/GUIScripts/iwd2/GUISAVE.py
deleted file mode 100644
index 71d14cd..0000000
--- a/gemrb/GUIScripts/iwd2/GUISAVE.py
+++ /dev/null
@@ -1,279 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-
-# GUISAVE.py - Save window
-
-###################################################
-
-import GemRB
-import GUICommon
-import LoadScreen
-from GUIDefines import *
-
-SaveWindow = 0
-ConfirmWindow = 0
-NameField = 0
-SaveButton = 0
-TextAreaControl = 0
-Games = ()
-ScrollBar = 0
-
-def OpenSaveWindow ():
- global SaveWindow, TextAreaControl, Games, ScrollBar
-
- if GUICommon.CloseOtherWindow (OpenSaveWindow):
- CloseSaveWindow ()
- return
-
- GemRB.HideGUI ()
- GUICommon.GameWindow.SetVisible(WINDOW_INVISIBLE)
-
- GemRB.LoadWindowPack ("GUISAVE", 800, 600)
- Window = SaveWindow = GemRB.LoadWindow (0)
- Window.SetFrame ()
- CancelButton=Window.GetControl (22)
- CancelButton.SetText (13727)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenSaveWindow)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
- GemRB.SetVar ("LoadIdx",0)
-
- for i in range(5):
- Button = Window.GetControl (55+i)
- Button.SetText (15588)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SavePress)
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- Button.SetVarAssoc ("LoadIdx",i)
-
- Button = Window.GetControl (60+i)
- Button.SetText (13957)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, DeleteGamePress)
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- Button.SetVarAssoc ("LoadIdx",i)
-
- #area previews
- Button = Window.GetControl (1+i)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- Button.SetFlags(IE_GUI_BUTTON_NO_IMAGE|IE_GUI_BUTTON_PICTURE,OP_SET)
-
- #PC portraits
- for j in range(PARTY_SIZE):
- Button = Window.GetControl (25+i*PARTY_SIZE+j)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
- Button.SetFlags(IE_GUI_BUTTON_NO_IMAGE|IE_GUI_BUTTON_PICTURE,OP_SET)
-
- ScrollBar=Window.GetControl (23)
- ScrollBar.SetEvent (IE_GUI_SCROLLBAR_ON_CHANGE, ScrollBarPress)
- Games=GemRB.GetSaveGames ()
- TopIndex = max (0, len(Games) - 5 + 1) #one more for the 'new game'
- GemRB.SetVar ("TopIndex",TopIndex)
- ScrollBar.SetVarAssoc ("TopIndex", TopIndex+1)
- ScrollBar.SetDefaultScrollBar ()
- ScrollBarPress ()
- Window.SetVisible (WINDOW_VISIBLE)
- return
-
-def ScrollBarPress():
- Window = SaveWindow
-
- #draw load game portraits
- Pos = GemRB.GetVar ("TopIndex")
- for i in range(5):
- ActPos = Pos + i
-
- Button1 = Window.GetControl (55+i)
- Button2 = Window.GetControl (60+i)
- if ActPos<=len(Games):
- Button1.SetState (IE_GUI_BUTTON_ENABLED)
- else:
- Button1.SetState (IE_GUI_BUTTON_DISABLED)
-
- if ActPos<len(Games):
- Slotname = Games[ActPos].GetName()
- Button2.SetState (IE_GUI_BUTTON_ENABLED)
- elif ActPos == len(Games):
- Slotname = 15304
- Button2.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- Slotname = ""
- Button2.SetState (IE_GUI_BUTTON_DISABLED)
-
- Label = Window.GetControl (0x10000005+i)
- Label.SetText (Slotname)
-
- if ActPos<len(Games):
- Slotname = Games[ActPos].GetGameDate()
- else:
- Slotname = ""
- Label = Window.GetControl (0x1000000a+i)
- Label.SetText (Slotname)
-
- Button=Window.GetControl (1+i)
- if ActPos<len(Games):
- Button.SetSprite2D(Games[ActPos].GetPreview())
- else:
- Button.SetPicture("")
- for j in range(PARTY_SIZE):
- Button=Window.GetControl (25+i*PARTY_SIZE+j)
- if ActPos<len(Games):
- Button.SetSprite2D(Games[ActPos].GetPortrait(j))
- else:
- Button.SetPicture("")
- return
-
-def AbortedSaveGame():
- if ConfirmWindow:
- ConfirmWindow.Unload ()
- SaveWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def ConfirmedSaveGame():
- global ConfirmWindow
-
- Pos = GemRB.GetVar ("TopIndex")+GemRB.GetVar ("LoadIdx")
- Label = ConfirmWindow.GetControl (3)
- Slotname = Label.QueryText ()
- LoadScreen.StartLoadScreen()
- if Pos < len(Games):
- GemRB.SaveGame(Games[Pos], Slotname, 22) #saves a game with version 2.2
- else:
- GemRB.SaveGame(None, Slotname, 22) #saves a game with version 2.2
- if ConfirmWindow:
- ConfirmWindow.Unload ()
- SaveWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def SavePress():
- global ConfirmWindow, NameField, SaveButton
-
- Pos = GemRB.GetVar ("TopIndex")+GemRB.GetVar ("LoadIdx")
- ConfirmWindow = GemRB.LoadWindow (1)
-
- #slot name
- if Pos<len(Games):
- Slotname = Games[Pos].GetName()
- save_strref = 15306
- else:
- Slotname = ""
- save_strref = 15588
- NameField = ConfirmWindow.GetControl (3)
- NameField.SetText (Slotname)
- NameField.SetEvent (IE_GUI_EDIT_ON_CHANGE, EditChange)
-
- #game hours (should be generated from game)
- if Pos<len(Games):
- Slotname = Games[Pos].GetGameDate()
- else:
- Slotname = ""
- Label = ConfirmWindow.GetControl (0x10000004)
- Label.SetText (Slotname)
-
- #areapreview
- #Button=ConfirmWindow.GetControl (0)
- #if Pos<len(Games):
- # Button.SetSprite2D(Games[Pos].GetPreview())
- #else:
- # Button.SetPicture("")
-
- #portraits
- #for j in range(PARTY_SIZE):
- # Button=ConfirmWindow.GetControl (25+j)
- # if Pos<len(Games):
- # Button.SetSprite2D(Games[ActPos].GetPortrait(j))
- # else:
- # Button.SetPicture("")
-
- #save
- SaveButton=ConfirmWindow.GetControl (7)
- SaveButton.SetText (save_strref)
- SaveButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, ConfirmedSaveGame)
- SaveButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
- #SaveButton.SetState (IE_GUI_BUTTON_DISABLED)
- if Slotname == "":
- SaveButton.SetState (IE_GUI_BUTTON_DISABLED)
-
- #cancel
- CancelButton=ConfirmWindow.GetControl (8)
- CancelButton.SetText (13727)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, AbortedSaveGame)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- ConfirmWindow.SetVisible (WINDOW_VISIBLE)
- NameField.SetStatus (IE_GUI_CONTROL_FOCUSED)
- return
-
-def EditChange():
- Name = NameField.QueryText ()
- if len(Name)==0:
- SaveButton.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- SaveButton.SetState (IE_GUI_BUTTON_ENABLED)
- return
-
-def DeleteGameConfirm():
- global Games
-
- TopIndex = GemRB.GetVar ("TopIndex")
- Pos = TopIndex +GemRB.GetVar ("LoadIdx")
- GemRB.DeleteSaveGame(Games[Pos])
- if TopIndex>0:
- GemRB.SetVar ("TopIndex",TopIndex-1)
- del Games[pos]
- ScrollBar.SetVarAssoc ("TopIndex", len(Games))
- ScrollBarPress()
- if ConfirmWindow:
- ConfirmWindow.Unload ()
- SaveWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def DeleteGameCancel():
- if ConfirmWindow:
- ConfirmWindow.Unload ()
- SaveWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def DeleteGamePress():
- global ConfirmWindow
-
- SaveWindow.SetVisible (WINDOW_INVISIBLE)
- ConfirmWindow=GemRB.LoadWindow (2)
- Text=ConfirmWindow.GetControl (0)
- Text.SetText (15305)
- DeleteButton=ConfirmWindow.GetControl (1)
- DeleteButton.SetText (13957)
- DeleteButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DeleteGameConfirm)
- CancelButton=ConfirmWindow.GetControl (2)
- CancelButton.SetText (13727)
- CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DeleteGameCancel)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- ConfirmWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def CloseSaveWindow ():
- if SaveWindow:
- SaveWindow.Unload ()
- if GemRB.GetVar ("QuitAfterSave"):
- GemRB.QuitGame ()
- GemRB.SetNextScript ("Start")
- return
-
- GUICommon.GameWindow.SetVisible(WINDOW_VISIBLE) #enabling the game control screen
- GemRB.UnhideGUI () #enabling the other windows
- return
diff --git a/gemrb/GUIScripts/iwd2/GUISPL.py b/gemrb/GUIScripts/iwd2/GUISPL.py
index 7325575..d2c5a4a 100644
--- a/gemrb/GUIScripts/iwd2/GUISPL.py
+++ b/gemrb/GUIScripts/iwd2/GUISPL.py
@@ -18,18 +18,18 @@
#
-# GUISPL.py - scripts to control priest spells windows from GUIPR winpack
+# GUISPL.py - scripts to control spells windows from GUISPL winpack
###################################################
import GemRB
import GUICommon
import GUICommonWindows
+import Spellbook
from GUIDefines import *
from ie_stats import *
from ie_action import ACT_CAST
-TopIndex = 0
SpellBookWindow = None
SpellBookSpellInfoWindow = None
SpellBookSpellLevel = 0
@@ -38,10 +38,15 @@ PortraitWindow = None
OldPortraitWindow = None
OptionsWindow = None
OldOptionsWindow = None
+ActiveSpellBooks = []
+BookCount = 0
+BookTopIndex = 0
+SelectedBook = 0
+BookNames = (1083,1079,1080,1078,1077,32,1081,39722)
def OpenSpellBookWindow ():
global SpellBookWindow, OptionsWindow, PortraitWindow
- global OldPortraitWindow, OldOptionsWindow, TopIndex
+ global OldPortraitWindow, OldOptionsWindow
if GUICommon.CloseOtherWindow (OpenSpellBookWindow):
if SpellBookWindow:
@@ -87,10 +92,6 @@ def OpenSpellBookWindow ():
Button = Window.GetControl (55 + i)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, RefreshSpellBookLevel)
Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
-
- for i in range (9):
- Button = Window.GetControl (55 + i)
- Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_SET)
Button.SetVarAssoc ("SpellBookSpellLevel", i)
# Setup memorized spells buttons
@@ -98,147 +99,218 @@ def OpenSpellBookWindow ():
Button = Window.GetControl (6 + i)
Button.SetBorder (0,0,0,0,0,0,0,0,160,0,1)
#Button.SetBAM ("SPELFRAM",0,0,0)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_OR)
- Button.SetState (IE_GUI_BUTTON_LOCKED)
+ Button.SetFlags (IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_PLAYONCE | IE_GUI_BUTTON_NO_IMAGE, OP_OR)
# Setup book spells buttons
for i in range (8):
Button = Window.GetControl (30 + i)
+ Button.SetFlags (IE_GUI_BUTTON_PLAYONCE, OP_OR)
Button.SetState (IE_GUI_BUTTON_LOCKED)
Button.SetVarAssoc ("SpellIndex", i)
- ScrollBar = Window.GetControl (54)
- TopIndex = 0
- GemRB.SetVar ("TopIndex",0)
- ScrollBar.SetVarAssoc ("TopIndex", 0)
+ GUICommonWindows.SetSelectionChangeHandler (SelectedNewPlayer)
+ SelectedNewPlayer ()
+ return
- GUICommonWindows.SetSelectionChangeHandler (UpdateSpellBookWindow)
- UpdateSpellBookWindow ()
+def SelectedNewPlayer ():
+ global ActiveSpellBooks
+ global BookTopIndex, BookCount, SelectedBook
+
+ Window = SpellBookWindow
+ pc = GemRB.GameGetSelectedPCSingle ()
+ ActiveSpellBooks=[]
+
+ for i in range(8):
+ if GemRB.GetKnownSpellsCount(pc, i)>0:
+ ActiveSpellBooks+=[i]
+ BookCount = len(ActiveSpellBooks)
+ BookTopIndex = 0
+ if len (ActiveSpellBooks):
+ SelectedBook = ActiveSpellBooks[0]
+ else:
+ SelectedBook = 0
+ GemRB.SetVar ("SelectedBook",SelectedBook)
+ UpdateSpellBook ()
return
-def UpdateSpellBookWindow ():
- global SpellBookMemorizedSpellList, PriestKnownSpellList, TopIndex
+def ResetScrollBar ():
+ pc = GemRB.GameGetSelectedPCSingle ()
+ ScrollBar = SpellBookWindow.GetControl (54)
+ GemRB.SetVar ("SpellTopIndex",0)
+ ScrollBar.SetVarAssoc ("SpellTopIndex", len(KnownSpellList))
+ ScrollBar.SetEvent (IE_GUI_SCROLLBAR_ON_CHANGE, ScrollBarPress)
+ ScrollBar.SetDefaultScrollBar ()
+
+def ScrollBarPress ():
+ UpdateSpellBookWindow ()
- SpellBookMemorizedSpellList = []
- SpellBookKnownSpellList = []
+def UpdateSpellBook ():
+ global SelectedBook
+
+ SelectedBook = GemRB.GetVar ("SelectedBook")
+ RefreshSpellBookLevel (False) # set up all the spell lists first
+ ResetScrollBar ()
+ UpdateSpellBookWindow ()
+
+def UpdateSpellBookWindow ():
+ global SpellBookSpellLevel
Window = SpellBookWindow
pc = GemRB.GameGetSelectedPCSingle ()
- type = IE_SPELL_TYPE_PRIEST
+
+ for i in range(4):
+ Button = Window.GetControl(88+i)
+
+ if len(ActiveSpellBooks)>BookTopIndex+i:
+ type = ActiveSpellBooks[BookTopIndex+i]
+ Button.SetText (BookNames[type])
+ Button.SetVarAssoc ("SelectedBook", type)
+ Button.SetFlags (IE_GUI_BUTTON_RADIOBUTTON, OP_OR)
+ Button.SetState (IE_GUI_BUTTON_ENABLED)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, UpdateSpellBook)
+ else:
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+ Button.SetText ("")
+
+ SelectedBook = GemRB.GetVar("SelectedBook")
+ type = SelectedBook
level = SpellBookSpellLevel
max_mem_cnt = GemRB.GetMemorizableSpellsCount (pc, type, level)
-
- #Label = Window.GetControl (0x10000032)
- #Label.SetText (GemRB.GetString(12137)+str(level+1) )
+ sorcerer_style = (type == IE_IWD2_SPELL_BARD) or (type == IE_IWD2_SPELL_SORCERER)
Name = GemRB.GetPlayerName (pc, 0)
- #Label = Window.GetControl (0xffffffff)
- #Label.SetText (Name)
+ Label = Window.GetControl (0xfffffff)
+ Label.SetText (Name)
Button = Window.GetControl (1)
Button.SetPicture (GemRB.GetPlayerPortrait (pc,0))
+ Button.SetState (IE_GUI_BUTTON_LOCKED)
- mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level)
+ mem_cnt = GetMemorizedSpellsCount () # count of unique memorized spells
+ true_mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level, True)
for i in range (24):
Button = Window.GetControl (6 + i)
- if i < mem_cnt:
- ms = GemRB.GetMemorizedSpell (pc, type, level, i)
- Button.SetSpellIcon (ms['SpellResRef'])
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_NAND)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_OR)
- if ms['Flags']:
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenSpellBookSpellUnmemorizeWindow)
+ Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_OR)
+ Label = Window.GetControl (0x1000003f+i)
+ # actually, it doesn't display any memorized spells for sorcerer-style spellbooks
+ if i < mem_cnt and not sorcerer_style:
+ ms = MemorizedSpellList[i]
+ spell = ms['SpellResRef']
+ Button.SetSpellIcon (spell)
+ Button.SetFlags (IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_PLAYONCE, OP_OR)
+ Button.SetTooltip (ms['SpellName'])
+ Button.SetVarAssoc ("SpellButton", i)
+ # since spells are stacked, we need to check first whether to unmemorize (deplete) or remove (already depeleted)
+ if ms['MemoCount'] < ms['KnownCount']:
+ # already depleted, just remove
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, lambda: OnSpellBookUnmemorizeSpell(ms['MemoCount']))
else:
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OnSpellBookUnmemorizeSpell)
+ # deplete and remove
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenSpellBookSpellRemoveWindow)
Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, OpenSpellBookSpellInfoWindow)
- spell = GemRB.GetSpell (ms['SpellResRef'])
- Button.SetTooltip (spell['SpellName'])
- SpellBookMemorizedSpellList.append (ms['SpellResRef'])
- Button.SetVarAssoc ("SpellButton", i)
- Button.EnableBorder (0, ms['Flags'] == 0)
+ tmp = str(ms['MemoCount'])+"/"+str(ms['KnownCount'])
+ Label.SetText (tmp)
else:
- if i < max_mem_cnt:
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_NAND)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_OR)
- else:
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_OR)
- Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_NAND)
+ Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_NAND)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, None)
Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, None)
- Button.SetTooltip ('')
Button.EnableBorder (0, 0)
+ Label.SetText ('')
-
- known_cnt = GemRB.GetKnownSpellsCount (pc, type, level)
+ known_cnt = len (KnownSpellList)
+ SpellTopIndex = GemRB.GetVar ("SpellTopIndex")
for i in range (8):
Button = Window.GetControl (30 + i)
- if i+TopIndex < known_cnt:
- ks = GemRB.GetKnownSpell (pc, type, level, i+TopIndex)
- Button.SetSpellIcon (ks['SpellResRef'])
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_NAND)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OnSpellBookMemorizeSpell)
+ Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_OR)
+ Label = Window.GetControl (0x10000025+i)
+ if i+SpellTopIndex < known_cnt:
+ ks = KnownSpellList[i+SpellTopIndex]
+ spell = ks['SpellResRef']
+ Button.SetSpellIcon (spell)
+ if not sorcerer_style:
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OnSpellBookMemorizeSpell)
Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, OpenSpellBookSpellInfoWindow)
- spell = GemRB.GetSpell (ks['SpellResRef'])
- Button.SetTooltip (spell['SpellName'])
- SpellBookKnownSpellList.append (ks['SpellResRef'])
- Button.SetVarAssoc ("SpellButton", 100 + i)
-
+ Label.SetText (ks['SpellName'])
+ Button.SetVarAssoc ("SpellButton", 100 + i + SpellTopIndex)
else:
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_OR)
Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_NAND)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, None)
Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, None)
- Button.SetTooltip ('')
Button.EnableBorder (0, 0)
+ Label.SetText ('')
+
+ # number of available spell slots
+ # sorcerer-style books are different, since max_mem_cnt holds the total level capacity, not the slot count
+ # and they display just the current and total number of memorizations per level
+ Label = Window.GetControl (0x10000004)
+ if sorcerer_style:
+ Label.SetText (str(true_mem_cnt)+"/"+str(max_mem_cnt))
+ else:
+ # reset mem_cnt to take into account stacks
+ mem_cnt = GetMemorizedSpellsCount (True)
+ Label.SetText (str(max_mem_cnt-mem_cnt))
#if actor is uncontrollable, make this grayed
CantCast = GemRB.GetPlayerStat(pc, IE_DISABLEDBUTTON)&(1<<ACT_CAST)
- if CantCast or GemRB.GetPlayerStat (pc, IE_STATE_ID) & STATE_DEAD:
- Window.SetVisible (WINDOW_GRAYED)
- else:
- Window.SetVisible (WINDOW_VISIBLE)
+ GUICommon.AdjustWindowVisibility (Window, pc, CantCast)
PortraitWindow.SetVisible (WINDOW_VISIBLE)
OptionsWindow.SetVisible (WINDOW_VISIBLE)
return
-#TODO: spell type selector
+def GetMemorizedSpellsCount (total=False):
+ '''count the real number of spells in MemorizedSpellList'''
+ # can't use len here, since there could be more than one memorization (a "stack")
+ # put the counts into a list and sum it, but be careful about depleted spells
+ # eg. fully depleted should still count as 1 and each partial too
+ count = 'MemoCount' # non-depleted only
+ if total:
+ count = 'KnownCount' # all
+
+ counts = map (lambda x: (x[count] & x[count]) or 1, MemorizedSpellList)
+ return sum(counts)
+
def SpellBookPrevPress ():
- global SpellType
+ global BookTopIndex
- UpdateSpellBookWindow ()
+ BookTopIndex = GemRB.GetVar ("BookTopIndex")
+ if BookTopIndex>0:
+ BookTopIndex -= 1
+ GemRB.SetVar("BookTopIndex", BookTopIndex)
+ UpdateSpellBook ()
return
-#TODO: spell type selector
def SpellBookNextPress ():
- global SpellBookSpellLevel
+ global BookTopIndex
- UpdateSpellBookWindow ()
+ BookTopIndex = GemRB.GetVar ("BookTopIndex")
+ if BookTopIndex<BookCount-4:
+ BookTopIndex += 1
+ GemRB.SetVar("BookTopIndex", BookTopIndex)
+ UpdateSpellBook ()
return
-def RefreshSpellBookLevel ():
- global SpellBookSpellLevel
+def RefreshSpellBookLevel (update=True):
+ global SpellBookSpellLevel, KnownSpellList, MemorizedSpellList
- SpellBookSpellLevel = GemRB.GetVar ("PriestSpellLevel")
- UpdateSpellBookWindow ()
+ SpellBookSpellLevel = GemRB.GetVar ("SpellBookSpellLevel")
+ pc = GemRB.GameGetSelectedPCSingle ()
+ KnownSpellList = Spellbook.GetKnownSpellsLevel (pc, SelectedBook, SpellBookSpellLevel)
+ MemorizedSpellList = Spellbook.GetMemorizedSpells (pc, SelectedBook, SpellBookSpellLevel)
+ if update:
+ UpdateSpellBookWindow ()
return
def OpenSpellBookSpellInfoWindow ():
global SpellBookSpellInfoWindow
- GemRB.HideGUI ()
-
if SpellBookSpellInfoWindow != None:
- if SpellBookSpellInfoWindow:
- SpellBookSpellInfoWindow.Unload ()
+ SpellBookSpellInfoWindow.Unload ()
SpellBookSpellInfoWindow = None
- GemRB.SetVar ("FloatWindow", -1)
- GemRB.UnhideGUI ()
return
SpellBookSpellInfoWindow = Window = GemRB.LoadWindow (3)
- GemRB.SetVar ("FloatWindow", SpellBookSpellInfoWindow.ID)
#back
Button = Window.GetControl (5)
@@ -246,12 +318,15 @@ def OpenSpellBookSpellInfoWindow ():
Button.SetFlags(IE_GUI_BUTTON_CANCEL,OP_OR)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenSpellBookSpellInfoWindow)
+ pc = GemRB.GameGetSelectedPCSingle ()
+ level = SpellBookSpellLevel
+ type = SelectedBook
index = GemRB.GetVar ("SpellButton")
if index < 100:
- ResRef = SpellBookMemorizedSpellList[index]
+ ms = GemRB.GetMemorizedSpell (pc, type, level, index)
+ ResRef = ms['SpellResRef']
else:
- ResRef = SpellBookKnownSpellList[index - 100]
-
+ ResRef = KnownSpellList[index - 100]["SpellResRef"]
spell = GemRB.GetSpell (ResRef)
Label = Window.GetControl (0x0fffffff)
@@ -263,48 +338,49 @@ def OpenSpellBookSpellInfoWindow ():
Text = Window.GetControl (3)
Text.SetText (spell['SpellDesc'])
- #IconResRef = 'SPL' + spell['SpellBookIcon'][2:]
-
- #Button = Window.GetControl (5)
- #Button.SetSprites (IconResRef, 0, 0, 0, 0, 0)
-
-
- GemRB.UnhideGUI ()
Window.ShowModal (MODAL_SHADOW_GRAY)
return
+# FIXME: for now don't do anything if paused, since we'd get stuck with the first frame
+# EH, doesn't work on the known spell buttons?
+def FlashOverButton (ControlID):
+ pause = GemRB.GamePause (10, 1) # quietly get the pause state
+ if pause == 1: # paused
+ return
+ Button = SpellBookWindow.GetControl(ControlID)
+ Button.SetAnimation ("FLASH")
+ # TODO: wait until it is done; the two flashes for memorizing were not shown in parallel
def OnSpellBookMemorizeSpell ():
pc = GemRB.GameGetSelectedPCSingle ()
level = SpellBookSpellLevel
- type = IE_SPELL_TYPE_PRIEST
-
- index = GemRB.GetVar ("SpellButton") - 100 + TopIndex
-
+ type = SelectedBook
+ Window = SpellBookWindow
+
+ index = GemRB.GetVar ("SpellButton") - 100
+ SpellTopIndex = GemRB.GetVar ("SpellTopIndex")
if GemRB.MemorizeSpell (pc, type, level, index):
- UpdateSpellBookWindow ()
+ RefreshSpellBookLevel () # calls also UpdateSpellBookWindow ()
+ GemRB.PlaySound ("GAM_24")
+ FlashOverButton (index - SpellTopIndex + 30) # FIXME: wrong button if the spell will be stacked
+ mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level, False)
+ FlashOverButton (mem_cnt + 5)
return
def OpenSpellBookSpellRemoveWindow ():
global SpellBookSpellUnmemorizeWindow
- GemRB.HideGUI ()
-
if SpellBookSpellUnmemorizeWindow != None:
if SpellBookSpellUnmemorizeWindow:
SpellBookSpellUnmemorizeWindow.Unload ()
SpellBookSpellUnmemorizeWindow = None
- GemRB.SetVar ("FloatWindow", -1)
-
- GemRB.UnhideGUI ()
return
SpellBookSpellUnmemorizeWindow = Window = GemRB.LoadWindow (5)
- GemRB.SetVar ("FloatWindow", SpellBookSpellUnmemorizeWindow.ID)
# "Are you sure you want to ....?"
TextArea = Window.GetControl (3)
- TextArea.SetText (63745)
+ TextArea.SetText (11824)
# Remove
Button = Window.GetControl (0)
@@ -318,78 +394,48 @@ def OpenSpellBookSpellRemoveWindow ():
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenSpellBookSpellRemoveWindow)
Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
- GemRB.UnhideGUI ()
Window.ShowModal (MODAL_SHADOW_GRAY)
return
-def OpenSpellBookSpellUnmemorizeWindow ():
- global SpellBookSpellUnmemorizeWindow
-
- GemRB.HideGUI ()
-
- if SpellBookSpellUnmemorizeWindow != None:
- if SpellBookSpellUnmemorizeWindow:
- SpellBookSpellUnmemorizeWindow.Unload ()
- SpellBookSpellUnmemorizeWindow = None
- GemRB.SetVar ("FloatWindow", -1)
-
- GemRB.UnhideGUI ()
+# since we can have semidepleted stacks, first make sure we unmemorize the depleted ones, only then unmemorize
+def OnSpellBookUnmemorizeSpell (mem_cnt):
+ if mem_cnt == 0:
+ # everything is depleted, so just remove
+ OnSpellBookRemoveSpell ()
return
- SpellBookSpellUnmemorizeWindow = Window = GemRB.LoadWindow (5)
- GemRB.SetVar ("FloatWindow", SpellBookSpellUnmemorizeWindow.ID)
-
- # "Are you sure you want to ....?"
- TextArea = Window.GetControl (3)
- TextArea.SetText (11824)
-
- # Remove
- Button = Window.GetControl (0)
- Button.SetText (17507)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OnSpellBookUnmemorizeSpell)
- Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- # Cancel
- Button = Window.GetControl (1)
- Button.SetText (13727)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenSpellBookSpellUnmemorizeWindow)
- Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+ # remove one depleted spell without touching the still memorized
+ # we'd need a different spell index, but it's all handled in the core
+ index = GemRB.GetVar ("SpellButton")
+ UnmemoSpell (index, True)
- GemRB.UnhideGUI ()
- Window.ShowModal (MODAL_SHADOW_GRAY)
return
-def OnSpellBookUnmemorizeSpell ():
+# not like removing spells in bg2, where you could delete known spells from the spellbook!
+def OnSpellBookRemoveSpell ():
if SpellBookSpellUnmemorizeWindow:
- OpenSpellBookSpellUnmemorizeWindow ()
-
- pc = GemRB.GameGetSelectedPCSingle ()
- level = SpellBookSpellLevel
- type = IE_SPELL_TYPE_PRIEST
+ OpenSpellBookSpellRemoveWindow ()
index = GemRB.GetVar ("SpellButton")
+ UnmemoSpell (index)
- if GemRB.UnmemorizeSpell (pc, type, level, index):
- UpdateSpellBookWindow ()
return
-
-def OnSpellBookRemoveSpell ():
- if SpellBookSpellUnmemorizeWindow:
- OpenSpellBookSpellRemoveWindow ()
-
+def UnmemoSpell (index, onlydepleted=False):
pc = GemRB.GameGetSelectedPCSingle ()
level = SpellBookSpellLevel
- type = IE_SPELL_TYPE_PRIEST
+ type = SelectedBook
- index = GemRB.GetVar ("SpellButton")
+ # remove spell from memory
+ if GemRB.UnmemorizeSpell (pc, type, level, index, onlydepleted):
+ UpdateSpellBookWindow ()
+ GemRB.PlaySound ("GAM_44")
+ FlashOverButton (index + 6)
+ else:
+ print "Spell unmemorization failed, huh?", pc, type, level, index, onlydepleted
- #remove spell from memory
- #GemRB.UnmemorizeSpell (pc, type, level, index)
- #remove spell from book
- #GemRB.RemoveSpell (pc, type, level, index)
+ RefreshSpellBookLevel (False)
UpdateSpellBookWindow ()
- return
###################################################
# End of file GUISPL.py
diff --git a/gemrb/GUIScripts/iwd2/GUIWORLD.py b/gemrb/GUIScripts/iwd2/GUIWORLD.py
index 885b989..b973b31 100644
--- a/gemrb/GUIScripts/iwd2/GUIWORLD.py
+++ b/gemrb/GUIScripts/iwd2/GUIWORLD.py
@@ -26,8 +26,6 @@
import GemRB
from GUIDefines import *
import GUICommon
-from GUIClasses import GWindow
-import GUICommonWindows
import MessageWindow
import CommonWindow
@@ -147,7 +145,7 @@ def DeathWindow():
return
def DeathWindowEnd ():
- GemRB.GamePause (1,1)
+ GemRB.GamePause (1,3)
GemRB.LoadWindowPack (GUICommon.GetWindowPack())
Window = GemRB.LoadWindow (17)
diff --git a/gemrb/GUIScripts/iwd2/GamePlay.py b/gemrb/GUIScripts/iwd2/GamePlay.py
deleted file mode 100644
index 959ae90..0000000
--- a/gemrb/GUIScripts/iwd2/GamePlay.py
+++ /dev/null
@@ -1,189 +0,0 @@
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-#
-#GamePlay Options Menu
-import GemRB
-from GUIDefines import *
-
-GamePlayWindow = 0
-TextAreaControl = 0
-
-def OnLoad():
- global GamePlayWindow, TextAreaControl
- GemRB.LoadWindowPack("GUIOPT", 800, 600)
- GamePlayWindow = GemRB.LoadWindow(8)
- GamePlayWindow.SetFrame( )
- TextAreaControl = GamePlayWindow.GetControl(40)
- DelayButton = GamePlayWindow.GetControl(21)
- DelaySlider = GamePlayWindow.GetControl(1)
- MouseSpdButton = GamePlayWindow.GetControl(22)
- MouseSpdSlider = GamePlayWindow.GetControl(2)
- KeySpdButton = GamePlayWindow.GetControl(23)
- KeySpdSlider = GamePlayWindow.GetControl(3)
- DifficultyButton = GamePlayWindow.GetControl(24)
- DifficultySlider = GamePlayWindow.GetControl(12)
- DitherButton = GamePlayWindow.GetControl(25)
- DitherButtonB = GamePlayWindow.GetControl(14)
- InfravisionButton = GamePlayWindow.GetControl(44)
- InfravisionButtonB = GamePlayWindow.GetControl(42)
- WeatherButton = GamePlayWindow.GetControl(46)
- WeatherButtonB = GamePlayWindow.GetControl(47)
- MaxHPButton = GamePlayWindow.GetControl(49)
- MaxHPButtonB = GamePlayWindow.GetControl(50)
- BloodButton = GamePlayWindow.GetControl(27)
- BloodButtonB = GamePlayWindow.GetControl(19)
- FeedbackButton = GamePlayWindow.GetControl(5)
- AutoPauseButton = GamePlayWindow.GetControl(6)
- OkButton = GamePlayWindow.GetControl(7)
- CancelButton = GamePlayWindow.GetControl(20)
- TextAreaControl.SetText(18042)
-
- OkButton.SetText(11973)
- OkButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- CancelButton.SetText(13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- FeedbackButton.SetText(17163)
- AutoPauseButton.SetText(17166)
- DelayButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, DelayPress)
- DelaySlider.SetEvent(IE_GUI_SLIDER_ON_CHANGE, DelayPress)
- DelaySlider.SetVarAssoc("Tooltips",TOOLTIP_DELAY_FACTOR)
-
- KeySpdButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, KeySpdPress)
- KeySpdSlider.SetEvent(IE_GUI_SLIDER_ON_CHANGE, KeySpdPress)
- KeySpdSlider.SetVarAssoc("Keyboard Scroll Speed",36)
-
- MouseSpdButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, MouseSpdPress)
- MouseSpdSlider.SetEvent(IE_GUI_SLIDER_ON_CHANGE, MouseSpdPress)
- MouseSpdSlider.SetVarAssoc("Mouse Scroll Speed",36)
-
- DifficultyButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, DifficultyPress)
- DifficultySlider.SetEvent(IE_GUI_SLIDER_ON_CHANGE, DifficultyPress)
- DifficultySlider.SetVarAssoc("Difficulty Level",2)
-
- BloodButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, BloodPress)
- BloodButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, BloodPress)
- BloodButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- BloodButtonB.SetVarAssoc("Gore",1)
- BloodButtonB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- DitherButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, DitherPress)
- DitherButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, DitherPress)
- DitherButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- DitherButtonB.SetVarAssoc("Always Dither",1)
- DitherButtonB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- InfravisionButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, InfravisionPress)
- InfravisionButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, InfravisionPress)
- InfravisionButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- InfravisionButtonB.SetVarAssoc("Darkvision",1)
- InfravisionButtonB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- WeatherButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, WeatherPress)
- WeatherButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, WeatherPress)
- WeatherButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- WeatherButtonB.SetVarAssoc("Weather",1)
- WeatherButtonB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- MaxHPButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, MaxHPPress)
- MaxHPButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, MaxHPPressB)
- MaxHPButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- MaxHPButtonB.SetVarAssoc("Maximum HP",1)
- MaxHPButtonB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- FeedbackButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, FeedbackPress)
- AutoPauseButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, AutoPausePress)
- OkButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, OkPress)
- CancelButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, CancelPress)
- GamePlayWindow.SetVisible(WINDOW_VISIBLE)
- return
-
-def DelayPress():
- TextAreaControl.SetText(18017)
- GemRB.SetTooltipDelay (GemRB.GetVar ("Tooltips") )
- return
-
-def KeySpdPress():
- TextAreaControl.SetText(18019)
- return
-
-def MouseSpdPress():
- TextAreaControl.SetText(18018)
- GemRB.SetMouseScrollSpeed (GemRB.GetVar ("Mouse Scroll Speed") )
- return
-
-def DifficultyPress():
- TextAreaControl.SetText(18020)
- return
-
-def BloodPress():
- TextAreaControl.SetText(18023)
- return
-
-def DitherPress():
- TextAreaControl.SetText(18021)
- return
-
-def InfravisionPress():
- TextAreaControl.SetText(11797)
- return
-
-def WeatherPress():
- TextAreaControl.SetText(20619)
- return
-
-def RestUntilHealPress():
- TextAreaControl.SetText(2242)
- return
-
-def MaxHPPress():
- TextAreaControl.SetText(15136)
- return
-
-def MaxHPPressB():
- #TODO: TextAreaControl.SetText(15136)
- return
-
-def FeedbackPress():
- GamePlayWindow.SetVisible(WINDOW_INVISIBLE)
- if GamePlayWindow:
- GamePlayWindow.Unload()
- GemRB.SetNextScript("Feedback")
- return
-
-def AutoPausePress():
- GamePlayWindow.SetVisible(WINDOW_INVISIBLE)
- if GamePlayWindow:
- GamePlayWindow.Unload()
- GemRB.SetNextScript("AutoPause")
- return
-
-def OkPress():
- GamePlayWindow.SetVisible(WINDOW_INVISIBLE)
- if GamePlayWindow:
- GamePlayWindow.Unload()
- GemRB.SetNextScript("Options")
- return
-
-def CancelPress():
- GamePlayWindow.SetVisible(WINDOW_INVISIBLE)
- if GamePlayWindow:
- GamePlayWindow.Unload()
- GemRB.SetNextScript("Options")
- return
diff --git a/gemrb/GUIScripts/iwd2/Gender.py b/gemrb/GUIScripts/iwd2/Gender.py
index e03b054..e879adf 100644
--- a/gemrb/GUIScripts/iwd2/Gender.py
+++ b/gemrb/GUIScripts/iwd2/Gender.py
@@ -110,5 +110,5 @@ def BackPress():
def NextPress():
if GenderWindow:
GenderWindow.Unload()
- GemRB.SetNextScript("Portrait") #appearance
+ GemRB.SetNextScript("CGPortrait") #appearance
return
diff --git a/gemrb/GUIScripts/iwd2/Graphics.py b/gemrb/GUIScripts/iwd2/Graphics.py
deleted file mode 100644
index b1fc93b..0000000
--- a/gemrb/GUIScripts/iwd2/Graphics.py
+++ /dev/null
@@ -1,184 +0,0 @@
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-#
-#Graphics Menu
-import GemRB
-from GUIDefines import *
-
-GraphicsWindow = 0
-TextAreaControl = 0
-
-def OnLoad():
- global GraphicsWindow, TextAreaControl
- GemRB.LoadWindowPack("GUIOPT", 800, 600)
- GraphicsWindow = GemRB.LoadWindow(6)
- GraphicsWindow.SetFrame( )
-
- TextAreaControl = GraphicsWindow.GetControl(33)
- BrightnessButton = GraphicsWindow.GetControl(35)
- BrightnessSlider = GraphicsWindow.GetControl(3)
- BrightnessSlider.SetVarAssoc("Brightness Correction",0)
-
- ContrastButton = GraphicsWindow.GetControl(36)
- ContrastSlider = GraphicsWindow.GetControl(22)
- ContrastSlider.SetVarAssoc("Gamma Correction",1)
-
- BppButton = GraphicsWindow.GetControl(37)
- BppButtonB1 = GraphicsWindow.GetControl(5)
- BppButtonB2 = GraphicsWindow.GetControl(6)
- BppButtonB3 = GraphicsWindow.GetControl(7)
- BppButtonB1.SetFlags(IE_GUI_BUTTON_RADIOBUTTON,OP_OR)
- BppButtonB2.SetFlags(IE_GUI_BUTTON_RADIOBUTTON,OP_OR)
- BppButtonB3.SetFlags(IE_GUI_BUTTON_RADIOBUTTON,OP_OR)
- BppButtonB1.SetVarAssoc("BitsPerPixel",16)
- BppButtonB2.SetVarAssoc("BitsPerPixel",24)
- BppButtonB3.SetVarAssoc("BitsPerPixel",32)
- BppButtonB1.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
- BppButtonB2.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
- BppButtonB3.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
- FullScreenButton = GraphicsWindow.GetControl(38)
- FullScreenButtonB = GraphicsWindow.GetControl(9)
- FullScreenButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- FullScreenButtonB.SetVarAssoc("Full Screen",1)
- FullScreenButtonB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- SoftMirrBltButton = GraphicsWindow.GetControl(44)
- SoftMirrBltButtonB = GraphicsWindow.GetControl(40)
- SoftMirrBltButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- SoftMirrBltButtonB.SetVarAssoc("SoftMirrorBlt",1)
- SoftMirrBltButtonB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- SoftTransBltButton = GraphicsWindow.GetControl(46)
- SoftTransBltButtonB = GraphicsWindow.GetControl(41)
- SoftTransBltButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- SoftTransBltButtonB.SetVarAssoc("SoftSrcKeyBlt",1)
- SoftTransBltButtonB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- SoftStandBltButton = GraphicsWindow.GetControl(48)
- SoftStandBltButtonB = GraphicsWindow.GetControl(42)
- SoftStandBltButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- SoftStandBltButtonB.SetVarAssoc("SoftBltFast",1)
- SoftStandBltButtonB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- TransShadowButton = GraphicsWindow.GetControl(50)
- TransShadowButtonB = GraphicsWindow.GetControl(51)
- TransShadowButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- TransShadowButtonB.SetVarAssoc("Translucent Shadows",1)
- TransShadowButtonB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- TransBlitButton = GraphicsWindow.GetControl(52)
- TransBlitButtonB = GraphicsWindow.GetControl(56)
- TransBlitButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- TransBlitButtonB.SetVarAssoc("Translucent Blts",1)
- TransBlitButtonB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- StaticAniButton = GraphicsWindow.GetControl(54)
- StaticAniButtonB = GraphicsWindow.GetControl(57)
- StaticAniButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- StaticAniButtonB.SetVarAssoc("Static Animations",1)
- StaticAniButtonB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- OkButton = GraphicsWindow.GetControl(21)
- CancelButton = GraphicsWindow.GetControl(32)
- TextAreaControl.SetText(18038)
- OkButton.SetText(11973)
- CancelButton.SetText(13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- BrightnessButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, BrightnessPress)
- BrightnessSlider.SetEvent(IE_GUI_SLIDER_ON_CHANGE, BrightnessPress)
- ContrastButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, ContrastPress)
- ContrastSlider.SetEvent(IE_GUI_SLIDER_ON_CHANGE, ContrastPress)
- BppButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, BppPress)
- BppButtonB1.SetEvent(IE_GUI_BUTTON_ON_PRESS, BppPress)
- BppButtonB2.SetEvent(IE_GUI_BUTTON_ON_PRESS, BppPress)
- BppButtonB3.SetEvent(IE_GUI_BUTTON_ON_PRESS, BppPress)
- FullScreenButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, FullScreenPress)
- FullScreenButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, FullScreenPress)
- TransShadowButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, TransShadowPress)
- TransShadowButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, TransShadowPress)
- SoftMirrBltButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, SoftMirrBltPress)
- SoftMirrBltButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, SoftMirrBltPress)
- SoftTransBltButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, SoftTransBltPress)
- SoftTransBltButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, SoftTransBltPress)
- SoftStandBltButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, SoftStandBltPress)
- SoftStandBltButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, SoftStandBltPress)
- TransBlitButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, TransBlitPress)
- TransBlitButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, TransBlitPress)
- StaticAniButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, StaticAniPress)
- StaticAniButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, StaticAniPress)
- OkButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, OkPress)
- CancelButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, CancelPress)
-
- GraphicsWindow.SetVisible(WINDOW_VISIBLE)
- return
-
-def BrightnessPress():
- TextAreaControl.SetText(17203)
- GemRB.SetGamma (GemRB.GetVar("Brightness Correction"),GemRB.GetVar("Gamma Correction")/2)
- return
-
-def ContrastPress():
- TextAreaControl.SetText(17204)
- GemRB.SetGamma (GemRB.GetVar("Brightness Correction"),GemRB.GetVar("Gamma Correction")/2)
- return
-
-def BppPress():
- TextAreaControl.SetText(17205)
- return
-
-def FullScreenPress():
- TextAreaControl.SetText(18000)
- GemRB.SetFullScreen (GemRB.GetVar("Full Screen"))
- return
-
-def TransShadowPress():
- TextAreaControl.SetText(20620)
- return
-
-def SoftMirrBltPress():
- TextAreaControl.SetText(18004)
- return
-
-def SoftTransBltPress():
- TextAreaControl.SetText(18006)
- return
-
-def SoftStandBltPress():
- TextAreaControl.SetText(18007)
- return
-
-def TransBlitPress():
- TextAreaControl.SetText(15141)
- return
-
-def StaticAniPress():
- TextAreaControl.SetText(18004)
- return
-
-def OkPress():
- if GraphicsWindow:
- GraphicsWindow.Unload()
- GemRB.SetNextScript("Options")
- return
-
-def CancelPress():
- if GraphicsWindow:
- GraphicsWindow.Unload()
- GemRB.SetNextScript("Options")
- return
diff --git a/gemrb/GUIScripts/iwd2/MessageWindow.py b/gemrb/GUIScripts/iwd2/MessageWindow.py
index b67a95e..d65391d 100644
--- a/gemrb/GUIScripts/iwd2/MessageWindow.py
+++ b/gemrb/GUIScripts/iwd2/MessageWindow.py
@@ -39,6 +39,7 @@ def OnLoad():
GemRB.SetVar ("MessageWindow", MessageWindow.ID)
GemRB.SetVar ("PortraitWindow", PortraitWindow.ID)
+ GemRB.SetVar ("ActionsWindow", 12345) # dummy so the EF_ACTION callback works
GemRB.SetVar ("TopWindow", -1)
GemRB.SetVar ("OtherWindow", -1)
GemRB.SetVar ("FloatWindow", -1)
diff --git a/gemrb/GUIScripts/iwd2/Movies.py b/gemrb/GUIScripts/iwd2/Movies.py
deleted file mode 100644
index 3fd337d..0000000
--- a/gemrb/GUIScripts/iwd2/Movies.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-#
-import GemRB
-from GUIDefines import *
-
-MovieWindow = 0
-TextAreaControl = 0
-MoviesTable = 0
-
-def OnLoad():
- global MovieWindow, TextAreaControl, MoviesTable
-
- GemRB.LoadWindowPack("GUIMOVIE", 800, 600)
- MovieWindow = GemRB.LoadWindow(2)
- MovieWindow.SetFrame ()
- TextAreaControl = MovieWindow.GetControl(0)
- TextAreaControl.SetFlags(IE_GUI_TEXTAREA_SELECTABLE)
- PlayButton = MovieWindow.GetControl(2)
- CreditsButton = MovieWindow.GetControl(3)
- DoneButton = MovieWindow.GetControl(4)
- MoviesTable = GemRB.LoadTable("MOVIDESC")
- for i in range(0, MoviesTable.GetRowCount() ):
- t = MoviesTable.GetRowName(i)
- if GemRB.GetVar(t)==1:
- s = MoviesTable.GetValue(i, 0)
- TextAreaControl.Append(s,-1)
- TextAreaControl.SetVarAssoc("MovieIndex",0)
- PlayButton.SetText(17318)
- CreditsButton.SetText(15591)
- DoneButton.SetText(11973)
- DoneButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- PlayButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, PlayPress)
- CreditsButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, CreditsPress)
- DoneButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, DonePress)
-
- MovieWindow.SetVisible(WINDOW_VISIBLE)
- return
-
-def PlayPress():
- s = GemRB.GetVar("MovieIndex")
- for i in range(0, MoviesTable.GetRowCount() ):
- t = MoviesTable.GetRowName(i)
- if GemRB.GetVar(t)==1:
- if s==0:
- s = MoviesTable.GetRowName(i)
- GemRB.PlayMovie(s, 1)
- MovieWindow.Invalidate()
- return
- s = s - 1
- return
-
-def CreditsPress():
- if MovieWindow:
- MovieWindow.Unload()
- GemRB.SetNextScript("Songs")
- return
-
-def DonePress():
- if MovieWindow:
- MovieWindow.Unload()
- GemRB.SetNextScript("Options")
- return
diff --git a/gemrb/GUIScripts/iwd2/Options.py b/gemrb/GUIScripts/iwd2/Options.py
index ccf7653..f8824f1 100644
--- a/gemrb/GUIScripts/iwd2/Options.py
+++ b/gemrb/GUIScripts/iwd2/Options.py
@@ -20,6 +20,7 @@
# Options.py - scripts to control options windows mostly from GUIOPT winpack
import GemRB
+import GUIOPT
from GUIDefines import *
OptionsWindow = 0
@@ -58,15 +59,15 @@ def OnLoad():
ReturnButton = OptionsWindow.GetControl(11)
GraphicsButton.SetText(17162)
- GraphicsButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, GraphicsPress)
+ GraphicsButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, GUIOPT.OpenVideoOptionsWindow)
SoundButton.SetText(17164)
- SoundButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, SoundPress)
+ SoundButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, GUIOPT.OpenAudioOptionsWindow)
GamePlayButton.SetText(17165)
- GamePlayButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, GamePlayPress)
+ GamePlayButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, GUIOPT.OpenGameplayOptionsWindow)
MoviesButton.SetText(15415)
- MoviesButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, MoviePress)
+ MoviesButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, GUIOPT.OpenMovieWindow)
KeyboardButton.SetText(33468)
- KeyboardButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, None) #TODO: KeyboardPress
+ KeyboardButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, GUIOPT.OpenHotkeyOptionsWindow)
ReturnButton.SetText(10308)
ReturnButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, ReturnPress)
@@ -82,31 +83,3 @@ def ReturnPress():
OptionsWindow.Unload()
GemRB.SetNextScript("Start")
return
-
-def GraphicsPress():
- global OptionsWindow
- if OptionsWindow:
- OptionsWindow.Unload()
- GemRB.SetNextScript("Graphics")
- return
-
-def SoundPress():
- global OptionsWindow
- if OptionsWindow:
- OptionsWindow.Unload()
- GemRB.SetNextScript("Sound")
- return
-
-def GamePlayPress():
- global OptionsWindow
- if OptionsWindow:
- OptionsWindow.Unload()
- GemRB.SetNextScript("GamePlay")
- return
-
-def MoviePress():
- global OptionsWindow
- if OptionsWindow:
- OptionsWindow.Unload()
- GemRB.SetNextScript("Movies")
- return
diff --git a/gemrb/GUIScripts/iwd2/Portrait.py b/gemrb/GUIScripts/iwd2/Portrait.py
deleted file mode 100644
index db1245d..0000000
--- a/gemrb/GUIScripts/iwd2/Portrait.py
+++ /dev/null
@@ -1,225 +0,0 @@
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-#
-#character generation, appearance (GUICG12)
-import GemRB
-from GUIDefines import *
-
-AppearanceWindow = 0
-PortraitButton = 0
-PortraitsTable = 0
-LastPortrait = 0
-Gender = 0
-
-def SetPicture ():
- global PortraitsTable, LastPortrait
-
- PortraitName = PortraitsTable.GetRowName (LastPortrait)+"L"
- PortraitButton.SetPicture (PortraitName)
- return
-
-def OnLoad ():
- global AppearanceWindow, PortraitButton, PortraitsTable, LastPortrait
- global Gender
-
- Gender=GemRB.GetVar ("Gender")
-
- GemRB.LoadWindowPack ("GUICG", 800, 600)
- AppearanceWindow = GemRB.LoadWindow (11)
- #AppearanceWindow.SetFrame ()
-
- #Load the Portraits Table
- PortraitsTable = GemRB.LoadTable ("PICTURES")
- LastPortrait = 0
-
- PortraitButton = AppearanceWindow.GetControl (1)
- PortraitButton.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_NO_IMAGE,OP_SET)
- PortraitButton.SetState (IE_GUI_BUTTON_LOCKED)
-
- LeftButton = AppearanceWindow.GetControl (2)
- RightButton = AppearanceWindow.GetControl (3)
-
- BackButton = AppearanceWindow.GetControl (5)
- BackButton.SetText (15416)
- BackButton.SetFlags (IE_GUI_BUTTON_CANCEL,OP_OR)
-
- CustomButton = AppearanceWindow.GetControl (6)
- CustomButton.SetText (17545)
-
- DoneButton = AppearanceWindow.GetControl (0)
- DoneButton.SetText (36789)
- DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT,OP_OR)
-
- RightButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, RightPress)
- LeftButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, LeftPress)
- BackButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, BackPress)
- CustomButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CustomPress)
- DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, NextPress)
-
- while True:
- if PortraitsTable.GetValue (LastPortrait, 0) == Gender:
- SetPicture ()
- break
- LastPortrait = LastPortrait + 1
- AppearanceWindow.SetVisible (WINDOW_VISIBLE)
- return
-
-def RightPress ():
- global LastPortrait
- while True:
- LastPortrait = LastPortrait + 1
- if LastPortrait >= PortraitsTable.GetRowCount ():
- LastPortrait = 0
- if PortraitsTable.GetValue (LastPortrait, 0) == Gender:
- SetPicture ()
- return
-
-def LeftPress ():
- global LastPortrait
- while True:
- LastPortrait = LastPortrait - 1
- if LastPortrait < 0:
- LastPortrait = PortraitsTable.GetRowCount ()-1
- if PortraitsTable.GetValue (LastPortrait, 0) == Gender:
- SetPicture ()
- return
-
-def BackPress ():
- if AppearanceWindow:
- AppearanceWindow.Unload ()
- GemRB.SetNextScript ("CharGen")
- GemRB.SetVar ("Gender",0) #scrapping the gender value
- return
-
-def CustomDone ():
- Window = CustomWindow
-
- Portrait = PortraitList1.QueryText ()
- GemRB.SetToken ("SmallPortrait", Portrait)
- Portrait = PortraitList2.QueryText ()
- GemRB.SetToken ("LargePortrait", Portrait)
- if Window:
- Window.Unload ()
- if AppearanceWindow:
- AppearanceWindow.Unload ()
- GemRB.SetNextScript ("CharGen2")
- return
-
-def CustomAbort ():
- if CustomWindow:
- CustomWindow.Unload ()
- return
-
-def LargeCustomPortrait ():
- Window = CustomWindow
-
- Portrait = PortraitList1.QueryText ()
- #small hack
- if GemRB.GetVar ("Row1") == RowCount1:
- return
-
- Label = Window.GetControl (0x10000007)
- Label.SetText (Portrait)
-
- Button = Window.GetControl (6)
- if Portrait=="":
- Portrait = "NOPORTMD"
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- if PortraitList2.QueryText ()!="":
- Button.SetState (IE_GUI_BUTTON_ENABLED)
-
- Button = Window.GetControl (0)
- Button.SetPicture (Portrait, "NOPORTMD")
- return
-
-def SmallCustomPortrait ():
- Window = CustomWindow
-
- Portrait = PortraitList2.QueryText ()
- #small hack
- if GemRB.GetVar ("Row2") == RowCount2:
- return
-
- Label = Window.GetControl (0x10000008)
- Label.SetText (Portrait)
-
- Button = Window.GetControl (6)
- if Portrait=="":
- Portrait = "NOPORTSM"
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- else:
- if PortraitList1.QueryText ()!="":
- Button.SetState (IE_GUI_BUTTON_ENABLED)
-
- Button = Window.GetControl (1)
- Button.SetPicture (Portrait, "NOPORTSM")
- return
-
-def CustomPress ():
- global PortraitList1, PortraitList2
- global RowCount1, RowCount2
- global CustomWindow
-
- CustomWindow = Window = GemRB.LoadWindow (18)
- PortraitList1 = Window.GetControl (2)
- RowCount1 = PortraitList1.GetPortraits (0)
- PortraitList1.SetEvent (IE_GUI_TEXTAREA_ON_CHANGE, LargeCustomPortrait)
- GemRB.SetVar ("Row1", RowCount1)
- PortraitList1.SetVarAssoc ("Row1",RowCount1)
-
- PortraitList2 = Window.GetControl (4)
- RowCount2 = PortraitList2.GetPortraits (1)
- PortraitList2.SetEvent (IE_GUI_TEXTAREA_ON_CHANGE, SmallCustomPortrait)
- GemRB.SetVar ("Row2", RowCount2)
- PortraitList2.SetVarAssoc ("Row2",RowCount2)
-
- Button = Window.GetControl (6)
- Button.SetText (11973)
- Button.SetFlags (IE_GUI_BUTTON_DEFAULT,OP_OR)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CustomDone)
- Button.SetState (IE_GUI_BUTTON_DISABLED)
-
- Button = Window.GetControl (7)
- Button.SetText (15416)
- Button.SetFlags (IE_GUI_BUTTON_CANCEL,OP_OR)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CustomAbort)
-
- Button = Window.GetControl (0)
- PortraitName = PortraitsTable.GetRowName (LastPortrait)+"L"
- Button.SetPicture (PortraitName, "NOPORTMD")
- Button.SetState (IE_GUI_BUTTON_LOCKED)
-
- Button = Window.GetControl (1)
- PortraitName = PortraitsTable.GetRowName (LastPortrait)+"S"
- Button.SetPicture (PortraitName, "NOPORTSM")
- Button.SetState (IE_GUI_BUTTON_LOCKED)
-
- Window.ShowModal (MODAL_SHADOW_NONE)
- return
-
-def NextPress ():
- if AppearanceWindow:
- AppearanceWindow.Unload ()
- PortraitTable = GemRB.LoadTable ("pictures")
- PortraitName = PortraitTable.GetRowName (LastPortrait )
- GemRB.SetToken ("SmallPortrait", PortraitName+"S")
- GemRB.SetToken ("LargePortrait", PortraitName+"L")
- #GemRB.SetVar ("PortraitIndex",LastPortrait)
- GemRB.SetNextScript ("CharGen2") #Before race
- return
diff --git a/gemrb/GUIScripts/iwd2/Skills.py b/gemrb/GUIScripts/iwd2/Skills.py
index 587e351..e55682d 100644
--- a/gemrb/GUIScripts/iwd2/Skills.py
+++ b/gemrb/GUIScripts/iwd2/Skills.py
@@ -143,8 +143,6 @@ def OnLoad():
CostTable = GemRB.LoadTable("skilcost")
- SkillRacTable = GemRB.LoadTable("SKILLRAC")
-
for i in range(RowCount):
GemRB.SetVar("Skill "+str(i),0) # Racial/Class bonuses don't factor in char-gen or leveling
# so can be safely ignored
@@ -240,7 +238,7 @@ def BackPress():
TmpTable = GemRB.LoadTable ("skillsta")
for i in range(TmpTable.GetRowCount()):
GemRB.SetVar("Skill "+str(i),0)
- StatID=TmpTable.GetValue (i, 2)
+ StatID=TmpTable.GetValue (i, 0, 2)
GemRB.SetPlayerStat (MyChar, StatID, 0)
if SkillWindow:
SkillWindow.Unload()
@@ -253,7 +251,7 @@ def NextPress():
TmpTable = GemRB.LoadTable ("skillsta")
SkillCount = TmpTable.GetRowCount ()
for i in range (SkillCount):
- StatID=TmpTable.GetValue (i, 2)
+ StatID=TmpTable.GetValue (i, 0, 2)
GemRB.SetPlayerStat (MyChar, StatID, GemRB.GetVar ("Skill "+str(i) ) )
if SkillWindow:
SkillWindow.Unload()
diff --git a/gemrb/GUIScripts/iwd2/Sound.py b/gemrb/GUIScripts/iwd2/Sound.py
deleted file mode 100644
index 4dd0a6e..0000000
--- a/gemrb/GUIScripts/iwd2/Sound.py
+++ /dev/null
@@ -1,132 +0,0 @@
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-#
-#sound options
-import GemRB
-from GUIDefines import *
-
-SoundWindow = 0
-TextAreaControl = 0
-
-def OnLoad():
- global SoundWindow, TextAreaControl
-
- GemRB.LoadWindowPack("GUIOPT", 800, 600)
- SoundWindow = GemRB.LoadWindow(7)
- SoundWindow.SetFrame( )
-
- TextAreaControl = SoundWindow.GetControl(14)
- AmbientButton = SoundWindow.GetControl(16)
- AmbientSlider = SoundWindow.GetControl(1)
- SoundEffectsButton = SoundWindow.GetControl(17)
- SoundEffectsSlider = SoundWindow.GetControl(2)
- DialogueButton = SoundWindow.GetControl(18)
- DialogueSlider = SoundWindow.GetControl(3)
- MusicButton = SoundWindow.GetControl(19)
- MusicSlider = SoundWindow.GetControl(4)
- MoviesButton = SoundWindow.GetControl(20)
- MoviesSlider = SoundWindow.GetControl(22)
- EnvironmentalButton = SoundWindow.GetControl(28)
- EnvironmentalButtonB = SoundWindow.GetControl(26)
- CharacterSoundButton = SoundWindow.GetControl(13)
- OkButton = SoundWindow.GetControl(24)
- CancelButton = SoundWindow.GetControl(25)
- TextAreaControl.SetText(18040)
- CharacterSoundButton.SetText(17778)
-
- OkButton.SetText(11973)
- OkButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR)
-
- CancelButton.SetText(13727)
- CancelButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
- AmbientButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, AmbientPress)
- AmbientSlider.SetEvent(IE_GUI_SLIDER_ON_CHANGE, AmbientPress)
- AmbientSlider.SetVarAssoc("Volume Ambients",10)
-
- SoundEffectsButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, SoundEffectsPress)
- SoundEffectsSlider.SetEvent(IE_GUI_SLIDER_ON_CHANGE, SoundEffectsPress)
- SoundEffectsSlider.SetVarAssoc("Volume SFX",10)
-
- DialogueButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, DialoguePress)
- DialogueSlider.SetEvent(IE_GUI_SLIDER_ON_CHANGE, DialoguePress)
- DialogueSlider.SetVarAssoc("Volume Voices",10)
-
- MusicButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, MusicPress)
- MusicSlider.SetEvent(IE_GUI_SLIDER_ON_CHANGE, MusicPress)
- MusicSlider.SetVarAssoc("Volume Music",10)
-
- MoviesButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, MoviesPress)
- MoviesSlider.SetEvent(IE_GUI_SLIDER_ON_CHANGE, MoviesPress)
- MoviesSlider.SetVarAssoc("Volume Movie",10)
-
- EnvironmentalButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, EnvironmentalPress)
- EnvironmentalButtonB.SetEvent(IE_GUI_BUTTON_ON_PRESS, EnvironmentalPress)
- EnvironmentalButtonB.SetFlags(IE_GUI_BUTTON_CHECKBOX,OP_OR)
- EnvironmentalButtonB.SetVarAssoc("Environmental Audio",1)
- EnvironmentalButtonB.SetSprites("GBTNOPT4", 0, 0, 1, 2, 3)
-
- CharacterSoundButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, CharacterSoundPress)
- OkButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, OkPress)
- CancelButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, CancelPress)
- SoundWindow.SetVisible(WINDOW_VISIBLE)
- return
-
-def AmbientPress():
- TextAreaControl.SetText(18008)
- GemRB.UpdateAmbientsVolume ()
- return
-
-def SoundEffectsPress():
- TextAreaControl.SetText(18009)
- return
-
-def DialoguePress():
- TextAreaControl.SetText(18010)
- return
-
-def MusicPress():
- TextAreaControl.SetText(18011)
- GemRB.UpdateMusicVolume ()
- return
-
-def MoviesPress():
- TextAreaControl.SetText(18012)
- return
-
-def EnvironmentalPress():
- TextAreaControl.SetText(18022)
- return
-
-def CharacterSoundPress():
- if SoundWindow:
- SoundWindow.Unload()
- GemRB.SetNextScript("CharSound")
- return
-
-def OkPress():
- if SoundWindow:
- SoundWindow.Unload()
- GemRB.SetNextScript("Options")
- return
-
-def CancelPress():
- if SoundWindow:
- SoundWindow.Unload()
- GemRB.SetNextScript("Options")
- return
diff --git a/gemrb/GUIScripts/pst/CMakeLists.txt b/gemrb/GUIScripts/pst/CMakeLists.txt
deleted file mode 100644
index 111981a..0000000
--- a/gemrb/GUIScripts/pst/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-FILE( GLOB FILES_TO_INSTALL *.py )
-
-INSTALL( FILES ${FILES_TO_INSTALL} DESTINATION ${DATA_DIR}/GUIScripts/pst )
diff --git a/gemrb/GUIScripts/pst/FloatMenuWindow.py b/gemrb/GUIScripts/pst/FloatMenuWindow.py
index 98e5eee..cb5d8aa 100644
--- a/gemrb/GUIScripts/pst/FloatMenuWindow.py
+++ b/gemrb/GUIScripts/pst/FloatMenuWindow.py
@@ -29,14 +29,37 @@ from GUIDefines import *
from ie_stats import *
from ie_action import *
+import GUIMA
+import GUIJRNL
+import GUIINV
+import GUIREC
+import GUIMG
+
FloatMenuWindow = None
+CID_PORTRAIT = 0
+CID_DIALOG = 1
+CID_WEAPONS = 2
+CID_SPELLS = 3
+CID_ITEMS = 4
+CID_ABILITIES = 5
+# FIXME: there are buttons 6-10 we hide completely. What are they?
+CID_HANDLE1 = 11
+CID_HANDLE2 = 12
+CID_PREV = 13
+CID_NEXT = 14
+CID_SLOTS = 15 # up to 19
+
+SLOT_COUNT = 5
+
+
MENU_MODE_SINGLE = 0
MENU_MODE_GROUP = 1
MENU_MODE_WEAPONS = 2
MENU_MODE_ITEMS = 3
MENU_MODE_SPELLS = 4
MENU_MODE_ABILITIES = 5
+MENU_MODE_DIALOG = 6
float_menu_mode = MENU_MODE_SINGLE
float_menu_index = 0
@@ -60,9 +83,25 @@ def UseWeapon ():
GemRB.SetEquippedQuickSlot (pc, float_menu_selected)
return
-def OpenFloatMenuWindow ():
+def DoSingleAction ():
+ i = GemRB.GetVar ('ItemButton')
+ print i
+ OpenFloatMenuWindow ()
+ if i == 0:
+ GUIMA.OpenMapWindow ()
+ elif i == 1:
+ GUIJRNL.OpenJournalWindow ()
+ elif i == 2:
+ GUIINV.OpenInventoryWindow ()
+ elif i == 3:
+ GUIREC.OpenRecordsWindow ()
+ elif i == 4:
+ # FIXME: Or priest scroll ....
+ GUIMG.OpenMageWindow ()
+
+def OpenFloatMenuWindow (x=0, y=0):
global FloatMenuWindow
- global float_menu_mode, float_menu_index
+ global float_menu_mode, float_menu_index, float_menu_selected
GemRB.HideGUI ()
@@ -103,59 +142,57 @@ def OpenFloatMenuWindow ():
FloatMenuWindow = Window = GemRB.LoadWindow (3)
GemRB.SetVar ("FloatWindow", Window.ID)
- x, y = GemRB.GetVar ("MenuX"), GemRB.GetVar ("MenuY")
-
# FIXME: keep the menu inside the viewport!!!
Window.SetPos (x, y, WINDOW_CENTER | WINDOW_BOUNDED)
# portrait button
- Button = Window.GetControl (0)
+ Button = Window.GetControl (CID_PORTRAIT)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, FloatMenuSelectNextPC)
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, GUICommon.OpenFloatMenuWindow)
+ Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, OpenFloatMenuWindow)
# Initiate Dialogue
- Button = Window.GetControl (1)
+ Button = Window.GetControl (CID_DIALOG)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, FloatMenuSelectDialog)
Button.SetTooltip (8191)
# Attack/Select Weapon
- Button = Window.GetControl (2)
+ Button = Window.GetControl (CID_WEAPONS)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, FloatMenuSelectWeapons)
Button.SetTooltip (8192)
# Cast spell
- Button = Window.GetControl (3)
+ Button = Window.GetControl (CID_SPELLS)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, FloatMenuSelectSpells)
Button.SetTooltip (8193)
# Use Item
- Button = Window.GetControl (4)
+ Button = Window.GetControl (CID_ITEMS)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, FloatMenuSelectItems)
Button.SetTooltip (8194)
# Use Special Ability
- Button = Window.GetControl (5)
+ Button = Window.GetControl (CID_ABILITIES)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, FloatMenuSelectAbilities)
Button.SetTooltip (8195)
# Menu Anchors/Handles
- Button = Window.GetControl (11)
+ Button = Window.GetControl (CID_HANDLE1)
Button.SetTooltip (8199)
Button.SetFlags (IE_GUI_BUTTON_DRAGGABLE, OP_OR)
Button.SetEvent (IE_GUI_BUTTON_ON_DRAG, FloatMenuDrag)
- Button = Window.GetControl (12)
+ Button = Window.GetControl (CID_HANDLE2)
Button.SetTooltip (8199)
Button.SetFlags (IE_GUI_BUTTON_DRAGGABLE, OP_OR)
Button.SetEvent (IE_GUI_BUTTON_ON_DRAG, FloatMenuDrag)
# Rotate Items left (to begin)
- Button = Window.GetControl (13)
+ Button = Window.GetControl (CID_PREV)
Button.SetTooltip (8197)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, FloatMenuPreviousItem)
# Rotate Items right (to end)
- Button = Window.GetControl (14)
+ Button = Window.GetControl (CID_NEXT)
Button.SetTooltip (8198)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, FloatMenuNextItem)
@@ -165,9 +202,12 @@ def OpenFloatMenuWindow ():
Button.SetPos (65535, 65535)
# 15 - 19 - empty item slot
- for i in range (15, 20):
- Button = Window.GetControl (i)
+ for i in range (SLOT_COUNT):
+ Button = Window.GetControl (CID_SLOTS + i)
Button.SetFlags (IE_GUI_BUTTON_ALIGN_RIGHT | IE_GUI_BUTTON_ALIGN_BOTTOM, OP_OR)
+ Button.SetVarAssoc ('ItemButton', i)
+ Button.SetFont ('NUMBER')
+ Button.SetPushOffset (0, 0)
# BAMs:
# AMALLSTP - 41655
@@ -202,6 +242,7 @@ def OpenFloatMenuWindow ():
float_menu_mode = MENU_MODE_SINGLE
else:
float_menu_mode = MENU_MODE_GROUP
+ float_menu_selected = 4 # "Abort current action" slot
float_menu_index = 0
@@ -213,52 +254,65 @@ def OpenFloatMenuWindow ():
def UpdateFloatMenuWindow ():
Window = FloatMenuWindow
+ # this enables the use of hotkeys without the window being open
+ if not FloatMenuWindow:
+ return
pc = GemRB.GameGetFirstSelectedPC ()
- Button = Window.GetControl (0)
+ Button = Window.GetControl (CID_PORTRAIT)
Button.SetSprites (GUICommonWindows.GetActorPortrait (pc, 'FMENU'), 0, 0, 1, 2, 3)
- Button = Window.GetControl (13)
+ Button = Window.GetControl (CID_PREV)
Button.SetState (IE_GUI_BUTTON_LOCKED)
- Button = Window.GetControl (14)
+ Button = Window.GetControl (CID_NEXT)
Button.SetState (IE_GUI_BUTTON_LOCKED)
if float_menu_mode == MENU_MODE_SINGLE:
- for i in range (5):
+ for i in range (SLOT_COUNT):
UpdateFloatMenuSingleAction (i)
+
elif float_menu_mode == MENU_MODE_GROUP:
- for i in range (5):
+ for i in range (SLOT_COUNT):
UpdateFloatMenuGroupAction (i)
+
elif float_menu_mode == MENU_MODE_WEAPONS:
# weapons
- for i in range (5):
+ for i in range (SLOT_COUNT):
UpdateFloatMenuItem (pc, i, 1)
+
elif float_menu_mode == MENU_MODE_ITEMS:
# items
- for i in range (5):
+ for i in range (SLOT_COUNT):
UpdateFloatMenuItem (pc, i, 0)
+
elif float_menu_mode == MENU_MODE_SPELLS:
# spells
RefreshSpellList(pc, False)
if float_menu_index:
- Button = Window.GetControl (13)
+ Button = Window.GetControl (CID_PREV)
Button.SetState (IE_GUI_BUTTON_ENABLED)
if float_menu_index+3<len(spell_list):
- Button = Window.GetControl (14)
+ Button = Window.GetControl (CID_NEXT)
Button.SetState (IE_GUI_BUTTON_ENABLED)
- for i in range (5):
+ for i in range (SLOT_COUNT):
UpdateFloatMenuSpell (pc, i)
+
elif float_menu_mode == MENU_MODE_ABILITIES:
# abilities
RefreshSpellList(pc, True)
if float_menu_index:
- Button = Window.GetControl (13)
+ Button = Window.GetControl (CID_PREV)
Button.SetState (IE_GUI_BUTTON_ENABLED)
if float_menu_index+3<len(spell_list):
- Button = Window.GetControl (14)
+ Button = Window.GetControl (CID_NEXT)
Button.SetState (IE_GUI_BUTTON_ENABLED)
- for i in range (5):
+ for i in range (SLOT_COUNT):
UpdateFloatMenuSpell (pc, i)
+
+ elif float_menu_mode == MENU_MODE_DIALOG:
+ for i in range (SLOT_COUNT):
+ ClearSlot (i)
+
return
def UpdateFloatMenuSingleAction (i):
@@ -274,12 +328,15 @@ def UpdateFloatMenuSingleAction (i):
# Statistics screen
# Mage Spell Book / Priest Scroll
- Button = Window.GetControl (15 + i)
+ Button = Window.GetControl (CID_SLOTS + i)
Button.SetSprites (butts[i][0], 0, 0, 1, 2, 3)
+ Button.SetPicture('')
Button.SetTooltip (butts[i][1])
Button.SetText ('')
- return
+ Button.SetState (IE_GUI_BUTTON_ENABLED)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, DoSingleAction)
+
def UpdateFloatMenuGroupAction (i):
Window = FloatMenuWindow
@@ -294,13 +351,13 @@ def UpdateFloatMenuGroupAction (i):
# Initiate dialogue
# Attack
# Abort Current Action
- Button = Window.GetControl (15 + i)
+ Button = Window.GetControl (CID_SLOTS + i)
#Button.SetSprites (butts[i][0], 0, 0, 1, 2, 3)
#Button.SetTooltip (butts[i][1])
#Button.SetText ('')
Button.SetActionIcon (globals(), butts[i], i+1 )
- return
+ Button.SetState (IE_GUI_BUTTON_ENABLED)
def RefreshSpellList(pc, innate):
global spell_hash, spell_list, type
@@ -308,7 +365,8 @@ def RefreshSpellList(pc, innate):
if innate:
type = IE_SPELL_TYPE_INNATE
else:
- if (CommonTables.ClassSkills.GetValue (GemRB.GetPlayerStat( pc, IE_CLASS), 1)=="*"):
+ ClassName = GUICommon.GetClassRowName (pc)
+ if CommonTables.ClassSkills.GetValue (ClassName, "CLERICSPELL") == "*":
type = IE_SPELL_TYPE_WIZARD
else:
type = IE_SPELL_TYPE_PRIEST
@@ -318,7 +376,7 @@ def RefreshSpellList(pc, innate):
spell_list = []
#level==0 is level #1
for level in range (9):
- mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level)
+ mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level, True)
for j in range (mem_cnt):
ms = GemRB.GetMemorizedSpell (pc, type, level, j)
@@ -339,7 +397,7 @@ def UpdateFloatMenuItem (pc, i, weapons):
slot_item = GemRB.GetSlotItem (pc, 10 + i)
else:
slot_item = GemRB.GetSlotItem (pc, 21 + i)
- Button = Window.GetControl (15 + i)
+ Button = Window.GetControl (CID_SLOTS + i)
#the selected state is in another bam, sucks, we have to do everything manually
if i == float_menu_selected:
@@ -350,37 +408,32 @@ def UpdateFloatMenuItem (pc, i, weapons):
# Weapons - the last action is 'Guard'
# TODO: use SetActionIcon whenever possible
if weapons and i==4:
+ # FIXME: rather call UpdateFloatMenuGroupAction?
Button.SetActionIcon (globals(), ACT_DEFEND)
+ Button.SetState (IE_GUI_BUTTON_ENABLED)
return
#if slot_item and slottype:
- if slot_item:
+ if slot_item and slot_item['Flags'] & IE_INV_ITEM_IDENTIFIED:
item = GemRB.GetItem (slot_item['ItemResRef'])
- identified = slot_item['Flags'] & IE_INV_ITEM_IDENTIFIED
- if not identified:
- Button.SetItemIcon ('')
- Button.SetText ('')
- Button.SetTooltip ('')
- return
Button.SetItemIcon (slot_item['ItemResRef'], 6)
- if item['StackAmount'] > 1:
+ if item['MaxStackAmount'] > 1:
Button.SetText (str (slot_item['Usages0']))
else:
Button.SetText ('')
- if not identified or item['ItemNameIdentified'] == -1:
+ if item['ItemNameIdentified'] == -1:
Button.SetTooltip (item['ItemName'])
else:
Button.SetTooltip (item['ItemNameIdentified'])
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_NAND)
+ #Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_NAND)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SelectItem)
- Button.SetVarAssoc ('ItemButton', i)
+ Button.SetState (IE_GUI_BUTTON_ENABLED)
+ #Button.SetVarAssoc ('ItemButton', i)
return
- Button.SetItemIcon ('')
- Button.SetText ('')
- Button.SetTooltip ('')
- return
+ ClearSlot (i)
+
def SelectItem ():
global float_menu_selected
@@ -403,7 +456,8 @@ def UpdateFloatMenuSpell (pc, i):
if i == float_menu_selected:
Button.SetBAM ('AMHILITE', 0, 0)
else:
- Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_NAND)
+ Button.SetPicture('')
+ #Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_NAND)
if i + float_menu_index < len (spell_list):
SpellResRef = spell_list[i + float_menu_index]
@@ -413,13 +467,32 @@ def UpdateFloatMenuSpell (pc, i):
spell = GemRB.GetSpell (SpellResRef)
Button.SetTooltip (spell['SpellName'])
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, SelectItem)
- Button.SetVarAssoc ('ItemButton', i)
+ #Button.SetVarAssoc ('ItemButton', i)
Button.SetState (IE_GUI_BUTTON_ENABLED)
else:
- Button.SetSpellIcon ('')
- Button.SetText ('')
- Button.SetTooltip ('')
- Button.SetState (IE_GUI_BUTTON_DISABLED)
+ ClearSlot (i)
+
+def ClearSlot (i):
+ Button = FloatMenuWindow.GetControl (CID_SLOTS + i)
+ Button.SetSprites ('AMGENS', 0, 0, 1, 0, 0)
+ Button.SetPicture ('')
+ Button.SetText ('')
+ Button.SetTooltip ('')
+ Button.SetState (IE_GUI_BUTTON_DISABLED)
+
+def FloatMenuSelectPreviousPC ():
+ sel = GemRB.GameGetFirstSelectedPC ()
+ if sel == 0:
+ GUICommon.OpenFloatMenuWindow ()
+ return
+
+ previous = sel % GemRB.GetPartySize () - 1
+ if previous == -1:
+ previous = 1
+ elif previous == 0:
+ previous = GemRB.GetPartySize ()
+ GemRB.GameSelectPC (previous, 1, SELECT_REPLACE)
+ # NOTE: it invokes FloatMenuSelectAnotherPC() through selection change handler
return
def FloatMenuSelectNextPC ():
@@ -441,9 +514,11 @@ def FloatMenuSelectAnotherPC ():
return
def FloatMenuSelectDialog ():
- global float_menu_selected
- GemRB.GameControlSetTargetMode (TARGET_MODE_TALK)
+ global float_menu_mode, float_menu_selected
+ float_menu_mode = MENU_MODE_DIALOG
+ float_menu_index = 0
float_menu_selected = None
+ GemRB.GameControlSetTargetMode (TARGET_MODE_TALK)
UpdateFloatMenuWindow ()
return
diff --git a/gemrb/GUIScripts/pst/GUICommonWindows.py b/gemrb/GUIScripts/pst/GUICommonWindows.py
deleted file mode 100644
index 2503a08..0000000
--- a/gemrb/GUIScripts/pst/GUICommonWindows.py
+++ /dev/null
@@ -1,653 +0,0 @@
-# -*-python-*-
-# GemRB - Infinity Engine Emulator
-# Copyright (C) 2003 The GemRB Project
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-# GUICommonWindows.py - functions to open common
-# windows in lower part of the screen
-###################################################
-
-import GemRB
-from GUIDefines import *
-from ie_stats import *
-from ie_action import *
-import GUIClasses
-import GUICommon
-import CommonTables
-import LUCommon
-import InventoryCommon
-
-# needed for all the Open*Window callbacks in the OptionsWindow
-import GUIJRNL
-import GUIMA
-import GUIMG
-import GUIINV
-import GUIOPT
-import GUIPR
-import GUIREC
-import Maze
-
-FRAME_PC_SELECTED = 0
-FRAME_PC_TARGET = 1
-
-TimeWindow = None
-PortWindow = None
-MenuWindow = None
-MainWindow = None
-global PortraitWindow
-PortraitWindow = None
-ActionsWindow = None
-OptionsWindow = None
-DraggedPortrait = None
-DiscWindow = None
-
-# Buttons:
-# 0 CNTREACH
-# 1 INVNT
-# 2 MAP
-# 3 MAGE
-# 4 AI
-# 5 STATS
-# 6 JRNL
-# 7 PRIEST
-# 8 OPTION
-# 9 REST
-# 10 TXTE
-
-def OpenCommonWindows ():
- global TimeWindow, PortWindow, MenuWindow, MainWindow
-
- TimeWindow = GemRB.LoadWindow (0)
- PortWindow = GemRB.LoadWindow (1)
- MenuWindow = GemRB.LoadWindow (2)
- MainWindow = GemRB.LoadWindow (3)
-
- Window = MenuWindow
-
- # Can't Reach ???
- Button = Window.GetControl (0)
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, None) #TODO: CntReachPress
-
- # AI
- Button = Window.GetControl (4)
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, AIPress)
-
- # Message popup
- Button = Window.GetControl (10)
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, TxtePress)
-
-
- SetupMenuWindowControls (Window)
-
-
- TimeWindow.SetVisible (WINDOW_VISIBLE)
- PortWindow.SetVisible (WINDOW_VISIBLE)
- MenuWindow.SetVisible (WINDOW_VISIBLE)
- MainWindow.SetVisible (WINDOW_VISIBLE)
-
-def CloseCommonWindows ():
- global MainWindow
-
- if MainWindow == None:
- return
- #if TimeWindow == None:
- # return
-
- if MainWindow:
- MainWindow.Unload ()
- if TimeWindow:
- TimeWindow.Unload ()
- if PortWindow:
- PortWindow.Unload ()
- if MenuWindow:
- MenuWindow.Unload ()
-
- MainWindow = None
-
-def SetupMenuWindowControls (Window):
- # Inventory
- Button = Window.GetControl (1)
- Button.SetTooltip (41601)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIINV.OpenInventoryWindow)
-
- # Map
- Button = Window.GetControl (2)
- Button.SetTooltip (41625)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIMA.OpenMapWindow)
-
- # Mage
- Button = Window.GetControl (3)
- Button.SetTooltip (41624)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIMG.OpenMageWindow)
- # Stats
- Button = Window.GetControl (5)
- Button.SetTooltip (4707)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIREC.OpenRecordsWindow)
-
- # Journal
- Button = Window.GetControl (6)
- Button.SetTooltip (41623)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIJRNL.OpenJournalWindow)
-
- # Priest
- Button = Window.GetControl (7)
- Button.SetTooltip (4709)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIPR.OpenPriestWindow)
-
- # Options
- Button = Window.GetControl (8)
- Button.SetTooltip (41626)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIOPT.OpenOptionsWindow)
-
- # Rest
- Button = Window.GetControl (9)
- Button.SetTooltip (41628)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUICommon.RestPress)
-
-
- # AI
- Button = Window.GetControl (4)
- Button.SetTooltip (41631) # or 41646 Activate ...
- #Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUICommon.OpenFloatMenuWindow)
-
- # (Un)Lock view on character
- Button = Window.GetControl (0)
- Button.SetTooltip (41647) # or 41648 Unlock ...
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OnLockViewPress)
-
- # Message popup
- Button = Window.GetControl (10)
- Button.SetTooltip (41660) # or 41661 Close ...
-
-
-def OnLockViewPress ():
- GemRB.GameControlSetScreenFlags (SF_CENTERONACTOR | SF_ALWAYSCENTER, OP_OR)
- print "OnLockViewPress"
-
-def AIPress ():
- print "AIPress"
-
-def TxtePress ():
- print "TxtePress"
-
-def SetupActionsWindowControls (Window):
- # time button
- Button = Window.GetControl (0)
- Button.SetAnimation ("WMTIME")
- Button.SetFlags (IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_ANIMATED, OP_SET)
- Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, GUICommon.GearsClicked)
- Button.SetEvent(IE_GUI_MOUSE_ENTER_BUTTON, UpdateClock)
-
- # 41627 - Return to the Game World
- Button = Window.GetControl (2)
- Button.SetState (IE_GUI_BUTTON_DISABLED)
- Button.SetTooltip (41627)
-
- # Select all characters
- Button = Window.GetControl (1)
- Button.SetTooltip (41659)
-
- # Abort current action
- Button = Window.GetControl (3)
- Button.SetTooltip (41655)
-
- # Formations
- Button = Window.GetControl (4)
- Button.SetTooltip (44945)
-
-
-
-# which=INVENTORY|STATS|FMENU
-def GetActorPortrait (actor, which):
- #return GemRB.GetPlayerPortrait( actor, which)
-
- # only the lowest byte is meaningful here (OneByteAnimID)
- anim_id = GemRB.GetPlayerStat (actor, IE_ANIMATION_ID) & 255
- row = "0x%02X" %anim_id
-
- return CommonTables.Pdolls.GetValue (row, which)
-
-
-def UpdateAnimation ():
- pc = GemRB.GameGetSelectedPCSingle ()
-
- disguise = GemRB.GetGameVar ("APPEARANCE")
- if disguise == 2: #dustman
- animid = "DR"
- elif disguise == 1: #zombie
- animid = "ZO"
- else:
- slot = GemRB.GetEquippedQuickSlot (pc)
- item = GemRB.GetSlotItem (pc, slot )
- animid = ""
- if item:
- item = GemRB.GetItem(item["ItemResRef"])
- if item:
- animid = item["AnimationType"]
-
- BioTable = GemRB.LoadTable ("BIOS")
- Specific = "%d"%GemRB.GetPlayerStat (pc, IE_SPECIFIC)
- AvatarName = BioTable.GetValue (Specific, "PC")
- AnimTable = GemRB.LoadTable ("ANIMS")
- if animid=="":
- animid="*"
- value = AnimTable.GetValue (animid, AvatarName)
- if value<0:
- return
- GemRB.SetPlayerStat (pc, IE_ANIMATION_ID, value)
- return
-
-
-SelectionChangeHandler = None
-SelectionChangeMultiHandler = None
-
-def SetSelectionChangeHandler (handler):
- """Updates the selection handler."""
-
- global SelectionChangeHandler
-
- # Switching from walking to non-walking environment:
- # set the first selected PC in walking env as a selected
- # in nonwalking env
- #if (not SelectionChangeHandler) and handler and (not GUICommon.NextWindowFn):
- if (not SelectionChangeHandler) and handler:
- sel = GemRB.GameGetFirstSelectedPC ()
- if not sel:
- sel = 1
- GemRB.GameSelectPCSingle (sel)
-
- SelectionChangeHandler = handler
-
- # redraw selection on change main selection | single selection
- SelectionChanged ()
-
-def SetSelectionChangeMultiHandler (handler):
- global SelectionChangeMultiHandler
- SelectionChangeMultiHandler = handler
- #SelectionChanged ()
-
-def RunSelectionChangeHandler ():
- if SelectionChangeHandler:
- SelectionChangeHandler ()
-
-portrait_hp_numeric = [0, 0, 0, 0, 0, 0]
-
-
-def OpenPortraitWindow (needcontrols):
- global PortraitWindow
-
- PortraitWindow = Window = GemRB.LoadWindow (1)
-
- for i in range (PARTY_SIZE):
- Button = Window.GetControl (i)
- Button.SetVarAssoc ('PressedPortrait', i+1)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, PortraitButtonOnPress)
- Button.SetEvent (IE_GUI_BUTTON_ON_SHIFT_PRESS, PortraitButtonOnShiftPress)
- Button.SetEvent (IE_GUI_BUTTON_ON_DRAG_DROP, InventoryCommon.OnDropItemToPC)
- Button.SetEvent (IE_GUI_BUTTON_ON_DRAG, PortraitButtonOnDrag)
- Button.SetEvent (IE_GUI_MOUSE_ENTER_BUTTON, PortraitButtonOnMouseEnter)
- Button.SetEvent (IE_GUI_MOUSE_LEAVE_BUTTON, PortraitButtonOnMouseLeave)
-
- Button.SetBorder (FRAME_PC_SELECTED, 1, 1, 2, 2, 0, 255, 0, 255)
- Button.SetBorder (FRAME_PC_TARGET, 3, 3, 4, 4, 255, 255, 0, 255)
-
- ButtonHP = Window.GetControl (6 + i)
- ButtonHP.SetVarAssoc ('PressedPortraitHP', i+1)
- ButtonHP.SetEvent (IE_GUI_BUTTON_ON_PRESS, PortraitButtonHPOnPress)
-
- portrait_hp_numeric[i] = 0
-
- UpdatePortraitWindow ()
- SelectionChanged ()
- return Window
-
-def UpdatePortraitWindow ():
- """Updates all of the portraits."""
-
- Window = PortraitWindow
-
- for i in range (PARTY_SIZE):
- Button = Window.GetControl (i)
- ButtonHP = Window.GetControl (6 + i)
-
- pic = GemRB.GetPlayerPortrait (i+1, 0)
- if not pic:
- Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- ButtonHP.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- continue
-
- #sel = GemRB.GameGetSelectedPCSingle () == i + 1
- Button.SetBAM (pic, 0, 0, -1)
-
- state = GemRB.GetPlayerStat (i+1, IE_STATE_ID)
- hp = GemRB.GetPlayerStat (i+1, IE_HITPOINTS)
- hp_max = GemRB.GetPlayerStat (i+1, IE_MAXHITPOINTS)
-
- if state & STATE_DEAD:
- cycle = 9
- elif state & STATE_HELPLESS:
- cycle = 8
- elif state & STATE_PETRIFIED:
- cycle = 7
- elif state & STATE_PANIC:
- cycle = 6
- elif state & STATE_POISONED:
- cycle = 2
- elif hp<hp_max/5:
- cycle = 4
- else:
- cycle = 0
-
- if cycle<6:
- Button.SetFlags(IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_ANIMATED | IE_GUI_BUTTON_PLAYRANDOM|IE_GUI_BUTTON_DRAGGABLE|IE_GUI_BUTTON_MULTILINE, OP_SET)
- else:
- Button.SetFlags(IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_ANIMATED | IE_GUI_BUTTON_DRAGGABLE|IE_GUI_BUTTON_MULTILINE, OP_SET)
- Button.SetAnimation (pic, cycle)
-
-
- ButtonHP.SetFlags(IE_GUI_BUTTON_PICTURE, OP_SET)
-
- if hp_max<1:
- ratio = 0.0
- else:
- ratio = (hp + 0.0) / hp_max
- if ratio > 1.0: ratio = 1.0
- r = int (255 * (1.0 - ratio))
- g = int (255 * ratio)
-
- ButtonHP.SetText ("%d / %d" %(hp, hp_max))
- ButtonHP.SetTextColor (r, g, 0, False)
- ButtonHP.SetBAM ('FILLBAR', 0, 0, -1)
- ButtonHP.SetPictureClipping (ratio)
-
- if portrait_hp_numeric[i-1]:
- op = OP_NAND
- else:
- op = OP_OR
-
- ButtonHP.SetFlags (IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_NO_TEXT, op)
-
-
- #if sel:
- # Button.EnableBorder(FRAME_PC_SELECTED, 1)
- #else:
- # Button.EnableBorder(FRAME_PC_SELECTED, 0)
- return
-
-def PortraitButtonOnDrag ():
- global DraggedPortrait
-
- #they start from 1
- DraggedPortrait = GemRB.GetVar ("PressedPortrait")
- GemRB.DragItem (DraggedPortrait, -1, "")
- return
-
-def PortraitButtonOnPress ():
- """Selects the portrait individually."""
-
- i = GemRB.GetVar ("PressedPortrait")
-
- if not i:
- return
-
- if GemRB.GameControlGetTargetMode() != TARGET_MODE_NONE:
- GemRB.ActOnPC (i)
- return
-
- if (not SelectionChangeHandler):
- if GemRB.GameIsPCSelected (i):
- GemRB.GameControlSetScreenFlags (SF_CENTERONACTOR, OP_OR)
- GemRB.GameSelectPC (i, True, SELECT_REPLACE)
- else:
- GemRB.GameSelectPCSingle (i)
- SelectionChanged ()
- RunSelectionChangeHandler ()
- return
-
-def PortraitButtonOnShiftPress ():
- i = GemRB.GetVar ('PressedPortrait')
-
- if (not SelectionChangeHandler):
- sel = GemRB.GameIsPCSelected (i)
- sel = not sel
- GemRB.GameSelectPC (i, sel)
- else:
- GemRB.GameSelectPCSingle (i)
- SelectionChanged ()
- RunSelectionChangeHandler ()
- return
-
-def PortraitButtonHPOnPress ():
- Window = PortraitWindow
-
- i = GemRB.GetVar ('PressedPortraitHP')
-
- portrait_hp_numeric[i-1] = not portrait_hp_numeric[i-1]
- ButtonHP = Window.GetControl (5 + i)
-
- if portrait_hp_numeric[i-1]:
- op = OP_NAND
- else:
- op = OP_OR
-
- ButtonHP.SetFlags (IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_NO_TEXT, op)
- return
-
-def StopAllOnPress ():
- for i in GemRB.GetSelectedActors():
- GemRB.ClearActions (i, 1)
- return
-
-# Run by Game class when selection was changed
-def SelectionChanged ():
- # FIXME: hack. If defined, display single selection
- if (not SelectionChangeHandler):
- for i in range (PARTY_SIZE):
- Button = PortraitWindow.GetControl (i)
- Button.EnableBorder (FRAME_PC_SELECTED, GemRB.GameIsPCSelected (i + 1))
- if SelectionChangeMultiHandler:
- SelectionChangeMultiHandler ()
- else:
- sel = GemRB.GameGetSelectedPCSingle ()
-
- for i in range (PARTY_SIZE):
- Button = PortraitWindow.GetControl (i)
- Button.EnableBorder (FRAME_PC_SELECTED, i + 1 == sel)
- import CommonWindow
- CommonWindow.CloseContainerWindow()
- return
-
-def PortraitButtonOnMouseEnter ():
- global DraggedPortrait
-
- i = GemRB.GetVar ("PressedPortrait")
-
- if not i:
- return
-
- if DraggedPortrait != None:
- GemRB.DragItem (0, -1, "")
- #this might not work
- GemRB.SwapPCs (DraggedPortrait, i)
- DraggedPortrait = None
-
- if GemRB.IsDraggingItem ():
- Button = PortraitWindow.GetControl (i-1)
- Button.EnableBorder (FRAME_PC_TARGET, 1)
-
-def PortraitButtonOnMouseLeave ():
- i = GemRB.GetVar ("PressedPortrait")
- if not i:
- return
-
- if GemRB.IsDraggingItem ():
- Button = PortraitWindow.GetControl (i-1)
- Button.EnableBorder (FRAME_PC_TARGET, 0)
- return
-
-def DisableAnimatedWindows ():
- global ActionsWindow, OptionsWindow
- GemRB.SetVar ("PortraitWindow", -1)
- ActionsWindow = GUIClasses.GWindow( GemRB.GetVar ("ActionsWindow") )
- GemRB.SetVar ("ActionsWindow", -1)
- OptionsWindow = GUIClasses.GWindow( GemRB.GetVar ("OptionsWindow") )
- GemRB.SetVar ("OptionsWindow", -1)
- GemRB.GamePause (1,1)
-
-def EnableAnimatedWindows ():
- GemRB.SetVar ("PortraitWindow", PortraitWindow.ID)
- GemRB.SetVar ("ActionsWindow", ActionsWindow.ID)
- GemRB.SetVar ("OptionsWindow", OptionsWindow.ID)
- GemRB.GamePause (0,1)
-
-def SetItemButton (Window, Button, Slot, PressHandler, RightPressHandler):
- if Slot != None:
- Item = GemRB.GetItem (Slot['ItemResRef'])
- identified = Slot['Flags'] & IE_INV_ITEM_IDENTIFIED
- #Button.SetVarAssoc ("LeftIndex", LeftTopIndex+i)
- #Button.SetSprites ('IVSLOT', 0, 0, 0, 0, 0)
- Button.SetItemIcon (Slot['ItemResRef'],0)
-
- if Item['StackAmount'] > 1:
- Button.SetText (str (Slot['Usages0']))
- else:
- Button.SetText ('')
-
-
- if not identified or Item['ItemNameIdentified'] == -1:
- Button.SetTooltip (Item['ItemName'])
- else:
- Button.SetTooltip (Item['ItemNameIdentified'])
-
- #Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_OR)
- #Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_NAND)
-
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, PressHandler)
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, RightPressHandler)
- #Button.SetEvent (IE_GUI_BUTTON_ON_SHIFT_PRESS, ShiftPressHandler)
- #Button.SetEvent (IE_GUI_BUTTON_ON_DRAG_DROP, DragDropHandler)
-
- else:
- #Button.SetVarAssoc ("LeftIndex", -1)
- Button.SetItemIcon ('')
- Button.SetTooltip (4273) # Ground Item
- Button.SetText ('')
- Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_NAND)
-
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, None)
- Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, None)
- #Button.SetEvent (IE_GUI_BUTTON_ON_SHIFT_PRESS, None)
- #Button.SetEvent (IE_GUI_BUTTON_ON_DRAG_DROP, None)
-
-def OpenWaitForDiscWindow ():
- global DiscWindow
- #print "OpenWaitForDiscWindow"
-
- if DiscWindow:
- GemRB.HideGUI ()
- if DiscWindow:
- DiscWindow.Unload ()
- GemRB.SetVar ("OtherWindow", -1)
- # ...LoadWindowPack()
- EnableAnimatedWindows ()
- DiscWindow = None
- GemRB.UnhideGUI ()
- return
-
- try:
- GemRB.HideGUI ()
- except:
- pass
-
- GemRB.LoadWindowPack ("GUIID")
- DiscWindow = Window = GemRB.LoadWindow (0)
- GemRB.SetVar ("OtherWindow", Window.ID)
- label = DiscWindow.GetControl (0)
-
- disc_num = GemRB.GetVar ("WaitForDisc")
- #disc_path = GemRB.GetVar ("WaitForDiscPath")
- disc_path = 'XX:'
-
- text = GemRB.GetString (31483) + " " + str (disc_num) + " " + GemRB.GetString (31569) + " " + disc_path + "\n" + GemRB.GetString (49152)
- label.SetText (text)
- DisableAnimatedWindows ()
-
- # 31483 - Please place PS:T disc number
- # 31568 - Please place the PS:T DVD
- # 31569 - in drive
- # 31570 - Wrong disc in drive
- # 31571 - There is no disc in drive
- # 31578 - No disc could be found in drive. Please place Disc 1 in drive.
- # 49152 - To quit the game, press Alt-F4
-
-
- try:
- GemRB.UnhideGUI ()
- except:
- DiscWindow.SetVisible (WINDOW_VISIBLE)
-
-def SetPSTGamedaysAndHourToken ():
- currentTime = GemRB.GetGameTime()
- hours = (currentTime % 7200) / 300
- if hours < 12:
- ampm = "AM"
- else:
- ampm = "PM"
- hours -= 12
- minutes = (currentTime % 300) / 60
-
- GemRB.SetToken ('CLOCK_HOUR', str (hours))
- GemRB.SetToken ('CLOCK_MINUTE', '%02d' %minutes)
- GemRB.SetToken ('CLOCK_AMPM', ampm)
-
-def UpdateClock():
- ActionsWindow = GemRB.LoadWindow(0)
- Button = ActionsWindow.GetControl (0)
- SetPSTGamedaysAndHourToken ()
- Button.SetTooltip (65027)
-
-def UpdateActionsWindow():
- # pst doesn't need this, but it is one of the core callbacks, so it has to be defined
- return
-
-def ActionStopPressed ():
- for i in range (PARTY_SIZE):
- if GemRB.GameIsPCSelected (i + 1):
- GemRB.ClearActions (i + 1)
- return
-
-def ActionTalkPressed ():
- GemRB.GameControlSetTargetMode (TARGET_MODE_TALK,GA_NO_DEAD|GA_NO_ENEMY|GA_NO_HIDDEN)
-
-def ActionAttackPressed ():
- GemRB.GameControlSetTargetMode (TARGET_MODE_ATTACK,GA_NO_DEAD|GA_NO_SELF|GA_NO_HIDDEN)
-
-def ActionDefendPressed ():
- GemRB.GameControlSetTargetMode (TARGET_MODE_DEFEND,GA_NO_SELF|GA_NO_ENEMY|GA_NO_HIDDEN)
-
-def ActionThievingPressed ():
- GemRB.GameControlSetTargetMode (TARGET_MODE_PICK, GA_NO_DEAD|GA_NO_SELF|GA_NO_ENEMY|GA_NO_HIDDEN)
-
-#this is an unused callback in PST
-def EmptyControls ():
- return
-
-def CheckLevelUp(pc):
- GemRB.SetVar ("CheckLevelUp"+str(pc), LUCommon.CanLevelUp (pc))
diff --git a/gemrb/GUIScripts/pst/GUIINV.py b/gemrb/GUIScripts/pst/GUIINV.py
index c724584..725836e 100644
--- a/gemrb/GUIScripts/pst/GUIINV.py
+++ b/gemrb/GUIScripts/pst/GUIINV.py
@@ -35,6 +35,13 @@ InventoryWindow = None
ItemAmountWindow = None
OverSlot = None
+def OpenInventoryWindowClick ():
+ tmp = GemRB.GetVar ("PressedPortrait")
+ GemRB.GameSelectPC (tmp, True, SELECT_REPLACE)
+ OpenInventoryWindow ()
+ return
+
+
ItemHash = {}
# Control ID's:
@@ -64,7 +71,7 @@ def OpenInventoryWindow ():
AvSlotsTable = GemRB.LoadTable ('avslots')
if GUICommon.CloseOtherWindow (OpenInventoryWindow):
- GemRB.HideGUI ()
+ GUICommon.GameWindow.SetVisible(WINDOW_VISIBLE)
if InventoryWindow:
InventoryWindow.Unload ()
InventoryWindow = None
@@ -141,8 +148,10 @@ def OpenInventoryWindow ():
GUICommonWindows.SetSelectionChangeHandler (UpdateInventoryWindow)
UpdateInventoryWindow ()
- GemRB.UnhideGUI()
-
+ GUICommon.GameWindow.SetVisible(WINDOW_INVISIBLE)
+ GUICommonWindows.PortraitWindow.SetVisible(WINDOW_VISIBLE)
+ GUICommonWindows.OptionsWindow.SetVisible(WINDOW_VISIBLE)
+ return
def UpdateInventoryWindow ():
global ItemHash
@@ -190,7 +199,6 @@ def RefreshInventoryWindow ():
# armor class
ac = GemRB.GetPlayerStat (pc, IE_ARMORCLASS)
- ac += GemRB.GetAbilityBonus (IE_DEX, 2, GemRB.GetPlayerStat (pc, IE_DEX) )
Label = Window.GetControl (0x1000003a)
Label.SetText (str (ac))
@@ -209,16 +217,12 @@ def RefreshInventoryWindow ():
Label.SetText (str (GemRB.GameGetPartyGold ()))
# class
- text = CommonTables.Classes.GetValue (GemRB.GetPlayerStat (pc, IE_CLASS) - 1, 0)
+ text = CommonTables.Classes.GetValue (GUICommon.GetClassRowName (pc), "NAME_REF")
Label = Window.GetControl (0x1000003f)
Label.SetText (text)
- held = GemRB.GetPlayerStat (pc, IE_HELD) + GemRB.GetPlayerStat (pc, IE_CASTERHOLD)
- if held == 0 and GemRB.GetPlayerStat (pc, IE_STATE_ID) & STATE_DEAD == 0:
- Window.SetVisible (WINDOW_VISIBLE)
- else:
- Window.SetVisible (WINDOW_GRAYED)
+ GUICommon.AdjustWindowVisibility (Window, pc, False)
# update ground inventory slots
Container = GemRB.GetContainer(pc, 1)
@@ -226,7 +230,7 @@ def RefreshInventoryWindow ():
for i in range (10):
Button = Window.GetControl (i+47)
if GemRB.IsDraggingItem ():
- Button.SetState (IE_GUI_BUTTON_SECOND)
+ Button.SetState (IE_GUI_BUTTON_FAKEPRESSED)
else:
Button.SetState (IE_GUI_BUTTON_ENABLED)
Button.SetEvent (IE_GUI_BUTTON_ON_DRAG_DROP, InventoryCommon.OnDragItemGround)
@@ -270,6 +274,9 @@ def UpdateSlot (pc, i):
slot = slot_list[i]+1
SlotType = GemRB.GetSlotType (slot)
slot_item = GemRB.GetSlotItem (pc, slot)
+ #PST displays the default weapon in the first slot if nothing else was equipped
+ if slot_item == None and SlotType["ID"] == 10 and GemRB.GetEquippedQuickSlot(pc)==10:
+ slot_item = GemRB.GetSlotItem (pc, 0)
ControlID = SlotType["ID"]
if ControlID<0:
@@ -291,7 +298,7 @@ def UpdateSlot (pc, i):
identified = slot_item['Flags'] & IE_INV_ITEM_IDENTIFIED
Button.SetItemIcon (slot_item['ItemResRef'])
- if item['StackAmount'] > 1:
+ if item['MaxStackAmount'] > 1:
Button.SetText (str (slot_item['Usages0']))
else:
Button.SetText ('')
@@ -330,7 +337,11 @@ def UpdateSlot (pc, i):
Button.EnableBorder (0, 0)
Button.EnableBorder (1, 0)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, None)
+
+ if SlotType["Effects"]==4:
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, DefaultWeapon)
+ else:
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, None)
Button.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, None)
Button.SetEvent (IE_GUI_BUTTON_ON_SHIFT_PRESS, None)
@@ -343,10 +354,16 @@ def UpdateSlot (pc, i):
if (SlotType["Type"]&SLOT_INVENTORY) or not GemRB.CanUseItemType (SlotType["Type"], itemname):
Button.SetState (IE_GUI_BUTTON_ENABLED)
else:
- Button.SetState (IE_GUI_BUTTON_SECOND)
+ Button.SetState (IE_GUI_BUTTON_FAKEPRESSED)
if slot_item and (GemRB.GetEquippedQuickSlot (pc)==slot or GemRB.GetEquippedAmmunition (pc)==slot):
- Button.SetState (IE_GUI_BUTTON_THIRD)
+ Button.SetState (IE_GUI_BUTTON_FAKEDISABLED)
+ return
+
+def DefaultWeapon ():
+ pc = GemRB.GameGetFirstSelectedActor ()
+ GemRB.SetEquippedQuickSlot (pc, 1000, -1)
+ UpdateInventoryWindow ()
return
def OnAutoEquip ():
diff --git a/gemrb/GUIScripts/pst/GUIJRNL.py b/gemrb/GUIScripts/pst/GUIJRNL.py
index 5e5d3f3..1ce37a8 100644
--- a/gemrb/GUIScripts/pst/GUIJRNL.py
+++ b/gemrb/GUIScripts/pst/GUIJRNL.py
@@ -110,6 +110,8 @@ def OpenJournalWindow ():
Button = JournalWindow.GetControl (3)
Button.SetText (20636)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenJournalWindow)
+ Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+ Button.SetStatus (IE_GUI_CONTROL_FOCUSED)
#JournalWindow.SetVisible (WINDOW_VISIBLE)
GemRB.UnhideGUI()
@@ -149,6 +151,8 @@ def OpenQuestsWindow ():
Button = Window.GetControl (5)
Button.SetText (46677)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenQuestsWindow)
+ Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+ Button.SetStatus (IE_GUI_CONTROL_FOCUSED)
# Done
Button = Window.GetControl (0)
@@ -318,6 +322,8 @@ def OpenBeastsWindow ():
Button = BeastsWindow.GetControl (7)
Button.SetText (46677)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenBeastsWindow)
+ Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+ Button.SetStatus (IE_GUI_CONTROL_FOCUSED)
# Done
Button = BeastsWindow.GetControl (4)
@@ -417,6 +423,8 @@ def OpenLogWindow ():
Button = Window.GetControl (1)
Button.SetText (46677)
Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenLogWindow)
+ Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
+ Button.SetStatus (IE_GUI_CONTROL_FOCUSED)
# Done
Button = Window.GetControl (0)
diff --git a/gemrb/GUIScripts/pst/GUIMA.py b/gemrb/GUIScripts/pst/GUIMA.py
index 33b4beb..e6a72db 100644
--- a/gemrb/GUIScripts/pst/GUIMA.py
+++ b/gemrb/GUIScripts/pst/GUIMA.py
@@ -177,7 +177,8 @@ def WorldMapWindowCommon (Travel):
WMap.SetAnimation ("WMPTY")
#center on current area
WMap.AdjustScrolling (0,0)
-
+ WMap.SetStatus (IE_GUI_CONTROL_FOCUSED)
+
# Done
Button = Window.GetControl (0)
Button.SetText (1403)
diff --git a/gemrb/GUIScripts/pst/GUIMG.py b/gemrb/GUIScripts/pst/GUIMG.py
index b434116..4af59a4 100644
--- a/gemrb/GUIScripts/pst/GUIMG.py
+++ b/gemrb/GUIScripts/pst/GUIMG.py
@@ -87,7 +87,7 @@ def UpdateMageWindow ():
Label = Window.GetControl (0x10000026)
GemRB.SetToken ('LEVEL', str (level + 1))
Label.SetText (19672)
- mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level)
+ mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level, False)
for i in range (12):
Icon = Window.GetControl (2 + i)
Icon.SetBorder (0, 0, 0, 0, 0, 0, 0, 0, 160, 0, 1)
@@ -137,11 +137,9 @@ def UpdateMageWindow ():
Icon.SetEvent (IE_GUI_BUTTON_ON_PRESS, None)
Icon.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, None)
Icon.SetTooltip ('')
- if (CommonTables.ClassSkills.GetValue (GemRB.GetPlayerStat (pc, IE_CLASS), 2)=="*") or \
- GemRB.GetPlayerStat (pc, IE_STATE_ID) & STATE_DEAD:
- Window.SetVisible (WINDOW_GRAYED)
- else:
- Window.SetVisible (WINDOW_VISIBLE)
+
+ CantCast = CommonTables.ClassSkills.GetValue (GUICommon.GetClassRowName (pc), "MAGESPELL") == "*"
+ GUICommon.AdjustWindowVisibility (Window, pc, CantCast)
def MagePrevLevelPress ():
global MageSpellLevel
diff --git a/gemrb/GUIScripts/pst/GUIOPT.py b/gemrb/GUIScripts/pst/GUIOPT.py
index a91d060..a859559 100644
--- a/gemrb/GUIScripts/pst/GUIOPT.py
+++ b/gemrb/GUIScripts/pst/GUIOPT.py
@@ -37,19 +37,15 @@ import GemRB
import GUICommon
import GUICommonWindows
import GUISAVE
+import GUIOPTControls
from GUIDefines import *
###################################################
OptionsWindow = None
-VideoOptionsWindow = None
-AudioOptionsWindow = None
-GameplayOptionsWindow = None
-FeedbackOptionsWindow = None
-AutopauseOptionsWindow = None
+SubOptionsWindow = None
+SubSubOptionsWindow = None
LoadMsgWindow = None
QuitMsgWindow = None
-MoviesWindow = None
-KeysWindow = None
###################################################
def OpenOptionsWindow ():
@@ -57,16 +53,6 @@ def OpenOptionsWindow ():
global OptionsWindow
if GUICommon.CloseOtherWindow (OpenOptionsWindow):
- if VideoOptionsWindow: OpenVideoOptionsWindow ()
- if AudioOptionsWindow: OpenAudioOptionsWindow ()
- if GameplayOptionsWindow: OpenGameplayOptionsWindow ()
- if FeedbackOptionsWindow: OpenFeedbackOptionsWindow ()
- if AutopauseOptionsWindow: OpenAutopauseOptionsWindow ()
- if LoadMsgWindow: OpenLoadMsgWindow ()
- if QuitMsgWindow: OpenQuitMsgWindow ()
- if KeysWindow: OpenKeysWindow ()
- if MoviesWindow: OpenMoviesWindow ()
-
GemRB.HideGUI ()
if OptionsWindow:
OptionsWindow.Unload ()
@@ -132,101 +118,76 @@ def OpenOptionsWindow ():
Label = Window.GetControl (0x10000007)
Label.SetText (GEMRB_VERSION)
- #Window.SetVisible (WINDOW_VISIBLE)
GemRB.UnhideGUI ()
+def TrySavingConfiguration():
+ if not GemRB.SaveConfig():
+ print "ARGH, could not write config to disk!!"
-
###################################################
def OpenVideoOptionsWindow ():
"""Open video options window"""
- global VideoOptionsWindow, VideoHelpText
+ global SubOptionsWindow, VideoHelpText
GemRB.HideGUI ()
- if VideoOptionsWindow:
- if VideoOptionsWindow:
- VideoOptionsWindow.Unload ()
- VideoOptionsWindow = None
- GemRB.SetVar ("FloatWindow", -1)
-
+ if SubOptionsWindow:
+ CloseSubOptionsWindow ()
+ TrySavingConfiguration()
GemRB.UnhideGUI ()
return
-
- VideoOptionsWindow = Window = GemRB.LoadWindow (1)
- GemRB.SetVar ("FloatWindow", VideoOptionsWindow.ID)
+ SubOptionsWindow = Window = GemRB.LoadWindow (1)
+ GemRB.SetVar ("FloatWindow", SubOptionsWindow.ID)
- VideoHelpText = OptHelpText ('VideoOptions', Window, 9, 31052)
+ VideoHelpText = GUIOPTControls.OptHelpText ('VideoOptions', Window, 9, 31052)
- OptDone ('VideoOptions', Window, 7)
- OptCancel ('VideoOptions', Window, 8)
+ GUIOPTControls.OptDone (OpenVideoOptionsWindow, Window, 7)
+ GUIOPTControls.OptCancel (OpenVideoOptionsWindow, Window, 8)
- OptSlider ('VideoOptions', 'Brightness', Window, 1, 10, 31234, "Brightness Correction", GammaFeedback, 1)
- OptSlider ('VideoOptions', 'Contrast', Window, 2, 11, 31429, "Gamma Correction", GammaFeedback, 1)
+ GUIOPTControls.OptSlider (31052, 31431, VideoHelpText, Window, 1, 10, 31234, "Brightness Correction", lambda: GammaFeedback(31431))
+ GUIOPTControls.OptSlider (31052, 31459, VideoHelpText, Window, 2, 11, 31429, "Gamma Correction", lambda: GammaFeedback(31459))
- OptCheckbox ('VideoOptions', 'SoftwareBlitting', Window, 6, 15, 30898, None) #TODO: SoftBlt
- OptCheckbox ('VideoOptions', 'SoftwareMirroring', Window, 4, 13, 30896, None) #TODO: SoftMirrorBlt
- OptCheckbox ('VideoOptions', 'SoftwareTransparency', Window, 5, 14, 30897, None) #TODO: SoftSrcKeyBlt
+ GUIOPTControls.OptCheckbox (31052, 31221, VideoHelpText, Window, 6, 15, 30898, "SoftBlt")
+ GUIOPTControls.OptCheckbox (31052, 31216, VideoHelpText, Window, 4, 13, 30896, "SoftMirrorBlt")
+ GUIOPTControls.OptCheckbox (31052, 31220, VideoHelpText, Window, 5, 14, 30897, "SoftSrcKeyBlt")
GemRB.UnhideGUI ()
Window.ShowModal (MODAL_SHADOW_GRAY)
return
-def GammaFeedback ():
- GemRB.SetGamma (GemRB.GetVar("Brightness Correction")/5,GemRB.GetVar("Gamma Correction")/5)
+def GammaFeedback (feedback_ref):
+ VideoHelpText.SetText (feedback_ref)
+ GemRB.SetGamma (GemRB.GetVar("Brightness Correction")/5,GemRB.GetVar("Gamma Correction")/20)
return
-def DisplayHelpVideoOptions ():
- VideoHelpText.SetText (31052)
-
-def DisplayHelpBrightness ():
- VideoHelpText.SetText (31431)
-
-def DisplayHelpContrast ():
- VideoHelpText.SetText (31459)
-
-def DisplayHelpSoftwareBlitting ():
- VideoHelpText.SetText (31221)
-
-def DisplayHelpSoftwareMirroring ():
- VideoHelpText.SetText (31216)
-
-def DisplayHelpSoftwareTransparency ():
- VideoHelpText.SetText (31220)
-
-
-
###################################################
saved_audio_options = {}
def OpenAudioOptionsWindow ():
"""Open audio options window"""
- global AudioOptionsWindow, AudioHelpText
+ global SubOptionsWindow, AudioHelpText
GemRB.HideGUI ()
- if AudioOptionsWindow:
- if AudioOptionsWindow:
- AudioOptionsWindow.Unload ()
- AudioOptionsWindow = None
- GemRB.SetVar ("FloatWindow", -1)
+ if SubOptionsWindow:
+ CloseSubOptionsWindow ()
# Restore values in case of cancel
if GemRB.GetVar ("Cancel") == 1:
for k, v in saved_audio_options.items ():
GemRB.SetVar (k, v)
- UpdateVolume ()
-
+ UpdateVolume (31210)
+
+ TrySavingConfiguration()
GemRB.UnhideGUI ()
return
-
- AudioOptionsWindow = Window = GemRB.LoadWindow (5)
- GemRB.SetVar ("FloatWindow", AudioOptionsWindow.ID)
+ SubOptionsWindow = Window = GemRB.LoadWindow (5)
+ GemRB.SetVar ("FloatWindow", SubOptionsWindow.ID)
# save values, so we can restore them on cancel
@@ -234,305 +195,152 @@ def OpenAudioOptionsWindow ():
saved_audio_options[v] = GemRB.GetVar (v)
- AudioHelpText = OptHelpText ('AudioOptions', Window, 9, 31210)
+ AudioHelpText = GUIOPTControls.OptHelpText ('AudioOptions', Window, 9, 31210)
- OptDone ('AudioOptions', Window, 7)
- OptCancel ('AudioOptions', Window, 8)
+ GUIOPTControls.OptDone (OpenAudioOptionsWindow, Window, 7)
+ GUIOPTControls.OptCancel (OpenAudioOptionsWindow, Window, 8)
-
- OptSlider ('AudioOptions', 'AmbientVolume', Window, 1, 10, 31460, "Volume Ambients", UpdateVolume)
- OptSlider ('AudioOptions', 'SoundFXVolume', Window, 2, 11, 31466, "Volume SFX", UpdateVolume)
- OptSlider ('AudioOptions', 'VoiceVolume', Window, 3, 12, 31467, "Volume Voices", UpdateVolume)
- OptSlider ('AudioOptions', 'MusicVolume', Window, 4, 13, 31468, "Volume Music", UpdateVolume)
- OptSlider ('AudioOptions', 'MovieVolume', Window, 5, 14, 31469, "Volume Movie", UpdateVolume)
+ GUIOPTControls.OptSlider (31210, 31227, AudioHelpText, Window, 1, 10, 31460, "Volume Ambients", lambda: UpdateVolume(31227))
+ GUIOPTControls.OptSlider (31210, 31228, AudioHelpText, Window, 2, 11, 31466, "Volume SFX", lambda: UpdateVolume(31228))
+ GUIOPTControls.OptSlider (31210, 31226, AudioHelpText, Window, 3, 12, 31467, "Volume Voices", lambda: UpdateVolume(31226))
+ GUIOPTControls.OptSlider (31210, 31225, AudioHelpText, Window, 4, 13, 31468, "Volume Music", lambda: UpdateVolume(31225))
+ GUIOPTControls.OptSlider (31210, 31229, AudioHelpText, Window, 5, 14, 31469, "Volume Movie", lambda: UpdateVolume(31229))
- OptCheckbox ('AudioOptions', 'CreativeEAX', Window, 6, 15, 30900, "Environmental Audio")
- OptCheckbox ('AudioOptions', 'SoundProcessing', Window, 16, 17, 63242, "Sound Processing")
- OptCheckbox ('AudioOptions', 'MusicProcessing', Window, 18, 19, 63243, "Music Processing")
-
+ GUIOPTControls.OptCheckbox (31210, 31224, AudioHelpText, Window, 6, 15, 30900, "Environmental Audio")
+ GUIOPTControls.OptCheckbox (31210, 63244, AudioHelpText, Window, 16, 17, 63242, "Sound Processing")
+ GUIOPTControls.OptCheckbox (31210, 63247, AudioHelpText, Window, 18, 19, 63243, "Music Processing")
- #AudioOptionsWindow.SetVisible (WINDOW_VISIBLE)
GemRB.UnhideGUI ()
Window.ShowModal (MODAL_SHADOW_GRAY)
-def UpdateVolume ():
+def UpdateVolume (volume_ref):
+ AudioHelpText.SetText (volume_ref)
GemRB.UpdateAmbientsVolume ()
GemRB.UpdateMusicVolume ()
-
-def DisplayHelpAudioOptions ():
- AudioHelpText.SetText (31210)
-
-def DisplayHelpAmbientVolume ():
- AudioHelpText.SetText (31227)
-
-def DisplayHelpSoundFXVolume ():
- AudioHelpText.SetText (31228)
-
-def DisplayHelpVoiceVolume ():
- AudioHelpText.SetText (31226)
-
-def DisplayHelpMusicVolume ():
- AudioHelpText.SetText (31225)
-
-def DisplayHelpMovieVolume ():
- AudioHelpText.SetText (31229)
-
-def DisplayHelpCreativeEAX ():
- AudioHelpText.SetText (31224)
-
-def DisplayHelpSoundProcessing ():
- AudioHelpText.SetText (63244)
-
-def DisplayHelpMusicProcessing ():
- AudioHelpText.SetText (63247)
-
-
###################################################
def OpenGameplayOptionsWindow ():
"""Open gameplay options window"""
- global GameplayOptionsWindow, GameplayHelpText
+ global SubOptionsWindow, GameplayHelpText
GemRB.HideGUI ()
- if GameplayOptionsWindow:
- if FeedbackOptionsWindow: OpenFeedbackOptionsWindow()
- if AutopauseOptionsWindow: OpenAutopauseOptionsWindow()
-
- if GameplayOptionsWindow:
- GameplayOptionsWindow.Unload ()
- GameplayOptionsWindow = None
- GemRB.SetVar ("FloatWindow", -1)
-
+ if SubOptionsWindow:
+ CloseSubOptionsWindow ()
+ TrySavingConfiguration()
GemRB.UnhideGUI ()
return
-
- GameplayOptionsWindow = Window = GemRB.LoadWindow (6)
- GemRB.SetVar ("FloatWindow", GameplayOptionsWindow.ID)
+ SubOptionsWindow = Window = GemRB.LoadWindow (6)
+ GemRB.SetVar ("FloatWindow", SubOptionsWindow.ID)
- GameplayHelpText = OptHelpText ('GameplayOptions', Window, 12, 31212)
+ GameplayHelpText = GUIOPTControls.OptHelpText ('GameplayOptions', Window, 12, 31212)
- OptDone ('GameplayOptions', Window, 10)
- OptCancel ('GameplayOptions', Window, 11)
+ GUIOPTControls.OptDone (OpenGameplayOptionsWindow, Window, 10)
+ GUIOPTControls.OptCancel (OpenGameplayOptionsWindow, Window, 11)
- OptSlider ('GameplayOptions', 'TooltipDelay', Window, 1, 13, 31481, "Tooltips", UpdateTooltips, TOOLTIP_DELAY_FACTOR)
- OptSlider ('GameplayOptions', 'MouseScrollingSpeed', Window, 2, 14, 31482, "Mouse Scroll Speed", UpdateMouseSpeed)
- OptSlider ('GameplayOptions', 'KeyboardScrollingSpeed', Window, 3, 15, 31480, "Keyboard Scroll Speed", UpdateKeyboardSpeed)
- OptSlider ('GameplayOptions', 'Difficulty', Window, 4, 16, 31479, "Difficulty Level")
+ GUIOPTControls.OptSlider (31212, 31232, GameplayHelpText, Window, 1, 13, 31481, "Tooltips", UpdateTooltips, TOOLTIP_DELAY_FACTOR)
+ GUIOPTControls.OptSlider (31212, 31230, GameplayHelpText, Window, 2, 14, 31482, "Mouse Scroll Speed", UpdateMouseSpeed)
+ GUIOPTControls.OptSlider (31212, 31231, GameplayHelpText, Window, 3, 15, 31480, "Keyboard Scroll Speed")
+ GUIOPTControls.OptSlider (31212, 31233, GameplayHelpText, Window, 4, 16, 31479, "Difficulty Level")
- OptCheckbox ('GameplayOptions', 'DitherAlways', Window, 5, 17, 31217, "Always Dither")
- OptCheckbox ('GameplayOptions', 'Gore', Window, 6, 18, 31218, "Gore???")
- OptCheckbox ('GameplayOptions', 'AlwaysRun', Window, 22, 23, 62418, "Always Run")
+ GUIOPTControls.OptCheckbox (31212, 31222, GameplayHelpText, Window, 5, 17, 31217, "Always Dither")
+ GUIOPTControls.OptCheckbox (31212, 31223, GameplayHelpText, Window, 6, 18, 31218, "Gore")
+ GUIOPTControls.OptCheckbox (31212, 62419, GameplayHelpText, Window, 22, 23, 62418, "Always Run")
- OptButton ('GameplayOptions', 'FeedbackOptions', Window, 8, 20, 31478)
- OptButton ('GameplayOptions', 'AutopauseOptions', Window, 9, 21, 31470)
+ PSTOptButton (31212, 31213, GameplayHelpText, Window, 8, 20, 31478, OpenFeedbackOptionsWindow)
+ PSTOptButton (31212, 31214, GameplayHelpText, Window, 9, 21, 31470, OpenAutopauseOptionsWindow)
GemRB.UnhideGUI ()
Window.ShowModal (MODAL_SHADOW_GRAY)
return
-def DisplayHelpGameplayOptions ():
- GameplayHelpText.SetText (31212)
-
def UpdateTooltips ():
- GemRB.SetTooltipDelay (GemRB.GetVar ("Tooltips") )
-
-def DisplayHelpTooltipDelay ():
GameplayHelpText.SetText (31232)
+ GemRB.SetTooltipDelay (GemRB.GetVar ("Tooltips") )
def UpdateMouseSpeed ():
- GemRB.SetMouseScrollSpeed (GemRB.GetVar ("Mouse Scroll Speed") )
-
-def DisplayHelpMouseScrollingSpeed ():
GameplayHelpText.SetText (31230)
-
-def UpdateKeyboardSpeed ():
- #GemRB.SetKeyboardScrollSpeed (GemRB.GetVar ("Keyboard Scroll Speed") )
- return
-
-def DisplayHelpKeyboardScrollingSpeed ():
- GameplayHelpText.SetText (31231)
-
-def DisplayHelpDifficulty ():
- GameplayHelpText.SetText (31233)
-
-def DisplayHelpDitherAlways ():
- GameplayHelpText.SetText (31222)
-
-def DisplayHelpGore ():
- GameplayHelpText.SetText (31223)
-
-def DisplayHelpAlwaysRun ():
- GameplayHelpText.SetText (62419)
-
-def DisplayHelpFeedbackOptions ():
- GameplayHelpText.SetText (31213)
-
-def DisplayHelpAutopauseOptions ():
- GameplayHelpText.SetText (31214)
-
-
+ GemRB.SetMouseScrollSpeed (GemRB.GetVar ("Mouse Scroll Speed") )
###################################################
def OpenFeedbackOptionsWindow ():
"""Open feedback options window"""
- global FeedbackOptionsWindow, FeedbackHelpText
+ global SubSubOptionsWindow, FeedbackHelpText
GemRB.HideGUI ()
- if FeedbackOptionsWindow:
- if FeedbackOptionsWindow:
- FeedbackOptionsWindow.Unload ()
- FeedbackOptionsWindow = None
- GemRB.SetVar ("FloatWindow", GameplayOptionsWindow.ID)
-
+ if SubSubOptionsWindow:
+ CloseSubSubOptionsWindow ()
GemRB.UnhideGUI ()
- GameplayOptionsWindow.ShowModal (MODAL_SHADOW_GRAY)
return
-
- FeedbackOptionsWindow = Window = GemRB.LoadWindow (8)
- GemRB.SetVar ("FloatWindow", FeedbackOptionsWindow.ID)
+ SubSubOptionsWindow = Window = GemRB.LoadWindow (8)
+ GemRB.SetVar ("FloatWindow", SubSubOptionsWindow.ID)
+ GemRB.SetVar ("Circle Feedback", GemRB.GetVar ("GUI Feedback Level") - 1)
- FeedbackHelpText = OptHelpText ('FeedbackOptions', Window, 9, 37410)
+ FeedbackHelpText = GUIOPTControls.OptHelpText ('FeedbackOptions', Window, 9, 37410)
- OptDone ('FeedbackOptions', Window, 7)
- OptCancel ('FeedbackOptions', Window, 8)
+ GUIOPTControls.OptDone (OpenFeedbackOptionsWindow, Window, 7)
+ GUIOPTControls.OptCancel (OpenFeedbackOptionsWindow, Window, 8)
- OptSlider ('FeedbackOptions', 'MarkerFeedback', Window, 1, 10, 37463, "GUI Feedback Level")
- OptSlider ('FeedbackOptions', 'LocatorFeedback', Window, 2, 11, 37586, "Locator Feedback Level")
- OptSlider ('FeedbackOptions', 'SelectionFeedbackLevel', Window, 20, 21, 54879, "Selection Sounds Frequency")
- OptSlider ('FeedbackOptions', 'CommandFeedbackLevel', Window, 22, 23, 55012, "Command Sounds Frequency")
-
- OptCheckbox ('FeedbackOptions', 'CharacterStates', Window, 6, 15, 37594, "")
- OptCheckbox ('FeedbackOptions', 'MiscellaneousMessages', Window, 17, 19, 37596, "")
- OptCheckbox ('FeedbackOptions', 'ToHitRolls', Window, 3, 12, 37588, "")
- OptCheckbox ('FeedbackOptions', 'CombatInfo', Window, 4, 13, 37590, "")
- OptCheckbox ('FeedbackOptions', 'SpellCasting', Window, 5, 14, 37592, "")
+ GUIOPTControls.OptSlider (31213, 37411, FeedbackHelpText, Window, 1, 10, 37463, "Circle Feedback", UpdateMarkerFeedback)
+ GUIOPTControls.OptSlider (31213, 37447, FeedbackHelpText, Window, 2, 11, 37586, "Locator Feedback Level")
+ GUIOPTControls.OptSlider (31213, 54878, FeedbackHelpText, Window, 20, 21, 54879, "Selection Sounds Frequency")
+ GUIOPTControls.OptSlider (31213, 54880, FeedbackHelpText, Window, 22, 23, 55012, "Command Sounds Frequency")
+ # TODO: once the pst overhead messaging system is in place, add the relevant game vars below
+ GUIOPTControls.OptCheckbox (31213, 37460, FeedbackHelpText, Window, 6, 15, 37594, "")
+ GUIOPTControls.OptCheckbox (31213, 37462, FeedbackHelpText, Window, 17, 19, 37596, "")
+ GUIOPTControls.OptCheckbox (31213, 37453, FeedbackHelpText, Window, 3, 12, 37588, "")
+ GUIOPTControls.OptCheckbox (31213, 37457, FeedbackHelpText, Window, 4, 13, 37590, "")
+ GUIOPTControls.OptCheckbox (31213, 37458, FeedbackHelpText, Window, 5, 14, 37592, "")
GemRB.UnhideGUI ()
Window.ShowModal (MODAL_SHADOW_GRAY)
-def DisplayHelpMarkerFeedback ():
- FeedbackHelpText.SetText (37411)
-
-def DisplayHelpLocatorFeedback ():
- FeedbackHelpText.SetText (37447)
-
-def DisplayHelpSelectionFeedbackLevel ():
- FeedbackHelpText.SetText (54878)
-
-def DisplayHelpCommandFeedbackLevel ():
- FeedbackHelpText.SetText (54880)
-
-def DisplayHelpCharacterStates ():
- FeedbackHelpText.SetText (37460)
-
-def DisplayHelpMiscellaneousMessages ():
- FeedbackHelpText.SetText (37462)
-
-def DisplayHelpToHitRolls ():
- FeedbackHelpText.SetText (37453)
-
-def DisplayHelpCombatInfo ():
- FeedbackHelpText.SetText (37457)
-
-def DisplayHelpSpellCasting ():
- FeedbackHelpText.SetText (37458)
-
+def UpdateMarkerFeedback ():
+ GemRB.SetVar ("GUI Feedback Level", GemRB.GetVar ("Circle Feedback") + 1)
###################################################
def OpenAutopauseOptionsWindow ():
"""Open autopause options window"""
- global AutopauseOptionsWindow, AutopauseHelpText
+ global SubSubOptionsWindow, AutopauseHelpText
GemRB.HideGUI ()
- if AutopauseOptionsWindow:
- if AutopauseOptionsWindow:
- AutopauseOptionsWindow.Unload ()
- AutopauseOptionsWindow = None
- GemRB.SetVar ("FloatWindow", GameplayOptionsWindow.ID)
-
+ if SubSubOptionsWindow:
+ CloseSubSubOptionsWindow ()
GemRB.UnhideGUI ()
- GameplayOptionsWindow.ShowModal (MODAL_SHADOW_GRAY)
return
- AutopauseOptionsWindow = Window = GemRB.LoadWindow (9)
- GemRB.SetVar ("FloatWindow", AutopauseOptionsWindow.ID)
+ SubSubOptionsWindow = Window = GemRB.LoadWindow (9)
+ GemRB.SetVar ("FloatWindow", SubSubOptionsWindow.ID)
- AutopauseHelpText = OptHelpText ('AutopauseOptions', Window, 1, 31214)
+ AutopauseHelpText = GUIOPTControls.OptHelpText ('AutopauseOptions', Window, 1, 31214)
- OptDone ('AutopauseOptions', Window, 16)
- OptCancel ('AutopauseOptions', Window, 17)
+ GUIOPTControls.OptDone (OpenAutopauseOptionsWindow, Window, 16)
+ GUIOPTControls.OptCancel (OpenAutopauseOptionsWindow, Window, 17)
- # Set variable for each checkbox according to a particular bit of
- # AutoPauseState
- state = GemRB.GetVar ("Auto Pause State")
- GemRB.SetVar("AutoPauseState_Unusable", (state & 0x01) != 0 )
- GemRB.SetVar("AutoPauseState_Attacked", (state & 0x02) != 0 )
- GemRB.SetVar("AutoPauseState_Hit", (state & 0x04) != 0 )
- GemRB.SetVar("AutoPauseState_Wounded", (state & 0x08) != 0 )
- GemRB.SetVar("AutoPauseState_Dead", (state & 0x10) != 0 )
- GemRB.SetVar("AutoPauseState_NoTarget", (state & 0x20) != 0 )
- GemRB.SetVar("AutoPauseState_EndRound", (state & 0x40) != 0 )
-
-
- OptCheckbox ('AutopauseOptions', 'CharacterHit', Window, 2, 9, 37598, "AutoPauseState_Hit", OnAutoPauseClicked)
- OptCheckbox ('AutopauseOptions', 'CharacterInjured', Window, 3, 10, 37681, "AutoPauseState_Wounded", OnAutoPauseClicked)
- OptCheckbox ('AutopauseOptions', 'CharacterDead', Window, 4, 11, 37682, "AutoPauseState_Dead", OnAutoPauseClicked)
- OptCheckbox ('AutopauseOptions', 'CharacterAttacked', Window, 5, 12, 37683, "AutoPauseState_Attacked", OnAutoPauseClicked)
- OptCheckbox ('AutopauseOptions', 'WeaponUnusable', Window, 6, 13, 37684, "AutoPauseState_Unusable", OnAutoPauseClicked)
- OptCheckbox ('AutopauseOptions', 'TargetGone', Window, 7, 14, 37685, "AutoPauseState_NoTarget", OnAutoPauseClicked)
- OptCheckbox ('AutopauseOptions', 'EndOfRound', Window, 8, 15, 37686, "AutoPauseState_EndRound", OnAutoPauseClicked)
+ # checkboxes OR the values if they associate to the same variable
+ GUIOPTControls.OptCheckbox (31214, 37688, AutopauseHelpText, Window, 2, 9, 37598, "Auto Pause State", None, 4)
+ GUIOPTControls.OptCheckbox (31214, 37689, AutopauseHelpText, Window, 3, 10, 37681, "Auto Pause State", None, 8)
+ GUIOPTControls.OptCheckbox (31214, 37690, AutopauseHelpText, Window, 4, 11, 37682, "Auto Pause State", None, 16)
+ GUIOPTControls.OptCheckbox (31214, 37691, AutopauseHelpText, Window, 5, 12, 37683, "Auto Pause State", None, 2)
+ GUIOPTControls.OptCheckbox (31214, 37692, AutopauseHelpText, Window, 6, 13, 37684, "Auto Pause State", None, 1)
+ GUIOPTControls.OptCheckbox (31214, 37693, AutopauseHelpText, Window, 7, 14, 37685, "Auto Pause State", None, 32)
+ GUIOPTControls.OptCheckbox (31214, 37694, AutopauseHelpText, Window, 8, 15, 37686, "Auto Pause State", None, 64)
GemRB.UnhideGUI ()
Window.ShowModal (MODAL_SHADOW_GRAY)
-
-
-def OnAutoPauseClicked ():
- state = (0x01 * GemRB.GetVar("AutoPauseState_Unusable") +
- 0x02 * GemRB.GetVar("AutoPauseState_Attacked") +
- 0x04 * GemRB.GetVar("AutoPauseState_Hit") +
- 0x08 * GemRB.GetVar("AutoPauseState_Wounded") +
- 0x10 * GemRB.GetVar("AutoPauseState_Dead") +
- 0x20 * GemRB.GetVar("AutoPauseState_NoTarget") +
- 0x40 * GemRB.GetVar("AutoPauseState_EndRound"))
-
- GemRB.SetVar("Auto Pause State", state)
-
-def DisplayHelpCharacterHit ():
- AutopauseHelpText.SetText (37688)
-
-def DisplayHelpCharacterInjured ():
- AutopauseHelpText.SetText (37689)
-
-def DisplayHelpCharacterDead ():
- AutopauseHelpText.SetText (37690)
-
-def DisplayHelpCharacterAttacked ():
- AutopauseHelpText.SetText (37691)
-
-def DisplayHelpWeaponUnusable ():
- AutopauseHelpText.SetText (37692)
-
-def DisplayHelpTargetGone ():
- AutopauseHelpText.SetText (37693)
-
-def DisplayHelpEndOfRound ():
- AutopauseHelpText.SetText (37694)
-
-
###################################################
###################################################
@@ -572,6 +380,7 @@ def OpenLoadMsgWindow ():
def LoadGame ():
+ OpenLoadMsgWindow () ##close self
OpenOptionsWindow ()
GemRB.QuitGame ()
GemRB.SetNextScript ('GUILOAD')
@@ -627,10 +436,9 @@ def QuitGame ():
GemRB.SetNextScript ('Start')
def SaveGame ():
+ GemRB.SetVar ("QuitAfterSave", 1)
OpenOptionsWindow ()
- GemRB.QuitGame ()
- GemRB.SetNextScript ('GUISAVE')
-
+ GUISAVE.OpenSaveWindow ()
###################################################
@@ -655,17 +463,15 @@ KEYS_PAGE_SIZE = 60
KEYS_PAGE_COUNT = ((len (key_list) - 1) / KEYS_PAGE_SIZE)+ 1
def OpenKeyboardMappingsWindow ():
- global KeysWindow
+ global SubOptionsWindow
global last_key_action
last_key_action = None
GemRB.HideGUI()
- if KeysWindow:
- if KeysWindow:
- KeysWindow.Unload ()
- KeysWindow = None
+ if SubOptionsWindow:
+ CloseSubOptionsWindow ()
GemRB.SetVar ("OtherWindow", OptionsWindow.ID)
GemRB.LoadWindowPack ("GUIOPT")
@@ -673,9 +479,8 @@ def OpenKeyboardMappingsWindow ():
return
GemRB.LoadWindowPack ("GUIKEYS")
- KeysWindow = Window = GemRB.LoadWindow (0)
- GemRB.SetVar ("OtherWindow", KeysWindow.ID)
-
+ SubOptionsWindow = Window = GemRB.LoadWindow (0)
+ GemRB.SetVar ("OtherWindow", SubOptionsWindow.ID)
# Default
Button = Window.GetControl (3)
@@ -696,14 +501,10 @@ def OpenKeyboardMappingsWindow ():
keys_setup_page (0)
-
- #KeysWindow.SetVisible (WINDOW_VISIBLE)
GemRB.UnhideGUI ()
-
def keys_setup_page (pageno):
- Window = KeysWindow
-
+ Window = SubOptionsWindow
# Page n of n
Label = Window.GetControl (0x10000001)
@@ -712,14 +513,12 @@ def keys_setup_page (pageno):
GemRB.SetToken ('NUMPAGES', str (KEYS_PAGE_COUNT))
Label.SetText (49053)
-
for i in range (KEYS_PAGE_SIZE):
try:
label, key = key_list[pageno * KEYS_PAGE_SIZE + i]
except:
label = ''
key = None
-
if key == None:
# Section header
@@ -740,14 +539,13 @@ def keys_setup_page (pageno):
Label.SetText (label)
Label.SetEvent (IE_GUI_LABEL_ON_PRESS, OnActionLabelPress)
Label.SetVarAssoc ("KeyAction", i)
-
last_key_action = None
def OnActionLabelPress ():
global last_key_action
- Window = KeysWindow
+ Window = SubOptionsWindow
i = GemRB.GetVar ("KeyAction")
if last_key_action != None:
@@ -768,25 +566,19 @@ def OnActionLabelPress ():
###################################################
def OpenMoviesWindow ():
- global MoviesWindow
+ global SubOptionsWindow
GemRB.HideGUI()
- if MoviesWindow:
- if MoviesWindow:
- MoviesWindow.Unload ()
- MoviesWindow = None
- GemRB.SetVar ("FloatWindow", -1)
-
+ if SubOptionsWindow:
+ CloseSubOptionsWindow ()
GemRB.LoadWindowPack ("GUIOPT")
GemRB.UnhideGUI ()
return
GemRB.LoadWindowPack ("GUIMOVIE")
- # FIXME: clean the window to black
- MoviesWindow = Window = GemRB.LoadWindow (0)
- GemRB.SetVar ("FloatWindow", MoviesWindow.ID)
-
+ SubOptionsWindow = Window = GemRB.LoadWindow (0)
+ GemRB.SetVar ("FloatWindow", SubOptionsWindow.ID)
# Play Movie
Button = Window.GetControl (2)
@@ -807,9 +599,6 @@ def OpenMoviesWindow ():
List = Window.GetControl (0)
List.SetFlags (IE_GUI_TEXTAREA_SELECTABLE)
List.SetVarAssoc ('SelectedMovie', -1)
-
- #Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenMoviesWindow)
-
MovieTable = GemRB.LoadTable ("MOVIDESC")
@@ -818,12 +607,9 @@ def OpenMoviesWindow ():
desc = MovieTable.GetValue (i, 0)
List.Append (desc, i)
-
-
GemRB.UnhideGUI ()
Window.ShowModal (MODAL_SHADOW_BLACK)
-
###################################################
def OnPlayMoviePress ():
selected = GemRB.GetVar ('SelectedMovie')
@@ -843,98 +629,35 @@ def OnCreditsPress ():
GemRB.PlayMovie ("CREDITS")
###################################################
-###################################################
-
-# These functions help to setup controls found
-# in Video, Audio, Gameplay, Feedback and Autopause
-# options windows
-
-# These controls are usually made from an active
-# control (button, slider ...) and a label
-
-def OptSlider (winname, ctlname, window, slider_id, label_id, label_strref, assoc_var, fn = None, scale = 1):
- """Standard slider for option windows"""
- slider = window.GetControl (slider_id)
- #slider.SetEvent (IE_GUI_MOUSE_ENTER_BUTTON, eval("DisplayHelp" + ctlname))
- #slider.SetEvent (IE_GUI_MOUSE_LEAVE_BUTTON, eval("DisplayHelp" + winname))
- if fn: slider.SetEvent (IE_GUI_SLIDER_ON_CHANGE, fn)
+def CloseSubOptionsWindow ():
+ global SubOptionsWindow
- slider.SetVarAssoc (assoc_var, scale)
-
- label = window.GetControl (label_id)
- label.SetText (label_strref)
- label.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- label.SetState (IE_GUI_BUTTON_LOCKED)
- #label.SetEvent (IE_GUI_MOUSE_OVER_BUTTON, eval("DisplayHelp" + ctlname))
- label.SetEvent (IE_GUI_MOUSE_ENTER_BUTTON, eval("DisplayHelp" + ctlname))
- label.SetEvent (IE_GUI_MOUSE_LEAVE_BUTTON, eval("DisplayHelp" + winname))
-
- return slider
-
-
-def OptCheckbox (winname, ctlname, window, button_id, label_id, label_strref, assoc_var = None, handler = None):
- """Standard checkbox for option windows"""
-
- button = window.GetControl (button_id)
- button.SetFlags (IE_GUI_BUTTON_CHECKBOX, OP_OR)
- button.SetEvent (IE_GUI_MOUSE_ENTER_BUTTON, eval("DisplayHelp" + ctlname))
- button.SetEvent (IE_GUI_MOUSE_LEAVE_BUTTON, eval("DisplayHelp" + winname))
- if assoc_var:
- button.SetVarAssoc (assoc_var, 1)
- if GemRB.GetVar (assoc_var):
- button.SetState (IE_GUI_BUTTON_PRESSED)
- else:
- button.SetState (IE_GUI_BUTTON_UNPRESSED)
- else:
- button.SetState (IE_GUI_BUTTON_UNPRESSED)
-
- if handler:
- button.SetEvent (IE_GUI_BUTTON_ON_PRESS, handler)
+ if SubOptionsWindow:
+ SubOptionsWindow.Unload ()
+ SubOptionsWindow = None
+ GemRB.SetVar ("FloatWindow", -1)
+ return
- label = window.GetControl (label_id)
- label.SetText (label_strref)
- label.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- label.SetState (IE_GUI_BUTTON_LOCKED)
- label.SetEvent (IE_GUI_MOUSE_ENTER_BUTTON, eval("DisplayHelp" + ctlname))
- label.SetEvent (IE_GUI_MOUSE_LEAVE_BUTTON, eval("DisplayHelp" + winname))
+def CloseSubSubOptionsWindow ():
+ global SubSubOptionsWindow, SubOptionsWindow
- return button
+ if SubSubOptionsWindow:
+ SubSubOptionsWindow.Unload ()
+ SubSubOptionsWindow = None
+ if SubOptionsWindow:
+ SubOptionsWindow.ShowModal (MODAL_SHADOW_GRAY)
+ GemRB.SetVar ("FloatWindow", SubOptionsWindow.ID)
+ return
-def OptButton (winname, ctlname, window, button_id, label_id, label_strref):
+def PSTOptButton (winname, ctlname, help_ta, window, button_id, label_id, label_strref, action):
"""Standard subwindow button for option windows"""
button = window.GetControl (button_id)
- button.SetEvent (IE_GUI_BUTTON_ON_PRESS, eval("Open%sWindow" %ctlname))
- button.SetEvent (IE_GUI_MOUSE_ENTER_BUTTON, eval("DisplayHelp" + ctlname))
- button.SetEvent (IE_GUI_MOUSE_LEAVE_BUTTON, eval("DisplayHelp" + winname))
-
- label = window.GetControl (label_id)
- label.SetText (label_strref)
- label.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
- label.SetState (IE_GUI_BUTTON_LOCKED)
- label.SetEvent (IE_GUI_MOUSE_ENTER_BUTTON, eval("DisplayHelp" + ctlname))
- label.SetEvent (IE_GUI_MOUSE_LEAVE_BUTTON, eval("DisplayHelp" + winname))
-
-def OptDone (winname, window, button_id):
- """Standard `Done' button for option windows"""
- button = window.GetControl (button_id)
- button.SetText (1403) # Done
- button.SetEvent (IE_GUI_BUTTON_ON_PRESS, eval("Open%sWindow" %winname))
- button.SetVarAssoc ("Cancel", 0)
-
-def OptCancel (winname, window, button_id):
- """Standard `Cancel' button for option windows"""
- button = window.GetControl (button_id)
- button.SetText (4196) # Cancel
- button.SetEvent (IE_GUI_BUTTON_ON_PRESS, eval("Open%sWindow" %winname))
- button.SetVarAssoc ("Cancel", 1)
-
-def OptHelpText (winname, window, text_id, text_strref):
- """Standard textarea with context help for option windows"""
- text = window.GetControl (text_id)
- text.SetText (text_strref)
- return text
+ button.SetEvent (IE_GUI_BUTTON_ON_PRESS, action)
+ button.SetEvent (IE_GUI_MOUSE_ENTER_BUTTON, lambda: help_ta.SetText (ctlname))
+ button.SetEvent (IE_GUI_MOUSE_LEAVE_BUTTON, lambda: help_ta.SetText (winname))
+ GUIOPTControls.OptBuddyLabel (window, label_id, label_strref, help_ta, ctlname, winname)
###################################################
# End of file GUIOPT.py
diff --git a/gemrb/GUIScripts/pst/GUIPR.py b/gemrb/GUIScripts/pst/GUIPR.py
index 81c42d3..13fbf78 100644
--- a/gemrb/GUIScripts/pst/GUIPR.py
+++ b/gemrb/GUIScripts/pst/GUIPR.py
@@ -92,7 +92,7 @@ def UpdatePriestWindow ():
Label.SetText (19672)
- mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level)
+ mem_cnt = GemRB.GetMemorizedSpellsCount (pc, type, level, False)
for i in range (12):
Icon = Window.GetControl (2 + i)
Icon.SetBorder (0, 0, 0, 0, 0, 0, 0, 0, 160, 0, 1)
@@ -141,12 +141,11 @@ def UpdatePriestWindow ():
Icon.SetEvent (IE_GUI_BUTTON_ON_PRESS, None)
Icon.SetEvent (IE_GUI_BUTTON_ON_RIGHT_PRESS, None)
Icon.SetTooltip ('')
- CantCast = CommonTables.ClassSkills.GetValue (GemRB.GetPlayerStat (pc, IE_CLASS), 1) == "*"
+
+ ClassName = GUICommon.GetClassRowName (pc)
+ CantCast = CommonTables.ClassSkills.GetValue (ClassName, "CLERICSPELL") == "*"
CantCast += GemRB.GetPlayerStat(pc, IE_DISABLEDBUTTON)&(1<<ACT_CAST)
- if CantCast or GemRB.GetPlayerStat (pc, IE_STATE_ID) & STATE_DEAD:
- Window.SetVisible (WINDOW_GRAYED)
- else:
- Window.SetVisible (WINDOW_VISIBLE)
+ GUICommon.AdjustWindowVisibility (Window, pc, CantCast)
def PriestPrevLevelPress ():
diff --git a/gemrb/GUIScripts/pst/GUIREC.py b/gemrb/GUIScripts/pst/GUIREC.py
index a1597e9..a02709e 100644
--- a/gemrb/GUIScripts/pst/GUIREC.py
+++ b/gemrb/GUIScripts/pst/GUIREC.py
@@ -262,7 +262,7 @@ def UpdateRecordsWindow ():
# class
- text = CommonTables.Classes.GetValue (GemRB.GetPlayerStat (pc, IE_CLASS) - 1, 0)
+ text = CommonTables.Classes.GetValue (GUICommon.GetClassRowName (pc), "NAME_REF")
Label = Window.GetControl (0x10000016)
Label.SetText (text)
@@ -303,38 +303,25 @@ def UpdateRecordsWindow ():
# puts default info to textarea (overview of PC's bonuses, saves, etc.
def OnRecordsButtonLeave ():
- Window = RecordsWindow
- # help, info textarea
- Text = Window.GetControl (0)
- Text.SetText (stats_overview)
+ OnRecordsHelpStat (-1, 0, stats_overview)
return
def OnRecordsHelpFaction ():
- Window = RecordsWindow
Help = GemRB.GetString (20106) + "\n\n" + faction_help
- TextArea = Window.GetControl (0)
- TextArea.SetText (Help)
+ OnRecordsHelpStat (-1, 0, Help)
return
def OnRecordsHelpArmorClass ():
- Window = RecordsWindow
- Help = GemRB.GetString (18493)
- TextArea = Window.GetControl (0)
- TextArea.SetText (Help)
+ OnRecordsHelpStat (-1, 0, 18493)
return
def OnRecordsHelpHitPoints ():
- Window = RecordsWindow
- Help = GemRB.GetString (18494)
- TextArea = Window.GetControl (0)
- TextArea.SetText (Help)
+ OnRecordsHelpStat (-1, 0, 18494)
return
def OnRecordsHelpAlignment ():
- Window = RecordsWindow
Help = GemRB.GetString (20105) + "\n\n" + alignment_help
- TextArea = Window.GetControl (0)
- TextArea.SetText (Help)
+ OnRecordsHelpStat (-1, 0, Help)
return
#Bio:
@@ -347,10 +334,14 @@ def OnRecordsHelpAlignment ():
# 39428 nordom
# 39429 vhailor
-def OnRecordsHelpStrength ():
- Window = RecordsWindow
- TextArea = Window.GetControl (0)
+def OnRecordsHelpStat (row, col, strref, bon1=0, bon2=0):
+ TextArea = RecordsWindow.GetControl (0)
+ TextArea.SetText (strref)
+ if row != -1:
+ TextArea.Append ("\n\n" + GemRB.StatComment (StatTable.GetValue(str(row),col), bon1, bon2) )
+ return
+def OnRecordsHelpStrength ():
# These are used to get the stats
pc = GemRB.GameGetSelectedPCSingle ()
@@ -365,15 +356,11 @@ def OnRecordsHelpStrength ():
y=0
if e>60:
s=19
- TextArea.SetText(18489)
- TextArea.Append("\n\n"+GemRB.StatComment(StatTable.GetValue(s,0),x,y) )
+ OnRecordsHelpStat (s, "STR", 18489, x, y)
return
def OnRecordsHelpDexterity ():
- Window = RecordsWindow
- TextArea = Window.GetControl (0)
-
# Loading table of modifications
Table = GemRB.LoadTable("dexmod")
@@ -386,42 +373,28 @@ def OnRecordsHelpDexterity ():
# Getting the dexterity description
x = -Table.GetValue(Dex,2)
- TextArea.SetText(18487)
- TextArea.Append("\n\n"+GemRB.StatComment(StatTable.GetValue(Dex,3),x,0) )
+ OnRecordsHelpStat (Dex, "DEX", 18487, x)
return
def OnRecordsHelpIntelligence ():
- Window = RecordsWindow
- TextArea = Window.GetControl (0)
-
# These are used to get the stats
pc = GemRB.GameGetSelectedPCSingle ()
# Getting the character's intelligence
Int = GemRB.GetPlayerStat (pc, IE_INT)
-
- TextArea.SetText(18488)
- TextArea.Append("\n\n"+GemRB.StatComment(StatTable.GetValue(Int,1),0,0) )
+ OnRecordsHelpStat (Int, "INT", 18488)
return
def OnRecordsHelpWisdom ():
- Window = RecordsWindow
- TextArea = Window.GetControl (0)
-
# These are used to get the stats
pc = GemRB.GameGetSelectedPCSingle ()
# Getting the character's wisdom
Wis = GemRB.GetPlayerStat (pc, IE_WIS)
-
- TextArea.SetText(18490)
- TextArea.Append("\n\n"+GemRB.StatComment(StatTable.GetValue(Wis,2),0,0) )
+ OnRecordsHelpStat (Wis, "WIS", 18490)
return
def OnRecordsHelpConstitution ():
- Window = RecordsWindow
- TextArea = Window.GetControl (0)
-
# Loading table of modifications
Table = GemRB.LoadTable("hpconbon")
@@ -434,22 +407,16 @@ def OnRecordsHelpConstitution ():
# Getting the constitution description
x = Table.GetValue(Con-1,1)
- TextArea.SetText(18491)
- TextArea.Append("\n\n"+GemRB.StatComment(StatTable.GetValue(Con,4),x,0) )
+ OnRecordsHelpStat (Con, "CON", 18491, x)
return
def OnRecordsHelpCharisma ():
- Window = RecordsWindow
- TextArea = Window.GetControl (0)
-
# These are used to get the stats
pc = GemRB.GameGetSelectedPCSingle ()
# Getting the character's charisma
Cha = GemRB.GetPlayerStat (pc, IE_CHR)
-
- TextArea.SetText(1903)
- TextArea.Append("\n\n"+GemRB.StatComment(StatTable.GetValue(Cha,5),0,0) )
+ OnRecordsHelpStat (Cha, "CHR", 1903)
return
def GetCharacterHeader (pc):
@@ -458,7 +425,7 @@ def GetCharacterHeader (pc):
BioTable = GemRB.LoadTable ("bios")
Class = GemRB.GetPlayerStat (pc, IE_CLASS) - 1
- Multi = CommonTables.Classes.GetValue (Class, 4)
+ Multi = GUICommon.HasMultiClassBits (pc)
Specific = "%d"%GemRB.GetPlayerStat (pc, IE_SPECIFIC)
#Nameless is Specific == 1
@@ -611,9 +578,10 @@ def GetStatOverview (pc):
# 4208 THAC0
stats.append ((4208, GS (IE_TOHIT), ''))
# 4209 Number of Attacks
- tmp = GS (IE_NUMBEROFATTACKS)
+ tmp = GemRB.GetCombatDetails(pc, 0)["APR"]
+
if (tmp&1):
- tmp2 = str(tmp/2) + chr(188)
+ tmp2 = str(tmp/2) + chr(189)
else:
tmp2 = str(tmp/2)
@@ -746,30 +714,35 @@ def OpenInformationWindow ():
InformationWindow = Window = GemRB.LoadWindow (5)
GemRB.SetVar ("FloatWindow", InformationWindow.ID)
+ # Biography
+ Button = Window.GetControl (1)
+ Button.SetText (4247)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenBiographyWindow)
+
+ # Done
+ Button = Window.GetControl (0)
+ Button.SetText (1403)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenInformationWindow)
+ Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
TotalPartyExp = 0
TotalPartyKills = 0
for i in range (1, GemRB.GetPartySize() + 1):
stat = GemRB.GetPCStats(i)
- TotalPartyExp = TotalPartyExp + stat['KillsChapterXP']
- TotalPartyKills = TotalPartyKills + stat['KillsChapterCount']
+ TotalPartyExp = TotalPartyExp + stat['KillsTotalXP']
+ TotalPartyKills = TotalPartyKills + stat['KillsTotalCount']
# These are used to get the stats
pc = GemRB.GameGetSelectedPCSingle ()
-
stat = GemRB.GetPCStats (pc)
Label = Window.GetControl (0x10000001)
Label.SetText (GemRB.GetPlayerName (pc, 1))
-
# class
- text = CommonTables.Classes.GetValue (GemRB.GetPlayerStat (pc, IE_CLASS) - 1, 0)
-
+ ClassTitle = GUICommon.GetActorClassTitle (pc)
Label = Window.GetControl (0x1000000A)
- Label.SetText (text)
-
-
+ Label.SetText (ClassTitle)
Label = Window.GetControl (0x10000002)
if stat['BestKilledName'] == -1:
@@ -777,22 +750,8 @@ def OpenInformationWindow ():
else:
Label.SetText (GemRB.GetString (stat['BestKilledName']))
- # NOTE: currentTime is in seconds, joinTime is in seconds * 15
- # (script updates???). In each case, there are 60 seconds
- # in a minute, 24 hours in a day, but ONLY 5 minutes in an hour!!
- # Hence currentTime (and joinTime after div by 15) has
- # 7200 secs a day (60 * 5 * 24)
- currentTime = GemRB.GetGameTime()
- joinTime = stat['JoinDate'] - stat['AwayTime']
-
- party_time = currentTime - (joinTime / 15)
- days = party_time / 7200
- hours = (party_time % 7200) / 300
-
- GemRB.SetToken ('GAMEDAYS', str (days))
- GemRB.SetToken ('HOUR', str (hours))
-
Label = Window.GetControl (0x10000003)
+ GUICommon.SetCurrentDateTokens (stat)
Label.SetText (41277)
Label = Window.GetControl (0x10000004)
@@ -803,17 +762,17 @@ def OpenInformationWindow ():
Label = Window.GetControl (0x10000006)
if TotalPartyExp != 0:
- PartyExp = int ((stat['KillsChapterXP'] * 100) / TotalPartyExp)
+ PartyExp = int ((stat['KillsTotalXP'] * 100) / TotalPartyExp)
Label.SetText (str (PartyExp) + '%')
else:
Label.SetText ("0%")
Label = Window.GetControl (0x10000007)
if TotalPartyKills != 0:
- PartyKills = int ((stat['KillsChapterCount'] * 100) / TotalPartyKills)
+ PartyKills = int ((stat['KillsTotalCount'] * 100) / TotalPartyKills)
Label.SetText (str (PartyKills) + '%')
else:
- Label.SetText ('0%')
+ Label.SetText ("0%")
Label = Window.GetControl (0x10000008)
Label.SetText (str (stat['KillsTotalXP']))
@@ -846,24 +805,10 @@ def OpenInformationWindow ():
Label = Window.GetControl (0x10000012)
Label.SetTextColor (255, 255, 255)
-
-
- # Biography
- Button = Window.GetControl (1)
- Button.SetText (4247)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenBiographyWindow)
-
- # Done
- Button = Window.GetControl (0)
- Button.SetText (1403)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenInformationWindow)
- Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR)
-
GemRB.UnhideGUI ()
Window.ShowModal (MODAL_SHADOW_GRAY)
-
def OpenBiographyWindow ():
global BiographyWindow
@@ -1000,8 +945,7 @@ def OpenLevelUpWindow ():
# Recording this avatar's current proficiency level
# Since Nameless one is not covered, hammer and club can't occur
# What is the avatar's class (Which we can use to lookup XP)
- ClassRow = GemRB.GetPlayerStat (pc, IE_CLASS)-1
- Class = CommonTables.Classes.GetRowName (ClassRow)
+ Class = GUICommon.GetClassRowName (pc)
# name
Label = Window.GetControl (0x10000000)
@@ -1009,7 +953,7 @@ def OpenLevelUpWindow ():
# class
Label = Window.GetControl (0x10000001)
- Label.SetText (CommonTables.Classes.GetValue (ClassRow, 0))
+ Label.SetText (CommonTables.Classes.GetValue (Class, "NAME_REF"))
# Armor Class
Label = Window.GetControl (0x10000023)
@@ -1130,7 +1074,7 @@ def OpenLevelUpWindow ():
# Thac0
Thac0 = GetThac0 (Class, NextLevel)
# Is the new thac0 better than old? (The smaller, the better)
- if Thac0 < GemRB.GetPlayerStat (pc, IE_TOHIT):
+ if Thac0 < GemRB.GetPlayerStat (pc, IE_TOHIT, 1):
Thac0Updated = True
else:
@@ -1195,7 +1139,7 @@ def OpenLevelUpWindow ():
# Multi class use the primary class level to determine Thac0
Thac0 = GetThac0 (Class, PrimNextLevel)
# Is the new thac0 better than old? (The smaller the better)
- if Thac0 < GemRB.GetPlayerStat (pc, IE_TOHIT):
+ if Thac0 < GemRB.GetPlayerStat (pc, IE_TOHIT, 1):
Thac0Updated = True
diff --git a/gemrb/GUIScripts/pst/GUISAVE.py b/gemrb/GUIScripts/pst/GUISAVE.py
index 07c6fd8..09f9367 100644
--- a/gemrb/GUIScripts/pst/GUISAVE.py
+++ b/gemrb/GUIScripts/pst/GUISAVE.py
@@ -156,10 +156,10 @@ def DeleteGameConfirm():
TopIndex = GemRB.GetVar("TopIndex")
Pos = TopIndex +GemRB.GetVar("SaveIdx")
GemRB.DeleteSaveGame (Games[Pos])
+ del Games[Pos]
if TopIndex>0:
GemRB.SetVar("TopIndex",TopIndex-1)
- Games = GemRB.GetSaveGames()
- #del Games[pos]
+ #Games = GemRB.GetSaveGames()
ScrollBar.SetVarAssoc("TopIndex", len(Games))
ScrollBarPress()
if ConfirmWindow:
@@ -168,8 +168,11 @@ def DeleteGameConfirm():
return
def DeleteGameCancel():
+ global ConfirmWindow
+
if ConfirmWindow:
ConfirmWindow.Unload()
+ ConfirmWindow = None
SaveWindow.SetVisible (WINDOW_VISIBLE)
return
@@ -299,12 +302,14 @@ def ConfirmedSaveGame ():
# We have to close floating window first
OpenSaveDetailWindow ()
LoadScreen.StartLoadScreen (LoadScreen.LS_TYPE_SAVING)
+ CloseSaveWindow ()
if Pos < len(Games):
GemRB.SaveGame (Games[Pos], Slotname)
else:
GemRB.SaveGame (None, Slotname)
- CloseSaveWindow ()
+def QuickSavePressed():
+ GemRB.SaveGame(1)
# Exit either back to game or to the Start window
def CloseSaveWindow ():
diff --git a/gemrb/GUIScripts/pst/GUIWORLD.py b/gemrb/GUIScripts/pst/GUIWORLD.py
index 081b852..8c78f05 100644
--- a/gemrb/GUIScripts/pst/GUIWORLD.py
+++ b/gemrb/GUIScripts/pst/GUIWORLD.py
@@ -24,7 +24,6 @@
###################################################
import GemRB
-import GUIClasses
import GUICommon
import GUICommonWindows
import CommonWindow
diff --git a/gemrb/GUIScripts/pst/MessageWindow.py b/gemrb/GUIScripts/pst/MessageWindow.py
index 5806656..a66b192 100644
--- a/gemrb/GUIScripts/pst/MessageWindow.py
+++ b/gemrb/GUIScripts/pst/MessageWindow.py
@@ -77,12 +77,12 @@ def OnLoad():
# Select all
Button = ActionsWindow.GetControl (3)
- Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUICommonWindows.StopAllOnPress)
+ Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUICommonWindows.ActionStopPressed)
FormationButton = ActionsWindow.GetControl (4)
FormationButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIWORLD.OpenFormationWindow)
- GUICommonWindows.SetupActionsWindowControls (ActionsWindow)
+ GUICommonWindows.SetupClockWindowControls (ActionsWindow)
GUICommonWindows.SetupMenuWindowControls (OptionsWindow)
UpdateControlStatus ()
@@ -100,6 +100,9 @@ def UpdateControlStatus ():
GemRB.SetVar ("OptionsWindow", -1)
MessageTA = GUIClasses.GTextArea(MessageWindow.ID, GemRB.GetVar ("MessageTextArea"))
MessageTA.SetStatus (IE_GUI_CONTROL_FOCUSED)
+
+ Label = MessageWindow.GetControl (0x10000003)
+ Label.SetText (str (GemRB.GameGetPartyGold ()))
else:
GemRB.SetVar ("MessageWindow", -1)
GemRB.SetVar ("PortraitWindow", PortraitWindow.ID)
diff --git a/gemrb/GUIScripts/pst/NewLife.py b/gemrb/GUIScripts/pst/NewLife.py
index 4b1677a..d879ca6 100644
--- a/gemrb/GUIScripts/pst/NewLife.py
+++ b/gemrb/GUIScripts/pst/NewLife.py
@@ -208,8 +208,9 @@ def OnLoad():
Label.SetText(254)
PhotoButton = NewLifeWindow.GetControl(35)
- PhotoButton.SetState(IE_GUI_BUTTON_DISABLED)
+ PhotoButton.SetState(IE_GUI_BUTTON_LOCKED)
PhotoButton.SetFlags(IE_GUI_BUTTON_NO_IMAGE | IE_GUI_BUTTON_PICTURE, OP_SET)
+ PhotoButton.SetEvent(IE_GUI_MOUSE_OVER_BUTTON, OverPhoto)
PhotoButton.SetPicture("STPNOC")
AcceptButton = NewLifeWindow.GetControl(0)
@@ -504,3 +505,6 @@ def IncreasePress():
UpdateLabels()
return
+def OverPhoto():
+ global TextArea
+ TextArea.SetText(18495)
diff --git a/gemrb/GUIScripts/pst/QuitGame.py b/gemrb/GUIScripts/pst/QuitGame.py
index 29361f2..5de18f8 100644
--- a/gemrb/GUIScripts/pst/QuitGame.py
+++ b/gemrb/GUIScripts/pst/QuitGame.py
@@ -47,7 +47,7 @@ def DonePress ():
GemRB.SetNextScript("Start")
def DeathWindowEnd ():
- GemRB.GamePause (1,1)
+ GemRB.GamePause (1,3)
GemRB.LoadWindowPack (GUICommon.GetWindowPack())
Window = GemRB.LoadWindow (25)
diff --git a/gemrb/GemRB.cfg.noinstall.sample b/gemrb/GemRB.cfg.noinstall.sample
index fb76d55..014fb5b 100644
--- a/gemrb/GemRB.cfg.noinstall.sample
+++ b/gemrb/GemRB.cfg.noinstall.sample
@@ -48,6 +48,13 @@ GameType=test
GameName=Baldur's Gate 2
#####################################################
+# Encoding [default|polish|czech] Language used by #
+# game data. Except of polish BG1, leave disabled. #
+#####################################################
+
+# Encoding=default
+
+#####################################################
# Video Parameters #
#####################################################
@@ -104,8 +111,6 @@ TooltipDelay=500
#CaseSensitive=1
-#GameOnCD=0
-
#####################################################
# GUI Parameters #
#####################################################
@@ -120,8 +125,8 @@ TooltipDelay=500
# coordinates and may stop being clickable). #
#####################################################
-# Enable all gui enhancements ? [Boolean]
-GUIEnhancements = 1
+# Enable all gui enhancements ? [Integer]
+GUIEnhancements = 15
#####################################################
@@ -168,7 +173,7 @@ CD5=/mnt/windows/Programmi/Black Isle/BGII - SoA/CD5/
# Cache directory. #
#####################################################
-CachePath=./gemrb/Cache/
+CachePath=./gemrb/Cache2/
#####################################################
# GemRB Save Path [String] #
@@ -219,6 +224,16 @@ GemRBPath=../gemrb
PluginsPath=./gemrb/plugins/
#####################################################
+# Custom Font Path [String] #
+# #
+# This is the path where GemRB looks for non-BAM #
+# fonts (ex TTF) #
+# #
+#####################################################
+
+#CustomFontPath=
+
+#####################################################
# Game Data Path [String] #
# #
# This is the subdirectory under GamePath where #
@@ -250,6 +265,47 @@ PluginsPath=./gemrb/plugins/
#####################################################
#GemRBOverridePath=/usr/share/games/gemrb
+#GemRBUnhardcodedPath=/usr/share/games/gemrb
+
+#####################################################
+# Input Parameters #
+#####################################################
+
+#whether or not to use software keyboard on devices that support one
+#UseSoftKeyboard=1
+
+#Adds a gutter around the screen for scrolling
+#TouchScrollAreas=1
+
+#####################################################
+# MouseFeedback #
+# Bitfield with reserved bits for disabling #
+# the mouse. Those bits cannot be set via config #
+# #
+# Show mouse+tooltips = 0 #
+# Hide mouse = 1 #
+# Hide tooltips = 2 #
+# Hide mouse+tooltips = 3 #
+#####################################################
+
+# For a strictly touchscreen device we recommend
+# Changing this to 3.
+
+# default is 0
+#MouseFeedback=0
+
+#####################################################
+# Touch Gesture Input Parameters #
+# Requires SDL 1.3 or later #
+# All "NumFing" settings must be > 1 and < 5 #
+# NumFingScroll and NumFingKboard cannot be equal #
+#####################################################
+
+#NumFingScroll=2
+
+#NumFingKboard=3
+
+#NumFingInfo=2
#####################################################
# END #
diff --git a/gemrb/GemRB.cfg.sample.in b/gemrb/GemRB.cfg.sample.in
index 7ebccd1..421aa95 100644
--- a/gemrb/GemRB.cfg.sample.in
+++ b/gemrb/GemRB.cfg.sample.in
@@ -48,8 +48,22 @@ GameType=bg2
GameName=Baldur's Gate 2
#####################################################
+# Encoding [default|polish|czech] Language used by #
+# game data. Except of polish BG1, leave disabled. #
+#####################################################
+
+# Encoding=default
+
+#####################################################
# Video Parameters #
#####################################################
+#NOTE: SCREEN width and height can NOT be ARBITRARY without installing the
+# widescreen mod: http://www.gibberlings3.net/widescreen/
+#Resolutions supported by the original games (gemrb) are:
+# * 640x480 (except in iwd2)
+# * 800x600 (bg2, iwd:how, iwd2)
+# * 1024x768 (bg2, iwd:how, iwd2)
+# * 1280x1024 (bg2, iwd:how, iwd2)
#Screen width
Width=640
@@ -104,8 +118,6 @@ TooltipDelay=500
#CaseSensitive=1
-#GameOnCD=0
-
#####################################################
# GUI Parameters #
#####################################################
@@ -120,8 +132,8 @@ TooltipDelay=500
# coordinates and may stop being clickable). #
#####################################################
-# Enable all gui enhancements ? [Boolean]
-GUIEnhancements = 1
+# Enable all gui enhancements ? [Integer]
+GUIEnhancements = 15
#####################################################
@@ -150,7 +162,7 @@ GUIEnhancements = 1
# #
# These are the paths where the Game you want to #
# play is installed. #
-# Enter the full path to the directory. #
+# Enter the full path to the directory. #
#####################################################
GamePath=/mnt/windows/Programmi/Black Isle/BGII - SoA/
@@ -168,7 +180,7 @@ CD5=/mnt/windows/Programmi/Black Isle/BGII - SoA/CD5/
# Cache directory. #
#####################################################
-CachePath=./Cache/
+CachePath=./Cache2/
#####################################################
# GemRB Save Path [String] #
@@ -185,9 +197,7 @@ CachePath=./Cache/
#SavePath=/mnt/windows/Programmi/Black Isle/BGII - SoA/
###### HERE BE DRAGONS #############################
-###### HERE BE DRAGONS #############################
-###### HERE BE DRAGONS #############################
-# You shouldn't need to change anything below this point.
+# You shouldn't need to change any paths below this point.
#####################################################
# GemRB Path [String] #
@@ -224,6 +234,16 @@ CachePath=./Cache/
#PluginsPath=@PLUGIN_DIR@
#####################################################
+# Custom Font Path [String] #
+# #
+# This is the path where GemRB looks for non-BAM #
+# fonts (ex TTF) #
+# #
+#####################################################
+
+#CustomFontPath=
+
+#####################################################
# Game Data Path [String] #
# #
# This is the subdirectory under GamePath where #
@@ -255,6 +275,47 @@ CachePath=./Cache/
#####################################################
#GemRBOverridePath=@DATA_DIR@
+#GemRBUnhardcodedPath=@DATA_DIR@
+
+#####################################################
+# Input Parameters #
+#####################################################
+
+#whether or not to use software keyboard on devices that support one
+#UseSoftKeyboard=1
+
+#Adds a gutter around the screen for scrolling
+#TouchScrollAreas=1
+
+#####################################################
+# MouseFeedback #
+# Bitfield with reserved bits for disabling #
+# the mouse. Those bits cannot be set via config #
+# #
+# Show mouse+tooltips = 0 #
+# Hide mouse = 1 #
+# Hide tooltips = 2 #
+# Hide mouse+tooltips = 3 #
+#####################################################
+
+# For a strictly touchscreen device we recommend
+# Changing this to 3.
+
+# default is 0
+#MouseFeedback=0
+
+#####################################################
+# Touch Gesture Input Parameters #
+# Requires SDL 1.3 or later #
+# All "NumFing" settings must be > 1 and < 5 #
+# NumFingScroll and NumFingKboard cannot be equal #
+#####################################################
+
+#NumFingScroll=2
+
+#NumFingKboard=3
+
+#NumFingInfo=2
#####################################################
# END #
diff --git a/gemrb/GemRB.cpp b/gemrb/GemRB.cpp
index 9f8b08b..7ac00f9 100644
--- a/gemrb/GemRB.cpp
+++ b/gemrb/GemRB.cpp
@@ -22,20 +22,24 @@
#include "win32def.h" // logging
-#include <cstdio>
-
#include "Interface.h"
-
-//this supposed to convince SDL to work on OS/X
-//WARNING: commenting this out will cause SDL 1.2.x to crash
-#ifdef __APPLE_CC__ // we need startup SDL here
-#include <SDL.h>
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
#endif
+using namespace GemRB;
+
#ifdef ANDROID
-#include <SDL/SDL.h>
-#include "audio.h"
+#include <SDL.h>
+// if/when android moves to SDL 1.3 remove these special functions.
+// SDL 1.3 fires window events for these conditions that are handled in SDLVideo.cpp.
+// see SDL_WINDOWEVENT_MINIMIZED and SDL_WINDOWEVENT_RESTORED
+#if SDL_COMPILEDVERSION < SDL_VERSIONNUM(1,3,0)
+#include "Audio.h"
// pause audio playing if app goes in background
static void appPutToBackground()
@@ -47,25 +51,54 @@ static void appPutToForeground()
{
core->GetAudioDrv()->Resume();
}
-
+#endif
#endif
int main(int argc, char* argv[])
{
+#ifdef HAVE_SETENV
+ setenv("SDL_VIDEO_X11_WMCLASS", argv[0], 0);
+# ifdef ANDROID
+ setenv("GEM_DATA", SDL_AndroidGetExternalStoragePath(), 1);
+# endif
+#endif
+
+#ifdef M_TRIM_THRESHOLD
+// Prevent fragmentation of the heap by malloc (glibc).
+//
+// The default threshold is 128*1024, which can result in a large memory usage
+// due to fragmentation since we use a lot of small objects. On the other hand
+// if the threshold is too low, free() starts to permanently ask the kernel
+// about shrinking the heap.
+ #ifdef HAVE_UNISTD_H
+ int pagesize = sysconf(_SC_PAGESIZE);
+ #else
+ int pagesize = 4*1024;
+ #endif
+ mallopt(M_TRIM_THRESHOLD, 5*pagesize);
+#endif
+
Interface::SanityCheck(VERSION_GEMRB);
- core = new Interface( argc, argv );
- if (core->Init() == GEM_ERROR) {
+ InitializeLogging();
+
+ core = new Interface();
+ CFGConfig* config = new CFGConfig(argc, argv);
+ if (core->Init( config ) == GEM_ERROR) {
+ delete config;
delete( core );
- printf("Press enter to continue...");
- textcolor(DEFAULT);
+ Log(MESSAGE, "Main", "Press enter to continue...");
getc(stdin);
+ ShutdownLogging();
return -1;
}
+ delete config;
#ifdef ANDROID
+#if SDL_COMPILEDVERSION < SDL_VERSIONNUM(1,3,0)
SDL_ANDROID_SetApplicationPutToBackgroundCallback(&appPutToBackground, &appPutToForeground);
#endif
+#endif
core->Main();
delete( core );
- textcolor(DEFAULT);
+ ShutdownLogging();
return 0;
}
diff --git a/gemrb/Makefile.am b/gemrb/Makefile.am
index 4feac3d..54ed58e 100644
--- a/gemrb/Makefile.am
+++ b/gemrb/Makefile.am
@@ -4,7 +4,7 @@ gemrb_SOURCES = GemRB.cpp
gemrb_LDADD = ./core/libgemrb_core.la
-SUBDIRS = core plugins includes GUIScripts override docs
+SUBDIRS = core plugins includes GUIScripts override docs unhardcoded
EXTRA_DIST = GemRB.cfg* plugins-prepare.sh CMakeLists.txt
gemrb_LDFLAGS = $(all_libraries) @LIBPTHREAD@
diff --git a/gemrb/core/ActorMgr.cpp b/gemrb/core/ActorMgr.cpp
index ebcee71..d1a1676 100644
--- a/gemrb/core/ActorMgr.cpp
+++ b/gemrb/core/ActorMgr.cpp
@@ -20,6 +20,8 @@
#include "ActorMgr.h"
+namespace GemRB {
+
ActorMgr::ActorMgr(void)
{
}
@@ -27,3 +29,5 @@ ActorMgr::ActorMgr(void)
ActorMgr::~ActorMgr(void)
{
}
+
+}
diff --git a/gemrb/core/ActorMgr.h b/gemrb/core/ActorMgr.h
index 7afcfba..dcd8384 100644
--- a/gemrb/core/ActorMgr.h
+++ b/gemrb/core/ActorMgr.h
@@ -22,15 +22,19 @@
#define ACTORMGR_H
#include "Plugin.h"
-#include "Scriptable/Actor.h"
-#include "System/DataStream.h"
+
+namespace GemRB {
+
+class Actor;
+class DataStream;
class GEM_EXPORT ActorMgr : public Plugin {
public:
ActorMgr(void);
virtual ~ActorMgr(void);
- virtual bool Open(DataStream* stream, bool autoFree = true) = 0;
+ virtual bool Open(DataStream* stream) = 0;
virtual Actor* GetActor(unsigned char is_in_party) = 0;
+ virtual int FindSpellType(char *name, unsigned short &level, unsigned int clsmsk, unsigned int kit) const = 0;
//returns saved size, updates internal offsets before save
virtual int GetStoredFileSize(Actor *ac) = 0;
@@ -38,4 +42,6 @@ public:
virtual int PutActor(DataStream *stream, Actor *actor, bool chr=false) = 0;
};
+}
+
#endif
diff --git a/gemrb/core/Ambient.cpp b/gemrb/core/Ambient.cpp
index db543f4..6df5119 100644
--- a/gemrb/core/Ambient.cpp
+++ b/gemrb/core/Ambient.cpp
@@ -20,6 +20,8 @@
#include "Ambient.h"
+namespace GemRB {
+
Ambient::Ambient()
{
}
@@ -34,3 +36,5 @@ Ambient::~Ambient()
void Ambient::setActive() { flags |= IE_AMBI_ENABLED; }
void Ambient::setInactive() { flags &= ~IE_AMBI_ENABLED; }
+
+}
diff --git a/gemrb/core/Ambient.h b/gemrb/core/Ambient.h
index ec4f9be..f5dfd47 100644
--- a/gemrb/core/Ambient.h
+++ b/gemrb/core/Ambient.h
@@ -29,6 +29,8 @@
#include <string>
#include <vector>
+namespace GemRB {
+
#define IE_AMBI_ENABLED 1
#define IE_AMBI_POINT 2
#define IE_AMBI_MAIN 4
@@ -74,4 +76,6 @@ public:
};
+}
+
#endif
diff --git a/gemrb/core/AmbientMgr.cpp b/gemrb/core/AmbientMgr.cpp
index a998eb8..8db488d 100644
--- a/gemrb/core/AmbientMgr.cpp
+++ b/gemrb/core/AmbientMgr.cpp
@@ -22,6 +22,8 @@
#include "Ambient.h"
+namespace GemRB {
+
AmbientMgr::AmbientMgr()
{
}
@@ -60,3 +62,5 @@ bool AmbientMgr::isActive(const std::string &name) const
}
return false;
}
+
+}
diff --git a/gemrb/core/AmbientMgr.h b/gemrb/core/AmbientMgr.h
index 0b6daf1..c90bdfc 100644
--- a/gemrb/core/AmbientMgr.h
+++ b/gemrb/core/AmbientMgr.h
@@ -27,6 +27,8 @@
#include <string>
#include <vector>
+namespace GemRB {
+
class Ambient;
class GEM_EXPORT AmbientMgr {
@@ -45,4 +47,6 @@ protected:
bool active;
};
+}
+
#endif
diff --git a/gemrb/core/AnimStructures.h b/gemrb/core/AnimStructures.h
index 9692cf9..0257d1d 100644
--- a/gemrb/core/AnimStructures.h
+++ b/gemrb/core/AnimStructures.h
@@ -21,9 +21,13 @@
#ifndef ANIMSTRUCTURES_H
#define ANIMSTRUCTURES_H
+namespace GemRB {
+
struct CycleEntry {
ieWord FramesCount;
ieWord FirstFrame;
};
+}
+
#endif
diff --git a/gemrb/core/Animation.cpp b/gemrb/core/Animation.cpp
index 6ec1caa..5732733 100644
--- a/gemrb/core/Animation.cpp
+++ b/gemrb/core/Animation.cpp
@@ -25,8 +25,11 @@
#include "Game.h"
#include "Interface.h"
#include "Map.h"
+#include "Sprite2D.h"
#include "Video.h"
+namespace GemRB {
+
Animation::Animation(int count)
{
frames = (Sprite2D **) calloc(count, sizeof(Sprite2D *));
@@ -71,8 +74,7 @@ void Animation::SetPos(unsigned int index)
void Animation::AddFrame(Sprite2D* frame, unsigned int index)
{
if (index>=indicesCount) {
- printf("You tried to write past a buffer in animation, BAD!\n");
- abort();
+ error("Animation", "You tried to write past a buffer in animation, BAD!\n");
}
core->GetVideoDriver()->FreeSprite(frames[index]);
frames[index]=frame;
@@ -106,14 +108,14 @@ unsigned int Animation::GetCurrentFrame() const
Sprite2D* Animation::LastFrame(void)
{
- if (!Flags&A_ANI_ACTIVE) {
- printf("Frame fetched while animation is inactive!\n");
+ if (!(Flags&A_ANI_ACTIVE)) {
+ Log(MESSAGE, "Sprite2D", "Frame fetched while animation is inactive1!");
return NULL;
}
if (gameAnimation) {
starttime = core->GetGame()->Ticks;
} else {
- GetTime( starttime );
+ starttime = GetTickCount();
}
Sprite2D* ret;
if (playReversed)
@@ -125,15 +127,15 @@ Sprite2D* Animation::LastFrame(void)
Sprite2D* Animation::NextFrame(void)
{
- if (!Flags&A_ANI_ACTIVE) {
- printf("Frame fetched while animation is inactive!\n");
+ if (!(Flags&A_ANI_ACTIVE)) {
+ Log(MESSAGE, "Sprite2D", "Frame fetched while animation is inactive2!");
return NULL;
}
if (starttime == 0) {
if (gameAnimation) {
starttime = core->GetGame()->Ticks;
} else {
- GetTime( starttime );
+ starttime = GetTickCount();
}
}
Sprite2D* ret;
@@ -142,14 +144,14 @@ Sprite2D* Animation::NextFrame(void)
else
ret = frames[pos];
- if (endReached && (Flags&A_ANI_PLAYONCE) )
+ if (endReached && (Flags&A_ANI_PLAYONCE))
return ret;
unsigned long time;
if (gameAnimation) {
time = core->GetGame()->Ticks;
} else {
- GetTime(time);
+ time = GetTickCount();
}
//it could be that we skip more than one frame in case of slow rendering
@@ -179,8 +181,8 @@ Sprite2D* Animation::NextFrame(void)
Sprite2D* Animation::GetSyncedNextFrame(Animation* master)
{
- if (!Flags&A_ANI_ACTIVE) {
- printf("Frame fetched while animation is inactive!\n");
+ if (!(Flags&A_ANI_ACTIVE)) {
+ Log(MESSAGE, "Sprite2D", "Frame fetched while animation is inactive!");
return NULL;
}
Sprite2D* ret;
@@ -190,9 +192,11 @@ Sprite2D* Animation::GetSyncedNextFrame(Animation* master)
ret = frames[pos];
starttime = master->starttime;
- pos = master->pos;
endReached = master->endReached;
+ //return a valid frame even if the master is longer (e.g. ankhegs)
+ pos = master->pos % indicesCount;
+
return ret;
}
@@ -259,3 +263,5 @@ void Animation::AddAnimArea(Animation* slave)
animArea.h = y+h-animArea.y;
}
}
+
+}
diff --git a/gemrb/core/Animation.h b/gemrb/core/Animation.h
index fcf9a7d..5ba11ee 100644
--- a/gemrb/core/Animation.h
+++ b/gemrb/core/Animation.h
@@ -26,10 +26,13 @@
#include "globals.h"
#include "Region.h"
-#include "Sprite2D.h"
#include <vector>
+namespace GemRB {
+
+class Sprite2D;
+
class GEM_EXPORT Animation {
private:
Sprite2D **frames;
@@ -69,4 +72,6 @@ public:
void AddAnimArea(Animation* slave);
};
+}
+
#endif
diff --git a/gemrb/core/AnimationFactory.cpp b/gemrb/core/AnimationFactory.cpp
index e663739..401169f 100644
--- a/gemrb/core/AnimationFactory.cpp
+++ b/gemrb/core/AnimationFactory.cpp
@@ -23,8 +23,11 @@
#include "win32def.h"
#include "Interface.h"
+#include "Sprite2D.h"
#include "Video.h"
+namespace GemRB {
+
AnimationFactory::AnimationFactory(const char* ResRef)
: FactoryObject( ResRef, IE_BAM_CLASS_ID )
{
@@ -43,7 +46,7 @@ AnimationFactory::~AnimationFactory(void)
// FIXME: track down where sprites are being leaked
if (datarefcount) {
- fprintf(stderr, "AnimationFactory %s has refcount %d\n", ResRef, datarefcount);
+ Log(ERROR, "AnimationFactory", "AnimationFactory %s has refcount %d", ResRef, datarefcount);
//assert(datarefcount == 0);
}
if (FrameData)
@@ -166,3 +169,5 @@ void AnimationFactory::DecDataRefCount()
assert(datarefcount > 0);
--datarefcount;
}
+
+}
diff --git a/gemrb/core/AnimationFactory.h b/gemrb/core/AnimationFactory.h
index b385362..73f9da1 100644
--- a/gemrb/core/AnimationFactory.h
+++ b/gemrb/core/AnimationFactory.h
@@ -25,8 +25,11 @@
#include "globals.h"
#include "Animation.h"
+#include "AnimStructures.h"
#include "FactoryObject.h"
+namespace GemRB {
+
class GEM_EXPORT AnimationFactory : public FactoryObject {
private:
std::vector< Sprite2D*> frames;
@@ -55,4 +58,6 @@ public:
void DecDataRefCount();
};
+}
+
#endif
diff --git a/gemrb/core/AnimationMgr.cpp b/gemrb/core/AnimationMgr.cpp
index 7ddece9..98e23a4 100644
--- a/gemrb/core/AnimationMgr.cpp
+++ b/gemrb/core/AnimationMgr.cpp
@@ -20,6 +20,8 @@
#include "AnimationMgr.h"
+namespace GemRB {
+
AnimationMgr::AnimationMgr(void)
{
}
@@ -27,3 +29,5 @@ AnimationMgr::AnimationMgr(void)
AnimationMgr::~AnimationMgr(void)
{
}
+
+}
diff --git a/gemrb/core/AnimationMgr.h b/gemrb/core/AnimationMgr.h
index d161aff..ee58eba 100644
--- a/gemrb/core/AnimationMgr.h
+++ b/gemrb/core/AnimationMgr.h
@@ -25,23 +25,26 @@
#include "Animation.h"
#include "AnimationFactory.h"
-#include "Font.h"
#include "Plugin.h"
+namespace GemRB {
+
+class Font;
+
class GEM_EXPORT AnimationMgr : public Plugin {
public:
AnimationMgr(void);
virtual ~AnimationMgr(void);
- virtual bool Open(DataStream* stream, bool autoFree = true) = 0;
+ virtual bool Open(DataStream* stream) = 0;
virtual int GetCycleSize(unsigned char Cycle) = 0;
virtual AnimationFactory* GetAnimationFactory(const char* ResRef,
unsigned char mode = IE_NORMAL) = 0;
- /** This function will load the Animation as a Font */
- virtual Font* GetFont() = 0;
/** Debug Function: Returns the Global Animation Palette as a Sprite2D Object.
If the Global Animation Palette is NULL, returns NULL. */
virtual Sprite2D* GetPalette() = 0;
virtual int GetCycleCount() = 0;
};
+}
+
#endif
diff --git a/gemrb/core/ArchiveImporter.cpp b/gemrb/core/ArchiveImporter.cpp
index 2c8524f..99e1df4 100644
--- a/gemrb/core/ArchiveImporter.cpp
+++ b/gemrb/core/ArchiveImporter.cpp
@@ -20,6 +20,8 @@
#include "ArchiveImporter.h"
+namespace GemRB {
+
ArchiveImporter::ArchiveImporter(void)
{
}
@@ -27,3 +29,5 @@ ArchiveImporter::ArchiveImporter(void)
ArchiveImporter::~ArchiveImporter(void)
{
}
+
+}
diff --git a/gemrb/core/ArchiveImporter.h b/gemrb/core/ArchiveImporter.h
index 076d679..d6968f6 100644
--- a/gemrb/core/ArchiveImporter.h
+++ b/gemrb/core/ArchiveImporter.h
@@ -25,16 +25,18 @@
#include "Plugin.h"
+namespace GemRB {
+
class GEM_EXPORT ArchiveImporter : public Plugin {
public:
ArchiveImporter(void);
virtual ~ArchiveImporter(void);
- virtual int OpenArchive(const char* filename) = 0;
virtual int CreateArchive(DataStream *stream) = 0;
//decompressing a .sav file similar to CBF
virtual int DecompressSaveGame(DataStream *compressed) = 0;
virtual int AddToSaveGame(DataStream *str, DataStream *uncompressed) = 0;
- virtual DataStream* GetStream(unsigned long Resource, unsigned long Type) = 0;
};
+}
+
#endif
diff --git a/gemrb/core/Audio.cpp b/gemrb/core/Audio.cpp
index fa114c4..836237c 100644
--- a/gemrb/core/Audio.cpp
+++ b/gemrb/core/Audio.cpp
@@ -20,6 +20,8 @@
#include "Audio.h"
+namespace GemRB {
+
const TypeID Audio::ID = { "Audio" };
Audio::Audio(void)
@@ -33,3 +35,5 @@ Audio::~Audio(void)
SoundHandle::~SoundHandle()
{
}
+
+}
diff --git a/gemrb/core/Audio.h b/gemrb/core/Audio.h
index 4606f38..e029105 100644
--- a/gemrb/core/Audio.h
+++ b/gemrb/core/Audio.h
@@ -27,9 +27,13 @@
#include "Plugin.h"
#include "Holder.h"
+namespace GemRB {
+
#define GEM_SND_RELATIVE 1
#define GEM_SND_LOOPING 2
#define GEM_SND_SPEECH IE_STR_SPEECH // 4
+#define GEM_SND_QUEUE 8
+
#define GEM_SND_VOL_MUSIC 1
#define GEM_SND_VOL_AMBIENTS 2
@@ -54,7 +58,6 @@ public:
virtual bool Init(void) = 0;
virtual Holder<SoundHandle> Play(const char* ResRef, int XPos, int YPos, unsigned int flags = 0, unsigned int *length = 0) = 0;
virtual Holder<SoundHandle> Play(const char* ResRef, unsigned int *length = 0) { return Play(ResRef, 0, 0, GEM_SND_RELATIVE, length); }
- virtual bool IsSpeaking() = 0;
virtual AmbientMgr* GetAmbientMgr() { return ambim; }
virtual void UpdateVolume(unsigned int flags = GEM_SND_VOL_MUSIC | GEM_SND_VOL_AMBIENTS) = 0;
virtual bool CanPlay() = 0;
@@ -79,4 +82,6 @@ protected:
};
+}
+
#endif // AUDIO_H_INCLUDED
diff --git a/gemrb/core/Bitmap.cpp b/gemrb/core/Bitmap.cpp
index 2a55fa4..13f1859 100644
--- a/gemrb/core/Bitmap.cpp
+++ b/gemrb/core/Bitmap.cpp
@@ -18,6 +18,8 @@
#include "Bitmap.h"
+namespace GemRB {
+
Bitmap::Bitmap(unsigned int w, unsigned int h)
: height(h), width(w), data(new unsigned char[height*width])
{
@@ -27,3 +29,5 @@ Bitmap::~Bitmap()
{
delete[] data;
}
+
+}
diff --git a/gemrb/core/Bitmap.h b/gemrb/core/Bitmap.h
index 2c37bdd..7d6fe9a 100644
--- a/gemrb/core/Bitmap.h
+++ b/gemrb/core/Bitmap.h
@@ -21,6 +21,8 @@
#include "exports.h"
+namespace GemRB {
+
class GEM_EXPORT Bitmap {
public:
Bitmap(unsigned int height, unsigned int width);
@@ -52,4 +54,6 @@ private:
unsigned char *data;
};
+}
+
#endif
diff --git a/gemrb/core/CMakeLists.txt b/gemrb/core/CMakeLists.txt
index 767e033..bc27fd3 100644
--- a/gemrb/core/CMakeLists.txt
+++ b/gemrb/core/CMakeLists.txt
@@ -1,6 +1,102 @@
ADD_DEFINITIONS(-DGEM_BUILD_DLL)
-FILE(GLOB gemrb_core_LIB_SRCS "*.cpp"
+IF (ANDROID)
+ set (PLATFORM_SRC System/Logger/Android.cpp)
+ELSEIF (WIN32)
+ set (PLATFORM_SRC System/Logger/Win32Console.cpp)
+ELSE ()
+ set (PLATFORM_SRC)
+ENDIF ()
+
+FILE(GLOB gemrb_core_LIB_SRCS
+ ActorMgr.cpp
+ Ambient.cpp
+ AmbientMgr.cpp
+ Animation.cpp
+ AnimationFactory.cpp
+ AnimationMgr.cpp
+ ArchiveImporter.cpp
+ Audio.cpp
+ Bitmap.cpp
+ Cache.cpp
+ Calendar.cpp
+ Callback.cpp
+ CharAnimations.cpp
+ Compressor.cpp
+ ControlAnimation.cpp
+ Core.cpp
+ DataFileMgr.cpp
+ Dialog.cpp
+ DialogHandler.cpp
+ DialogMgr.cpp
+ DisplayMessage.cpp
+ EffectMgr.cpp
+ EffectQueue.cpp
+ Factory.cpp
+ FactoryObject.cpp
+ FileCache.cpp
+ Font.cpp
+ FontManager.cpp
+ Game.cpp
+ GameData.cpp
+ GlobalTimer.cpp
+ Image.cpp
+ ImageFactory.cpp
+ ImageMgr.cpp
+ ImageWriter.cpp
+ IndexedArchive.cpp
+ IniSpawn.cpp
+ Interface.cpp
+ InterfaceConfig.cpp
+ Inventory.cpp
+ Item.cpp
+ ItemMgr.cpp
+ KeyMap.cpp
+ LRUCache.cpp
+ Map.cpp
+ MapMgr.cpp
+ MoviePlayer.cpp
+ MusicMgr.cpp
+ Palette.cpp
+ PalettedImageMgr.cpp
+ Particles.cpp
+ Plugin.cpp
+ PluginLoader.cpp
+ PluginMgr.cpp
+ Polygon.cpp
+ Projectile.cpp
+ ProjectileMgr.cpp
+ ProjectileServer.cpp
+ Region.cpp
+ Resource.cpp
+ ResourceDesc.cpp
+ ResourceManager.cpp
+ ResourceSource.cpp
+ SaveGameIterator.cpp
+ SaveGameMgr.cpp
+ ScriptEngine.cpp
+ ScriptedAnimation.cpp
+ SoundMgr.cpp
+ Spell.cpp
+ SpellMgr.cpp
+ Spellbook.cpp
+ Sprite2D.cpp
+ SpriteCover.cpp
+ Store.cpp
+ StoreMgr.cpp
+ StringMgr.cpp
+ SymbolMgr.cpp
+ TableMgr.cpp
+ Tile.cpp
+ TileMap.cpp
+ TileMapMgr.cpp
+ TileOverlay.cpp
+ TileSetMgr.cpp
+ Variables.cpp
+ Video.cpp
+ WindowMgr.cpp
+ WorldMap.cpp
+ WorldMapMgr.cpp
GameScript/Actions.cpp
GameScript/GSUtils.cpp
GameScript/GameScript.cpp
@@ -22,23 +118,32 @@ FILE(GLOB gemrb_core_LIB_SRCS "*.cpp"
GUI/Window.cpp
GUI/WorldMapControl.cpp
Scriptable/Actor.cpp
+ Scriptable/CombatInfo.cpp
Scriptable/Container.cpp
Scriptable/Door.cpp
Scriptable/InfoPoint.cpp
Scriptable/Scriptable.cpp
Scriptable/PCStatStruct.cpp
- System/CachedFileStream.cpp
System/DataStream.cpp
System/FileStream.cpp
System/MemoryStream.cpp
+ System/Logger.cpp
+ System/Logger/File.cpp
+ System/Logger/MessageWindowLogger.cpp
+ System/Logger/Stdio.cpp
+ System/Logging.cpp
+ System/SlicedStream.cpp
+ System/String.cpp
+ System/StringBuffer.cpp
System/VFS.cpp
- System/snprintf.cpp
+ ${PLATFORM_SRC}
)
if (STATIC_LINK)
ADD_LIBRARY(gemrb_core STATIC ${gemrb_core_LIB_SRCS})
else (STATIC_LINK)
ADD_LIBRARY(gemrb_core SHARED ${gemrb_core_LIB_SRCS})
+ TARGET_LINK_LIBRARIES(gemrb_core ${CMAKE_DL_LIBS} ${COREFOUNDATION_LIBRARY})
IF(WIN32)
INSTALL(TARGETS gemrb_core RUNTIME DESTINATION ${LIB_DIR})
ELSE(WIN32)
@@ -50,3 +155,8 @@ SET_TARGET_PROPERTIES(gemrb_core PROPERTIES
COMPILE_DEFINITIONS
"PLUGINDIR=\"${PLUGIN_DIR}\";DATADIR=\"${DATA_DIR}\";SYSCONFDIR=\"${SYSCONF_DIR}\""
)
+
+IF (APPLE)
+ SET_TARGET_PROPERTIES(gemrb_core PROPERTIES
+ INSTALL_NAME_DIR ${LIB_DIR})
+ENDIF (APPLE)
diff --git a/gemrb/core/Cache.cpp b/gemrb/core/Cache.cpp
index 647b0cb..935678c 100644
--- a/gemrb/core/Cache.cpp
+++ b/gemrb/core/Cache.cpp
@@ -20,8 +20,11 @@
#include "Cache.h"
+#include <cassert>
#include <ctype.h>
+namespace GemRB {
+
// private inlines
inline unsigned int Cache::MyHashKey(const char* key) const
{
@@ -309,3 +312,5 @@ void Cache::Cleanup()
pAssoc=nextAssoc;
}
}
+
+}
diff --git a/gemrb/core/Cache.h b/gemrb/core/Cache.h
index b83e576..4f038f0 100644
--- a/gemrb/core/Cache.h
+++ b/gemrb/core/Cache.h
@@ -24,6 +24,8 @@
#include "globals.h"
#include "win32def.h"
+namespace GemRB {
+
#define KEYSIZE 8
#ifndef ReleaseFun
@@ -90,4 +92,6 @@ public:
~Cache();
};
+}
+
#endif //CACHE_H
diff --git a/gemrb/core/Calendar.cpp b/gemrb/core/Calendar.cpp
index 673bdb0..4e3d14f 100644
--- a/gemrb/core/Calendar.cpp
+++ b/gemrb/core/Calendar.cpp
@@ -26,6 +26,8 @@
#include "TableMgr.h"
#include "Variables.h"
+namespace GemRB {
+
Calendar::Calendar(void)
{
int i;
@@ -94,3 +96,4 @@ int Calendar::GetCalendarDay(int date) const
return dayandmonth+1;
}
+}
diff --git a/gemrb/core/Calendar.h b/gemrb/core/Calendar.h
index 28740f0..6bd95ac 100644
--- a/gemrb/core/Calendar.h
+++ b/gemrb/core/Calendar.h
@@ -23,6 +23,8 @@
#include "exports.h"
+namespace GemRB {
+
class GEM_EXPORT Calendar {
private:
int daysinyear;
@@ -37,4 +39,6 @@ public:
int GetCalendarDay(int date) const;
};
+}
+
#endif
diff --git a/gemrb/core/Callback.cpp b/gemrb/core/Callback.cpp
index 8cfb7bf..b0e85cd 100644
--- a/gemrb/core/Callback.cpp
+++ b/gemrb/core/Callback.cpp
@@ -18,6 +18,8 @@
#include "Callback.h"
+namespace GemRB {
+
Callback::~Callback()
{
}
@@ -31,3 +33,5 @@ bool Callback::call(int)
{
return true;
}
+
+}
diff --git a/gemrb/core/Callback.h b/gemrb/core/Callback.h
index 208e628..a5918a9 100644
--- a/gemrb/core/Callback.h
+++ b/gemrb/core/Callback.h
@@ -23,6 +23,8 @@
#include "Holder.h"
+namespace GemRB {
+
class GEM_EXPORT Callback : public Held<Callback> {
public:
virtual ~Callback();
@@ -32,4 +34,6 @@ public:
typedef Holder<Callback> EventHandler;
+}
+
#endif
diff --git a/gemrb/core/CharAnimations.cpp b/gemrb/core/CharAnimations.cpp
index 66dc4b1..4d93553 100644
--- a/gemrb/core/CharAnimations.cpp
+++ b/gemrb/core/CharAnimations.cpp
@@ -22,6 +22,8 @@
#include "win32def.h"
+#include "AnimationFactory.h"
+#include "DataFileMgr.h"
#include "Game.h"
#include "GameData.h"
#include "ImageMgr.h"
@@ -30,11 +32,15 @@
#include "Palette.h"
#include "Video.h"
+namespace GemRB {
+
static int AvatarsCount = 0;
static AvatarStruct *AvatarTable = NULL;
static const ieByte SixteenToNine[16]={0,1,2,3,4,5,6,7,8,7,6,5,4,3,2,1};
static const ieByte SixteenToFive[16]={0,0,1,1,2,2,3,3,4,4,3,3,2,2,1,1};
+static const int zOrder_TwoPiece[2] = { 1, 0 };
+
static const int zOrder_Mirror16[16][4] = {
{ 0, 3, 2, 1 },
{ 0, 3, 2, 1 },
@@ -58,8 +64,8 @@ static const int zOrder_8[8][4] = {
{ 0, 3, 2, 1 },
{ 0, 3, 1, 2 },
{ 1, 0, 3, 2 },
- { 1, 0, 3, 2 },
- { 1, 0, 3, 2 },
+ { 1, 2, 0, 3 },
+ { 1, 2, 0, 3 },
{ 2, 0, 3, 1 },
{ 2, 0, 3, 1 },
{ 2, 0, 3, 1 }
@@ -124,6 +130,18 @@ int CharAnimations::GetBloodColor() const
return AvatarTable[AvatarsRowNum].BloodColor;
}
+unsigned int CharAnimations::GetFlags() const
+{
+ if(AvatarsRowNum==~0u) return 0;
+ return AvatarTable[AvatarsRowNum].Flags;
+}
+
+unsigned char CharAnimations::MaybeOverrideStance(unsigned char stance) const
+{
+ if(AvatarsRowNum==~0u) return stance;
+ return AvatarTable[AvatarsRowNum].StanceOverride[stance];
+}
+
static ieResRef EmptySound={0};
const ieResRef &CharAnimations::GetWalkSound() const
@@ -146,6 +164,8 @@ int CharAnimations::GetActorPartCount() const
return 9;
case IE_ANI_FOUR_FRAMES: //wyvern animations
return 4;
+ case IE_ANI_TWO_PIECE: //ankheg animations
+ return 2;
case IE_ANI_PST_GHOST: //special pst anims
if (AvatarTable[AvatarsRowNum].Prefixes[1][0]=='*') {
return 1;
@@ -178,6 +198,15 @@ int CharAnimations::GetTotalPartCount() const
}
}
+const ieResRef& CharAnimations::GetArmourLevel(int ArmourLevel) const
+{
+ //ignore ArmourLevel for the static pst anims (all sprites are displayed)
+ if (AvatarTable[AvatarsRowNum].AnimationType == IE_ANI_PST_GHOST) {
+ ArmourLevel = 0;
+ }
+ return AvatarTable[AvatarsRowNum].Prefixes[ArmourLevel];
+}
+
void CharAnimations::SetArmourLevel(int ArmourLevel)
{
if (AvatarsRowNum==~0u) return;
@@ -185,8 +214,7 @@ void CharAnimations::SetArmourLevel(int ArmourLevel)
if (AvatarTable[AvatarsRowNum].AnimationType == IE_ANI_PST_GHOST) {
ArmourLevel = 0;
}
- strncpy( ResRef, AvatarTable[AvatarsRowNum].Prefixes[ArmourLevel], 8 );
- ResRef[8]=0;
+ CopyResRef( ResRef, AvatarTable[AvatarsRowNum].Prefixes[ArmourLevel] );
DropAnims();
}
@@ -293,6 +321,8 @@ void CharAnimations::CheckColorMod()
}
}
}
+ //this is set by sanctuary and stoneskin (override global colors)
+ lockPalette = false;
}
void CharAnimations::SetupColors(PaletteType type)
@@ -427,9 +457,11 @@ Palette* CharAnimations::GetPartPalette(int part)
int actorPartCount = GetActorPartCount();
PaletteType type = PAL_MAIN;
- if (part == actorPartCount) type = PAL_WEAPON;
- if (part == actorPartCount+1) type = PAL_OFFHAND;
- if (part == actorPartCount+2) type = PAL_HELMET;
+ // always use unmodified BAM palette for the supporting part
+ if (GetAnimType() == IE_ANI_TWO_PIECE && part == 1) return NULL;
+ else if (part == actorPartCount) type = PAL_WEAPON;
+ else if (part == actorPartCount+1) type = PAL_OFFHAND;
+ else if (part == actorPartCount+2) type = PAL_HELMET;
if (modifiedPalette[(int)type])
return modifiedPalette[(int)type];
@@ -448,8 +480,7 @@ void CharAnimations::InitAvatarsTable()
{
AutoTable Avatars("avatars");
if (!Avatars) {
- printMessage("CharAnimations", "A critical animation file is missing!\n", LIGHT_RED);
- abort();
+ error("CharAnimations", "A critical animation file is missing!\n");
}
AvatarTable = (AvatarStruct *) calloc ( AvatarsCount = Avatars->GetRowCount(), sizeof(AvatarStruct) );
int i=AvatarsCount;
@@ -482,6 +513,9 @@ void CharAnimations::InitAvatarsTable()
AvatarTable[i].WalkScale = 0;
AvatarTable[i].RunScale = 0;
AvatarTable[i].Bestiary = -1;
+
+ for (int j = 0; j < MAX_ANIMS; j++)
+ AvatarTable[i].StanceOverride[j] = j;
if (resdata) {
char section[12];
@@ -504,22 +538,24 @@ void CharAnimations::InitAvatarsTable()
int rows = blood->GetRowCount();
for(int i=0;i<rows;i++) {
unsigned long value = 0;
+ unsigned long flags = 0;
unsigned long rmin = 0;
unsigned long rmax = 0xffff;
valid_number(blood->QueryField(i,0), (long &)value);
valid_number(blood->QueryField(i,1), (long &)rmin);
valid_number(blood->QueryField(i,2), (long &)rmax);
- if (value>255 || rmin>0xffff || rmax>0xffff) {
- printMessage("CharAnimations", "bloodclr entry:", LIGHT_RED);
- printf("%02x %04x-%04x ", (unsigned int) value, (unsigned int) rmin, (unsigned int) rmax);
- printStatus("Invalid value!", LIGHT_RED);
+ valid_number(blood->QueryField(i,3), (long &)flags);
+ if (value>255 || rmin>rmax || rmax>0xffff) {
+ Log(ERROR, "CharAnimations", "Invalid bloodclr entry: %02x %04x-%04x ",
+ (unsigned int) value, (unsigned int) rmin, (unsigned int) rmax);
continue;
}
for(int j=0;j<AvatarsCount;j++) {
if (rmax<AvatarTable[j].AnimID) break;
if (rmin>AvatarTable[j].AnimID) continue;
- AvatarTable[j].BloodColor = value;
+ AvatarTable[j].BloodColor = (char) value;
+ AvatarTable[j].Flags = (unsigned int) flags;
}
}
}
@@ -531,7 +567,7 @@ void CharAnimations::InitAvatarsTable()
ieResRef value;
unsigned long rmin = 0;
unsigned long rmax = 0xffff;
- unsigned int range = 0;
+ unsigned long range = 0;
strnuprcpy(value, walk->QueryField(i,0), 8);
valid_number(walk->QueryField(i,1), (long &)rmin);
@@ -541,11 +577,41 @@ void CharAnimations::InitAvatarsTable()
value[0]=0;
range = 0;
}
+ if (range>255 || rmin>rmax || rmax>0xffff) {
+ Log(ERROR, "CharAnimations", "Invalid walksnd entry: %02x %04x-%04x ",
+ (unsigned int) range, (unsigned int) rmin, (unsigned int) rmax);
+ continue;
+ }
for(int j=0;j<AvatarsCount;j++) {
if (rmax<AvatarTable[j].AnimID) break;
if (rmin>AvatarTable[j].AnimID) continue;
memcpy(AvatarTable[j].WalkSound, value, sizeof(ieResRef) );
- AvatarTable[j].WalkSoundCount = range;
+ AvatarTable[j].WalkSoundCount = (unsigned int) range;
+ }
+ }
+ }
+
+ AutoTable stances("stances", true);
+ if (stances) {
+ int rows = stances->GetRowCount();
+ for (int i = 0; i < rows; i++) {
+ unsigned long id = 0, s1 = 0, s2 = 0;
+ valid_number(stances->GetRowName(i), (long &)id);
+ valid_number(stances->QueryField(i, 0), (long &)s1);
+ valid_number(stances->QueryField(i, 1), (long &)s2);
+
+ if (s1 >= MAX_ANIMS || s2 >= MAX_ANIMS) {
+ Log(ERROR, "CharAnimations", "Invalid stances entry: %04x %d %d",
+ (unsigned int) id, (unsigned int) s1, (unsigned int) s2);
+ continue;
+ }
+
+ for (int j = 0; j < AvatarsCount; j++) {
+ if (id < AvatarTable[j].AnimID) break;
+ if (id == AvatarTable[j].AnimID) {
+ AvatarTable[j].StanceOverride[s1] = s2;
+ break;
+ }
}
}
}
@@ -609,8 +675,7 @@ CharAnimations::CharAnimations(unsigned int AnimID, ieDword ArmourLevel)
}
}
ResRef[0]=0;
- printMessage("CharAnimations", " ", LIGHT_RED);
- printf("Invalid or nonexistent avatar entry:%04X\n", AnimID);
+ Log(ERROR, "CharAnimations", "Invalid or nonexistent avatar entry:%04X", AnimID);
}
//we have to drop them when armourlevel changes
@@ -685,6 +750,11 @@ IE_ANI_FOUR_FILES: The Animation is coded in Four Files. Probably it is an old T
IE_ANI_FOUR_FILES_2: Like IE_ANI_FOUR_FILES but with only 16 cycles per frame.
+IE_ANI_FOUR_FILES_3: A variation of the four files animation without equipment, and
+ with even and odd orientations split across two files, plus the standard
+ separate eastern parts, so the layout is
+ [NAME][H|L]G1[/E]
+
IE_ANI_TWENTYTWO: This Animation Type stores the Animation in the following format
[NAME][ACTIONCODE][/E]
ACTIONCODE=A1-6, CA, SX, SA (sling is A1)
@@ -729,6 +799,9 @@ IE_ANI_TWO_FILES_3B: Animations using this type are stored using the following t
This is the standard IWD animation, but BG2 also has it.
See MOR2
+IE_ANI_TWO_PIECE: This is a modified IE_ANI_SIX_FILES with supporting still frames (using a
+ different palette) stored in a second set of files. Currently only used by MAKH
+
IE_ANI_FOUR_FRAMES: These animations are large, four bams make a frame.
@@ -782,12 +855,11 @@ WSW 003 | 013 ESE
Animation** CharAnimations::GetAnimation(unsigned char Stance, unsigned char Orient)
{
if (StanceID>=MAX_ANIMS) {
- printf("Illegal stance ID\n");
- abort();
+ error("CharAnimation", "Illegal stance ID\n");
}
//for paletted dragon animations, we need the stance id
- StanceID = nextStanceID = Stance;
+ StanceID = nextStanceID = Stance;
int AnimType = GetAnimType();
//alter stance here if it is missing and you know a substitute
@@ -821,6 +893,8 @@ Animation** CharAnimations::GetAnimation(unsigned char Stance, unsigned char Ori
}
}
+ StanceID = MaybeOverrideStance(StanceID);
+
//TODO: Implement Auto Resource Loading
//setting up the sequencing of animation cycles
autoSwitchOnEnd = false;
@@ -864,7 +938,7 @@ Animation** CharAnimations::GetAnimation(unsigned char Stance, unsigned char Ori
autoSwitchOnEnd = true;
break;
default:
- printf ("Invalid Stance: %d\n", StanceID);
+ Log(MESSAGE, "CharAnimation", "Invalid Stance: %d", StanceID);
break;
}
Animation** anims = Anims[StanceID][Orient];
@@ -875,7 +949,7 @@ Animation** CharAnimations::GetAnimation(unsigned char Stance, unsigned char Ori
int partCount = GetTotalPartCount();
int actorPartCount = GetActorPartCount();
- if (partCount < 0) return 0;
+ if (partCount <= 0) return 0;
anims = new Animation*[partCount];
EquipResRefData* equipdat = 0;
@@ -894,7 +968,7 @@ Animation** CharAnimations::GetAnimation(unsigned char Stance, unsigned char Ori
if (equipdat) delete equipdat;
//we need this long for special anims
- strncpy( NewResRef, ResRef, 8 );
+ strlcpy( NewResRef, ResRef, sizeof(ieResRef) );
GetAnimResRef( StanceID, Orient, NewResRef, Cycle, part, equipdat);
} else {
// Equipment animation parts
@@ -931,10 +1005,8 @@ Animation** CharAnimations::GetAnimation(unsigned char Stance, unsigned char Ori
if (!af) {
if (part < actorPartCount) {
- char warnbuf[200];
- snprintf(warnbuf, 200,
- "Couldn't create animationfactory: %s (%04x)\n", NewResRef, GetAnimationID());
- printMessage("CharAnimations",warnbuf,LIGHT_RED);
+ Log(ERROR, "CharAnimations", "Couldn't create animationfactory: %s (%04x)",
+ NewResRef, GetAnimationID());;
for (int i = 0; i < part; ++i)
delete anims[i];
delete[] anims;
@@ -951,11 +1023,8 @@ Animation** CharAnimations::GetAnimation(unsigned char Stance, unsigned char Ori
if (!a) {
if (part < actorPartCount) {
- char warnbuf[200];
- snprintf(warnbuf, 200,
- "Couldn't load animation: %s, cycle %d\n",
+ Log(ERROR, "CharAnimations", "Couldn't load animation: %s, cycle %d",
NewResRef, Cycle);
- printMessage("CharAnimations",warnbuf,LIGHT_RED);
for (int i = 0; i < part; ++i)
delete anims[i];
delete[] anims;
@@ -1066,11 +1135,22 @@ Animation** CharAnimations::GetAnimation(unsigned char Stance, unsigned char Ori
case IE_ANI_FOUR_FILES:
case IE_ANI_FOUR_FILES_2:
case IE_ANI_SIX_FILES_2:
+ case IE_ANI_TWO_PIECE:
case IE_ANI_FRAGMENT:
Orient&=~1;
Anims[StanceID][Orient] = anims;
Anims[StanceID][Orient + 1] = anims;
break;
+ case IE_ANI_FOUR_FILES_3:
+ //only 8 orientations for WALK
+ if (StanceID == IE_ANI_WALK) {
+ Orient&=~1;
+ Anims[StanceID][Orient] = anims;
+ Anims[StanceID][Orient + 1] = anims;
+ } else {
+ Anims[StanceID][Orient] = anims;
+ }
+ break;
case IE_ANI_PST_ANIMATION_3: //no stc just std
case IE_ANI_PST_ANIMATION_2: //no std just stc
@@ -1100,8 +1180,7 @@ Animation** CharAnimations::GetAnimation(unsigned char Stance, unsigned char Ori
Anims[StanceID][0] = anims;
break;
default:
- printMessage("CharAnimations","Unknown animation type\n",LIGHT_RED);
- abort();
+ error("CharAnimations", "Unknown animation type\n");
}
delete equipdat;
@@ -1115,7 +1194,6 @@ void CharAnimations::GetAnimResRef(unsigned char StanceID,
char* NewResRef, unsigned char& Cycle,
int Part, EquipResRefData*& EquipData)
{
- char tmp[256];
EquipData = 0;
Orient &= 15;
switch (GetAnimType()) {
@@ -1132,7 +1210,8 @@ void CharAnimations::GetAnimResRef(unsigned char StanceID,
break;
case IE_ANI_BIRD:
- Cycle = (ieByte) ((StanceID&1) * 9 + SixteenToNine[Orient]);
+ // TODO: use 0-8 for gliding; those only have a single frame
+ Cycle = 9 + SixteenToNine[Orient];
break;
case IE_ANI_FRAGMENT:
@@ -1175,10 +1254,18 @@ void CharAnimations::GetAnimResRef(unsigned char StanceID,
AddLRSuffix2( NewResRef, StanceID, Cycle, Orient, EquipData );
break;
+ case IE_ANI_FOUR_FILES_3:
+ AddHLSuffix( NewResRef, StanceID, Cycle, Orient );
+ break;
+
case IE_ANI_SIX_FILES_2: //MOGR (variant of FOUR_FILES)
AddLR3Suffix( NewResRef, StanceID, Cycle, Orient );
break;
+ case IE_ANI_TWO_PIECE: //MAKH
+ AddTwoPieceSuffix( NewResRef, StanceID, Cycle, Orient, Part );
+ break;
+
case IE_ANI_CODE_MIRROR_2: //9 orientations
AddVHR2Suffix( NewResRef, StanceID, Cycle, Orient );
break;
@@ -1203,9 +1290,7 @@ void CharAnimations::GetAnimResRef(unsigned char StanceID,
strnlwrcpy(NewResRef, AvatarTable[AvatarsRowNum].Prefixes[Part], 8);
break;
default:
- sprintf (tmp,"Unknown animation type in avatars.2da row: %d\n", AvatarsRowNum);
- printMessage ("CharAnimations",tmp, LIGHT_RED);
- abort();
+ error("CharAnimations", "Unknown animation type in avatars.2da row: %d\n", AvatarsRowNum);
}
}
@@ -1224,8 +1309,7 @@ void CharAnimations::GetEquipmentResRef(const char* equipRef, bool offhand,
GetMHREquipmentRef( ResRef, Cycle, equipRef, offhand, equip );
break;
default:
- printMessage ("CharAnimations", "Unsupported animation type for equipment animation.\n", LIGHT_RED);
- abort();
+ error("CharAnimations", "Unsupported animation type for equipment animation.\n");
break;
}
}
@@ -1239,6 +1323,8 @@ const int* CharAnimations::GetZOrder(unsigned char Orient)
return zOrder_8[Orient/2];
case IE_ANI_FOUR_FILES:
return 0; // FIXME
+ case IE_ANI_TWO_PIECE:
+ return zOrder_TwoPiece;
default:
return 0;
}
@@ -1316,6 +1402,7 @@ void CharAnimations::AddVHR2Suffix(char* ResRef, unsigned char StanceID,
case IE_ANI_ATTACK: //temporarily
case IE_ANI_ATTACK_BACKSLASH:
strcat( ResRef, "g21" );
+ Cycle+=9;
break;
case IE_ANI_ATTACK_SLASH:
@@ -1323,8 +1410,8 @@ void CharAnimations::AddVHR2Suffix(char* ResRef, unsigned char StanceID,
break;
case IE_ANI_ATTACK_JAB:
- strcat( ResRef, "g26" );
- Cycle+=45;
+ strcat( ResRef, "g22" );
+ Cycle+=18;
break;
case IE_ANI_CAST: //looping
@@ -1379,9 +1466,12 @@ void CharAnimations::AddVHR2Suffix(char* ResRef, unsigned char StanceID,
case IE_ANI_WALK:
strcat( ResRef, "g11" );
break;
+
+ case IE_ANI_HIDE:
+ strcat( ResRef, "g22" );
+ break;
default:
- printf("VHR2 Animation: unhandled stance: %s %d\n", ResRef, StanceID);
- abort();
+ error("CharAnimation", "VHR2 Animation: unhandled stance: %s %d\n", ResRef, StanceID);
break;
}
}
@@ -1459,8 +1549,7 @@ void CharAnimations::AddVHR3Suffix(char* ResRef, unsigned char StanceID,
strcat( ResRef, "g11" );
break;
default:
- printf("VHR3 Animation: unhandled stance: %s %d\n", ResRef, StanceID);
- abort();
+ error("CharAnimation", "VHR3 Animation: unhandled stance: %s %d\n", ResRef, StanceID);
break;
}
}
@@ -1515,14 +1604,14 @@ void CharAnimations::AddFFSuffix(char* ResRef, unsigned char StanceID,
Cycle += 48;
break;
+ case IE_ANI_SLEEP:
case IE_ANI_TWITCH:
strcat( ResRef, "g2" );
Cycle += 64;
break;
default:
- printf("Four frames Animation: unhandled stance: %s %d\n", ResRef, StanceID);
- abort();
+ error("CharAnimation", "Four frames Animation: unhandled stance: %s %d\n", ResRef, StanceID);
break;
}
@@ -1663,8 +1752,7 @@ void CharAnimations::AddVHRSuffix(char* ResRef, unsigned char StanceID,
break;
default:
- printf("VHR Animation: unhandled stance: %s %d\n", ResRef, StanceID);
- abort();
+ error("CharAnimation", "VHR Animation: unhandled stance: %s %d\n", ResRef, StanceID);
break;
}
EquipData->Cycle = Cycle;
@@ -1732,13 +1820,13 @@ void CharAnimations::AddSixSuffix(char* ResRef, unsigned char StanceID,
break;
case IE_ANI_TWITCH:
+ case IE_ANI_SLEEP:
strcat( ResRef, "g2" );
Cycle = 64 + Orient;
break;
default:
- printf("Six Animation: unhandled stance: %s %d\n", ResRef, StanceID);
- abort();
+ error("CharAnimation", "Six Animation: unhandled stance: %s %d\n", ResRef, StanceID);
break;
}
@@ -1787,8 +1875,7 @@ void CharAnimations::AddLR2Suffix(char* ResRef, unsigned char StanceID,
Cycle = 32 + Orient;
break;
default:
- printf("LR2 Animation: unhandled stance: %s %d\n", ResRef, StanceID);
- abort();
+ error("CharAnimation", "LR2 Animation: unhandled stance: %s %d\n", ResRef, StanceID);
break;
}
if (Orient>=4) {
@@ -1910,8 +1997,7 @@ void CharAnimations::AddMHRSuffix(char* ResRef, unsigned char StanceID,
Cycle = Orient;
break;
default:
- printf("MHR Animation: unhandled stance: %s %d\n", ResRef, StanceID);
- abort();
+ error("CharAnimation", "MHR Animation: unhandled stance: %s %d\n", ResRef, StanceID);
break;
}
if (Orient>=5) {
@@ -2018,14 +2104,14 @@ void CharAnimations::AddLRSuffix2( char* ResRef, unsigned char StanceID,
Cycle = 32 + Orient / 2;
break;
case IE_ANI_SLEEP:
+ case IE_ANI_HIDE:
case IE_ANI_TWITCH:
strcat( ResRef, "g1" );
strcpy( EquipData->Suffix, "g1" );
Cycle = 40 + Orient / 2;
break;
default:
- printf("LRSuffix2 Animation: unhandled stance: %s %d\n", ResRef, StanceID);
- abort();
+ error("CharAnimation", "LRSuffix2 Animation: unhandled stance: %s %d\n", ResRef, StanceID);
break;
}
if (Orient > 9) {
@@ -2035,6 +2121,65 @@ void CharAnimations::AddLRSuffix2( char* ResRef, unsigned char StanceID,
EquipData->Cycle = Cycle;
}
+void CharAnimations::AddTwoPieceSuffix(char* ResRef, unsigned char StanceID,
+ unsigned char& Cycle, unsigned char Orient, int Part)
+{
+ if (Part == 1) {
+ strcat( ResRef, "d" );
+ }
+
+ switch (StanceID) {
+ case IE_ANI_DIE:
+ strcat( ResRef, "g1" );
+ Cycle = 8 + Orient / 2;
+ break;
+ case IE_ANI_TWITCH:
+ case IE_ANI_SLEEP:
+ strcat( ResRef, "g1" );
+ Cycle = 16 + Orient / 2;
+ break;
+ case IE_ANI_READY:
+ case IE_ANI_HEAD_TURN:
+ case IE_ANI_AWAKE:
+ case IE_ANI_DAMAGE:
+ strcat( ResRef, "g1" );
+ Cycle = 24 + Orient / 2;
+ break;
+ case IE_ANI_WALK:
+ strcat( ResRef, "g2" );
+ Cycle = Orient / 2;
+ break;
+ case IE_ANI_GET_UP:
+ case IE_ANI_EMERGE:
+ strcat( ResRef, "g2" );
+ Cycle = 8 + Orient / 2;
+ break;
+ case IE_ANI_HIDE:
+ strcat( ResRef, "g2" );
+ Cycle = 16 + Orient / 2;
+ break;
+ case IE_ANI_ATTACK:
+ case IE_ANI_ATTACK_BACKSLASH:
+ strcat( ResRef, "g3" );
+ Cycle = Orient / 2;
+ break;
+ case IE_ANI_ATTACK_SLASH:
+ case IE_ANI_ATTACK_JAB:
+ case IE_ANI_CAST:
+ case IE_ANI_CONJURE:
+ case IE_ANI_SHOOT:
+ strcat( ResRef, "g3" );
+ Cycle = 8 + Orient / 2;
+ break;
+ default:
+ error("CharAnimation", "Two-piece Animation: unhandled stance: %s %d", ResRef, StanceID);
+ break;
+ }
+ if (Orient > 9) {
+ strcat( ResRef, "e" );
+ }
+}
+
void CharAnimations::AddLRSuffix( char* ResRef, unsigned char StanceID,
unsigned char& Cycle, unsigned char Orient, EquipResRefData *&EquipData)
{
@@ -2048,22 +2193,17 @@ void CharAnimations::AddLRSuffix( char* ResRef, unsigned char StanceID,
Cycle = Orient / 2;
break;
case IE_ANI_ATTACK_SLASH:
+ case IE_ANI_CAST:
+ case IE_ANI_CONJURE:
strcat( ResRef, "g2" );
strcpy( EquipData->Suffix, "g2" );
Cycle = 8 + Orient / 2;
break;
case IE_ANI_ATTACK_JAB:
- strcat( ResRef, "g2" );
- strcpy( EquipData->Suffix, "g2" );
- Cycle = 16 + Orient / 2;
- break;
- case IE_ANI_CAST:
- case IE_ANI_CONJURE:
case IE_ANI_SHOOT:
- //these animations are missing
strcat( ResRef, "g2" );
strcpy( EquipData->Suffix, "g2" );
- Cycle = Orient / 2;
+ Cycle = 16 + Orient / 2;
break;
case IE_ANI_WALK:
strcat( ResRef, "g1" );
@@ -2101,8 +2241,7 @@ void CharAnimations::AddLRSuffix( char* ResRef, unsigned char StanceID,
Cycle = 40 + Orient / 2;
break;
default:
- printf("LR Animation: unhandled stance: %s %d\n", ResRef, StanceID);
- abort();
+ error("CharAnimation", "LR Animation: unhandled stance: %s %d\n", ResRef, StanceID);
break;
}
if (Orient > 9) {
@@ -2175,8 +2314,7 @@ void CharAnimations::AddLR3Suffix( char* ResRef, unsigned char StanceID,
Cycle = 24 + Orient / 2;
break;
default:
- printf("LR3 Animation: unhandled stance: %s %d\n", ResRef, StanceID);
- abort();
+ error("CharAnimation", "LR3 Animation: unhandled stance: %s %d\n", ResRef, StanceID);
break;
}
if (Orient > 9) {
@@ -2250,8 +2388,7 @@ void CharAnimations::AddMMR2Suffix(char* ResRef, unsigned char StanceID,
Cycle = ( Orient / 2 );
break;
default:
- printf("MMR Animation: unhandled stance: %s %d\n", ResRef, StanceID);
- abort();
+ error("CharAnimation", "MMR Animation: unhandled stance: %s %d\n", ResRef, StanceID);
break;
}
if (Orient > 9) {
@@ -2337,8 +2474,7 @@ void CharAnimations::AddMMRSuffix(char* ResRef, unsigned char StanceID,
Cycle = ( Orient / 2 );
break;
default:
- printf("MMR Animation: unhandled stance: %s %d\n", ResRef, StanceID);
- abort();
+ error("CharAnimation", "MMR Animation: unhandled stance: %s %d\n", ResRef, StanceID);
break;
}
if (Orient > 9) {
@@ -2346,6 +2482,65 @@ void CharAnimations::AddMMRSuffix(char* ResRef, unsigned char StanceID,
}
}
+void CharAnimations::AddHLSuffix(char* ResRef, unsigned char StanceID,
+ unsigned char& Cycle, unsigned char Orient)
+{
+ //even orientations in 'h', odd in 'l', and since the WALK animation
+ //with fewer orientations is first in h, all other stances in that
+ //file need to be offset by those cycles
+ int offset = ((Orient % 2)^1) * 8;
+
+ switch (StanceID) {
+
+ case IE_ANI_WALK:
+ //only available in 8 orientations instead of the usual 16
+ Cycle = 0 + Orient / 2;
+ offset = 1;
+ break;
+
+ case IE_ANI_HEAD_TURN:
+ Cycle = offset + Orient / 2;
+ break;
+
+ case IE_ANI_AWAKE:
+ case IE_ANI_READY:
+ //the following are not available
+ case IE_ANI_CAST:
+ case IE_ANI_CONJURE:
+ case IE_ANI_HIDE:
+ case IE_ANI_SHOOT:
+ case IE_ANI_ATTACK:
+ case IE_ANI_ATTACK_SLASH:
+ case IE_ANI_ATTACK_BACKSLASH:
+ case IE_ANI_ATTACK_JAB:
+ Cycle = 8 + offset + Orient / 2;
+ break;
+
+ case IE_ANI_DAMAGE:
+ Cycle = 16 + offset + Orient / 2;
+ break;
+
+ case IE_ANI_DIE:
+ case IE_ANI_GET_UP:
+ case IE_ANI_EMERGE:
+ Cycle = 24 + offset + Orient / 2;
+ break;
+
+ case IE_ANI_SLEEP:
+ case IE_ANI_TWITCH:
+ Cycle = 32 + offset + Orient / 2;
+ break;
+
+ default:
+ error("CharAnimation", "HL Animation: unhandled stance: %s %d", ResRef, StanceID);
+ break;
+ }
+ strcat(ResRef, offset ? "hg1" : "lg1");
+ if (Orient > 9) {
+ strcat(ResRef, "e");
+ }
+}
+
void CharAnimations::PulseRGBModifiers()
{
unsigned long time = core->GetGame()->Ticks;
@@ -2406,3 +2601,12 @@ void CharAnimations::PulseRGBModifiers()
lastModUpdate += inc*40;
}
+
+void CharAnimations::DebugDump()
+{
+ Log (DEBUG, "CharAnimations", "Anim ID : %04x", GetAnimationID() );
+ Log (DEBUG, "CharAnimations", "BloodColor: %d", GetBloodColor() );
+ Log (DEBUG, "CharAnimations", "Flags : %04x", GetFlags() );
+}
+
+}
diff --git a/gemrb/core/CharAnimations.h b/gemrb/core/CharAnimations.h
index ea33310..5dd9210 100644
--- a/gemrb/core/CharAnimations.h
+++ b/gemrb/core/CharAnimations.h
@@ -30,6 +30,8 @@
#include <vector>
+namespace GemRB {
+
#define AV_PREFIX1 0
#define AV_PREFIX2 1
#define AV_PREFIX3 2
@@ -80,6 +82,8 @@
#define IE_ANI_FOUR_FILES_2 14 //METT
#define IE_ANI_CODE_MIRROR_3 15 //MSPS
#define IE_ANI_TWO_FILES_3B 16 //iwd animations (eg. MBBM)
+#define IE_ANI_TWO_PIECE 17 //MAKH
+#define IE_ANI_FOUR_FILES_3 18 //mostly civilians
//PST animation types
#define IE_ANI_PST_ANIMATION_1 56 //full animation
@@ -102,6 +106,9 @@
#define IE_ANI_RANGED_XBOW 1
#define IE_ANI_RANGED_THROW 2
+//special flags
+#define AV_NO_BODY_HEAT 1
+
struct AvatarStruct {
/* entries from avatars.2da */
unsigned int AnimID;
@@ -112,7 +119,8 @@ struct AvatarStruct {
char Size;
/* comes from bloodclr.2da */
- char BloodColor;
+ char BloodColor;
+ unsigned int Flags;
/* resdata.ini entries */
unsigned int WalkScale; /* 1000 / walkscale */
@@ -122,6 +130,9 @@ struct AvatarStruct {
/* comes from walksnd.2da */
ieResRef WalkSound;
ieByte WalkSoundCount;
+
+ /* comes from stances.2da */
+ unsigned char StanceOverride[MAX_ANIMS];
};
struct EquipResRefData;
@@ -180,10 +191,12 @@ public: //attribute functions
int GetAnimType() const;
int GetSize() const;
int GetBloodColor() const;
+ unsigned int GetFlags() const;
const ieResRef &GetWalkSound() const;
int GetWalkSoundCount() const;
+ const ieResRef &GetArmourLevel(int ArmourLevel) const;
void PulseRGBModifiers();
-
+ void DebugDump();
private:
void DropAnims();
void InitAvatarsTable();
@@ -192,6 +205,8 @@ private:
unsigned char& Cycle, unsigned char Orient);
void AddFFSuffix(char* ResRef, unsigned char AnimID,
unsigned char& Cycle, unsigned char Orient, int Part);
+ void AddHLSuffix(char* ResRef, unsigned char AnimID,
+ unsigned char& Cycle, unsigned char Orient);
void AddNFSuffix(char* ResRef, unsigned char AnimID,
unsigned char& Cycle, unsigned char Orient, int Part);
void AddVHR2Suffix(char* ResRef, unsigned char AnimID,
@@ -204,6 +219,8 @@ private:
const char* equipRef, bool offhand, EquipResRefData* equip);
void AddSixSuffix(char* ResRef, unsigned char AnimID,
unsigned char& Cycle, unsigned char Orient);
+ void AddTwoPieceSuffix(char* ResRef, unsigned char AnimID,
+ unsigned char& Cycle, unsigned char Orient, int Part);
void AddMHRSuffix(char* ResRef, unsigned char AnimID,
unsigned char& Cycle, unsigned char Orient, EquipResRefData*& equip);
void GetMHREquipmentRef(char* ResRef, unsigned char& Cycle,
@@ -228,6 +245,9 @@ private:
char* ResRef, unsigned char& Cycle, int Part, EquipResRefData*& equip);
void GetEquipmentResRef(const char* equipRef, bool offhand,
char* ResRef, unsigned char& Cycle, EquipResRefData* equip);
+ unsigned char MaybeOverrideStance(unsigned char stance) const;
};
+}
+
#endif
diff --git a/gemrb/core/Compressor.cpp b/gemrb/core/Compressor.cpp
index e7a675b..e6983db 100644
--- a/gemrb/core/Compressor.cpp
+++ b/gemrb/core/Compressor.cpp
@@ -22,6 +22,8 @@
#include "globals.h"
+namespace GemRB {
+
Compressor::Compressor(void)
{
}
@@ -30,8 +32,4 @@ Compressor::~Compressor(void)
{
}
-// Initialization Function. Returns FALSE if there was an error during initialization, else returns TRUE.
-int Compressor::Init(void)
-{
- return GEM_OK;
}
diff --git a/gemrb/core/Compressor.h b/gemrb/core/Compressor.h
index 3409f80..85f847d 100644
--- a/gemrb/core/Compressor.h
+++ b/gemrb/core/Compressor.h
@@ -24,18 +24,18 @@
#include "Plugin.h"
#include "System/DataStream.h"
-#include <cstdio>
+namespace GemRB {
class GEM_EXPORT Compressor : public Plugin {
public:
Compressor(void);
virtual ~Compressor(void);
- /** Initialization Function. Returns FALSE if there was an error during initialization, else returns TRUE. */
- virtual int Init(void);
/** decompresses a datastream (memory or file) to a FILE * stream */
- virtual int Decompress(FILE* dest, DataStream* source, unsigned int size_guess = 0) const = 0;
+ virtual int Decompress(DataStream* dest, DataStream* source, unsigned int size_guess = 0) const = 0;
/** compresses a datastream (memory or file) to another DataStream */
virtual int Compress(DataStream *dest, DataStream* source) const = 0;
};
+}
+
#endif
diff --git a/gemrb/core/ControlAnimation.cpp b/gemrb/core/ControlAnimation.cpp
index 6e61884..3a92549 100644
--- a/gemrb/core/ControlAnimation.cpp
+++ b/gemrb/core/ControlAnimation.cpp
@@ -22,12 +22,16 @@
#include "win32def.h"
+#include "AnimationFactory.h"
#include "GameData.h"
+#include "GlobalTimer.h"
#include "Interface.h"
#include "Palette.h" /* needed only for paperdoll palettes */
#include "Video.h" /* needed only for paperdoll palettes */
#include "GUI/Button.h"
+namespace GemRB {
+
ControlAnimation::ControlAnimation(Control* ctl, const ieResRef ResRef, int Cycle)
{
control = NULL;
@@ -45,6 +49,7 @@ ControlAnimation::ControlAnimation(Control* ctl, const ieResRef ResRef, int Cycl
control = ctl;
control->animation = this;
has_palette = false;
+ is_blended = false;
}
//freeing the bitmaps only once, but using an intelligent algorithm
@@ -69,11 +74,17 @@ bool ControlAnimation::SameResource(const ieResRef ResRef, int Cycle)
return true;
}
-void ControlAnimation::UpdateAnimation(void)
+void ControlAnimation::UpdateAnimation(bool paused)
{
unsigned long time;
int Cycle = cycle;
+ if (paused && !(control->Flags & IE_GUI_BUTTON_PLAYALWAYS)) {
+ // try again later
+ core->timer->AddAnimation( this, 1 );
+ return;
+ }
+
if (control->Flags & IE_GUI_BUTTON_PLAYRANDOM) {
// simple Finite-State Machine
if (anim_phase == 0) {
@@ -108,6 +119,7 @@ void ControlAnimation::UpdateAnimation(void)
//stopping at end frame
if (control->Flags & IE_GUI_BUTTON_PLAYONCE) {
core->timer->RemoveAnimation( this );
+ control->SetAnimPicture( NULL );
return;
}
anim_phase = 0;
@@ -122,8 +134,18 @@ void ControlAnimation::UpdateAnimation(void)
if (has_palette) {
Palette* palette = pic->GetPalette();
palette->SetupPaperdollColours(colors, 0);
+ if (is_blended) {
+ palette->CreateShadedAlphaChannel();
+ }
pic->SetPalette(palette);
palette->Release();
+ } else {
+ if (is_blended) {
+ Palette* palette = pic->GetPalette();
+ palette->CreateShadedAlphaChannel();
+ pic->SetPalette(palette);
+ palette->Release();
+ }
}
control->SetAnimPicture( pic );
@@ -136,3 +158,9 @@ void ControlAnimation::SetPaletteGradients(ieDword *col)
has_palette = true;
}
+void ControlAnimation::SetBlend(bool b)
+{
+ is_blended = b;
+}
+
+}
diff --git a/gemrb/core/ControlAnimation.h b/gemrb/core/ControlAnimation.h
index c85870f..3b91488 100644
--- a/gemrb/core/ControlAnimation.h
+++ b/gemrb/core/ControlAnimation.h
@@ -23,13 +23,15 @@
#include "RGBAColor.h"
#include "exports.h"
-
-#include "AnimationFactory.h"
-#include "Sprite2D.h"
-#include "GUI/Control.h"
+#include "globals.h"
#include <vector>
+namespace GemRB {
+
+class AnimationFactory;
+class Control;
+
class GEM_EXPORT ControlAnimation {
private:
AnimationFactory* bam;
@@ -38,14 +40,18 @@ private:
unsigned int frame;
unsigned int anim_phase;
bool has_palette;
+ bool is_blended;
ieDword colors[8];
public:
ControlAnimation(Control* ctl, const ieResRef ResRef, int Cycle = 0);
~ControlAnimation(void);
- void UpdateAnimation();
+ void UpdateAnimation(bool paused);
//report if the current resource is the same as descripted by the params
bool SameResource(const ieResRef ResRef, int Cycle);
void SetPaletteGradients(ieDword *col);
+ void SetBlend(bool b);
};
+}
+
#endif
diff --git a/gemrb/core/Core.cpp b/gemrb/core/Core.cpp
index 5fd0b66..5a17d52 100644
--- a/gemrb/core/Core.cpp
+++ b/gemrb/core/Core.cpp
@@ -46,66 +46,9 @@ BOOL WINAPI DllEntryPoint(HINSTANCE /*hinstDLL*/, DWORD /*fdwReason*/,
}
#endif
-//// Globally used functions
-
-ieByte pl_uppercase[256];
-ieByte pl_lowercase[256];
-
-// these 3 functions will copy a string to a zero terminated string with a maximum length
-void strnlwrcpy(char *dest, const char *source, int count)
-{
- while(count--) {
- *dest++ = pl_lowercase[(ieByte) *source];
- if(!*source++) {
- while(count--) *dest++=0;
- break;
- }
- }
- *dest=0;
-}
-
-void strnuprcpy(char* dest, const char *source, int count)
-{
- while(count--) {
- *dest++ = pl_uppercase[(ieByte) *source];
- if(!*source++) {
- while(count--) *dest++=0;
- break;
- }
- }
- *dest=0;
-}
-
-// this one also filters spaces, used to copy variables
-void strnspccpy(char* dest, const char *source, int count)
-{
- memset(dest,0,count);
- while(count--) {
- char c = pl_uppercase[(ieByte) *source];
- if (c!=' ') {
- *dest++=c;
- }
- if(!*source++) {
- return;
- }
- }
-}
+namespace GemRB {
-#ifndef HAVE_STRNLEN
-int strnlen(const char* string, int maxlen)
-{
- if (!string) {
- return -1;
- }
- int i = 0;
- while (maxlen-- > 0) {
- if (!string[i])
- break;
- i++;
- }
- return i;
-}
-#endif // ! HAVE_STRNLEN
+//// Globally used functions
static const unsigned char orientations[25]={
6,7,8,9,10,
@@ -270,54 +213,11 @@ int EARelation(Scriptable* Owner, Actor* target)
return EAR_NEUTRAL;
}
-/** Returns the length of string (up to a delimiter) */
-GEM_EXPORT int strlench(const char* string, char ch)
-{
- int i;
- for (i = 0; string[i] && string[i] != ch; i++)
- ;
- return i;
-}
-
-//// Compatibility functions
-#ifndef HAVE_STRNDUP
-GEM_EXPORT char* strndup(const char* s, size_t l)
-{
- size_t len = strlen( s );
- if (len < l) {
- l = len;
- }
- char* string = ( char* ) malloc( l + 1 );
- strncpy( string, s, l );
- string[l] = 0;
- return string;
-}
-#endif
-
-#ifdef WIN32
-
-#else
-
-char* strupr(char* string)
+// safely copies a ResRef (ie. nulls out the unused buffer size)
+void CopyResRef(ieResRef d, const ieResRef s)
{
- char* s;
- if (string) {
- for (s = string; *s; ++s)
- *s = toupper( *s );
- }
- return string;
+ strncpy(d, s, sizeof(ieResRef) - 1);
+ d[sizeof(ieResRef) - 1] = '\0';
}
-char* strlwr(char* string)
-{
- char* s;
- if (string) {
- for (s = string; *s; ++s)
- *s = tolower( *s );
- }
- return string;
}
-
-
-#endif // ! WIN32
-
diff --git a/gemrb/core/DataFileMgr.cpp b/gemrb/core/DataFileMgr.cpp
index 2c95d67..4f9727a 100644
--- a/gemrb/core/DataFileMgr.cpp
+++ b/gemrb/core/DataFileMgr.cpp
@@ -20,6 +20,8 @@
#include "DataFileMgr.h"
+namespace GemRB {
+
DataFileMgr::DataFileMgr(void)
{
}
@@ -27,3 +29,5 @@ DataFileMgr::DataFileMgr(void)
DataFileMgr::~DataFileMgr(void)
{
}
+
+}
diff --git a/gemrb/core/DataFileMgr.h b/gemrb/core/DataFileMgr.h
index 8773767..c18a139 100644
--- a/gemrb/core/DataFileMgr.h
+++ b/gemrb/core/DataFileMgr.h
@@ -31,6 +31,8 @@
#include "Plugin.h"
#include "System/DataStream.h"
+namespace GemRB {
+
/**
* @class DataFileMgr
* Abstract loader for .INI files
@@ -40,7 +42,7 @@ class GEM_EXPORT DataFileMgr : public Plugin {
public:
DataFileMgr(void);
virtual ~DataFileMgr(void);
- virtual bool Open(DataStream* stream, bool autoFree = false) = 0;
+ virtual bool Open(DataStream* stream) = 0;
virtual int GetTagsCount() const = 0;
virtual const char* GetTagNameByIndex(int index) const = 0;
virtual int GetKeysCount(const char* Tag) const = 0;
@@ -55,4 +57,6 @@ public:
const bool Default) const = 0;
};
+}
+
#endif
diff --git a/gemrb/core/Dialog.cpp b/gemrb/core/Dialog.cpp
index a8399ee..0550af1 100644
--- a/gemrb/core/Dialog.cpp
+++ b/gemrb/core/Dialog.cpp
@@ -24,6 +24,8 @@
#include "GameScript/GameScript.h"
+namespace GemRB {
+
Dialog::Dialog(void)
{
TopLevelCount = 0;
@@ -98,3 +100,5 @@ int Dialog::FindRandomState(Scriptable* target)
}
return -1;
}
+
+}
diff --git a/gemrb/core/Dialog.h b/gemrb/core/Dialog.h
index 2b7e921..060ca89 100644
--- a/gemrb/core/Dialog.h
+++ b/gemrb/core/Dialog.h
@@ -26,6 +26,8 @@
#include <vector>
+namespace GemRB {
+
#define IE_DLG_TR_TEXT 0x01
#define IE_DLG_TR_TRIGGER 0x02
#define IE_DLG_TR_ACTION 0x04
@@ -80,4 +82,6 @@ public:
DialogState** initialStates;
};
+}
+
#endif
diff --git a/gemrb/core/DialogHandler.cpp b/gemrb/core/DialogHandler.cpp
index 687547b..cdd060b 100644
--- a/gemrb/core/DialogHandler.cpp
+++ b/gemrb/core/DialogHandler.cpp
@@ -25,10 +25,16 @@
#include "DisplayMessage.h"
#include "Game.h"
#include "GameData.h"
+#include "GlobalTimer.h"
+#include "PluginMgr.h"
#include "ScriptEngine.h"
+#include "TableMgr.h"
#include "Video.h"
#include "GameScript/GameScript.h"
#include "GUI/GameControl.h"
+#include "GUI/TextArea.h"
+
+namespace GemRB {
//translate section values (journal, solved, unsolved, user)
static int sectionMap[4]={4,1,2,0};
@@ -56,7 +62,7 @@ DialogHandler::~DialogHandler(void)
}
//Try to start dialogue between two actors (one of them could be inanimate)
-int DialogHandler::InitDialog(Scriptable* spk, Scriptable* tgt, const char* dlgref)
+bool DialogHandler::InitDialog(Scriptable* spk, Scriptable* tgt, const char* dlgref)
{
if (dlg) {
delete dlg;
@@ -64,13 +70,12 @@ int DialogHandler::InitDialog(Scriptable* spk, Scriptable* tgt, const char* dlgr
}
PluginHolder<DialogMgr> dm(IE_DLG_CLASS_ID);
- dm->Open( gamedata->GetResource( dlgref, IE_DLG_CLASS_ID ), true );
+ dm->Open(gamedata->GetResource(dlgref, IE_DLG_CLASS_ID));
dlg = dm->GetDialog();
if (!dlg) {
- printMessage("GameControl", " ", LIGHT_RED);
- printf( "Cannot start dialog: %s\n", dlgref );
- return -1;
+ Log(ERROR, "GameControl", "Cannot start dialog: %s", dlgref);
+ return false;
}
strnlwrcpy(dlg->ResRef, dlgref, 8); //this isn't handled by GetDialog???
@@ -85,8 +90,9 @@ int DialogHandler::InitDialog(Scriptable* spk, Scriptable* tgt, const char* dlgr
if (!originalTargetID) originalTargetID = tgt->GetGlobalID();
if (tgt->Type==ST_ACTOR) {
Actor *tar = (Actor *) tgt;
- spk->LastTalkedTo=targetID;
- tar->LastTalkedTo=speakerID;
+ // TODO: verify
+ spk->LastTalker=targetID;
+ tar->LastTalker=speakerID;
tar->SetCircleSize();
}
if (oldTarget) oldTarget->SetCircleSize();
@@ -94,16 +100,23 @@ int DialogHandler::InitDialog(Scriptable* spk, Scriptable* tgt, const char* dlgr
GameControl *gc = core->GetGameControl();
if (!gc)
- return -1;
+ return false;
+
+ Video *video = core->GetVideoDriver();
+ Region vp = video->GetViewport();
+ //allow mouse selection from dialog (even though screen is locked)
+ video->SetMouseEnabled(true);
+ core->timer->SetMoveViewPort( tgt->Pos.x, tgt->Pos.y, 0, true );
+ video->MoveViewportTo( tgt->Pos.x-vp.w/2, tgt->Pos.y-vp.h/2 );
//check if we are already in dialog
if (gc->GetDialogueFlags()&DF_IN_DIALOG) {
- return 0;
+ return true;
}
int si = dlg->FindFirstState( tgt );
if (si < 0) {
- return -1;
+ return false;
}
//we need GUI for dialogs
@@ -112,6 +125,7 @@ int DialogHandler::InitDialog(Scriptable* spk, Scriptable* tgt, const char* dlgr
//no exploring while in dialogue
gc->SetScreenFlags(/*SF_GUIENABLED|*/SF_DISABLEMOUSE|SF_LOCKSCROLL, BM_OR);
+ Log(WARNING, "DialogHandler", "Errors occuring while in dialog mode cannot be logged in the MessageWindow.");
gc->SetDialogueFlags(DF_IN_DIALOG, BM_OR);
if (tgt->Type==ST_ACTOR) {
@@ -119,12 +133,6 @@ int DialogHandler::InitDialog(Scriptable* spk, Scriptable* tgt, const char* dlgr
tar->DialogInterrupt();
}
- //allow mouse selection from dialog (even though screen is locked)
- Video *video = core->GetVideoDriver();
- Region vp = video->GetViewport();
- video->SetMouseEnabled(true);
- core->timer->SetMoveViewPort( tgt->Pos.x, tgt->Pos.y, 0, true );
- video->MoveViewportTo( tgt->Pos.x-vp.w/2, tgt->Pos.y-vp.h/2 );
//there are 3 bits, if they are all unset, the dialog freezes scripts
if (!(dlg->Flags&7) ) {
gc->SetDialogueFlags(DF_FREEZE_SCRIPTS, BM_OR);
@@ -134,7 +142,7 @@ int DialogHandler::InitDialog(Scriptable* spk, Scriptable* tgt, const char* dlgr
//core->GetGame()->SetControlStatus(CS_HIDEGUI, BM_NAND);
//core->GetGame()->SetControlStatus(CS_DIALOG, BM_OR);
//core->SetEventFlag(EF_PORTRAIT);
- return 0;
+ return true;
}
/*try to break will only try to break it, false means unconditional stop*/
@@ -170,8 +178,11 @@ void DialogHandler::EndDialog(bool try_to_break)
core->GetGUIScriptEngine()->RunFunction( "GUIWORLD", "DialogEnded" );
//restoring original size
core->GetGame()->SetControlStatus(CS_DIALOG, BM_NAND);
- core->GetGameControl()->SetScreenFlags(SF_DISABLEMOUSE|SF_LOCKSCROLL, BM_NAND);
- core->GetGameControl()->SetDialogueFlags(0, BM_SET);
+ GameControl* gc = core->GetGameControl();
+ if ( !(gc->GetScreenFlags()&SF_CUTSCENE)) {
+ gc->SetScreenFlags(SF_DISABLEMOUSE|SF_LOCKSCROLL, BM_NAND);
+ }
+ gc->SetDialogueFlags(0, BM_SET);
core->SetEventFlag(EF_PORTRAIT);
}
@@ -180,21 +191,21 @@ void DialogHandler::DialogChoose(unsigned int choose)
{
TextArea* ta = core->GetMessageTextArea();
if (!ta) {
- printMessage("GameControl","Dialog aborted???",LIGHT_RED);
+ Log(ERROR, "GameControl", "Dialog aborted???");
EndDialog();
return;
}
Actor *speaker = GetSpeaker();
if (!speaker) {
- printMessage("GameControl","Speaker gone???",LIGHT_RED);
+ Log(ERROR, "GameControl", "Speaker gone???");
EndDialog();
return;
}
Scriptable *target = GetTarget();
if (!target) {
- printMessage("GameControl","Target gone???",LIGHT_RED);
+ Log(ERROR, "GameControl", "Target gone???");
EndDialog();
return;
}
@@ -203,16 +214,11 @@ void DialogHandler::DialogChoose(unsigned int choose)
tgt = (Actor *)target;
}
- Video *video = core->GetVideoDriver();
- Region vp = video->GetViewport();
- video->SetMouseEnabled(true);
- core->timer->SetMoveViewPort( target->Pos.x, target->Pos.y, 0, true );
- video->MoveViewportTo( target->Pos.x-vp.w/2, target->Pos.y-vp.h/2 );
-
+ int si;
if (choose == (unsigned int) -1) {
//increasing talkcount after top level condition was determined
- int si = dlg->FindFirstState( tgt );
+ si = dlg->FindFirstState( tgt );
if (si<0) {
EndDialog();
return;
@@ -227,9 +233,9 @@ void DialogHandler::DialogChoose(unsigned int choose)
tgt->InteractCount++;
}
}
- ds = dlg->GetState( si );
+ //ds = dlg->GetState( si );
} else {
- if (ds->transitionsCount <= choose) {
+ if (!ds || ds->transitionsCount <= choose) {
return;
}
@@ -246,7 +252,7 @@ void DialogHandler::DialogChoose(unsigned int choose)
Section |= 2;
}
if (core->GetGame()->AddJournalEntry(tr->journalStrRef, sectionMap[Section], tr->Flags>>16) ) {
- displaymsg->DisplayConstantString(STR_JOURNALCHANGE,0xffff00);
+ displaymsg->DisplayConstantString(STR_JOURNALCHANGE, DMC_BG2XPGREEN);
char *string = core->GetString( tr->journalStrRef );
//cutting off the strings at the first crlf
char *poi = strchr(string,'\n');
@@ -260,11 +266,13 @@ void DialogHandler::DialogChoose(unsigned int choose)
if (tr->textStrRef != 0xffffffff) {
//allow_zero is for PST (deionarra's text)
- displaymsg->DisplayStringName( (int) (tr->textStrRef), 0x8080FF, speaker, IE_STR_SOUND|IE_STR_SPEECH|IE_STR_ALLOW_ZERO);
+ displaymsg->DisplayStringName( (int) (tr->textStrRef), DMC_DIALOGPARTY, speaker, IE_STR_SOUND|IE_STR_SPEECH|IE_STR_ALLOW_ZERO);
if (core->HasFeature( GF_DIALOGUE_SCROLLS )) {
ta->AppendText( "", -1 );
}
}
+ target->ImmediateEvent();
+ target->ProcessActions(); //run the action queue now
if (tr->actions.size()) {
// does this belong here? we must clear actions somewhere before
@@ -273,10 +281,12 @@ void DialogHandler::DialogChoose(unsigned int choose)
// needs to end before final actions are executed due to
// actions making new dialogs!
if (target->Type == ST_ACTOR) ((Movable *)target)->ClearPath(); // fuzzie added this
- target->ClearActions();
+ target->ClearActions();
// do not interrupt during dialog actions (needed for aerie.d polymorph block)
char buf[20];
+ strcpy(buf, "BreakInstants()");
+ target->AddAction( GenerateAction( buf ) );
strcpy(buf, "SetInterrupt(FALSE)");
target->AddAction( GenerateAction( buf ) );
for (unsigned int i = 0; i < tr->actions.size(); i++) {
@@ -293,11 +303,6 @@ void DialogHandler::DialogChoose(unsigned int choose)
EndDialog();
}
- // *** the commented-out line here should no longer be required, with instant handling ***
- // all dialog actions must be executed immediately
- //target->ProcessActions(true);
- // (do not clear actions - final actions can involve waiting/moving)
-
if (final_dialog) {
return;
}
@@ -307,7 +312,7 @@ void DialogHandler::DialogChoose(unsigned int choose)
core->SetCutSceneMode( false );
//displaying dialog for selected option
- int si = tr->stateIndex;
+ si = tr->stateIndex;
//follow external linkage, if required
if (tr->Dialog[0] && strnicmp( tr->Dialog, dlg->ResRef, 8 )) {
//target should be recalculated!
@@ -332,16 +337,22 @@ void DialogHandler::DialogChoose(unsigned int choose)
// TODO: work out if this should go somewhere more central (such
// as GetActorByDialog), or if there's a less awful way to do this
// (we could cache the entries, for example)
- // TODO: fix for ToB (see also the Interact action)
AutoTable pdtable("interdia");
if (pdtable) {
- int row = pdtable->FindTableValue( pdtable->GetColumnIndex("FILE"), tr->Dialog );
+ int col;
+
+ if (core->GetGame()->Expansion==5) {
+ col = pdtable->GetColumnIndex("25FILE");
+ } else {
+ col = pdtable->GetColumnIndex("FILE");
+ }
+ int row = pdtable->FindTableValue( col, tr->Dialog );
tgt = target->GetCurrentArea()->GetActorByScriptName(pdtable->GetRowName(row));
}
}
target = tgt;
if (!target) {
- printMessage("Dialog","Can't redirect dialog\n",YELLOW);
+ Log(WARNING, "Dialog", "Can't redirect dialog");
ta->SetMinRow( false );
EndDialog();
return;
@@ -353,32 +364,33 @@ void DialogHandler::DialogChoose(unsigned int choose)
// we have to make a backup, tr->Dialog is freed
ieResRef tmpresref;
strnlwrcpy(tmpresref,tr->Dialog, 8);
- if (target->GetInternalFlag()&IF_NOINT) {
+ /*if (target->GetInternalFlag()&IF_NOINT) {
// this whole check moved out of InitDialog by fuzzie, see comments
// for the IF_NOINT check in BeginDialog
- displaymsg->DisplayConstantString(STR_TARGETBUSY,0xff0000);
+ displaymsg->DisplayConstantString(STR_TARGETBUSY, DMC_RED);
ta->SetMinRow( false );
EndDialog();
return;
- }
- int ret = InitDialog( speaker, target, tmpresref);
- if (ret<0) {
+ }*/
+ if (!InitDialog( speaker, target, tmpresref)) {
// error was displayed by InitDialog
ta->SetMinRow( false );
EndDialog();
return;
}
}
- ds = dlg->GetState( si );
- if (!ds) {
- printMessage("Dialog","Can't find next dialog\n",YELLOW);
- ta->SetMinRow( false );
- EndDialog();
- return;
- }
}
+
+ ds = dlg->GetState( si );
+ if (!ds) {
+ Log(WARNING, "Dialog", "Can't find next dialog");
+ ta->SetMinRow( false );
+ EndDialog();
+ return;
+ }
+
//displaying npc text
- displaymsg->DisplayStringName( ds->StrRef, 0x70FF70, target, IE_STR_SOUND|IE_STR_SPEECH);
+ displaymsg->DisplayStringName( ds->StrRef, DMC_DIALOG, target, IE_STR_SOUND|IE_STR_SPEECH);
//adding a gap between options and npc text
ta->AppendText("",-1);
int i;
@@ -429,7 +441,7 @@ void DialogHandler::DialogChoose(unsigned int choose)
}
// this happens if a trigger isn't implemented or the dialog is wrong
if (!idx) {
- printMessage("Dialog", "There were no valid dialog options!\n", YELLOW);
+ Log(WARNING, "Dialog", "There were no valid dialog options!");
core->GetGameControl()->SetDialogueFlags(DF_OPENENDWINDOW, BM_OR);
}
end_of_choose:
@@ -487,3 +499,5 @@ Actor *DialogHandler::GetSpeaker()
return GetActorByGlobalID(speakerID);
}
+
+}
diff --git a/gemrb/core/DialogHandler.h b/gemrb/core/DialogHandler.h
index 499fb0d..9779aa8 100644
--- a/gemrb/core/DialogHandler.h
+++ b/gemrb/core/DialogHandler.h
@@ -25,6 +25,8 @@
#include "Dialog.h"
+namespace GemRB {
+
class GEM_EXPORT DialogHandler {
public:
DialogHandler();
@@ -43,9 +45,11 @@ public:
Scriptable *GetTarget();
Actor *GetSpeaker();
- int InitDialog(Scriptable* speaker, Scriptable* target, const char* dlgref);
+ bool InitDialog(Scriptable* speaker, Scriptable* target, const char* dlgref);
void EndDialog(bool try_to_break=false);
void DialogChoose(unsigned int choose);
};
+}
+
#endif
diff --git a/gemrb/core/DialogMgr.cpp b/gemrb/core/DialogMgr.cpp
index bc68aa5..c213f20 100644
--- a/gemrb/core/DialogMgr.cpp
+++ b/gemrb/core/DialogMgr.cpp
@@ -20,6 +20,8 @@
#include "DialogMgr.h"
+namespace GemRB {
+
DialogMgr::DialogMgr(void)
{
}
@@ -27,3 +29,5 @@ DialogMgr::DialogMgr(void)
DialogMgr::~DialogMgr(void)
{
}
+
+}
diff --git a/gemrb/core/DialogMgr.h b/gemrb/core/DialogMgr.h
index 125ae52..eba6dc3 100644
--- a/gemrb/core/DialogMgr.h
+++ b/gemrb/core/DialogMgr.h
@@ -25,12 +25,16 @@
#include "Plugin.h"
#include "System/DataStream.h"
+namespace GemRB {
+
class GEM_EXPORT DialogMgr : public Plugin {
public:
DialogMgr(void);
virtual ~DialogMgr(void);
- virtual bool Open(DataStream* stream, bool autoFree = true) = 0;
+ virtual bool Open(DataStream* stream) = 0;
virtual Dialog* GetDialog() const = 0;
};
+}
+
#endif
diff --git a/gemrb/core/DisplayMessage.cpp b/gemrb/core/DisplayMessage.cpp
index ceecd6b..8c9c805 100644
--- a/gemrb/core/DisplayMessage.cpp
+++ b/gemrb/core/DisplayMessage.cpp
@@ -26,18 +26,23 @@
#include "TableMgr.h"
#include "GUI/Label.h"
#include "GUI/TextArea.h"
+#include "Scriptable/Actor.h"
-GEM_EXPORT DisplayMessage * displaymsg;
+#include <cstdarg>
+
+namespace GemRB {
+
+GEM_EXPORT DisplayMessage * displaymsg = NULL;
static int strref_table[STRREF_COUNT];
#define PALSIZE 8
static Color ActorColor[PALSIZE];
-static const char* DisplayFormatName = "[color=%lX]%s - [/color][p][color=%lX]%s[/color][/p]";
-static const char* DisplayFormatAction = "[color=%lX]%s - [/color][p][color=%lX]%s %s[/color][/p]";
-static const char* DisplayFormat = "[/color][p][color=%lX]%s[/color][/p]";
-static const char* DisplayFormatValue = "[/color][p][color=%lX]%s: %d[/color][/p]";
-static const char* DisplayFormatNameString = "[color=%lX]%s - [/color][p][color=%lX]%s: %s[/color][/p]";
+static const char* DisplayFormatName = "[color=%06X]%s - [/color][p][color=%06X]%s[/color][/p]";
+static const char* DisplayFormatAction = "[color=%06X]%s - [/color][p][color=%06X]%s %s[/color][/p]";
+static const char* DisplayFormat = "[/color][p][color=%06X]%s[/color][/p]";
+static const char* DisplayFormatValue = "[/color][p][color=%06X]%s: %d[/color][/p]";
+static const char* DisplayFormatNameString = "[color=%06X]%s - [/color][p][color=%06X]%s: %s[/color][/p]";
DisplayMessage::DisplayMessage(void) {
ReadStrrefs();
@@ -61,16 +66,14 @@ void DisplayMessage::DisplayString(const char* Text, Scriptable *target) const
{
Label *l = core->GetMessageLabel();
if (l) {
- l->SetText(Text, 0);
+ l->SetText(Text);
}
TextArea *ta = core->GetMessageTextArea();
if (ta) {
ta->AppendText( Text, -1 );
} else {
if(target) {
- char *tmp = strdup(Text);
-
- target->DisplayHeadText(tmp);
+ target->DisplayHeadText(Text);
}
}
}
@@ -161,7 +164,7 @@ void DisplayMessage::DisplayConstantStringNameString(int stridx, unsigned int co
actor_color = GetSpeakerColor(name, actor);
char* text = core->GetString( strref_table[stridx], IE_STR_SOUND );
char* text2 = core->GetString( strref_table[stridx2], IE_STR_SOUND );
- int newlen = (int)(strlen( DisplayFormat ) + strlen(name) + strlen( text ) + strlen(text2) + 18);
+ int newlen = (int)(strlen( DisplayFormat ) + strlen(name) + strlen( text ) + strlen(text2) + 20);
char* newstr = ( char* ) malloc( newlen );
if (strlen(text2)) {
snprintf( newstr, newlen, DisplayFormatNameString, actor_color, name, color, text, text2 );
@@ -186,6 +189,22 @@ void DisplayMessage::DisplayConstantStringName(int stridx, unsigned int color, c
core->FreeString(text);
}
+//Treats the constant string as a numeric format string, otherwise like the previous method
+void DisplayMessage::DisplayConstantStringNameValue(int stridx, unsigned int color, const Scriptable *speaker, int value) const
+{
+ if (stridx<0) return;
+ if(!speaker) return;
+
+ char* text = core->GetString( strref_table[stridx], IE_STR_SOUND|IE_STR_SPEECH );
+ //allow for a number
+ int bufflen = strlen(text)+6;
+ char* newtext = ( char* ) malloc( bufflen );
+ snprintf( newtext, bufflen, text, value );
+ core->FreeString(text);
+ DisplayStringName(newtext, color, speaker);
+ free(newtext);
+}
+
// String format is
// <charname> - blah blah <someoneelse>
void DisplayMessage::DisplayConstantStringAction(int stridx, unsigned int color, const Scriptable *attacker, const Scriptable *target) const
@@ -210,6 +229,22 @@ void DisplayMessage::DisplayConstantStringAction(int stridx, unsigned int color,
free( newstr );
}
+// display tokenized strings like ~Open lock check. Open lock skill %d vs. lock difficulty %d (%d DEX bonus).~
+void DisplayMessage::DisplayRollStringName(int stridx, unsigned int color, const Scriptable *speaker, ...) const
+{
+ ieDword feedback = 0;
+ core->GetDictionary()->Lookup("EnableRollFeedback", feedback);
+ if (feedback) {
+ char tmp[200];
+ va_list numbers;
+ va_start(numbers, speaker);
+ // fill it out
+ vsnprintf(tmp, sizeof(tmp), core->GetString(stridx), numbers);
+ displaymsg->DisplayStringName(tmp, color, speaker);
+ va_end(numbers);
+ }
+}
+
void DisplayMessage::DisplayStringName(int stridx, unsigned int color, const Scriptable *speaker, ieDword flags) const
{
if (stridx<0) return;
@@ -227,13 +262,16 @@ void DisplayMessage::DisplayStringName(const char *text, unsigned int color, con
if (!text) return;
speaker_color = GetSpeakerColor(name, speaker);
- //FIXME: what happens if there is no name?
- if (name) {
- int newlen = (int)(strlen( DisplayFormatName ) + strlen( name ) +
- + strlen( text ) + 18);
- char* newstr = ( char* ) malloc( newlen );
- snprintf( newstr, newlen, DisplayFormatName, speaker_color, name, color, text );
- DisplayString( newstr );
- free( newstr );
+ // if there is no name, use the script name to help debugging
+ if (!strcmp(name, "")) {
+ name = speaker->GetScriptName();
}
+
+ int newlen = (int)(strlen(DisplayFormatName) + strlen(name) + strlen(text) + 18);
+ char* newstr = (char *) malloc(newlen);
+ snprintf(newstr, newlen, DisplayFormatName, speaker_color, name, color, text);
+ DisplayString(newstr);
+ free(newstr);
+}
+
}
diff --git a/gemrb/core/DisplayMessage.h b/gemrb/core/DisplayMessage.h
index 9fc781b..dfcc854 100644
--- a/gemrb/core/DisplayMessage.h
+++ b/gemrb/core/DisplayMessage.h
@@ -28,8 +28,21 @@
#define DISPLAYMESSAGE_H
#include "exports.h"
+#include "ie_types.h"
-#include "ActorMgr.h"
+#include <cstdlib>
+
+namespace GemRB {
+
+#define DMC_WHITE 0xf0f0f0
+#define DMC_RED 0xff0000
+#define DMC_LIGHTGREY 0xd7d7be
+#define DMC_BG2XPGREEN 0xbcefbc
+#define DMC_GOLD 0xc0c000
+#define DMC_DIALOG DMC_WHITE
+#define DMC_DIALOGPARTY 0x8080FF
+
+class Scriptable;
class GEM_EXPORT DisplayMessage
{
@@ -55,6 +68,8 @@ public:
void DisplayConstantStringValue(int stridx, unsigned int color, ieDword value) const;
/** displays a string constant in the textarea, starting with speaker's name */
void DisplayConstantStringName(int stridx, unsigned int color, const Scriptable *speaker) const;
+ /** displays a string constant in the textarea, starting with speaker's name, also replaces one numeric value (it is a format string) */
+ void DisplayConstantStringNameValue(int stridx, unsigned int color, const Scriptable *speaker, int value) const;
/** displays a string constant in the textarea, starting with actor, and ending with target */
void DisplayConstantStringAction(int stridx, unsigned int color, const Scriptable *actor, const Scriptable *target) const;
/** displays a string in the textarea */
@@ -63,8 +78,12 @@ public:
/** displays a string in the textarea, starting with speaker's name */
void DisplayStringName(int stridx, unsigned int color, const Scriptable *speaker, ieDword flags) const;
void DisplayStringName(const char *text, unsigned int color, const Scriptable *speaker) const;
+ /** iwd2 hidden roll debugger */
+ void DisplayRollStringName(int stridx, unsigned int color, const Scriptable *speaker, ...) const;
};
extern GEM_EXPORT DisplayMessage * displaymsg;
+}
+
#endif
diff --git a/gemrb/core/Effect.h b/gemrb/core/Effect.h
index 400c6bc..d5eafb4 100644
--- a/gemrb/core/Effect.h
+++ b/gemrb/core/Effect.h
@@ -31,6 +31,8 @@
#include "Region.h"
+namespace GemRB {
+
class Actor;
//local variables in creatures are stored in fake opcodes
@@ -70,7 +72,10 @@ class Actor;
//#define FX_CAN_RESIST_NO_DISPEL 2 //same as 0 (not resistable, not dispellable)
#define FX_NO_RESIST_CAN_DISPEL 3
#define FX_CAN_DISPEL 1
-#define FX_CAN_RESIST 3
+
+// Effect save flags (ToBEx)
+#define SF_BYPASS_MIRROR_IMAGE 0x1000000
+#define SF_IGNORE_DIFFICULTY 0x2000000
/**
* @class Effect
@@ -88,8 +93,8 @@ struct Effect {
ieWord unknown2;
ieDword Resistance;
ieDword Duration;
- ieWord Probability1;
- ieWord Probability2;
+ ieWord ProbabilityRangeMax;
+ ieWord ProbabilityRangeMin;
//keep these four in one bunch, VariableName will
//spread across them
ieResRef Resource;
@@ -109,6 +114,8 @@ struct Effect {
ieDword MaxAffectedLevel;
ieDword Parameter3;
ieDword Parameter4;
+ ieDword Parameter5;
+ ieDword Parameter6;
ieDword PosX, PosY;
ieDword SourceType; //1-item, 2-spell
ieResRef Source;
@@ -136,4 +143,6 @@ public:
// FIXME: what about area spells? They can have map & coordinates as target
//void AddEffect(Effect* fx, Actor* self, Actor* pretarget);
+}
+
#endif // ! EFFECT_H
diff --git a/gemrb/core/EffectMgr.cpp b/gemrb/core/EffectMgr.cpp
index 7ca50f4..9e8b9c2 100644
--- a/gemrb/core/EffectMgr.cpp
+++ b/gemrb/core/EffectMgr.cpp
@@ -20,6 +20,8 @@
#include "EffectMgr.h"
+namespace GemRB {
+
EffectMgr::EffectMgr(void)
{
}
@@ -27,3 +29,5 @@ EffectMgr::EffectMgr(void)
EffectMgr::~EffectMgr(void)
{
}
+
+}
diff --git a/gemrb/core/EffectMgr.h b/gemrb/core/EffectMgr.h
index 689651c..2381923 100644
--- a/gemrb/core/EffectMgr.h
+++ b/gemrb/core/EffectMgr.h
@@ -32,6 +32,8 @@
#include "Plugin.h"
#include "System/DataStream.h"
+namespace GemRB {
+
/**
* @class EffectMgr
* Abstract loader for Effect objects
@@ -53,4 +55,6 @@ public:
virtual void PutEffectV2(DataStream *stream, const Effect *fx) = 0;
};
+}
+
#endif
diff --git a/gemrb/core/EffectQueue.cpp b/gemrb/core/EffectQueue.cpp
index ca980d6..c692665 100644
--- a/gemrb/core/EffectQueue.cpp
+++ b/gemrb/core/EffectQueue.cpp
@@ -20,6 +20,10 @@
#include "EffectQueue.h"
+#include "ie_feats.h"
+#include "overlays.h"
+#include "strrefs.h"
+
#include "DisplayMessage.h"
#include "Effect.h"
#include "Game.h"
@@ -27,10 +31,14 @@
#include "Map.h"
#include "SymbolMgr.h"
#include "Scriptable/Actor.h"
-#include "Spell.h" //needs for the source flags bitfield
+#include "Spell.h" //needs for the source flags bitfield
+#include "TableMgr.h"
+#include "System/StringBuffer.h"
#include <cstdio>
+namespace GemRB {
+
static struct {
const char* Name;
EffectFunction Function;
@@ -42,6 +50,49 @@ static int initialized = 0;
static EffectDesc *effectnames = NULL;
static int effectnames_count = 0;
static int pstflags = false;
+static bool iwd2fx = false;
+
+static EffectRef fx_unsummon_creature_ref = { "UnsummonCreature", -1 };
+static EffectRef fx_ac_vs_creature_type_ref = { "ACVsCreatureType", -1 };
+static EffectRef fx_spell_focus_ref = { "SpellFocus", -1 };
+static EffectRef fx_spell_resistance_ref = { "SpellResistance", -1 };
+static EffectRef fx_protection_from_display_string_ref = { "Protection:String", -1 };
+static EffectRef fx_variable_ref = { "Variable:StoreLocalVariable", -1 };
+
+//immunity effects
+static EffectRef fx_level_immunity_ref = { "Protection:Spelllevel", -1 };
+static EffectRef fx_opcode_immunity_ref = { "Protection:Opcode", -1 }; //bg2
+static EffectRef fx_opcode_immunity2_ref = { "Protection:Opcode2", -1 };//iwd
+static EffectRef fx_spell_immunity_ref = { "Protection:Spell", -1 }; //bg2
+static EffectRef fx_spell_immunity2_ref = { "Protection:Spell2", -1 };//iwd
+static EffectRef fx_store_spell_sequencer_ref = { "Sequencer:Store", -1 }; //bg2, works against sequencers
+static EffectRef fx_school_immunity_ref = { "Protection:School", -1 };
+static EffectRef fx_secondary_type_immunity_ref = { "Protection:SecondaryType", -1 };
+
+//decrementing immunity effects
+static EffectRef fx_level_immunity_dec_ref = { "Protection:SpellLevelDec", -1 };
+static EffectRef fx_spell_immunity_dec_ref = { "Protection:SpellDec", -1 };
+static EffectRef fx_school_immunity_dec_ref = { "Protection:SchoolDec", -1 };
+static EffectRef fx_secondary_type_immunity_dec_ref = { "Protection:SecondaryTypeDec", -1 };
+
+//bounce effects
+static EffectRef fx_level_bounce_ref = { "Bounce:SpellLevel", -1 };
+//static EffectRef fx_opcode_bounce_ref = { "Bounce:Opcode", -1 };
+static EffectRef fx_spell_bounce_ref = { "Bounce:Spell", -1 };
+static EffectRef fx_school_bounce_ref = { "Bounce:School", -1 };
+static EffectRef fx_secondary_type_bounce_ref = { "Bounce:SecondaryType", -1 };
+
+//decrementing bounce effects
+static EffectRef fx_level_bounce_dec_ref = { "Bounce:SpellLevelDec", -1 };
+static EffectRef fx_spell_bounce_dec_ref = { "Bounce:SpellDec", -1 };
+static EffectRef fx_school_bounce_dec_ref = { "Bounce:SchoolDec", -1 };
+static EffectRef fx_secondary_type_bounce_dec_ref = { "Bounce:SecondaryTypeDec", -1 };
+
+//spelltrap (multiple decrementing immunity)
+static EffectRef fx_spelltrap = { "SpellTrap", -1 };
+
+//weapon immunity
+static EffectRef fx_weapon_immunity_ref = { "Protection:Weapons", -1 };
bool EffectQueue::match_ids(Actor *target, int table, ieDword value)
{
@@ -52,6 +103,10 @@ bool EffectQueue::match_ids(Actor *target, int table, ieDword value)
int a, stat;
switch (table) {
+ case 0:
+ stat = IE_FACTION; break;
+ case 1:
+ stat = IE_TEAM; break;
case 2: //EA
stat = IE_EA; break;
case 3: //GENERAL
@@ -86,6 +141,10 @@ bool EffectQueue::match_ids(Actor *target, int table, ieDword value)
}
}
return true;
+ case 9:
+ stat = target->GetClassMask();
+ if (value&stat) return true;
+ return false;
default:
return false;
}
@@ -97,7 +156,7 @@ bool EffectQueue::match_ids(Actor *target, int table, ieDword value)
static const bool fx_instant[MAX_TIMING_MODE]={true,true,true,false,false,false,false,false,true,true,true};
-inline bool IsInstant(ieByte timingmode)
+static inline bool IsInstant(ieByte timingmode)
{
if( timingmode>=MAX_TIMING_MODE) return false;
return fx_instant[timingmode];
@@ -105,7 +164,7 @@ inline bool IsInstant(ieByte timingmode)
static const bool fx_equipped[MAX_TIMING_MODE]={false,false,true,false,false,true,false,false,true,false,false};
-inline bool IsEquipped(ieByte timingmode)
+static inline bool IsEquipped(ieByte timingmode)
{
if( timingmode>=MAX_TIMING_MODE) return false;
return fx_equipped[timingmode];
@@ -114,7 +173,7 @@ inline bool IsEquipped(ieByte timingmode)
// 0 1 2 3 4 5 6 7 8 9 10
static const bool fx_relative[MAX_TIMING_MODE]={true,false,false,true,true,true,false,false,false,false,false};
-inline bool NeedPrepare(ieWord timingmode)
+static inline bool NeedPrepare(ieWord timingmode)
{
if( timingmode>=MAX_TIMING_MODE) return false;
return fx_relative[timingmode];
@@ -128,7 +187,7 @@ inline bool NeedPrepare(ieWord timingmode)
static const int fx_prepared[MAX_TIMING_MODE]={DURATION,PERMANENT,PERMANENT,DELAYED, //0-3
DELAYED,DELAYED,DELAYED,DELAYED,PERMANENT,PERMANENT,PERMANENT}; //4-7
-inline int DelayType(ieByte timingmode)
+static inline int DelayType(ieByte timingmode)
{
if( timingmode>=MAX_TIMING_MODE) return INVALID;
return fx_prepared[timingmode];
@@ -137,7 +196,7 @@ inline int DelayType(ieByte timingmode)
//which effects are removable
static const bool fx_removable[MAX_TIMING_MODE]={true,true,false,true,true,false,true,true,false,false,true};
-inline int IsRemovable(ieByte timingmode)
+static inline int IsRemovable(ieByte timingmode)
{
if( timingmode>=MAX_TIMING_MODE) return INVALID;
return fx_removable[timingmode];
@@ -150,25 +209,18 @@ FX_DURATION_AFTER_EXPIRES,FX_DURATION_PERMANENT_UNSAVED, //4,5
FX_DURATION_INSTANT_LIMITED,FX_DURATION_JUST_EXPIRED,FX_DURATION_PERMANENT_UNSAVED,//6,8
FX_DURATION_INSTANT_PERMANENT_AFTER_BONUSES,FX_DURATION_JUST_EXPIRED};//9,10
-//change the timing method for effect that should trigger after this effect expired
-static const ieDword fx_to_delayed[]={FX_DURATION_JUST_EXPIRED,FX_DURATION_JUST_EXPIRED,
-FX_DURATION_PERMANENT_UNSAVED,FX_DURATION_DELAY_LIMITED_PENDING,
-FX_DURATION_AFTER_EXPIRES,FX_DURATION_PERMANENT_UNSAVED, //4,5
-FX_DURATION_JUST_EXPIRED,FX_DURATION_JUST_EXPIRED,FX_DURATION_JUST_EXPIRED,//6,8
-FX_DURATION_JUST_EXPIRED,FX_DURATION_JUST_EXPIRED};//9,10
-
-inline ieByte TriggeredEffect(ieByte timingmode)
+static inline ieByte TriggeredEffect(ieByte timingmode)
{
if( timingmode>=MAX_TIMING_MODE) return false;
return fx_triggered[timingmode];
}
-int compare_effects(const void *a, const void *b)
+static int compare_effects(const void *a, const void *b)
{
return stricmp(((EffectRef *) a)->Name,((EffectRef *) b)->Name);
}
-int find_effect(const void *a, const void *b)
+static int find_effect(const void *a, const void *b)
{
return stricmp((const char *) a,((const EffectRef *) b)->Name);
}
@@ -180,15 +232,12 @@ static EffectDesc* FindEffect(const char* effectname)
}
void *tmp = bsearch(effectname, effectnames, effectnames_count, sizeof(EffectDesc), find_effect);
if( !tmp) {
- printMessage( "EffectQueue", "", YELLOW);
- printf("Couldn't assign effect: %s\n", effectname );
+ Log(WARNING, "EffectQueue", "Couldn't assign effect: %s", effectname);
}
return (EffectDesc *) tmp;
}
-static EffectRef fx_protection_from_display_string_ref = { "Protection:String", -1 };
-
-inline static void ResolveEffectRef(EffectRef &effect_reference)
+static inline void ResolveEffectRef(EffectRef &effect_reference)
{
if( effect_reference.opcode==-1) {
EffectDesc* ref = FindEffect(effect_reference.Name);
@@ -208,6 +257,7 @@ bool Init_EffectQueue()
return true;
}
pstflags = !!core->HasFeature(GF_PST_STATE_FLAGS);
+ iwd2fx = !!core->HasFeature(GF_ENHANCED_EFFECTS);
memset( Opcodes, 0, sizeof( Opcodes ) );
for(i=0;i<MAX_EFFECTS;i++) {
@@ -220,12 +270,12 @@ bool Init_EffectQueue()
int eT = core->LoadSymbol( "effects" );
if( eT < 0) {
- printMessage( "EffectQueue","A critical scripting file is missing!\n",LIGHT_RED );
+ Log(ERROR, "EffectQueue", "A critical scripting file is missing!");
return false;
}
Holder<SymbolMgr> effectsTable = core->GetSymbol( eT );
if( !effectsTable) {
- printMessage( "EffectQueue","A critical scripting file is damaged!\n",LIGHT_RED );
+ Log(ERROR, "EffectQueue", "A critical scripting file is damaged!");
return false;
}
@@ -250,12 +300,11 @@ bool Init_EffectQueue()
//reverse linking opcode number
//using this unused field
if( (poi->opcode!=-1) && effectname[0]!='*') {
- printf("Clashing Opcodes FN: %d vs. %d, %s\n", i, poi->opcode, effectname);
- abort();
+ error("EffectQueue", "Clashing Opcodes FN: %d vs. %d, %s\n", i, poi->opcode, effectname);
}
poi->opcode = i;
}
- //printf("-------- FN: %d, %s\n", i, effectname);
+ //print("-------- FN: %d, %s", i, effectname);
}
core->DelSymbol( eT );
@@ -314,8 +363,7 @@ Effect *EffectQueue::CreateEffect(ieDword opcode, ieDword param1, ieDword param2
memset(fx,0,sizeof(Effect));
fx->Target = FX_TARGET_SELF;
fx->Opcode = opcode;
- //probability2 is the low number (by effectqueue 331)
- fx->Probability1 = 100;
+ fx->ProbabilityRangeMax = 100;
fx->Parameter1 = param1;
fx->Parameter2 = param2;
fx->TimingMode = timing;
@@ -401,17 +449,17 @@ Effect *EffectQueue::CreateEffectCopy(Effect *oldfx, EffectRef &effect_reference
return CreateEffectCopy(oldfx, effect_reference.opcode, param1, param2);
}
-static EffectRef fx_unsummon_creature_ref = { "UnsummonCreature", -1 };
-
Effect *EffectQueue::CreateUnsummonEffect(Effect *fx)
{
Effect *newfx = NULL;
if( (fx->TimingMode&0xff) == FX_DURATION_INSTANT_LIMITED) {
newfx = CreateEffectCopy(fx, fx_unsummon_creature_ref, 0, 0);
newfx->TimingMode = FX_DURATION_DELAY_PERMANENT;
+ newfx->Target = FX_TARGET_PRESET;
if( newfx->Resource3[0]) {
strnuprcpy(newfx->Resource,newfx->Resource3, sizeof(ieResRef)-1 );
} else {
+ //FIXME: unhardcode; should probably use a spell hit (shtable) in some way
strnuprcpy(newfx->Resource,"SPGFLSH1", sizeof(ieResRef)-1 );
}
if( fx->TimingMode == FX_DURATION_ABSOLUTE) {
@@ -485,6 +533,13 @@ int EffectQueue::AddEffect(Effect* fx, Scriptable* self, Actor* pretarget, const
int flg;
ieDword spec = 0;
Actor *st = (self && (self->Type==ST_ACTOR)) ?(Actor *) self:NULL;
+ Effect* new_fx;
+
+ if (self) {
+ fx->CasterID = self->GetGlobalID();
+ } else {
+ if (Owner) fx->CasterID = Owner->GetGlobalID();
+ }
switch (fx->Target) {
case FX_TARGET_ORIGINAL:
@@ -509,6 +564,7 @@ int EffectQueue::AddEffect(Effect* fx, Scriptable* self, Actor* pretarget, const
break;
case FX_TARGET_ALL_BUT_SELF:
+ new_fx = new Effect;
map=self->GetCurrentArea();
i= map->GetActorCount(true);
while(i--) {
@@ -517,13 +573,15 @@ int EffectQueue::AddEffect(Effect* fx, Scriptable* self, Actor* pretarget, const
if( st==actor) {
continue;
}
- fx->SetPosition(actor->Pos);
+ memcpy( new_fx, fx, sizeof( Effect ) );
+ new_fx->SetPosition(actor->Pos);
- flg = ApplyEffect( actor, fx, 1 );
- if( fx->TimingMode != FX_DURATION_JUST_EXPIRED) {
- actor->fxqueue.AddEffect( fx, flg==FX_INSERT );
+ flg = ApplyEffect( actor, new_fx, 1 );
+ if( new_fx->TimingMode != FX_DURATION_JUST_EXPIRED) {
+ actor->fxqueue.AddEffect( new_fx, flg==FX_INSERT );
}
}
+ delete new_fx;
flg = FX_APPLIED;
break;
@@ -534,6 +592,7 @@ int EffectQueue::AddEffect(Effect* fx, Scriptable* self, Actor* pretarget, const
map = self->GetCurrentArea();
spec = st->GetStat(IE_SPECIFIC);
+ new_fx = new Effect;
//GetActorCount(false) returns all nonparty critters
i = map->GetActorCount(false);
while(i--) {
@@ -541,13 +600,15 @@ int EffectQueue::AddEffect(Effect* fx, Scriptable* self, Actor* pretarget, const
if( actor->GetStat(IE_SPECIFIC)!=spec) {
continue;
}
- fx->SetPosition(actor->Pos);
+ memcpy( new_fx, fx, sizeof( Effect ) );
+ new_fx->SetPosition(actor->Pos);
- flg = ApplyEffect( actor, fx, 1 );
- if( fx->TimingMode != FX_DURATION_JUST_EXPIRED) {
- actor->fxqueue.AddEffect( fx, flg==FX_INSERT );
+ flg = ApplyEffect( actor, new_fx, 1 );
+ if( new_fx->TimingMode != FX_DURATION_JUST_EXPIRED) {
+ actor->fxqueue.AddEffect( new_fx, flg==FX_INSERT );
}
}
+ delete new_fx;
flg = FX_APPLIED;
break;
case FX_TARGET_OTHER_SIDE:
@@ -557,6 +618,7 @@ int EffectQueue::AddEffect(Effect* fx, Scriptable* self, Actor* pretarget, const
map = self->GetCurrentArea();
spec = pretarget->GetStat(IE_SPECIFIC);
+ new_fx = new Effect;
//GetActorCount(false) returns all nonparty critters
i = map->GetActorCount(false);
while(i--) {
@@ -564,18 +626,22 @@ int EffectQueue::AddEffect(Effect* fx, Scriptable* self, Actor* pretarget, const
if( actor->GetStat(IE_SPECIFIC)!=spec) {
continue;
}
- fx->SetPosition(actor->Pos);
+ memcpy( new_fx, fx, sizeof( Effect ) );
+ new_fx->SetPosition(actor->Pos);
- flg = ApplyEffect( actor, fx, 1 );
+ flg = ApplyEffect( actor, new_fx, 1 );
//GetActorCount can now return all nonparty critters
- if( fx->TimingMode != FX_DURATION_JUST_EXPIRED) {
- actor->fxqueue.AddEffect( fx, flg==FX_INSERT );
+ if( new_fx->TimingMode != FX_DURATION_JUST_EXPIRED) {
+ actor->fxqueue.AddEffect( new_fx, flg==FX_INSERT );
}
}
+ delete new_fx;
flg = FX_APPLIED;
break;
case FX_TARGET_PRESET:
- fx->SetPosition(pretarget->Pos);
+ //fx->SetPosition(pretarget->Pos);
+ //knock needs this
+ fx->SetPosition(dest);
flg = ApplyEffect( pretarget, fx, 1 );
if( fx->TimingMode != FX_DURATION_JUST_EXPIRED) {
@@ -587,54 +653,63 @@ int EffectQueue::AddEffect(Effect* fx, Scriptable* self, Actor* pretarget, const
case FX_TARGET_PARTY:
all_party:
+ new_fx = new Effect;
game = core->GetGame();
i = game->GetPartySize(false);
while(i--) {
Actor* actor = game->GetPC( i, false );
- fx->SetPosition(actor->Pos);
+ memcpy( new_fx, fx, sizeof( Effect ) );
+ new_fx->SetPosition(actor->Pos);
- flg = ApplyEffect( actor, fx, 1 );
- if( fx->TimingMode != FX_DURATION_JUST_EXPIRED) {
- actor->fxqueue.AddEffect( fx, flg==FX_INSERT );
+ flg = ApplyEffect( actor, new_fx, 1 );
+ if( new_fx->TimingMode != FX_DURATION_JUST_EXPIRED) {
+ actor->fxqueue.AddEffect( new_fx, flg==FX_INSERT );
}
}
+ delete new_fx;
flg = FX_APPLIED;
break;
case FX_TARGET_ALL:
+ new_fx = new Effect;
map = self->GetCurrentArea();
i = map->GetActorCount(true);
while(i--) {
Actor* actor = map->GetActor( i, true );
- fx->SetPosition(actor->Pos);
+ memcpy( new_fx, fx, sizeof( Effect ) );
+ new_fx->SetPosition(actor->Pos);
- flg = ApplyEffect( actor, fx, 1 );
- if( fx->TimingMode != FX_DURATION_JUST_EXPIRED) {
- actor->fxqueue.AddEffect( fx, flg==FX_INSERT );
+ flg = ApplyEffect( actor, new_fx, 1 );
+ if( new_fx->TimingMode != FX_DURATION_JUST_EXPIRED) {
+ actor->fxqueue.AddEffect( new_fx, flg==FX_INSERT );
}
}
+ delete new_fx;
flg = FX_APPLIED;
break;
case FX_TARGET_ALL_BUT_PARTY:
+ new_fx = new Effect;
map = self->GetCurrentArea();
i = map->GetActorCount(false);
while(i--) {
Actor* actor = map->GetActor( i, false );
- fx->SetPosition(actor->Pos);
+ memcpy( new_fx, fx, sizeof( Effect ) );
+ new_fx->SetPosition(actor->Pos);
- flg = ApplyEffect( actor, fx, 1 );
+ flg = ApplyEffect( actor, new_fx, 1 );
//GetActorCount can now return all nonparty critters
- if( fx->TimingMode != FX_DURATION_JUST_EXPIRED) {
- actor->fxqueue.AddEffect( fx, flg==FX_INSERT );
+ if( new_fx->TimingMode != FX_DURATION_JUST_EXPIRED) {
+ actor->fxqueue.AddEffect( new_fx, flg==FX_INSERT );
}
}
+ delete new_fx;
flg = FX_APPLIED;
break;
case FX_TARGET_UNKNOWN:
default:
- printf( "Unknown FX target type: %d\n", fx->Target);
+ Log(MESSAGE, "EffectQueue", "Unknown FX target type: %d", fx->Target);
flg = FX_ABORT;
break;
}
@@ -681,7 +756,7 @@ int EffectQueue::AddAllEffects(Actor* target, const Point &destination) const
}
//resisted effect based on level
-inline bool check_level(Actor *target, Effect *fx)
+static inline bool check_level(Actor *target, Effect *fx)
{
//skip non level based effects
//check if an effect has no level based resistance, but instead the dice sizes/count
@@ -719,8 +794,14 @@ inline bool check_level(Actor *target, Effect *fx)
ieDword level = (ieDword) target->GetXPLevel( true );
//return true if resisted
- if (fx->MinAffectedLevel > 0 || fx->MaxAffectedLevel > 0) {
- if (level < fx->MinAffectedLevel || level > fx->MaxAffectedLevel) {
+ if ((signed)fx->MinAffectedLevel > 0) {
+ if ((signed)level < (signed)fx->MinAffectedLevel) {
+ return true;
+ }
+ }
+
+ if ((signed)fx->MaxAffectedLevel > 0) {
+ if ((signed)level > (signed)fx->MaxAffectedLevel) {
return true;
}
}
@@ -729,57 +810,23 @@ inline bool check_level(Actor *target, Effect *fx)
//roll for the effect probability, there is a high and a low treshold, the d100
//roll should hit in the middle
-inline bool check_probability(Effect* fx)
+static inline bool check_probability(Effect* fx)
{
- //watch for this, probability1 is the high number
- //probability2 is the low number
//random value is 0-99
- if( fx->random_value<=fx->Probability2 || fx->random_value>fx->Probability1) {
+ if (fx->random_value<fx->ProbabilityRangeMin || fx->random_value>fx->ProbabilityRangeMax) {
return false;
}
return true;
}
-//immunity effects
-static EffectRef fx_level_immunity_ref = { "Protection:Spelllevel", -1 };
-static EffectRef fx_opcode_immunity_ref = { "Protection:Opcode", -1 }; //bg2
-static EffectRef fx_opcode_immunity2_ref = { "Protection:Opcode2", -1 };//iwd
-static EffectRef fx_spell_immunity_ref = { "Protection:Spell", -1 }; //bg2
-static EffectRef fx_spell_immunity2_ref = { "Protection:Spell2", -1 };//iwd
-static EffectRef fx_store_spell_sequencer_ref = { "Sequencer:Store", -1 }; //bg2, works against sequencers
-static EffectRef fx_school_immunity_ref = { "Protection:School", -1 };
-static EffectRef fx_secondary_type_immunity_ref = { "Protection:SecondaryType", -1 };
-
-//decrementing immunity effects
-static EffectRef fx_level_immunity_dec_ref = { "Protection:SpellLevelDec", -1 };
-static EffectRef fx_spell_immunity_dec_ref = { "Protection:SpellDec", -1 };
-static EffectRef fx_school_immunity_dec_ref = { "Protection:SchoolDec", -1 };
-static EffectRef fx_secondary_type_immunity_dec_ref = { "Protection:SecondaryTypeDec", -1 };
-
-//bounce effects
-static EffectRef fx_level_bounce_ref = { "Bounce:SpellLevel", -1 };
-//static EffectRef fx_opcode_bounce_ref = { "Bounce:Opcode", -1 };
-static EffectRef fx_spell_bounce_ref = { "Bounce:Spell", -1 };
-static EffectRef fx_school_bounce_ref = { "Bounce:School", -1 };
-static EffectRef fx_secondary_type_bounce_ref = { "Bounce:SecondaryType", -1 };
-
-//decrementing bounce effects
-static EffectRef fx_level_bounce_dec_ref = { "Bounce:SpellLevelDec", -1 };
-static EffectRef fx_spell_bounce_dec_ref = { "Bounce:SpellDec", -1 };
-static EffectRef fx_school_bounce_dec_ref = { "Bounce:SchoolDec", -1 };
-static EffectRef fx_secondary_type_bounce_dec_ref = { "Bounce:SecondaryTypeDec", -1 };
-
-//spelltrap (multiple decrementing immunity)
-static EffectRef fx_spelltrap = { "SpellTrap", -1 };
-
//this is for whole spell immunity/bounce
-inline static void DecreaseEffect(Effect *efx)
+static inline int DecreaseEffect(Effect *efx)
{
- efx->Parameter1--;
- if( (int) efx->Parameter1<1) {
- //don't remove effects directly!!!
- efx->TimingMode = FX_DURATION_JUST_EXPIRED;
+ if (efx->Parameter1) {
+ efx->Parameter1--;
+ return true;
}
+ return false;
}
//lower decreasing immunities/bounces
@@ -800,7 +847,7 @@ static int check_type(Actor* actor, Effect* fx)
}
*/
//spell level immunity
- if(fx->Power && actor->fxqueue.HasEffectWithParamPair(fx_level_immunity_ref, fx->Power, 0) ) {
+ if(fx->Power && actor->fxqueue.HasEffectWithParamPair(fx_level_immunity_ref, 0, fx->Power) ) {
return 0;
}
@@ -834,26 +881,28 @@ static int check_type(Actor* actor, Effect* fx)
//decrementing immunity checks
//decrementing level immunity
- efx = actor->fxqueue.HasEffectWithParamPair(fx_level_immunity_dec_ref, fx->Power, 0);
- if( efx ) {
- DecreaseEffect(efx);
- return 0;
+ if (fx->Power) {
+ efx = actor->fxqueue.HasEffectWithParamPair(fx_level_immunity_dec_ref, 0, fx->Power);
+ if( efx ) {
+ if (DecreaseEffect(efx))
+ return 0;
+ }
}
//decrementing spell immunity
if( fx->Source[0]) {
efx = actor->fxqueue.HasEffectWithResource(fx_spell_immunity_dec_ref, fx->Source);
if( efx) {
- DecreaseEffect(efx);
- return 0;
+ if (DecreaseEffect(efx))
+ return 0;
}
}
//decrementing primary type immunity (school)
if( fx->PrimaryType) {
efx = actor->fxqueue.HasEffectWithParam(fx_school_immunity_dec_ref, fx->PrimaryType);
if( efx) {
- DecreaseEffect(efx);
- return 0;
+ if (DecreaseEffect(efx))
+ return 0;
}
}
@@ -861,8 +910,8 @@ static int check_type(Actor* actor, Effect* fx)
if( fx->SecondaryType) {
efx = actor->fxqueue.HasEffectWithParam(fx_secondary_type_immunity_dec_ref, fx->SecondaryType);
if( efx) {
- DecreaseEffect(efx);
- return 0;
+ if (DecreaseEffect(efx))
+ return 0;
}
}
@@ -871,21 +920,25 @@ static int check_type(Actor* actor, Effect* fx)
//if the spelltrap effect already absorbed enough levels
//but still didn't get removed, it will absorb levels it shouldn't
//it will also absorb multiple spells in a single round
- efx=actor->fxqueue.HasEffectWithParamPair(fx_spelltrap, 0, fx->Power);
- if( efx) {
- //storing the absorbed spell level
- efx->Parameter3+=fx->Power;
- //instead of a single effect, they had to create an effect for each level
- //HOW DAMN LAME
- //if decrease needs the spell level, use fx->Power here
- actor->fxqueue.DecreaseParam1OfEffect(fx_spelltrap, 1);
- //efx->Parameter1--;
- return 0;
+ if (fx->Power) {
+ efx=actor->fxqueue.HasEffectWithParamPair(fx_spelltrap, 0, fx->Power);
+ if( efx) {
+ //storing the absorbed spell level
+ efx->Parameter3+=fx->Power;
+ //instead of a single effect, they had to create an effect for each level
+ //HOW DAMN LAME
+ //if decrease needs the spell level, use fx->Power here
+ actor->fxqueue.DecreaseParam1OfEffect(fx_spelltrap, 1);
+ //efx->Parameter1--;
+ return 0;
+ }
}
//bounce checks
- if( (bounce&BNC_LEVEL) && actor->fxqueue.HasEffectWithParamPair(fx_level_bounce_ref, fx->Power, 0) ) {
- return 0;
+ if (fx->Power) {
+ if( (bounce&BNC_LEVEL) && actor->fxqueue.HasEffectWithParamPair(fx_level_bounce_ref, 0, fx->Power) ) {
+ return 0;
+ }
}
if( fx->Source[0] && (bounce&BNC_RESOURCE) && actor->fxqueue.HasEffectWithResource(fx_spell_bounce_ref, fx->Source) ) {
@@ -906,35 +959,37 @@ static int check_type(Actor* actor, Effect* fx)
//decrementing bounce checks
//level decrementing bounce check
- if( (bounce&BNC_LEVEL_DEC)) {
- efx=actor->fxqueue.HasEffectWithParamPair(fx_level_bounce_dec_ref, fx->Power, 0);
- if( efx) {
- DecreaseEffect(efx);
- return -1;
+ if (fx->Power) {
+ if( (bounce&BNC_LEVEL_DEC)) {
+ efx=actor->fxqueue.HasEffectWithParamPair(fx_level_bounce_dec_ref, 0, fx->Power);
+ if( efx) {
+ if (DecreaseEffect(efx))
+ return -1;
+ }
}
}
if( fx->Source[0] && (bounce&BNC_RESOURCE_DEC)) {
efx=actor->fxqueue.HasEffectWithResource(fx_spell_bounce_dec_ref, fx->Resource);
if( efx) {
- DecreaseEffect(efx);
- return -1;
+ if (DecreaseEffect(efx))
+ return -1;
}
}
if( fx->PrimaryType && (bounce&BNC_SCHOOL_DEC) ) {
efx=actor->fxqueue.HasEffectWithParam(fx_school_bounce_dec_ref, fx->PrimaryType);
if( efx) {
- DecreaseEffect(efx);
- return -1;
+ if (DecreaseEffect(efx))
+ return -1;
}
}
if( fx->SecondaryType && (bounce&BNC_SECTYPE_DEC) ) {
efx=actor->fxqueue.HasEffectWithParam(fx_secondary_type_bounce_dec_ref, fx->SecondaryType);
if( efx) {
- DecreaseEffect(efx);
- return -1;
+ if (DecreaseEffect(efx))
+ return -1;
}
}
@@ -944,17 +999,27 @@ static int check_type(Actor* actor, Effect* fx)
//check resistances, saving throws
static bool check_resistance(Actor* actor, Effect* fx)
{
+ Actor *caster;
+ Scriptable *cob;
+
if( !actor) {
return false;
}
+ cob = GetCasterObject();
+ if (cob && cob->Type==ST_ACTOR) {
+ caster = (Actor *) cob;
+ } else {
+ caster = 0;
+ }
+
//opcode immunity
if( actor->fxqueue.HasEffectWithParam(fx_opcode_immunity_ref, fx->Opcode) ) {
- printf ("immune to effect: %s\n", (char*) Opcodes[fx->Opcode].Name);
+ Log(MESSAGE, "EffectQueue", "immune to effect: %s", (char*) Opcodes[fx->Opcode].Name);
return true;
}
if( actor->fxqueue.HasEffectWithParam(fx_opcode_immunity2_ref, fx->Opcode) ) {
- printf ("immune2 to effect: %s\n", (char*) Opcodes[fx->Opcode].Name);
+ Log(MESSAGE, "EffectQueue", "immune2 to effect: %s", (char*) Opcodes[fx->Opcode].Name);
return true;
}
@@ -966,7 +1031,7 @@ static bool check_resistance(Actor* actor, Effect* fx)
*/
//not resistable (no saves either?)
- if( fx->Resistance != FX_CAN_RESIST_CAN_DISPEL) {
+ if(fx->Resistance != FX_CAN_RESIST_CAN_DISPEL) {
return false;
}
@@ -976,7 +1041,7 @@ static bool check_resistance(Actor* actor, Effect* fx)
//don't resist self
bool selective_mr = core->HasFeature(GF_SELECTIVE_MAGIC_RES);
- if (fx->Target==FX_TARGET_SELF) {
+ if (fx->CasterID == actor->GetGlobalID()) {
if (selective_mr) {
return false;
}
@@ -984,19 +1049,45 @@ static bool check_resistance(Actor* actor, Effect* fx)
//magic immunity
ieDword val = actor->GetStat(IE_RESISTMAGIC);
- if( fx->random_value < val) {
- // when using biased magic resistance non-hostile spells aren't resisted
- if ((selective_mr && (fx->SourceFlags&SF_HOSTILE)) || !selective_mr) {
- printf ("effect resisted: %s\n", (char*) Opcodes[fx->Opcode].Name);
- return true;
- }
+ bool resisted = false;
+
+ if (iwd2fx) {
+ // 3ed style check
+ // TODO: check if luck really affects it (i doubt it does)
+ int roll = actor->LuckyRoll(1, 20, 0);
+ ieDword check = fx->CasterLevel + roll;
+ int penetration = 0;
+ // +2/+4 level bonus from the (greater) spell penetration feat
+ if (caster && caster->HasFeat(FEAT_SPELL_PENETRATION)) {
+ penetration += 2 * caster->GetStat(IE_FEAT_SPELL_PENETRATION);
+ }
+ check += penetration;
+ resisted = (signed) check < (signed) val;
+ // ~Spell Resistance check (Spell resistance:) %d vs. (d20 + caster level + spell resistance mod) = %d + %d + %d.~
+ displaymsg->DisplayRollStringName(39673, DMC_LIGHTGREY, actor, val, roll, fx->CasterLevel, penetration);
+ } else {
+ // 2.5 style check
+ resisted = (signed) fx->random_value < (signed) val;
+ }
+ if (resisted) {
+ // we take care of irresistible spells a few checks above, so selective mr has no impact here anymore
+ displaymsg->DisplayConstantStringName(STR_MAGIC_RESISTED, DMC_WHITE, actor);
+ Log(MESSAGE, "EffectQueue", "effect resisted: %s", (char*) Opcodes[fx->Opcode].Name);
+ return true;
+ }
+
+ //saving throws, bonus can be improved by school specific bonus
+ int bonus = fx->SavingThrowBonus + actor->fxqueue.BonusForParam2(fx_spell_resistance_ref, fx->PrimaryType);
+ if (caster) {
+ bonus += actor->fxqueue.BonusAgainstCreature(fx_ac_vs_creature_type_ref,caster);
+ //saving throw could be made difficult by caster's school specific bonus
+ bonus -= caster->fxqueue.BonusForParam2(fx_spell_focus_ref, fx->PrimaryType);
}
- //saving throws
bool saved = false;
for (int i=0;i<5;i++) {
if( fx->SavingThrowType&(1<<i)) {
- saved = actor->GetSavingThrow(i, fx->SavingThrowBonus);
+ saved = actor->GetSavingThrow(i, bonus);
if( saved) {
break;
}
@@ -1006,7 +1097,7 @@ static bool check_resistance(Actor* actor, Effect* fx)
if( fx->IsSaveForHalfDamage) {
fx->Parameter1/=2;
} else {
- printf ("%s saved against effect: %s\n", actor->GetName(1), (char*) Opcodes[fx->Opcode].Name);
+ Log(MESSAGE, "EffectQueue", "%s saved against effect: %s", actor->GetName(1), (char*) Opcodes[fx->Opcode].Name);
return true;
}
}
@@ -1025,7 +1116,10 @@ static bool check_resistance(Actor* actor, Effect* fx)
int EffectQueue::ApplyEffect(Actor* target, Effect* fx, ieDword first_apply, ieDword resistance) const
{
- //printf( "FX 0x%02x: %s(%d, %d)\n", fx->Opcode, effectnames[fx->Opcode].Name, fx->Parameter1, fx->Parameter2 );
+ //print("FX 0x%02x: %s(%d, %d)", fx->Opcode, effectnames[fx->Opcode].Name, fx->Parameter1, fx->Parameter2);
+ if (fx->TimingMode == FX_DURATION_JUST_EXPIRED) {
+ return FX_NOT_APPLIED;
+ }
if( fx->Opcode >= MAX_EFFECTS) {
fx->TimingMode = FX_DURATION_JUST_EXPIRED;
return FX_NOT_APPLIED;
@@ -1033,19 +1127,17 @@ int EffectQueue::ApplyEffect(Actor* target, Effect* fx, ieDword first_apply, ieD
ieDword GameTime = core->GetGame()->GameTime;
- fx->FirstApply=first_apply;
- if( first_apply) {
- if (Owner)
- fx->CasterID = Owner->GetGlobalID();
+ if (first_apply) {
+ fx->FirstApply = 1;
if( (fx->PosX==0xffffffff) && (fx->PosY==0xffffffff)) {
fx->PosX = target->Pos.x;
fx->PosY = target->Pos.y;
}
//gemrb specific, stat based chance
- if ((fx->Probability2 == 100) && Owner && (Owner->Type==ST_ACTOR) ) {
- fx->Probability2 = 0;
- fx->Probability1 = ((Actor *) Owner)->GetSafeStat(fx->Probability1);
+ if ((fx->ProbabilityRangeMin == 100) && Owner && (Owner->Type==ST_ACTOR) ) {
+ fx->ProbabilityRangeMin = 0;
+ fx->ProbabilityRangeMax = ((Actor *) Owner)->GetSafeStat(fx->ProbabilityRangeMax);
}
if (resistance) {
@@ -1110,28 +1202,28 @@ int EffectQueue::ApplyEffect(Actor* target, Effect* fx, ieDword first_apply, ieD
break;
//this shouldn't happen
default:
- printf("Unknown delay type: %d (from %d)\n", DelayType(fx->TimingMode&0xff), fx->TimingMode);
- abort();
+ error("EffectQueue", "Unknown delay type: %d (from %d)\n", DelayType(fx->TimingMode&0xff), fx->TimingMode);
}
EffectFunction fn = 0;
if( fx->Opcode<MAX_EFFECTS) {
fn = Opcodes[fx->Opcode].Function;
if (!(target || (Opcodes[fx->Opcode].Flags & EFFECT_NO_ACTOR))) {
- printf("targetless opcode without EFFECT_NO_ACTOR: %d, skipping\n", fx->Opcode);
+ Log(MESSAGE, "EffectQueue", "targetless opcode without EFFECT_NO_ACTOR: %d, skipping", fx->Opcode);
return FX_NOT_APPLIED;
}
}
int res = FX_ABORT;
if( fn) {
- if( target && first_apply ) {
+ if( target && fx->FirstApply ) {
if( !target->fxqueue.HasEffectWithParamPair(fx_protection_from_display_string_ref, fx->Parameter1, 0) ) {
- displaymsg->DisplayStringName( Opcodes[fx->Opcode].Strref, 0xf0f0f0,
+ displaymsg->DisplayStringName( Opcodes[fx->Opcode].Strref, DMC_WHITE,
target, IE_STR_SOUND);
}
}
res=fn( Owner, target, fx );
+ fx->FirstApply = 0;
//if there is no owner, we assume it is the target
switch( res ) {
@@ -1152,14 +1244,14 @@ int EffectQueue::ApplyEffect(Actor* target, Effect* fx, ieDword first_apply, ieD
case FX_PERMANENT:
//don't stick around if it was executed permanently
//for example, a permanent strength modifier effect
- if( (fx->TimingMode == FX_DURATION_INSTANT_PERMANENT) ) {
+ if( fx->TimingMode == FX_DURATION_INSTANT_PERMANENT ) {
fx->TimingMode = FX_DURATION_JUST_EXPIRED;
}
break;
case FX_ABORT:
break;
default:
- abort();
+ error("EffectQueue", "Unknown effect result '%x', aborting ...\n", res);
}
} else {
//effect not found, it is going to be discarded
@@ -1179,7 +1271,7 @@ int EffectQueue::ApplyEffect(Actor* target, Effect* fx, ieDword first_apply, ieD
#define MATCH_PROJECTILE() if((*f)->Projectile!=projectile) { continue; }
static const bool fx_live[MAX_TIMING_MODE]={true,true,true,false,false,false,false,false,true,true,false};
-inline bool IsLive(ieByte timingmode)
+static inline bool IsLive(ieByte timingmode)
{
if( timingmode>=MAX_TIMING_MODE) return false;
return fx_live[timingmode];
@@ -1275,6 +1367,7 @@ void EffectQueue::RemoveAllEffectsWithResource(ieDword opcode, const ieResRef re
}
}
+//this will modify effect reference
void EffectQueue::RemoveAllEffectsWithResource(EffectRef &effect_reference, const ieResRef resource) const
{
ResolveEffectRef(effect_reference);
@@ -1306,6 +1399,13 @@ void EffectQueue::RemoveAllDetrimentalEffects(ieDword opcode, ieDword current) c
}
}
+//this will modify effect reference
+void EffectQueue::RemoveAllDetrimentalEffects(EffectRef &effect_reference, ieDword current) const
+{
+ ResolveEffectRef(effect_reference);
+ RemoveAllDetrimentalEffects(effect_reference.opcode, current);
+}
+
//Removes all effects with a matching param2
//param2 is usually an effect's subclass (quality) while param1 is more like quantity.
//So opcode+param2 usually pinpoints an effect better when not all effects of a given
@@ -1322,6 +1422,36 @@ void EffectQueue::RemoveAllEffectsWithParam(ieDword opcode, ieDword param2) cons
}
}
+//this will modify effect reference
+void EffectQueue::RemoveAllEffectsWithParam(EffectRef &effect_reference, ieDword param2) const
+{
+ ResolveEffectRef(effect_reference);
+ RemoveAllEffectsWithParam(effect_reference.opcode, param2);
+}
+
+//Removes all effects with a matching resource field
+void EffectQueue::RemoveAllEffectsWithParamAndResource(ieDword opcode, ieDword param2, const ieResRef resource) const
+{
+ std::list< Effect* >::const_iterator f;
+ for ( f = effects.begin(); f != effects.end(); f++ ) {
+ MATCH_OPCODE();
+ MATCH_LIVE_FX();
+ MATCH_PARAM2();
+ if(resource[0]) {
+ MATCH_RESOURCE();
+ }
+
+ (*f)->TimingMode = FX_DURATION_JUST_EXPIRED;
+ }
+}
+
+//this will modify effect reference
+void EffectQueue::RemoveAllEffectsWithParamAndResource(EffectRef &effect_reference, ieDword param2, const ieResRef resource) const
+{
+ ResolveEffectRef(effect_reference);
+ RemoveAllEffectsWithParamAndResource(effect_reference.opcode, param2, resource);
+}
+
//this function is called by FakeEffectExpiryCheck
//probably also called by rest
void EffectQueue::RemoveExpiredEffects(ieDword futuretime) const
@@ -1357,20 +1487,6 @@ void EffectQueue::RemoveAllNonPermanentEffects() const
}
}
-//this will modify effect reference
-
-void EffectQueue::RemoveAllDetrimentalEffects(EffectRef &effect_reference, ieDword current) const
-{
- ResolveEffectRef(effect_reference);
- RemoveAllDetrimentalEffects(effect_reference.opcode, current);
-}
-
-void EffectQueue::RemoveAllEffectsWithParam(EffectRef &effect_reference, ieDword param2) const
-{
- ResolveEffectRef(effect_reference);
- RemoveAllEffectsWithParam(effect_reference.opcode, param2);
-}
-
//remove certain levels of effects, possibly matching school/secondary type
//this method removes whole spells (tied together by their source)
//FIXME: probably this isn't perfect
@@ -1444,6 +1560,7 @@ Effect *EffectQueue::HasOpcodeWithParam(ieDword opcode, ieDword param2) const
return NULL;
}
+//this will modify effect reference
Effect *EffectQueue::HasEffectWithParam(EffectRef &effect_reference, ieDword param2) const
{
ResolveEffectRef(effect_reference);
@@ -1473,6 +1590,7 @@ Effect *EffectQueue::HasOpcodeWithParamPair(ieDword opcode, ieDword param1, ieDw
return NULL;
}
+//this will modify effect reference
Effect *EffectQueue::HasEffectWithParamPair(EffectRef &effect_reference, ieDword param1, ieDword param2) const
{
ResolveEffectRef(effect_reference);
@@ -1482,57 +1600,78 @@ Effect *EffectQueue::HasEffectWithParamPair(EffectRef &effect_reference, ieDword
return HasOpcodeWithParamPair(effect_reference.opcode, param1, param2);
}
-// sums all the values of the specific damage bonus effects of the passed "damage type"
-int EffectQueue::SpecificDamageBonus(ieDword opcode, ieDword param2) const
+//this could be used for stoneskins and mirror images as well
+void EffectQueue::DecreaseParam1OfEffect(ieDword opcode, ieDword amount) const
{
- int bonus = 0;
std::list< Effect* >::const_iterator f;
for ( f = effects.begin(); f != effects.end(); f++ ) {
MATCH_OPCODE();
MATCH_LIVE_FX();
- MATCH_PARAM2();
- bonus += (signed) (*f)->Parameter1;
+ ieDword value = (*f)->Parameter1;
+ if( value>amount) {
+ value -= amount;
+ amount = 0;
+ } else {
+ amount -= value;
+ value = 0;
+ }
+ (*f)->Parameter1=value;
+ if (value) {
+ return;
+ }
}
- return bonus;
}
-static EffectRef fx_damage_bonus_modifier_ref = { "DamageBonusModifier", -1 };
-int EffectQueue::SpecificDamageBonus(ieDword damage_type) const
+void EffectQueue::DecreaseParam1OfEffect(EffectRef &effect_reference, ieDword amount) const
{
- ResolveEffectRef(fx_damage_bonus_modifier_ref);
- if(fx_damage_bonus_modifier_ref.opcode < 0) {
- return 0;
+ ResolveEffectRef(effect_reference);
+ if( effect_reference.opcode<0) {
+ return;
}
- return SpecificDamageBonus(fx_damage_bonus_modifier_ref.opcode, damage_type);
+ DecreaseParam1OfEffect(effect_reference.opcode, amount);
}
-//this could be used for stoneskins and mirror images as well
-void EffectQueue::DecreaseParam1OfEffect(ieDword opcode, ieDword amount) const
+//this is only used for Cloak of Warding Overlay in PST
+//returns the damage amount NOT soaked
+int EffectQueue::DecreaseParam3OfEffect(ieDword opcode, ieDword amount, ieDword param2) const
{
std::list< Effect* >::const_iterator f;
for ( f = effects.begin(); f != effects.end(); f++ ) {
MATCH_OPCODE();
MATCH_LIVE_FX();
- ieDword value = (*f)->Parameter1;
- if( value>amount) value-=amount;
- else value = 0;
- (*f)->Parameter1=value;
+ MATCH_PARAM2();
+ ieDword value = (*f)->Parameter3;
+ if( value>amount) {
+ value -= amount;
+ amount = 0;
+ } else {
+ amount -= value;
+ value = 0;
+ }
+ (*f)->Parameter3=value;
+ if (value) {
+ return 0;
+ }
}
+ return amount;
}
-void EffectQueue::DecreaseParam1OfEffect(EffectRef &effect_reference, ieDword amount) const
+//this is only used for Cloak of Warding Overlay in PST
+//returns the damage amount NOT soaked
+int EffectQueue::DecreaseParam3OfEffect(EffectRef &effect_reference, ieDword amount, ieDword param2) const
{
ResolveEffectRef(effect_reference);
if( effect_reference.opcode<0) {
- return;
+ return amount;
}
- DecreaseParam1OfEffect(effect_reference.opcode, amount);
+ return DecreaseParam3OfEffect(effect_reference.opcode, amount, param2);
}
-
//this function does IDS targeting for effects (extra damage/thac0 against creature)
-static const int ids_stats[7]={IE_EA, IE_GENERAL, IE_RACE, IE_CLASS, IE_SPECIFIC, IE_SEX, IE_ALIGNMENT};
+//faction/team may be useful for grouping creatures differently, without messing with existing general/specific values
+static const int ids_stats[9]={IE_FACTION, IE_TEAM, IE_EA, IE_GENERAL, IE_RACE, IE_CLASS, IE_SPECIFIC, IE_SEX, IE_ALIGNMENT};
+//0,1 and 9 are only in GemRB
int EffectQueue::BonusAgainstCreature(ieDword opcode, Actor *actor) const
{
int sum = 0;
@@ -1541,14 +1680,33 @@ int EffectQueue::BonusAgainstCreature(ieDword opcode, Actor *actor) const
MATCH_OPCODE();
MATCH_LIVE_FX();
if( (*f)->Parameter1) {
+ ieDword param1;
ieDword ids = (*f)->Parameter2;
- if( ids<2 || ids>8) {
- ids=2;
+ switch(ids) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ param1 = actor->GetStat(ids_stats[ids]);
+ MATCH_PARAM1();
+ break;
+ case 9:
+ //pseudo stat/classmask
+ param1 = actor->GetClassMask() & (*f)->Parameter1;
+ if (!param1) continue;
+ break;
+ default:
+ break;
}
- ieDword param1 = actor->GetStat(ids_stats[ids-2]);
- MATCH_PARAM1();
}
int val = (int) (*f)->Parameter3;
+ //we are really lucky with this, most of these boni are using +2 (including fiendslayer feat)
+ //it would be much more inconvenient if we had to use v2 effect files
if( !val) val = 2;
sum += val;
}
@@ -1564,6 +1722,28 @@ int EffectQueue::BonusAgainstCreature(EffectRef &effect_reference, Actor *actor)
return BonusAgainstCreature(effect_reference.opcode, actor);
}
+int EffectQueue::BonusForParam2(ieDword opcode, ieDword param2) const
+{
+ int sum = 0;
+ std::list< Effect* >::const_iterator f;
+ for ( f = effects.begin(); f != effects.end(); f++ ) {
+ MATCH_OPCODE();
+ MATCH_LIVE_FX();
+ MATCH_PARAM2();
+ sum += (*f)->Parameter1;
+ }
+ return sum;
+}
+
+int EffectQueue::BonusForParam2(EffectRef &effect_reference, ieDword param2) const
+{
+ ResolveEffectRef(effect_reference);
+ if( effect_reference.opcode<0) {
+ return 0;
+ }
+ return BonusForParam2(effect_reference.opcode, param2);
+}
+
bool EffectQueue::WeaponImmunity(ieDword opcode, int enchantment, ieDword weapontype) const
{
std::list< Effect* >::const_iterator f;
@@ -1588,8 +1768,6 @@ bool EffectQueue::WeaponImmunity(ieDword opcode, int enchantment, ieDword weapon
return false;
}
-static EffectRef fx_weapon_immunity_ref = { "Protection:Weapons", -1 };
-
bool EffectQueue::WeaponImmunity(int enchantment, ieDword weapontype) const
{
ResolveEffectRef(fx_weapon_immunity_ref);
@@ -1621,58 +1799,34 @@ void EffectQueue::AddWeaponEffects(EffectQueue *fxqueue, EffectRef &fx_ref) cons
}
}
-/* no longer needed, use IE_CASTING stat
-static EffectRef fx_disable_spellcasting_ref = { "DisableCasting", -1 };
-int EffectQueue::DisabledSpellcasting(int types) const
+// figure out how much damage reduction applies for a given weapon enchantment and damage type
+int EffectQueue::SumDamageReduction(EffectRef &effect_reference, ieDword weaponEnchantment, int &total) const
{
- ResolveEffectRef(fx_disable_spellcasting_ref);
- if( fx_disable_spellcasting_ref.opcode < 0) {
- return 0;
- }
+ ResolveEffectRef(effect_reference);
+ ieDword opcode = effect_reference.opcode;
+ int remaining = 0;
+ int count = 0;
- unsigned int spelltype_mask = 0;
- bool iwd2 = !!core->HasFeature(GF_ENHANCED_EFFECTS);
- ieDword opcode = fx_disable_spellcasting_ref.opcode;
std::list< Effect* >::const_iterator f;
- for ( f = effects.begin(); f != effects.end(); f++ ) {
+ for (f = effects.begin(); f != effects.end(); f++) {
MATCH_OPCODE();
MATCH_LIVE_FX();
- if (iwd2) {
- switch((*f)->Parameter2) {
- case 0: // all
- spelltype_mask |= 7;
- break;
- case 1: // mage and cleric
- spelltype_mask |= 3;
- break;
- case 2: // mage
- spelltype_mask |= 2;
- break;
- case 3: // cleric
- spelltype_mask |= 1;
- break;
- case 4: // innate
- spelltype_mask |= 4;
- break;
- }
- } else {
- switch((*f)->Parameter2) {
- case 0: // mage
- spelltype_mask |= 2;
- break;
- case 1: // cleric
- spelltype_mask |= 1;
- break;
- case 2: // innate
- spelltype_mask |= 4;
- break;
- }
+ Effect* fx = *f;
+ if (!fx) continue;
+ count++;
+ // add up if the effect has enough enchantment (or ignores it)
+ if (!fx->Parameter2 || fx->Parameter2 > weaponEnchantment) {
+ remaining += fx->Parameter1;
}
+ total += fx->Parameter1;
+ }
+ if (count) {
+ return remaining;
+ } else {
+ return -1;
}
- return spelltype_mask & types;
}
-*/
//useful for immunity vs spell, can't use item, etc.
Effect *EffectQueue::HasOpcodeWithResource(ieDword opcode, const ieResRef resource) const
@@ -1694,6 +1848,19 @@ Effect *EffectQueue::HasEffectWithResource(EffectRef &effect_reference, const ie
return HasOpcodeWithResource(effect_reference.opcode, resource);
}
+//returns the first effect with source 'Removed'
+Effect *EffectQueue::HasSource(const ieResRef Removed) const
+{
+ std::list< Effect* >::const_iterator f;
+ for ( f = effects.begin(); f != effects.end(); f++ ) {
+ MATCH_LIVE_FX();
+ MATCH_SOURCE();
+
+ return (*f);
+ }
+ return NULL;
+}
+
//used in contingency/sequencer code (cannot have the same contingency twice)
Effect *EffectQueue::HasOpcodeWithSource(ieDword opcode, const ieResRef Removed) const
{
@@ -1727,7 +1894,14 @@ bool EffectQueue::HasAnyDispellableEffect() const
void EffectQueue::dump() const
{
- printf( "EFFECT QUEUE:\n" );
+ StringBuffer buffer;
+ dump(buffer);
+ Log(DEBUG, "EffectQueue", buffer);
+}
+
+void EffectQueue::dump(StringBuffer& buffer) const
+{
+ buffer.append("EFFECT QUEUE:\n");
int i = 0;
std::list< Effect* >::const_iterator f;
for ( f = effects.begin(); f != effects.end(); f++ ) {
@@ -1737,7 +1911,7 @@ void EffectQueue::dump() const
if( fx->Opcode < MAX_EFFECTS)
Name = (char*) Opcodes[fx->Opcode].Name;
- printf( " %2d: 0x%02x: %s (%d, %d) S:%s\n", i++, fx->Opcode, Name, fx->Parameter1, fx->Parameter2, fx->Source );
+ buffer.appendFormatted(" %2d: 0x%02x: %s (%d, %d) S:%s\n", i++, fx->Opcode, Name, fx->Parameter1, fx->Parameter2, fx->Source);
}
}
}
@@ -1763,15 +1937,14 @@ bool EffectQueue::HasDuration(Effect *fx)
return false;
}
-static EffectRef fx_variable_ref = { "Variable:StoreLocalVariable", -1 };
-
//returns true if the effect must be saved
-//variables are saved differently
bool EffectQueue::Persistent(Effect* fx)
{
- //we save this as variable
+ // local variable effects self-destruct if they were processed already
+ // but if they weren't processed, e.g. in a global actor, we must save them
+ // TODO: do we really need to special-case this? leaving it for now - fuzzie
if( fx->Opcode==(ieDword) ResolveEffect(fx_variable_ref)) {
- return false;
+ return true;
}
switch (fx->TimingMode) {
@@ -1868,15 +2041,6 @@ ieDword EffectQueue::GetSavedEffectsCount() const
return cnt;
}
-void EffectQueue::TransformToDelay(ieByte &TimingMode)
-{
- if( TimingMode<MAX_TIMING_MODE) {;
- TimingMode = fx_to_delayed[TimingMode];
- } else {
- TimingMode = FX_DURATION_JUST_EXPIRED;
- }
-}
-
int EffectQueue::ResolveEffect(EffectRef &effect_reference)
{
ResolveEffectRef(effect_reference);
@@ -1903,14 +2067,23 @@ int EffectQueue::CheckImmunity(Actor *target) const
if( target->ImmuneToProjectile(fx->Projectile)) return 0;
//don't resist item projectile payloads based on spell school, bounce, etc.
- if( fx->InventorySlot) {
- return 1;
- }
+ //FIXME: -Uh, why not ?
+ //Allegedly, the book of infinite spells needed this, but irresistable by level
+ //spells got fx->Power = 0, so i added those exceptions and removed this
+ //if( fx->InventorySlot) {
+ // return 1;
+ //}
//check level resistances
//check specific spell immunity
//check school/sectype immunity
- return check_type(target, fx);
+ int ret = check_type(target, fx);
+ if (ret<0) {
+ if (target->Modified[IE_SANCTUARY]&(1<<OV_BOUNCE) ) {
+ target->Modified[IE_SANCTUARY]|=(1<<OV_BOUNCE2);
+ }
+ }
+ return ret;
}
return 0;
}
@@ -1933,10 +2106,12 @@ void EffectQueue::AffectAllInRange(Map *map, const Point &pos, int idstype, int
continue;
}
//line of sight
- if( !map->IsVisible(actor->Pos, pos)) {
+ if( !map->IsVisibleLOS(actor->Pos, pos)) {
continue;
}
AddAllEffects(actor, actor->Pos);
}
}
+
+}
diff --git a/gemrb/core/EffectQueue.h b/gemrb/core/EffectQueue.h
index 1380c39..65a3213 100644
--- a/gemrb/core/EffectQueue.h
+++ b/gemrb/core/EffectQueue.h
@@ -33,11 +33,15 @@
#include "Effect.h"
#include "Region.h"
+#include <cstdlib>
#include <list>
+namespace GemRB {
+
class Actor;
class Map;
class Scriptable;
+class StringBuffer;
/** Maximum number of different Effect opcodes */
#define MAX_EFFECTS 512
@@ -88,6 +92,9 @@ class Scriptable;
#define IMM_SECTYPE_DEC 0x1000
#define IMM_RESOURCE_DEC 0x2000
+//pst immunities
+#define IMM_GUARDIAN 0x80000000
+
// FIXME: Dice roll should be probably done just once, e.g. when equipping
// the item, not each time the fx are applied
// <avenger> the dice values are actually level limits, except in 3 hp modifier functions
@@ -212,6 +219,8 @@ public:
/* directly removes effects with specified opcode, use effect_reference when you can */
void RemoveAllEffects(ieDword opcode) const;
+
+ /* directly removes effects with specified opcode and resource (used by IWD) */
void RemoveAllEffectsWithResource(ieDword opcode, const ieResRef resource) const;
/* removes any effects (delayed or not) which were using projectile */
@@ -232,6 +241,7 @@ public:
void RemoveAllDetrimentalEffects(EffectRef &effect_reference, ieDword current) const;
void RemoveAllEffectsWithParam(EffectRef &effect_reference, ieDword param2) const;
void RemoveAllEffectsWithResource(EffectRef &effect_reference, const ieResRef resource) const;
+ void RemoveAllEffectsWithParamAndResource(EffectRef &effect_reference, ieDword param2, const ieResRef resource) const;
void RemoveLevelEffects(ieResRef &Removed, ieDword level, ieDword flags, ieDword match) const;
/* returns true if the timing method supports simplified duration */
@@ -261,16 +271,18 @@ public:
Effect *HasEffectWithParam(EffectRef &effect_reference, ieDword param2) const;
Effect *HasEffectWithParamPair(EffectRef &effect_reference, ieDword param1, ieDword param2) const;
Effect *HasEffectWithResource(EffectRef &effect_reference, const ieResRef resource) const;
+ Effect *HasSource(const ieResRef source) const;
Effect *HasEffectWithSource(EffectRef &effect_reference, const ieResRef source) const;
void DecreaseParam1OfEffect(EffectRef &effect_reference, ieDword amount) const;
- int SpecificDamageBonus(ieDword damage_type) const;
+ int DecreaseParam3OfEffect(EffectRef &effect_reference, ieDword amount, ieDword param2) const;
+ //int SpecificDamageBonus(ieDword damage_type) const;
+ int BonusForParam2(EffectRef &effect_reference, ieDword param2) const;
bool HasAnyDispellableEffect() const;
- //transforming timing modes
- static void TransformToDelay(ieByte &TimingMode);
//getting summarised effects
int BonusAgainstCreature(EffectRef &effect_reference, Actor *actor) const;
//getting weapon immunity flag
bool WeaponImmunity(int enchantment, ieDword weapontype) const;
+ int SumDamageReduction(EffectRef &effect_reference, ieDword weaponEnchantment, int &total) const;
//melee and ranged effects
void AddWeaponEffects(EffectQueue *fxqueue, EffectRef &fx_ref) const;
// checks if spells of type "types" are disabled (usually by armor)
@@ -285,6 +297,7 @@ public:
void AffectAllInRange(Map *map, const Point &pos, int idstype, int idsvalue, unsigned int range, Actor *except);
/** Lists contents of the queue on a terminal for debugging */
void dump() const;
+ void dump(StringBuffer&) const;
//resolve effect
static int ResolveEffect(EffectRef &effect_reference);
static bool match_ids(Actor *target, int table, ieDword value);
@@ -299,15 +312,19 @@ private:
static Effect *CreateEffectCopy(Effect *oldfx, ieDword opcode, ieDword param1, ieDword param2);
void RemoveAllDetrimentalEffects(ieDword opcode, ieDword current) const;
void RemoveAllEffectsWithParam(ieDword opcode, ieDword param2) const;
+ void RemoveAllEffectsWithParamAndResource(ieDword opcode, ieDword param2, const ieResRef resource) const;
Effect *HasOpcode(ieDword opcode) const;
Effect *HasOpcodeWithParam(ieDword opcode, ieDword param2) const;
Effect *HasOpcodeWithParamPair(ieDword opcode, ieDword param1, ieDword param2) const;
Effect *HasOpcodeWithResource(ieDword opcode, const ieResRef resource) const;
Effect *HasOpcodeWithSource(ieDword opcode, const ieResRef source) const;
void DecreaseParam1OfEffect(ieDword opcode, ieDword amount) const;
- int SpecificDamageBonus(ieDword opcode, ieDword param2) const;
+ int DecreaseParam3OfEffect(ieDword opcode, ieDword amount, ieDword param2) const;
+ int BonusForParam2(ieDword opcode, ieDword param2) const;
int BonusAgainstCreature(ieDword opcode, Actor *actor) const;
bool WeaponImmunity(ieDword opcode, int enchantment, ieDword weapontype) const;
};
+}
+
#endif // ! EFFECTQUEUE_H
diff --git a/gemrb/core/Factory.cpp b/gemrb/core/Factory.cpp
index 797c4a0..4cef6c4 100644
--- a/gemrb/core/Factory.cpp
+++ b/gemrb/core/Factory.cpp
@@ -24,6 +24,8 @@
#include <cstring>
+namespace GemRB {
+
Factory::Factory(void)
{
}
@@ -63,3 +65,5 @@ void Factory::FreeObjects(void)
delete( fobjects[i] );
}
}
+
+}
diff --git a/gemrb/core/Factory.h b/gemrb/core/Factory.h
index d6c1c09..256a0dd 100644
--- a/gemrb/core/Factory.h
+++ b/gemrb/core/Factory.h
@@ -27,6 +27,8 @@
#include "AnimationFactory.h"
#include "FactoryObject.h"
+namespace GemRB {
+
class GEM_EXPORT Factory {
private:
std::vector< FactoryObject*> fobjects;
@@ -39,4 +41,6 @@ public:
void FreeObjects(void);
};
+}
+
#endif
diff --git a/gemrb/core/FactoryObject.cpp b/gemrb/core/FactoryObject.cpp
index 8c0da9b..787bbbe 100644
--- a/gemrb/core/FactoryObject.cpp
+++ b/gemrb/core/FactoryObject.cpp
@@ -22,6 +22,8 @@
#include "win32def.h"
+namespace GemRB {
+
FactoryObject::FactoryObject(const char* name, SClass_ID SuperClassID)
{
strnlwrcpy( ResRef, name, 8 );
@@ -31,3 +33,5 @@ FactoryObject::FactoryObject(const char* name, SClass_ID SuperClassID)
FactoryObject::~FactoryObject(void)
{
}
+
+}
diff --git a/gemrb/core/FactoryObject.h b/gemrb/core/FactoryObject.h
index a1189c6..7b45a84 100644
--- a/gemrb/core/FactoryObject.h
+++ b/gemrb/core/FactoryObject.h
@@ -24,6 +24,8 @@
#include "exports.h"
#include "globals.h"
+namespace GemRB {
+
class GEM_EXPORT FactoryObject {
public:
SClass_ID SuperClassID;
@@ -32,4 +34,6 @@ public:
virtual ~FactoryObject(void);
};
+}
+
#endif
diff --git a/gemrb/core/FileCache.cpp b/gemrb/core/FileCache.cpp
new file mode 100644
index 0000000..be164d8
--- /dev/null
+++ b/gemrb/core/FileCache.cpp
@@ -0,0 +1,57 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "FileCache.h"
+
+#include "Compressor.h"
+#include "Interface.h"
+#include "PluginMgr.h"
+#include "System/FileStream.h"
+#include "System/VFS.h"
+
+namespace GemRB {
+
+DataStream* CacheCompressedStream(DataStream *stream, const char* filename, int length, bool overwrite)
+{
+ if (!core->IsAvailable(PLUGIN_COMPRESSION_ZLIB)) {
+ Log(ERROR, "FileCache", "No Compression Manager Available. Cannot Load Compressed File.");
+ return NULL;
+ }
+
+ char fname[_MAX_PATH];
+ ExtractFileFromPath(fname, filename);
+ char path[_MAX_PATH];
+ PathJoin(path, core->CachePath, fname, NULL);
+
+ if (overwrite || !file_exists(path)) {
+ FileStream out;
+ if (!out.Create(path)) {
+ Log(ERROR, "FileCache", "Cannot write %s.", path);
+ return NULL;
+ }
+
+ PluginHolder<Compressor> comp(PLUGIN_COMPRESSION_ZLIB);
+ if (comp->Decompress(&out, stream, length) != GEM_OK)
+ return NULL;
+ } else {
+ stream->Seek(length, GEM_CURRENT_POS);
+ }
+ return FileStream::OpenFile(path);
+}
+
+}
diff --git a/gemrb/core/FileCache.h b/gemrb/core/FileCache.h
new file mode 100644
index 0000000..45cb420
--- /dev/null
+++ b/gemrb/core/FileCache.h
@@ -0,0 +1,30 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FILECACHE_H
+#define FILECACHE_H
+
+#include "System/DataStream.h"
+
+namespace GemRB {
+
+GEM_EXPORT DataStream* CacheCompressedStream(DataStream *stream, const char* filename, int length = 0, bool overwrite = false);
+
+}
+
+#endif
diff --git a/gemrb/core/Font.cpp b/gemrb/core/Font.cpp
index 72c7b88..aa29ab5 100644
--- a/gemrb/core/Font.cpp
+++ b/gemrb/core/Font.cpp
@@ -18,9 +18,6 @@
*
*/
-//This class represents game fonts. Fonts are special .bam files.
-//Each cycle stands for a letter.
-
#include "Font.h"
#include "win32def.h"
@@ -28,142 +25,131 @@
#include "GameData.h"
#include "Interface.h"
#include "Palette.h"
+#include "Sprite2D.h"
#include "Video.h"
#include <cassert>
-unsigned int lastX = 0;
-
-#define PARAGRAPH_START_X 5;
+namespace GemRB {
-static const Color black = {0, 0, 0, 0};
+#define SET_BLIT_PALETTE( palette )\
+if (palette != NULL) ((Palette*)palette)->IncRef();\
+if (blitPalette != NULL) blitPalette->Release();\
+blitPalette = palette;
-inline size_t mystrlen(const char* string)
+Font::Font()
+: resRefs(NULL), numResRefs(0), palette(NULL), maxHeight(0)
{
- if (!string) {
- return ( size_t ) 0;
- }
- const char* tmp = string;
- size_t count = 0;
- while (*tmp != 0) {
- if (( ( unsigned char ) * tmp ) >= 0xf0) {
- tmp += 3;
- count += 3;
+ name[0] = '\0';
+ multibyte = false;
+
+ // TODO: list incomplete
+ // maybe want to externalize this
+ // list compiled form wiki: http://www.gemrb.org/wiki/doku.php?id=engine:encodings
+ const char* multibyteEncodings[] = {
+ // Chinese
+ "GBK", "BIG5",
+ // Korean
+ "EUCKR",
+ // Japanese
+ "SJIS"
+ };
+ const size_t listSize = sizeof(multibyteEncodings) / sizeof(multibyteEncodings[0]);
+ const char* encoding = core->TLKEncoding.c_str();
+
+ for (size_t i = 0; i < listSize; i++) {
+ if (stricmp(encoding, multibyteEncodings[i]) == 0) {
+ multibyte = true;
+ break;
}
- count++;
- tmp++;
}
- return count;
-}
-
-Font::Font(int w, int h, Palette* pal)
-{
- lastX = 0;
- count = 0;
- FirstChar = 0;
- sprBuffer = 0;
-
- width = w;
- height = h;
- tmpPixels = (unsigned char*)malloc(width*height);
-
- memset( xPos, 0, sizeof( xPos) );
- memset( yPos, 0, sizeof( yPos) );
-
- pal->IncRef();
- palette = pal;
- maxHeight = h;
}
Font::~Font(void)
{
- Video *video = core->GetVideoDriver();
- gamedata->FreePalette( palette );
- video->FreeSprite( sprBuffer );
+ blank->release();
+ SetPalette(NULL);
+ free(resRefs);
}
-void Font::FinalizeSprite(bool cK, int index)
+bool Font::AddResRef(const ieResRef resref)
{
- sprBuffer = core->GetVideoDriver()->CreateSprite8( width, height, 8, tmpPixels, palette ? palette->col : 0, cK, index );
- tmpPixels = 0;
+ if (resref) {
+ resRefs = (ieResRef*)realloc(resRefs, sizeof(ieResRef) * ++numResRefs);
+ strnlwrcpy( resRefs[numResRefs - 1], resref, sizeof(ieResRef)-1);
+ return true;
+ }
+ return false;
}
-void Font::AddChar(unsigned char* spr, int w, int h, short xPos, short yPos)
+bool Font::MatchesResRef(const ieResRef resref)
{
- if (!spr) {
- size[count].x = 0;
- size[count].y = 0;
- size[count].w = 0;
- size[count].h = 0;
- this->xPos[count] = 0;
- this->yPos[count] = 0;
- count++;
- return;
- }
- unsigned char * currPtr = tmpPixels + lastX;
- unsigned char * srcPtr = ( unsigned char * ) spr;
- for (int y = 0; y < h; y++) {
- memcpy( currPtr, srcPtr, w );
- srcPtr += w;
- currPtr += width;
+ for (int i=0; i < numResRefs; i++)
+ {
+ if (strnicmp( resref, resRefs[i], sizeof(ieResRef)-1) == 0){
+ return true;
+ }
}
- size[count].x = lastX;
- size[count].y = 0;
- size[count].w = w;
- size[count].h = h;
- this->xPos[count] = xPos;
- this->yPos[count] = yPos;
- count++;
- lastX += w;
+ return false;
}
void Font::PrintFromLine(int startrow, Region rgn, const unsigned char* string,
- Palette* hicolor, unsigned char Alignment, Font* initials,
+ Palette* hicolor, ieByte Alignment, Font* initials,
Sprite2D* cursor, unsigned int curpos, bool NoColor) const
{
bool enablecap=false;
int capital = 0;
- if (initials)
+ int initials_rows = 0;
+ int last_initial_row = 0;
+ int initials_x = 0;
+ int initials_row = 0;
+ ieWord currCap = 0;
+ ieWord* tmp = NULL;
+ size_t len = GetDoubleByteString(string, tmp);
+
+ int num_empty_rows = 0;
+
+ if (initials && initials != this)
{
capital=1;
enablecap=true;
+ initials_rows = 1 + ((initials->maxHeight - 1) / maxHeight); // ceiling
+ currCap = string[0];
+ if ((startrow > 0 && initials_rows > 0) || (len > 0 && isspace(currCap))) { // we need to look back to get the cap
+ while(isspace(currCap) && num_empty_rows < (int)len){//we cant cap whiteSpace so keep looking
+ currCap = string[++num_empty_rows];
+ // WARNING: this assumes all preceeding whiteSpace is an empty line
+ }
+ last_initial_row = startrow - 1; // always the row before current since this cannot be the first row
+ initials_rows = initials_rows - (startrow + 1) + num_empty_rows; // startrow + 1 because start row is 0 based, but initials_rows is 1 based
+ }
}
- int initials_rows = 0;
- int initials_x = 0;
- unsigned int psx = PARAGRAPH_START_X;
+ unsigned int psx = IE_FONT_PADDING;
Palette *pal = hicolor;
if (!pal) {
pal = palette;
}
- if (startrow) enablecap=false;
- if (initials==this) {
- enablecap=false;
- }
+ Palette* blitPalette = NULL;
+ SET_BLIT_PALETTE(pal);
+
+ SetupString( tmp, rgn.w, NoColor, initials, enablecap );
- sprBuffer->SetPalette( pal );
- size_t len = strlen( ( char* ) string );
- char* tmp = ( char* ) malloc( len + 1 );
- memcpy( tmp, ( char * ) string, len + 1 );
- SetupString( tmp, rgn.w, NoColor );
- int ystep = 0;
+ if (startrow) enablecap=false;
+ int ystep;
if (Alignment & IE_FONT_SINGLE_LINE) {
- for (size_t i = 0; i < len; i++) {
- int height = yPos[( unsigned char ) tmp[i] - 1];
- if (ystep < height)
- ystep = height;
- }
+ ystep = CalcStringHeight(tmp, len, NoColor);
+ if (!ystep) ystep = maxHeight;
} else {
- ystep = size[1].h;
+ ystep = maxHeight;
}
- if (!ystep) ystep = maxHeight;
int x = psx, y = ystep;
int w = CalcStringWidth( tmp, NoColor );
if (Alignment & IE_FONT_ALIGN_CENTER) {
x = ( rgn.w - w) / 2;
} else if (Alignment & IE_FONT_ALIGN_RIGHT) {
- x = ( rgn.w - w );
+ x = ( rgn.w - w ) - IE_FONT_PADDING;
}
if (Alignment & IE_FONT_ALIGN_MIDDLE) {
int h = 0;
@@ -174,26 +160,28 @@ void Font::PrintFromLine(int startrow, Region rgn, const unsigned char* string,
h = h * ystep;
y += ( rgn.h - h ) / 2;
} else if (Alignment & IE_FONT_ALIGN_BOTTOM) {
- int h = 1;
+ int h = 0;
for (size_t i = 0; i <= len; i++) {
if (( tmp[i] == 0 ) || ( tmp[i] == '\n' ))
h++;
}
h = h * ystep;
- y += ( rgn.h - h );
+ y += ( rgn.h - h ) - IE_FONT_PADDING;
} else if (Alignment & IE_FONT_ALIGN_TOP) {
- y += 5;
+ y += IE_FONT_PADDING;
}
Video* video = core->GetVideoDriver();
+ const Sprite2D* currGlyph;
+ ieWord currChar = '\0';
int row = 0;
for (size_t i = 0; i < len; i++) {
- if (( ( unsigned char ) tmp[i] ) == '[' && !NoColor) {
+ if (( tmp[i] ) == '[' && !NoColor) {
i++;
char tag[256];
tag[0]=0;
- for (int k = 0; k < 256 && i<len; k++) {
+ for (size_t k = 0; k < 256 && i<len; k++) {
if (tmp[i] == ']') {
tag[k] = 0;
break;
@@ -209,28 +197,26 @@ void Font::PrintFromLine(int startrow, Region rgn, const unsigned char* string,
continue;
}
-
if (strnicmp( tag, "color=", 6 ) == 0) {
unsigned int r,g,b;
if (sscanf( tag, "color=%02X%02X%02X", &r, &g, &b ) != 3)
continue;
- const Color c = {(unsigned char) r,(unsigned char)g, (unsigned char)b, 0};
+ const Color c = {(unsigned char)r, (unsigned char)g, (unsigned char)b, 0};
Palette* newPal = core->CreatePalette( c, palette->back );
- sprBuffer->SetPalette( newPal );
+ SET_BLIT_PALETTE(newPal);
gamedata->FreePalette( newPal );
continue;
}
if (stricmp( tag, "/color" ) == 0) {
- sprBuffer->SetPalette( pal );
+ SET_BLIT_PALETTE(pal);
continue;
}
-
if (stricmp( "p", tag ) == 0) {
psx = x;
continue;
}
if (stricmp( "/p", tag ) == 0) {
- psx = PARAGRAPH_START_X;
+ psx = IE_FONT_PADDING;
}
continue;
}
@@ -257,51 +243,72 @@ void Font::PrintFromLine(int startrow, Region rgn, const unsigned char* string,
}
continue;
}
- unsigned char currChar = ( unsigned char ) tmp[i] - 1;
+ currChar = tmp[i];
if (initials && capital && enablecap) {
+ currCap = currChar;
x = initials->PrintInitial( x, y, rgn, currChar );
initials_x = x;
//how many more lines to be indented (one was already indented)
- initials_rows = (initials->maxHeight-1)/maxHeight;
+ initials_rows = (initials->maxHeight - 1) / maxHeight;
+ initials_rows += num_empty_rows;
+ initials_row = row;
+ last_initial_row = initials_row;
+
enablecap = false;
continue;
+ } else if (initials && currCap
+ && row > last_initial_row
+ && (row - num_empty_rows - initials_row) <= ((initials->maxHeight-1)/maxHeight)){
+ // means this row doesnt have a cap, but a preceeding one did and its overlapping this row
+ int initY = y;
+ if (!num_empty_rows || row > num_empty_rows) {// num_empty_rows is for scrolling text areas
+ initY = (y - (maxHeight * (row - initials_row - num_empty_rows)));
+ }
+ x = initials->PrintInitial( x, initY, rgn, currCap );
+ initials_x = x;
+ last_initial_row++;
+ if (num_empty_rows && row <= num_empty_rows) continue;
+ else x += psx;
+ }
+ if (i > 0) {
+ // kerning
+ x -= GetKerningOffset(tmp[i-1], currChar);
}
- video->BlitSpriteRegion( sprBuffer, size[currChar],
- x + rgn.x, y + rgn.y - yPos[currChar], true, &rgn );
+ currGlyph = GetCharSprite(currChar);
+ video->BlitSprite(currGlyph, x + rgn.x, y + rgn.y, true, &rgn, blitPalette);
if (cursor && ( i == curpos )) {
- video->BlitSprite( cursor, x + rgn.x,
- y + rgn.y, true, &rgn );
+ video->BlitSprite( cursor, x + rgn.x, y + rgn.y, true, &rgn );
}
- x += size[currChar].w;
+ x += currGlyph->Width;
}
if (cursor && ( curpos == len )) {
- video->BlitSprite( cursor, x + rgn.x,
- y + rgn.y, true, &rgn );
+ video->BlitSprite( cursor, x + rgn.x, y + rgn.y, true, &rgn );
}
+ SET_BLIT_PALETTE(NULL);
free( tmp );
}
void Font::Print(Region rgn, const unsigned char* string, Palette* hicolor,
- unsigned char Alignment, bool anchor, Font* initials,
+ ieByte Alignment, bool anchor, Font* initials,
Sprite2D* cursor, unsigned int curpos, bool NoColor) const
{
- Print(rgn, rgn, string, hicolor, Alignment, anchor, initials, cursor, curpos, NoColor);
+ Region cliprgn = rgn;
+ if (!anchor) {
+ Region Viewport = core->GetVideoDriver()->GetViewport();
+ cliprgn.x -= Viewport.x;
+ cliprgn.y -= Viewport.y;
+ }
+ Print(cliprgn, rgn, string, hicolor, Alignment, anchor, initials, cursor, curpos, NoColor);
}
void Font::Print(Region cliprgn, Region rgn, const unsigned char* string,
- Palette* hicolor, unsigned char Alignment, bool anchor, Font* initials,
+ Palette* hicolor, ieByte Alignment, bool anchor, Font* initials,
Sprite2D* cursor, unsigned int curpos, bool NoColor) const
{
- bool enablecap=false;
- int capital = 0;
- if (initials)
- {
- capital=1;
- enablecap=true;
- }
+ int capital = (initials) ? 1 : 0;
- unsigned int psx = PARAGRAPH_START_X;
+ unsigned int psx = IE_FONT_PADDING;
Palette* pal = hicolor;
if (!pal) {
pal = palette;
@@ -310,30 +317,25 @@ void Font::Print(Region cliprgn, Region rgn, const unsigned char* string,
initials = NULL;
}
- sprBuffer->SetPalette( pal );
- size_t len = strlen( ( char* ) string );
- char* tmp = ( char* ) malloc( len + 1 );
- memcpy( tmp, ( char * ) string, len + 1 );
+ Palette* blitPalette = NULL;
+ SET_BLIT_PALETTE( pal );
+
+ ieWord* tmp = NULL;
+ size_t len = GetDoubleByteString(string, tmp);
while (len > 0 && (tmp[len - 1] == '\n' || tmp[len - 1] == '\r')) {
// ignore trailing newlines
tmp[len - 1] = 0;
len--;
}
- SetupString( tmp, rgn.w, NoColor );
- int ystep = 0;
+ SetupString( tmp, rgn.w, NoColor, initials, capital );
+ int ystep;
if (Alignment & IE_FONT_SINGLE_LINE) {
-
- for (size_t i = 0; i < len; i++) {
- if (tmp[i] == 0) continue;
- int height = yPos[( unsigned char ) tmp[i] - 1];
- if (ystep < height)
- ystep = height;
- }
+ ystep = CalcStringHeight(tmp, len, NoColor);
+ if (!ystep) ystep = maxHeight;
} else {
- ystep = size[1].h;
+ ystep = maxHeight;
}
- if (!ystep) ystep = maxHeight;
int x = psx, y = ystep;
Video* video = core->GetVideoDriver();
@@ -342,7 +344,7 @@ void Font::Print(Region cliprgn, Region rgn, const unsigned char* string,
x = ( rgn.w - w ) / 2;
} else if (Alignment & IE_FONT_ALIGN_RIGHT) {
int w = CalcStringWidth( tmp, NoColor );
- x = ( rgn.w - w );
+ x = ( rgn.w - w ) - IE_FONT_PADDING;
}
if (Alignment & IE_FONT_ALIGN_MIDDLE) {
@@ -354,22 +356,25 @@ void Font::Print(Region cliprgn, Region rgn, const unsigned char* string,
h = h * ystep;
y += ( rgn.h - h ) / 2;
} else if (Alignment & IE_FONT_ALIGN_BOTTOM) {
- int h = 1;
+ int h = 0;
for (size_t i = 0; i <= len; i++) {
if (tmp[i] == 0)
h++;
}
h = h * ystep;
- y += ( rgn.h - h );
+ y += ( rgn.h - h ) - IE_FONT_PADDING;
} else if (Alignment & IE_FONT_ALIGN_TOP) {
- y += 5;
+ y += IE_FONT_PADDING;
}
+
+ ieWord currChar = '\0';
+ const Sprite2D* currGlyph = NULL;
for (size_t i = 0; i < len; i++) {
- if (( ( unsigned char ) tmp[i] ) == '[' && !NoColor) {
+ if (( tmp[i] ) == '[' && !NoColor) {
i++;
char tag[256];
tag[0]=0;
- for (int k = 0; k < 256 && i<len; k++) {
+ for (size_t k = 0; k < 256 && i<len; k++) {
if (tmp[i] == ']') {
tag[k] = 0;
break;
@@ -379,24 +384,21 @@ void Font::Print(Region cliprgn, Region rgn, const unsigned char* string,
if (strnicmp( tag, "capital=",8)==0) {
sscanf( tag, "capital=%d", &capital);
- if (capital) {
- enablecap=true;
- }
continue;
}
-
+
if (strnicmp( tag, "color=", 6 ) == 0) {
unsigned int r,g,b;
if (sscanf( tag, "color=%02X%02X%02X", &r, &g, &b ) != 3)
continue;
- const Color c = {(unsigned char) r,(unsigned char) g,(unsigned char) b, 0};
+ const Color c = {(unsigned char)r, (unsigned char)g, (unsigned char)b, 0};
Palette* newPal = core->CreatePalette( c, palette->back );
- sprBuffer->SetPalette( newPal );
+ SET_BLIT_PALETTE(newPal);
gamedata->FreePalette( newPal );
continue;
}
if (stricmp( tag, "/color" ) == 0) {
- sprBuffer->SetPalette( pal );
+ SET_BLIT_PALETTE(pal);
continue;
}
if (stricmp( "p", tag ) == 0) {
@@ -404,7 +406,7 @@ void Font::Print(Region cliprgn, Region rgn, const unsigned char* string,
continue;
}
if (stricmp( "/p", tag ) == 0) {
- psx = PARAGRAPH_START_X;
+ psx = IE_FONT_PADDING;
continue;
}
continue;
@@ -421,72 +423,107 @@ void Font::Print(Region cliprgn, Region rgn, const unsigned char* string,
}
continue;
}
- unsigned char currChar = ( unsigned char ) tmp[i] - 1;
+ currChar = tmp[i];
+ currGlyph = GetCharSprite(currChar);
if (initials && capital) {
x = initials->PrintInitial( x, y, rgn, currChar );
- enablecap=false;
continue;
}
- video->BlitSpriteRegion( sprBuffer, size[currChar],
- x + rgn.x, y + rgn.y - yPos[currChar],
- anchor, &cliprgn );
+
+ if (i > 0) {
+ // kerning
+ x -= GetKerningOffset(tmp[i-1], currChar);
+ }
+
+ video->BlitSprite(currGlyph, x + rgn.x, y + rgn.y, anchor, &cliprgn, blitPalette);
+
if (cursor && ( curpos == i ))
video->BlitSprite( cursor, x + rgn.x, y + rgn.y, anchor, &cliprgn );
- x += size[currChar].w;
+ x += currGlyph->Width;
}
if (cursor && ( curpos == len )) {
video->BlitSprite( cursor, x + rgn.x, y + rgn.y, anchor, &cliprgn );
}
+ SET_BLIT_PALETTE(NULL);
free( tmp );
}
-int Font::PrintInitial(int x, int y, const Region &rgn, unsigned char currChar) const
+int Font::PrintInitial(int x, int y, const Region &rgn, ieWord currChar) const
{
- Video *video = core->GetVideoDriver();
- video->BlitSpriteRegion( sprBuffer, size[currChar],
- x + rgn.x, y + rgn.y - yPos[currChar], true, &rgn );
- x += size[currChar].w;
+ const Sprite2D* glyph = GetCharSprite(currChar);
+ core->GetVideoDriver()->BlitSprite(glyph, x + rgn.x, y + rgn.y, true, &rgn);
+
+ x += glyph->Width;
return x;
}
-int Font::CalcStringWidth(const char* string, bool NoColor) const
+int Font::CalcStringWidth(const unsigned char* string, bool NoColor) const
{
- size_t ret = 0, len = strlen( string );
+ ieWord* tmp = NULL;
+ GetDoubleByteString(string, tmp);
+ int width = CalcStringWidth(tmp, NoColor);
+ free(tmp);
+ return width;
+}
+
+int Font::CalcStringWidth(const ieWord* string, bool NoColor) const
+{
+ size_t ret = 0, len = dbStrLen(string);
for (size_t i = 0; i < len; i++) {
- if (( ( unsigned char ) string[i] ) == '[' && !NoColor) {
- i++;
- if (i>=len)
- break;
- char tag[256];
- int k = 0;
- for (k = 0; k < 256; k++) {
- if (string[i] == ']') {
- tag[k] = 0;
- break;
- }
- tag[k] = string[i++];
+ if (( string[i] ) == '[' && !NoColor) {
+ i++; // cannot be ']' when it is '['
+ while(i<len && (string[i]) != ']') {
+ i++;
}
- continue;
+ } else {
+ ret += GetCharSprite(string[i])->Width;
}
- ret += size[( unsigned char ) string[i] - 1].w;
}
return ( int ) ret;
}
-void Font::SetupString(char* string, unsigned int width, bool NoColor) const
+int Font::CalcStringHeight(const ieWord* string, unsigned int len, bool NoColor) const
+{
+ int h, max = 0;
+ for (unsigned int i = 0; i < len; i++) {
+ if (( string[i] ) == '[' && !NoColor) {
+ i++; // cannot be ']' when it is '['
+ while(i<len && (string[i]) != ']') {
+ i++;
+ }
+ } else {
+ h = GetCharSprite(string[i])->Height;
+ //the space check is here to hack around overly high frames
+ //in some bg1 fonts that throw vertical alignment off
+ if (h > max && string[i] != ' ') {
+ max = h;
+ }
+ }
+ }
+ return max;
+}
+
+void Font::SetupString(ieWord* string, unsigned int width, bool NoColor, Font *initials, bool enablecap) const
{
- size_t len = strlen( string );
- unsigned int psx = PARAGRAPH_START_X;
+ size_t len = dbStrLen(string);
+ unsigned int psx = IE_FONT_PADDING;
int lastpos = 0;
unsigned int x = psx, wx = 0;
bool endword = false;
+ int initials_rows = 0;
+ int initials_x = 0;
for (size_t pos = 0; pos < len; pos++) {
if (x + wx > width) {
+ // we wrapped, force a new line somewhere
if (!endword && ( x == psx ))
lastpos = ( int ) pos;
else
string[lastpos] = 0;
x = psx;
+ if (initials_rows > 0) {
+ initials_rows--;
+ x += initials_x;
+ }
}
if (string[pos] == 0) {
continue;
@@ -495,14 +532,19 @@ void Font::SetupString(char* string, unsigned int width, bool NoColor) const
if (string[pos] == '\r')
string[pos] = ' ';
if (string[pos] == '\n') {
+ // force a new line here
string[pos] = 0;
x = psx;
wx = 0;
+ if (initials_rows > 0) {
+ initials_rows--;
+ x += initials_x;
+ }
lastpos = ( int ) pos;
endword = true;
continue;
}
- if (( ( unsigned char ) string[pos] ) == '[' && !NoColor) {
+ if (( string[pos] ) == '[' && !NoColor) {
pos++;
if (pos>=len)
break;
@@ -515,22 +557,35 @@ void Font::SetupString(char* string, unsigned int width, bool NoColor) const
}
tag[k] = string[pos++];
}
+ if (strnicmp( tag, "capital=",8)==0) {
+ int capital = 0;
+ sscanf( tag, "capital=%d", &capital);
+ if (capital) {
+ enablecap=true;
+ }
+ continue;
+ }
if (stricmp( "p", tag ) == 0) {
psx = x;
continue;
}
if (stricmp( "/p", tag ) == 0) {
- psx = PARAGRAPH_START_X;
+ psx = IE_FONT_PADDING;
continue;
}
continue;
}
- if (string[pos] && string[pos] != ' ') {
- string[pos] = ( unsigned char ) (string[pos] - FirstChar);
+ if (initials && enablecap) {
+ wx += initials->GetCharSprite(string[pos])->Width;
+ enablecap=false;
+ initials_x = wx + psx;
+ //how many more lines to be indented (one was already indented)
+ initials_rows = (initials->maxHeight - 1) / maxHeight;
+ continue;
+ } else {
+ wx += GetCharSprite(string[pos])->Width;
}
-
- wx += size[( unsigned char ) string[pos] - 1].w;
if (( string[pos] == ' ' ) || ( string[pos] == '-' )) {
x += wx;
wx = 0;
@@ -540,6 +595,42 @@ void Font::SetupString(char* string, unsigned int width, bool NoColor) const
}
}
+size_t Font::GetDoubleByteString(const unsigned char* string, ieWord* &dbString) const
+{
+ size_t len = strlen((char*)string);
+ dbString = (ieWord*)malloc((len+1) * sizeof(ieWord));
+ size_t dbLen = 0;
+ for(size_t i=0; i<len; ++i)
+ {
+ // we are assuming that every multibyte encoding uses single bytes for chars 32 - 127
+ if( multibyte && (i+1 < len) && (string[i] >= 128 || string[i] < 32)) { // this is a double byte char
+ dbString[dbLen] = (string[i+1] << 8) + string[i];
+ ++i;
+ } else
+ dbString[dbLen] = string[i];
+ assert(dbString[dbLen] != 0);
+ ++dbLen;
+ }
+ dbString[dbLen] = '\0';
+
+ // we dont always use everything we allocated.
+ // realloc in this case to avoid static anylizer warnings about "garbage values"
+ // since this realloc always truncates it *should* be quick
+ dbString = (ieWord*)realloc(dbString, (dbLen+1) * sizeof(ieWord));
+
+ return dbLen;
+}
+
+void Font::SetName(const char* newName)
+{
+ strnlwrcpy( name, newName, sizeof(name)-1);
+
+ if (strnicmp(name, "STATES", 6) == 0) {
+ // state fonts are NEVER multibyte; regardless of TKL encoding.
+ multibyte = false;
+ }
+}
+
Palette* Font::GetPalette() const
{
assert(palette);
@@ -549,12 +640,19 @@ Palette* Font::GetPalette() const
void Font::SetPalette(Palette* pal)
{
+ if (pal) pal->IncRef();
if (palette) palette->Release();
- pal->IncRef();
palette = pal;
}
-void Font::SetFirstChar( unsigned char first)
+int Font::dbStrLen(const ieWord* string) const
{
- FirstChar = first;
+ if (string == NULL) return 0;
+ int count = 0;
+ for ( ; string[count] != 0; count++)
+ continue; // intentionally empty loop
+ return count;
+}
+
+#undef SET_BLIT_PALETTE
}
diff --git a/gemrb/core/Font.h b/gemrb/core/Font.h
index 240bdf4..82873b4 100644
--- a/gemrb/core/Font.h
+++ b/gemrb/core/Font.h
@@ -32,18 +32,18 @@
#include <vector>
-class Palette;
+namespace GemRB {
-struct StringList {
- Sprite2D*** strings;
- unsigned int* heights;
- unsigned int* lengths;
- int StringCount;
- int starty;
- int curx;
- int cury;
+enum FontStyle {
+ NORMAL = 0x00,
+ BOLD = 0x01,
+ ITALIC = 0x02,
+ UNDERLINE = 0x04
};
+class Palette;
+class Sprite2D;
+
#define IE_FONT_ALIGN_LEFT 0x00
#define IE_FONT_ALIGN_CENTER 0x01
#define IE_FONT_ALIGN_RIGHT 0x02
@@ -52,60 +52,74 @@ struct StringList {
#define IE_FONT_ALIGN_MIDDLE 0x20 //Only for single line Text
#define IE_FONT_SINGLE_LINE 0x40
+#define IE_FONT_PADDING 5
+
/**
* @class Font
* Class for using and manipulating images serving as fonts
*/
class GEM_EXPORT Font {
-private:
- int count;
+protected:
+ ieResRef* resRefs;
+ int numResRefs;
+ char name[20];
+
Palette* palette;
- Sprite2D* sprBuffer;
- unsigned char FirstChar;
+ Sprite2D* blank;
- short xPos[256];
- short yPos[256];
+ bool multibyte;
- // For the temporary bitmap
- unsigned char* tmpPixels;
- unsigned int width, height;
public:
- /** ResRef of the Font image */
- ieResRef ResRef;
int maxHeight;
- Region size[256];
+
public:
- Font(int w, int h, Palette* palette);
- ~Font(void);
- void AddChar(unsigned char* spr, int w, int h, short xPos, short yPos);
- /** Call this after adding all characters */
- void FinalizeSprite(bool cK, int index);
+ Font();
+ virtual ~Font(void);
+
+ //allow reading but not setting glyphs
+ virtual const Sprite2D* GetCharSprite(ieWord chr) const = 0;
+
+ bool AddResRef(const ieResRef resref);
+ bool MatchesResRef(const ieResRef resref);
+ const char* GetName() const {return name;};
+ void SetName(const char* newName);
+
+ virtual ieWord GetPointSize() const {return 0;};
+ virtual FontStyle GetStyle() const {return NORMAL;};
+
+ Palette* GetPalette() const;
+ void SetPalette(Palette* pal);
+
+ // Printing methods
void Print(Region cliprgn, Region rgn, const unsigned char* string,
- Palette* color, unsigned char Alignment, bool anchor = false,
+ Palette* color, ieByte Alignment, bool anchor = false,
Font* initials = NULL, Sprite2D* cursor = NULL,
unsigned int curpos = 0, bool NoColor = false) const;
void Print(Region rgn, const unsigned char* string, Palette* color,
- unsigned char Alignment, bool anchor = false,
+ ieByte Alignment, bool anchor = false,
Font* initials = NULL, Sprite2D* cursor = NULL,
unsigned int curpos = 0, bool NoColor = false) const;
void PrintFromLine(int startrow, Region rgn, const unsigned char* string,
- Palette* color, unsigned char Alignment,
+ Palette* color, ieByte Alignment,
Font* initials = NULL, Sprite2D* cursor = NULL,
unsigned int curpos = 0, bool NoColor = false) const;
- Palette* GetPalette() const;
- void SetPalette(Palette* pal);
/** Returns width of the string rendered in this font in pixels */
- int CalcStringWidth(const char* string, bool NoColor = false) const;
- void SetupString(char* string, unsigned int width, bool NoColor = false) const;
- /** Sets ASCII code of the first character in the font.
- * (it allows remapping numeric fonts from \000 to '0') */
- void SetFirstChar(unsigned char first);
+ int CalcStringWidth(const unsigned char* string, bool NoColor = false) const;
+ void SetupString(ieWord* string, unsigned int width, bool NoColor = false, Font *initials = NULL, bool enablecap = false) const;
+ size_t GetDoubleByteString(const unsigned char* string, ieWord* &dbString) const;
+protected:
+ virtual int GetKerningOffset(ieWord /*leftChr*/, ieWord /*rightChr*/) const {return 0;};
private:
- int PrintInitial(int x, int y, const Region &rgn, unsigned char currChar) const;
+ int PrintInitial(int x, int y, const Region &rgn, ieWord currChar) const;
+ int CalcStringWidth(const ieWord* string, bool NoColor = false) const;
+ int CalcStringHeight(const ieWord* string, unsigned int len, bool NoColor) const;
+ int dbStrLen(const ieWord* string) const;
};
+}
+
#endif
diff --git a/gemrb/core/FontManager.cpp b/gemrb/core/FontManager.cpp
new file mode 100644
index 0000000..2eb9ecf
--- /dev/null
+++ b/gemrb/core/FontManager.cpp
@@ -0,0 +1,37 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "FontManager.h"
+
+namespace GemRB {
+
+const TypeID FontManager::ID = { "FontMgr" };
+
+FontManager::FontManager(void)
+{
+
+}
+
+FontManager::~FontManager(void)
+{
+
+}
+
+}
diff --git a/gemrb/core/FontManager.h b/gemrb/core/FontManager.h
new file mode 100644
index 0000000..00ea545
--- /dev/null
+++ b/gemrb/core/FontManager.h
@@ -0,0 +1,58 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef GemRB_FontManager_h
+#define GemRB_FontManager_h
+
+#include "TypeID.h"
+#include "Resource.h"
+#include "exports.h"
+#include "Font.h"
+
+namespace GemRB {
+
+class GEM_EXPORT FontManager : public Resource {
+private:
+ /*
+ private data members
+ */
+public:
+ /*
+ Public data members
+ */
+ static const TypeID ID;
+private:
+ /*
+ Private methods
+ */
+public:
+ /*
+ Public methods
+ */
+ FontManager(void);
+ virtual ~FontManager(void);
+
+ virtual Font* GetFont(unsigned short ptSize,
+ FontStyle style, Palette* pal = NULL) = 0;
+};
+
+}
+
+#endif
diff --git a/gemrb/core/GUI/Button.cpp b/gemrb/core/GUI/Button.cpp
index 941cdd4..11a25ba 100644
--- a/gemrb/core/GUI/Button.cpp
+++ b/gemrb/core/GUI/Button.cpp
@@ -21,9 +21,13 @@
#include "GUI/Button.h"
#include "GUI/GameControl.h"
+#include "GUI/EventMgr.h"
+#include "GUI/ScrollBar.h"
+#include "GUI/Window.h"
-#include "defsounds.h"
#include "win32def.h"
+#include "defsounds.h"
+#include "ie_cursors.h"
#include "GameData.h"
#include "Interface.h"
@@ -31,6 +35,8 @@
#include "Variables.h"
#include "Video.h"
+namespace GemRB {
+
Button::Button()
{
Unpressed = Pressed = Selected = Disabled = NULL;
@@ -64,6 +70,7 @@ Button::Button()
memset( borders, 0, sizeof( borders ));
starttime = 0;
Anchor.null();
+ PushOffset = Point(2, 2);
}
Button::~Button()
{
@@ -96,7 +103,7 @@ void Button::SetImage(unsigned char type, Sprite2D* img)
Unpressed = img;
break;
- case IE_GUI_BUTTON_SECOND:
+ case IE_GUI_BUTTON_FAKEPRESSED:
case IE_GUI_BUTTON_PRESSED:
core->GetVideoDriver()->FreeSprite( Pressed );
Pressed = img;
@@ -108,7 +115,7 @@ void Button::SetImage(unsigned char type, Sprite2D* img)
break;
case IE_GUI_BUTTON_DISABLED:
- case IE_GUI_BUTTON_THIRD:
+ case IE_GUI_BUTTON_FAKEDISABLED:
core->GetVideoDriver()->FreeSprite( Disabled );
Disabled = img;
break;
@@ -125,21 +132,27 @@ void Button::CloseUpColor()
unsigned long newtime;
Changed = true;
- GetTime( newtime );
+ newtime = GetTickCount();
if (newtime<starttime) {
return;
}
- SourceRGB.r = (SourceRGB.r + DestRGB.r) / 2;
- SourceRGB.g = (SourceRGB.g + DestRGB.g) / 2;
- SourceRGB.b = (SourceRGB.b + DestRGB.b) / 2;
- SourceRGB.a = (SourceRGB.a + DestRGB.a) / 2;
- if (SourceRGB.r == DestRGB.r &&
- SourceRGB.g == DestRGB.g &&
- SourceRGB.b == DestRGB.b &&
- SourceRGB.a == DestRGB.a) {
+
+ Color nc;
+
+ nc.r = (SourceRGB.r + DestRGB.r) / 2;
+ nc.g = (SourceRGB.g + DestRGB.g) / 2;
+ nc.b = (SourceRGB.b + DestRGB.b) / 2;
+ nc.a = (SourceRGB.a + DestRGB.a) / 2;
+ if (SourceRGB.r == nc.r &&
+ SourceRGB.g == nc.g &&
+ SourceRGB.b == nc.b &&
+ SourceRGB.a == nc.a) {
+ SourceRGB = DestRGB;
starttime = 0;
return;
}
+
+ SourceRGB = nc;
starttime = newtime + 40;
}
@@ -167,7 +180,7 @@ void Button::Draw(unsigned short x, unsigned short y)
Image = Unpressed;
break;
- case IE_GUI_BUTTON_SECOND:
+ case IE_GUI_BUTTON_FAKEPRESSED:
case IE_GUI_BUTTON_PRESSED:
Image = Pressed;
if (! Image)
@@ -181,7 +194,7 @@ void Button::Draw(unsigned short x, unsigned short y)
break;
case IE_GUI_BUTTON_DISABLED:
- case IE_GUI_BUTTON_THIRD:
+ case IE_GUI_BUTTON_FAKEDISABLED:
Image = Disabled;
if (! Image)
Image = Unpressed;
@@ -198,28 +211,56 @@ void Button::Draw(unsigned short x, unsigned short y)
if (State == IE_GUI_BUTTON_PRESSED) {
//shift the writing/border a bit
- x+= 2;
- y+= 2;
+ x+= PushOffset.x;
+ y+= PushOffset.y;
}
// Button picture
+ if (AnimPicture) {
+ int xOffs = ( Width / 2 ) - ( AnimPicture->Width / 2 );
+ int yOffs = ( Height / 2 ) - ( AnimPicture->Height / 2 );
+ Region r( x + XPos + xOffs, y + YPos + yOffs, (int)(AnimPicture->Width * Clipping), AnimPicture->Height );
+
+ if (Flags & IE_GUI_BUTTON_CENTER_PICTURES) {
+ video->BlitSprite( AnimPicture, x + XPos + xOffs + AnimPicture->XPos, y + YPos + yOffs + AnimPicture->YPos, true, &r );
+ } else {
+ video->BlitSprite( AnimPicture, x + XPos + xOffs, y + YPos + yOffs, true, &r );
+ }
+ }
+
+ // Button picture
+ int picXPos = 0, picYPos = 0;
if (Picture && (Flags & IE_GUI_BUTTON_PICTURE) ) {
// Picture is drawn centered
- int xOffs = ( Width / 2 ) - ( Picture->Width / 2 );
- int yOffs = ( Height / 2 ) - ( Picture->Height / 2 );
+ picXPos = ( Width / 2 ) - ( Picture->Width / 2 ) + x + XPos;
+ picYPos = ( Height / 2 ) - ( Picture->Height / 2 ) + y + YPos;
if (Flags & IE_GUI_BUTTON_HORIZONTAL) {
- xOffs += x + XPos + Picture->XPos;
- yOffs += y + YPos + Picture->YPos;
- video->BlitSprite( Picture, xOffs, yOffs, true );
- Region r = Region( xOffs, yOffs + (int) (Picture->Height * Clipping), Picture->Width, (int) (Picture->Height*(1.0 - Clipping)) );
- video->DrawRect( r, SourceRGB, true );
+ picXPos += Picture->XPos;
+ picYPos += Picture->YPos;
+
+ // Clipping: 0 = overlay over full button, 1 = no overlay
+ int overlayHeight = Picture->Height * (1.0 - Clipping);
+ if (overlayHeight < 0)
+ overlayHeight = 0;
+ if (overlayHeight >= Picture->Height)
+ overlayHeight = Picture->Height;
+ int buttonHeight = Picture->Height - overlayHeight;
+
+ Region rb = Region(picXPos, picYPos, Picture->Width, buttonHeight);
+ Region ro = Region(picXPos, picYPos + buttonHeight, Picture->Width, overlayHeight);
+
+ video->BlitSprite( Picture, picXPos, picYPos, true, &rb );
+
+ // TODO: Add an option to add BLIT_GREY to the flags
+ video->BlitGameSprite( Picture, picXPos, picYPos, BLIT_TINTED, SourceRGB, 0, 0, &ro, true);
+
// do NOT uncomment this, you can't change Changed or invalidate things from
// the middle of Window::DrawWindow() -- it needs moving to somewhere else
//CloseUpColor();
}
else {
- Region r( x + XPos + xOffs, y + YPos + yOffs, (int)(Picture->Width * Clipping), Picture->Height );
- video->BlitSprite( Picture, x + XPos + xOffs + Picture->XPos, y + YPos + yOffs + Picture->YPos, true, &r );
+ Region r( picXPos, picYPos, (int)(Picture->Width * Clipping), Picture->Height );
+ video->BlitSprite( Picture, picXPos + Picture->XPos, picYPos + Picture->YPos, true, &r );
}
}
@@ -246,19 +287,6 @@ void Button::Draw(unsigned short x, unsigned short y)
}
}
- // Button picture
- if (AnimPicture) {
- int xOffs = ( Width / 2 ) - ( AnimPicture->Width / 2 );
- int yOffs = ( Height / 2 ) - ( AnimPicture->Height / 2 );
- Region r( x + XPos + xOffs, y + YPos + yOffs, (int)(AnimPicture->Width * Clipping), AnimPicture->Height );
-
- if (Flags & IE_GUI_BUTTON_CENTER_PICTURES) {
- video->BlitSprite( AnimPicture, x + XPos + xOffs + AnimPicture->XPos, y + YPos + yOffs + AnimPicture->YPos, true, &r );
- } else {
- video->BlitSprite( AnimPicture, x + XPos + xOffs, y + YPos + yOffs, true, &r );
- }
- }
-
// Button label
if (hasText && ! ( Flags & IE_GUI_BUTTON_NO_TEXT )) {
Palette* ppoi = normal_palette;
@@ -287,9 +315,18 @@ void Button::Draw(unsigned short x, unsigned short y)
if (! (Flags & IE_GUI_BUTTON_MULTILINE)) {
align |= IE_FONT_SINGLE_LINE;
}
- font->Print( Region( x + XPos, y + YPos, Width - 2, Height - 2),
- ( unsigned char * ) Text, ppoi,
- (ieByte) align, true );
+
+ Region r;
+ if (Picture && (Flags & IE_GUI_BUTTON_PORTRAIT) == IE_GUI_BUTTON_PORTRAIT) {
+ // constrain the label (status icons) to the picture bounds
+ // we are subtracting IE_FONT_PADDING because Font indents 5px, but we dont want that here
+ r = Region(picXPos - IE_FONT_PADDING, picYPos + IE_FONT_PADDING,
+ Picture->Width + IE_FONT_PADDING, Picture->Height);
+ } else {
+ r = Region( x + XPos, y + YPos, Width - 2, Height - 2);
+ }
+
+ font->Print( r, ( unsigned char * ) Text, ppoi, (ieByte) align, true );
}
if (! (Flags&IE_GUI_BUTTON_NO_IMAGE)) {
@@ -345,23 +382,23 @@ void Button::SetFont(Font* newfont)
font = newfont;
}
/** Handling The default button (enter) */
-void Button::OnSpecialKeyPress(unsigned char Key)
+bool Button::OnSpecialKeyPress(unsigned char Key)
{
if (State != IE_GUI_BUTTON_DISABLED && State != IE_GUI_BUTTON_LOCKED) {
if (Key == GEM_RETURN) {
if (Flags & IE_GUI_BUTTON_DEFAULT ) {
RunEventHandler( ButtonOnPress );
- return;
+ return true;
}
}
else if (Key == GEM_ESCAPE) {
if (Flags & IE_GUI_BUTTON_CANCEL ) {
RunEventHandler( ButtonOnPress );
- return;
+ return true;
}
}
}
- Control::OnSpecialKeyPress(Key);
+ return Control::OnSpecialKeyPress(Key);
}
/** Mouse Button Down */
@@ -404,19 +441,16 @@ void Button::OnMouseDown(unsigned short x, unsigned short y,
}
if ((Button & GEM_MB_DOUBLECLICK) && ButtonOnDoublePress) {
RunEventHandler( ButtonOnDoublePress );
- printMessage("Button","Doubleclick detected\n",GREEN);
}
break;
case GEM_MB_SCRLUP:
if (scrlbr) {
scrlbr->ScrollUp();
- core->RedrawAll();
}
break;
case GEM_MB_SCRLDOWN:
if (scrlbr) {
scrlbr->ScrollDown();
- core->RedrawAll();
}
break;
}
@@ -504,6 +538,21 @@ void Button::OnMouseUp(unsigned short x, unsigned short y,
}
}
+void Button::OnMouseWheelScroll(short x, short y)
+{
+ ScrollBar* scrlbr = (ScrollBar*) sb;
+ if (!scrlbr) {
+ Control *ctrl = Owner->GetScrollControl();
+ if (ctrl && (ctrl->ControlType == IE_GUI_SCROLLBAR)) {
+ scrlbr = (ScrollBar *) ctrl;
+ }
+ }
+
+ if (scrlbr) {
+ scrlbr->OnMouseWheelScroll(x, y);
+ }
+}
+
void Button::OnMouseOver(unsigned short x, unsigned short y)
{
Owner->Cursor = IE_CURSOR_NORMAL;
@@ -511,7 +560,7 @@ void Button::OnMouseOver(unsigned short x, unsigned short y)
return;
}
- if ( RunEventHandler( MouseOverButton )) {
+ if ( RunEventHandler( MouseOverButton )<0) {
//event handler destructed this object
return;
}
@@ -572,7 +621,7 @@ void Button::OnMouseLeave(unsigned short /*x*/, unsigned short /*y*/)
/** Sets the Text of the current control */
-int Button::SetText(const char* string, int /*pos*/)
+void Button::SetText(const char* string)
{
free(Text);
Text = NULL;
@@ -583,13 +632,12 @@ int Button::SetText(const char* string, int /*pos*/)
} else {
Text = strndup( string, 255 );
if (Flags&IE_GUI_BUTTON_LOWERCASE)
- strlwr( Text );
+ strtolower( Text );
else if (Flags&IE_GUI_BUTTON_CAPS)
- strupr( Text );
+ strtoupper( Text );
hasText = true;
}
Changed = true;
- return 0;
}
/** Set Event Handler */
@@ -635,8 +683,8 @@ bool Button::SetEvent(int eventType, EventHandler handler)
return true;
}
-/** Redraws a button from a given radio button group */
-void Button::RedrawButton(const char* VariableName, unsigned int Sum)
+/** Refresh a button from a given radio button group */
+void Button::UpdateState(const char* VariableName, unsigned int Sum)
{
if (strnicmp( VarName, VariableName, MAX_VARIABLE_LENGTH )) {
return;
@@ -696,7 +744,9 @@ bool Button::IsPixelTransparent(unsigned short x, unsigned short y)
// some buttons have hollow Image frame filled w/ Picture
// some buttons in BG2 are text only (if BAM == 'GUICTRL')
if (Picture || PictureList.size() || ! Unpressed) return false;
- return Unpressed->IsPixelTransparent(x, y);
+ int xOffs = ( Width / 2 ) - ( Unpressed->Width / 2 );
+ int yOffs = ( Height / 2 ) - ( Unpressed->Height / 2 );
+ return Unpressed->IsPixelTransparent(x - xOffs, y - yOffs);
}
// Set palette used for drawing button label in normal state
@@ -707,14 +757,21 @@ void Button::SetTextColor(const Color &fore, const Color &back)
Changed = true;
}
-void Button::SetHorizontalOverlay(double clip, const Color &src, const Color &dest)
+void Button::SetHorizontalOverlay(double clip, const Color &/*src*/, const Color &dest)
{
if ((Clipping>clip) || !(Flags&IE_GUI_BUTTON_HORIZONTAL) ) {
Flags |= IE_GUI_BUTTON_HORIZONTAL;
+#if 0
+ // FIXME: This doesn't work while CloseUpColor isn't being called
+ // (see Draw)
SourceRGB=src;
DestRGB=dest;
- GetTime( starttime );
+ starttime = GetTickCount();
starttime += 40;
+#else
+ SourceRGB = DestRGB = dest;
+ starttime = 0;
+#endif
}
Clipping = clip;
Changed = true;
@@ -724,3 +781,10 @@ void Button::SetAnchor(ieWord x, ieWord y)
{
Anchor = Point(x,y);
}
+
+void Button::SetPushOffset(ieWord x, ieWord y)
+{
+ PushOffset = Point(x,y);
+}
+
+}
diff --git a/gemrb/core/GUI/Button.h b/gemrb/core/GUI/Button.h
index 1ae3d91..f63cc94 100644
--- a/gemrb/core/GUI/Button.h
+++ b/gemrb/core/GUI/Button.h
@@ -37,6 +37,8 @@
#include <list>
+namespace GemRB {
+
class Palette;
// NOTE: keep these synchronized with GUIDefines.py!!!
@@ -47,14 +49,14 @@ class Palette;
// Like DISABLED, but processes MouseOver events and draws UNPRESSED bitmap
#define IE_GUI_BUTTON_LOCKED 4
// Draws the disabled bitmap, but otherwise works like unpressed
-#define IE_GUI_BUTTON_THIRD 5
-#define IE_GUI_BUTTON_SECOND 6
+#define IE_GUI_BUTTON_FAKEDISABLED 5
+#define IE_GUI_BUTTON_FAKEPRESSED 6
#define IE_GUI_BUTTON_LOCKED_PRESSED 7 //all the same as LOCKED
#define IE_GUI_BUTTON_NO_IMAGE 0x00000001 // don't draw image (BAM)
#define IE_GUI_BUTTON_PICTURE 0x00000002 // draw picture (BMP, MOS, ...)
#define IE_GUI_BUTTON_SOUND 0x00000004
-#define IE_GUI_BUTTON_ALT_SOUND 0x00000008
+#define IE_GUI_BUTTON_CAPS 0x00000008 // convert text to uppercase
#define IE_GUI_BUTTON_CHECKBOX 0x00000010 // or radio button
#define IE_GUI_BUTTON_RADIOBUTTON 0x00000020 // sticks in a state
#define IE_GUI_BUTTON_DEFAULT 0x00000040 // enter key triggers it
@@ -73,12 +75,14 @@ class Palette;
#define IE_GUI_BUTTON_NO_TEXT 0x00010000 // don't draw button label
#define IE_GUI_BUTTON_PLAYRANDOM 0x00020000
#define IE_GUI_BUTTON_PLAYONCE 0x00040000
+#define IE_GUI_BUTTON_PLAYALWAYS 0x00080000 // play even when game is paused
-#define IE_GUI_BUTTON_CENTER_PICTURES 0x00080000 // center button's PictureList
-#define IE_GUI_BUTTON_BG1_PAPERDOLL 0x00100000 // BG1-style paperdoll PictureList
-#define IE_GUI_BUTTON_HORIZONTAL 0x00200000 // horizontal clipping of overlay
-#define IE_GUI_BUTTON_CANCEL 0x00400000 // cancel key triggers it
-#define IE_GUI_BUTTON_CAPS 0x00800000 // convert text to uppercase
+#define IE_GUI_BUTTON_CENTER_PICTURES 0x00100000 // center button's PictureList
+#define IE_GUI_BUTTON_BG1_PAPERDOLL 0x00200000 // BG1-style paperdoll PictureList
+#define IE_GUI_BUTTON_HORIZONTAL 0x00400000 // horizontal clipping of overlay
+#define IE_GUI_BUTTON_CANCEL 0x00800000 // cancel key triggers it
+//WARNING: we cannot add any more flags here
+//the top 8 bits are reserved for the control ID (see setFlags)
//composite button flags
#define IE_GUI_BUTTON_NORMAL 0x00000004 // default button, doesn't stick
@@ -133,7 +137,7 @@ public:
/** Sets the Button State */
void SetState(unsigned char state);
/** Sets the Text of the current control */
- int SetText(const char* string, int pos = 0);
+ void SetText(const char* string);
/** Sets the Picture */
void SetPicture(Sprite2D* Picture);
/** Clears the list of Pictures */
@@ -160,9 +164,11 @@ public: // Public Events
unsigned short Mod);
/** Mouse Button Up */
void OnMouseUp(unsigned short x, unsigned short y, unsigned short Button,
- unsigned short Mod);
+ unsigned short Mod);
+ /** Mouse wheel scroll */
+ void OnMouseWheelScroll(short x, short y);
/** A special key has been pressed */
- void OnSpecialKeyPress(unsigned char Key);
+ bool OnSpecialKeyPress(unsigned char Key);
/** Set handler for specified event */
bool SetEvent(int eventType, EventHandler handler);
/** Button Pressed Event Script Function Name */
@@ -177,12 +183,15 @@ public: // Public Events
EventHandler MouseLeaveButton;
EventHandler MouseOverButton;
/** Refreshes the button from a radio group */
- void RedrawButton(const char* VariableName, unsigned int Sum);
+ void UpdateState(const char* VariableName, unsigned int Sum);
/** Set palette used for drawing button label in normal state. */
void SetTextColor(const Color &fore, const Color &back);
/** Sets percent (0-1.0) of width for clipping picture */
void SetPictureClipping(double clip) { Clipping = clip; }
+ /** Set explicit anchor point for text */
void SetAnchor(ieWord x, ieWord y);
+ /** Set offset pictures and label move when button is pressed */
+ void SetPushOffset(ieWord x, ieWord y);
private: // Private attributes
char* Text;
bool hasText;
@@ -209,11 +218,16 @@ private: // Private attributes
/** HP Bar over portraits */
unsigned long starttime;
Color SourceRGB, DestRGB;
+ /** Explicit text anchor point if IE_GUI_BUTTON_ANCHOR is set */
Point Anchor;
+ /** Offset pictures and label move when the button is pressed. */
+ Point PushOffset;
/** frame settings */
ButtonBorder borders[MAX_NUM_BORDERS];
bool IsPixelTransparent (unsigned short x, unsigned short y);
void CloseUpColor();
};
+}
+
#endif
diff --git a/gemrb/core/GUI/Console.cpp b/gemrb/core/GUI/Console.cpp
index 9cf4b95..a72f783 100644
--- a/gemrb/core/GUI/Console.cpp
+++ b/gemrb/core/GUI/Console.cpp
@@ -27,6 +27,9 @@
#include "Palette.h"
#include "ScriptEngine.h"
#include "Video.h"
+#include "GUI/EventMgr.h"
+
+namespace GemRB {
Console::Console(void)
{
@@ -66,7 +69,7 @@ void Console::Draw(unsigned short x, unsigned short y)
Color black = {
0x00, 0x00, 0x00, 0xff
};
- Region r( x + XPos, y + YPos, Width, Height );
+ Region r( (short)x + XPos, (short)y + YPos, Width, Height );
core->GetVideoDriver()->DrawRect( r, black );
font->Print( r, Buffer, palette,
IE_FONT_ALIGN_LEFT | IE_FONT_ALIGN_MIDDLE, true, NULL,
@@ -93,13 +96,12 @@ void Console::SetBackGround(Sprite2D* back)
Back = back;
}
/** Sets the Text of the current control */
-int Console::SetText(const char* string, int /*pos*/)
+void Console::SetText(const char* string)
{
- strncpy( ( char * ) Buffer, string, max );
- return 0;
+ strlcpy( ( char * ) Buffer, string, max );
}
/** Key Press Event */
-void Console::OnKeyPress(unsigned char Key, unsigned short /*Mod*/)
+bool Console::OnKeyPress(unsigned char Key, unsigned short /*Mod*/)
{
if (Key >= 0x20) {
size_t len = strlen( ( char* ) Buffer );
@@ -110,10 +112,12 @@ void Console::OnKeyPress(unsigned char Key, unsigned short /*Mod*/)
Buffer[CurPos++] = Key;
Buffer[len + 1] = 0;
}
+ return true;
}
+ return false;
}
/** Special Key Press */
-void Console::OnSpecialKeyPress(unsigned char Key)
+bool Console::OnSpecialKeyPress(unsigned char Key)
{
size_t len;
@@ -167,6 +171,7 @@ void Console::OnSpecialKeyPress(unsigned char Key)
Changed = true;
break;
}
+ return true;
}
//ctrl-up
@@ -215,7 +220,17 @@ void Console::HistoryAdd(bool force)
}
}
+void Console::SetFocus(bool focus)
+{
+ Control::SetFocus(focus);
+ if (hasFocus) {
+ core->GetVideoDriver()->ShowSoftKeyboard();
+ }
+}
+
bool Console::SetEvent(int /*eventType*/, EventHandler /*handler*/)
{
return false;
}
+
+}
diff --git a/gemrb/core/GUI/Console.h b/gemrb/core/GUI/Console.h
index c693eec..198091c 100644
--- a/gemrb/core/GUI/Console.h
+++ b/gemrb/core/GUI/Console.h
@@ -30,6 +30,8 @@
#include "GUI/Control.h"
#include "GUI/TextArea.h"
+namespace GemRB {
+
class Palette;
/**
@@ -57,7 +59,7 @@ public:
/** Set BackGround */
void SetBackGround(Sprite2D* back);
/** Sets the Text of the current control */
- int SetText(const char* string, int pos = 0);
+ void SetText(const char* string);
private:
/** Text Editing Cursor Sprite */
Sprite2D* Cursor;
@@ -80,9 +82,10 @@ private:
public: //Events
/** Key Press Event */
- void OnKeyPress(unsigned char Key, unsigned short Mod);
+ bool OnKeyPress(unsigned char Key, unsigned short Mod);
/** Special Key Press */
- void OnSpecialKeyPress(unsigned char Key);
+ bool OnSpecialKeyPress(unsigned char Key);
+ void SetFocus(bool focus);
bool SetEvent(int eventType, EventHandler handler);
private:
void HistoryBack();
@@ -90,4 +93,6 @@ private:
void HistoryAdd(bool force);
};
+}
+
#endif
diff --git a/gemrb/core/GUI/Control.cpp b/gemrb/core/GUI/Control.cpp
index fc02eb9..11efa1e 100644
--- a/gemrb/core/GUI/Control.cpp
+++ b/gemrb/core/GUI/Control.cpp
@@ -20,6 +20,7 @@
#include "GUI/Control.h"
+#include "GUI/EventMgr.h"
#include "GUI/Window.h"
#include "win32def.h"
@@ -29,9 +30,15 @@
#include "ScriptEngine.h"
#include "Video.h"
+#ifdef ANDROID
+#include "Variables.h"
+#endif
+
#include <cstdio>
#include <cstring>
+namespace GemRB {
+
Control::Control()
{
hasFocus = false;
@@ -49,12 +56,13 @@ Control::Control()
animation = NULL;
AnimPicture = NULL;
ControlType = IE_GUI_INVALID;
+ FunctionNumber = -1;
}
Control::~Control()
{
if (InHandler) {
- printMessage("Control","Destroying control inside event handler, crash may occur!\n", LIGHT_RED);
+ Log(ERROR, "Control", "Destroying control inside event handler, crash may occur!");
}
core->DisplayTooltip( 0, 0, NULL );
free (Tooltip);
@@ -87,15 +95,22 @@ void Control::DisplayTooltip()
core->DisplayTooltip( 0, 0, NULL );
}
-void Control::ResetEventHandler(EventHandler handler)
+void Control::ResetEventHandler(EventHandler &handler)
{
handler = NULL;
}
+void Control::SetText(const char* /*string*/)
+{
+}
+
+//return -1 if there is an error
+//return 1 if there is no handler (not an error)
+//return 0 if the handler ran as intended
int Control::RunEventHandler(EventHandler handler)
{
if (InHandler) {
- printMessage("Control","Nested event handlers are not supported!\n", YELLOW);
+ Log(WARNING, "Control", "Nested event handlers are not supported!");
return -1;
}
if (handler) {
@@ -106,82 +121,20 @@ int Control::RunEventHandler(EventHandler handler)
unsigned short WID = wnd->WindowID;
unsigned short ID = (unsigned short) ControlID;
InHandler = true;
+ //TODO: detect caller errors, trap them???
handler->call();
+ InHandler = false;
if (!core->IsValidWindow(WID,wnd) ) {
- printMessage ("Control","Owner window destructed!\n", LIGHT_RED);
+ Log(ERROR, "Control", "Owner window destructed!");
return -1;
}
if (!wnd->IsValidControl(ID,this) ) {
- printMessage ("Control","Control destructed!\n", LIGHT_RED);
+ Log(ERROR, "Control", "Control destructed!");
return -1;
}
- InHandler = false;
+ return 0;
}
- return 0;
-}
-
-/** Key Press Event */
-void Control::OnKeyPress(unsigned char Key, unsigned short /*Mod*/)
-{
- //printf("OnKeyPress: CtrlID = 0x%08X, Key = %c (0x%02hX)\n", (unsigned int) ControlID, Key, Key);
-#ifdef ANDROID // mapping volume control to volume control keys on device, these keys must be set up in AndroidAppSettings.cfg
- switch(Key) {
- case 'o': // volume down
- case 'p': // volume up
- int Ambients, Movie, Music, SFX, Voices;
- core->GetDictionary()->Lookup( "Volume Ambients", (ieDword&)Ambients );
- core->GetDictionary()->Lookup( "Volume Movie", (ieDword&)Movie );
- core->GetDictionary()->Lookup( "Volume Music", (ieDword&)Music );
- core->GetDictionary()->Lookup( "Volume SFX", (ieDword&)SFX );
- core->GetDictionary()->Lookup( "Volume Voices", (ieDword&)Voices );
- if (Key=='o') {
- if(Ambients>0) Ambients-=10; if(Ambients<0) Ambients=0;
- if(Movie>0) Movie-=10; if(Movie<0) Movie=0;
- if(Music>0) Music-=10; if(Music<0) Music=0;
- if(SFX>0) SFX-=10; if(SFX<0) SFX=0;
- if(Voices>0) Voices-=10; if(Voices<0) Voices=0;
- } else {
- if(Ambients<100) Ambients+=10; if(Ambients>100) Ambients=100;
- if(Movie<100) Movie+=10; if(Movie>100) Movie=100;
- if(Music<100) Music+=10; if(Music>100) Music=100;
- if(SFX<100) SFX+=10; if(SFX>100) SFX=100;
- if(Voices<100) Voices+=10; if(Voices>100) Voices=100;
- }
- core->GetDictionary()->SetAt( "Volume Ambients", Ambients );
- core->GetDictionary()->SetAt( "Volume Movie", Movie );
- core->GetDictionary()->SetAt( "Volume Music", Music );
- core->GetDictionary()->SetAt( "Volume SFX", SFX );
- core->GetDictionary()->SetAt( "Volume Voices", Voices );
- core->GetAudioDrv()->UpdateVolume();
- break;
- }
-#else
-(void)Key; // unused, fool the compiler
-#endif
-}
-
-/** Key Release Event */
-void Control::OnKeyRelease(unsigned char /*Key*/, unsigned short /*Mod*/)
-{
- //printf( "OnKeyRelease: CtrlID = 0x%08X, Key = %c (0x%02hX)\n", (unsigned int) ControlID, Key, Key );
-}
-
-/** Mouse Enter Event */
-void Control::OnMouseEnter(unsigned short /*x*/, unsigned short /*y*/)
-{
-// printf("OnMouseEnter: CtrlID = 0x%08X, x = %hd, y = %hd\n", (unsigned int) ControlID, x, y);
-}
-
-/** Mouse Leave Event */
-void Control::OnMouseLeave(unsigned short /*x*/, unsigned short /*y*/)
-{
-// printf("OnMouseLeave: CtrlID = 0x%08X, x = %hd, y = %hd\n", (unsigned int) ControlID, x, y);
-}
-
-/** Mouse Over Event */
-void Control::OnMouseOver(unsigned short /*x*/, unsigned short /*y*/)
-{
- //printf("OnMouseOver: CtrlID = 0x%08X, x = %hd, y = %hd\n", (unsigned int) ControlID, x, y);
+ return 1;
}
/** Mouse Button Down */
@@ -200,25 +153,46 @@ void Control::OnMouseDown(unsigned short x, unsigned short y,
void Control::OnMouseUp(unsigned short /*x*/, unsigned short /*y*/,
unsigned short /*Button*/, unsigned short /*Mod*/)
{
- //printf("OnMouseUp: CtrlID = 0x%08X, x = %hd, y = %hd, Button = %d, Mos = %hd\n", (unsigned int) ControlID, x, y, Button, Mod);
+ //print("OnMouseUp: CtrlID = 0x%08X, x = %hd, y = %hd, Button = %d, Mos = %hd",(unsigned int) ControlID, x, y, Button, Mod);
+}
+
+/** Mouse scroll wheel */
+void Control::OnMouseWheelScroll( short x, short y)
+{
+ Control *ctrl = Owner->GetScrollControl();
+ if (ctrl && (ctrl!=this)) {
+ ctrl->OnMouseWheelScroll( x, y );
+ }
}
/** Special Key Press */
-void Control::OnSpecialKeyPress(unsigned char Key)
+bool Control::OnSpecialKeyPress(unsigned char Key)
{
if (Key == GEM_UP || Key == GEM_DOWN) {
Control *ctrl = Owner->GetScrollControl();
if (ctrl && (ctrl!=this)) {
- ctrl->OnSpecialKeyPress(Key);
+ return ctrl->OnSpecialKeyPress(Key);
}
}
+ return false;
+}
+void Control::SetFocus(bool focus)
+{
+ hasFocus = focus;
}
+bool Control::isFocused()
+{
+ return hasFocus;
+}
/** Sets the Display Flags */
int Control::SetFlags(int arg_flags, int opcode)
{
- if ((arg_flags >>24) != ControlType)
+ if ((arg_flags >>24) != ControlType) {
+ Log(WARNING, "Control", "Trying to modify invalid flag %x on control %d (opcode %d)",
+ arg_flags, ControlID, opcode);
return -2;
+ }
switch (opcode) {
case BM_SET:
Flags = arg_flags; //set
@@ -260,7 +234,7 @@ int Control::SetScrollBar(Control* ptr)
{
if (ptr && (ptr->ControlType!=IE_GUI_SCROLLBAR)) {
ptr = NULL;
- printMessage("Control","Attached control is not a ScrollBar!\n",YELLOW);
+ Log(WARNING, "Control", "Attached control is not a ScrollBar!");
return -1;
}
sb = ptr;
@@ -268,3 +242,5 @@ int Control::SetScrollBar(Control* ptr)
if (ptr) return 1;
return 0;
}
+
+}
diff --git a/gemrb/core/GUI/Control.h b/gemrb/core/GUI/Control.h
index 50a5ad2..4e00109 100644
--- a/gemrb/core/GUI/Control.h
+++ b/gemrb/core/GUI/Control.h
@@ -50,6 +50,8 @@
#include "Callback.h"
+namespace GemRB {
+
class ControlAnimation;
class Sprite2D;
class Window;
@@ -61,17 +63,22 @@ class Window;
*/
class GEM_EXPORT Control {
+protected:
+ /** Focused Control */
+ bool hasFocus;
public:
Control();
virtual ~Control();
/** Draws the Control on the Output Display */
virtual void Draw(unsigned short x, unsigned short y) = 0;
/** Sets the Text of the current control */
- virtual int SetText(const char* string, int pos = 0) = 0;
+ virtual void SetText(const char* string);
/** Sets the Tooltip text of the current control */
int SetTooltip(const char* string);
/** Displays the tooltip text, Worldmap handles this differently */
virtual void DisplayTooltip();
+ /** Update the control if it's tied to a GUI variable */
+ virtual void UpdateState(const char*, unsigned int) {}
/** Variable length is 40-1 (zero terminator) */
char VarName[MAX_VARIABLE_LENGTH];
/** the value of the control to add to the variable */
@@ -97,8 +104,6 @@ public: // Public attributes
/** Text to display as a tooltip when the mouse cursor hovers
* for some time over the control */
char* Tooltip;
- /** Focused Control */
- bool hasFocus;
/** If true, control is redrawn during next call to gc->DrawWindows.
* Then it's set back to false. */
bool Changed;
@@ -108,35 +113,41 @@ public: // Public attributes
Window* Owner;
/** Attached Scroll Bar Pointer*/
Control* sb;
+ /** Associated function key index, 0 based, -1 is unassigned */
+ ieDword FunctionNumber;
public: //Events
/** Reset/init event handler */
- void ResetEventHandler(EventHandler handler);
+ void ResetEventHandler(EventHandler &handler);
/** Returns the Owner */
Window *GetOwner() const { return Owner; }
/** Set the Flags */
int SetFlags(int arg_flags, int opcode);
+ virtual void SetFocus(bool focus);
+ bool isFocused();
/** Set handler for specified event. Override in child classes */
virtual bool SetEvent(int eventType, EventHandler handler) = 0;
/** Run specified handler, it may return error code */
int RunEventHandler(EventHandler handler);
/** Key Press Event */
- virtual void OnKeyPress(unsigned char Key, unsigned short Mod);
+ virtual bool OnKeyPress(unsigned char /*Key*/, unsigned short /*Mod*/) { return false; };
/** Key Release Event */
- virtual void OnKeyRelease(unsigned char Key, unsigned short Mod);
+ virtual bool OnKeyRelease(unsigned char /*Key*/, unsigned short /*Mod*/) { return false; };
/** Mouse Enter Event */
- virtual void OnMouseEnter(unsigned short x, unsigned short y);
+ virtual void OnMouseEnter(unsigned short /*x*/, unsigned short /*y*/) {};
/** Mouse Leave Event */
- virtual void OnMouseLeave(unsigned short x, unsigned short y);
+ virtual void OnMouseLeave(unsigned short /*x*/, unsigned short /*y*/) {};
/** Mouse Over Event */
- virtual void OnMouseOver(unsigned short x, unsigned short y);
+ virtual void OnMouseOver(unsigned short /*x*/, unsigned short /*y*/) {};
/** Mouse Button Down */
- virtual void OnMouseDown(unsigned short x, unsigned short y,
- unsigned short Button, unsigned short Mod);
+ virtual void OnMouseDown(unsigned short /*x*/, unsigned short /*y*/,
+ unsigned short /*Button*/, unsigned short /*Mod*/);
/** Mouse Button Up */
- virtual void OnMouseUp(unsigned short x, unsigned short y,
- unsigned short Button, unsigned short Mod);
+ virtual void OnMouseUp(unsigned short /*x*/, unsigned short /*y*/,
+ unsigned short /*Button*/, unsigned short /*Mod*/);
+ /** Mouse wheel scroll */
+ virtual void OnMouseWheelScroll( short x, short y);
/** Special Key Press */
- virtual void OnSpecialKeyPress(unsigned char Key);
+ virtual bool OnSpecialKeyPress(unsigned char Key);
virtual bool IsPixelTransparent(unsigned short /*x*/, unsigned short /*y*/) {
return false;
}
@@ -144,6 +155,12 @@ public: //Events
void SetAnimPicture(Sprite2D* Picture);
/** Sets the Scroll Bar Pointer */
int SetScrollBar(Control* ptr);
+
+ /** Assigned function key */
+ void SetFunctionNumber(int x) { FunctionNumber = x; }
+ int GetFunctionNumber() { return FunctionNumber; }
};
+}
+
#endif
diff --git a/gemrb/core/GUI/EventMgr.cpp b/gemrb/core/GUI/EventMgr.cpp
index 41e22b2..d41293c 100644
--- a/gemrb/core/GUI/EventMgr.cpp
+++ b/gemrb/core/GUI/EventMgr.cpp
@@ -23,13 +23,22 @@
#include "GUI/GameControl.h"
#include "win32def.h"
+#include "ie_cursors.h"
+#include "Game.h"
#include "Interface.h"
+#include "KeyMap.h"
#include "Video.h"
+#include "GUI/Window.h"
+
+namespace GemRB {
EventMgr::EventMgr(void)
{
- last_win_focused = NULL;
+ // Function bar window (for function keys)
+ function_bar = NULL;
+ // Last window focused for keyboard events
+ last_win_focused = NULL;
// Last window focused for mouse events (eg, with a click). Used to determine MouseUp events
last_win_mousefocused = NULL;
// Last window we were over. Used to determine MouseEnter and MouseLeave events
@@ -110,13 +119,14 @@ void EventMgr::Clear()
last_win_focused = NULL;
last_win_mousefocused = NULL;
last_win_over = NULL;
+ function_bar = NULL;
}
/** Remove a Window from the array */
void EventMgr::DelWindow(Window *win)
-//unsigned short WindowID, const char *WindowPack)
{
- if (last_win_focused == win) {
+ bool focused = (last_win_focused == win);
+ if (focused) {
last_win_focused = NULL;
}
if (last_win_mousefocused == win) {
@@ -125,10 +135,14 @@ void EventMgr::DelWindow(Window *win)
if (last_win_over == win) {
last_win_over = NULL;
}
+ if (function_bar == win) {
+ function_bar = NULL;
+ }
if (windows.size() == 0) {
return;
}
+
int pos = -1;
std::vector< Window*>::iterator m;
for (m = windows.begin(); m != windows.end(); ++m) {
@@ -139,10 +153,14 @@ void EventMgr::DelWindow(Window *win)
for (t = topwin.begin(); t != topwin.end(); ++t) {
if ( (*t) == pos) {
topwin.erase( t );
+ if (focused && topwin.size() > 0) {
+ //revert focus to new top window
+ SetFocused(windows[topwin[0]], NULL);
+ }
return;
}
}
- printMessage("EventManager","Couldn't find window",YELLOW);
+ Log(WARNING, "EventManager", "Couldn't delete window!");
}
}
}
@@ -214,7 +232,8 @@ void EventMgr::RefreshCursor(int idx)
video->SetMouseGrayed(false);
}
idx &= IE_CURSOR_MASK;
- video->SetCursor( core->Cursors[idx], core->Cursors[idx ^ 1] );
+ video->SetCursor( core->Cursors[idx], VID_CUR_UP );
+ video->SetCursor( core->Cursors[idx ^ 1], VID_CUR_DOWN );
}
bool EventMgr::ClickMatch(unsigned short x, unsigned short y, unsigned long thisTime)
@@ -236,7 +255,7 @@ void EventMgr::MouseDown(unsigned short x, unsigned short y, unsigned short Butt
Control *ctrl;
unsigned long thisTime;
- GetTime( thisTime );
+ thisTime = GetTickCount();
if (ClickMatch(x, y, thisTime)) {
Button |= GEM_MB_DOUBLECLICK;
dc_x = 0;
@@ -276,7 +295,7 @@ void EventMgr::MouseDown(unsigned short x, unsigned short y, unsigned short Butt
if (( *m )->Visible == WINDOW_FRONT) //stop looking further
break;
}
-
+
if ((Button == GEM_MB_SCRLUP || Button == GEM_MB_SCRLDOWN) && last_win_mousefocused) {
ctrl = last_win_mousefocused->GetScrollControl();
if (ctrl) {
@@ -288,18 +307,27 @@ void EventMgr::MouseDown(unsigned short x, unsigned short y, unsigned short Butt
last_win_mousefocused->SetMouseFocused(NULL);
}
}
+
/** BroadCast Mouse Up Event */
void EventMgr::MouseUp(unsigned short x, unsigned short y, unsigned short Button,
unsigned short Mod)
{
MButtons &= ~Button;
- if (last_win_mousefocused == NULL) return;
- Control *last_ctrl_mousefocused = last_win_mousefocused->GetMouseFocus();
+ Control *last_ctrl_mousefocused = GetMouseFocusedControl();
if (last_ctrl_mousefocused == NULL) return;
last_ctrl_mousefocused->OnMouseUp( x - last_win_mousefocused->XPos - last_ctrl_mousefocused->XPos,
y - last_win_mousefocused->YPos - last_ctrl_mousefocused->YPos, Button, Mod );
}
+/** BroadCast Mouse ScrollWheel Event */
+void EventMgr::MouseWheelScroll( short x, short y)//these are signed!
+{
+ Control *ctrl = GetMouseFocusedControl();
+ if (ctrl) {
+ ctrl->OnMouseWheelScroll( x, y);
+ }
+}
+
/** BroadCast Mouse Idle Event */
void EventMgr::MouseIdle(unsigned long /*time*/)
{
@@ -314,18 +342,28 @@ void EventMgr::KeyPress(unsigned char Key, unsigned short Mod)
{
if (last_win_focused == NULL) return;
Control *ctrl = last_win_focused->GetFocus();
- if (ctrl == NULL) return;
- ctrl->OnKeyPress( Key, Mod );
+ if (!ctrl || !ctrl->OnKeyPress( Key, Mod )) {
+ // FIXME: need a better way to determine when to call ResolveKey/SetHotKey
+ if (core->GetGameControl()
+ && !MButtons // checking for drag actions
+ && !core->IsPresentingModalWindow()
+ && !core->GetKeyMap()->ResolveKey(Key, 0)) {
+ core->GetGame()->SetHotKey(toupper(Key));
+ }
+ //this is to refresh changing mouse cursors should the focus change)
+ FakeMouseMove();
+ }
}
+
/** BroadCast Key Release Event */
void EventMgr::KeyRelease(unsigned char Key, unsigned short Mod)
{
if (last_win_focused == NULL) return;
- Control *ctrl = last_win_focused->GetFocus();
if (Key == GEM_GRAB) {
core->GetVideoDriver()->ToggleGrabInput();
return;
}
+ Control *ctrl = last_win_focused->GetFocus();
if (ctrl == NULL) return;
ctrl->OnKeyRelease( Key, Mod );
}
@@ -354,11 +392,19 @@ void EventMgr::OnSpecialKeyPress(unsigned char Key)
//the default cancel control will get only GEM_ESCAPE
else if (Key == GEM_ESCAPE) {
ctrl = last_win_focused->GetDefaultControl(1);
+ } else if (Key >= GEM_FUNCTION1 && Key <= GEM_FUNCTION16) {
+ if (function_bar) {
+ ctrl = function_bar->GetFunctionControl(Key-GEM_FUNCTION1);
+ } else {
+ ctrl = last_win_focused->GetFunctionControl(Key-GEM_FUNCTION1);
+ }
}
- //if there was no default button set, then the current focus will get it
+ //if there was no default button set, then the current focus will get it (except function keys)
if (!ctrl) {
- ctrl = last_win_focused->GetFocus();
+ if (Key<GEM_FUNCTION1 || Key > GEM_FUNCTION16) {
+ ctrl = last_win_focused->GetFocus();
+ }
}
//if one is under focus, use the default scroll focus
if (!ctrl) {
@@ -376,33 +422,37 @@ void EventMgr::OnSpecialKeyPress(unsigned char Key)
break;
//buttons will receive only GEM_RETURN
case IE_GUI_BUTTON:
+ if (Key >= GEM_FUNCTION1 && Key <= GEM_FUNCTION16) {
+ //fake mouse button
+ ctrl->OnMouseDown(0,0,GEM_MB_ACTION,0);
+ ctrl->OnMouseUp(0,0,GEM_MB_ACTION,0);
+ return;
+ }
if (Key != GEM_RETURN && Key!=GEM_ESCAPE) {
return;
}
break;
- case IE_GUI_GAMECONTROL:
- //gamecontrols will receive all special keys
- break;
- case IE_GUI_EDIT:
- case IE_GUI_TEXTAREA:
- //editboxes and textareas will receive all special keys
- break;
- default:
- //other controls don't receive any
- return;
+ // shouldnt be any harm in sending these events to any control
}
ctrl->OnSpecialKeyPress( Key );
}
}
+/** Trigger a fake MouseMove event with current coordinates (typically used to
+ * refresh the cursor without actual user input) */
+void EventMgr::FakeMouseMove()
+{
+ int x, y;
+ core->GetVideoDriver()->GetMousePos(x, y);
+ MouseMove((unsigned short) x, (unsigned short) y);
+}
+
void EventMgr::SetFocused(Window *win, Control *ctrl)
{
last_win_focused = win;
last_win_focused->SetFocused(ctrl);
//this is to refresh changing mouse cursors should the focus change)
- int x,y;
- core->GetVideoDriver()->GetMousePos(x,y);
- MouseMove((unsigned short) x, (unsigned short) y);
+ FakeMouseMove();
}
void EventMgr::SetDCDelay(unsigned long t)
@@ -437,3 +487,12 @@ unsigned long EventMgr::SetRKFlags(unsigned long arg, unsigned int op)
rk_flags=tmp;
return rk_flags;
}
+
+Control* EventMgr::GetMouseFocusedControl()
+{
+ if (last_win_mousefocused) {
+ return last_win_mousefocused->GetMouseFocus();
+ }
+ return NULL;
+}
+}
diff --git a/gemrb/core/GUI/EventMgr.h b/gemrb/core/GUI/EventMgr.h
index bda4ae8..99ff1bf 100644
--- a/gemrb/core/GUI/EventMgr.h
+++ b/gemrb/core/GUI/EventMgr.h
@@ -28,14 +28,15 @@
#ifndef EVENTMGR_H
#define EVENTMGR_H
-#include "GUI/Control.h"
-
#include "exports.h"
-#include "WindowMgr.h"
-
#include <vector>
+namespace GemRB {
+
+class Control;
+class Window;
+
#define GEM_LEFT 0x81
#define GEM_RIGHT 0x82
#define GEM_UP 0x83
@@ -51,7 +52,8 @@
#define GEM_PGUP 0x8d
#define GEM_PGDOWN 0x8e
#define GEM_GRAB 0x8f
-
+#define GEM_FUNCTION1 0x90 //don't use anything between these two and keep a round number
+#define GEM_FUNCTION16 0x9f
#define GEM_MOD_SHIFT 1
#define GEM_MOD_CTRL 2
@@ -86,6 +88,16 @@ private:
unsigned short dc_x, dc_y;
unsigned long dc_time, dc_delay;
unsigned long rk_delay, rk_flags;
+
+ /** Function bar window containing function key buttons */
+ Window* function_bar;
+ /** Last Window focused */
+ Window* last_win_focused;
+ /** Last Window mouse event focused */
+ Window* last_win_mousefocused;
+ /** Last Window under Mouse Pointer*/
+ Window* last_win_over;
+ /** Sets a Window on the Top of the Window Queue */
public:
EventMgr(void);
~EventMgr(void);
@@ -98,6 +110,8 @@ public:
void Clear();
/** Call this to change the cursor (moving over windows will change it back) */
void RefreshCursor(int idx);
+ /** Trigger a fake MouseMove event with current coordinates (typically used to refresh cursor) */
+ void FakeMouseMove();
/** BroadCast Mouse Move Event */
void MouseMove(unsigned short x, unsigned short y);
/** BroadCast Mouse Move Event */
@@ -106,6 +120,8 @@ public:
/** BroadCast Mouse Move Event */
void MouseUp(unsigned short x, unsigned short y, unsigned short Button,
unsigned short Mod);
+ /** BroadCast Mouse Scroll Event */
+ void MouseWheelScroll( short x, short y);
/** BroadCast Mouse Idle Event */
void MouseIdle(unsigned long time);
/** BroadCast Key Press Event */
@@ -123,20 +139,16 @@ public:
void SetRKDelay(unsigned long t);
unsigned long GetRKDelay();
unsigned long SetRKFlags(unsigned long arg, unsigned int op);
-
+ void inline SetFunctionBar(Window *win) { function_bar = win; }
+ Control* GetMouseFocusedControl();
/** Mask of which Mouse Buttons are pressed */
unsigned char MButtons;
private:
- /** Last Window focused */
- Window* last_win_focused;
- /** Last Window mouse event focused */
- Window* last_win_mousefocused;
- /** Last Window under Mouse Pointer*/
- Window* last_win_over;
- /** Sets a Window on the Top of the Window Queue */
void SetDefaultFocus(Window *win);
void SetOnTop(int Index);
bool ClickMatch(unsigned short x, unsigned short y, unsigned long thisTime);
};
+}
+
#endif // ! EVENTMGR_H
diff --git a/gemrb/core/GUI/GameControl.cpp b/gemrb/core/GUI/GameControl.cpp
index 0794c08..a92ed28 100644
--- a/gemrb/core/GUI/GameControl.cpp
+++ b/gemrb/core/GUI/GameControl.cpp
@@ -22,37 +22,43 @@
#include "strrefs.h"
#include "win32def.h"
+#include "CharAnimations.h"
#include "DialogHandler.h"
#include "DisplayMessage.h"
#include "Effect.h"
+#include "Font.h"
#include "Game.h"
#include "GameData.h"
+#include "GlobalTimer.h"
#include "ImageMgr.h"
#include "Interface.h"
#include "Item.h"
+#include "PathFinder.h"
#include "SaveGameIterator.h"
#include "ScriptEngine.h"
+#include "TableMgr.h"
#include "TileMap.h"
#include "Video.h"
#include "damages.h"
+#include "ie_cursors.h"
+#include "opcode_params.h"
#include "GameScript/GSUtils.h"
+#include "GUI/EventMgr.h"
+#include "GUI/TextArea.h"
+#include "GUI/Window.h"
#include "Scriptable/Container.h"
#include "Scriptable/Door.h"
#include "Scriptable/InfoPoint.h"
#include <cmath>
+namespace GemRB {
+
#define DEBUG_SHOW_INFOPOINTS 0x01
#define DEBUG_SHOW_CONTAINERS 0x02
#define DEBUG_SHOW_DOORS DEBUG_SHOW_CONTAINERS
#define DEBUG_SHOW_LIGHTMAP 0x08
-#ifdef TOUCHSCREEN
-# define SCROLL_BORDER 32
-#else
-# define SCROLL_BORDER 5
-#endif
-
static const Color cyan = {
0x00, 0xff, 0xff, 0xff
};
@@ -65,11 +71,13 @@ static const Color magenta = {
static const Color green = {
0x00, 0xff, 0x00, 0xff
};
-/*
+static const Color darkgreen = {
+ 0x00, 0x78, 0x00, 0xff
+};
static Color white = {
0xff, 0xff, 0xff, 0xff
};
-*/
+
static const Color black = {
0x00, 0x00, 0x00, 0xff
};
@@ -80,13 +88,10 @@ static const Color gray = {
0x80, 0x80, 0x80, 0xff
};
-//Animation* effect;
-
#define FORMATIONSIZE 10
typedef Point formation_type[FORMATIONSIZE];
ieDword formationcount;
static formation_type *formations=NULL;
-static bool mqs = false;
static ieResRef TestSpell="SPWI207";
//If one of the actors has tracking on, the gamecontrol needs to display
@@ -99,15 +104,6 @@ void GameControl::SetTracker(Actor *actor, ieDword dist)
distance = dist;
}
-//Multiple Quick saves is an experimental GemRB feature.
-//multiple quick saves are kept, their age is determined by the slot
-//number. There is an algorithm which keeps about log2(n) slots alive.
-//The algorithm is implemented in SaveGameIterator
-void GameControl::MultipleQuickSaves(int arg)
-{
- mqs=arg==1;
-}
-
GameControl::GameControl(void)
{
if (!formations) {
@@ -122,8 +118,6 @@ GameControl::GameControl(void)
lastActorID = 0;
trackerID = 0;
distance = 0;
- MouseIsDown = false;
- DrawSelectionRect = false;
overDoor = NULL;
overContainer = NULL;
overInfoPoint = NULL;
@@ -132,17 +126,26 @@ GameControl::GameControl(void)
lastCursor = IE_CURSOR_NORMAL;
moveX = moveY = 0;
scrolling = false;
-#ifdef TOUCHSCREEN
- touched=false;
-#endif
+ touchScrollAreasEnabled = false;
numScrollCursor = 0;
DebugFlags = 0;
AIUpdateCounter = 1;
- EnableRunning = true; //make this a game flag if you wish
+ AlwaysRun = false; //make this a game flag if you wish
ieDword tmp=0;
+ ClearMouseState();
ResetTargetMode();
+ core->GetDictionary()->Lookup("TouchScrollAreas",tmp);
+ if (tmp) {
+ touchScrollAreasEnabled = true;
+ touched = false;
+ scrollAreasWidth = 32;
+ } else {
+ scrollAreasWidth = 5;
+ }
+
+ tmp=0;
core->GetDictionary()->Lookup("Center",tmp);
if (tmp) {
ScreenFlags=SF_ALWAYSCENTER|SF_CENTERONACTOR;
@@ -194,12 +197,9 @@ Point GameControl::GetFormationOffset(ieDword formation, ieDword pos)
return formations[formation][pos];
}
-//Moves an actor to a new position, keeping the current formation
//WARNING: don't pass p as a reference because it gets modified
-void GameControl::MoveToPointFormation(Actor *actor, unsigned int pos, Point src, Point p)
+Point GameControl::GetFormationPoint(Map *map, unsigned int pos, Point src, Point p)
{
- Map* map = actor->GetCurrentArea() ;
-
int formation=core->GetGame()->GetFormation();
if (pos>=FORMATIONSIZE) pos=FORMATIONSIZE-1;
@@ -237,7 +237,7 @@ void GameControl::MoveToPointFormation(Actor *actor, unsigned int pos, Point src
p.x*=16;
p.y*=12;
}
- CreateMovement(actor, p);
+ return p;
}
void GameControl::Center(unsigned short x, unsigned short y)
@@ -250,19 +250,29 @@ void GameControl::Center(unsigned short x, unsigned short y)
video->MoveViewportTo( Viewport.x, Viewport.y );
}
+void GameControl::ClearMouseState()
+{
+ MouseIsDown = false;
+ DrawSelectionRect = false;
+ FormationRotation = false;
+}
+
// generate an action to do the actual movement
// only PST supports RunToPoint
void GameControl::CreateMovement(Actor *actor, const Point &p)
{
char Tmp[256];
-
Action *action = NULL;
- if (DoubleClick && EnableRunning) {
+ static bool CanRun = true;
+
+ //try running (in PST) only if not encumbered
+ ieDword speed = actor->CalculateSpeed(true);
+ if ( (speed==actor->GetStat(IE_MOVEMENTRATE)) && CanRun && (DoubleClick || AlwaysRun)) {
sprintf( Tmp, "RunToPoint([%d.%d])", p.x, p.y );
action = GenerateAction( Tmp );
//if it didn't work don't insist
if (!action)
- EnableRunning = false;
+ CanRun = false;
}
if (!action) {
sprintf( Tmp, "MoveToPoint([%d.%d])", p.x, p.y );
@@ -270,8 +280,7 @@ void GameControl::CreateMovement(Actor *actor, const Point &p)
}
actor->AddAction( action );
- // force action so that we get target recticles immediately
- actor->ProcessActions(true);
+ actor->CommandActor();
}
GameControl::~GameControl(void)
@@ -288,19 +297,6 @@ GameControl::~GameControl(void)
}
}
-//Autosave was triggered by the GUI
-void GameControl::AutoSave()
-{
- core->GetSaveGameIterator()->CreateSaveGame(0, false);
-}
-
-//QuickSave was triggered by the GUI
-//mqs is the 'multiple quick saves' flag
-void GameControl::QuickSave()
-{
- core->GetSaveGameIterator()->CreateSaveGame(1, mqs == 1);
-}
-
// ArrowSprite cycles
// 321
// 4 0
@@ -322,7 +318,7 @@ static const int arrow_orientations[16]={
//Draws arrow markers along the edge of the game window
//WARNING:don't use reference for point, because it is altered
-void GameControl::DrawArrowMarker(const Region &screen, Point p, const Region &viewport)
+void GameControl::DrawArrowMarker(const Region &screen, Point p, const Region &viewport, const Color& color)
{
Video* video = core->GetVideoDriver();
@@ -357,8 +353,56 @@ void GameControl::DrawArrowMarker(const Region &screen, Point p, const Region &v
draw |= D_BOTTOM;
}
if (arrow_orientations[draw]>=0) {
- video->BlitGameSprite( core->GetScrollCursorSprite(arrow_orientations[draw], 0), p.x+screen.x, p.y+screen.y, 0, black, NULL);
+ Sprite2D *arrow = core->GetScrollCursorSprite(arrow_orientations[draw], 0);
+ video->BlitGameSprite(arrow, p.x+screen.x, p.y+screen.y, BLIT_TINTED, color, NULL);
+ arrow->release();
+ }
+ spr->release();
+}
+
+void GameControl::DrawTargetReticle(Point p, int size, bool animate, bool flash, bool actorSelected)
+{
+ // reticles are never drawn in cutscenes
+ if (GetScreenFlags()&SF_CUTSCENE)
+ return;
+
+ unsigned short step = 0;
+ if (animate) {
+ // generates "step" from sequence 3 2 1 0 1 2 3 4
+ // updated each 1/15 sec
+ ++step = tp_steps [(GetTickCount() >> 6) & 7];
+ } else {
+ step = 3;
+ }
+ if (size < 3) size = 3;
+
+ /* segments should not go outside selection radius */
+ unsigned short xradius = (size * 4) - 5;
+ unsigned short yradius = (size * 3) - 5;
+
+ Color color = green;
+ if (flash) {
+ if (step & 2) {
+ color = white;
+ } else {
+ if (!actorSelected) color = darkgreen;
+ }
}
+
+ Region viewport = core->GetVideoDriver()->GetViewport();
+ // TODO: 0.5 and 0.7 are pretty much random values
+ // right segment
+ core->GetVideoDriver()->DrawEllipseSegment( p.x + step - viewport.x, p.y - viewport.y, xradius,
+ yradius, color, -0.5, 0.5 );
+ // top segment
+ core->GetVideoDriver()->DrawEllipseSegment( p.x - viewport.x, p.y - step - viewport.y, xradius,
+ yradius, color, -0.7 - M_PI_2, 0.7 - M_PI_2 );
+ // left segment
+ core->GetVideoDriver()->DrawEllipseSegment( p.x - step - viewport.x, p.y - viewport.y, xradius,
+ yradius, color, -0.5 - M_PI, 0.5 - M_PI );
+ // bottom segment
+ core->GetVideoDriver()->DrawEllipseSegment( p.x - viewport.x, p.y + step - viewport.y, xradius,
+ yradius, color, -0.7 - M_PI - M_PI_2, 0.7 - M_PI - M_PI_2 );
}
/** Draws the Control on the Output Display */
@@ -387,19 +431,26 @@ void GameControl::Draw(unsigned short x, unsigned short y)
}
Region viewport = video->GetViewport();
+ // handle keeping the actor in the spotlight, but only when unpaused
+ if ((ScreenFlags & SF_ALWAYSCENTER) && update_scripts) {
+ Actor *star = core->GetFirstSelectedActor();
+ moveX = star->Pos.x - viewport.x - viewport.w/2;
+ moveY = star->Pos.y - viewport.y - viewport.h/2;
+ }
+
if (moveX || moveY) {
viewport.x += moveX;
viewport.y += moveY;
Point mapsize = area->TMap->GetMapSize();
- if ( viewport.x < 0 )//if we are at top of the map
+ if ( viewport.x < 0 )//if we are at the left of the map
viewport.x = 0;
- else if ( (viewport.x + viewport.w) >= mapsize.x) //if we are at the bottom
- viewport.x = mapsize.x - viewport.w;
+ else if ( (viewport.x + viewport.w) >= mapsize.x) //if we are at the right
+ viewport.x = mapsize.x - viewport.w - 1;
- if ( viewport.y < 0 ) //if we are at the left of the map
+ if ( viewport.y < 0 ) //if we are at the top of the map
viewport.y = 0;
- else if ( (viewport.y + viewport.h ) >= mapsize.y ) //if we are at the right
- viewport.y = mapsize.y - viewport.h;
+ else if ( (viewport.y + viewport.h ) >= mapsize.y ) //if we are at the bottom
+ viewport.y = mapsize.y - viewport.h - 1;
// override any existing viewport moves which may be in progress
core->timer->SetMoveViewPort( viewport.x, viewport.y, 0, false );
@@ -467,6 +518,10 @@ void GameControl::Draw(unsigned short x, unsigned short y)
Container *c;
for (idx = 0; (c = area->TMap->GetContainer( idx )); idx++) {
+ if (c->Flags & CONT_DISABLED) {
+ continue;
+ }
+
c->Highlight = false;
if (overContainer == c && target_mode) {
if (c->VisibleTrap(0) || (c->Flags & CONT_LOCKED)) {
@@ -506,14 +561,21 @@ void GameControl::Draw(unsigned short x, unsigned short y)
Actor *target = monsters[i++];
if (target->InParty) continue;
if (target->GetStat(IE_NOTRACKING)) continue;
- DrawArrowMarker(screen, target->Pos, viewport);
+ DrawArrowMarker(screen, target->Pos, viewport, black);
}
- delete monsters;
+ free(monsters);
} else {
trackerID = 0;
}
}
+ if (lastActorID) {
+ Actor* actor = GetLastActor();
+ if (actor) {
+ DrawArrowMarker(screen, actor->Pos, viewport, green);
+ }
+ }
+
if (ScreenFlags & SF_DISABLEMOUSE)
return;
Point p(lastMouseX, lastMouseY);
@@ -525,6 +587,27 @@ void GameControl::Draw(unsigned short x, unsigned short y)
video->DrawRect( SelectionRect, green, false, true );
}
+ // draw reticles
+ if (FormationRotation) {
+ FormationApplicationPoint.x = lastMouseX;
+ FormationApplicationPoint.y = lastMouseY;
+ core->GetVideoDriver()->ConvertToGame( FormationApplicationPoint.x, FormationApplicationPoint.y );
+
+ Actor *actor;
+ int max = game->GetPartySize(false);
+ // we only care about PCs and not summons for this. the summons will be included in
+ // the final mouse up event.
+ int formationPos = 0;
+ for(int idx = 1; idx<=max; idx++) {
+ actor = game->FindPC(idx);
+ if(actor->IsSelected()) {
+ // transform the formation point
+ p = GetFormationPoint(actor->GetCurrentArea(), formationPos++, FormationApplicationPoint, FormationPivotPoint);
+ DrawTargetReticle(p, 4, false);
+ }
+ }
+ }
+
// Show wallpolygons
if (DebugFlags & DEBUG_SHOW_INFOPOINTS) {
@@ -587,41 +670,35 @@ void GameControl::Draw(unsigned short x, unsigned short y)
}
}
-#ifdef TOUCHSCREEN
- if (moveY < 0 && scrolling)
- video->DrawLine(screen.x+4, screen.y+SCROLL_BORDER, screen.w+screen.x-4, screen.y+SCROLL_BORDER, red);
- else
- video->DrawLine(screen.x+4, screen.y+SCROLL_BORDER, screen.w+screen.x-4, screen.y+SCROLL_BORDER, gray);
- if (moveY > 0 && scrolling)
- video->DrawLine(screen.x+4, screen.h-SCROLL_BORDER, screen.w+screen.x-4, screen.h-SCROLL_BORDER, red);
- else
- video->DrawLine(screen.x+4, screen.h-SCROLL_BORDER, screen.w+screen.x-4, screen.h-SCROLL_BORDER, gray);
- if (moveX < 0 && scrolling)
- video->DrawLine(screen.x+SCROLL_BORDER, screen.y+4, screen.x+SCROLL_BORDER, screen.h+screen.y-4, red);
- else
- video->DrawLine(screen.x+SCROLL_BORDER, screen.y+4, screen.x+SCROLL_BORDER, screen.h+screen.y-4, gray);
- if (moveX > 0 && scrolling)
- video->DrawLine(screen.w+screen.x-SCROLL_BORDER, screen.y+4, screen.w+screen.x-SCROLL_BORDER, screen.h-4, red);
- else
- video->DrawLine(screen.w+screen.x-SCROLL_BORDER, screen.y+4, screen.w+screen.x-SCROLL_BORDER, screen.h-4, gray);
-#endif
-}
-
-/** inherited from Control, GameControl doesn't need it */
-int GameControl::SetText(const char* /*string*/, int /*pos*/)
-{
- return 0;
+ if (touchScrollAreasEnabled) {
+ if (moveY < 0 && scrolling)
+ video->DrawLine(screen.x+4, screen.y+scrollAreasWidth, screen.w+screen.x-4, screen.y+scrollAreasWidth, red);
+ else
+ video->DrawLine(screen.x+4, screen.y+scrollAreasWidth, screen.w+screen.x-4, screen.y+scrollAreasWidth, gray);
+ if (moveY > 0 && scrolling)
+ video->DrawLine(screen.x+4, screen.h-scrollAreasWidth, screen.w+screen.x-4, screen.h-scrollAreasWidth, red);
+ else
+ video->DrawLine(screen.x+4, screen.h-scrollAreasWidth, screen.w+screen.x-4, screen.h-scrollAreasWidth, gray);
+ if (moveX < 0 && scrolling)
+ video->DrawLine(screen.x+scrollAreasWidth, screen.y+4, screen.x+scrollAreasWidth, screen.h+screen.y-4, red);
+ else
+ video->DrawLine(screen.x+scrollAreasWidth, screen.y+4, screen.x+scrollAreasWidth, screen.h+screen.y-4, gray);
+ if (moveX > 0 && scrolling)
+ video->DrawLine(screen.w+screen.x-scrollAreasWidth, screen.y+4, screen.w+screen.x-scrollAreasWidth, screen.h-4, red);
+ else
+ video->DrawLine(screen.w+screen.x-scrollAreasWidth, screen.y+4, screen.w+screen.x-scrollAreasWidth, screen.h-4, gray);
+ }
}
/** Key Press Event */
-void GameControl::OnKeyPress(unsigned char Key, unsigned short /*Mod*/)
+bool GameControl::OnKeyPress(unsigned char Key, unsigned short /*Mod*/)
{
if (DialogueFlags&DF_IN_DIALOG) {
- return;
+ return false;
}
unsigned int i, pc;
Game* game = core->GetGame();
- if (!game) return;
+ if (!game) return false;
switch (Key) {
case '0':
@@ -669,12 +746,12 @@ void GameControl::OnKeyPress(unsigned char Key, unsigned short /*Mod*/)
break;
case 'c': // show containers in ANDROID, GEM_ALT is not possible to use
DebugFlags |= DEBUG_SHOW_CONTAINERS;
- return;
+ break;
#endif
default:
- core->GetGame()->SetHotKey(toupper(Key));
- break;
+ return false;
}
+ return true;
}
//Select (or deselect) a new actor (or actors)
@@ -697,14 +774,17 @@ void GameControl::SelectActor(int whom, int type)
}
if (type==1) {
game->SelectActor( actor, true, SELECT_NORMAL );
+ actor->PlaySelectionSound();
return;
}
bool was_selected = actor->IsSelected();
- if (game->SelectActor( actor, true, SELECT_REPLACE ))
+ if (game->SelectActor( actor, true, SELECT_REPLACE )) {
if (was_selected || (ScreenFlags & SF_ALWAYSCENTER)) {
ScreenFlags |= SF_CENTERONACTOR;
}
+ actor->PlaySelectionSound();
+ }
}
//Effect for the ctrl-r cheatkey (resurrect)
@@ -712,16 +792,16 @@ static EffectRef heal_ref = { "CurrentHPModifier", -1 };
static EffectRef damage_ref = { "Damage", -1 };
/** Key Release Event */
-void GameControl::OnKeyRelease(unsigned char Key, unsigned short Mod)
+bool GameControl::OnKeyRelease(unsigned char Key, unsigned short Mod)
{
unsigned int i;
Game* game = core->GetGame();
if (!game)
- return;
+ return false;
if (DialogueFlags&DF_IN_DIALOG) {
- if (Mod) return;
+ if (Mod) return false;
switch(Key) {
case '1':
case '2':
@@ -735,43 +815,39 @@ void GameControl::OnKeyRelease(unsigned char Key, unsigned short Mod)
{
TextArea *ta = core->GetMessageTextArea();
if (ta) {
- ta->OnKeyPress(Key,Mod);
+ return ta->OnKeyPress(Key,Mod);
}
}
break;
}
- return;
+ return false;
}
+ if (Mod & GEM_MOD_SHIFT) {
+ Key = toupper(Key);
+ }
+
//cheatkeys with ctrl-
if (Mod & GEM_MOD_CTRL) {
if (!core->CheatEnabled()) {
- return;
+ return false;
}
Map* area = game->GetCurrentArea( );
if (!area)
- return;
+ return false;
Actor *lastActor = area->GetActorByGlobalID(lastActorID);
Point p(lastMouseX, lastMouseY);
core->GetVideoDriver()->ConvertToGame( p.x, p.y );
switch (Key) {
- case 'f': //toggle full screen mode
- core->GetVideoDriver()->ToggleFullscreenMode();
- break;
- case 'd': //disarm a trap
+ case 'd': //detect a trap or door
if (overInfoPoint) {
- overInfoPoint->DetectTrap(256);
+ overInfoPoint->DetectTrap(256, lastActorID);
}
if (overContainer) {
- if (overContainer->Trapped &&
- !( overContainer->TrapDetected )) {
- overContainer->TrapDetected = 1;
- }
+ overContainer->DetectTrap(256, lastActorID);
}
if (overDoor) {
- if (overDoor->Trapped &&
- !( overDoor->TrapDetected )) {
- overDoor->TrapDetected = 1;
- }
+ overDoor->TryDetectSecret(256, lastActorID);
+ overDoor->DetectTrap(256, lastActorID);
}
break;
case 'l': //play an animation (vvc/bam) over an actor
@@ -791,11 +867,12 @@ void GameControl::OnKeyRelease(unsigned char Key, unsigned short Mod)
target = overDoor;
}
if (target) {
- src->CastSpell( TestSpell, target, false );
+ src->SetSpellResRef(TestSpell);
+ src->CastSpell(target, false);
if (src->LastTarget) {
- src->CastSpellEnd(0);
+ src->CastSpellEnd(0, 0);
} else {
- src->CastSpellPointEnd(0);
+ src->CastSpellPointEnd(0, 0);
}
}
}
@@ -837,10 +914,31 @@ void GameControl::OnKeyRelease(unsigned char Key, unsigned short Mod)
case 'j': //teleports the selected actors
for (i = 0; i < game->selected.size(); i++) {
Actor* actor = game->selected[i];
+ actor->ClearActions();
MoveBetweenAreasCore(actor, core->GetGame()->CurrentArea, p, -1, true);
}
break;
+ case 'M':
+ if (!lastActor) {
+ lastActor = area->GetActor( p, GA_DEFAULT);
+ }
+ if (!lastActor) {
+ // ValidTarget never returns immobile targets, making debugging a nightmare
+ // so if we don't have an actor, we make really really sure by checking manually
+ unsigned int count = area->GetActorCount(true);
+ while (count--) {
+ Actor *actor = area->GetActor(count, true);
+ if (actor->IsOver(p)) {
+ actor->GetAnims()->DebugDump();
+ }
+ }
+ }
+ if (lastActor) {
+ lastActor->GetAnims()->DebugDump();
+ break;
+ }
+ break;
case 'm': //prints a debug dump (ctrl-m in the original game too)
if (!lastActor) {
lastActor = area->GetActor( p, GA_DEFAULT);
@@ -852,39 +950,45 @@ void GameControl::OnKeyRelease(unsigned char Key, unsigned short Mod)
while (count--) {
Actor *actor = area->GetActor(count, true);
if (actor->IsOver(p)) {
- actor->DebugDump();
+ actor->dump();
}
}
}
if (lastActor) {
- lastActor->DebugDump();
+ lastActor->dump();
break;
}
if (overDoor) {
- overDoor->DebugDump();
+ overDoor->dump();
break;
}
if (overContainer) {
- overContainer->DebugDump();
+ overContainer->dump();
break;
}
if (overInfoPoint) {
- overInfoPoint->DebugDump();
+ overInfoPoint->dump();
break;
}
- core->GetGame()->GetCurrentArea()->DebugDump(Mod & GEM_MOD_SHIFT);
+ core->GetGame()->GetCurrentArea()->dump(false);
+ break;
+ case 'N': //prints a list of all the live actors in the area
+ core->GetGame()->GetCurrentArea()->dump(true);
break;
case 'v': //marks some of the map visited (random vision distance)
area->ExploreMapChunk( p, rand()%30, 1 );
break;
+ case 'V': //
+ core->GetDictionary()->DebugDump();
+ break;
case 'w': // consolidates found ground piles under the pointed pc
area->MoveVisibleGroundPiles(p);
break;
case 'x': // shows coordinates on the map
- printf( "%s [%d.%d]\n", area->GetScriptName(), p.x, p.y );
+ Log(MESSAGE, "GameControl", "Position: %s [%d.%d]", area->GetScriptName(), p.x, p.y );
break;
case 'g'://shows loaded areas and other game information
- game->DebugDump();
+ game->dump();
break;
case 'i'://interact trigger (from the original game)
if (!lastActor) {
@@ -918,6 +1022,7 @@ void GameControl::OnKeyRelease(unsigned char Key, unsigned short Mod)
if (fx) {
core->ApplyEffect(fx, lastActor, lastActor);
}
+ delete fx;
}
break;
case 't'://advances time
@@ -931,7 +1036,7 @@ void GameControl::OnKeyRelease(unsigned char Key, unsigned short Mod)
lastActor->ClearActions();
lastActor->ClearPath();
char Tmp[40];
- strncpy(Tmp,"JoinParty()",sizeof(Tmp) );
+ strlcpy(Tmp, "JoinParty()", sizeof(Tmp));
lastActor->AddAction( GenerateAction(Tmp) );
}
break;
@@ -944,45 +1049,46 @@ void GameControl::OnKeyRelease(unsigned char Key, unsigned short Mod)
lastActor->ClearActions();
lastActor->ClearPath();
char Tmp[40];
- strncpy(Tmp,"LeaveParty()",sizeof(Tmp) );
+ strlcpy(Tmp, "LeaveParty()", sizeof(Tmp));
lastActor->AddAction( GenerateAction(Tmp) );
}
break;
- case 'y': //kills actor or all enemies
- if (Mod & GEM_MOD_SHIFT) {
- // mwahaha!
+ case 'Y': // damages all enemies by 300 (resistances apply)
+ // mwahaha!
+ Effect *newfx;
+ newfx = EffectQueue::CreateEffect(damage_ref, 300, DAMAGE_MAGIC<<16, FX_DURATION_INSTANT_PERMANENT);
+ Actor *victim;
+ i = area->GetActorCount(0);
+ while(i--) {
+ victim = area->GetActor(i, 0);
+ if (victim->Modified[IE_EA] == EA_ENEMY) {
+ core->ApplyEffect(newfx, victim, victim);
+ }
+ }
+ delete newfx;
+ case 'y': //kills actor
+ if (lastActor) {
+ //using action so the actor is killed
+ //correctly (synchronisation)
+ lastActor->ClearActions();
+ lastActor->ClearPath();
+
Effect *newfx;
newfx = EffectQueue::CreateEffect(damage_ref, 300, DAMAGE_MAGIC<<16, FX_DURATION_INSTANT_PERMANENT);
- Actor *victim;
- for (int i = area->GetActorCount(0)-1; i >= 0; i--) {
- victim = area->GetActor(i, 0);
- if (victim->Modified[IE_EA] == EA_ENEMY) {
- core->ApplyEffect(newfx, victim, victim);
- }
- }
+ core->ApplyEffect(newfx, lastActor, lastActor);
delete newfx;
- } else {
- if (lastActor) {
- //using action so the actor is killed
- //correctly (synchronisation)
- lastActor->ClearActions();
- lastActor->ClearPath();
-
- Effect *newfx;
- newfx = EffectQueue::CreateEffect(damage_ref, 300, DAMAGE_MAGIC<<16, FX_DURATION_INSTANT_PERMANENT);
+ if (! (lastActor->GetInternalFlag() & IF_REALLYDIED)) {
+ newfx = EffectQueue::CreateEffect(damage_ref, 300, DAMAGE_ACID<<16, FX_DURATION_INSTANT_PERMANENT);
+ core->ApplyEffect(newfx, lastActor, lastActor);
+ delete newfx;
+ newfx = EffectQueue::CreateEffect(damage_ref, 300, DAMAGE_CRUSHING<<16, FX_DURATION_INSTANT_PERMANENT);
core->ApplyEffect(newfx, lastActor, lastActor);
- if (! (lastActor->GetInternalFlag() & IF_REALLYDIED)) {
- newfx = EffectQueue::CreateEffect(damage_ref, 300, DAMAGE_ACID<<16, FX_DURATION_INSTANT_PERMANENT);
- core->ApplyEffect(newfx, lastActor, lastActor);
- newfx = EffectQueue::CreateEffect(damage_ref, 300, DAMAGE_CRUSHING<<16, FX_DURATION_INSTANT_PERMANENT);
- core->ApplyEffect(newfx, lastActor, lastActor);
- }
delete newfx;
- } else if (overContainer) {
- overContainer->SetContainerLocked(0);
- } else if (overDoor) {
- overDoor->SetDoorLocked(0,0);
}
+ } else if (overContainer) {
+ overContainer->SetContainerLocked(0);
+ } else if (overDoor) {
+ overDoor->SetDoorLocked(0,0);
}
break;
case 'z': //shift through the avatar animations backward
@@ -997,53 +1103,33 @@ void GameControl::OnKeyRelease(unsigned char Key, unsigned short Mod)
break;
case '4': //show all traps and infopoints
DebugFlags ^= DEBUG_SHOW_INFOPOINTS;
- printf("Show traps and infopoints %s\n", DebugFlags & DEBUG_SHOW_INFOPOINTS ? "ON" : "OFF");
+ Log(MESSAGE, "GameControl", "Show traps and infopoints %s", DebugFlags & DEBUG_SHOW_INFOPOINTS ? "ON" : "OFF");
break;
case '6': //show the lightmap
DebugFlags ^= DEBUG_SHOW_LIGHTMAP;
- printf("Show lightmap %s\n", DebugFlags & DEBUG_SHOW_LIGHTMAP ? "ON" : "OFF");
+ Log(MESSAGE, "GameControl", "Show lightmap %s", DebugFlags & DEBUG_SHOW_LIGHTMAP ? "ON" : "OFF");
break;
case '7': //toggles fog of war
core->FogOfWar ^= FOG_DRAWFOG;
- printf("Show Fog-Of-War: %s\n", core->FogOfWar & FOG_DRAWFOG ? "ON" : "OFF");
+ Log(MESSAGE, "GameControl", "Show Fog-Of-War: %s", core->FogOfWar & FOG_DRAWFOG ? "ON" : "OFF");
break;
case '8': //show searchmap over area
core->FogOfWar ^= FOG_DRAWSEARCHMAP;
- printf("Show searchmap %s\n", core->FogOfWar & FOG_DRAWSEARCHMAP ? "ON" : "OFF");
+ Log(MESSAGE, "GameControl", "Show searchmap %s", core->FogOfWar & FOG_DRAWSEARCHMAP ? "ON" : "OFF");
break;
default:
- printf( "KeyRelease:%d - %d\n", Key, Mod );
+ Log(MESSAGE, "GameControl", "KeyRelease:%d - %d", Key, Mod );
break;
}
- return; //return from cheatkeys
+ return true; //return from cheatkeys
}
switch (Key) {
+//FIXME: move these to guiscript
case 'h': //hard pause
- if (DialogueFlags & DF_FREEZE_SCRIPTS) break;
- //fallthrough
- case ' ': //soft pause
- DialogueFlags ^= DF_FREEZE_SCRIPTS;
- if (DialogueFlags&DF_FREEZE_SCRIPTS) {
- displaymsg->DisplayConstantString(STR_PAUSED,0xff0000);
- SetDisplayText(STR_PAUSED, 0); // time 0 = removed instantly on unpause
- } else {
- displaymsg->DisplayConstantString(STR_UNPAUSED,0xff0000);
- }
- break;
- case 'm':
- core->GetGUIScriptEngine()->RunFunction("GUIMA","OpenMapWindow");
- break;
- case 'j':
- core->GetGUIScriptEngine()->RunFunction("GUIJRNL","OpenJournalWindow");
- break;
- case 'i':
- core->GetGUIScriptEngine()->RunFunction("GUIINV","OpenInventoryWindow");
+ core->SetPause(PAUSE_ON);
break;
- case 'r':
- core->GetGUIScriptEngine()->RunFunction("GUIREC","OpenRecordsWindow");
- break;
- case 'q': //quicksave
- QuickSave();
+ case ' ': //soft pause
+ core->TogglePause();
break;
case GEM_ALT: //alt key (shows containers)
#ifdef ANDROID
@@ -1052,8 +1138,9 @@ void GameControl::OnKeyRelease(unsigned char Key, unsigned short Mod)
DebugFlags &= ~DEBUG_SHOW_CONTAINERS;
break;
default:
- break;
+ return false;
}
+ return true;
}
void GameControl::DisplayTooltip() {
@@ -1062,8 +1149,7 @@ void GameControl::DisplayTooltip() {
Map* area = game->GetCurrentArea( );
if (area) {
Actor *actor = area->GetActorByGlobalID(lastActorID);
- if (actor && (actor->GetStat(IE_STATE_ID)&STATE_DEAD || actor->GetInternalFlag()&IF_JUSTDIED)) {
- // checking IF_JUSTDIED is kind of horrid, but seems necessary
+ if (actor && (actor->GetStat(IE_STATE_ID)&STATE_DEAD || actor->GetInternalFlag()&IF_REALLYDIED)) {
// no tooltips for dead actors!
actor->SetOver( false );
lastActorID = 0;
@@ -1096,8 +1182,9 @@ void GameControl::DisplayTooltip() {
// neutral: display name only
snprintf(buffer, 100, "%s", name);
} else if (strindex == -1) {
- // non-neutral, not in party, no injured strings: display hp
- snprintf(buffer, 100, "%s\n%d/%d", name, hp, maxhp);
+ // non-neutral, not in party, no injured strings: display name
+ // this case is mostly hit in bg1
+ snprintf(buffer, 100, "%s", name);
} else {
// non-neutral, not in party: display injured string
int strindex;
@@ -1193,6 +1280,10 @@ int GameControl::GetCursorOverDoor(Door *overDoor) const
//returns the appropriate cursor over a container (or pile)
int GameControl::GetCursorOverContainer(Container *overContainer) const
{
+ if (overContainer->Flags & CONT_DISABLED) {
+ return lastCursor;
+ }
+
if (target_mode == TARGET_MODE_PICK) {
if (overContainer->VisibleTrap(0)) {
return IE_CURSOR_TRAP;
@@ -1230,66 +1321,64 @@ void GameControl::OnMouseOver(unsigned short x, unsigned short y)
return;
}
-#ifdef TOUCHSCREEN
- int mousescrollspd = core->GetMouseScrollSpeed();
- Region region;
- Map* map;
- Point mapsize;
- Region viewport = core->GetVideoDriver()->GetViewport();
- moveX = 0;
- moveY = 0;
- // Top scroll area
- region=Region(XPos, YPos, Width, YPos+SCROLL_BORDER);
- if (region.PointInside(x, y)) {
- // Check for end of map area
- if (viewport.y > 0)
- moveY = -mousescrollspd;
- }
- // Bottom scroll area
- region=Region(XPos, Height-SCROLL_BORDER, Width, Height);
- if (region.PointInside(x, y)) {
- // Check for end of map area
- map = core->GetGame()->GetCurrentArea();
- if (map != NULL) {
- mapsize = map->TMap->GetMapSize();
- if((viewport.y + viewport.h) < mapsize.y)
- moveY = mousescrollspd;
- }
- }
- // Left scroll area
- region=Region(XPos, YPos, XPos+SCROLL_BORDER, Height);
- if (region.PointInside(x, y)) {
- // Check for end of map area
- if(viewport.x > 0)
- moveX = -mousescrollspd;
- }
- // Right scroll area
- region=Region(Width-SCROLL_BORDER, YPos, Width, Height);
- if (region.PointInside(x, y)) {
- // Check for end of map area
- map = core->GetGame()->GetCurrentArea();
- if (map != NULL) {
- mapsize = map->TMap->GetMapSize();
- if((viewport.x + viewport.w) < mapsize.x)
- moveX = mousescrollspd;
- }
- }
- if ((moveX != 0 || moveY != 0) && touched) {
- scrolling = true;
- return;
- } else {
+ Video *video = core->GetVideoDriver();
+
+ if (touchScrollAreasEnabled) {
+ int mousescrollspd = core->GetMouseScrollSpeed();
+ Region region;
+ Map* map;
+ Point mapsize;
+ Region viewport = video->GetViewport();
moveX = 0;
moveY = 0;
- scrolling = false;
- Video* video = core->GetVideoDriver();
- video->SetDragCursor(NULL);
+ // Top scroll area
+ region=Region(XPos, YPos, Width, YPos+scrollAreasWidth);
+ if (region.PointInside(x, y)) {
+ // Check for end of map area
+ if (viewport.y > 0)
+ moveY = -mousescrollspd;
+ }
+ // Bottom scroll area
+ region=Region(XPos, Height-scrollAreasWidth, Width, Height);
+ if (region.PointInside(x, y)) {
+ // Check for end of map area
+ map = core->GetGame()->GetCurrentArea();
+ if (map != NULL) {
+ mapsize = map->TMap->GetMapSize();
+ if((viewport.y + viewport.h) < mapsize.y)
+ moveY = mousescrollspd;
+ }
+ }
+ // Left scroll area
+ region=Region(XPos, YPos, XPos+scrollAreasWidth, Height);
+ if (region.PointInside(x, y)) {
+ // Check for end of map area
+ if(viewport.x > 0)
+ moveX = -mousescrollspd;
+ }
+ // Right scroll area
+ region=Region(Width-scrollAreasWidth, YPos, Width, Height);
+ if (region.PointInside(x, y)) {
+ // Check for end of map area
+ map = core->GetGame()->GetCurrentArea();
+ if (map != NULL) {
+ mapsize = map->TMap->GetMapSize();
+ if((viewport.x + viewport.w) < mapsize.x)
+ moveX = mousescrollspd;
+ }
+ }
+ if ((moveX != 0 || moveY != 0) && touched) {
+ SetScrolling(true);
+ return;
+ } else {
+ SetScrolling(false);
+ }
}
-#endif
lastMouseX = x;
lastMouseY = y;
Point p( x,y );
- core->GetVideoDriver()->ConvertToGame( p.x, p.y );
+ video->ConvertToGame( p.x, p.y );
if (MouseIsDown && ( !DrawSelectionRect )) {
if (( abs( p.x - StartX ) > 5 ) || ( abs( p.y - StartY ) > 5 )) {
DrawSelectionRect = true;
@@ -1328,6 +1417,10 @@ void GameControl::OnMouseOver(unsigned short x, unsigned short y)
overContainer = area->TMap->GetContainer( p );
if (!DrawSelectionRect) {
+ if (FormationRotation) {
+ nextCursor = IE_CURSOR_USE;
+ goto end_function;
+ }
if (overDoor) {
nextCursor = GetCursorOverDoor(overDoor);
}
@@ -1337,7 +1430,13 @@ void GameControl::OnMouseOver(unsigned short x, unsigned short y)
}
Actor *prevActor = lastActor;
- lastActor = area->GetActor( p, target_types);
+ // let us target party members even if they are invisible
+ lastActor = area->GetActor(p, GA_NO_DEAD);
+ if (lastActor && lastActor->Modified[IE_EA]>=EA_CONTROLLED) {
+ if (!lastActor->ValidTarget(target_types)) {
+ lastActor = NULL;
+ }
+ }
if (lastActor != prevActor) {
// we store prevActor so we can remove the tooltip on actor change
// (maybe we should be checking this and actor movements every frame?)
@@ -1361,7 +1460,7 @@ void GameControl::OnMouseOver(unsigned short x, unsigned short y)
nextCursor = IE_CURSOR_TALK;
//don't let the pc to talk to frozen/stoned creatures
ieDword state = lastActor->GetStat(IE_STATE_ID);
- if (state & STATE_CANTMOVE) {
+ if (state & (STATE_CANTMOVE^STATE_SLEEP)) {
nextCursor |= IE_CURSOR_GRAY;
}
} else {
@@ -1378,7 +1477,7 @@ void GameControl::OnMouseOver(unsigned short x, unsigned short y)
} else {
//don't let the pc to talk to frozen/stoned creatures
ieDword state = lastActor->GetStat(IE_STATE_ID);
- if (state & STATE_CANTMOVE) {
+ if (state & (STATE_CANTMOVE^STATE_SLEEP)) {
nextCursor |= IE_CURSOR_GRAY;
}
}
@@ -1451,6 +1550,10 @@ end_function:
}
/** Global Mouse Move Event */
+#if TARGET_OS_IPHONE
+// iOS will never have a mouse.
+void GameControl::OnGlobalMouseMove(unsigned short /*x*/, unsigned short /*y*/) {}
+#else
void GameControl::OnGlobalMouseMove(unsigned short x, unsigned short y)
{
if (ScreenFlags & SF_DISABLEMOUSE) {
@@ -1461,65 +1564,67 @@ void GameControl::OnGlobalMouseMove(unsigned short x, unsigned short y)
return;
}
-#ifndef TOUCHSCREEN
- int mousescrollspd = core->GetMouseScrollSpeed();
-
- if (x <= SCROLL_BORDER)
- moveX = -mousescrollspd;
- else {
- if (x >= ( core->Width - SCROLL_BORDER ))
- moveX = mousescrollspd;
- else
- moveX = 0;
- }
- if (y <= SCROLL_BORDER)
- moveY = -mousescrollspd;
- else {
- if (y >= ( core->Height - SCROLL_BORDER ))
- moveY = mousescrollspd;
- else
- moveY = 0;
- }
+ if (!touchScrollAreasEnabled) {
+ int mousescrollspd = core->GetMouseScrollSpeed();
- if (moveX != 0 || moveY != 0) {
- scrolling = true;
- } else if (scrolling) {
- scrolling = false;
+ if (x <= scrollAreasWidth)
+ moveX = -mousescrollspd;
+ else {
+ if (x >= ( core->Width - scrollAreasWidth ))
+ moveX = mousescrollspd;
+ else
+ moveX = 0;
+ }
+ if (y <= scrollAreasWidth)
+ moveY = -mousescrollspd;
+ else {
+ if (y >= ( core->Height - scrollAreasWidth ))
+ moveY = mousescrollspd;
+ else
+ moveY = 0;
+ }
- Video* video = core->GetVideoDriver();
- video->SetDragCursor(NULL);
+ SetScrolling(moveX != 0 || moveY != 0);
}
-#else
-(void)x;
-(void)y;
-#endif
}
+#endif
void GameControl::UpdateScrolling() {
- if (!scrolling) return;
+ // mouse scroll speed is checked because scrolling is not always done by the mouse (ie cutscenes/keyboard/etc)
+ if (!scrolling || !core->GetMouseScrollSpeed() || (moveX == 0 && moveY == 0)) return;
+
+ int cursorFrame = 0; // right
+ if (moveY < 0) {
+ cursorFrame = 2; // up
+ if (moveX > 0) cursorFrame--; // +right
+ else if (moveX < 0) cursorFrame++; // +left
+ } else if (moveY > 0) {
+ cursorFrame = 6; // down
+ if (moveX > 0) cursorFrame++; // +right
+ else if (moveX < 0) cursorFrame--; // +left
+ } else if (moveX < 0) {
+ cursorFrame = 4; // left
+ }
+
+ Sprite2D* cursor = core->GetScrollCursorSprite(cursorFrame, numScrollCursor);
+ core->GetVideoDriver()->SetCursor(cursor, VID_CUR_DRAG);
+ cursor->release();
- int mousescrollspd = core->GetMouseScrollSpeed(); // TODO: why check against this value and not +/-?
- Video* video = core->GetVideoDriver();
+ numScrollCursor = (numScrollCursor+1) % 15;
+}
- if (moveX == mousescrollspd && moveY == 0) { // right
- video->SetDragCursor(core->GetScrollCursorSprite(0,numScrollCursor));
- } else if (moveX == mousescrollspd && moveY == -mousescrollspd) { // upper right
- video->SetDragCursor(core->GetScrollCursorSprite(1,numScrollCursor));
- } else if (moveX == 0 && moveY == -mousescrollspd) { // up
- video->SetDragCursor(core->GetScrollCursorSprite(2,numScrollCursor));
- } else if (moveX == -mousescrollspd && moveY == -mousescrollspd) { // upper left
- video->SetDragCursor(core->GetScrollCursorSprite(3,numScrollCursor));
- } else if (moveX == -mousescrollspd && moveY == 0) { // left
- video->SetDragCursor(core->GetScrollCursorSprite(4,numScrollCursor));
- } else if (moveX == -mousescrollspd && moveY == mousescrollspd) { // bottom left
- video->SetDragCursor(core->GetScrollCursorSprite(5,numScrollCursor));
- } else if (moveX == 0 && moveY == mousescrollspd) { // bottom
- video->SetDragCursor(core->GetScrollCursorSprite(6,numScrollCursor));
- } else if (moveX == mousescrollspd && moveY == mousescrollspd) { // bottom right
- video->SetDragCursor(core->GetScrollCursorSprite(7,numScrollCursor));
- }
+void GameControl::SetScrolling(bool scroll) {
+ if (scrolling != scroll) {
+ scrolling = scroll;
+ if (!scrolling) {
+ moveX = 0;
+ moveY = 0;
- numScrollCursor = (numScrollCursor+1) % 15;
+ // only clear the drag cursor when changing scrolling to false!
+ // clearing on every move kills drag operations such as dragging portraits
+ core->GetVideoDriver()->SetCursor(NULL, VID_CUR_DRAG);
+ }
+ }
}
//generate action code for source actor to try to attack a target
@@ -1529,8 +1634,9 @@ void GameControl::TryToAttack(Actor *source, Actor *tgt)
source->ClearPath();
source->ClearActions();
- strncpy(Tmp,"NIDSpecial3()",sizeof(Tmp) );
+ strlcpy(Tmp, "NIDSpecial3()", sizeof(Tmp));
source->AddAction( GenerateActionDirect( Tmp, tgt) );
+ source->CommandActor();
}
//generate action code for source actor to try to defend a target
@@ -1541,8 +1647,9 @@ void GameControl::TryToDefend(Actor *source, Actor *tgt)
source->ClearPath();
source->ClearActions();
source->SetModal(MS_NONE);
- strncpy(Tmp,"NIDSpecial4()",sizeof(Tmp) );
+ strlcpy(Tmp, "NIDSpecial4()", sizeof(Tmp));
source->AddAction( GenerateActionDirect( Tmp, tgt) );
+ source->CommandActor();
}
//generate action code for source actor to try to pick pockets of a target
@@ -1554,8 +1661,9 @@ void GameControl::TryToPick(Actor *source, Actor *tgt)
source->ClearPath();
source->ClearActions();
source->SetModal(MS_NONE);
- strncpy(Tmp,"PickPockets([-1])", sizeof(Tmp) );
+ strlcpy(Tmp, "PickPockets([-1])", sizeof(Tmp));
source->AddAction( GenerateActionDirect( Tmp, tgt) );
+ source->CommandActor();
}
//generate action code for source actor to try to pick a lock/disable trap on a door
@@ -1567,11 +1675,12 @@ void GameControl::TryToPick(Actor *source, Door *tgt)
source->ClearActions();
source->SetModal(MS_NONE);
if (tgt->Trapped && tgt->TrapDetected) {
- strncpy(Tmp, "RemoveTraps([-1])", sizeof(Tmp) );
+ strlcpy(Tmp, "RemoveTraps([-1])", sizeof(Tmp));
} else {
- strncpy(Tmp, "PickLock([-1])", sizeof(Tmp) );
+ strlcpy(Tmp, "PickLock([-1])", sizeof(Tmp));
}
source->AddAction( GenerateActionDirect( Tmp, tgt ) );
+ source->CommandActor();
}
//generate action code for source actor to try to pick a lock/disable trap on a container
@@ -1583,11 +1692,12 @@ void GameControl::TryToPick(Actor *source, Container *tgt)
source->ClearActions();
source->SetModal(MS_NONE);
if (tgt->Trapped && tgt->TrapDetected) {
- strncpy(Tmp, "RemoveTraps([-1])", sizeof(Tmp) );
+ strlcpy(Tmp, "RemoveTraps([-1])", sizeof(Tmp));
} else {
- strncpy(Tmp, "PickLock([-1])", sizeof(Tmp) );
+ strlcpy(Tmp, "PickLock([-1])", sizeof(Tmp));
}
source->AddAction( GenerateActionDirect( Tmp, tgt ) );
+ source->CommandActor();
}
//generate action code for source actor to try to disable trap (only trap type active regions)
@@ -1600,8 +1710,9 @@ void GameControl::TryToDisarm(Actor *source, InfoPoint *tgt)
source->ClearPath();
source->ClearActions();
source->SetModal(MS_NONE);
- strncpy(Tmp, "RemoveTraps([-1])", sizeof(Tmp) );
+ strlcpy(Tmp, "RemoveTraps([-1])", sizeof(Tmp));
source->AddAction( GenerateActionDirect( Tmp, tgt ) );
+ source->CommandActor();
}
//generate action code for source actor to use item/cast spell on a point
@@ -1619,13 +1730,13 @@ void GameControl::TryToCast(Actor *source, const Point &tgt)
spellCount--;
if (spellOrItem>=0) {
if (spellIndex<0) {
- strncpy(Tmp, "SpellPointNoDec(\"\",[0.0])", sizeof(Tmp) );
+ strlcpy(Tmp, "SpellPointNoDec(\"\",[0.0])", sizeof(Tmp));
} else {
- strncpy(Tmp, "SpellPoint(\"\",[0.0])", sizeof(Tmp) );
+ strlcpy(Tmp, "SpellPoint(\"\",[0.0])", sizeof(Tmp));
}
} else {
//using item on target
- strncpy(Tmp, "UseItemPoint(\"\",[0,0],0)", sizeof(Tmp) );
+ strlcpy(Tmp, "UseItemPoint(\"\",[0,0],0)", sizeof(Tmp));
}
Action* action = GenerateAction( Tmp );
action->pointParameter=tgt;
@@ -1645,6 +1756,7 @@ void GameControl::TryToCast(Actor *source, const Point &tgt)
} else {
action->int0Parameter = spellSlot;
action->int1Parameter = spellIndex;
+ action->int2Parameter = UI_SILENT;
}
source->AddAction( action );
if (!spellCount) {
@@ -1664,6 +1776,14 @@ void GameControl::TryToCast(Actor *source, Actor *tgt)
source->ClearPath();
source->ClearActions();
+ // cannot target spells on invisible or sanctuaried creatures
+ // invisible actors are invisible, so this is usually impossible by itself, but improved invisibility changes that
+ if (source != tgt && tgt->Untargetable() ) {
+ displaymsg->DisplayConstantStringName(STR_NOSEE_NOCAST, DMC_RED, source);
+ ResetTargetMode();
+ return;
+ }
+
spellCount--;
if (spellOrItem>=0) {
if (spellIndex<0) {
@@ -1692,6 +1812,7 @@ void GameControl::TryToCast(Actor *source, Actor *tgt)
} else {
action->int0Parameter = spellSlot;
action->int1Parameter = spellIndex;
+ action->int2Parameter = UI_SILENT;
}
source->AddAction( action );
if (!spellCount) {
@@ -1711,9 +1832,10 @@ void GameControl::TryToTalk(Actor *source, Actor *tgt)
source->ClearPath();
source->ClearActions();
source->SetModal(MS_NONE);
- strncpy(Tmp,"NIDSpecial1()",sizeof(Tmp) );
+ strlcpy(Tmp, "NIDSpecial1()", sizeof(Tmp));
dialoghandler->targetID = tgt->GetGlobalID(); //this is a hack, but not so deadly
source->AddAction( GenerateActionDirect( Tmp, tgt) );
+ source->CommandActor();
}
//generate action code for actor appropriate for the target mode when the target is a container
@@ -1721,6 +1843,11 @@ void GameControl::HandleContainer(Container *container, Actor *actor)
{
char Tmp[256];
+ //container is disabled, it should not react
+ if (container->Flags & CONT_DISABLED) {
+ return;
+ }
+
if ((target_mode == TARGET_MODE_CAST) && spellCount) {
//we'll get the container back from the coordinates
TryToCast(actor, container->Pos);
@@ -1735,19 +1862,21 @@ void GameControl::HandleContainer(Container *container, Actor *actor)
actor->ClearActions();
snprintf(Tmp, sizeof(Tmp), "BashDoor(\"%s\")", container->GetScriptName());
actor->AddAction(GenerateAction(Tmp));
+ actor->CommandActor();
return;
}
- if ((target_mode == TARGET_MODE_PICK)) {
+ if (target_mode == TARGET_MODE_PICK) {
TryToPick(actor, container);
return;
}
actor->ClearPath();
actor->ClearActions();
- strncpy(Tmp,"UseContainer()",sizeof(Tmp) );
+ strlcpy(Tmp, "UseContainer()", sizeof(Tmp));
core->SetCurrentContainer( actor, container);
actor->AddAction( GenerateAction( Tmp) );
+ actor->CommandActor();
}
//generate action code for actor appropriate for the target mode when the target is a door
@@ -1773,6 +1902,7 @@ void GameControl::HandleDoor(Door *door, Actor *actor)
actor->ClearActions();
snprintf(Tmp, sizeof(Tmp), "BashDoor(\"%s\")", door->GetScriptName());
actor->AddAction(GenerateAction(Tmp));
+ actor->CommandActor();
return;
}
@@ -1787,6 +1917,7 @@ void GameControl::HandleDoor(Door *door, Actor *actor)
// internal gemrb toggle door action hack - should we use UseDoor instead?
sprintf( Tmp, "NIDSpecial9()" );
actor->AddAction( GenerateAction( Tmp) );
+ actor->CommandActor();
}
//generate action code for actor appropriate for the target mode when the target is an active region (infopoint, trap or travel)
@@ -1798,16 +1929,26 @@ bool GameControl::HandleActiveRegion(InfoPoint *trap, Actor * actor, Point &p)
//don't bother with this region further
return true;
}
- if ((target_mode == TARGET_MODE_PICK)) {
+ if (target_mode == TARGET_MODE_PICK) {
TryToDisarm(actor, trap);
return true;
}
switch(trap->Type) {
case ST_TRAVEL:
- actor->UseExit(trap->GetGlobalID());
+ trap->AddTrigger(TriggerEntry(trigger_clicked, actor->GetGlobalID()));
+ //clear the go closer flag
+ trap->GetCurrentArea()->LastGoCloser = 0;
return false;
case ST_TRIGGER:
+ // always display overhead text; totsc's ar0511 library relies on it
+ if (trap->overHeadText) {
+ if (trap->textDisplaying != 1) {
+ trap->textDisplaying = 1;
+ trap->timeStartDisplaying = core->GetGame()->Ticks;
+ DisplayString( trap );
+ }
+ }
//the importer shouldn't load the script
//if it is unallowed anyway (though
//deactivated scripts could be reactivated)
@@ -1816,30 +1957,20 @@ bool GameControl::HandleActiveRegion(InfoPoint *trap, Actor * actor, Point &p)
//reset trap and deactivated flags
if (trap->Scripts[0]) {
if (!(trap->Flags&TRAP_DEACTIVATED) ) {
- trap->LastTriggerObject = trap->LastTrigger = actor->GetGlobalID();
- trap->ImmediateEvent();
+ trap->AddTrigger(TriggerEntry(trigger_clicked, actor->GetGlobalID()));
//directly feeding the event, even if there are actions in the queue
- trap->Scripts[0]->Update();
- trap->ProcessActions(true);
- //if reset trap flag not set, deactivate it
- //hmm, better not, info triggers don't deactivate themselves on click
- //if (!(trap->Flags&TRAP_RESET)) {
- // trap->Flags|=TRAP_DEACTIVATED;
- //}
- }
- } else {
- if (trap->overHeadText) {
- if (trap->textDisplaying != 1) {
- trap->textDisplaying = 1;
- trap->timeStartDisplaying = core->GetGame()->Ticks;
- DisplayString( trap );
- }
+ //trap->Scripts[0]->Update();
+ // FIXME
+ trap->ExecuteScript(1);
+ trap->ProcessActions();
}
}
- if (trap->Flags&TRAP_USEPOINT) {
- //overriding the target point
- p = trap->UsePoint;
- return false;
+ if (trap->GetUsePoint() ) {
+ char Tmp[256];
+ sprintf(Tmp, "TriggerWalkTo(\"%s\")", trap->GetScriptName());
+ actor->AddAction(GenerateAction(Tmp));
+ actor->CommandActor();
+ return true;
}
return true;
default:;
@@ -1848,13 +1979,17 @@ bool GameControl::HandleActiveRegion(InfoPoint *trap, Actor * actor, Point &p)
}
/** Mouse Button Down */
void GameControl::OnMouseDown(unsigned short x, unsigned short y, unsigned short Button,
- unsigned short /*Mod*/)
+ unsigned short Mod)
{
if (ScreenFlags&SF_DISABLEMOUSE)
return;
short px=x;
short py=y;
+
+ core->GetVideoDriver()->ConvertToGame( px, py );
+ FormationRotation = false;
+
DoubleClick = false;
switch(Button)
{
@@ -1864,10 +1999,22 @@ void GameControl::OnMouseDown(unsigned short x, unsigned short y, unsigned short
case GEM_MB_SCRLDOWN:
OnSpecialKeyPress(GEM_DOWN);
break;
+ case GEM_MB_MENU: //right click.
+ if (core->HasFeature(GF_HAS_FLOAT_MENU) && !Mod) {
+ core->GetGUIScriptEngine()->RunFunction( "GUICommon", "OpenFloatMenuWindow", false, Point (x, y));
+ }
+ else if (target_mode == TARGET_MODE_NONE) {
+ ClearMouseState();
+ if (core->GetGame()->selected.size() > 1) {
+ FormationRotation = true;
+ FormationPivotPoint.x = px;
+ FormationPivotPoint.y = py;
+ }
+ }
+ break;
case GEM_MB_ACTION|GEM_MB_DOUBLECLICK:
DoubleClick = true;
case GEM_MB_ACTION:
- core->GetVideoDriver()->ConvertToGame( px, py );
MouseIsDown = true;
SelectionRect.x = px;
SelectionRect.y = py;
@@ -1875,15 +2022,15 @@ void GameControl::OnMouseDown(unsigned short x, unsigned short y, unsigned short
StartY = py;
SelectionRect.w = 0;
SelectionRect.h = 0;
-#ifdef TOUCHSCREEN
- touched=true;
-#endif
+ if (touchScrollAreasEnabled) {
+ touched=true;
+ }
}
}
/** Mouse Button Up */
void GameControl::OnMouseUp(unsigned short x, unsigned short y, unsigned short Button,
- unsigned short /*Mod*/)
+ unsigned short Mod)
{
unsigned int i;
char Tmp[256];
@@ -1902,33 +2049,30 @@ void GameControl::OnMouseUp(unsigned short x, unsigned short y, unsigned short B
Map* area = game->GetCurrentArea( );
if (!area) return;
-#ifdef TOUCHSCREEN
- touched=false;
- if (scrolling) {
- moveX = 0;
- moveY = 0;
- scrolling=false;
- Video* video = core->GetVideoDriver();
- video->SetDragCursor(NULL);
- if (DrawSelectionRect) {
- Actor** ab;
- unsigned int count = area->GetActorInRect( ab, SelectionRect,true );
- if (count != 0) {
- for (i = 0; i < highlighted.size(); i++)
- highlighted[i]->SetOver( false );
- highlighted.clear();
- game->SelectActor( NULL, false, SELECT_NORMAL );
- for (i = 0; i < count; i++) {
- // FIXME: should call handler only once
- game->SelectActor( ab[i], true, SELECT_NORMAL );
+ if (touchScrollAreasEnabled) {
+ touched=false;
+ if (scrolling) {
+ SetScrolling(false);
+ if (DrawSelectionRect) {
+ Actor** ab;
+ unsigned int count = area->GetActorInRect( ab, SelectionRect,true );
+ if (count != 0) {
+ for (i = 0; i < highlighted.size(); i++)
+ highlighted[i]->SetOver( false );
+ highlighted.clear();
+ game->SelectActor( NULL, false, SELECT_NORMAL );
+ for (i = 0; i < count; i++) {
+ // FIXME: should call handler only once
+ game->SelectActor( ab[i], true, SELECT_NORMAL );
+ }
}
+ free( ab );
+ DrawSelectionRect = false;
}
- free( ab );
- DrawSelectionRect = false;
+ return;
}
- return;
}
-#endif
+
if (DrawSelectionRect) {
Actor** ab;
unsigned int count = area->GetActorInRect( ab, SelectionRect,true );
@@ -1947,23 +2091,34 @@ void GameControl::OnMouseUp(unsigned short x, unsigned short y, unsigned short B
return;
}
- //hidden actors are not selectable by clicking on them
- Actor* actor = area->GetActor( p, GA_DEFAULT /*| GA_NO_DEAD */| GA_NO_HIDDEN | target_types);
- if (Button == GEM_MB_MENU) {
+ //hidden actors are not selectable by clicking on them unless they're party members
+ Actor* actor = NULL;
+ if (!FormationRotation) {
+ actor = area->GetActor(p, target_types & ~GA_NO_HIDDEN);
+ if (actor && actor->Modified[IE_EA]>=EA_CONTROLLED) {
+ if (!actor->ValidTarget(GA_NO_HIDDEN)) {
+ actor = NULL;
+ }
+ }
+ }
+ if (Button == GEM_MB_MENU && (!core->HasFeature(GF_HAS_FLOAT_MENU) || Mod)) {
if (actor) {
- //from GSUtils
- DisplayStringCore(actor, VB_SELECT+core->Roll(1,3,-1), DS_CONST|DS_CONSOLE);
+ //play select sound on right click on actor
+ actor->PlaySelectionSound();
return;
}
- core->GetDictionary()->SetAt( "MenuX", x );
- core->GetDictionary()->SetAt( "MenuY", y );
- core->GetGUIScriptEngine()->RunFunction( "GUICommon", "OpenFloatMenuWindow" );
- return;
+ // reset the action bar
+ core->GetGUIScriptEngine()->RunFunction("GUICommonWindows", "EmptyControls");
+ core->SetEventFlag(EF_ACTION);
+ if (!FormationRotation) {
+ return;
+ }
+ FormationRotation = false;
+ //refresh the mouse cursor
+ core->GetEventMgr()->FakeMouseMove();
}
- if (Button != GEM_MB_ACTION) {
- return;
- }
+ if (Button > GEM_MB_MENU) return;
if (!game->selected.size()) {
//TODO: this is a hack, we need some restructuring here
@@ -1983,30 +2138,30 @@ void GameControl::OnMouseUp(unsigned short x, unsigned short y, unsigned short B
pc = game->selected[0];
}
if (!actor) {
- //add a check if you don't want some random monster handle doors and such
- if (overDoor) {
- HandleDoor(overDoor, pc);
- return;
- }
- if (overContainer) {
- HandleContainer(overContainer, pc);
- return;
- }
- if (overInfoPoint) {
- if (overInfoPoint->Type==ST_TRAVEL) {
- int i = game->selected.size();
- ieDword exitID = overInfoPoint->GetGlobalID();
- while(i--) {
- game->selected[i]->UseExit(exitID);
+ if (Button == GEM_MB_ACTION) {
+ //add a check if you don't want some random monster handle doors and such
+ if (overDoor) {
+ HandleDoor(overDoor, pc);
+ return;
+ }
+ if (overContainer) {
+ HandleContainer(overContainer, pc);
+ return;
+ }
+ if (overInfoPoint) {
+ if (overInfoPoint->Type==ST_TRAVEL) {
+ int i = game->selected.size();
+ ieDword exitID = overInfoPoint->GetGlobalID();
+ while(i--) {
+ game->selected[i]->UseExit(exitID);
+ }
}
- } else {
if (HandleActiveRegion(overInfoPoint, pc, p)) {
core->SetEventFlag(EF_RESETTARGET);
return;
}
}
}
-
//just a single actor, no formation
if (game->selected.size()==1) {
//the player is using an item or spell on the ground
@@ -2040,6 +2195,7 @@ void GameControl::OnMouseUp(unsigned short x, unsigned short y, unsigned short B
party.push_back(act);
}
}
+ //summons etc
for (i = 0; i < game->selected.size(); i++) {
Actor *act = game->selected[i];
if (!act->InParty) {
@@ -2048,12 +2204,24 @@ void GameControl::OnMouseUp(unsigned short x, unsigned short y, unsigned short B
}
//party formation movement
- Point src = party[0]->Pos;
+ Point src;
+ //p = FormationPivotPoint;
+ if (Button == GEM_MB_MENU) {
+ p = FormationPivotPoint;
+ src = FormationApplicationPoint;
+ } else {
+ src = party[0]->Pos;
+ }
+ Point move;
+
for(i = 0; i < party.size(); i++) {
actor = party[i];
actor->ClearPath();
actor->ClearActions();
- MoveToPointFormation(actor, i, src, p);
+
+ Map* map = actor->GetCurrentArea();
+ move = GetFormationPoint(map, i, src, p);
+ CreateMovement(actor, move);
}
if (DoubleClick) Center(x,y);
@@ -2068,12 +2236,49 @@ void GameControl::OnMouseUp(unsigned short x, unsigned short y, unsigned short B
//we got an actor past this point
if (target_mode == TARGET_MODE_NONE) {
- DisplayStringCore(actor, VB_SELECT+core->Roll(1,3,-1), DS_CONST|DS_CONSOLE);
+ //play select sound
+ actor->PlaySelectionSound();
}
PerformActionOn(actor);
}
+void GameControl::OnMouseWheelScroll(short x, short y)
+{
+ Region Viewport = core->GetVideoDriver()->GetViewport();
+ Game* game = core->GetGame();
+ Map *map = game->GetCurrentArea();
+ if (!map) return;
+
+ Point mapsize = map->TMap->GetMapSize();
+
+ Viewport.x += x;
+ if (Viewport.x <= 0) {
+ Viewport.x = 0;
+ } else if (Viewport.x + Viewport.w >= mapsize.x) {
+ Viewport.x = mapsize.x - Viewport.w - 1;
+ }
+
+ Viewport.y += y;
+ if (Viewport.y <= 0) {
+ Viewport.y = 0;
+ } else if (Viewport.y + Viewport.h >= mapsize.y) {
+ Viewport.y = mapsize.y - Viewport.h - 1;
+ }
+
+ if (ScreenFlags & SF_LOCKSCROLL) {
+ moveX = 0;
+ moveY = 0;
+ } else {
+ // override any existing viewport moves which may be in progress
+ core->timer->SetMoveViewPort( Viewport.x, Viewport.y, 0, false );
+ // move it directly ourselves, since we might be paused
+ core->GetVideoDriver()->MoveViewportTo( Viewport.x, Viewport.y );
+ }
+ //update cursor
+ core->GetEventMgr()->FakeMouseMove();
+}
+
void GameControl::PerformActionOn(Actor *actor)
{
Game* game = core->GetGame();
@@ -2184,13 +2389,9 @@ void GameControl::PerformActionOn(Actor *actor)
//sets target mode, and resets the cursor
void GameControl::SetTargetMode(int mode) {
- int x,y;
-
target_mode = mode;
- //This hack is to refresh the mouse cursor
- core->GetVideoDriver()->GetMousePos(x,y);
- //calling into the videodriver to set the mouseposition won't work
- core->GetEventMgr()->MouseMove(x,y);
+ //refresh the mouse cursor
+ core->GetEventMgr()->FakeMouseMove();
}
void GameControl::ResetTargetMode() {
@@ -2203,7 +2404,7 @@ void GameControl::UpdateTargetMode() {
}
/** Special Key Press */
-void GameControl::OnSpecialKeyPress(unsigned char Key)
+bool GameControl::OnSpecialKeyPress(unsigned char Key)
{
if (DialogueFlags&DF_IN_DIALOG) {
switch(Key) {
@@ -2212,90 +2413,57 @@ void GameControl::OnSpecialKeyPress(unsigned char Key)
core->GetGUIScriptEngine()->RunFunction("GUIWORLD", "CloseContinueWindow");
break;
}
- return; //don't accept keys in dialog
+ return false; //don't accept keys in dialog
}
- Region Viewport = core->GetVideoDriver()->GetViewport();
Game *game = core->GetGame();
- if (!game) return;
- Map *map = game->GetCurrentArea();
- if (!map) return;
-
- Point mapsize = map->TMap->GetMapSize();
+ if (!game) return false;
int partysize = game->GetPartySize(false);
+
int pm;
- char tmpstr[10];
-
+ ieDword keyScrollSpd = 64;
+ core->GetDictionary()->Lookup("Keyboard Scroll Speed", keyScrollSpd);
switch (Key) {
case GEM_LEFT:
- if (Viewport.x > 63)
- Viewport.x -= 64;
- else
- Viewport.x = 0;
+ OnMouseWheelScroll(keyScrollSpd * -1, 0);
break;
case GEM_UP:
- if (Viewport.y > 63)
- Viewport.y -= 64;
- else
- Viewport.y = 0;
+ OnMouseWheelScroll(0, keyScrollSpd * -1);
break;
case GEM_DOWN:
- if (Viewport.y + Viewport.h + 64 < mapsize.y)
- Viewport.y += 64;
- else {
- Viewport.y = mapsize.y - Viewport.h;
- if (Viewport.y<0) Viewport.y=0;
- }
+ OnMouseWheelScroll(0, keyScrollSpd);
break;
case GEM_RIGHT:
- if (Viewport.x + Viewport.w + 64 < mapsize.x)
- Viewport.x += 64;
- else {
- Viewport.x = mapsize.x - Viewport.w;
- if (Viewport.x<0) Viewport.x=0;
- }
+ OnMouseWheelScroll(keyScrollSpd, 0);
break;
case GEM_ALT:
DebugFlags |= DEBUG_SHOW_CONTAINERS;
- return;
+ break;
case GEM_TAB:
// show partymember hp/maxhp as overhead text
for (pm=0; pm < partysize; pm++) {
Actor *pc = game->GetPC(pm, true);
if (!pc) continue;
- //sucks but this is set in different places
- if (pc->GetStat(IE_MC_FLAGS) & MC_HIDE_HP) continue;
- if (pc->GetStat(IE_EXTSTATE_ID) & EXTSTATE_NO_HP) continue;
- memset(tmpstr, 0, 10);
- snprintf(tmpstr, 10, "%d/%d", pc->Modified[IE_HITPOINTS], pc->Modified[IE_MAXHITPOINTS]);
- pc->DisplayHeadText(strdup(tmpstr));
+ pc->DisplayHeadHPRatio();
}
- return;
+ break;
case GEM_MOUSEOUT:
moveX = 0;
moveY = 0;
- return;
+ break;
case GEM_ESCAPE:
core->GetGUIScriptEngine()->RunFunction("GUICommonWindows", "EmptyControls");
- core->SetEventFlag(EF_ACTION);
- return;
+ core->SetEventFlag(EF_ACTION|EF_RESETTARGET);
+ break;
case GEM_PGUP:
core->GetGUIScriptEngine()->RunFunction("CommonWindow","OnIncreaseSize");
- return;
+ break;
case GEM_PGDOWN:
core->GetGUIScriptEngine()->RunFunction("CommonWindow","OnDecreaseSize");
- return;
+ break;
default:
- return;
- }
- if (ScreenFlags & SF_LOCKSCROLL) {
- moveX = 0;
- moveY = 0;
- } else {
- // override any existing viewport moves which may be in progress
- core->timer->SetMoveViewPort( Viewport.x, Viewport.y, 0, false );
- // move it directly ourselves, since we might be paused
- core->GetVideoDriver()->MoveViewportTo( Viewport.x, Viewport.y );
+ return false;
}
+ return true;
}
void GameControl::CalculateSelection(const Point &p)
@@ -2387,8 +2555,8 @@ void GameControl::HandleWindowHide(const char *WindowName, const char *WindowPos
}
return;
}
- printMessage("GameControl", "Invalid Window Index: ", LIGHT_RED);
- printf("%s:%u\n",WindowName, index);
+ Log(ERROR, "GameControl", "Invalid Window Index: %s:%u",
+ WindowName, index);
}
}
}
@@ -2440,8 +2608,8 @@ void GameControl::HandleWindowReveal(const char *WindowName, const char *WindowP
}
return;
}
- printMessage("GameControl", "Invalid Window Index ", LIGHT_RED);
- printf("%s:%u\n",WindowName, index);
+ Log(ERROR, "GameControl", "Invalid Window Index %s:%u",
+ WindowName, index);
}
}
}
@@ -2487,7 +2655,7 @@ void GameControl::ResizeDel(Window* win, int type)
switch (type) {
case 0: //Left
if (LeftCount!=1) {
- printMessage("GameControl","More than one left window!\n",LIGHT_RED);
+ Log(ERROR, "GameControl", "More than one left window!");
}
LeftCount--;
if (!LeftCount) {
@@ -2499,7 +2667,7 @@ void GameControl::ResizeDel(Window* win, int type)
case 1: //Bottom
if (BottomCount!=1) {
- printMessage("GameControl","More than one bottom window!\n",LIGHT_RED);
+ Log(ERROR, "GameControl", "More than one bottom window!");
}
BottomCount--;
if (!BottomCount) {
@@ -2510,7 +2678,7 @@ void GameControl::ResizeDel(Window* win, int type)
case 2: //Right
if (RightCount!=1) {
- printMessage("GameControl","More than one right window!\n",LIGHT_RED);
+ Log(ERROR, "GameControl", "More than one right window!");
}
RightCount--;
if (!RightCount) {
@@ -2521,7 +2689,7 @@ void GameControl::ResizeDel(Window* win, int type)
case 3: //Top
if (TopCount!=1) {
- printMessage("GameControl","More than one top window!\n",LIGHT_RED);
+ Log(ERROR, "GameControl", "More than one top window!");
}
TopCount--;
if (!TopCount) {
@@ -2598,6 +2766,7 @@ void GameControl::ResizeAdd(Window* win, int type)
}
//Create an overhead text over an arbitrary point
+// UNUSED
void GameControl::DisplayString(const Point &p, const char *Text)
{
Scriptable* scr = new Scriptable( ST_TRIGGER );
@@ -2621,6 +2790,14 @@ void GameControl::DisplayString(Scriptable* target)
scr->textDisplaying = 1;
scr->timeStartDisplaying = target->timeStartDisplaying;
scr->Pos = target->Pos;
+
+ // add as a "subtitle" to the main message window
+ ieDword tmp = 0;
+ core->GetDictionary()->Lookup("Duplicate Floating Text", tmp);
+ if (tmp) {
+ // pass NULL target so pst does not display multiple
+ displaymsg->DisplayString(target->overHeadText, NULL);
+ }
}
/** changes displayed map to the currently selected PC */
@@ -2644,7 +2821,7 @@ void GameControl::ChangeMap(Actor *pc, bool forced)
//center on first selected actor
Video *video = core->GetVideoDriver();
Region vp = video->GetViewport();
- if (ScreenFlags&SF_CENTERONACTOR) {
+ if (pc && (ScreenFlags&SF_CENTERONACTOR)) {
core->timer->SetMoveViewPort( pc->Pos.x, pc->Pos.y, 0, true );
video->MoveViewportTo( pc->Pos.x-vp.w/2, pc->Pos.y-vp.h/2 );
ScreenFlags&=~SF_CENTERONACTOR;
@@ -2695,7 +2872,7 @@ Sprite2D* GameControl::GetScreenshot(bool show_gui)
//copies a downscaled screenshot into a sprite for save game preview
Sprite2D* GameControl::GetPreview()
{
- // We get preview by first taking a screenshot of size 640x405,
+ // We get preview by first taking a screenshot of quintuple size of the preview control size (a few pixels bigger only in pst),
// centered in the display. This is to get a decent picture for
// higher screen resolutions.
// FIXME: how do orig games solve that?
@@ -2708,27 +2885,20 @@ Sprite2D* GameControl::GetPreview()
if (x < 0) {
x = 0;
} else {
- w = 640;
+ w = 515;
}
if (y < 0) {
y = 0;
} else {
- h = 405;
+ h = 385;
}
if (!x)
y = 0;
- int hf = HideGUI ();
- signed char v = Owner->Visible;
- Owner->Visible = WINDOW_VISIBLE;
Draw (0, 0);
- Owner->Visible = v;
Sprite2D *screenshot = video->GetScreenshot( Region(x, y, w, h) );
- if (hf) {
- UnhideGUI ();
- }
core->DrawWindows();
Sprite2D* preview = video->SpriteScaleDown ( screenshot, 5 );
@@ -2847,3 +3017,9 @@ void GameControl::SetDisplayText(ieStrRef text, unsigned int time)
SetDisplayText(core->GetString(displaymsg->GetStringReference(text), 0), time);
}
+void GameControl::ToggleAlwaysRun()
+{
+ AlwaysRun = !AlwaysRun;
+}
+
+}
diff --git a/gemrb/core/GUI/GameControl.h b/gemrb/core/GUI/GameControl.h
index 0ff21d3..08fdb02 100644
--- a/gemrb/core/GUI/GameControl.h
+++ b/gemrb/core/GUI/GameControl.h
@@ -35,6 +35,8 @@
#include "Interface.h"
#include "Map.h"
+namespace GemRB {
+
class GameControl;
class Window;
class DialogHandler;
@@ -81,6 +83,8 @@ class DialogHandler;
#define TARGET_TYPE_ALL 0 //(TARGET_TYPE_ALLY | TARGET_TYPE_ENEMY | TARGET_TYPE_NEUTRAL)
*/
+static const unsigned long tp_steps[8]={3,2,1,0,1,2,3,4};
+
/**
* @class GameControl
* Widget displaying areas, where most of the game 'happens'.
@@ -96,10 +100,10 @@ public:
public:
/** Draws the Control on the Output Display */
void Draw(unsigned short x, unsigned short y);
- /** Sets the Text of the current control */
- int SetText(const char* string, int pos = 0);
+ /** Draws the target reticle for Actor movement. */
+ void DrawTargetReticle(Point p, int size, bool animate, bool flash=false, bool actorSelected=false);
/** Sets multiple quicksaves flag*/
- static void MultipleQuickSaves(int arg);
+ //static void MultipleQuickSaves(int arg);
void SetTracker(Actor *actor, ieDword dist);
private:
ieDword lastActorID;
@@ -107,30 +111,34 @@ private:
ieDword distance; //tracking distance
std::vector< Actor*> highlighted;
bool DrawSelectionRect;
+ bool FormationRotation;
bool MouseIsDown;
bool DoubleClick;
Region SelectionRect;
+ Point FormationPivotPoint;
+ Point FormationApplicationPoint;
short StartX, StartY;
- //int action;
-#ifdef TOUCHSCREEN
+ // following variables used for touch scroll areas
+ bool touchScrollAreasEnabled; // true, if scroll areas enabled
bool touched; // true, if player touched screen (left button down and hold)
-#endif
+ unsigned int scrollAreasWidth; // scroll areas width
+
public:
Door* overDoor;
Container* overContainer;
InfoPoint* overInfoPoint;
- // allow targetting allies, enemies and/or neutrals (bitmask)
+ // allow targeting allies, enemies and/or neutrals (bitmask)
int target_types;
+ unsigned short lastMouseX, lastMouseY;
private:
- // currently selected targetting type, such as talk, attack, cast, ...
+ // currently selected targeting type, such as talk, attack, cast, ...
// private to enforce proper cursor changes
int target_mode;
unsigned char lastCursor;
short moveX, moveY;
int numScrollCursor;
bool scrolling;
- unsigned short lastMouseX, lastMouseY;
int DebugFlags;
Point pfs;
PathNode* drawPath;
@@ -139,12 +147,12 @@ private:
int DialogueFlags;
char *DisplayText;
unsigned int DisplayTextTime;
- bool EnableRunning;
+ bool AlwaysRun;
public: //Events
/** Key Press Event */
- void OnKeyPress(unsigned char Key, unsigned short Mod);
+ bool OnKeyPress(unsigned char Key, unsigned short Mod);
/** Key Release Event */
- void OnKeyRelease(unsigned char Key, unsigned short Mod);
+ bool OnKeyRelease(unsigned char Key, unsigned short Mod);
/** Mouse Over Event */
void OnMouseOver(unsigned short x, unsigned short y);
/** Global Mouse Move Event */
@@ -155,25 +163,24 @@ public: //Events
/** Mouse Button Up */
void OnMouseUp(unsigned short x, unsigned short y, unsigned short Button,
unsigned short Mod);
+ void OnMouseWheelScroll(short x, short y);
/** Special Key Press */
- void OnSpecialKeyPress(unsigned char Key);
+ bool OnSpecialKeyPress(unsigned char Key);
void DisplayTooltip();
void UpdateScrolling();
+ void SetScrolling(bool scroll);
void SetTargetMode(int mode);
int GetTargetMode() { return target_mode; }
void SetScreenFlags(int value, int mode);
void SetDialogueFlags(int value, int mode);
int GetScreenFlags() { return ScreenFlags; }
int GetDialogueFlags() { return DialogueFlags; }
- /** this function is called from the area when autosave is needed */
- void AutoSave();
void SetDisplayText(char *text, unsigned int time);
void SetDisplayText(ieStrRef text, unsigned int time);
/* centers viewport to the points specified */
void Center(unsigned short x, unsigned short y);
+ void ClearMouseState();
private:
- /** this function is called when the user presses 'q' (or equivalent) */
- void QuickSave();
/** this function safely retrieves an Actor by ID */
Actor *GetActorByGlobalID(ieDword ID);
void CalculateSelection(const Point &p);
@@ -183,7 +190,7 @@ private:
void HandleWindowReveal(const char *WindowName, const char *WindowPosition);
void ReadFormations();
/** Draws an arrow on the edge of the screen based on the point (points at offscreen actors) */
- void DrawArrowMarker(const Region &screen, Point p, const Region &viewport);
+ void DrawArrowMarker(const Region &screen, Point p, const Region &viewport, const Color& color);
private:
unsigned char LeftCount, BottomCount, RightCount, TopCount;
@@ -231,7 +238,7 @@ public:
bool HandleActiveRegion(InfoPoint *trap, Actor *actor, Point &p);
Point GetFormationOffset(ieDword formation, ieDword pos);
- void MoveToPointFormation(Actor *actor, unsigned int pos, Point src, Point p);
+ Point GetFormationPoint(Map *map, unsigned int pos, Point src, Point p);
/** calls MoveToPoint or RunToPoint */
void CreateMovement(Actor *actor, const Point &p);
/** Displays a string over an object */
@@ -252,6 +259,9 @@ public:
/** Page is the spell type + spell level info */
void SetupCasting(ieResRef spellname, int type, int level, int slot, Actor *actor, int targettype, int cnt);
bool SetEvent(int eventType, EventHandler handler);
+ void ToggleAlwaysRun();
};
+}
+
#endif
diff --git a/gemrb/core/GUI/Label.cpp b/gemrb/core/GUI/Label.cpp
index 4d67af4..8c8b959 100644
--- a/gemrb/core/GUI/Label.cpp
+++ b/gemrb/core/GUI/Label.cpp
@@ -25,8 +25,12 @@
#include "GameData.h"
#include "Interface.h"
#include "Palette.h"
+#include "Sprite2D.h"
#include "Variables.h"
#include "Video.h"
+#include "GUI/Window.h"
+
+namespace GemRB {
Label::Label(Font* font)
{
@@ -57,7 +61,7 @@ void Label::Draw(unsigned short x, unsigned short y)
}
if (font && Buffer) {
font->Print( Region( this->XPos + x, this->YPos + y,
- this->Width, this->Height ), ( unsigned char * ) Buffer,
+ this->Width, this->Height ), (unsigned char*)Buffer,
useRGB?palette:NULL,
Alignment | IE_FONT_SINGLE_LINE, true );
}
@@ -71,7 +75,7 @@ void Label::Draw(unsigned short x, unsigned short y)
}
/** This function sets the actual Label Text */
-int Label::SetText(const char* string, int /*pos*/)
+void Label::SetText(const char* string)
{
if (Buffer )
free( Buffer );
@@ -95,7 +99,6 @@ int Label::SetText(const char* string, int /*pos*/)
if (Owner) {
Owner->Invalidate();
}
- return 0;
}
/** Sets the Foreground Font Color */
void Label::SetColor(Color col, Color bac)
@@ -110,7 +113,7 @@ void Label::SetAlignment(unsigned char Alignment)
this->Alignment = Alignment;
if (Alignment == IE_FONT_ALIGN_CENTER) {
if (core->HasFeature( GF_LOWER_LABEL_TEXT )) {
- strlwr( Buffer );
+ strtolower( Buffer );
}
}
Changed = true;
@@ -119,7 +122,7 @@ void Label::SetAlignment(unsigned char Alignment)
void Label::OnMouseUp(unsigned short x, unsigned short y,
unsigned short /*Button*/, unsigned short /*Mod*/)
{
- //printf( "Label::OnMouseUp\n" );
+ //print("Label::OnMouseUp");
if (( x <= Width ) && ( y <= Height )) {
if (VarName[0] != 0) {
core->GetDictionary()->SetAt( VarName, Value );
@@ -150,3 +153,5 @@ const char* Label::QueryText() const
{
return ( const char * ) Buffer;
}
+
+}
diff --git a/gemrb/core/GUI/Label.h b/gemrb/core/GUI/Label.h
index b0a841d..c553f7a 100644
--- a/gemrb/core/GUI/Label.h
+++ b/gemrb/core/GUI/Label.h
@@ -34,6 +34,8 @@
#include "Font.h"
+namespace GemRB {
+
class Palette;
// !!! Keep these synchronized with GUIDefines.py !!!
@@ -51,9 +53,11 @@ public:
/** Draws the Control on the Output Display */
void Draw(unsigned short x, unsigned short y);
/** This function sets the actual Label Text */
- int SetText(const char* string, int pos = 0);
+ void SetText(const char* string);
/** Sets the Foreground Font Color */
void SetColor(Color col, Color bac);
+ /** Set the font being used */
+ void SetFont(Font *font) { this->font = font; }
/** Sets the Alignment of Text */
void SetAlignment(unsigned char Alignment);
/** Simply returns the pointer to the text, don't modify it! */
@@ -80,4 +84,6 @@ private: // Private attributes
unsigned char Alignment;
};
+}
+
#endif
diff --git a/gemrb/core/GUI/MapControl.cpp b/gemrb/core/GUI/MapControl.cpp
index 4abd158..0380ded 100644
--- a/gemrb/core/GUI/MapControl.cpp
+++ b/gemrb/core/GUI/MapControl.cpp
@@ -20,11 +20,19 @@
#include "GUI/MapControl.h"
#include "win32def.h"
+#include "ie_cursors.h"
#include "Game.h"
+#include "GlobalTimer.h"
#include "Interface.h"
#include "Map.h"
+#include "Sprite2D.h"
#include "Video.h"
+#include "GUI/EventMgr.h"
+#include "GUI/Window.h"
+#include "Scriptable/Actor.h"
+
+namespace GemRB {
#define MAP_NO_NOTES 0
#define MAP_VIEW_NOTES 1
@@ -168,7 +176,7 @@ void MapControl::Realize()
if (YCenter < 0) YCenter = 0;
}
-void MapControl::RedrawMapControl(const char *VariableName, unsigned int Sum)
+void MapControl::UpdateState(const char *VariableName, unsigned int Sum)
{
if (strnicmp( VarName, VariableName, MAX_VARIABLE_LENGTH )) {
return;
@@ -224,6 +232,11 @@ void MapControl::Draw(unsigned short XWin, unsigned short YWin)
vp.w = ViewWidth;
vp.h = ViewHeight;
+ if ((vp.x + vp.w) >= MAP_TO_SCREENX( Width ))
+ vp.w = MAP_TO_SCREENX( Width ) - vp.x;
+ if ((vp.y + vp.h) >= MAP_TO_SCREENY( Height ))
+ vp.h = MAP_TO_SCREENY( Height ) - vp.y;
+
video->DrawRect( vp, colors[green], false, false );
// Draw PCs' ellipses
@@ -268,40 +281,6 @@ void MapControl::Draw(unsigned short XWin, unsigned short YWin)
}
}
-/** Key Press Event */
-void MapControl::OnKeyPress(unsigned char Key, unsigned short /*Mod*/)
-{
-#ifdef ANDROID
- switch(Key) {
- case 'o':
- case 'p':
- Control::OnKeyPress(Key, 0);
- break;
- }
-#else
-(void)Key; // unused, fool the compiler
-#endif
-}
-
-/** Key Release Event */
-void MapControl::OnKeyRelease(unsigned char Key, unsigned short Mod)
-{
- switch (Key) {
- case '\t':
- //not GEM_TAB
- printf( "TAB released\n" );
- return;
- case 'f':
- if (Mod & GEM_MOD_CTRL)
- core->GetVideoDriver()->ToggleFullscreenMode();
- break;
- default:
- break;
- }
- if (!core->CheatEnabled()) {
- return;
- }
-}
/** Mouse Over Event */
void MapControl::OnMouseOver(unsigned short x, unsigned short y)
{
@@ -418,7 +397,7 @@ void MapControl::ViewHandle(unsigned short x, unsigned short y)
void MapControl::OnMouseDown(unsigned short x, unsigned short y, unsigned short Button,
unsigned short /*Mod*/)
{
- switch((unsigned char) Button) {
+ switch((unsigned char) Button & GEM_MB_NORMAL) {
case GEM_MB_SCRLUP:
OnSpecialKeyPress(GEM_UP);
return;
@@ -471,7 +450,7 @@ void MapControl::OnMouseUp(unsigned short x, unsigned short y, unsigned short Bu
return;
case MAP_VIEW_NOTES:
//left click allows setting only when in MAP_SET_NOTE mode
- if ((Button == GEM_MB_ACTION) ) {
+ if (Button == GEM_MB_ACTION) {
ViewHandle(x,y);
}
ClickHandle(Button);
@@ -483,29 +462,25 @@ void MapControl::OnMouseUp(unsigned short x, unsigned short y, unsigned short Bu
}
/** Special Key Press */
-void MapControl::OnSpecialKeyPress(unsigned char Key)
+bool MapControl::OnSpecialKeyPress(unsigned char Key)
{
+ ieDword keyScrollSpd = 64;
+ core->GetDictionary()->Lookup("Keyboard Scroll Speed", keyScrollSpd);
switch (Key) {
case GEM_LEFT:
- ScrollX -= 64;
+ ScrollX -= keyScrollSpd;
break;
case GEM_UP:
- ScrollY -= 64;
+ ScrollY -= keyScrollSpd;
break;
case GEM_RIGHT:
- ScrollX += 64;
+ ScrollX += keyScrollSpd;
break;
case GEM_DOWN:
- ScrollY += 64;
- break;
- case GEM_ALT:
- printf( "ALT pressed\n" );
- break;
- case GEM_TAB:
- printf( "TAB pressed\n" );
+ ScrollY += keyScrollSpd;
break;
default:
- break;
+ return false;
}
if (ScrollX > MapWidth - Width)
@@ -516,6 +491,7 @@ void MapControl::OnSpecialKeyPress(unsigned char Key)
ScrollX = 0;
if (ScrollY < 0)
ScrollY = 0;
+ return true;
}
bool MapControl::SetEvent(int eventType, EventHandler handler)
@@ -538,3 +514,5 @@ bool MapControl::SetEvent(int eventType, EventHandler handler)
return true;
}
+
+}
diff --git a/gemrb/core/GUI/MapControl.h b/gemrb/core/GUI/MapControl.h
index 1154bf8..851225d 100644
--- a/gemrb/core/GUI/MapControl.h
+++ b/gemrb/core/GUI/MapControl.h
@@ -23,8 +23,6 @@
* Declares MapControl, widget for displaying current area map
*/
-class MapControl;
-
#ifndef MAPCONTROL_H
#define MAPCONTROL_H
@@ -33,6 +31,8 @@ class MapControl;
#include "exports.h"
#include "Interface.h"
+namespace GemRB {
+
// !!! Keep these synchronized with GUIDefines.py !!!
#define IE_GUI_MAP_ON_PRESS 0x09000000
#define IE_GUI_MAP_ON_RIGHT_PRESS 0x09000005
@@ -72,18 +72,16 @@ public:
MapControl(void);
~MapControl(void);
- /** redraws the control after its associated variable has changed */
- void RedrawMapControl(const char *VariableName, unsigned int Sum);
+ /** Refreshes the control after its associated variable has changed */
+ void UpdateState(const char *VariableName, unsigned int Sum);
/** Draws the Control on the Output Display */
void Draw(unsigned short XWin, unsigned short YWin);
void DrawFog(unsigned short XWin, unsigned short YWin);
/** Compute parameters after changes in control's or screen geometry */
void Realize();
- /** Sets the Text of the current control */
- int SetText(const char* /*string*/, int /*pos*/) { return 0; }
/** Key Press Event */
- void OnKeyPress(unsigned char Key, unsigned short Mod);
+ //void OnKeyPress(unsigned char Key, unsigned short Mod);
/** Mouse Over Event */
void OnMouseOver(unsigned short x, unsigned short y);
/** Mouse Leave Event */
@@ -94,10 +92,8 @@ public:
/** Mouse Button Up */
void OnMouseUp(unsigned short x, unsigned short y, unsigned short Button,
unsigned short Mod);
- /** Key Release Event */
- void OnKeyRelease(unsigned char Key, unsigned short Mod);
/** Special Key Press */
- void OnSpecialKeyPress(unsigned char Key);
+ bool OnSpecialKeyPress(unsigned char Key);
/** Set handler for specified event */
bool SetEvent(int eventType, EventHandler handler);
private:
@@ -107,4 +103,6 @@ private:
void ViewHandle(unsigned short x, unsigned short y);
};
+}
+
#endif
diff --git a/gemrb/core/GUI/Progressbar.cpp b/gemrb/core/GUI/Progressbar.cpp
index d31f589..43612c9 100644
--- a/gemrb/core/GUI/Progressbar.cpp
+++ b/gemrb/core/GUI/Progressbar.cpp
@@ -24,9 +24,12 @@
#include "Interface.h"
#include "Video.h"
+#include "GUI/Window.h"
#include <cstring>
+namespace GemRB {
+
Progressbar::Progressbar( unsigned short KnobStepsCount, bool Clear)
{
BackGround = NULL;
@@ -120,12 +123,12 @@ void Progressbar::SetPosition(unsigned int pos)
Changed = true;
}
-void Progressbar::RedrawProgressbar(const char* VariableName, int Sum)
+void Progressbar::UpdateState(const char* VariableName, unsigned int Sum)
{
if (strnicmp( VarName, VariableName, MAX_VARIABLE_LENGTH )) {
return;
}
- SetPosition((unsigned int) Sum);
+ SetPosition(Sum);
if((Value==100) && Changed)
RunEventHandler( EndReached );
}
@@ -162,12 +165,6 @@ void Progressbar::SetSliderPos(int x, int y, int x2, int y2)
CapYPos=y2;
}
-/* dummy virtual function */
-int Progressbar::SetText(const char* /*string*/, int /*pos*/)
-{
- return 0;
-}
-
bool Progressbar::SetEvent(int eventType, EventHandler handler)
{
Changed = true;
@@ -182,3 +179,5 @@ bool Progressbar::SetEvent(int eventType, EventHandler handler)
return true;
}
+
+}
diff --git a/gemrb/core/GUI/Progressbar.h b/gemrb/core/GUI/Progressbar.h
index 411ae55..0132843 100644
--- a/gemrb/core/GUI/Progressbar.h
+++ b/gemrb/core/GUI/Progressbar.h
@@ -33,6 +33,8 @@
#include "Animation.h"
#include "Sprite2D.h"
+namespace GemRB {
+
// !!! Keep in sync with GUIDefines.py !!!
#define IE_GUI_PROGRESS_END_REACHED 0x01000000
@@ -60,10 +62,8 @@ public:
void SetBarCap(Sprite2D *img3);
/** Sets the mos coordinates for the progressbar filler mos/cap */
void SetSliderPos(int x, int y, int x2, int y2);
- /** Dummy function */
- int SetText(const char * string, int pos = 0);
- /** Redraws a progressbar which is associated with VariableName */
- void RedrawProgressbar(const char *VariableName, int Sum);
+ /** Refreshes a progressbar which is associated with VariableName */
+ void UpdateState(const char *VariableName, unsigned int Sum);
/** Set handler for specified event */
bool SetEvent(int eventType, EventHandler handler);
@@ -86,4 +86,6 @@ public:
EventHandler EndReached;
};
+}
+
#endif
diff --git a/gemrb/core/GUI/ScrollBar.cpp b/gemrb/core/GUI/ScrollBar.cpp
index aea1b98..a304eff 100644
--- a/gemrb/core/GUI/ScrollBar.cpp
+++ b/gemrb/core/GUI/ScrollBar.cpp
@@ -8,7 +8,7 @@
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
@@ -25,15 +25,20 @@
#include "Interface.h"
#include "Variables.h"
#include "Video.h"
+#include "GUI/EventMgr.h"
+#include "GUI/Window.h"
+
+namespace GemRB {
ScrollBar::ScrollBar(void)
{
Pos = 0;
- Value = 10;
+ Value = 0;
State = 0;
+ stepPx = 0;
ResetEventHandler( ScrollBarOnChange );
ta = NULL;
- for(int i=0;i<SB_RES_COUNT;i++) {
+ for(int i=0;i<SB_RES_COUNT;i++) {
Frames[i]=NULL;
}
}
@@ -41,34 +46,98 @@ ScrollBar::ScrollBar(void)
ScrollBar::~ScrollBar(void)
{
Video *video=core->GetVideoDriver();
- for(int i=0;i<SB_RES_COUNT;i++) {
+ for(int i=0;i<SB_RES_COUNT;i++) {
if(Frames[i]) {
video->FreeSprite(Frames[i]);
}
}
}
+int ScrollBar::GetFrameHeight(int frame) const
+{
+ if (!Frames[frame]) return 0;
+ return Frames[frame]->Height;
+}
+
+void ScrollBar::CalculateStep()
+{
+ if (Value){
+ stepPx = (double)((double)(Height
+ - GetFrameHeight(IE_GUI_SCROLLBAR_SLIDER)
+ - GetFrameHeight(IE_GUI_SCROLLBAR_DOWN_UNPRESSED)
+ - GetFrameHeight(IE_GUI_SCROLLBAR_UP_UNPRESSED)) / (double)(Value));
+ }else{
+ stepPx = 0.0;
+ }
+}
+
/** Sets a new position, relays the change to an associated textarea and calls
any existing GUI OnChange callback */
-void ScrollBar::SetPos(int NewPos)
+void ScrollBar::SetPos(ieDword NewPos, bool redraw)
{
+ if (!Frames[IE_GUI_SCROLLBAR_UP_UNPRESSED]) return;
+
+ if (NewPos > Value) NewPos = Value;
+
+ if (( State & SLIDER_GRAB ) == 0){
+ // set the slider to the exact y for NewPos. in SetPosForY(y) it is set to any arbitrary position that may lie between 2 values.
+ // if the slider is grabbed dont set position! otherwise you will get a flicker as it bounces between exact positioning and arbitrary
+ SliderYPos = ( unsigned short ) ( GetFrameHeight(IE_GUI_SCROLLBAR_UP_UNPRESSED) +
+ ( NewPos * ( ( Height - GetFrameHeight(IE_GUI_SCROLLBAR_SLIDER)
+ - GetFrameHeight(IE_GUI_SCROLLBAR_UP_UNPRESSED)
+ - GetFrameHeight(IE_GUI_SCROLLBAR_DOWN_UNPRESSED) ) /
+ ( double ) ( Value < 1 ? 1 : Value ) ) ) );
+ }
if (Pos && ( Pos == NewPos )) {
return;
}
+
Changed = true;
Pos = (ieWord) NewPos;
if (ta) {
- TextArea* t = ( TextArea* ) ta;
- t->SetRow( Pos );
+ (( TextArea* )ta)->SetRow( Pos );
}
if (VarName[0] != 0) {
core->GetDictionary()->SetAt( VarName, Pos );
}
RunEventHandler( ScrollBarOnChange );
+ if(redraw) core->RedrawAll();
+}
+
+/** Sets the Pos for a given y coordinate (control coordinates) */
+/** Provides per-pixel scrolling. Top = 0px */
+void ScrollBar::SetPosForY(unsigned short y)
+{
+ if (Value > 0) {// if the value is 0 we are simultaneously at both the top and bottom so there is nothing to do
+ unsigned short YMax = Height
+ - GetFrameHeight(IE_GUI_SCROLLBAR_SLIDER)
+ - GetFrameHeight(IE_GUI_SCROLLBAR_DOWN_UNPRESSED)
+ - GetFrameHeight(IE_GUI_SCROLLBAR_UP_UNPRESSED);
+
+ if (y > YMax) y = YMax;
+
+ if (stepPx) {
+ unsigned short NewPos = (unsigned short)(y / stepPx);
+ if (Pos != NewPos) {
+ SetPos( NewPos, false );
+ }
+ if (ta) {
+ // we must "scale" the pixels the slider moves
+ TextArea* t = (TextArea*) ta;
+ unsigned int taY = y * (t->GetRowHeight() / stepPx);
+ t->ScrollToY(taY, this);
+ }
+ SliderYPos = (y + GetFrameHeight(IE_GUI_SCROLLBAR_UP_UNPRESSED) - 0);
+ core->RedrawAll();
+ }
+ }else{
+ // top is our default position
+ SliderYPos = GetFrameHeight(IE_GUI_SCROLLBAR_UP_UNPRESSED);
+ }
}
/** Refreshes the ScrollBar according to a guiscript variable */
-void ScrollBar::RedrawScrollBar(const char* Variable, int Sum)
+void ScrollBar::UpdateState(const char* Variable, unsigned int Sum)
{
if (strnicmp( VarName, Variable, MAX_VARIABLE_LENGTH )) {
return;
@@ -76,20 +145,22 @@ void ScrollBar::RedrawScrollBar(const char* Variable, int Sum)
SetPos( Sum );
}
-/** Mousewheel support */
+/** SDL < 1.3 Mousewheel support */
void ScrollBar::ScrollUp()
{
- if (Pos > 0) {
- SetPos( Pos - 1 );
- }
+ if( Pos ) SetPos( Pos - 1 );
}
-/** Mousewheel support */
+/** SDL < 1.3 Mousewheel support */
void ScrollBar::ScrollDown()
{
- if ( (ieDword) Pos + 1 < Value ) {
- SetPos( Pos + 1 );
- }
+ SetPos( Pos + 1 );
+}
+
+double ScrollBar::GetStep()
+{
+ CalculateStep();
+ return stepPx;
}
/** Draws the ScrollBar control */
@@ -102,44 +173,48 @@ void ScrollBar::Draw(unsigned short x, unsigned short y)
if (XPos == 65535) {
return;
}
- int upMy = Frames[IE_GUI_SCROLLBAR_UP_UNPRESSED]->Height;
- int doMy = Frames[IE_GUI_SCROLLBAR_DOWN_UNPRESSED]->Height;
- unsigned int domy = (Height - doMy);
-
- unsigned short slmy = ( unsigned short )
- ( upMy +
- ( Pos * ( ( domy - Frames[IE_GUI_SCROLLBAR_SLIDER]->Height - upMy ) /
- ( double ) ( Value < 2 ? 1 : Value - 1 ) ) ) );
- unsigned short slx = ( unsigned short ) ((Width - Frames[IE_GUI_SCROLLBAR_SLIDER]->Width) / 2 );
+ Video *video=core->GetVideoDriver();
+ int upMy = GetFrameHeight(IE_GUI_SCROLLBAR_UP_UNPRESSED);
+ int doMy = GetFrameHeight(IE_GUI_SCROLLBAR_DOWN_UNPRESSED);
+ unsigned int domy = (Height - doMy);
+
+ //draw the up button
if (( State & UP_PRESS ) != 0) {
- core->GetVideoDriver()->BlitSprite( Frames[IE_GUI_SCROLLBAR_UP_PRESSED],
- x + XPos, y + YPos, true );
+ if (Frames[IE_GUI_SCROLLBAR_UP_PRESSED])
+ video->BlitSprite( Frames[IE_GUI_SCROLLBAR_UP_PRESSED], x + XPos, y + YPos, true );
} else {
- core->GetVideoDriver()->BlitSprite( Frames[IE_GUI_SCROLLBAR_UP_UNPRESSED],
- x + XPos, y + YPos, true );
+ if (Frames[IE_GUI_SCROLLBAR_UP_UNPRESSED])
+ video->BlitSprite( Frames[IE_GUI_SCROLLBAR_UP_UNPRESSED], x + XPos, y + YPos, true );
}
- int maxy = y + YPos + Height -
- Frames[IE_GUI_SCROLLBAR_DOWN_UNPRESSED]->Height;
- int stepy = Frames[IE_GUI_SCROLLBAR_TROUGH]->Height;
- Region rgn( x + XPos, y + YPos + upMy, Width, domy - upMy);
- for (int dy = y + YPos + upMy; dy < maxy; dy += stepy) {
- core->GetVideoDriver()->BlitSprite( Frames[IE_GUI_SCROLLBAR_TROUGH],
- x + XPos + ( ( Width / 2 ) -
- Frames[IE_GUI_SCROLLBAR_TROUGH]->Width / 2 ),
- dy, true, &rgn );
+ //draw the trough
+ int maxy = y + YPos + Height - GetFrameHeight(IE_GUI_SCROLLBAR_DOWN_UNPRESSED);
+ int stepy = GetFrameHeight(IE_GUI_SCROLLBAR_TROUGH);
+ if (stepy) {
+ Region rgn( x + XPos, y + YPos + upMy, Width, domy - upMy);
+ for (int dy = y + YPos + upMy; dy < maxy; dy += stepy) {
+ //TROUGH surely exists if it has a nonzero height
+ video->BlitSprite( Frames[IE_GUI_SCROLLBAR_TROUGH],
+ x + XPos + ( ( Width / 2 ) - Frames[IE_GUI_SCROLLBAR_TROUGH]->Width / 2 ),
+ dy, true, &rgn );
+ }
}
+ //draw the down button
if (( State & DOWN_PRESS ) != 0) {
- core->GetVideoDriver()->BlitSprite( Frames[IE_GUI_SCROLLBAR_DOWN_PRESSED],
- x + XPos, maxy, true );
+ if (Frames[IE_GUI_SCROLLBAR_DOWN_PRESSED])
+ video->BlitSprite( Frames[IE_GUI_SCROLLBAR_DOWN_PRESSED], x + XPos, maxy, true );
} else {
- core->GetVideoDriver()->BlitSprite( Frames[IE_GUI_SCROLLBAR_DOWN_UNPRESSED],
- x + XPos, maxy, true );
+ if (Frames[IE_GUI_SCROLLBAR_DOWN_UNPRESSED])
+ video->BlitSprite( Frames[IE_GUI_SCROLLBAR_DOWN_UNPRESSED], x + XPos, maxy, true );
}
- core->GetVideoDriver()->BlitSprite( Frames[IE_GUI_SCROLLBAR_SLIDER],
+ //draw the slider if it exists
+ if (Frames[IE_GUI_SCROLLBAR_SLIDER]) {
+ unsigned short slx = ( unsigned short ) ((Width - Frames[IE_GUI_SCROLLBAR_SLIDER]->Width) / 2 );
+ video->BlitSprite( Frames[IE_GUI_SCROLLBAR_SLIDER],
x + XPos + slx + Frames[IE_GUI_SCROLLBAR_SLIDER]->XPos,
- y + YPos + slmy + Frames[IE_GUI_SCROLLBAR_SLIDER]->YPos,
+ y + YPos + Frames[IE_GUI_SCROLLBAR_SLIDER]->YPos + SliderYPos,
true );
+ }
}
/** Sets a ScrollBar GUI resource */
@@ -156,8 +231,8 @@ void ScrollBar::SetImage(unsigned char type, Sprite2D* img)
}
/** Mouse Button Down */
-void ScrollBar::OnMouseDown(unsigned short x, unsigned short y,
- unsigned short Button, unsigned short /*Mod*/)
+void ScrollBar::OnMouseDown(unsigned short /*x*/, unsigned short y,
+ unsigned short Button, unsigned short /*Mod*/)
{
//removing the double click flag, use a more sophisticated method
//if it is needed later
@@ -170,103 +245,54 @@ void ScrollBar::OnMouseDown(unsigned short x, unsigned short y,
ScrollDown();
return;
}
-
- core->RedrawAll();
-
- unsigned short upMx = (unsigned short) Frames[IE_GUI_SCROLLBAR_UP_UNPRESSED]->Width;
- unsigned short upMy = (unsigned short) Frames[IE_GUI_SCROLLBAR_UP_UNPRESSED]->Height;
- unsigned short domy = (unsigned short) (Height - Frames[IE_GUI_SCROLLBAR_DOWN_UNPRESSED]->Height);
- unsigned short slheight = domy - upMy;
- unsigned short refheight = (unsigned short) (slheight - Frames[IE_GUI_SCROLLBAR_SLIDER]->Height);
- double step = refheight / (double) ( Value < 2 ? 1 : Value - 1 );
- unsigned short ymax = upMy + refheight;
- unsigned short ymy = y - upMy;
- unsigned short doMx = (unsigned short) Frames[IE_GUI_SCROLLBAR_DOWN_UNPRESSED]->Width;
- unsigned short slMx = (unsigned short) Frames[IE_GUI_SCROLLBAR_SLIDER]->Width;
- unsigned short slmy = (unsigned short) (upMy + Pos * step);
- unsigned short slMy = (unsigned short) (slmy + Frames[IE_GUI_SCROLLBAR_SLIDER]->Height);
- if (( x <= upMx ) && ( y <= upMy )) {
- if (Pos > 0)
- SetPos( Pos - 1 );
+ if (y <= GetFrameHeight(IE_GUI_SCROLLBAR_UP_UNPRESSED) ) {
State |= UP_PRESS;
+ ScrollUp();
return;
}
- if (y >= domy) {
- if (( x <= doMx ) && ( y <= Height )) {
- if ( (ieDword) Pos + 1 < Value )
- SetPos( Pos + 1 );
- State |= DOWN_PRESS;
- return;
- }
- }
- if (y >= slmy) {
- if (( x <= slMx ) && ( y <= slMy )) {
- State |= SLIDER_GRAB;
- return;
- }
- }
- if (y <= upMy) {
- SetPos( 0 );
+ if (y >= Height - GetFrameHeight(IE_GUI_SCROLLBAR_DOWN_UNPRESSED)) {
+ State |= DOWN_PRESS;
+ ScrollDown();
return;
}
- if (y >= ymax) {
- SetPos( Value - 1 );
+ CalculateStep();
+ // if we made it this far we will jump the nib to y and "grab" it
+ // this way we only need to click once to jump+scroll
+ State |= SLIDER_GRAB;
+ if (y >= SliderYPos && y < SliderYPos + GetFrameHeight(IE_GUI_SCROLLBAR_SLIDER)) {
+ Frames[IE_GUI_SCROLLBAR_SLIDER]->YPos = y - SliderYPos;
return;
}
- unsigned short befst = ( unsigned short ) ( ymy / step );
- unsigned short aftst = befst + 1;
- if (( ymy - ( befst * step ) ) < ( ( aftst * step ) - ymy )) {
- SetPos( befst );
- } else {
- SetPos( aftst );
- }
+ SetPosForY(y - GetFrameHeight(IE_GUI_SCROLLBAR_UP_UNPRESSED));
}
/** Mouse Button Up */
void ScrollBar::OnMouseUp(unsigned short /*x*/, unsigned short /*y*/,
- unsigned short /*Button*/, unsigned short /*Mod*/)
+ unsigned short /*Button*/, unsigned short /*Mod*/)
{
Changed = true;
State = 0;
+ Frames[IE_GUI_SCROLLBAR_SLIDER]->YPos = 0; //this is to clear any offset incurred by grabbing the slider
}
-/** Mouse Over Event */
-void ScrollBar::OnMouseOver(unsigned short /*x*/, unsigned short y)
+/** Mousewheel scroll */
+void ScrollBar::OnMouseWheelScroll(short /*x*/, short y)
{
- if (( State & SLIDER_GRAB ) != 0) {
- core->RedrawAll();
- unsigned short upMy =(unsigned short) Frames[IE_GUI_SCROLLBAR_UP_UNPRESSED]->Height;
- unsigned short domy = (unsigned short) (Height - Frames[IE_GUI_SCROLLBAR_DOWN_UNPRESSED]->Height);
- unsigned short slheight = domy - upMy;
- unsigned short refheight = (unsigned short) (slheight - Frames[IE_GUI_SCROLLBAR_SLIDER]->Height);
- double step = refheight / ( double ) ( Value < 2 ? 1 : Value - 1 );
- unsigned short yzero = (unsigned short) (upMy + Frames[IE_GUI_SCROLLBAR_SLIDER]->Height / 2 );
- unsigned short ymax = yzero + refheight;
- unsigned short ymy = y - yzero;
- if (y <= yzero) {
- SetPos( 0 );
- return;
- }
- if (y >= ymax) {
- SetPos( Value - 1 );
- return;
- }
- unsigned short befst = ( unsigned short ) ( ymy / step );
- unsigned short aftst = befst + 1;
- if (( ymy - ( befst * step ) ) < ( ( aftst * step ) - ymy )) {
- if (befst > Value )
- SetPos( befst );
- } else {
- if (aftst < Value )
- SetPos( aftst );
- }
+ if ( State == 0 ){//dont allow mousewheel to do anything if the slider is being interacted with already.
+ unsigned short fauxY = (SliderYPos - GetFrameHeight(IE_GUI_SCROLLBAR_UP_UNPRESSED));
+ if ((short)fauxY + y <= 0) fauxY = 0;
+ else fauxY += y;
+ SetPosForY(fauxY);
}
}
-/** Sets the Text of the current control */
-int ScrollBar::SetText(const char* /*string*/, int /*pos*/)
+/** Mouse Over Event */
+void ScrollBar::OnMouseOver(unsigned short /*x*/, unsigned short y)
{
- return 0;
+ if (( State & SLIDER_GRAB )
+ && y >= (GetFrameHeight(IE_GUI_SCROLLBAR_UP_UNPRESSED) + Frames[IE_GUI_SCROLLBAR_SLIDER]->YPos)) {
+ SetPosForY(y - GetFrameHeight(IE_GUI_SCROLLBAR_UP_UNPRESSED) - Frames[IE_GUI_SCROLLBAR_SLIDER]->YPos);
+ }
}
/** Sets the Maximum Value of the ScrollBar */
@@ -275,7 +301,7 @@ void ScrollBar::SetMax(unsigned short Max)
Value = Max;
if (Max == 0) {
SetPos( 0 );
- } else if (Pos >= Max) {
+ } else if (Pos >= Max){
SetPos( Max - 1 );
}
}
@@ -295,3 +321,5 @@ bool ScrollBar::SetEvent(int eventType, EventHandler handler)
return true;
}
+
+}
diff --git a/gemrb/core/GUI/ScrollBar.h b/gemrb/core/GUI/ScrollBar.h
index 4a2d172..dab0aeb 100644
--- a/gemrb/core/GUI/ScrollBar.h
+++ b/gemrb/core/GUI/ScrollBar.h
@@ -35,6 +35,8 @@
#include "Sprite2D.h"
+namespace GemRB {
+
// !!! Keep these synchronized with GUIDefines.py !!!
#define IE_GUI_SCROLLBAR_ON_CHANGE 0x07000000
@@ -62,23 +64,30 @@ class GEM_EXPORT ScrollBar : public Control {
public:
ScrollBar(void);
~ScrollBar(void);
+ /** safe method to get the height of a frame */
+ int GetFrameHeight(int frame) const;
/**sets position, updates associated stuff */
- void SetPos(int NewPos);
+ void SetPos(ieDword NewPos, bool redraw = true);
+ void SetPosForY(unsigned short y);
void ScrollUp();
void ScrollDown();
- /**redraws scrollbar if associated with VarName */
- void RedrawScrollBar(const char* VarName, int Sum);
+ double GetStep();
+ /** refreshes scrollbar if associated with VarName */
+ void UpdateState(const char* VarName, unsigned int Sum);
/**/
void Draw(unsigned short x, unsigned short y);
private: //Private attributes
/** Images for drawing the Scroll Bar */
Sprite2D* Frames[SB_RES_COUNT];
- /** Cursor Position */
+ unsigned short SliderYPos;
+ /** Item Index */
unsigned short Pos;
+ /** slider y delta between steps */
+ double stepPx;
/** Scroll Bar Status */
unsigned short State;
- /** Sets the Text of the current control */
- int SetText(const char* string, int pos = 0);
+private:
+ void CalculateStep();
public:
void SetImage(unsigned char type, Sprite2D* img);
/** Sets the Maximum Value of the ScrollBar */
@@ -94,10 +103,14 @@ public: // Public Events
unsigned short Mod);
/** Mouse Over Event */
void OnMouseOver(unsigned short x, unsigned short y);
+ /** Mouse Wheel Scroll Event */
+ void OnMouseWheelScroll(short x, short y);
/** Set handler for specified event */
bool SetEvent(int eventType, EventHandler handler);
/** OnChange Scripted Event Function Name */
EventHandler ScrollBarOnChange;
};
+}
+
#endif
diff --git a/gemrb/core/GUI/Slider.cpp b/gemrb/core/GUI/Slider.cpp
index 09812ab..7c54d34 100644
--- a/gemrb/core/GUI/Slider.cpp
+++ b/gemrb/core/GUI/Slider.cpp
@@ -25,9 +25,12 @@
#include "Interface.h"
#include "Variables.h"
#include "Video.h"
+#include "GUI/Window.h"
#include <cmath>
+namespace GemRB {
+
Slider::Slider(short KnobXPos, short KnobYPos, short KnobStep,
unsigned short KnobStepsCount, bool Clear)
{
@@ -114,8 +117,8 @@ void Slider::SetPosition(unsigned int pos)
Changed = true;
}
-/** Redraws a slider which is associated with VariableName */
-void Slider::RedrawSlider(const char* VariableName, int Sum)
+/** Refreshes a slider which is associated with VariableName */
+void Slider::UpdateState(const char* VariableName, unsigned int Sum)
{
if (strnicmp( VarName, VariableName, MAX_VARIABLE_LENGTH )) {
return;
@@ -273,12 +276,6 @@ void Slider::OnMouseOver(unsigned short x, unsigned short /*y*/)
}
}
-/** Sets the Text of the current control */
-int Slider::SetText(const char* /*string*/, int /*pos*/)
-{
- return 0;
-}
-
/** Sets the slider change event */
bool Slider::SetEvent(int eventType, EventHandler handler)
{
@@ -294,3 +291,5 @@ bool Slider::SetEvent(int eventType, EventHandler handler)
return true;
}
+
+}
diff --git a/gemrb/core/GUI/Slider.h b/gemrb/core/GUI/Slider.h
index 66f26ae..382c38f 100644
--- a/gemrb/core/GUI/Slider.h
+++ b/gemrb/core/GUI/Slider.h
@@ -34,6 +34,8 @@
#include "Sprite2D.h"
+namespace GemRB {
+
// !!! Keep these synchronized with GUIDefines.py !!!
#define IE_GUI_SLIDER_ON_CHANGE 0x02000000
@@ -60,12 +62,10 @@ public:
void SetPosition(unsigned int pos);
/** Sets the selected image */
void SetImage(unsigned char type, Sprite2D * img);
- /** Sets the Text of the current control */
- int SetText(const char * string, int pos = 0);
/** Sets the State of the Slider */
void SetState(int arg) { State=(unsigned char) arg; }
- /** Redraws a slider which is associated with VariableName */
- void RedrawSlider(const char *VariableName, int Sum);
+ /** Refreshes a slider which is associated with VariableName */
+ void UpdateState(const char *VariableName, unsigned int Sum);
private: // Private attributes
/** BackGround Image. If smaller than the Control Size, the image will be tiled. */
@@ -103,4 +103,6 @@ public: // Public Events
EventHandler SliderOnChange;
};
+}
+
#endif
diff --git a/gemrb/core/GUI/TextArea.cpp b/gemrb/core/GUI/TextArea.cpp
index b19ad57..bbd3e38 100644
--- a/gemrb/core/GUI/TextArea.cpp
+++ b/gemrb/core/GUI/TextArea.cpp
@@ -24,7 +24,6 @@
#include "win32def.h"
-#include "Audio.h"
#include "DialogHandler.h"
#include "GameData.h"
#include "ImageMgr.h"
@@ -32,15 +31,20 @@
#include "Palette.h"
#include "Variables.h"
#include "Video.h"
+#include "GUI/EventMgr.h"
+#include "GUI/Window.h"
#include "Scriptable/Actor.h"
#include <cstdio>
#include <cstdlib>
+namespace GemRB {
+
TextArea::TextArea(Color hitextcolor, Color initcolor, Color lowtextcolor)
{
keeplines = 100;
rows = 0;
+ TextYPos = 0;
startrow = 0;
minrow = 0;
Cursor = NULL;
@@ -49,7 +53,6 @@ TextArea::TextArea(Color hitextcolor, Color initcolor, Color lowtextcolor)
seltext = -1;
Value = 0xffffffff;
ResetEventHandler( TextAreaOnChange );
- ResetEventHandler( TextAreaOutOfText );
PortraitResRef[0]=0;
palette = core->CreatePalette( hitextcolor, lowtextcolor );
initpalette = core->CreatePalette( initcolor, lowtextcolor );
@@ -61,7 +64,7 @@ TextArea::TextArea(Color hitextcolor, Color initcolor, Color lowtextcolor)
tmp.g = 152;
tmp.b = 102;
lineselpal = core->CreatePalette( tmp, lowtextcolor );
- InternalFlags = 1;
+ InternalFlags = TA_INITIALS;
//Drop Capitals means initials on!
core->GetDictionary()->Lookup("Drop Capitals", InternalFlags);
if (InternalFlags) {
@@ -90,10 +93,7 @@ void TextArea::RefreshSprite(const char *portrait)
SetAnimPicture(NULL);
}
strnlwrcpy(PortraitResRef, portrait, 8);
- if (!strnicmp(PortraitResRef, "none", 8) ) {
- return;
- }
- ResourceHolder<ImageMgr> im(PortraitResRef);
+ ResourceHolder<ImageMgr> im(PortraitResRef, true);
if (im == NULL) {
return;
}
@@ -126,16 +126,12 @@ void TextArea::Draw(unsigned short x, unsigned short y)
{
unsigned long thisTime;
- GetTime( thisTime);
+ thisTime = GetTickCount();
if (thisTime>starttime) {
starttime = thisTime+ticks;
- smooth--;
- while (smooth<=0) {
- smooth+=ftext->maxHeight;
- if (startrow<rows) {
- startrow++;
- }
- }
+
+ TextYPos++;// can't use ScrollToY
+ if (TextYPos % ftext->maxHeight == 0) SetRow(startrow + 1);
/** Forcing redraw of whole screen before drawing text*/
Owner->Invalidate();
@@ -153,16 +149,11 @@ void TextArea::Draw(unsigned short x, unsigned short y)
if (XPos == 65535) {
return;
}
- size_t linesize = lines.size();
- if (linesize == 0) {
- return;
- }
- //smooth vertical scrolling up
- if (Flags & IE_GUI_TEXTAREA_SMOOTHSCROLL) {
- clip.y+=smooth;
- clip.h-=smooth;
+ if (lines.size() == 0) {
+ return;
}
+ size_t linesize = lines.size() - 1; // -1 because 0 counts
//if textarea is 'selectable' it actually means, it is a listbox
//in this case the selected value equals the line number
@@ -174,12 +165,11 @@ void TextArea::Draw(unsigned short x, unsigned short y)
Buffer[0] = 0;
int len = 0;
int lastlen = 0;
- for (size_t i = 0; i < linesize; i++) {
+ for (size_t i = 0; i <= linesize; i++) {
if (strnicmp( "[s=", lines[i], 3 ) == 0) {
int tlen;
- unsigned long idx, acolor, bcolor;
- char* rest;
- idx = strtoul( lines[i] + 3, &rest, 0 );
+ unsigned long acolor, bcolor;
+ char* rest = strchr( lines[i] + 3, ',' );
if (*rest != ',')
goto notmatched;
acolor = strtoul( rest + 1, &rest, 16 );
@@ -207,7 +197,7 @@ void TextArea::Draw(unsigned short x, unsigned short y)
memcpy( &Buffer[lastlen], lines[i], len - lastlen );
}
lastlen = len;
- if (i != linesize - 1) {
+ if (i != linesize) {
Buffer[lastlen - 1] = '\n';
Buffer[lastlen] = 0;
}
@@ -221,28 +211,25 @@ void TextArea::Draw(unsigned short x, unsigned short y)
} else {
pos = -1;
}
- ftext->PrintFromLine( startrow, clip,
- ( unsigned char * ) Buffer, palette,
- IE_FONT_ALIGN_LEFT, finit, Cursor, pos );
+
+ /* lets fake scrolling the text by simply offsetting the textClip by between 0 and maxHeight pixels.
+ don't forget to increase the clipping height by the same amount */
+ short LineOffset = (short)(TextYPos % ftext->maxHeight);
+ Region textClip(clip.x, clip.y - LineOffset, clip.w, clip.h + LineOffset);
+
+ ftext->PrintFromLine( startrow, textClip,
+ ( unsigned char * ) Buffer, palette,
+ IE_FONT_ALIGN_LEFT, finit, Cursor, pos );
free( Buffer );
video->SetClipRect( NULL );
- //streaming text
- if (linesize>50) {
- //the buffer is filled enough
- return;
- }
- if (core->GetAudioDrv()->IsSpeaking() ) {
- //the narrator is still talking
- return;
- }
- if (RunEventHandler( TextAreaOutOfText )) {
- return;
- }
- if (linesize==lines.size()) {
- ResetEventHandler( TextAreaOutOfText );
- return;
+
+ if ((Flags &IE_GUI_TEXTAREA_SMOOTHSCROLL)
+ && linesize <= (size_t)(1 + (Height - 1) / ftext->maxHeight)) {
+ // streaming text: keep pushing newlines until we have an entire areas worth of them.
+ // this way it will appear that the text scrolls out of view
+ AppendText("\n", -1);
}
- AppendText("\n",-1);
+
return;
}
// normal scrolling textarea
@@ -266,7 +253,7 @@ void TextArea::Draw(unsigned short x, unsigned short y)
ftext->PrintFromLine( sr, clip,
( unsigned char * ) lines[i], pal,
IE_FONT_ALIGN_LEFT, finit, NULL );
- yl = ftext->size[1].h*(lrows[i]-sr);
+ yl = ftext->maxHeight * (lrows[i]-sr);
clip.y+=yl;
clip.h-=yl;
break;
@@ -281,7 +268,7 @@ void TextArea::Draw(unsigned short x, unsigned short y)
pal = palette;
ftext->Print( clip, ( unsigned char * ) lines[i], pal,
IE_FONT_ALIGN_LEFT, true );
- yl = ftext->size[1].h*lrows[i];
+ yl = ftext->maxHeight * lrows[i];
clip.y+=yl;
clip.h-=yl;
@@ -297,36 +284,26 @@ int TextArea::SetScrollBar(Control* ptr)
}
/** Sets the Actual Text */
-int TextArea::SetText(const char* text, int pos)
+void TextArea::SetText(const char* text)
{
- if (pos==0) {
- if (!text[0]) {
- lines.clear();
- lrows.clear();
- }
-
- if (lines.size() == 0) {
- pos = -1;
- }
- }
- if (pos >= ( int ) lines.size()) {
- return -1;
+ if (!text[0]) {
+ Clear();
}
+
int newlen = ( int ) strlen( text );
- if (pos == -1) {
+ if (lines.size() == 0) {
char* str = (char *) malloc( newlen + 1 );
memcpy( str, text, newlen + 1 );
lines.push_back( str );
lrows.push_back( 0 );
} else {
- lines[pos] = (char *) realloc( lines[pos], newlen + 1 );
- memcpy( lines[pos], text, newlen + 1 );
+ lines[0] = (char *) realloc( lines[0], newlen + 1 );
+ memcpy( lines[0], text, newlen + 1 );
}
CurPos = newlen;
CurLine = lines.size()-1;
UpdateControls();
- return 0;
}
void TextArea::SetMinRow(bool enable)
@@ -460,6 +437,18 @@ void TextArea::UpdateControls()
SetRow(pos);
}
}
+
+ GameControl* gc = core->GetGameControl();
+ if (gc && gc->GetDialogueFlags()&DF_IN_DIALOG) {
+ // This hack is to refresh the mouse cursor so that reply below cursor gets
+ // highlighted during a dialog
+ // FIXME: we check DF_IN_DIALOG here to avoid recurssion in the MessageWindowLogger, but what happens when an error happens during dialog?
+ // I'm not super sure about how to avoid that. for now the logger will not log anything in dialog mode.
+ int x,y;
+ core->GetVideoDriver()->GetMousePos(x,y);
+ core->GetEventMgr()->MouseMove(x,y);
+ }
+
core->RedrawAll();
}
@@ -472,14 +461,14 @@ void TextArea::SetFonts(Font* init, Font* text)
}
/** Key Press Event */
-void TextArea::OnKeyPress(unsigned char Key, unsigned short /*Mod*/)
+bool TextArea::OnKeyPress(unsigned char Key, unsigned short /*Mod*/)
{
if (Flags & IE_GUI_TEXTAREA_EDITABLE) {
if (Key >= 0x20) {
Owner->Invalidate();
Changed = true;
int len = GetRowLength(CurLine);
- //printf("len: %d Before: %s\n",len, lines[CurLine]);
+ //print("len: %d Before: %s", len, lines[CurLine]);
lines[CurLine] = (char *) realloc( lines[CurLine], len + 2 );
for (int i = len; i > CurPos; i--) {
lines[CurLine][i] = lines[CurLine][i - 1];
@@ -487,28 +476,28 @@ void TextArea::OnKeyPress(unsigned char Key, unsigned short /*Mod*/)
lines[CurLine][CurPos] = Key;
lines[CurLine][len + 1] = 0;
CurPos++;
- //printf("pos: %d After: %s\n",CurPos, lines[CurLine]);
+ //print("pos: %d After: %s", CurPos, lines[CurLine]);
CalcRowCount();
RunEventHandler( TextAreaOnChange );
}
- return;
+ return true;
}
//Selectable=false for dialogs, rather unintuitive, but fact
if ((Flags & IE_GUI_TEXTAREA_SELECTABLE) || ( Key < '1' ) || ( Key > '9' ))
- return;
+ return false;
GameControl *gc = core->GetGameControl();
if (gc && (gc->GetDialogueFlags()&DF_IN_DIALOG) ) {
Changed = true;
seltext=minrow-1;
if ((unsigned int) seltext>=lines.size()) {
- return;
+ return true;
}
for(int i=0;i<Key-'0';i++) {
do {
seltext++;
if ((unsigned int) seltext>=lines.size()) {
- return;
+ return true;
}
}
while (strnicmp( lines[seltext], "[s=", 3 ) != 0 );
@@ -518,20 +507,22 @@ void TextArea::OnKeyPress(unsigned char Key, unsigned short /*Mod*/)
if (idx==-1) {
//this kills this object, don't use any more data!
gc->dialoghandler->EndDialog();
- return;
+ return true;
}
gc->dialoghandler->DialogChoose( idx );
+ return true;
}
+ return false;
}
/** Special Key Press */
-void TextArea::OnSpecialKeyPress(unsigned char Key)
+bool TextArea::OnSpecialKeyPress(unsigned char Key)
{
int len;
int i;
if (!(Flags&IE_GUI_TEXTAREA_EDITABLE)) {
- return;
+ return false;
}
Owner->Invalidate();
Changed = true;
@@ -577,7 +568,7 @@ void TextArea::OnSpecialKeyPress(unsigned char Key)
break;
case GEM_DELETE:
len = GetRowLength(CurLine);
- //printf("len: %d Before: %s\n",len, lines[CurLine]);
+ //print("len: %d Before: %s", len, lines[CurLine]);
if (CurPos>=len) {
//TODO: merge next line
break;
@@ -586,12 +577,12 @@ void TextArea::OnSpecialKeyPress(unsigned char Key)
for (i = CurPos; i < len; i++) {
lines[CurLine][i] = lines[CurLine][i + 1];
}
- //printf("pos: %d After: %s\n",CurPos, lines[CurLine]);
+ //print("pos: %d After: %s", CurPos, lines[CurLine]);
break;
case GEM_BACKSP:
len = GetRowLength(CurLine);
if (CurPos != 0) {
- //printf("len: %d Before: %s\n",len, lines[CurLine]);
+ //print("len: %d Before: %s", len, lines[CurLine]);
if (len<1) {
break;
}
@@ -601,15 +592,15 @@ void TextArea::OnSpecialKeyPress(unsigned char Key)
}
lines[CurLine][len - 1] = 0;
CurPos--;
- //printf("pos: %d After: %s\n",CurPos, lines[CurLine]);
+ //print("pos: %d After: %s", CurPos, lines[CurLine]);
} else {
if (CurLine) {
//TODO: merge lines
int oldline = CurLine;
CurLine--;
int old = GetRowLength(CurLine);
- //printf("len: %d Before: %s\n",old, lines[CurLine]);
- //printf("len: %d Before: %s\n",len, lines[oldline]);
+ //print("len: %d Before: %s", old, lines[CurLine]);
+ //print("len: %d Before: %s", len, lines[oldline]);
lines[CurLine] = (char *) realloc (lines[CurLine], len+old);
memcpy(lines[CurLine]+old, lines[oldline],len);
free(lines[oldline]);
@@ -617,13 +608,13 @@ void TextArea::OnSpecialKeyPress(unsigned char Key)
lines.erase(lines.begin()+oldline);
lrows.erase(lrows.begin()+oldline);
CurPos = old;
- //printf("pos: %d len: %d After: %s\n",CurPos, GetRowLength(CurLine), lines[CurLine]);
+ //print("pos: %d len: %d After: %s", CurPos, GetRowLength(CurLine), lines[CurLine]);
}
}
break;
case GEM_RETURN:
//add an empty line after CurLine
- //printf("pos: %d Before: %s\n",CurPos, lines[CurLine]);
+ //print("pos: %d Before: %s", CurPos, lines[CurLine]);
lrows.insert(lrows.begin()+CurLine, 0);
len = GetRowLength(CurLine);
//copy the text after the cursor into the new line
@@ -637,12 +628,13 @@ void TextArea::OnSpecialKeyPress(unsigned char Key)
//move cursor to next line beginning
CurLine++;
CurPos=0;
- //printf("len: %d After: %s\n",GetRowLength(CurLine-1), lines[CurLine-1]);
- //printf("len: %d After: %s\n",GetRowLength(CurLine), lines[CurLine]);
+ //print("len: %d After: %s", GetRowLength(CurLine-1), lines[CurLine-1]);
+ //print("len: %d After: %s", GetRowLength(CurLine), lines[CurLine]);
break;
}
CalcRowCount();
RunEventHandler( TextAreaOnChange );
+ return true;
}
/** Returns Row count */
@@ -671,11 +663,34 @@ int TextArea::GetTopIndex()
return startrow;
}
+int TextArea::GetRowHeight()
+{
+ return ftext->maxHeight;
+}
+
+/** Will scroll y pixels. sender is the control requesting the scroll (ie the scrollbar) */
+void TextArea::ScrollToY(unsigned long y, Control* sender)
+{
+ if (sb && sender != sb) {
+ // we must "scale" the pixels
+ ((ScrollBar*)sb)->SetPosForY(y * (((ScrollBar*)sb)->GetStep() / (double)ftext->maxHeight));
+ // sb->SetPosForY will recall this method so we dont need to do more... yet.
+ }else if(sb){
+ // our scrollbar has set position for us
+ TextYPos = y;
+ }else{
+ // no scrollbar. need to call SetRow myself.
+ // SetRow will set TextYPos.
+ SetRow( y / ftext->maxHeight );
+ }
+}
+
/** Set Starting Row */
void TextArea::SetRow(int row)
{
if (row < rows) {
startrow = row;
+ TextYPos = row * ftext->maxHeight;
}
Changed = true;
}
@@ -711,12 +726,11 @@ void TextArea::CalcRowCount()
for (size_t i = 0; i < lines.size(); i++) {
// rows++;
tr = 0;
- int len = ( int ) strlen( lines[i] );
- char* tmp = (char *) malloc( len + 1 );
- memcpy( tmp, lines[i], len + 1 );
+ ieWord* tmp = NULL;
+ size_t len = (int)ftext->GetDoubleByteString((unsigned char*)lines[i], tmp);
ftext->SetupString( tmp, w );
- for (int p = 0; p <= len; p++) {
- if (( ( unsigned char ) tmp[p] ) == '[') {
+ for (size_t p = 0; p <= len; p++) {
+ if (( tmp[p] ) == '[') {
p++;
//char tag[256];
int k = 0;
@@ -761,12 +775,25 @@ void TextArea::CalcRowCount()
return;
}
ScrollBar* bar = ( ScrollBar* ) sb;
- tr = rows - Height/ftext->size[1].h + 1;
+ tr = rows - Height/ftext->maxHeight + 1;
if (tr<0) {
tr = 0;
}
bar->SetMax( (ieWord) tr );
}
+
+/** Mousewheel scroll */
+/** This method is key to touchscreen scrolling */
+void TextArea::OnMouseWheelScroll(short /*x*/, short y)
+{
+ if (!(IE_GUI_TEXTAREA_SMOOTHSCROLL & Flags)){
+ unsigned long fauxY = TextYPos;
+ if ((long)fauxY + y <= 0) fauxY = 0;
+ else fauxY += y;
+ ScrollToY(fauxY, this);
+ }
+}
+
/** Mouse Over Event */
void TextArea::OnMouseOver(unsigned short /*x*/, unsigned short y)
{
@@ -780,7 +807,7 @@ void TextArea::OnMouseOver(unsigned short /*x*/, unsigned short y)
if (seltext != (int) i)
core->RedrawAll();
seltext = ( int ) i;
- //printf("CtrlId = 0x%08lx, seltext = %d, rows = %d, row = %d, r = %d\n", ControlID, i, rows, row, r);
+ //print("CtrlId = 0x%08lx, seltext = %d, rows = %d, row = %d, r = %d", ControlID, i, rows, row, r);
return;
}
}
@@ -788,14 +815,17 @@ void TextArea::OnMouseOver(unsigned short /*x*/, unsigned short y)
core->RedrawAll();
}
seltext = -1;
- //printf("CtrlId = 0x%08lx, seltext = %d, rows %d, row %d, r = %d\n", ControlID, seltext, rows, row, r);
+ //print("CtrlId = 0x%08lx, seltext = %d, rows %d, row %d, r = %d", ControlID, seltext, rows, row, r);
}
/** Mouse Button Up */
-void TextArea::OnMouseUp(unsigned short x, unsigned short y, unsigned short /*Button*/,
+void TextArea::OnMouseUp(unsigned short x, unsigned short y, unsigned short Button,
unsigned short /*Mod*/)
{
- if (( x <= Width ) && ( y <= ( Height - 5 ) ) && ( seltext != -1 )) {
+ if (!(Button & (GEM_MB_ACTION|GEM_MB_MENU)))
+ return;
+
+ if ((x < Width) && (y < Height - 5) && (seltext != -1)) {
Value = (unsigned int) seltext;
Changed = true;
if (strnicmp( lines[seltext], "[s=", 3 ) == 0) {
@@ -822,16 +852,28 @@ void TextArea::OnMouseUp(unsigned short x, unsigned short y, unsigned short /*Bu
RunEventHandler( TextAreaOnChange );
}
-/** Copies the current TextArea content to another TextArea control */
-void TextArea::CopyTo(TextArea* ta)
+void TextArea::SetText(const std::vector<char*>& text)
{
- ta->Clear();
- for (size_t i = 0; i < lines.size(); i++) {
- ta->SetText( lines[i], -1 );
+ Clear();
+ for (size_t i = 0; i < text.size(); i++) {
+ int newlen = strlen(text[i]);
+ char* str = (char *) malloc(newlen + 1);
+ memcpy(str, text[i], newlen + 1);
+ lines.push_back(str);
+ lrows.push_back(0);
+ CurPos = newlen;
}
+ CurLine = lines.size() - 1;
+ UpdateControls();
+}
+
+/** Copies the current TextArea content to another TextArea control */
+void TextArea::CopyTo(TextArea *ta)
+{
+ ta->SetText(lines);
}
-void TextArea::RedrawTextArea(const char* VariableName, unsigned int Sum)
+void TextArea::UpdateState(const char* VariableName, unsigned int Sum)
{
if (strnicmp( VarName, VariableName, MAX_VARIABLE_LENGTH )) {
return;
@@ -852,7 +894,7 @@ void TextArea::SelectText(const char *select)
} else {
SetRow( i );
}
- RedrawTextArea( VarName, i);
+ UpdateState(VarName, i);
CalcRowCount();
Owner->Invalidate();
core->RedrawAll();
@@ -877,9 +919,6 @@ bool TextArea::SetEvent(int eventType, EventHandler handler)
case IE_GUI_TEXTAREA_ON_CHANGE:
TextAreaOnChange = handler;
break;
- case IE_GUI_TEXTAREA_OUT_OF_TEXT:
- TextAreaOutOfText = handler;
- break;
default:
return false;
}
@@ -922,34 +961,23 @@ void TextArea::Clear()
//setting up the textarea for smooth scrolling, the first
//TEXTAREA_OUTOFTEXT callback is called automatically
-void TextArea::SetupScroll(unsigned long tck)
+void TextArea::SetupScroll()
{
SetPreservedRow(0);
- smooth = ftext->maxHeight;
startrow = 0;
- ticks = tck;
+ // ticks is the number of ticks it takes to scroll this font 1 px
+ ticks = 2400 / ftext->maxHeight;
//clearing the textarea
Clear();
- unsigned int i = (unsigned int) (Height/smooth);
- while (i--) {
+ unsigned int i = (unsigned int) (1 + ((Height - 1) / ftext->maxHeight)); // ceiling
+ while (i--) { //push empty lines so that the text starts out of view.
char *str = (char *) malloc(1);
str[0]=0;
lines.push_back(str);
lrows.push_back(0);
}
- i = (unsigned int) lines.size();
Flags |= IE_GUI_TEXTAREA_SMOOTHSCROLL;
- GetTime( starttime );
- if (RunEventHandler( TextAreaOutOfText )) {
- //event handler destructed this object?
- return;
- }
- if (i==lines.size()) {
- ResetEventHandler( TextAreaOutOfText );
- return;
- }
- //recalculates rows
- AppendText("\n",-1);
+ starttime = GetTickCount();
}
void TextArea::OnMouseDown(unsigned short /*x*/, unsigned short /*y*/, unsigned short Button,
@@ -977,3 +1005,13 @@ void TextArea::OnMouseDown(unsigned short /*x*/, unsigned short /*y*/, unsigned
}
}
}
+
+void TextArea::SetFocus(bool focus)
+{
+ Control::SetFocus(focus);
+ if (hasFocus && Flags & IE_GUI_TEXTAREA_EDITABLE) {
+ core->GetVideoDriver()->ShowSoftKeyboard();
+ }
+}
+
+}
diff --git a/gemrb/core/GUI/TextArea.h b/gemrb/core/GUI/TextArea.h
index 2ba24a4..aa61a78 100644
--- a/gemrb/core/GUI/TextArea.h
+++ b/gemrb/core/GUI/TextArea.h
@@ -35,10 +35,11 @@
#include "Font.h"
+namespace GemRB {
+
// Keep these synchronized with GUIDefines.py
// 0x05 is the control type of TextArea
#define IE_GUI_TEXTAREA_ON_CHANGE 0x05000000
-#define IE_GUI_TEXTAREA_OUT_OF_TEXT 0x05000001
// TextArea flags, keep these in sync too
// the control type is intentionally left out
@@ -71,7 +72,9 @@ public:
/** Set the TextArea value to the line number containing the string parameter */
void SelectText(const char *select);
/** Sets the Actual Text */
- int SetText(const char* text, int pos = 0);
+ void SetText(const char* text);
+ /** Sets text */
+ void SetText(const std::vector<char*>& text);
/** Clears the textarea */
void Clear();
/** Discards scrolled out lines from the textarea */
@@ -88,8 +91,10 @@ public:
}
/** adds empty lines so minrow will be the uppermost visible row */
void PadMinRow();
- /** Sets up scrolling, tck is the scrolling speed */
- void SetupScroll(unsigned long tck);
+ /** Sets up auto scrolling (chapter text) */
+ void SetupScroll();
+ /** Per Pixel scrolling */
+ void ScrollToY(unsigned long y, Control* sender);
/** Sets the Fonts */
void SetFonts(Font* init, Font* text);
/** Returns Number of Rows */
@@ -100,6 +105,8 @@ public:
int GetVisibleRowCount();
/** Returns Starting Row */
int GetTopIndex();
+ /** Returns total height of the text */
+ int GetRowHeight();
/** Set Starting Row */
void SetRow(int row);
/** Sets preserved lines */
@@ -113,7 +120,7 @@ public:
/** Returns the selected text */
const char* QueryText();
/** Marks textarea for redraw with a new value */
- void RedrawTextArea(const char* VariableName, unsigned int Sum);
+ void UpdateState(const char* VariableName, unsigned int Sum);
int SetScrollBar(Control *ptr);
private: // Private attributes
std::vector< char*> lines;
@@ -123,8 +130,7 @@ private: // Private attributes
int minrow;
/** lines to be kept even if scrolled out */
int keeplines;
- /** vertical offset for smooth scrolling */
- int smooth;
+ unsigned long TextYPos;
/** timer for scrolling */
unsigned long starttime;
/** timer ticks for scrolling (speed) */
@@ -155,9 +161,11 @@ private: //internal functions
public: //Events
/** Key Press Event */
- void OnKeyPress(unsigned char Key, unsigned short Mod);
+ bool OnKeyPress(unsigned char Key, unsigned short Mod);
/** Special Key Press */
- void OnSpecialKeyPress(unsigned char Key);
+ bool OnSpecialKeyPress(unsigned char Key);
+ /** Mousewheel scroll */
+ void OnMouseWheelScroll(short x, short y);
/** Mouse Over Event */
void OnMouseOver(unsigned short x, unsigned short y);
/** Mouse Button Up */
@@ -168,10 +176,11 @@ public: //Events
unsigned short Mod);
/** Set handler for specified event */
bool SetEvent(int eventType, EventHandler handler);
+ void SetFocus(bool focus);
/** OnChange Scripted Event Function Name */
EventHandler TextAreaOnChange;
- /** OutOfText Scripted Event Function Name */
- EventHandler TextAreaOutOfText;
};
+}
+
#endif
diff --git a/gemrb/core/GUI/TextEdit.cpp b/gemrb/core/GUI/TextEdit.cpp
index 969ea88..b782845 100644
--- a/gemrb/core/GUI/TextEdit.cpp
+++ b/gemrb/core/GUI/TextEdit.cpp
@@ -25,12 +25,17 @@
#include "Interface.h"
#include "Palette.h"
#include "Video.h"
+#include "GUI/EventMgr.h"
+#include "GUI/Window.h"
+
+namespace GemRB {
TextEdit::TextEdit(unsigned short maxLength, unsigned short px, unsigned short py)
{
max = maxLength;
FontPosX = px;
FontPosY = py;
+ Alignment = IE_FONT_ALIGN_MIDDLE | IE_FONT_ALIGN_LEFT;
Buffer = ( unsigned char * ) malloc( max + 1 );
font = NULL;
Cursor = NULL;
@@ -55,6 +60,12 @@ TextEdit::~TextEdit(void)
video->FreeSprite( Cursor );
}
+void TextEdit::SetAlignment(unsigned char Alignment)
+{
+ this->Alignment = Alignment;
+ Changed = true;
+}
+
/** Draws the Control on the Output Display */
void TextEdit::Draw(unsigned short x, unsigned short y)
{
@@ -72,11 +83,11 @@ void TextEdit::Draw(unsigned short x, unsigned short y)
//The aligning of textedit fields is done by absolute positioning (FontPosX, FontPosY)
if (hasFocus) {
font->Print( Region( x + XPos + FontPosX, y + YPos + FontPosY, Width, Height ), Buffer,
- palette, IE_FONT_ALIGN_LEFT | IE_FONT_ALIGN_TOP,
+ palette, Alignment,
true, NULL, Cursor, CurPos );
} else {
font->Print( Region( x + XPos + FontPosX, y + YPos + FontPosY, Width, Height ), Buffer,
- palette, IE_FONT_ALIGN_LEFT | IE_FONT_ALIGN_TOP, true );
+ palette, Alignment, true );
}
}
@@ -88,7 +99,7 @@ void TextEdit::SetFont(Font* f)
Changed = true;
return;
}
- printMessage("TextEdit","Invalid font set!\n", LIGHT_RED);
+ Log(ERROR, "TextEdit", "Invalid font set!");
}
Font *TextEdit::GetFont() { return font; }
@@ -114,11 +125,11 @@ void TextEdit::SetBackGround(Sprite2D* back)
}
/** Key Press Event */
-void TextEdit::OnKeyPress(unsigned char Key, unsigned short /*Mod*/)
+bool TextEdit::OnKeyPress(unsigned char Key, unsigned short /*Mod*/)
{
if (Key >= 0x20) {
if (Value && ( (Key<'0') || (Key>'9') ) )
- return;
+ return false;
Owner->Invalidate();
Changed = true;
int len = ( int ) strlen( ( char* ) Buffer );
@@ -131,10 +142,12 @@ void TextEdit::OnKeyPress(unsigned char Key, unsigned short /*Mod*/)
CurPos++;
}
RunEventHandler( EditOnChange );
+ return true;
}
+ return false;
}
/** Special Key Press */
-void TextEdit::OnSpecialKeyPress(unsigned char Key)
+bool TextEdit::OnSpecialKeyPress(unsigned char Key)
{
int len;
@@ -177,22 +190,28 @@ void TextEdit::OnSpecialKeyPress(unsigned char Key)
break;
case GEM_RETURN:
RunEventHandler( EditOnDone );
- return;
-
}
RunEventHandler( EditOnChange );
+ return true;
+}
+
+void TextEdit::SetFocus(bool focus)
+{
+ Control::SetFocus(focus);
+ if (hasFocus) {
+ core->GetVideoDriver()->ShowSoftKeyboard();
+ }
}
/** Sets the Text of the current control */
-int TextEdit::SetText(const char* string, int /*pos*/)
+void TextEdit::SetText(const char* string)
{
- strncpy( ( char * ) Buffer, string, max );
- Buffer[max]=0;
- CurPos = (ieWord) strlen((char *) Buffer);
+ int len = strlcpy( ( char * ) Buffer, string, max + 1 );
+ if (len > max) CurPos = max + 1;
+ else CurPos = len;
if (Owner) {
Owner->Invalidate();
}
- return 0;
}
void TextEdit::SetBufferLength(ieWord buflen)
@@ -231,3 +250,5 @@ bool TextEdit::SetEvent(int eventType, EventHandler handler)
return true;
}
+
+}
diff --git a/gemrb/core/GUI/TextEdit.h b/gemrb/core/GUI/TextEdit.h
index f92e913..4ebfde0 100644
--- a/gemrb/core/GUI/TextEdit.h
+++ b/gemrb/core/GUI/TextEdit.h
@@ -34,6 +34,8 @@
#include "Font.h"
+namespace GemRB {
+
class Palette;
// !!! Keep these synchronized with GUIDefines.py
@@ -63,16 +65,19 @@ public:
/** Set BackGround */
void SetBackGround(Sprite2D* back);
/** Sets the Text of the current control */
- int SetText(const char* string, int pos = 0);
+ void SetText(const char* string);
/** Sets the Text of the current control */
const char* QueryText();
/** Sets the buffer length */
void SetBufferLength(ieWord buflen);
+ /** Sets the alignment */
+ void SetAlignment(unsigned char Alignment);
private:
/** Text Editing Cursor Sprite */
Sprite2D* Cursor;
/** Text Font */
Font* font;
+ unsigned char Alignment;
/** Background */
Sprite2D* Back;
/** Max Edit Text Length */
@@ -87,15 +92,18 @@ private:
Palette* palette;
public: //Events
/** Key Press Event */
- void OnKeyPress(unsigned char Key, unsigned short Mod);
+ bool OnKeyPress(unsigned char Key, unsigned short Mod);
/** Special Key Press */
- void OnSpecialKeyPress(unsigned char Key);
+ bool OnSpecialKeyPress(unsigned char Key);
/** Set handler for specified event */
bool SetEvent(int eventType, EventHandler handler);
+ void SetFocus(bool focus);
/** OnChange Scripted Event Function Name */
EventHandler EditOnChange;
EventHandler EditOnDone;
EventHandler EditOnCancel;
};
+}
+
#endif
diff --git a/gemrb/core/GUI/Window.cpp b/gemrb/core/GUI/Window.cpp
index ed1395a..c0a2fdf 100644
--- a/gemrb/core/GUI/Window.cpp
+++ b/gemrb/core/GUI/Window.cpp
@@ -24,6 +24,7 @@
#include "GUI/Control.h"
#include "GUI/MapControl.h"
#include "GUI/Progressbar.h"
+#include "GUI/ScrollBar.h"
#include "GUI/Slider.h"
#include "win32def.h"
@@ -31,6 +32,10 @@
#include "Interface.h"
#include "Video.h"
+#include "ie_cursors.h"
+
+namespace GemRB {
+
Window::Window(unsigned short WindowID, unsigned short XPos,
unsigned short YPos, unsigned short Width, unsigned short Height)
{
@@ -50,6 +55,7 @@ Window::Window(unsigned short WindowID, unsigned short XPos,
DefaultControl[0] = -1;
DefaultControl[1] = -1;
ScrollControl = -1;
+ FunctionBar = false;
}
Window::~Window()
@@ -150,6 +156,21 @@ void Window::SetFrame()
Invalidate();
}
+Control* Window::GetFunctionControl(int x)
+{
+ if (!FunctionBar) {
+ return NULL;
+ }
+
+ std::vector< Control*>::const_iterator m;
+
+ for (m = Controls.begin(); m != Controls.end(); m++) {
+ Control *ctrl = *m;
+ if ( ctrl->GetFunctionNumber() == x ) return ctrl;
+ }
+ return NULL;
+}
+
/** Returns the Control at X,Y Coordinates */
Control* Window::GetControl(unsigned short x, unsigned short y, bool ignore)
{
@@ -203,12 +224,12 @@ Control* Window::GetMouseFocus() const
void Window::SetFocused(Control* ctrl)
{
if (lastFocus != NULL) {
- lastFocus->hasFocus = false;
+ lastFocus->SetFocus(false);
lastFocus->Changed = true;
}
lastFocus = ctrl;
if (ctrl != NULL) {
- lastFocus->hasFocus = true;
+ lastFocus->SetFocus(true);
lastFocus->Changed = true;
}
}
@@ -344,45 +365,8 @@ void Window::InvalidateForControl(Control *ctrl) {
void Window::RedrawControls(const char* VarName, unsigned int Sum)
{
- for (unsigned int i = 0; i < Controls.size(); i++) {
- switch (Controls[i]->ControlType) {
- case IE_GUI_MAP:
- {
- MapControl *mc = ( MapControl* ) (Controls[i]);
- mc->RedrawMapControl( VarName, Sum );
- break;
- }
- case IE_GUI_BUTTON:
- {
- Button* bt = ( Button* ) ( Controls[i] );
- bt->RedrawButton( VarName, Sum );
- break;
- }
- case IE_GUI_TEXTAREA:
- {
- TextArea* pb = ( TextArea* ) ( Controls[i] );
- pb->RedrawTextArea( VarName, Sum );
- break;
- }
- case IE_GUI_PROGRESSBAR:
- {
- Progressbar* pb = ( Progressbar* ) ( Controls[i] );
- pb->RedrawProgressbar( VarName, Sum );
- break;
- }
- case IE_GUI_SLIDER:
- {
- Slider* sl = ( Slider* ) ( Controls[i] );
- sl->RedrawSlider( VarName, Sum );
- break;
- }
- case IE_GUI_SCROLLBAR:
- {
- ScrollBar* sb = ( ScrollBar* ) ( Controls[i] );
- sb->RedrawScrollBar( VarName, Sum );
- break;
- }
- }
+ for (std::vector<Control *>::iterator c = Controls.begin(); c != Controls.end(); ++c) {
+ (*c)->UpdateState( VarName, Sum);
}
}
@@ -440,3 +424,5 @@ void Window::OnMouseOver(unsigned short x, unsigned short y)
}
lastOver->OnMouseOver( x - XPos - lastOver->XPos, y - YPos - lastOver->YPos );
}
+
+}
diff --git a/gemrb/core/GUI/Window.h b/gemrb/core/GUI/Window.h
index a4798dd..f8b3b3d 100644
--- a/gemrb/core/GUI/Window.h
+++ b/gemrb/core/GUI/Window.h
@@ -29,15 +29,15 @@
#define WINDOW_H
#include "GUI/Control.h"
-#include "GUI/ScrollBar.h"
-#include "GUI/TextArea.h"
#include "exports.h"
-#include "Sprite2D.h"
-
#include <vector>
+namespace GemRB {
+
+class Sprite2D;
+
// Window Flags
#define WF_CHANGED 1 //window changed
#define WF_FRAME 2 //window has frame
@@ -53,40 +53,6 @@
#define WINDOW_SCALE 0x08
#define WINDOW_BOUNDED 0x10
-// IE specific cursor types
-
-#define IE_CURSOR_INVALID -1
-#define IE_CURSOR_NORMAL 0
-#define IE_CURSOR_TAKE 2 //over pile type containers
-#define IE_CURSOR_WALK 4
-#define IE_CURSOR_BLOCKED 6
-#define IE_CURSOR_USE 8 //never hardcoded
-#define IE_CURSOR_WAIT 10 //hourglass
-#define IE_CURSOR_ATTACK 12
-#define IE_CURSOR_SWAP 14 //dragging portraits
-#define IE_CURSOR_DEFEND 16
-#define IE_CURSOR_TALK 18
-#define IE_CURSOR_CAST 20 //targeting with non weapon
-#define IE_CURSOR_INFO 22 //never hardcoded
-#define IE_CURSOR_LOCK 24 //locked door
-#define IE_CURSOR_LOCK2 26 //locked container
-#define IE_CURSOR_STAIR 28 //never hardcoded
-#define IE_CURSOR_DOOR 30 //doors
-#define IE_CURSOR_CHEST 32
-#define IE_CURSOR_TRAVEL 34
-#define IE_CURSOR_STEALTH 36
-#define IE_CURSOR_TRAP 38
-#define IE_CURSOR_PICK 40 //pickpocket
-#define IE_CURSOR_PASS 42 //never hardcoded
-#define IE_CURSOR_GRAB 44
-#define IE_CURSOR_WAY 46 //waypoint (not in PST)
-#define IE_CURSOR_INFO2 46 //PST
-#define IE_CURSOR_PORTAL 48 //PST
-#define IE_CURSOR_STAIR2 50 //PST
-#define IE_CURSOR_EXTRA 52 //PST
-
-#define IE_CURSOR_MASK 127
-#define IE_CURSOR_GRAY 128
/**
* @class Window
* Class serving as a container for Control/widget objects
@@ -107,6 +73,8 @@ public:
void DrawWindow();
/** Set window frame used to fill screen on higher resolutions*/
void SetFrame();
+ /** Returns the Control associated with the function key index, valid indices are 0-11 */
+ Control* GetFunctionControl(int x);
/** Returns the Control at X,Y Coordinates */
Control* GetControl(unsigned short x, unsigned short y, bool ignore=0);
/** Returns the Control by Index */
@@ -167,6 +135,7 @@ public: //Public attributes
int Cursor;
int DefaultControl[2]; //default enter and cancel
int ScrollControl;
+ bool FunctionBar;
private: // Private attributes
/** BackGround Image. No BackGround if this variable is NULL. */
Sprite2D* BackGround;
@@ -187,4 +156,6 @@ public:
void release(void);
};
+}
+
#endif
diff --git a/gemrb/core/GUI/WorldMapControl.cpp b/gemrb/core/GUI/WorldMapControl.cpp
index cca132f..f869640 100644
--- a/gemrb/core/GUI/WorldMapControl.cpp
+++ b/gemrb/core/GUI/WorldMapControl.cpp
@@ -20,12 +20,18 @@
#include "GUI/WorldMapControl.h"
#include "win32def.h"
+#include "ie_cursors.h"
+#include "Font.h"
#include "Game.h"
#include "GameData.h"
#include "Interface.h"
#include "Video.h"
#include "WorldMap.h"
+#include "GUI/EventMgr.h"
+#include "GUI/Window.h"
+
+namespace GemRB {
#define MAP_TO_SCREENX(x) XWin + XPos - ScrollX + (x)
#define MAP_TO_SCREENY(y) YWin + YPos - ScrollY + (y)
@@ -40,11 +46,11 @@ WorldMapControl::WorldMapControl(const char *font, int direction)
Value = direction;
Game* game = core->GetGame();
WorldMap* worldmap = core->GetWorldMap();
- strncpy(currentArea, game->CurrentArea, 8);
+ CopyResRef(currentArea, game->CurrentArea);
int entry = core->GetAreaAlias(currentArea);
if (entry >= 0) {
WMPAreaEntry *m = worldmap->GetEntry(entry);
- strncpy(currentArea, m->AreaResRef, 8);
+ CopyResRef(currentArea, m->AreaResRef);
}
//if there is no trivial area, look harder
@@ -52,7 +58,7 @@ WorldMapControl::WorldMapControl(const char *font, int direction)
core->HasFeature(GF_FLEXIBLE_WMAP) ) {
WMPAreaEntry *m = worldmap->FindNearestEntry(currentArea, (unsigned int &) entry);
if (m) {
- strncpy(currentArea, m->AreaResRef, 8);
+ CopyResRef(currentArea, m->AreaResRef);
}
}
@@ -119,12 +125,21 @@ void WorldMapControl::Draw(unsigned short XWin, unsigned short YWin)
int yOffs = MAP_TO_SCREENY(m->Y);
Sprite2D* icon = m->GetMapIcon(worldmap->bam);
if( icon ) {
- video->BlitSprite( icon, xOffs, yOffs, true, &r );
+ if (m == Area) {
+ Palette *pal = icon->GetPalette();
+ icon->SetPalette(pal_selected);
+ video->BlitSprite( icon, xOffs, yOffs, true, &r );
+ icon->SetPalette(pal);
+ pal->Release();
+ } else {
+ video->BlitSprite( icon, xOffs, yOffs, true, &r );
+ }
video->FreeSprite( icon );
}
- if (AnimPicture && !strnicmp(m->AreaResRef, currentArea, 8) ) {
- core->GetVideoDriver()->BlitSprite( AnimPicture, xOffs, yOffs, true, &r );
+ if (AnimPicture && (!strnicmp(m->AreaResRef, currentArea, 8)
+ || !strnicmp(m->AreaName, currentArea, 8))) {
+ video->BlitSprite( AnimPicture, xOffs, yOffs, true, &r );
}
}
@@ -150,7 +165,7 @@ void WorldMapControl::Draw(unsigned short XWin, unsigned short YWin)
if (!m->GetCaption())
continue;
- int tw = ftext->CalcStringWidth( m->GetCaption() ) + 5;
+ int tw = ftext->CalcStringWidth( (unsigned char*)m->GetCaption() ) + 5;
int th = ftext->maxHeight;
Palette* text_pal = pal_normal;
@@ -169,18 +184,6 @@ void WorldMapControl::Draw(unsigned short XWin, unsigned short YWin)
video->SetClipRect(&clipbackup);
}
-/** Key Release Event */
-void WorldMapControl::OnKeyRelease(unsigned char Key, unsigned short Mod)
-{
- switch (Key) {
- case 'f':
- if (Mod & GEM_MOD_CTRL)
- core->GetVideoDriver()->ToggleFullscreenMode();
- break;
- default:
- break;
- }
-}
void WorldMapControl::AdjustScrolling(short x, short y)
{
WorldMap* worldmap = core->GetWorldMap();
@@ -238,29 +241,28 @@ void WorldMapControl::OnMouseOver(unsigned short x, unsigned short y)
if ( (ae->GetAreaStatus() & WMP_ENTRY_WALKABLE)!=WMP_ENTRY_WALKABLE) {
continue; //invisible or inaccessible
}
- if (!strnicmp(ae->AreaResRef, currentArea, 8) ) {
- continue; //current area
- }
Sprite2D *icon=ae->GetMapIcon(worldmap->bam);
- int h=0,w=0;
+ int h=0, w=0, iconx=0, icony=0;
if (icon) {
h=icon->Height;
w=icon->Width;
+ iconx = icon->XPos;
+ icony = icon->YPos;
core->GetVideoDriver()->FreeSprite( icon );
}
if (ftext && ae->GetCaption()) {
- int tw = ftext->CalcStringWidth( ae->GetCaption() ) + 5;
+ int tw = ftext->CalcStringWidth( (unsigned char*)ae->GetCaption() ) + 5;
int th = ftext->maxHeight;
if(h<th)
h=th;
if(w<tw)
w=tw;
}
- if (ae->X > x) continue;
- if (ae->X + w < x) continue;
- if (ae->Y > y) continue;
- if (ae->Y + h < y) continue;
+ if (ae->X - iconx > x) continue;
+ if (ae->X - iconx + w < x) continue;
+ if (ae->Y - icony > y) continue;
+ if (ae->Y - icony + h < y) continue;
lastCursor = IE_CURSOR_NORMAL;
Area=ae;
if(oldArea!=ae) {
@@ -323,40 +325,46 @@ void WorldMapControl::OnMouseUp(unsigned short /*x*/, unsigned short /*y*/,
}
}
-/** Special Key Press */
-void WorldMapControl::OnSpecialKeyPress(unsigned char Key)
+/** Mouse wheel scroll */
+void WorldMapControl::OnMouseWheelScroll(short x, short y)
{
+ ScrollX += x;
+ ScrollY += y;
+
WorldMap* worldmap = core->GetWorldMap();
+ Sprite2D *MapMOS = worldmap->GetMapMOS();
+ if (ScrollX > MapMOS->Width - Width)
+ ScrollX = MapMOS->Width - Width;
+ if (ScrollY > MapMOS->Height - Height)
+ ScrollY = MapMOS->Height - Height;
+ if (ScrollX < 0)
+ ScrollX = 0;
+ if (ScrollY < 0)
+ ScrollY = 0;
+}
+
+/** Special Key Press */
+bool WorldMapControl::OnSpecialKeyPress(unsigned char Key)
+{
+ ieDword keyScrollSpd = 64;
+ core->GetDictionary()->Lookup("Keyboard Scroll Speed", keyScrollSpd);
switch (Key) {
case GEM_LEFT:
- ScrollX -= 64;
+ OnMouseWheelScroll(keyScrollSpd * -1, 0);
break;
case GEM_UP:
- ScrollY -= 64;
+ OnMouseWheelScroll(0, keyScrollSpd * -1);
break;
case GEM_RIGHT:
- ScrollX += 64;
+ OnMouseWheelScroll(keyScrollSpd, 0);
break;
case GEM_DOWN:
- ScrollY += 64;
- break;
- case GEM_ALT:
- printf( "ALT pressed\n" );
- break;
- case GEM_TAB:
- printf( "TAB pressed\n" );
+ OnMouseWheelScroll(0, keyScrollSpd);
break;
+ default:
+ return false;
}
-
- Sprite2D *MapMOS = worldmap->GetMapMOS();
- if (ScrollX > MapMOS->Width - Width)
- ScrollX = MapMOS->Width - Width;
- if (ScrollY > MapMOS->Height - Height)
- ScrollY = MapMOS->Height - Height;
- if (ScrollX < 0)
- ScrollX = 0;
- if (ScrollY < 0)
- ScrollY = 0;
+ return true;
}
bool WorldMapControl::SetEvent(int eventType, EventHandler handler)
@@ -415,3 +423,5 @@ void WorldMapControl::SetColor(int which, Color color)
Changed = true;
}
+
+}
diff --git a/gemrb/core/GUI/WorldMapControl.h b/gemrb/core/GUI/WorldMapControl.h
index c02cef7..eed00cb 100644
--- a/gemrb/core/GUI/WorldMapControl.h
+++ b/gemrb/core/GUI/WorldMapControl.h
@@ -34,6 +34,8 @@
#include "Dialog.h"
#include "Interface.h"
+namespace GemRB {
+
class Palette;
class WMPAreaEntry;
class WorldMapControl;
@@ -66,8 +68,6 @@ public:
void Draw(unsigned short x, unsigned short y);
/** Sets the exit direction (we need this to calculate distances) */
void SetDirection(int direction);
- /** Sets the Text of the current control */
- int SetText(const char* /*string*/, int /*pos*/) { return 0; }
/** Set color for one type of area labels */
void SetColor(int which, Color color);
int ScrollX, ScrollY;
@@ -105,12 +105,14 @@ private:
/** Mouse Button Up */
void OnMouseUp(unsigned short x, unsigned short y, unsigned short Button,
unsigned short Mod);
- /** Key Release Event */
- void OnKeyRelease(unsigned char Key, unsigned short Mod);
+ /** Mouse Wheel Event */
+ void OnMouseWheelScroll(short x, short y);
/** Special Key Press */
- void OnSpecialKeyPress(unsigned char Key);
+ bool OnSpecialKeyPress(unsigned char Key);
/** DisplayTooltip */
void DisplayTooltip();
};
+}
+
#endif
diff --git a/gemrb/core/Game.cpp b/gemrb/core/Game.cpp
index f5c0f10..12638d5 100644
--- a/gemrb/core/Game.cpp
+++ b/gemrb/core/Game.cpp
@@ -29,13 +29,19 @@
#include "DisplayMessage.h"
#include "GameData.h"
#include "Interface.h"
+#include "IniSpawn.h"
#include "MapMgr.h"
#include "MusicMgr.h"
#include "Particles.h"
+#include "PluginMgr.h"
#include "ScriptEngine.h"
+#include "TableMgr.h"
#include "GameScript/GameScript.h"
#include "GUI/GameControl.h"
#include "System/DataStream.h"
+#include "System/StringBuffer.h"
+
+namespace GemRB {
#define MAX_MAPS_LOADED 1
@@ -47,6 +53,7 @@ Game::Game(void) : Scriptable( ST_GLOBAL )
version = 0;
Expansion = 0;
LoadMos[0] = 0;
+ TextScreen[0] = 0;
SelectedSingle = 1; //the PC we are looking at (inventory, shop)
PartyGold = 0;
SetScript( core->GlobalScript, 0 );
@@ -85,8 +92,8 @@ Game::Game(void) : Scriptable( ST_GLOBAL )
//loading rest/daylight switching movies (only bg2 has them)
memset(restmovies,'*',sizeof(restmovies));
- memset(daymovies,'*',sizeof(restmovies));
- memset(nightmovies,'*',sizeof(restmovies));
+ memset(daymovies,'*',sizeof(daymovies));
+ memset(nightmovies,'*',sizeof(nightmovies));
if (table.load("restmov")) {
for(int i=0;i<8;i++) {
strnuprcpy(restmovies[i],table->QueryField(i,0),8);
@@ -95,11 +102,40 @@ Game::Game(void) : Scriptable( ST_GLOBAL )
}
}
+ //loading npc starting levels
+ ieResRef tn;
+ if (Expansion == 5) { // tob is special
+ CopyResRef(tn, "npclvl25");
+ } else {
+ CopyResRef(tn, "npclevel");
+ }
+ if (table.load(tn)) {
+ int cols = table->GetColumnCount();
+ int rows = table->GetRowCount();
+ int i, j;
+ npclevels.reserve(rows);
+ for (i = 0; i < rows; i++) {
+ npclevels.push_back (std::vector<char *>(cols+1));
+ for(j = -1; j < cols; j++) {
+ char *ref = new char[9];
+ if (j == -1) {
+ CopyResRef(ref, table->GetRowName(i));
+ npclevels[i][j+1] = ref;
+ } else {
+ CopyResRef(ref, table->QueryField(i, j));
+ npclevels[i][j+1] = ref;
+ }
+ }
+ }
+ }
+
interval = 1000/AI_UPDATE_TIME;
hasInfra = false;
familiarBlock = false;
//FIXME:i'm not sure in this...
NoInterrupt();
+ bntchnc = NULL;
+ bntrows = -1;
}
Game::~Game(void)
@@ -147,9 +183,17 @@ Game::~Game(void)
while(i--) {
free (planepositions[i]);
}
+
+ i = npclevels.size();
+ while (i--) {
+ size_t j = npclevels[i].size();
+ while(j--) {
+ delete [] npclevels[i][j];
+ }
+ }
}
-bool IsAlive(Actor *pc)
+static bool IsAlive(Actor *pc)
{
if (pc->GetStat(IE_STATE_ID)&STATE_DEAD) {
return false;
@@ -312,6 +356,8 @@ void Game::ConsolidateParty()
}
for ( m = PCs.begin(); m != PCs.end(); ++m) {
(*m)->RefreshEffects(NULL);
+ //TODO: how to set up bardsongs
+ (*m)->SetModalSpell((*m)->ModalState, 0);
}
}
@@ -342,6 +388,9 @@ int Game::LeaveParty (Actor* actor)
if (core->HasFeature( GF_HAS_DPLAYER )) {
actor->SetScript( "", SCR_DEFAULT );
+ if (actor->GetBase(IE_MC_FLAGS) & MC_EXPORTABLE) {
+ actor->SetDialog("MULTIJ");
+ }
}
actor->SetBase( IE_EA, EA_NEUTRAL );
return ( int ) NPCs.size() - 1;
@@ -369,8 +418,7 @@ void Game::InitActorPos(Actor *actor)
AutoTable strta("startpos");
if (!start || !strta) {
- printMessage("Game","Game is missing character start data.\n",RED);
- abort();
+ error("Game", "Game is missing character start data.\n");
}
// 0 - single player, 1 - tutorial, 2 - expansion
ieDword playmode = 0;
@@ -389,6 +437,8 @@ void Game::InitActorPos(Actor *actor)
actor->Pos.x = actor->Destination.x = (short) atoi( strta->QueryField( strta->GetRowIndex(xpos), ip ) );
actor->Pos.y = actor->Destination.y = (short) atoi( strta->QueryField( strta->GetRowIndex(ypos), ip ) );
+ actor->HomeLocation.x = actor->Pos.x;
+ actor->HomeLocation.y = actor->Pos.y;
actor->SetOrientation( atoi( strta->QueryField( strta->GetRowIndex(rot), ip) ), false );
if (strta.load("startare")) {
@@ -475,7 +525,7 @@ void Game::SetHotKey(unsigned long Key)
Actor *actor = *m;
if (actor->IsSelected()) {
- actor->HotKey = (ieDword) Key;
+ actor->AddTrigger(TriggerEntry(trigger_hotkey, (ieDword) Key));
}
}
}
@@ -483,7 +533,7 @@ void Game::SetHotKey(unsigned long Key)
bool Game::SelectPCSingle(int index)
{
Actor* actor = FindPC( index );
- if (!actor || ! actor->ValidTarget( GA_NO_HIDDEN ))
+ if (!actor)
return false;
SelectedSingle = index;
@@ -586,19 +636,22 @@ bool Game::SelectActor(Actor* actor, bool select, unsigned flags)
return true;
}
-// Gets average party level, of onlyalive is true, then counts only living PCs
+// Gets sum of party level, if onlyalive is true, then counts only living PCs
+// If you need average party level, divide this with GetPartySize
int Game::GetPartyLevel(bool onlyalive) const
{
- int count = 0;
+ int amount = 0;
+
for (unsigned int i = 0; i<PCs.size(); i++) {
if (onlyalive) {
if (PCs[i]->GetStat(IE_STATE_ID)&STATE_DEAD) {
continue;
}
}
- count += PCs[i]->GetXPLevel(0);
+ amount += PCs[i]->GetXPLevel(0);
}
- return count;
+
+ return amount;
}
// Returns map structure (ARE) if it is already loaded in memory
@@ -699,7 +752,7 @@ int Game::DelMap(unsigned int index, int forced)
if (!map) { //this shouldn't happen, i guess
- printMessage("Game","Erased NULL Map\n",YELLOW);
+ Log(WARNING, "Game", "Erased NULL Map");
Maps.erase( Maps.begin()+index);
if (MapIndex>(int) index) {
MapIndex--;
@@ -727,6 +780,17 @@ int Game::DelMap(unsigned int index, int forced)
{
return 1;
}
+ //if there are still selected actors on the map (e.g. summons)
+ //unselect them now before they get axed
+ std::vector< Actor*>::iterator m;
+ for (m = selected.begin(); m != selected.end();) {
+ if (!(*m)->InParty && !stricmp(Maps[index]->GetScriptName(), (*m)->Area)) {
+ m = selected.erase(m);
+ } else {
+ ++m;
+ }
+ }
+
//remove map from memory
core->SwapoutArea(Maps[index]);
delete( Maps[index] );
@@ -741,10 +805,30 @@ int Game::DelMap(unsigned int index, int forced)
return 0;
}
+void Game::PlacePersistents(Map *newMap, const char *ResRef)
+{
+ unsigned int i, last;
+
+ // count the number of replaced actors, so we don't need to recheck them
+ // if their max level is still lower than ours, each check would also result in a substitution
+ last = NPCs.size()-1;
+ for (i = 0; i < NPCs.size(); i++) {
+ if (stricmp( NPCs[i]->Area, ResRef ) == 0) {
+ if (i < last && CheckForReplacementActor(i)) {
+ i--;
+ last--;
+ continue;
+ }
+ newMap->AddActor( NPCs[i], false );
+ NPCs[i]->SetMap(newMap);
+ }
+ }
+}
+
/* Loads an area */
int Game::LoadMap(const char* ResRef, bool loadscreen)
{
- unsigned int i;
+ unsigned int i, ret;
Map *newMap;
PluginHolder<MapMgr> mM(IE_ARE_CLASS_ID);
ScriptEngine *sE = core->GetGUIScriptEngine();
@@ -756,6 +840,7 @@ int Game::LoadMap(const char* ResRef, bool loadscreen)
int index = FindMap(ResRef);
if (index>=0) {
+ PlacePersistents(GetMap(index), ResRef);
return index;
}
@@ -769,7 +854,7 @@ int Game::LoadMap(const char* ResRef, bool loadscreen)
if (!ds) {
goto failedload;
}
- if(!mM->Open( ds, true )) {
+ if(!mM->Open(ds)) {
goto failedload;
}
newMap = mM->GetMap(ResRef, IsDay());
@@ -779,27 +864,80 @@ int Game::LoadMap(const char* ResRef, bool loadscreen)
core->LoadProgress(100);
+ ret = AddMap( newMap );
+
+ //spawn creatures on a map already in the game
+ //this feature exists in all blackisle games but not in bioware games
+ if (core->HasFeature(GF_SPAWN_INI)) {
+ newMap->LoadIniSpawn();
+ }
+
for (i = 0; i < PCs.size(); i++) {
if (stricmp( PCs[i]->Area, ResRef ) == 0) {
- newMap->AddActor( PCs[i] );
- }
- }
- for (i = 0; i < NPCs.size(); i++) {
- if (stricmp( NPCs[i]->Area, ResRef ) == 0) {
- newMap->AddActor( NPCs[i] );
+ newMap->AddActor( PCs[i], false );
}
}
+
+ PlacePersistents(newMap, ResRef);
+
if (hide) {
core->UnhideGCWindow();
}
- return AddMap( newMap );
+ newMap->InitActors();
+
+ return ret;
failedload:
- if (hide)
+ if (hide) {
core->UnhideGCWindow();
+ }
core->LoadProgress(100);
return -1;
}
+// check if the actor is in npclevel.2da and replace accordingly
+bool Game::CheckForReplacementActor(int i)
+{
+ if (core->InCutSceneMode() || npclevels.empty()) {
+ return false;
+ }
+
+ Actor* act = NPCs[i];
+ ieDword level = GetPartyLevel(false) / GetPartySize(false);
+ if (!(act->Modified[IE_MC_FLAGS]&MC_BEENINPARTY) && !(act->Modified[IE_STATE_ID]&STATE_DEAD) && act->GetXPLevel(false) < level) {
+ ieResRef newcre = "****"; // default table value
+ std::vector<std::vector<char *> >::iterator it;
+ for (it = npclevels.begin(); it != npclevels.end(); it++) {
+ if (!stricmp((*it)[0], act->GetScriptName()) && (level > 2)) {
+ // the tables have entries only up to level 24
+ ieDword safeLevel = npclevels[0].size() - 1;
+ if (level < safeLevel) {
+ safeLevel = level;
+ }
+ CopyResRef(newcre, (*it)[safeLevel-2]);
+ break;
+ }
+ }
+
+ if (stricmp(newcre, "****")) {
+ int pos = gamedata->LoadCreature(newcre, 0, false, act->version);
+ if (pos < 0) {
+ error("Game::CheckForReplacementActor", "LoadCreature failed: pos is negative!\n");
+ } else {
+ Actor *newact = GetNPC(pos);
+ if (!newact) {
+ error("Game::CheckForReplacementActor", "GetNPC failed: cannot find act!\n");
+ } else {
+ newact->Pos = act->Pos; // the map is not loaded yet, so no SetPosition
+ CopyResRef(newact->Area, act->Area);
+ DelNPC(InStore(act));
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
int Game::AddNPC(Actor* npc)
{
int slot = InStore( npc ); //already an npc
@@ -878,7 +1016,9 @@ bool Game::AddJournalEntry(ieStrRef strref, int Section, int Group)
je->Section = (ieByte) Section;
je->Group = (ieByte) Group;
ieDword chapter = 0;
- locals->Lookup("CHAPTER", chapter);
+ if (!core->HasFeature(GF_NO_NEW_VARIABLES)) {
+ locals->Lookup("CHAPTER", chapter);
+ }
je->Chapter = (ieByte) chapter;
je->GameTime = GameTime;
return true;
@@ -887,7 +1027,9 @@ bool Game::AddJournalEntry(ieStrRef strref, int Section, int Group)
je = new GAMJournalEntry;
je->GameTime = GameTime;
ieDword chapter = 0;
- locals->Lookup("CHAPTER", chapter);
+ if (!core->HasFeature(GF_NO_NEW_VARIABLES)) {
+ locals->Lookup("CHAPTER", chapter);
+ }
je->Chapter = (ieByte) chapter;
je->unknown09 = 0;
je->Section = (ieByte) Section;
@@ -1017,14 +1159,17 @@ int Game::GetXPFromCR(int cr)
{
if (!crtable) LoadCRTable();
if (crtable) {
- int level = GetPartyLevel(true);
- if (cr>=MAX_CRLEVEL) {
- cr=MAX_CRLEVEL-1;
+ int size = GetPartySize(true);
+ if (!size) return 0; // everyone just died anyway
+ int level = GetPartyLevel(true) / size;
+ if (cr+1>=MAX_CRLEVEL) {
+ cr=MAX_CRLEVEL-2;
}
- printf("Challenge Rating: %d, party level: %d ", cr, level);
- return crtable[level][cr];
+ Log(MESSAGE, "Game", "Challenge Rating: %d, party level: %d", cr, level);
+ // it also has a column for cr 0.25 and 0.5
+ return crtable[level-1][cr+1];
}
- printMessage("Game","Cannot find moncrate.2da!\n", LIGHT_RED);
+ Log(ERROR, "Game", "Cannot find moncrate.2da!");
return 0;
}
@@ -1051,15 +1196,15 @@ void Game::ShareXP(int xp, int flags)
}
if (xp>0) {
- displaymsg->DisplayConstantStringValue( STR_GOTXP, 0xbcefbc, (ieDword) xp); //you have gained ... xp
+ displaymsg->DisplayConstantStringValue( STR_GOTXP, DMC_BG2XPGREEN, (ieDword) xp); //you have gained ... xp
} else {
- displaymsg->DisplayConstantStringValue( STR_LOSTXP, 0xbcefbc, (ieDword) -xp); //you have lost ... xp
+ displaymsg->DisplayConstantStringValue( STR_LOSTXP, DMC_BG2XPGREEN, (ieDword) -xp); //you have lost ... xp
}
for (unsigned int i=0; i<PCs.size(); i++) {
if (PCs[i]->GetStat(IE_STATE_ID)&STATE_DEAD) {
continue;
}
- PCs[i]->AddExperience(individual);
+ PCs[i]->AddExperience(individual, flags&SX_COMBAT);
}
}
@@ -1097,7 +1242,7 @@ bool Game::EveryoneNearPoint(Map *area, const Point &p, int flags) const
return false;
}
if (Distance(p,PCs[i])>MAX_TRAVELING_DISTANCE) {
-printf("Actor %s is not near!\n", PCs[i]->LongName);
+ Log(MESSAGE, "Game", "Actor %s is not near!", PCs[i]->LongName);
return false;
}
}
@@ -1124,17 +1269,6 @@ void Game::PartyMemberDied(Actor *actor)
}
}
-//reports if someone died
-int Game::PartyMemberDied() const
-{
- for (unsigned int i=0; i<PCs.size(); i++) {
- if (PCs[i]->GetInternalFlag()&IF_JUSTDIED) {
- return i;
- }
- }
- return -1;
-}
-
void Game::IncrementChapter()
{
//chapter first set to 0 (prologue)
@@ -1154,9 +1288,9 @@ void Game::SetReputation(ieDword r)
if (r<10) r=10;
else if (r>200) r=200;
if (Reputation>r) {
- displaymsg->DisplayConstantStringValue(STR_LOSTREP,0xc0c000,(Reputation-r)/10);
+ displaymsg->DisplayConstantStringValue(STR_LOSTREP, DMC_GOLD, (Reputation-r)/10);
} else if (Reputation<r) {
- displaymsg->DisplayConstantStringValue(STR_GOTREP,0xc0c000,(r-Reputation)/10);
+ displaymsg->DisplayConstantStringValue(STR_GOTREP, DMC_GOLD, (r-Reputation)/10);
}
Reputation = r;
for (unsigned int i=0; i<PCs.size(); i++) {
@@ -1186,9 +1320,9 @@ void Game::AddGold(ieDword add)
old = PartyGold;
PartyGold += add;
if (old<PartyGold) {
- displaymsg->DisplayConstantStringValue( STR_GOTGOLD, 0xc0c000, PartyGold-old);
+ displaymsg->DisplayConstantStringValue( STR_GOTGOLD, DMC_GOLD, PartyGold-old);
} else {
- displaymsg->DisplayConstantStringValue( STR_LOSTGOLD, 0xc0c000, old-PartyGold);
+ displaymsg->DisplayConstantStringValue( STR_LOSTGOLD, DMC_GOLD, old-PartyGold);
}
}
@@ -1200,6 +1334,8 @@ void Game::AdvanceTime(ieDword add)
if (h!=GameTime/(300*AI_UPDATE_TIME)) {
//asking for a new weather when the hour changes
WeatherBits&=~WB_HASWEATHER;
+ //update clock display
+ core->GetGUIScriptEngine()->RunFunction("GUICommonWindows", "UpdateClock");
}
Ticks+=add*interval;
//change the tileset if needed
@@ -1211,7 +1347,6 @@ void Game::AdvanceTime(ieDword add)
int areatype = (area->AreaType&(AT_FOREST|AT_CITY|AT_DUNGEON))>>3;
ieResRef *res;
- printMessage("Game","Switching DayLight\n",GREEN);
if (IsDay()) {
res=&nightmovies[areatype];
} else {
@@ -1240,33 +1375,13 @@ bool Game::PartyOverflow() const
return (PCs.size()>partysize);
}
-bool Game::PCInCombat(Actor* actor) const
-{
- if (!CombatCounter) {
- return false;
- }
-
- if (actor->LastTarget) {
- return true;
- }
- if (AttackersOf(actor->GetGlobalID(), actor->GetCurrentArea())) {
- return true;
- }
- return false;
-}
-
bool Game::AnyPCInCombat() const
{
if (!CombatCounter) {
return false;
}
- for (unsigned int i=0; i<PCs.size(); i++) {
- if (PCInCombat (PCs[i])) {
- return true;
- }
- }
- return false;
+ return true;
}
//returns true if the protagonist (or the whole party died)
@@ -1305,34 +1420,13 @@ bool Game::EveryoneDead() const
void Game::UpdateScripts()
{
- ExecuteScript( 1 );
- ProcessActions(false);
+ Update();
size_t idx;
- bool PartyAttack = false;
+ PartyAttack = false;
for (idx=0;idx<Maps.size();idx++) {
Maps[idx]->UpdateScripts();
- size_t acnt=Attackers.size();
- while(acnt--) {
- Actor *actor = Maps[idx]->GetActorByGlobalID(Attackers[acnt]);
- if (actor) {
- if ( !Maps[idx]->GetActorByGlobalID(actor->LastTarget) ) {
- //Actor's target left area
- OutAttack(Attackers[acnt]);
- continue;
- } else {
- //each attacker handles their own round initiation
- actor->InitRound(GameTime);
- if (actor->InParty) {
- PartyAttack = true;
- }
- }
- } else {
- //Attacker is gone from area
- OutAttack(Attackers[acnt]);
- }
- }
}
if (PartyAttack) {
@@ -1436,20 +1530,53 @@ void Game::PlayerDream()
delete( gs );
}
+//Start a TextScreen dream for the protagonist
+void Game::TextDream()
+{
+ ieDword dream, chapter;
+ locals->Lookup("CHAPTER", chapter);
+ if (!locals->Lookup("DREAM", dream)) {
+ dream = 1;
+ }
+ snprintf(TextScreen, sizeof(ieResRef)-1, "drmtxt%d", dream+1);
+ if ((chapter > dream) && (core->Roll(1, 100, 0) <= 33)
+ && gamedata->Exists(TextScreen, IE_2DA_CLASS_ID)) {
+
+ // give innate spell to protagonist
+ AutoTable drm(TextScreen);
+ if (drm) {
+ const char *repLabel;
+ if (Reputation >= 100)
+ repLabel = "GOOD_POWER";
+ else
+ repLabel = "BAD_POWER";
+ int row = drm->GetRowIndex(repLabel);
+ if (row != -1) {
+ Actor *actor = GetPC(0, false);
+ actor->LearnSpell(drm->QueryField(row, 0), LS_MEMO|LS_LEARN);
+ }
+ }
+
+ locals->SetAt("DREAM", dream+1);
+ core->SetEventFlag(EF_TEXTSCREEN);
+ }
+}
+
//noareacheck = no random encounters
//dream = 0 - based on area non-0 - select from list
//-1 no dream
//hp is how much hp the rest will heal
-void Game::RestParty(int checks, int dream, int hp)
+//returns true if a cutscene dream is about to be played
+bool Game::RestParty(int checks, int dream, int hp)
{
if (!(checks&REST_NOMOVE) ) {
if (!EveryoneStopped()) {
- return;
+ return false;
}
}
Actor *leader = GetPC(0, true);
if (!leader) {
- return;
+ return false;
}
Map *area = leader->GetCurrentArea();
@@ -1457,45 +1584,61 @@ void Game::RestParty(int checks, int dream, int hp)
if (!(checks&REST_NOSCATTER) ) {
if (!EveryoneNearPoint( area, leader->Pos, 0 ) ) {
//party too scattered
- displaymsg->DisplayConstantString( STR_SCATTERED, 0xff0000 );
- return;
+ displaymsg->DisplayConstantString( STR_SCATTERED, DMC_RED );
+ return false;
}
}
if (!(checks&REST_NOCRITTER) ) {
//don't allow resting while in combat
if (AnyPCInCombat()) {
- displaymsg->DisplayConstantString( STR_CANTRESTMONS, 0xff0000 );
- return;
+ displaymsg->DisplayConstantString( STR_CANTRESTMONS, DMC_RED );
+ return false;
}
//don't allow resting if hostiles are nearby
if (area->AnyEnemyNearPoint(leader->Pos)) {
- displaymsg->DisplayConstantString( STR_CANTRESTMONS, 0xff0000 );
- return;
+ displaymsg->DisplayConstantString( STR_CANTRESTMONS, DMC_RED );
+ return false;
}
}
//rest check, if PartyRested should be set, area should return true
- //area should advance gametime too (so partial rest is possible)
+ // TODO: implement "rest until healed", it's an option in some games
int hours = 8;
+ int hoursLeft = 0;
if (!(checks&REST_NOAREA) ) {
//you cannot rest here
- if (area->AreaFlags&1) {
- displaymsg->DisplayConstantString( STR_MAYNOTREST, 0xff0000 );
- return;
+ if (area->AreaFlags&AF_NOSAVE) {
+ displaymsg->DisplayConstantString( STR_MAYNOTREST, DMC_RED );
+ return false;
}
//you may not rest here, find an inn
if (!(area->AreaType&(AT_OUTDOOR|AT_FOREST|AT_DUNGEON|AT_CAN_REST) ))
{
- displaymsg->DisplayConstantString( STR_MAYNOTREST, 0xff0000 );
- return;
+ displaymsg->DisplayConstantString( STR_MAYNOTREST, DMC_RED );
+ return false;
}
//area encounters
- if(area->Rest( leader->Pos, 8, (GameTime/AI_UPDATE_TIME)%7200/3600) ) {
- return;
+ // also advances gametime (so partial rest is possible)
+ hoursLeft = area->CheckRestInterruptsAndPassTime( leader->Pos, hours, (GameTime/AI_UPDATE_TIME)%7200/3600);
+ if (hoursLeft) {
+ // partial rest only, so adjust the parameters for the loop below
+ if (hp) {
+ hp = hp * (hours - hoursLeft) / hours;
+ // 0 means full heal, so we need to cancel it if we rounded to 0
+ if (!hp) {
+ hp = 1;
+ }
+ }
+ hours -= hoursLeft;
+ // the interruption occured before any resting could be done, so just bail out
+ if (!hours) {
+ return false;
+ }
}
+ } else {
+ AdvanceTime(hours*300*AI_UPDATE_TIME);
}
- AdvanceTime(2400*AI_UPDATE_TIME);
int i = GetPartySize(true); // party size, only alive
@@ -1507,15 +1650,26 @@ void Game::RestParty(int checks, int dream, int hp)
//if hp = 0, then healing will be complete
tar->Heal(hp);
//removes fatigue, recharges spells
- tar->Rest(0);
- tar->PartyRested();
+ tar->Rest(hours);
+ if (!hoursLeft)
+ tar->PartyRested();
+ }
+
+ // abort the partial rest; we got what we wanted
+ if (hoursLeft) {
+ return false;
}
- //movie and cutscene dreams
+ //movie, cutscene, and still frame dreams
+ bool cutscene = false;
if (dream>=0) {
//cutscene dreams
- if (gamedata->Exists("player1d",IE_BCS_CLASS_ID, true))
+ if (gamedata->Exists("player1d",IE_BCS_CLASS_ID, true)) {
+ cutscene = true;
PlayerDream();
+ } else if (gamedata->Exists("drmtxt2", IE_2DA_CLASS_ID, true)) {
+ TextDream();
+ }
//select dream based on area
ieResRef *movie;
@@ -1534,43 +1688,53 @@ void Game::RestParty(int checks, int dream, int hp)
area->PartyRested();
core->SetEventFlag(EF_ACTION);
- //restindex will be -1 in the case of PST
- //FIXME: I don't quite see why we can't sumply use the same strings.2da entry
- //It seems we could reduce complexity here, and free up 2-3 string slots too
+ //bg1 has "You have rested for <DURATION>" while pst has "You have
+ //rested for <HOUR> <DURATION>" and then bg1 has "<HOUR> hours" while
+ //pst just has "Hours", so this works for both
int restindex = displaymsg->GetStringReference(STR_REST);
- int strindex;
+ int hrsindex = displaymsg->GetStringReference(STR_HOURS);
char* tmpstr = NULL;
core->GetTokenDictionary()->SetAtCopy("HOUR", hours);
- if (restindex != -1) {
- strindex = displaymsg->GetStringReference(STR_HOURS);
- } else {
- strindex = displaymsg->GetStringReference(STR_PST_HOURS);
- restindex = displaymsg->GetStringReference(STR_PST_REST);
- }
//this would be bad
- if (strindex == -1 || restindex == -1) return;
- tmpstr = core->GetString(strindex, 0);
+ if (hrsindex == -1 || restindex == -1) return cutscene;
+ tmpstr = core->GetString(hrsindex, 0);
//as would this
- if (!tmpstr) return;
+ if (!tmpstr) return cutscene;
core->GetTokenDictionary()->SetAtCopy("DURATION", tmpstr);
core->FreeString(tmpstr);
- displaymsg->DisplayString(restindex, 0xffffff, 0);
+ displaymsg->DisplayString(restindex, DMC_WHITE, 0);
+ return cutscene;
}
//timestop effect
void Game::TimeStop(Actor* owner, ieDword end)
{
timestop_owner=owner;
- timestop_end=GameTime+end;
+ timestop_end=end;
+}
+
+// check if the passed actor is a victim of timestop
+bool Game::TimeStoppedFor(const Actor* target)
+{
+ if (!timestop_owner) {
+ return false;
+ }
+ if (target == timestop_owner || target->GetStat(IE_DISABLETIMESTOP)) {
+ return false;
+ }
+ return true;
}
//recalculate the party's infravision state
void Game::Infravision()
{
+ ieDword tmp = 0;
hasInfra = false;
+ core->GetDictionary()->Lookup("infravision", tmp);
+ if (!tmp) return;
Map *map = GetCurrentArea();
if (!map) return;
for(size_t i=0;i<PCs.size();i++) {
@@ -1589,7 +1753,6 @@ void Game::Infravision()
//returns the colour which should be applied onto the whole game area viewport
//this is based on timestop, dream area, weather, daytime
-static const Color TimeStopTint={0xe0,0xe0,0xe0,0x20}; //greyscale
static const Color DreamTint={0xf0,0xe0,0xd0,0x10}; //light brown scale
static const Color NightTint={0x80,0x80,0xe0,0x40}; //dark, bluish
static const Color DuskTint={0xe0,0x80,0x80,0x40}; //dark, reddish
@@ -1598,9 +1761,6 @@ static const Color DarkTint={0x80,0x80,0xe0,0x10}; //slightly dark bluish
const Color *Game::GetGlobalTint() const
{
- if (timestop_end>GameTime) {
- return &TimeStopTint;
- }
Map *map = GetCurrentArea();
if (!map) return NULL;
if (map->AreaFlags&AF_DREAM) {
@@ -1638,28 +1798,6 @@ bool Game::IsDay()
return true;
}
-void Game::InAttack(ieDword globalID)
-{
- std::vector< ieDword>::const_iterator idx;
-
- for(idx=Attackers.begin(); idx!=Attackers.end();idx++) {
- if (*idx==globalID) return;
- }
- Attackers.push_back(globalID);
-}
-
-void Game::OutAttack(ieDword globalID)
-{
- std::vector< ieDword>::iterator idx;
-
- for(idx=Attackers.begin(); idx!=Attackers.end();idx++) {
- if (*idx==globalID) {
- Attackers.erase(idx);
- break;
- }
- }
-}
-
void Game::ChangeSong(bool always, bool force)
{
int Song;
@@ -1678,27 +1816,8 @@ void Game::ChangeSong(bool always, bool force)
area->PlayAreaSong( Song, always, force );
}
-int Game::AttackersOf(ieDword globalID, Map *area) const
-{
- if (!area) {
- return 0;
- }
- std::vector< ieDword>::const_iterator idx;
-
- int cnt = 0;
- for(idx=Attackers.begin(); idx!=Attackers.end();idx++) {
- Actor * actor = area->GetActorByGlobalID(*idx);
- if (actor) {
- if (actor->LastTarget==globalID) {
- cnt++;
- }
- }
- }
- return cnt;
-}
-
/* this method redraws weather. If update is false,
-then the weather particles won't change (game paused)
+// then the weather particles won't change (game paused)
*/
void Game::DrawWeather(const Region &screen, bool update)
{
@@ -1719,12 +1838,10 @@ void Game::DrawWeather(const Region &screen, bool update)
weather->SetPhase(P_FADE);
}
}
- //if (GameTime&1) {
- int drawn = weather->Update();
- if (drawn) {
- WeatherBits &= ~WB_START;
- }
- //}
+ int drawn = weather->Update();
+ if (drawn) {
+ WeatherBits &= ~WB_INCREASESTORM;
+ }
if (WeatherBits&WB_HASWEATHER) {
return;
@@ -1741,8 +1858,8 @@ void Game::StartRainOrSnow(bool conditional, int w)
}
// whatever was responsible for calling this, we now have some set weather
WeatherBits = w | WB_HASWEATHER;
- if (w & WB_LIGHTNING) {
- if (WeatherBits&WB_START) {
+ if (w & WB_LIGHTNINGMASK) {
+ if (WeatherBits&WB_INCREASESTORM) {
//already raining
if (GameTime&1) {
core->PlaySound(DS_LIGHTNING1);
@@ -1773,17 +1890,19 @@ void Game::StartRainOrSnow(bool conditional, int w)
void Game::SetExpansion(ieDword value)
{
- if (Expansion>=value) {
- return;
+ if (value) {
+ if (Expansion>=value) {
+ return;
+ }
+ Expansion = value;
}
- Expansion = value;
- switch(Expansion) {
+ core->SetEventFlag(EF_EXPANSION);
+ switch(value) {
default:
- core->SetEventFlag(EF_EXPANSION);
break;
//TODO: move this hardcoded hack to the scripts
- case 5:
+ case 0:
core->GetDictionary()->SetAt( "PlayMode", 2 );
int i = GetPartySize(false);
@@ -1794,36 +1913,30 @@ void Game::SetExpansion(ieDword value)
}
}
-void Game::DebugDump()
+void Game::dump() const
{
+ StringBuffer buffer;
size_t idx;
- printf("Currently loaded areas:\n");
+ buffer.append("Currently loaded areas:\n");
for(idx=0;idx<Maps.size();idx++) {
Map *map = Maps[idx];
- printf("%s\n",map->GetScriptName());
- }
- printf("Current area: %s Previous area: %s\n", CurrentArea, PreviousArea);
- printf("Global script: %s\n", Scripts[0]->GetName());
- printf("CombatCounter: %d\n", (int) CombatCounter);
- printf("Attackers count: %d\n", (int) Attackers.size());
- for(idx=0;idx<Attackers.size(); idx++) {
- Actor *actor = GetActorByGlobalID(Attackers[idx]);
- if (!actor) {
- printf("Name: ???\n");
- continue;
- }
- Actor *whom = GetActorByGlobalID(actor->LastTarget);
- printf("Name: %s Attacking : %s\n", actor->ShortName, whom?whom->ShortName:"???");
+ print("%s", map->GetScriptName());
}
+ buffer.appendFormatted("Current area: %s Previous area: %s\n", CurrentArea, PreviousArea);
+ buffer.appendFormatted("Global script: %s\n", Scripts[0]->GetName());
+ int hours = GameTime/AI_UPDATE_TIME/300;
+ buffer.appendFormatted("Game time: %d (%d days, %d hours)\n", GameTime, hours/24, hours%24);
+ buffer.appendFormatted("CombatCounter: %d\n", (int) CombatCounter);
- printf("Party size: %d\n", (int) PCs.size());
+ buffer.appendFormatted("Party size: %d\n", (int) PCs.size());
for(idx=0;idx<PCs.size();idx++) {
Actor *actor = PCs[idx];
- printf("Name: %s Order %d %s\n",actor->ShortName, actor->InParty, actor->Selected?"x":"-");
+ buffer.appendFormatted("Name: %s Order %d %s\n",actor->ShortName, actor->InParty, actor->Selected?"x":"-");
}
+ Log(DEBUG, "Game", buffer);
}
Actor *Game::GetActorByGlobalID(ieDword globalID)
@@ -1846,3 +1959,40 @@ ieByte *Game::AllocateMazeData()
return mazedata;
}
+bool Game::IsTimestopActive() const
+{
+ return timestop_end > GameTime;
+}
+
+bool Game::RandomEncounter(ieResRef &BaseArea)
+{
+ if (bntrows<0) {
+ AutoTable table;
+
+ if (table.load("bntychnc")) {
+ bntrows = table->GetRowCount();
+ bntchnc = (int *) calloc(sizeof(int),bntrows);
+ for(int i = 0; i<bntrows; i++) {
+ bntchnc[i] = atoi(table->QueryField(i, 0));
+ }
+ } else {
+ bntrows = 0;
+ }
+ }
+
+ int rep = Reputation/10;
+ if (rep>=bntrows) return false;
+ if (core->Roll(1, 100, 0)>bntchnc[rep]) return false;
+ //TODO: unhardcode this
+ memcpy(BaseArea+4,"10",3);
+ return gamedata->Exists(BaseArea, IE_ARE_CLASS_ID);
+}
+
+void Game::ResetPartyCommentTimes()
+{
+ for (unsigned int slot=0; slot<PCs.size(); slot++) {
+ PCs[slot]->ResetCommentTime();
+ }
+}
+
+}
diff --git a/gemrb/core/Game.h b/gemrb/core/Game.h
index 2bb0798..e0d867b 100644
--- a/gemrb/core/Game.h
+++ b/gemrb/core/Game.h
@@ -25,7 +25,6 @@
*/
-class Game;
#ifndef GAME_H
#define GAME_H
@@ -34,13 +33,18 @@ class Game;
#include "ie_types.h"
#include "Callback.h"
-#include "Map.h"
+#include "Scriptable/Scriptable.h"
+#include "Scriptable/PCStatStruct.h"
#include "Variables.h"
-#include "Scriptable/Actor.h"
#include <vector>
+namespace GemRB {
+
+class Actor;
+class Map;
class Particles;
+class TableMgr;
//the size of the bestiary register
#define BESTIARY_SIZE 260
@@ -48,6 +52,7 @@ class Particles;
//ShareXP flags
#define SX_DIVIDE 1 //divide XP among team members
#define SX_CR 2 //use challenge rating resolution
+#define SX_COMBAT 4 //combat xp, adjusted by difficulty
//joinparty flags
#define JP_JOIN 1 //refresh join time
@@ -85,10 +90,22 @@ class Particles;
#define WB_RAIN 1
#define WB_SNOW 2
#define WB_FOG 3
-#define WB_MASK 7
-#define WB_LIGHTNING 8
-#define WB_HASWEATHER 0x40
-#define WB_START 0x80
+#define WB_TYPEMASK 3
+#define WB_LIGHTRAIN 4
+#define WB_MEDIUMRAIN 8
+#define WB_HEAVYRAIN 12
+#define WB_RAINMASK 12
+#define WB_LIGHTWIND 0x10
+#define WB_MEDWIND 0x20
+#define WB_STRONGWING 0x30
+#define WB_WINDMASK 0x30
+
+#define WB_RARELIGHTNING 0x40
+#define WB_MEDLIGHTNING 0x80
+#define WB_HEAVYLIGHTNING 0xc0
+#define WB_LIGHTNINGMASK 0xc0
+#define WB_INCREASESTORM 0x100
+#define WB_HASWEATHER 0x200
//Rest flags
#define REST_NOAREA 1 //no area check
@@ -236,7 +253,9 @@ private:
std::vector< GAMLocationEntry*> savedpositions;
std::vector< GAMLocationEntry*> planepositions;
std::vector< char*> mastarea;
- std::vector< ieDword> Attackers;
+ std::vector<std::vector<char *> > npclevels;
+ int *bntchnc;
+ int bntrows;
CRRow *crtable;
ieResRef restmovies[8];
ieResRef daymovies[8];
@@ -271,7 +290,7 @@ public:
ieDword PartyGold;
ieWord NpcInParty;
ieWord WeatherBits;
- ieDword Unknown48; //still unknown
+ ieDword CurrentLink; //named currentLink in original engine (set to -1)
ieDword Reputation;
ieDword ControlStatus; // used in bg2, iwd (where you can switch panes off)
ieDword Expansion; // mostly used by BG2. IWD games set it to 3 on newgame
@@ -279,6 +298,7 @@ public:
ieResRef CurrentArea;
ieResRef PreviousArea; //move here if the worldmap exit is illegal?
ieResRef LoadMos;
+ ieResRef TextScreen;
Actor *timestop_owner;
ieDword timestop_end;
Particles *weather;
@@ -286,6 +306,7 @@ public:
EventHandler event_handler; //like in Control
bool hasInfra;
bool familiarBlock;
+ bool PartyAttack;
private:
/** reads the challenge rating table */
void LoadCRTable();
@@ -345,6 +366,8 @@ public:
bool MasterArea(const char *area);
/** Dynamically adding an area to master areas*/
void SetMasterArea(const char *area);
+ /** place persistent actors in the fresly loaded area*/
+ void PlacePersistents(Map *map, const char *ResRef);
/** Returns slot of the map, if it was already loaded,
* don't load it again, set changepf == true,
* if you want to change the pathfinder too. */
@@ -354,9 +377,8 @@ public:
Actor* GetNPC(unsigned int Index);
void SwapPCs(unsigned int Index1, unsigned int Index2);
bool IsDay();
- void InAttack(ieDword globalID);
- void OutAttack(ieDword globalID);
- int AttackersOf(ieDword globalID, Map *area) const;
+ /** checks if the actor should be replaced via npclevel.2da and then does it */
+ bool CheckForReplacementActor(int i);
//journal entries
/** Deletes one or all journal entries if strref is -1 */
@@ -409,9 +431,6 @@ public:
}
return Formations[WhichFormation];
}
- size_t GetAttackerCount() const {
- return Attackers.size();
- }
/** converts challenge rating to xp */
int GetXPFromCR(int cr);
@@ -419,8 +438,6 @@ public:
void ShareXP(int XP, int flags);
/** returns true if we should start the party overflow window */
bool PartyOverflow() const;
- /** returns true if actor is an attacker or being attacked */
- bool PCInCombat(Actor *actor) const;
/** returns true if any pc is attacker or being attacked */
bool AnyPCInCombat() const;
/** returns true if the party death condition is true */
@@ -428,8 +445,6 @@ public:
/** returns true if no one moves */
bool EveryoneStopped() const;
bool EveryoneNearPoint(Map *map, const Point &p, int flags) const;
- /** returns true if a PC just died */
- int PartyMemberDied() const;
/** a party member just died now */
void PartyMemberDied(Actor *);
/** Increments chapter variable and refreshes kill stats */
@@ -454,9 +469,11 @@ public:
areas run scripts on door, infopoint, container, actors too */
void UpdateScripts();
/** runs area functionality, sets partyrested trigger */
- void RestParty(int checks, int dream, int hp);
+ bool RestParty(int checks, int dream, int hp);
/** timestop effect initiated by actor */
void TimeStop(Actor *actor, ieDword end);
+ /** check if the passed actor is a victim of timestop */
+ bool TimeStoppedFor(const Actor* target=NULL);
/** updates the infravision info */
void Infravision();
/** gets the colour which should be applied over the game area,
@@ -471,15 +488,24 @@ public:
/** sets expansion mode */
void SetExpansion(ieDword value);
/** Dumps information about the object */
- void DebugDump();
+ void dump() const;
/** Finds an actor by global ID */
Actor *GetActorByGlobalID(ieDword objectID);
/** Allocates maze data */
ieByte *AllocateMazeData();
+ /** Checks if any timestop effects are active */
+ bool IsTimestopActive() const;
+ /** Checks the bounty encounters (used in bg1) */
+ bool RandomEncounter(ieResRef &BaseArea);
+ /** Resets the area and bored comment timers of the whole party */
+ void ResetPartyCommentTimes();
private:
bool DetermineStartPosType(const TableMgr *strta);
ieResRef *GetDream(Map *area);
void PlayerDream();
+ void TextDream();
};
+}
+
#endif // ! GAME_H
diff --git a/gemrb/core/GameData.cpp b/gemrb/core/GameData.cpp
index 7153cee..ff1d93a 100644
--- a/gemrb/core/GameData.cpp
+++ b/gemrb/core/GameData.cpp
@@ -20,9 +20,12 @@
#include "GameData.h"
+#include "globals.h"
+
#include "ActorMgr.h"
#include "AnimationMgr.h"
#include "Cache.h"
+#include "CharAnimations.h"
#include "Effect.h"
#include "EffectMgr.h"
#include "Factory.h"
@@ -32,14 +35,19 @@
#include "Interface.h"
#include "Item.h"
#include "ItemMgr.h"
+#include "PluginMgr.h"
#include "ResourceDesc.h"
+#include "ScriptedAnimation.h"
#include "Spell.h"
#include "SpellMgr.h"
+#include "StoreMgr.h"
#include "Scriptable/Actor.h"
#include "System/FileStream.h"
#include <cstdio>
+namespace GemRB {
+
static void ReleaseItem(void *poi)
{
delete ((Item *) poi);
@@ -81,6 +89,12 @@ void GameData::ClearCaches()
SpellCache.RemoveAll(ReleaseSpell);
EffectCache.RemoveAll(ReleaseEffect);
PaletteCache.RemoveAll(ReleasePalette);
+
+ while (!stores.empty()) {
+ Store *store = stores.begin()->second;
+ stores.erase(stores.begin());
+ delete store;
+ }
}
Actor *GameData::GetCreature(const char* ResRef, unsigned int PartySlot)
@@ -90,7 +104,7 @@ Actor *GameData::GetCreature(const char* ResRef, unsigned int PartySlot)
return 0;
PluginHolder<ActorMgr> actormgr(IE_CRE_CLASS_ID);
- if (!actormgr->Open( ds, true )) {
+ if (!actormgr->Open(ds)) {
return 0;
}
Actor* actor = actormgr->GetActor(PartySlot);
@@ -106,11 +120,9 @@ int GameData::LoadCreature(const char* ResRef, unsigned int PartySlot, bool char
char nPath[_MAX_PATH], fName[16];
snprintf( fName, sizeof(fName), "%s.chr", ResRef);
PathJoin( nPath, core->GamePath, "characters", fName, NULL );
- FileStream *fs = new FileStream();
- fs -> Open( nPath, true );
- stream = (DataStream *) fs;
+ stream = FileStream::OpenFile(nPath);
PluginHolder<ActorMgr> actormgr(IE_CRE_CLASS_ID);
- if (!actormgr->Open( stream, true )) {
+ if (!actormgr->Open(stream)) {
return -1;
}
actor = actormgr->GetActor(PartySlot);
@@ -144,15 +156,15 @@ int GameData::LoadCreature(const char* ResRef, unsigned int PartySlot, bool char
}
/** Loads a 2DA Table, returns -1 on error or the Table Index on success */
-int GameData::LoadTable(const ieResRef ResRef)
+int GameData::LoadTable(const ieResRef ResRef, bool silent)
{
int ind = GetTableIndex( ResRef );
if (ind != -1) {
tables[ind].refcount++;
return ind;
}
- //printf("(%s) Table not found... Loading from file\n", ResRef);
- DataStream* str = GetResource( ResRef, IE_2DA_CLASS_ID );
+ //print("(%s) Table not found... Loading from file", ResRef);
+ DataStream* str = GetResource( ResRef, IE_2DA_CLASS_ID, silent );
if (!str) {
return -1;
}
@@ -161,7 +173,7 @@ int GameData::LoadTable(const ieResRef ResRef)
delete str;
return -1;
}
- if (!tm->Open( str, true )) {
+ if (!tm->Open(str)) {
return -1;
}
Table t;
@@ -257,8 +269,7 @@ void GameData::FreePalette(Palette *&pal, const ieResRef name)
}
if (!name || !name[0]) {
if(pal->named) {
- printf("Palette is supposed to be named, but got no name!\n");
- abort();
+ error("GameData", "Palette is supposed to be named, but got no name!\n");
} else {
pal->Release();
pal=NULL;
@@ -266,14 +277,11 @@ void GameData::FreePalette(Palette *&pal, const ieResRef name)
return;
}
if (!pal->named) {
- printf("Unnamed palette, it should be %s!\n", name);
- abort();
+ error("GameData", "Unnamed palette, it should be %s!\n", name);
}
res=PaletteCache.DecRef((void *) pal, name, true);
if (res<0) {
- printMessage( "Core", "Corrupted Palette cache encountered (reference count went below zero), ", LIGHT_RED );
- printf( "Palette name is: %.8s\n", name);
- abort();
+ error("Core", "Corrupted Palette cache encountered (reference count went below zero), Palette name is: %.8s\n", name);
}
if (!res) {
pal->Release();
@@ -281,19 +289,19 @@ void GameData::FreePalette(Palette *&pal, const ieResRef name)
pal = NULL;
}
-Item* GameData::GetItem(const ieResRef resname)
+Item* GameData::GetItem(const ieResRef resname, bool silent)
{
Item *item = (Item *) ItemCache.GetResource(resname);
if (item) {
return item;
}
- DataStream* str = GetResource( resname, IE_ITM_CLASS_ID );
+ DataStream* str = GetResource(resname, IE_ITM_CLASS_ID, silent);
PluginHolder<ItemMgr> sm(IE_ITM_CLASS_ID);
if (!sm) {
delete ( str );
return NULL;
}
- if (!sm->Open( str, true )) {
+ if (!sm->Open(str)) {
return NULL;
}
@@ -316,9 +324,7 @@ void GameData::FreeItem(Item const *itm, const ieResRef name, bool free)
res=ItemCache.DecRef((void *) itm, name, free);
if (res<0) {
- printMessage( "Core", "Corrupted Item cache encountered (reference count went below zero), ", LIGHT_RED );
- printf( "Item name is: %.8s\n", name);
- abort();
+ error("Core", "Corrupted Item cache encountered (reference count went below zero), Item name is: %.8s\n", name);
}
if (res) return;
if (free) delete itm;
@@ -336,7 +342,7 @@ Spell* GameData::GetSpell(const ieResRef resname, bool silent)
delete ( str );
return NULL;
}
- if (!sm->Open( str, true )) {
+ if (!sm->Open(str)) {
return NULL;
}
@@ -352,36 +358,14 @@ Spell* GameData::GetSpell(const ieResRef resname, bool silent)
return spell;
}
-// this is a HACK and should be replaced with a proper copying mechanism to save on lookups
-Spell* GameData::GetUncachedSpell(const ieResRef resname, bool silent)
-{
- DataStream* str = GetResource( resname, IE_SPL_CLASS_ID, silent );
- PluginHolder<SpellMgr> sm(IE_SPL_CLASS_ID);
- if (!sm) {
- delete ( str );
- return NULL;
- }
- if (!sm->Open( str, true )) {
- return NULL;
- }
-
- Spell *spell = new Spell();
- //this is required for storing the 'source'
- strnlwrcpy(spell->Name, resname, 8);
- sm->GetSpell( spell, silent );
-
- return spell;
-}
-
void GameData::FreeSpell(Spell *spl, const ieResRef name, bool free)
{
int res;
res=SpellCache.DecRef((void *) spl, name, free);
if (res<0) {
- printMessage( "Core", "Corrupted Spell cache encountered (reference count went below zero), ", LIGHT_RED );
- printf( "Spell name is: %.8s or %.8s\n", name, spl->Name);
- abort();
+ error("Core", "Corrupted Spell cache encountered (reference count went below zero), Spell name is: %.8s or %.8s\n",
+ name, spl->Name);
}
if (res) return;
if (free) delete spl;
@@ -399,7 +383,7 @@ Effect* GameData::GetEffect(const ieResRef resname)
delete ( str );
return NULL;
}
- if (!em->Open( str, true )) {
+ if (!em->Open(str)) {
return NULL;
}
@@ -418,9 +402,7 @@ void GameData::FreeEffect(Effect *eff, const ieResRef name, bool free)
res=EffectCache.DecRef((void *) eff, name, free);
if (res<0) {
- printMessage( "Core", "Corrupted Effect cache encountered (reference count went below zero), ", LIGHT_RED );
- printf( "Effect name is: %.8s\n", name);
- abort();
+ error("Core", "Corrupted Effect cache encountered (reference count went below zero), Effect name is: %.8s\n", name);
}
if (res) return;
if (free) delete eff;
@@ -434,7 +416,7 @@ ScriptedAnimation* GameData::GetScriptedAnimation( const char *effect, bool doub
if (Exists( effect, IE_VVC_CLASS_ID, true ) ) {
DataStream *ds = GetResource( effect, IE_VVC_CLASS_ID );
- ret = new ScriptedAnimation(ds, true);
+ ret = new ScriptedAnimation(ds);
} else {
AnimationFactory *af = (AnimationFactory *)
GetFactoryResource( effect, IE_BAM_CLASS_ID, IE_NORMAL );
@@ -451,11 +433,11 @@ ScriptedAnimation* GameData::GetScriptedAnimation( const char *effect, bool doub
// Return single BAM frame as a sprite. Use if you want one frame only,
// otherwise it's not efficient
-Sprite2D* GameData::GetBAMSprite(const ieResRef ResRef, int cycle, int frame)
+Sprite2D* GameData::GetBAMSprite(const ieResRef ResRef, int cycle, int frame, bool silent)
{
Sprite2D *tspr;
AnimationFactory* af = ( AnimationFactory* )
- GetFactoryResource( ResRef, IE_BAM_CLASS_ID, IE_NORMAL );
+ GetFactoryResource( ResRef, IE_BAM_CLASS_ID, IE_NORMAL, silent );
if (!af) return 0;
if (cycle == -1)
tspr = af->GetFrameWithoutCycle( (unsigned short) frame );
@@ -484,7 +466,8 @@ void* GameData::GetFactoryResource(const char* resname, SClass_ID type,
PluginHolder<AnimationMgr> ani(IE_BAM_CLASS_ID);
if (!ani)
return NULL;
- ani->Open( ret, true );
+ if (!ani->Open(ret))
+ return NULL;
AnimationFactory* af = ani->GetAnimationFactory( resname, mode );
factory->AddFactoryObject( af );
return af;
@@ -493,7 +476,7 @@ void* GameData::GetFactoryResource(const char* resname, SClass_ID type,
}
case IE_BMP_CLASS_ID:
{
- ResourceHolder<ImageMgr> img(resname);
+ ResourceHolder<ImageMgr> img(resname, silent);
if (img) {
ImageFactory* fact = img->GetImageFactory( resname );
factory->AddFactoryObject( fact );
@@ -503,9 +486,72 @@ void* GameData::GetFactoryResource(const char* resname, SClass_ID type,
return NULL;
}
default:
- printf( "\n" );
- printMessage( "KEYImporter", " ", WHITE );
- printf( "%s files are not supported.\n", core->TypeExt( type ) );
+ Log(MESSAGE, "KEYImporter", "%s files are not supported.",
+ core->TypeExt(type));
return NULL;
}
}
+
+Store* GameData::GetStore(const ieResRef ResRef)
+{
+ StoreMap::iterator it = stores.find(ResRef);
+ if (it != stores.end()) {
+ return it->second;
+ }
+
+ DataStream* str = gamedata->GetResource(ResRef, IE_STO_CLASS_ID);
+ PluginHolder<StoreMgr> sm(IE_STO_CLASS_ID);
+ if (sm == NULL) {
+ delete ( str );
+ return NULL;
+ }
+ if (!sm->Open(str)) {
+ return NULL;
+ }
+
+ Store* store = sm->GetStore(new Store());
+ if (store == NULL) {
+ return NULL;
+ }
+ strnlwrcpy(store->Name, ResRef, 8);
+ // The key needs to last as long as the store,
+ // so use the one we just copied.
+ stores[store->Name] = store;
+ return store;
+}
+
+void GameData::SaveStore(Store* store)
+{
+ if (!store)
+ return;
+ StoreMap::iterator it = stores.find(store->Name);
+ if (it == stores.end()) {
+ error("GameData", "Saving a store that wasn't cached.");
+ }
+
+ PluginHolder<StoreMgr> sm(IE_STO_CLASS_ID);
+ if (sm == NULL) {
+ error("GameData", "Can't save store to cache.");
+ }
+
+ FileStream str;
+
+ if (!str.Create(store->Name, IE_STO_CLASS_ID)) {
+ error("GameData", "Can't create file while saving store.");
+ }
+ if (!sm->PutStore(&str, store)) {
+ error("GameData", "Error saving store.");
+ }
+
+ stores.erase(it);
+ delete store;
+}
+
+void GameData::SaveAllStores()
+{
+ while (!stores.empty()) {
+ SaveStore(stores.begin()->second);
+ }
+}
+
+}
diff --git a/gemrb/core/GameData.h b/gemrb/core/GameData.h
index e1ce10f..8c00272 100644
--- a/gemrb/core/GameData.h
+++ b/gemrb/core/GameData.h
@@ -24,11 +24,21 @@
#include "SClassID.h"
#include "exports.h"
#include "ie_types.h"
+#include "iless.h"
#include "Cache.h"
#include "Holder.h"
#include "ResourceManager.h"
+#include <map>
+#include <vector>
+
+#ifdef _MSC_VER // No SFINAE
+#include "TableMgr.h"
+#endif
+
+namespace GemRB {
+
class Actor;
struct Effect;
class Factory;
@@ -38,6 +48,7 @@ class ScriptedAnimation;
class Spell;
class Sprite2D;
class TableMgr;
+class Store;
struct Table {
Holder<TableMgr> tm;
@@ -63,7 +74,7 @@ public:
// (See also the AutoTable class)
/** Loads a 2DA Table, returns -1 on error or the Table Index on success */
- int LoadTable(const char * ResRef);
+ int LoadTable(const ieResRef ResRef, bool silent=false);
/** Gets the index of a loaded table, returns -1 on error */
int GetTableIndex(const char * ResRef) const;
/** Gets a Loaded Table by its index, returns NULL on error */
@@ -74,10 +85,9 @@ public:
Palette* GetPalette(const ieResRef resname);
void FreePalette(Palette *&pal, const ieResRef name=NULL);
- Item* GetItem(const ieResRef resname);
+ Item* GetItem(const ieResRef resname, bool silent=false);
void FreeItem(Item const *itm, const ieResRef name, bool free=false);
Spell* GetSpell(const ieResRef resname, bool silent=false);
- Spell* GetUncachedSpell(const ieResRef resname, bool silent=false);
void FreeSpell(Spell *spl, const ieResRef name, bool free=false);
Effect* GetEffect(const ieResRef resname);
void FreeEffect(Effect *eff, const ieResRef name, bool free=false);
@@ -86,11 +96,17 @@ public:
ScriptedAnimation* GetScriptedAnimation( const char *ResRef, bool doublehint);
/** returns a single sprite (not cached) from a BAM resource */
- Sprite2D* GetBAMSprite(const ieResRef ResRef, int cycle, int frame);
+ Sprite2D* GetBAMSprite(const ieResRef ResRef, int cycle, int frame, bool silent=false);
/** returns factory resource, currently works only with animations */
void* GetFactoryResource(const char* resname, SClass_ID type,
unsigned char mode = IE_NORMAL, bool silent=false);
+
+ Store* GetStore(const ieResRef ResRef);
+ /// Saves a store to the cache and frees it.
+ void SaveStore(Store* store);
+ /// Saves all stores in the cache
+ void SaveAllStores();
private:
Cache ItemCache;
Cache SpellCache;
@@ -98,6 +114,8 @@ private:
Cache PaletteCache;
Factory* factory;
std::vector<Table> tables;
+ typedef std::map<const char*, Store*, iless> StoreMap;
+ StoreMap stores;
};
extern GEM_EXPORT GameData * gamedata;
@@ -109,8 +127,8 @@ public:
ResourceHolder()
{
}
- ResourceHolder(const char* resname)
- : Holder<T>(static_cast<T*>(gamedata->GetResource(resname,&T::ID)))
+ ResourceHolder(const char* resname, bool silent = false)
+ : Holder<T>(static_cast<T*>(gamedata->GetResource(resname, &T::ID, silent)))
{
}
ResourceHolder(const char* resname, const ResourceManager& manager, bool silent = false)
@@ -119,4 +137,6 @@ public:
}
};
+}
+
#endif
diff --git a/gemrb/core/GameScript/Actions.cpp b/gemrb/core/GameScript/Actions.cpp
index fb34e6c..c55f058 100644
--- a/gemrb/core/GameScript/Actions.cpp
+++ b/gemrb/core/GameScript/Actions.cpp
@@ -26,12 +26,14 @@
#include "win32def.h"
#include "AmbientMgr.h"
-#include "Audio.h"
+#include "CharAnimations.h"
#include "DataFileMgr.h"
#include "DialogHandler.h"
#include "DisplayMessage.h"
#include "Game.h"
#include "GameData.h"
+#include "GlobalTimer.h"
+#include "IniSpawn.h"
#include "Item.h"
#include "Map.h"
#include "MusicMgr.h"
@@ -41,10 +43,13 @@
#include "Video.h"
#include "WorldMap.h"
#include "GUI/GameControl.h"
+#include "GUI/EventMgr.h"
#include "Scriptable/Container.h"
#include "Scriptable/Door.h"
#include "Scriptable/InfoPoint.h"
+namespace GemRB {
+
//------------------------------------------------------------
// Action Functions
//-------------------------------------------------------------
@@ -397,7 +402,12 @@ void GameScript::SetHPPercent(Scriptable* Sender, Action* parameters)
return;
}
Actor* actor = ( Actor* ) scr;
- actor->NewBase( IE_HITPOINTS, parameters->int0Parameter, MOD_PERCENT);
+ // 0 - adjust to max hp, 1 - adjust to current
+ if (parameters->int1Parameter) {
+ actor->NewBase(IE_HITPOINTS, parameters->int0Parameter, MOD_PERCENT);
+ } else {
+ actor->NewBase(IE_HITPOINTS, actor->GetStat(IE_MAXHITPOINTS) * parameters->int0Parameter/100, MOD_ABSOLUTE);
+ }
}
void GameScript::AddHP(Scriptable* Sender, Action* parameters)
@@ -457,7 +467,7 @@ void GameScript::TriggerActivation(Scriptable* Sender, Action* parameters)
ip = Sender->GetCurrentArea()->TMap->GetInfoPoint(parameters->objects[1]->objectName);
}
if (!ip || (ip->Type!=ST_TRIGGER && ip->Type!=ST_TRAVEL && ip->Type!=ST_PROXIMITY)) {
- printf("Script error: No Trigger Named \"%s\"\n", parameters->objects[1]->objectName);
+ Log(WARNING, "Actions", "Script error: No Trigger Named \"%s\"", parameters->objects[1]->objectName);
return;
}
InfoPoint *trigger = (InfoPoint *) ip;
@@ -542,7 +552,10 @@ void GameScript::JumpToObject(Scriptable* Sender, Action* parameters)
if (parameters->string0Parameter[0]) {
CreateVisualEffectCore(Sender, Sender->Pos, parameters->string0Parameter, 0);
}
- MoveBetweenAreasCore( (Actor *) Sender, map->GetScriptName(), tar->Pos, -1, true);
+ Actor *actor = (Actor *) Sender;
+ if (actor->Persistent() || !CreateMovementEffect(actor, map->GetScriptName(), tar->Pos) ) {
+ MoveBetweenAreasCore( actor, map->GetScriptName(), tar->Pos, -1, true);
+ }
}
}
@@ -552,8 +565,15 @@ void GameScript::TeleportParty(Scriptable* /*Sender*/, Action* parameters)
int i = game->GetPartySize(false);
while (i--) {
Actor *tar = game->GetPC(i, false);
- MoveBetweenAreasCore( tar, parameters->string0Parameter,
- parameters->pointParameter, -1, true);
+ MoveBetweenAreasCore( tar, parameters->string0Parameter, parameters->pointParameter, -1, true);
+ }
+
+ //move familiars with the party
+ i = game->GetNPCCount();
+ while (i--) {
+ Actor *tar = game->GetNPC(i);
+ if (tar->GetBase(IE_EA)==EA_FAMILIAR)
+ MoveBetweenAreasCore( tar, parameters->string0Parameter, parameters->pointParameter, -1, true);
}
}
@@ -562,9 +582,6 @@ void GameScript::MoveToExpansion(Scriptable* Sender, Action* parameters)
{
Game *game = core->GetGame();
- if (!parameters->int0Parameter) {
- parameters->int0Parameter = 5;
- }
game->SetExpansion(parameters->int0Parameter);
Sender->ReleaseCurrentAction();
}
@@ -572,20 +589,41 @@ void GameScript::MoveToExpansion(Scriptable* Sender, Action* parameters)
//add some animation effects too?
void GameScript::ExitPocketPlane(Scriptable* /*Sender*/, Action* /*parameters*/)
{
+ int i, cnt;
+ Point pos;
+ ieResRef area;
+
Game *game = core->GetGame();
- for (int i = 0; i < game->GetPartySize(false); i++) {
+ cnt = game->GetPartySize(false);
+ for (i = 0; i < cnt; i++) {
Actor* act = game->GetPC( i, false );
if (act) {
+ GAMLocationEntry *gle;
if (game->GetPlaneLocationCount() <= (unsigned int)i) {
- // what are we meant to do here?
- printf("argh, couldn't restore party member %d!", i + 1);
- continue;
+ // no location, meaning the actor joined the party after the save
+ // reuse the last valid location
+ gle = game->GetPlaneLocationEntry(game->GetPlaneLocationCount()-1);
+ } else {
+ gle = game->GetPlaneLocationEntry(i);
+ }
+
+ // save player1 location for familiar movement
+ if (!i) {
+ pos = gle->Pos;
+ memcpy(area, gle->AreaResRef, sizeof(area) );
}
- GAMLocationEntry *gle = game->GetPlaneLocationEntry(i);
MoveBetweenAreasCore(act, gle->AreaResRef, gle->Pos, -1, true);
}
}
-
+
+ // move familiars
+ cnt = game->GetNPCCount();
+ for (i = 0; i < cnt; i++) {
+ Actor* act = game->GetNPC( i );
+ if (act->GetBase(IE_EA)==EA_FAMILIAR) {
+ MoveBetweenAreasCore(act, area, pos, -1, true);
+ }
+ }
// don't clear locations!
}
@@ -596,22 +634,32 @@ void GameScript::MoveGlobalsTo(Scriptable* /*Sender*/, Action* parameters)
int i = game->GetPartySize(false);
while (i--) {
Actor *tar = game->GetPC(i, false);
- //if the actor isn't in the area, we don't care
+ //if the actor isn't in the source area, we don't care
if (strnicmp(tar->Area, parameters->string0Parameter,8) ) {
continue;
}
+ // no need of CreateMovementEffect, party members are always moved immediately
MoveBetweenAreasCore( tar, parameters->string1Parameter,
parameters->pointParameter, -1, true);
}
i = game->GetNPCCount();
while (i--) {
Actor *tar = game->GetNPC(i);
- //if the actor isn't in the area, we don't care
- if (strnicmp(tar->Area, parameters->string0Parameter,8) ) {
+ //if the actor isn't in the source area, we don't care
+ if (strnicmp(tar->Area, parameters->string0Parameter, 8) ) {
continue;
}
- MoveBetweenAreasCore( tar, parameters->string1Parameter,
- parameters->pointParameter, -1, true);
+ //if the actor is currently in a loaded area, remove it from there
+ Map *map = tar->GetCurrentArea();
+ if (map) {
+ map->RemoveActor(tar);
+ }
+ //update the target's area to the destination
+ strnuprcpy(tar->Area, parameters->string1Parameter, 8);
+ //if the destination area is currently loaded, move the actor there now
+ if (game->FindMap(tar->Area) ) {
+ MoveBetweenAreasCore( tar, parameters->string1Parameter, parameters->pointParameter, -1, true);
+ }
}
}
@@ -622,8 +670,12 @@ void GameScript::MoveGlobal(Scriptable* Sender, Action* parameters)
return;
}
- MoveBetweenAreasCore( (Actor *) tar, parameters->string0Parameter,
- parameters->pointParameter, -1, true);
+ Actor *actor = (Actor *) tar;
+ //FIXME:CreateMovement UnMakes globals, probably this isn't what we want!!!
+ //maybe there is some flag that marks real global actors and temporary ones
+ if (actor->InParty || !CreateMovementEffect(actor, parameters->string0Parameter, parameters->pointParameter) ) {
+ MoveBetweenAreasCore( actor, parameters->string0Parameter, parameters->pointParameter, -1, true);
+ }
}
//we also allow moving to door, container
@@ -640,8 +692,10 @@ void GameScript::MoveGlobalObject(Scriptable* Sender, Action* parameters)
const Map *map = to->GetCurrentArea();
if (map) {
- MoveBetweenAreasCore( (Actor *) tar, map->GetScriptName(),
- to->Pos, -1, true);
+ Actor *actor = (Actor *) tar;
+ if (actor->InParty || !CreateMovementEffect(actor, parameters->string0Parameter, to->Pos) ) {
+ MoveBetweenAreasCore( (Actor *) tar, map->GetScriptName(), to->Pos, -1, true);
+ }
}
}
@@ -655,8 +709,11 @@ void GameScript::MoveGlobalObjectOffScreen(Scriptable* Sender, Action* parameter
if (!to) {
return;
}
- MoveBetweenAreasCore( (Actor *) tar, parameters->string0Parameter,
- to->Pos, -1, false);
+
+ Actor *actor = (Actor *) tar;
+ if (actor->InParty || !CreateMovementEffect(actor, parameters->string0Parameter, to->Pos) ) {
+ MoveBetweenAreasCore( actor, parameters->string0Parameter, to->Pos, -1, false);
+ }
}
//don't use offset from Sender
@@ -678,7 +735,7 @@ void GameScript::CreateCreatureObjectDoor(Scriptable* Sender, Action* parameters
{
//we hack this to death
strcpy(parameters->string1Parameter, "SPDIMNDR");
- CreateCreatureCore( Sender, parameters, CC_OFFSET | CC_CHECK_IMPASSABLE|CC_CHECK_OVERLAP | CC_PLAY_ANIM );
+ CreateCreatureCore( Sender, parameters, CC_OBJECT | CC_CHECK_IMPASSABLE|CC_CHECK_OVERLAP | CC_PLAY_ANIM );
}
//don't use offset from Sender
@@ -764,15 +821,19 @@ void GameScript::StartCutScene(Scriptable* Sender, Action* parameters)
void GameScript::CutSceneID(Scriptable* /*Sender*/, Action* /*parameters*/)
{
// shouldn't get called
- printMessage("GameScript","CutSceneID was called!\n",YELLOW);
+ Log(WARNING, "GameScript", "CutSceneID was called!");
}
+static EffectRef fx_charm_ref = { "State:Charmed", -1 };
+
void GameScript::Enemy(Scriptable* Sender, Action* /*parameters*/)
{
if (Sender->Type != ST_ACTOR) {
return;
}
Actor* actor = ( Actor* ) Sender;
+
+ actor->fxqueue.RemoveAllEffects(fx_charm_ref);
actor->SetBase( IE_EA, EA_ENEMY );
}
@@ -782,6 +843,8 @@ void GameScript::Ally(Scriptable* Sender, Action* /*parameters*/)
return;
}
Actor* actor = ( Actor* ) Sender;
+
+ actor->fxqueue.RemoveAllEffects(fx_charm_ref);
actor->SetBase( IE_EA, EA_ALLY );
}
@@ -815,6 +878,10 @@ void GameScript::SetPlayerSound(Scriptable* Sender, Action* parameters)
if (!tar || tar->Type != ST_ACTOR) {
return;
}
+ if (((ieDword) parameters->int0Parameter)>=100) {
+ Log(WARNING, "GameScript", "Invalid index %d in SetPlayerSound.", parameters->int0Parameter);
+ return;
+ }
Actor* actor = ( Actor* ) tar;
actor->StrRefs[parameters->int0Parameter]=parameters->int1Parameter;
}
@@ -932,6 +999,7 @@ void GameScript::WaitRandom(Scriptable* Sender, Action* parameters)
if (!Sender->CurrentActionState) {
Sender->ReleaseCurrentAction();
+ return;
}
assert(Sender->CurrentActionState >= 0);
@@ -947,6 +1015,7 @@ void GameScript::Wait(Scriptable* Sender, Action* parameters)
if (!Sender->CurrentActionState) {
Sender->ReleaseCurrentAction();
+ return;
}
assert(Sender->CurrentActionState >= 0);
@@ -1026,7 +1095,7 @@ void GameScript::MoveToPointNoRecticle(Scriptable* Sender, Action* parameters)
}
Actor *actor = ( Actor* ) Sender;
if (!actor->InMove() || actor->Destination != parameters->pointParameter) {
- actor->WalkTo( parameters->pointParameter, IF_NORECTICLE, 0 );
+ actor->WalkTo( parameters->pointParameter, IF_NORETICLE, 0 );
}
if (!actor->InMove()) {
// we should probably instead keep retrying until we reach dest
@@ -1060,7 +1129,7 @@ void GameScript::RunToPointNoRecticle(Scriptable* Sender, Action* parameters)
}
Actor* actor = ( Actor* ) Sender;
if (!actor->InMove() || actor->Destination != parameters->pointParameter) {
- actor->WalkTo( parameters->pointParameter, IF_NORECTICLE|IF_RUNNING, 0 );
+ actor->WalkTo( parameters->pointParameter, IF_NORETICLE|IF_RUNNING, 0 );
}
if (!actor->InMove()) {
// we should probably instead keep retrying until we reach dest
@@ -1126,13 +1195,10 @@ void GameScript::MoveToPoint(Scriptable* Sender, Action* parameters)
return;
}
Actor* actor = ( Actor* ) Sender;
- //InMove can clear destination, so we need to save it
- Point dest = actor->Destination;
// try the actual move, if we are not already moving there
if (!actor->InMove() || actor->Destination != parameters->pointParameter) {
actor->WalkTo( parameters->pointParameter, 0 );
- dest = actor->Destination;
}
// give up if we can't move there (no path was found)
@@ -1247,6 +1313,43 @@ void GameScript::ReturnToSavedLocationDelete(Scriptable* Sender, Action* paramet
}
}
+void GameScript::ReturnToStartLocation(Scriptable* Sender, Action* parameters)
+{
+ Scriptable* tar = GetActorFromObject(Sender, parameters->objects[1], GA_NO_DEAD);
+ if (!tar) {
+ tar = Sender;
+ }
+ if (tar->Type != ST_ACTOR) {
+ Sender->ReleaseCurrentAction();
+ return;
+ }
+
+ Actor* actor = (Actor *) tar;
+ Point p = actor->HomeLocation;
+ if (p.isnull()) {
+ Sender->ReleaseCurrentAction();
+ return;
+ }
+ if (!actor->InMove() || actor->Destination != p) {
+ actor->WalkTo(p, 0, 0);
+ }
+ if (!actor->InMove()) {
+ // we should probably instead keep retrying until we reach dest
+ Sender->ReleaseCurrentAction();
+ }
+}
+
+void GameScript::TriggerWalkTo(Scriptable* Sender, Action* parameters)
+{
+ Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1], 0 );
+ if (!tar) {
+ Sender->ReleaseCurrentAction();
+ return;
+ }
+ MoveToObjectCore(Sender, parameters, 0, false);
+ tar->AddTrigger(TriggerEntry(trigger_walkedtotrigger, Sender->GetGlobalID()));
+}
+
void GameScript::MoveToObjectNoInterrupt(Scriptable* Sender, Action* parameters)
{
MoveToObjectCore(Sender, parameters, IF_NOINT, false);
@@ -1306,12 +1409,14 @@ void GameScript::RestorePartyLocation(Scriptable* /*Sender*/, Action* /*paramete
for (int i = 0; i < game->GetPartySize(false); i++) {
Actor* act = game->GetPC( i, false );
if (act) {
+ GAMLocationEntry *gle;
if (game->GetSavedLocationCount() <= (unsigned int)i) {
- // what are we meant to do here?
- printf("argh, couldn't restore party member %d!", i + 1);
- continue;
+ // no location, meaning the actor joined the party after the save
+ // reuse the last valid location
+ gle = game->GetSavedLocationEntry(game->GetSavedLocationCount()-1);
+ } else {
+ gle = game->GetSavedLocationEntry(i);
}
- GAMLocationEntry *gle = game->GetSavedLocationEntry(i);
MoveBetweenAreasCore(act, gle->AreaResRef, gle->Pos, -1, true);
}
}
@@ -1523,7 +1628,7 @@ void GameScript::DisplayStringHead(Scriptable* Sender, Action* parameters)
Scriptable* target = GetActorFromObject( Sender, parameters->objects[1] );
if (!target) {
target=Sender;
- printf("DisplayStringHead/FloatMessage got no target, assuming Sender!\n");
+ Log(WARNING, "Actions", "DisplayStringHead/FloatMessage got no target, assuming Sender!");
}
DisplayStringCore(target, parameters->int0Parameter, DS_CONSOLE|DS_HEAD|DS_SPEECH );
@@ -1556,7 +1661,7 @@ void GameScript::FloatMessageFixed(Scriptable* Sender, Action* parameters)
Scriptable* target = GetActorFromObject( Sender, parameters->objects[1] );
if (!target) {
target=Sender;
- printf("DisplayStringHead/FloatMessage got no target, assuming Sender!\n");
+ Log(ERROR, "GameScript", "DisplayStringHead/FloatMessage got no target, assuming Sender!");
}
DisplayStringCore(target, parameters->int0Parameter, DS_CONSOLE|DS_HEAD);
@@ -1567,12 +1672,12 @@ void GameScript::FloatMessageFixedRnd(Scriptable* Sender, Action* parameters)
Scriptable* target = GetActorFromObject( Sender, parameters->objects[1] );
if (!target) {
target=Sender;
- printf("DisplayStringHead/FloatMessage got no target, assuming Sender!\n");
+ Log(ERROR, "GameScript", "DisplayStringHead/FloatMessage got no target, assuming Sender!");
}
SrcVector *rndstr=LoadSrc(parameters->string0Parameter);
if (!rndstr) {
- printMessage("GameScript","Cannot display resource!",LIGHT_RED);
+ Log(ERROR, "GameScript", "Cannot display resource!");
return;
}
DisplayStringCore(target, rndstr->at(rand()%rndstr->size()), DS_CONSOLE|DS_HEAD);
@@ -1584,12 +1689,12 @@ void GameScript::FloatMessageRnd(Scriptable* Sender, Action* parameters)
Scriptable* target = GetActorFromObject( Sender, parameters->objects[1] );
if (!target) {
target=Sender;
- printf("DisplayStringHead/FloatMessage got no target, assuming Sender!\n");
+ Log(ERROR, "GameScript", "DisplayStringHead/FloatMessage got no target, assuming Sender!");
}
SrcVector *rndstr=LoadSrc(parameters->string0Parameter);
if (!rndstr) {
- printMessage("GameScript","Cannot display resource!",LIGHT_RED);
+ Log(ERROR, "GameScript", "Cannot display resource!");
return;
}
DisplayStringCore(target, rndstr->at(rand()%rndstr->size()), DS_CONSOLE|DS_HEAD);
@@ -1613,10 +1718,9 @@ void GameScript::DisplayString(Scriptable* Sender, Action* parameters)
//DisplayStringHead, but wait until done
void GameScript::DisplayStringWait(Scriptable* Sender, Action* parameters)
{
+ ieDword gt = core->GetGame()->GameTime;
if (Sender->CurrentActionState) {
- // TODO: should probably store the actual time and wait for that,
- // rather than this hack
- if (!core->GetAudioDrv()->IsSpeaking()) {
+ if (gt >= (ieDword)parameters->int2Parameter) {
Sender->ReleaseCurrentAction();
}
return;
@@ -1627,6 +1731,8 @@ void GameScript::DisplayStringWait(Scriptable* Sender, Action* parameters)
}
DisplayStringCore( target, parameters->int0Parameter, DS_CONSOLE|DS_WAIT|DS_SPEECH|DS_HEAD);
Sender->CurrentActionState = 1;
+ // parameters->int2Parameter is unused here so hijack it to store the wait time
+ parameters->int2Parameter = gt + target->GetWait();
}
void GameScript::ForceFacing(Scriptable* Sender, Action* parameters)
@@ -1728,7 +1834,7 @@ void GameScript::StartSong(Scriptable* /*Sender*/, Action* parameters)
void GameScript::StartMusic(Scriptable* Sender, Action* parameters)
{
//don't break on bad values
- if (parameters->int0Parameter>10) return;
+ if (parameters->int0Parameter >= 10) return;
Map *map = Sender->GetCurrentArea();
if (!map) return;
bool force, restart;
@@ -1761,7 +1867,7 @@ void GameScript::StartCombatCounter(Scriptable* Sender, Action* /*parameters*/)
void GameScript::SetMusic(Scriptable* Sender, Action* parameters)
{
//iwd2 allows setting all 10 slots, though, there is no evidence they are used
- if (parameters->int0Parameter>10) return;
+ if (parameters->int0Parameter >= 10) return;
Map *map = Sender->GetCurrentArea();
if (!map) return;
map->SongHeader.SongList[parameters->int0Parameter]=parameters->int1Parameter;
@@ -1770,20 +1876,20 @@ void GameScript::SetMusic(Scriptable* Sender, Action* parameters)
//optional integer parameter (isSpeech)
void GameScript::PlaySound(Scriptable* Sender, Action* parameters)
{
- printf( "PlaySound(%s)\n", parameters->string0Parameter );
+ Log(MESSAGE, "Actions", "PlaySound(%s)", parameters->string0Parameter);
core->GetAudioDrv()->Play( parameters->string0Parameter, Sender->Pos.x,
Sender->Pos.y, parameters->int0Parameter ? GEM_SND_SPEECH : 0 );
}
void GameScript::PlaySoundPoint(Scriptable* /*Sender*/, Action* parameters)
{
- printf( "PlaySound(%s)\n", parameters->string0Parameter );
+ Log(MESSAGE, "Actions", "PlaySound(%s)", parameters->string0Parameter );
core->GetAudioDrv()->Play( parameters->string0Parameter, parameters->pointParameter.x, parameters->pointParameter.y );
}
void GameScript::PlaySoundNotRanged(Scriptable* /*Sender*/, Action* parameters)
{
- printf( "PlaySound(%s)\n", parameters->string0Parameter );
+ Log(MESSAGE, "Actions", "PlaySound(%s)", parameters->string0Parameter );
core->GetAudioDrv()->Play( parameters->string0Parameter, 0, 0);
}
@@ -1896,22 +2002,10 @@ void GameScript::SoundActivate(Scriptable* /*Sender*/, Action* parameters)
}
// according to IESDP this action is about animations
+//PST's SetCorpseEnabled also handles containers, but no one uses it
void GameScript::AmbientActivate(Scriptable* Sender, Action* parameters)
{
- AreaAnimation* anim = Sender->GetCurrentArea( )->GetAnimation( parameters->string0Parameter);
- if (!anim) {
- anim = Sender->GetCurrentArea( )->GetAnimation( parameters->objects[1]->objectName );
- }
- if (!anim) {
- printf( "Script error: No Animation Named \"%s\" or \"%s\"\n",
- parameters->string0Parameter,parameters->objects[1]->objectName );
- return;
- }
- if (parameters->int0Parameter) {
- anim->Flags |= A_ANI_ACTIVE;
- } else {
- anim->Flags &= ~A_ANI_ACTIVE;
- }
+ AmbientActivateCore(Sender, parameters, parameters->int0Parameter);
}
void GameScript::ChangeTileState(Scriptable* Sender, Action* parameters)
@@ -1934,7 +2028,7 @@ void GameScript::StaticStart(Scriptable* Sender, Action* parameters)
{
AreaAnimation *anim = Sender->GetCurrentArea()->GetAnimation(parameters->objects[1]->objectName);
if (!anim) {
- printf( "Script error: No Animation Named \"%s\"\n",
+ Log(WARNING, "Actions", "Script error: No Animation Named \"%s\"",
parameters->objects[1]->objectName );
return;
}
@@ -1945,7 +2039,7 @@ void GameScript::StaticStop(Scriptable* Sender, Action* parameters)
{
AreaAnimation *anim = Sender->GetCurrentArea()->GetAnimation(parameters->objects[1]->objectName);
if (!anim) {
- printf( "Script error: No Animation Named \"%s\"\n",
+ Log(WARNING, "Actions", "Script error: No Animation Named \"%s\"",
parameters->objects[1]->objectName );
return;
}
@@ -1956,7 +2050,7 @@ void GameScript::StaticPalette(Scriptable* Sender, Action* parameters)
{
AreaAnimation *anim = Sender->GetCurrentArea()->GetAnimation(parameters->objects[1]->objectName);
if (!anim) {
- printf( "Script error: No Animation Named \"%s\"\n",
+ Log(WARNING, "Actions", "Script error: No Animation Named \"%s\"",
parameters->objects[1]->objectName );
return;
}
@@ -1977,7 +2071,7 @@ void GameScript::PlaySequenceTimed(Scriptable* Sender, Action* parameters)
}
Actor* actor = ( Actor* ) tar;
actor->SetStance( parameters->int0Parameter );
- int delay = parameters->int1Parameter || 1;
+ int delay = parameters->int1Parameter;
actor->SetWait( delay );
}
@@ -2001,64 +2095,16 @@ void GameScript::WaitAnimation(Scriptable* Sender, Action* parameters)
// PlaySequence without object parameter defaults to Sender
void GameScript::PlaySequence(Scriptable* Sender, Action* parameters)
{
- Scriptable* tar;
- if (parameters->objects[1]) {
- tar = GetActorFromObject( Sender, parameters->objects[1] );
- if (!tar) {
- //could be an animation
- AreaAnimation* anim = Sender->GetCurrentArea( )->GetAnimation( parameters->objects[1]->objectName);
- if (anim) {
- //set animation's cycle to parameters->int0Parameter;
- anim->sequence=parameters->int0Parameter;
- anim->frame=0;
- //what else to be done???
- anim->InitAnimation();
- }
- return;
- }
-
- } else {
- tar = Sender;
- }
- if (tar->Type != ST_ACTOR) {
- return;
- }
- Actor* actor = ( Actor* ) tar;
- actor->SetStance( parameters->int0Parameter );
+ PlaySequenceCore(Sender, parameters, parameters->int0Parameter);
}
//same as PlaySequence, but the value comes from a variable
-//ToDo: create a PlaySequenceCore in GSUtils
void GameScript::PlaySequenceGlobal(Scriptable* Sender, Action* parameters)
{
- Scriptable* tar;
ieDword value;
value = (ieDword) CheckVariable( Sender, parameters->string0Parameter );
-
- if (parameters->objects[1]) {
- tar = GetActorFromObject( Sender, parameters->objects[1] );
- if (!tar) {
- //could be an animation
- AreaAnimation* anim = Sender->GetCurrentArea( )->GetAnimation( parameters->objects[1]->objectName);
- if (anim) {
- //set animation's cycle to value;
- anim->sequence=value;
- anim->frame=0;
- //what else to be done???
- anim->InitAnimation();
- }
- return;
- }
-
- } else {
- tar = Sender;
- }
- if (tar->Type != ST_ACTOR) {
- return;
- }
- Actor* actor = ( Actor* ) tar;
- actor->SetStance( value );
+ PlaySequenceCore(Sender, parameters, value);
}
void GameScript::SetDialogue(Scriptable* Sender, Action* parameters)
@@ -2139,14 +2185,40 @@ void GameScript::NIDSpecial2(Scriptable* Sender, Action* /*parameters*/)
return;
}
Actor *actor = (Actor *) Sender;
- if (!game->EveryoneNearPoint(actor->GetCurrentArea(), actor->Pos, true) ) {
+ if (!game->EveryoneNearPoint(actor->GetCurrentArea(), actor->Pos, ENP_CANMOVE) ) {
//we abort the command, everyone should be here
Sender->ReleaseCurrentAction();
return;
}
+
//travel direction passed to guiscript
int direction = Sender->GetCurrentArea()->WhichEdge(actor->Pos);
- printf("Travel direction returned: %d\n", direction);
+ Log(MESSAGE, "Actions", "Travel direction returned: %d", direction);
+ //this is notoriously flaky
+ //if it doesn't work for the sender try other party members, too
+ if (direction == -1) {
+ int i, best, directions[4] = { -1, -1, -1, -1 };
+ for (i = 0; i < game->GetPartySize(false); i++) {
+ actor = game->GetPC(i, false);
+ if (actor != Sender) {
+ int partydir = actor->GetCurrentArea()->WhichEdge(actor->Pos);
+ if (partydir != -1) {
+ directions[partydir]++;
+ }
+ }
+ }
+ best = 0;
+ for (i = 1; i < 4; ++i) {
+ if (directions[i] > directions[best]) {
+ best = i;
+ }
+ }
+ if (directions[best] != -1) {
+ direction = best;
+ }
+ Log(DEBUG, "Actions", "Travel direction determined by party: %d", direction);
+ }
+
if (direction==-1) {
Sender->ReleaseCurrentAction();
return;
@@ -2280,7 +2352,7 @@ void GameScript::SetDoorFlag(Scriptable* Sender, Action* parameters)
flag&=~DOOR_LOCKED;
door->SetDoorLocked(parameters->int1Parameter!=0, false);
}
- if (flag&DOOR_OPEN) {
+ if (flag&(DOOR_OPEN|DOOR_HIDDEN)) {
flag&=~DOOR_OPEN;
door->SetDoorOpen(parameters->int1Parameter!=0, false, 0);
}
@@ -2304,6 +2376,7 @@ void GameScript::RemoveTraps(Scriptable* Sender, Action* parameters)
Sender->ReleaseCurrentAction();
return;
}
+ Actor * actor = (Actor *) Sender;
unsigned int distance;
Point *p, *otherp;
Door *door = NULL;
@@ -2340,12 +2413,12 @@ void GameScript::RemoveTraps(Scriptable* Sender, Action* parameters)
otherp = p;
distance = Distance(tar, Sender);
flags = trigger->Trapped && trigger->TrapDetected && trigger->CanDetectTrap();
+ actor->SetDisarmingTrap(trigger->GetGlobalID());
break;
default:
Sender->ReleaseCurrentAction();
return;
}
- Actor * actor = (Actor *) Sender;
actor->SetOrientation( GetOrient( *otherp, actor->Pos ), false);
if (distance <= MAX_OPERATING_DISTANCE) {
if (flags) {
@@ -2448,6 +2521,7 @@ void GameScript::OpenDoor(Scriptable* Sender, Action* parameters) {
return;
}
Door* door = ( Door* ) tar;
+ int gid = 0;
// no idea if this is right, or whether OpenDoor/CloseDoor should allow opening
// of all doors, or some doors, or whether it should still check for non-actors
if (Sender->Type == ST_ACTOR) {
@@ -2456,9 +2530,10 @@ void GameScript::OpenDoor(Scriptable* Sender, Action* parameters) {
if (!door->TryUnlock(actor)) {
return;
}
+ gid = actor->GetGlobalID();
}
//if not an actor opens, it don't play sound
- door->SetDoorOpen( true, (Sender->Type == ST_ACTOR), 0 );
+ door->SetDoorOpen(true, (Sender->Type == ST_ACTOR), gid);
Sender->ReleaseCurrentAction();
}
@@ -2504,7 +2579,7 @@ void GameScript::ToggleDoor(Scriptable* Sender, Action* /*parameters*/)
if (distance <= MAX_OPERATING_DISTANCE) {
actor->SetOrientation( GetOrient( *otherp, actor->Pos ), false);
if (!door->TryUnlock(actor)) {
- displaymsg->DisplayConstantString(STR_DOORLOCKED,0xd7d7be,door);
+ displaymsg->DisplayConstantString(STR_DOORLOCKED, DMC_LIGHTGREY, door);
//playsound unsuccessful opening of door
if(door->IsOpen())
core->PlaySound(DS_CLOSE_FAIL);
@@ -2515,8 +2590,7 @@ void GameScript::ToggleDoor(Scriptable* Sender, Action* /*parameters*/)
return; //don't open door
}
- // should we be triggering the trap on close?
- door->TriggerTrap(0, actor->GetGlobalID());
+ //trap scripts are triggered by SetDoorOpen
door->SetDoorOpen( !door->IsOpen(), true, actor->GetGlobalID() );
} else {
MoveNearerTo(Sender, *p, MAX_OPERATING_DISTANCE,0);
@@ -2549,121 +2623,29 @@ void GameScript::MoveBetweenAreas(Scriptable* Sender, Action* parameters)
if (parameters->string1Parameter[0]) {
CreateVisualEffectCore(Sender, Sender->Pos, parameters->string1Parameter, 0);
}
- MoveBetweenAreasCore((Actor *) Sender, parameters->string0Parameter,
- parameters->pointParameter, parameters->int0Parameter, true);
+
+ Actor *actor = (Actor *) Sender;
+ if (actor->Persistent() || !CreateMovementEffect(actor, parameters->string0Parameter, parameters->pointParameter) ) {
+ MoveBetweenAreasCore(actor, parameters->string0Parameter, parameters->pointParameter, parameters->int0Parameter, true);
+ }
}
//spell is depleted, casting time is calculated, interruptible
//FIXME The caster must meet the level requirements as set in the spell file
void GameScript::Spell(Scriptable* Sender, Action* parameters)
{
- ieResRef spellres;
-
- //resolve spellname
- if (!ResolveSpellName( spellres, parameters) ) {
- Sender->ReleaseCurrentAction();
- return;
- }
-
- //if target was set, fire spell
- if (Sender->LastTarget) {
- Sender->CastSpellEnd(0);
- Sender->ReleaseCurrentAction();
- return;
- }
-
- //the target was converted to a point
- if(!Sender->LastTargetPos.isempty()) {
- Sender->CastSpellPointEnd(0);
- Sender->ReleaseCurrentAction();
- return;
- }
-
- //parse target
- int seeflag;
- unsigned int dist = GetSpellDistance(spellres, Sender);
- if (dist == 0xffffffff) {
- seeflag = 0;
- } else {
- seeflag = GA_NO_DEAD;
- }
-
- Scriptable* tar = GetStoredActorFromObject( Sender, parameters->objects[1], seeflag );
- if (!tar) {
- Sender->ReleaseCurrentAction();
- return;
- }
-
- if(Sender->Type==ST_ACTOR) {
- Actor *act = (Actor *) Sender;
-
- //move near to target
- if (dist != 0xffffffff) {
- if (PersonalDistance(tar, Sender) > dist || !Sender->GetCurrentArea()->IsVisible(Sender->Pos, tar->Pos)) {
- MoveNearerTo(Sender,tar,dist);
- return;
- }
- }
-
- //face target
- if (tar != Sender) {
- act->SetOrientation( GetOrient( tar->Pos, act->Pos ), false );
- }
-
- //stop doing anything else
- act->SetModal(MS_NONE);
- }
- int duration = Sender->CastSpell( spellres, tar, true );
- if (duration != -1) Sender->SetWait(duration);
-
- //if target was set, feed action back
- if (!Sender->LastTarget && Sender->LastTargetPos.isempty()) {
- Sender->ReleaseCurrentAction();
+ // handle the SpellWait iwd2 special case (other games don't use int0, so it is harmless)
+ if (parameters->int0Parameter == 0) {
+ parameters->int0Parameter = Sender->LastMarkedSpell;
}
+ SpellCore(Sender, parameters, SC_NO_DEAD|SC_RANGE_CHECK|SC_DEPLETE|SC_AURA_CHECK);
}
//spell is depleted, casting time is calculated, interruptible
//FIXME The caster must meet the level requirements as set in the spell file
void GameScript::SpellPoint(Scriptable* Sender, Action* parameters)
{
- ieResRef spellres;
-
- //resolve spellname
- if (!ResolveSpellName( spellres, parameters) ) {
- Sender->ReleaseCurrentAction();
- return;
- }
-
- //if target was set, fire spell
- if (!Sender->LastTargetPos.isempty()) {
- Sender->CastSpellPointEnd(0);
- Sender->ReleaseCurrentAction();
- return;
- }
-
- if(Sender->Type==ST_ACTOR) {
- unsigned int dist = GetSpellDistance(spellres, Sender);
-
- Actor *act = (Actor *) Sender;
- //move near to target
- if (PersonalDistance(parameters->pointParameter, Sender) > dist || !Sender->GetCurrentArea()->IsVisible(Sender->Pos, parameters->pointParameter)) {
- MoveNearerTo(Sender,parameters->pointParameter,dist, 0);
- return;
- }
-
- //face target
- act->SetOrientation( GetOrient( parameters->pointParameter, act->Pos ), false );
- //stop doing anything else
- act->SetModal(MS_NONE);
- }
-
- int duration = Sender->CastSpellPoint( spellres, parameters->pointParameter, true );
- if (duration != -1) Sender->SetWait(duration);
-
- //if target was set, feed action back
- if (!Sender->LastTarget && Sender->LastTargetPos.isempty()) {
- Sender->ReleaseCurrentAction();
- }
+ SpellPointCore(Sender, parameters, SC_RANGE_CHECK|SC_DEPLETE|SC_AURA_CHECK);
}
//spell is not depleted (doesn't need to be memorised or known)
@@ -2671,56 +2653,7 @@ void GameScript::SpellPoint(Scriptable* Sender, Action* parameters)
//FIXME The caster must meet the level requirements as set in the spell file
void GameScript::SpellNoDec(Scriptable* Sender, Action* parameters)
{
- ieResRef spellres;
-
- //resolve spellname
- if (!ResolveSpellName( spellres, parameters) ) {
- Sender->ReleaseCurrentAction();
- return;
- } else {
- if (!Sender->SpellResRef[0]) {
- Sender->SetSpellResRef(spellres);
- }
- }
-
- //if target was set, fire spell
- if (Sender->LastTarget) {
- Sender->CastSpellEnd(0);
- Sender->ReleaseCurrentAction();
- return;
- }
-
- //the target was converted to a point
- if(!Sender->LastTargetPos.isempty()) {
- Sender->CastSpellPointEnd(0);
- Sender->ReleaseCurrentAction();
- return;
- }
-
- //parse target
- Scriptable* tar = GetStoredActorFromObject( Sender, parameters->objects[1] );
- if (!tar) {
- Sender->ReleaseCurrentAction();
- return;
- }
-
- //face target
- if (Sender->Type==ST_ACTOR) {
- Actor *act = (Actor *) Sender;
- if (tar != Sender) {
- act->SetOrientation( GetOrient( tar->Pos, act->Pos ), false );
- }
-
- //stop doing anything else
- act->SetModal(MS_NONE);
- }
- int duration = Sender->CastSpell( spellres, tar, false );
- if (duration != -1) Sender->SetWait(duration);
-
- //if target was set, feed action back
- if (!Sender->LastTarget && Sender->LastTargetPos.isempty()) {
- Sender->ReleaseCurrentAction();
- }
+ SpellCore(Sender, parameters, SC_NO_DEAD|SC_RANGE_CHECK|SC_AURA_CHECK);
}
//spell is not depleted (doesn't need to be memorised or known)
@@ -2728,41 +2661,7 @@ void GameScript::SpellNoDec(Scriptable* Sender, Action* parameters)
//FIXME The caster must meet the level requirements as set in the spell file
void GameScript::SpellPointNoDec(Scriptable* Sender, Action* parameters)
{
- ieResRef spellres;
-
- //resolve spellname
- if (!ResolveSpellName( spellres, parameters) ) {
- Sender->ReleaseCurrentAction();
- return;
- } else {
- if (!Sender->SpellResRef[0]) {
- Sender->SetSpellResRef(spellres);
- }
- }
-
- //if target was set, fire spell
- if (!Sender->LastTargetPos.isempty()) {
- Sender->CastSpellPointEnd(0);
- Sender->ReleaseCurrentAction();
- return;
- }
-
- //face target
- if (Sender->Type==ST_ACTOR) {
- Actor *act = (Actor *) Sender;
- act->SetOrientation( GetOrient( parameters->pointParameter, act->Pos ), false );
-
- //stop doing anything else
- act->SetModal(MS_NONE);
- }
-
- int duration = Sender->CastSpellPoint( spellres, parameters->pointParameter, false );
- if (duration != -1) Sender->SetWait(duration);
-
- //if target was set, feed action back
- if (Sender->LastTargetPos.isempty()) {
- Sender->ReleaseCurrentAction();
- }
+ SpellPointCore(Sender, parameters, SC_RANGE_CHECK|SC_AURA_CHECK);
}
//spell is not depleted (doesn't need to be memorised or known)
@@ -2770,141 +2669,33 @@ void GameScript::SpellPointNoDec(Scriptable* Sender, Action* parameters)
//FIXME The caster must meet the level requirements as set in the spell file
void GameScript::ForceSpell(Scriptable* Sender, Action* parameters)
{
- ieResRef spellres;
-
- //resolve spellname
- if (!ResolveSpellName( spellres, parameters) ) {
- Sender->ReleaseCurrentAction();
- return;
- } else {
- if (!Sender->SpellResRef[0]) {
- Sender->SetSpellResRef(spellres);
- }
- }
-
- //if target was set, fire spell
- if (Sender->LastTarget) {
- Sender->CastSpellEnd(0);
- Sender->ReleaseCurrentAction();
- return;
- }
-
- //the target was converted to a point
- if(!Sender->LastTargetPos.isempty()) {
- Sender->CastSpellPointEnd(0);
- Sender->ReleaseCurrentAction();
- return;
- }
-
- //parse target
- Scriptable* tar = GetStoredActorFromObject( Sender, parameters->objects[1] );
- if (!tar) {
- Sender->ReleaseCurrentAction();
- return;
- }
-
- //face target
- if (Sender->Type==ST_ACTOR) {
- Actor *act = (Actor *) Sender;
- if (tar != Sender) {
- act->SetOrientation( GetOrient( tar->Pos, act->Pos ), false );
- }
-
- //stop doing anything else
- act->SetModal(MS_NONE);
- }
- int duration = Sender->CastSpell (spellres, tar, false);
- if (duration != -1) Sender->SetWait(duration);
-
- //if target was set, feed action back
- if (!Sender->LastTarget && Sender->LastTargetPos.isempty()) {
- Sender->ReleaseCurrentAction();
- }
+ SpellCore(Sender, parameters, SC_NOINTERRUPT);
}
-//spell is not depleted (doesn't need to be memorised or known)
-//casting time is calculated, not interruptable
-//FIXME The caster must meet the level requirements as set in the spell file
-void GameScript::ForceSpellPoint(Scriptable* Sender, Action* parameters)
+void GameScript::ForceSpellRange(Scriptable* Sender, Action* parameters)
{
- ieResRef spellres;
-
- if (!ResolveSpellName( spellres, parameters) ) {
- Sender->ReleaseCurrentAction();
- return;
- } else {
- if (!Sender->SpellResRef[0]) {
- Sender->SetSpellResRef(spellres);
- }
- }
-
- //if target was set, fire spell
- if (!Sender->LastTargetPos.isempty()) {
- Sender->CastSpellPointEnd(0);
- Sender->ReleaseCurrentAction();
- return;
- }
-
- //face target
- if (Sender->Type==ST_ACTOR) {
- Actor *act = (Actor *) Sender;
- act->SetOrientation( GetOrient( parameters->pointParameter, act->Pos ), false );
-
- //stop doing anything else
- act->SetModal(MS_NONE);
- }
-
- int duration = Sender->CastSpellPoint (spellres, parameters->pointParameter, false);
- if (duration != -1) Sender->SetWait(duration);
-
- //if target was set, feed action back
- if (Sender->LastTargetPos.isempty()) {
- Sender->ReleaseCurrentAction();
- }
+ SpellCore(Sender, parameters, SC_NOINTERRUPT|SC_RANGE_CHECK);
}
-//ForceSpell with zero casting time
-//zero casting time, no depletion, not interruptable
+//spell is not depleted (doesn't need to be memorised or known)
+//casting time is calculated, not interruptable
//FIXME The caster must meet the level requirements as set in the spell file
-//FIXME The spell level is taken as parameter2 in some cases (FIXED)
-void GameScript::ReallyForceSpell(Scriptable* Sender, Action* parameters)
-{
- ieResRef spellres;
- int level;
-
- if (!ResolveSpellName( spellres, parameters) ) {
- Sender->ReleaseCurrentAction();
- return;
- } else {
- if (!Sender->SpellResRef[0]) {
- Sender->SetSpellResRef(spellres);
- }
- }
-
- Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] );
- if (!tar) {
- Sender->ReleaseCurrentAction();
- return;
- }
- if (Sender->Type == ST_ACTOR) {
- Actor *actor = (Actor *) Sender;
- if (tar != Sender) {
- actor->SetOrientation( GetOrient( tar->Pos, actor->Pos ), false );
- }
- actor->SetStance (IE_ANI_CONJURE);
- }
- Sender->CastSpell (spellres, tar, false, true);
- if (parameters->string0Parameter[0]) {
- level = parameters->int0Parameter;
- } else {
- level = parameters->int1Parameter;
- }
- if (tar->Type==ST_ACTOR) {
- Sender->CastSpellEnd(level);
- } else {
- Sender->CastSpellPointEnd(level);
- }
- Sender->ReleaseCurrentAction();
+void GameScript::ForceSpellPoint(Scriptable* Sender, Action* parameters)
+{
+ SpellPointCore(Sender, parameters, SC_NOINTERRUPT);
+}
+
+void GameScript::ForceSpellPointRange(Scriptable* Sender, Action* parameters)
+{
+ SpellPointCore(Sender, parameters, SC_NOINTERRUPT|SC_RANGE_CHECK);
+}
+
+//ForceSpell with zero casting time
+//zero casting time, no depletion, not interruptable
+//FIXME The caster must meet the level requirements as set in the spell file
+void GameScript::ReallyForceSpell(Scriptable* Sender, Action* parameters)
+{
+ SpellCore(Sender, parameters, SC_NOINTERRUPT|SC_SETLEVEL|SC_INSTANT);
}
//ForceSpellPoint with zero casting time
@@ -2913,85 +2704,68 @@ void GameScript::ReallyForceSpell(Scriptable* Sender, Action* parameters)
//FIXME The caster must meet the level requirements as set in the spell file
void GameScript::ReallyForceSpellPoint(Scriptable* Sender, Action* parameters)
{
- ieResRef spellres;
- int level;
-
- if (!ResolveSpellName( spellres, parameters) ) {
- Sender->ReleaseCurrentAction();
- return;
- } else {
- if (!Sender->SpellResRef[0]) {
- Sender->SetSpellResRef(spellres);
- }
- }
-
- //Sender->LastTargetPos=parameters->pointParameter;
- if (Sender->Type == ST_ACTOR) {
- if (Sender->GetInternalFlag()&IF_STOPATTACK) {
- Sender->ReleaseCurrentAction();
- return;
- }
- Actor *actor = (Actor *) Sender;
- actor->SetOrientation( GetOrient( parameters->pointParameter, actor->Pos ), false );
- actor->SetStance (IE_ANI_CONJURE);
- }
- Sender->CastSpellPoint (spellres, parameters->pointParameter, false, true);
- if (parameters->string0Parameter[0]) {
- level = parameters->int0Parameter;
- } else {
- level = parameters->int1Parameter;
- }
- Sender->CastSpellPointEnd(level);
- Sender->ReleaseCurrentAction();
+ SpellPointCore(Sender, parameters, SC_NOINTERRUPT|SC_SETLEVEL|SC_INSTANT);
}
// this differs from ReallyForceSpell that this one allows dead Sender casting
// zero casting time, no depletion
void GameScript::ReallyForceSpellDead(Scriptable* Sender, Action* parameters)
{
- ieResRef spellres;
- int level;
-
- if (!ResolveSpellName( spellres, parameters) ) {
- Sender->ReleaseCurrentAction();
- return;
- } else {
- if (!Sender->SpellResRef[0]) {
- Sender->SetSpellResRef(spellres);
- }
- }
+ // the difference from ReallyForceSpell is handled by the lack of AF_ALIVE being set
+ SpellCore(Sender, parameters, SC_NOINTERRUPT|SC_SETLEVEL|SC_INSTANT);
+}
+void GameScript::Activate(Scriptable* Sender, Action* parameters)
+{
Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] );
if (!tar) {
- Sender->ReleaseCurrentAction();
+ //it could still be an area animation, PST allows deactivating them via Activate
+ AmbientActivateCore(Sender, parameters, 1);
return;
}
- Sender->LastTargetPos=parameters->pointParameter;
-
- Sender->CastSpell (spellres, tar, false, true);
- if (parameters->string0Parameter[0]) {
- level = parameters->int0Parameter;
- } else {
- level = parameters->int1Parameter;
+ if (tar->Type == ST_ACTOR) {
+ tar->Unhide();
+ return;
}
- if (tar->Type==ST_ACTOR) {
- Sender->CastSpellEnd(parameters->int1Parameter);
- } else {
- Sender->CastSpellPointEnd(parameters->int1Parameter);
+
+ //PST allows activating of containers
+ if (tar->Type == ST_CONTAINER) {
+ ((Container *) tar)->Flags&=~CONT_DISABLED;
+ return;
+ }
+
+ //and regions
+ if (tar->Type == ST_PROXIMITY || tar->Type == ST_TRAVEL || tar->Type==ST_TRIGGER) {
+ ((InfoPoint *) tar)->Flags&=~TRAP_DEACTIVATED;
+ return;
}
- Sender->ReleaseCurrentAction();
}
void GameScript::Deactivate(Scriptable* Sender, Action* parameters)
{
Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] );
if (!tar) {
+ //it could still be an area animation, PST allows deactivating them via Deactivate
+ AmbientActivateCore(Sender, parameters, 0);
return;
}
- if (tar->Type != ST_ACTOR) {
+ if (tar->Type == ST_ACTOR) {
+ tar->Hide();
+ return;
+ }
+ //PST allows deactivating of containers
+ //but IWD doesn't, ar9705 chests rely on it (if this is changed, make sure they are all still selectable!)
+ //FIXME: add a new game flag / differentiate more container flags
+ if (tar->Type == ST_CONTAINER && !core->HasFeature(GF_SPECIFIC_DMG_BONUS)) {
+ ((Container *) tar)->Flags|=CONT_DISABLED;
+ return;
+ }
+
+ //and regions
+ if (tar->Type == ST_PROXIMITY || tar->Type == ST_TRAVEL || tar->Type==ST_TRIGGER) {
+ ((InfoPoint *) tar)->Flags|=TRAP_DEACTIVATED;
return;
}
- tar->Hide();
}
void GameScript::MakeGlobal(Scriptable* Sender, Action* /*parameters*/)
@@ -3013,6 +2787,7 @@ void GameScript::UnMakeGlobal(Scriptable* Sender, Action* /*parameters*/)
slot = core->GetGame()->InStore( act );
if (slot >= 0) {
core->GetGame()->DelNPC( slot );
+ act->SetPersistent(-1);
}
}
@@ -3070,7 +2845,10 @@ void GameScript::TakePartyGold(Scriptable* Sender, Action* parameters)
core->GetGame()->AddGold((ieDword) -(int) gold);
if (Sender->Type == ST_ACTOR) {
Actor* act = ( Actor* ) Sender;
- act->SetBase(IE_GOLD, act->GetBase(IE_GOLD)+gold);
+ //fixes PST limlim shop, partymembers don't receive the taken gold
+ if (!act->InParty) {
+ act->SetBase(IE_GOLD, act->GetBase(IE_GOLD)+gold);
+ }
}
}
@@ -3087,11 +2865,14 @@ void GameScript::AddXPObject(Scriptable* Sender, Action* parameters)
int xp = parameters->int0Parameter;
if (displaymsg->HasStringReference(STR_GOTQUESTXP)) {
core->GetTokenDictionary()->SetAtCopy("EXPERIENCEAMOUNT", xp);
- displaymsg->DisplayConstantStringName(STR_GOTQUESTXP, 0xbcefbc, actor);
+ displaymsg->DisplayConstantStringName(STR_GOTQUESTXP, DMC_BG2XPGREEN, actor);
} else {
- displaymsg->DisplayConstantStringValue(STR_GOTXP, 0xbcefbc, (ieDword)xp);
+ displaymsg->DisplayConstantStringValue(STR_GOTXP, DMC_BG2XPGREEN, (ieDword)xp);
}
- actor->AddExperience(xp);
+
+ //normally the second parameter is 0, but it may be handy to have control over that (See SX_* flags)
+ actor->AddExperience(xp, parameters->int1Parameter);
+ core->PlaySound(DS_GOTXP);
}
void GameScript::AddXP2DA(Scriptable* /*Sender*/, Action* parameters)
@@ -3105,10 +2886,10 @@ void GameScript::AddXP2DA(Scriptable* /*Sender*/, Action* parameters)
}
if (parameters->int0Parameter>0) {
- displaymsg->DisplayString(parameters->int0Parameter, 0x40f0f000,IE_STR_SOUND);
+ displaymsg->DisplayString(parameters->int0Parameter, DMC_BG2XPGREEN, IE_STR_SOUND);
}
if (!xptable) {
- printMessage("GameScript","Can't perform ADDXP2DA",LIGHT_RED);
+ Log(ERROR, "GameScript", "Can't perform ADDXP2DA");
return;
}
const char * xpvalue = xptable->QueryField( parameters->string0Parameter, "0" ); //level is unused
@@ -3120,11 +2901,13 @@ void GameScript::AddXP2DA(Scriptable* /*Sender*/, Action* parameters)
//give xp everyone
core->GetGame()->ShareXP(atoi(xpvalue), 0 );
}
+ core->PlaySound(DS_GOTXP);
}
void GameScript::AddExperienceParty(Scriptable* /*Sender*/, Action* parameters)
{
core->GetGame()->ShareXP(parameters->int0Parameter, SX_DIVIDE);
+ core->PlaySound(DS_GOTXP);
}
//this needs moncrate.2da, but otherwise independent from GF_CHALLENGERATING
@@ -3137,6 +2920,7 @@ void GameScript::AddExperiencePartyGlobal(Scriptable* Sender, Action* parameters
{
ieDword xp = CheckVariable( Sender, parameters->string0Parameter, parameters->string1Parameter );
core->GetGame()->ShareXP(xp, SX_DIVIDE);
+ core->PlaySound(DS_GOTXP);
}
void GameScript::SetMoraleAI(Scriptable* Sender, Action* parameters)
@@ -3226,7 +3010,11 @@ void GameScript::JoinParty(Scriptable* Sender, Action* parameters)
ieResRef resref;
//set dialog only if we got a row
if (pdtable->GetRowIndex( scriptname ) != -1) {
- strnlwrcpy(resref, pdtable->QueryField( scriptname, "JOIN_DIALOG_FILE"),8);
+ if (game->Expansion==5) {
+ strnlwrcpy(resref, pdtable->QueryField( scriptname, "25JOIN_DIALOG_FILE"), sizeof(ieResRef)-1);
+ } else {
+ strnlwrcpy(resref, pdtable->QueryField( scriptname, "JOIN_DIALOG_FILE"), sizeof(ieResRef)-1);
+ }
act->SetDialog( resref );
}
}
@@ -3270,17 +3058,6 @@ void GameScript::ForceHide(Scriptable* Sender, Action* parameters)
actor->BaseStats[IE_AVATARREMOVAL]=1;
}
-void GameScript::Activate(Scriptable* Sender, Action* parameters)
-{
- Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] );
- if (!tar || tar->Type != ST_ACTOR) {
- return;
- }
- // Deactivate hides, so this should unhide..
- //tar->Activate();
- tar->Unhide();
-}
-
void GameScript::ForceLeaveAreaLUA(Scriptable* Sender, Action* parameters)
{
Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] );
@@ -3289,8 +3066,12 @@ void GameScript::ForceLeaveAreaLUA(Scriptable* Sender, Action* parameters)
}
Actor* actor = ( Actor* ) tar;
//the LoadMos ResRef may be empty
- strncpy(core->GetGame()->LoadMos, parameters->string1Parameter,8);
- MoveBetweenAreasCore( actor, parameters->string0Parameter, parameters->pointParameter, parameters->int0Parameter, true);
+ if (parameters->string1Parameter[0]) {
+ strnlwrcpy(core->GetGame()->LoadMos, parameters->string1Parameter, sizeof(ieResRef)-1);
+ }
+ if (actor->Persistent() || !CreateMovementEffect(actor, parameters->string0Parameter, parameters->pointParameter) ) {
+ MoveBetweenAreasCore( actor, parameters->string0Parameter, parameters->pointParameter, parameters->int0Parameter, true);
+ }
}
void GameScript::LeaveAreaLUA(Scriptable* Sender, Action* parameters)
@@ -3300,8 +3081,12 @@ void GameScript::LeaveAreaLUA(Scriptable* Sender, Action* parameters)
}
Actor* actor = ( Actor* ) Sender;
//the LoadMos ResRef may be empty
- strncpy(core->GetGame()->LoadMos, parameters->string1Parameter,8);
- MoveBetweenAreasCore( actor, parameters->string0Parameter, parameters->pointParameter, parameters->int0Parameter, true);
+ if (parameters->string1Parameter[0]) {
+ strnlwrcpy(core->GetGame()->LoadMos, parameters->string1Parameter, sizeof(ieResRef)-1);
+ }
+ if (actor->Persistent() || !CreateMovementEffect(actor, parameters->string0Parameter, parameters->pointParameter) ) {
+ MoveBetweenAreasCore( actor, parameters->string0Parameter, parameters->pointParameter, parameters->int0Parameter, true);
+ }
}
//this is a blocking action, because we have to move to the Entry
@@ -3312,7 +3097,9 @@ void GameScript::LeaveAreaLUAEntry(Scriptable* Sender, Action* parameters)
return;
}
Game *game = core->GetGame();
- strncpy(game->LoadMos, parameters->string1Parameter,8);
+ if (parameters->string1Parameter[0]) {
+ strnlwrcpy(game->LoadMos, parameters->string1Parameter, sizeof(ieResRef)-1);
+ }
Point p = GetEntryPoint(parameters->string0Parameter, parameters->string1Parameter);
if (p.isempty()) {
Sender->ReleaseCurrentAction();
@@ -3324,34 +3111,22 @@ void GameScript::LeaveAreaLUAEntry(Scriptable* Sender, Action* parameters)
Sender->ReleaseCurrentAction();
}
+//at this time it is unclear what the LeaveAreaLUAPanic* commands are used for
+//since they are always followed by the non-panic version of the command in all
+//games that use them (bg1 + bg2) we simply make them de-facto no-ops for now
void GameScript::LeaveAreaLUAPanic(Scriptable* Sender, Action* parameters)
{
if (Sender->Type != ST_ACTOR) {
return;
}
- Actor* actor = ( Actor* ) Sender;
- strncpy(core->GetGame()->LoadMos, parameters->string1Parameter,8);
- MoveBetweenAreasCore( actor, parameters->string0Parameter, parameters->pointParameter, parameters->int0Parameter, true);
+ if (parameters->string1Parameter[0]) {
+ strnlwrcpy(core->GetGame()->LoadMos, parameters->string1Parameter, sizeof(ieResRef)-1);
+ }
}
-//this is a blocking action, because we have to move to the Entry
void GameScript::LeaveAreaLUAPanicEntry(Scriptable* Sender, Action* parameters)
{
- if (Sender->Type != ST_ACTOR) {
- Sender->ReleaseCurrentAction();
- return;
- }
- Game *game = core->GetGame();
- strncpy(game->LoadMos, parameters->string1Parameter,8);
- Point p = GetEntryPoint(parameters->string0Parameter, parameters->string1Parameter);
- if (p.isempty()) {
- Sender->ReleaseCurrentAction();
- return;
- }
- parameters->pointParameter=p;
- strcpy(parameters->string1Parameter, "");
LeaveAreaLUAPanic(Sender, parameters);
- Sender->ReleaseCurrentAction();
}
void GameScript::SetToken(Scriptable* /*Sender*/, Action* parameters)
@@ -3387,18 +3162,19 @@ void GameScript::PlayDead(Scriptable* Sender, Action* parameters)
return;
}
Actor* actor = ( Actor* ) Sender;
+
actor->CurrentActionInterruptable = false;
- if (Sender->CurrentActionState == 0) {
- // TODO: what if parameter is 0? see orphan2
+ if (!Sender->CurrentActionTicks && parameters->int0Parameter) {
+ // set countdown on first run
Sender->CurrentActionState = parameters->int0Parameter;
actor->SetStance( IE_ANI_DIE );
- } else {
- actor->CurrentActionState--;
- if (Sender->CurrentActionState == 0) {
- actor->SetStance( IE_ANI_GET_UP );
- Sender->ReleaseCurrentAction();
- }
}
+ if (Sender->CurrentActionState <= 0) {
+ actor->SetStance( IE_ANI_GET_UP );
+ Sender->ReleaseCurrentAction();
+ return;
+ }
+ actor->CurrentActionState--;
}
void GameScript::PlayDeadInterruptable(Scriptable* Sender, Action* parameters)
@@ -3408,17 +3184,18 @@ void GameScript::PlayDeadInterruptable(Scriptable* Sender, Action* parameters)
return;
}
Actor* actor = ( Actor* ) Sender;
- if (Sender->CurrentActionState == 0) {
- // TODO: what if parameter is 0? see orphan2
+
+ if (!Sender->CurrentActionTicks && parameters->int0Parameter) {
+ // set countdown on first run
Sender->CurrentActionState = parameters->int0Parameter;
actor->SetStance( IE_ANI_DIE );
- } else {
- actor->CurrentActionState--;
- if (Sender->CurrentActionState == 0) {
- actor->SetStance( IE_ANI_GET_UP );
- Sender->ReleaseCurrentAction();
- }
}
+ if (Sender->CurrentActionState <= 0) {
+ actor->SetStance( IE_ANI_GET_UP );
+ Sender->ReleaseCurrentAction();
+ return;
+ }
+ actor->CurrentActionState--;
}
/* this may not be correct, just a placeholder you can fix */
@@ -3697,7 +3474,6 @@ void GameScript::ClearAllActions(Scriptable* Sender, Action* /*parameters*/)
except = (Actor *) Sender;
}
Map *map = Sender->GetCurrentArea();
- ieDword gametime = core->GetGame()->GameTime;
int i = map->GetActorCount(true);
while(i--) {
Actor* act = map->GetActor(i,true);
@@ -3705,10 +3481,6 @@ void GameScript::ClearAllActions(Scriptable* Sender, Action* /*parameters*/)
if (!act->ValidTarget(GA_NO_DEAD) ) {
continue;
}
- //Do we need this???
- if (!act->Schedule(gametime, false) ) {
- continue;
- }
act->ClearActions();
act->ClearPath();
act->SetModal(MS_NONE);
@@ -3722,8 +3494,8 @@ void GameScript::ClearActions(Scriptable* Sender, Action* parameters)
if (parameters->objects[1]) {
tar = GetActorFromObject( Sender, parameters->objects[1] );
if (!tar) {
- printMessage("GameScript","Couldn't find target for ClearActions!",YELLOW);
- parameters->objects[1]->Dump();
+ Log(WARNING, "GameScript", "Couldn't find target for ClearActions!");
+ parameters->objects[1]->dump();
return;
}
}
@@ -3758,23 +3530,30 @@ void GameScript::SetLeavePartyDialogFile(Scriptable* Sender, Action* /*parameter
}
AutoTable pdtable("pdialog");
Actor* act = ( Actor* ) Sender;
- const char* scriptingname = act->GetScriptName();
- act->SetDialog( pdtable->QueryField( scriptingname, "POST_DIALOG_FILE" ) );
+ const char* scriptname = act->GetScriptName();
+ if (pdtable->GetRowIndex( scriptname ) != -1) {
+ ieResRef resref;
+
+ if (core->GetGame()->Expansion==5) {
+ strnlwrcpy(resref, pdtable->QueryField( scriptname, "25POST_DIALOG_FILE" ), sizeof(ieResRef)-1 );
+ } else {
+ strnlwrcpy(resref, pdtable->QueryField( scriptname, "POST_DIALOG_FILE" ), sizeof(ieResRef)-1 );
+ }
+ act->SetDialog(resref);
+ }
}
-void GameScript::TextScreen(Scriptable* Sender, Action* parameters)
+void GameScript::TextScreen(Scriptable* /*Sender*/, Action* parameters)
{
- strnlwrcpy(core->GetGame()->LoadMos, parameters->string0Parameter,8);
- core->GetGUIScriptEngine()->RunFunction( "TextScreen", "StartTextScreen" );
- core->GetVideoDriver()->SetMouseEnabled(true);
- Sender->SetWait(1);
- Sender->ReleaseCurrentAction(); // should this be blocking?
+ core->SetPause(PAUSE_ON, 1);
+ strnlwrcpy(core->GetGame()->TextScreen, parameters->string0Parameter, sizeof(ieResRef)-1);
+ core->SetEventFlag(EF_TEXTSCREEN);
}
void GameScript::IncrementChapter(Scriptable* Sender, Action* parameters)
{
- TextScreen(Sender, parameters); // textscreen will release blocking for us
core->GetGame()->IncrementChapter();
+ TextScreen(Sender, parameters);
}
void GameScript::SetCriticalPathObject(Scriptable* Sender, Action* parameters)
@@ -3808,7 +3587,11 @@ void GameScript::SetCreatureAreaFlag(Scriptable* Sender, Action* parameters)
return;
}
Actor* actor = ( Actor* ) Sender;
- actor->SetMCFlag(parameters->int0Parameter, parameters->int1Parameter);
+ if (parameters->int1Parameter) {
+ actor->SetMCFlag(parameters->int0Parameter, BM_OR);
+ } else {
+ actor->SetMCFlag(parameters->int0Parameter, BM_NAND);
+ }
}
//this will be a global change, fixme if it should be local
@@ -3845,7 +3628,7 @@ void GameScript::SetVisualRange(Scriptable* Sender, Action* parameters)
void GameScript::MakeUnselectable(Scriptable* Sender, Action* parameters)
{
- Sender->UnselectableTimer=parameters->int0Parameter;
+ Sender->UnselectableTimer=parameters->int0Parameter * AI_UPDATE_TIME;
//update color
if (Sender->Type != ST_ACTOR) {
@@ -3863,7 +3646,7 @@ void GameScript::MakeUnselectable(Scriptable* Sender, Action* parameters)
void GameScript::Debug(Scriptable* /*Sender*/, Action* parameters)
{
InDebug=parameters->int0Parameter;
- printMessage("GameScript",parameters->string0Parameter,YELLOW);
+ Log(WARNING, "GameScript", "DEBUG: %s", parameters->string0Parameter);
}
void GameScript::IncrementProficiency(Scriptable* Sender, Action* parameters)
@@ -4107,7 +3890,7 @@ void GameScript::SetGabber(Scriptable* Sender, Action* parameters)
if (gc->GetDialogueFlags()&DF_IN_DIALOG) {
gc->dialoghandler->speakerID = tar->GetGlobalID();
} else {
- printMessage("GameScript","Can't set gabber!",YELLOW);
+ Log(WARNING, "GameScript", "Can't set gabber!");
}
}
@@ -4144,7 +3927,7 @@ void GameScript::RemovePaladinHood(Scriptable* Sender, Action* /*parameters*/)
Actor *act = (Actor *) Sender;
act->ApplyKit(true);
act->SetMCFlag(MC_FALLEN_PALADIN, BM_OR);
- if (act->InParty) displaymsg->DisplayConstantStringName(STR_PALADIN_FALL, 0xbcefbc, act);
+ if (act->InParty) displaymsg->DisplayConstantStringName(STR_PALADIN_FALL, DMC_BG2XPGREEN, act);
}
void GameScript::RemoveRangerHood(Scriptable* Sender, Action* /*parameters*/)
@@ -4155,7 +3938,7 @@ void GameScript::RemoveRangerHood(Scriptable* Sender, Action* /*parameters*/)
Actor *act = (Actor *) Sender;
act->ApplyKit(true);
act->SetMCFlag(MC_FALLEN_RANGER, BM_OR);
- if (act->InParty) displaymsg->DisplayConstantStringName(STR_RANGER_FALL, 0xbcefbc, act);
+ if (act->InParty) displaymsg->DisplayConstantStringName(STR_RANGER_FALL, DMC_BG2XPGREEN, act);
}
void GameScript::RegainPaladinHood(Scriptable* Sender, Action* /*parameters*/)
@@ -4205,12 +3988,16 @@ void GameScript::TakePartyItemNum(Scriptable* Sender, Action* parameters)
Game *game=core->GetGame();
int i=game->GetPartySize(false);
while (i--) {
- int res=MoveItemCore(game->GetPC(i,false), Sender, parameters->string0Parameter,IE_INV_ITEM_UNDROPPABLE, IE_INV_ITEM_UNSTEALABLE);
+ Actor *pc = game->GetPC(i, false);
+ int personal_count = pc->inventory.CountItems(parameters->string0Parameter, true);
+ if (!personal_count) continue;
+ int res=MoveItemCore(pc, Sender, parameters->string0Parameter,IE_INV_ITEM_UNDROPPABLE, IE_INV_ITEM_UNSTEALABLE, count);
if (res == MIC_GOTITEM) {
i++;
- count--;
+ // decrease only by the removed amount, since multiple slots may have been involved
+ count -= (personal_count - pc->inventory.CountItems(parameters->string0Parameter, true));
}
- if (!count) return;
+ if (count < 1) return;
}
}
@@ -4269,7 +4056,10 @@ void GameScript::CreateItem(Scriptable *Sender, Action* parameters)
}
CREItem *item = new CREItem();
- CreateItemCore(item, parameters->string0Parameter, parameters->int0Parameter, parameters->int1Parameter, parameters->int2Parameter);
+ if (!CreateItemCore(item, parameters->string0Parameter, parameters->int0Parameter, parameters->int1Parameter, parameters->int2Parameter)) {
+ delete item;
+ return;
+ }
if (tar->Type==ST_CONTAINER) {
myinv->AddItem(item);
} else {
@@ -4277,9 +4067,9 @@ void GameScript::CreateItem(Scriptable *Sender, Action* parameters)
Map *map=tar->GetCurrentArea();
// drop it at my feet
map->AddItemToLocation(tar->Pos, item);
- if (((Actor *)tar)->InParty) displaymsg->DisplayConstantString(STR_INVFULL_ITEMDROP, 0xbcefbc);
+ if (((Actor *)tar)->InParty) displaymsg->DisplayConstantString(STR_INVFULL_ITEMDROP, DMC_BG2XPGREEN);
} else {
- if (((Actor *)tar)->InParty) displaymsg->DisplayConstantString(STR_GOTITEM, 0xbcefbc);
+ if (((Actor *)tar)->InParty) displaymsg->DisplayConstantString(STR_GOTITEM, DMC_BG2XPGREEN);
}
}
}
@@ -4300,7 +4090,10 @@ void GameScript::CreateItemNumGlobal(Scriptable *Sender, Action* parameters)
}
int value = CheckVariable( Sender, parameters->string0Parameter );
CREItem *item = new CREItem();
- CreateItemCore(item, parameters->string1Parameter, value, 0, 0);
+ if (!CreateItemCore(item, parameters->string1Parameter, value, 0, 0)) {
+ delete item;
+ return;
+ }
if (Sender->Type==ST_CONTAINER) {
myinv->AddItem(item);
} else {
@@ -4308,9 +4101,9 @@ void GameScript::CreateItemNumGlobal(Scriptable *Sender, Action* parameters)
Map *map=Sender->GetCurrentArea();
// drop it at my feet
map->AddItemToLocation(Sender->Pos, item);
- if (((Actor *)Sender)->InParty) displaymsg->DisplayConstantString(STR_INVFULL_ITEMDROP, 0xbcefbc);
+ if (((Actor *)Sender)->InParty) displaymsg->DisplayConstantString(STR_INVFULL_ITEMDROP, DMC_BG2XPGREEN);
} else {
- if (((Actor *)Sender)->InParty) displaymsg->DisplayConstantString(STR_GOTITEM, 0xbcefbc);
+ if (((Actor *)Sender)->InParty) displaymsg->DisplayConstantString(STR_GOTITEM, DMC_BG2XPGREEN);
}
}
}
@@ -4328,7 +4121,10 @@ void GameScript::TakeItemReplace(Scriptable *Sender, Action* parameters)
if (!item) {
item = new CREItem();
}
- CreateItemCore(item, parameters->string0Parameter, -1, 0, 0);
+ if (!CreateItemCore(item, parameters->string0Parameter, -1, 0, 0)) {
+ delete item;
+ return;
+ }
if (ASI_SUCCESS != scr->inventory.AddSlotItem(item,slot)) {
Map *map = scr->GetCurrentArea();
map->AddItemToLocation(Sender->Pos, item);
@@ -4336,6 +4132,7 @@ void GameScript::TakeItemReplace(Scriptable *Sender, Action* parameters)
}
//same as equipitem, but with additional slots parameter, and object to perform action
+// XEquipItem("00Troll1",Myself,SLOT_RING_LEFT,TRUE)
void GameScript::XEquipItem(Scriptable *Sender, Action* parameters)
{
Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] );
@@ -4344,11 +4141,36 @@ void GameScript::XEquipItem(Scriptable *Sender, Action* parameters)
return;
}
Actor *actor = (Actor *) tar;
- int slot = actor->inventory.FindItem(parameters->string0Parameter, 0);
+ int slot = actor->inventory.FindItem(parameters->string0Parameter, IE_INV_ITEM_UNDROPPABLE);
if (slot<0) {
return;
}
- actor->inventory.EquipItem(slot);
+
+ int slot2 = parameters->int0Parameter;
+ bool equip = parameters->int1Parameter;
+
+ if (equip) {
+ if (slot != slot2) {
+ // swap them first, so we equip to the desired slot
+ CREItem *si = actor->inventory.RemoveItem(slot);
+ actor->inventory.AddSlotItem(si, slot2);
+ }
+ actor->inventory.EquipItem(slot2);
+ } else {
+ CREItem *si = actor->inventory.RemoveItem(slot);
+ if (si) {
+ if (actor->inventory.AddSlotItem(si, SLOT_ONLYINVENTORY) == ASI_FAILED) {
+ Map *map = Sender->GetCurrentArea();
+ if (map) {
+ //drop item at the feet of the character instead of destroying it
+ map->AddItemToLocation(Sender->Pos, si);
+ } else {
+ delete si;
+ }
+ }
+ }
+ }
+
actor->ReinitQuickSlots();
}
@@ -4580,30 +4402,41 @@ void GameScript::PickPockets(Scriptable *Sender, Action* parameters)
}
if (scr->GetStat(IE_EA)>EA_EVILCUTOFF) {
- displaymsg->DisplayConstantString(STR_PICKPOCKET_EVIL,0xffffff);
+ displaymsg->DisplayConstantString(STR_PICKPOCKET_EVIL, DMC_WHITE);
Sender->ReleaseCurrentAction();
return;
}
int skill = snd->GetStat(IE_PICKPOCKET);
int tgt = scr->GetStat(IE_PICKPOCKET);
- //the original engine has no random here
- if (tgt != 255) {
- skill -= tgt;
- //if you want original behaviour: remove this
- skill += core->Roll(1,100, snd->GetStat(IE_LUCK) );
+ int check;
+ if (core->HasFeature(GF_3ED_RULES)) {
+ int roll = core->Roll(1, 20, 0);
+ int level = scr->GetXPLevel(true);
+ int wismod = scr->GetAbilityBonus(IE_WIS);
+ // ~Pick pocket check. (10 + skill w/Dex bonus) %d vs. ((d20 + target's level) + Wisdom modifier) %d + %d.~
+ displaymsg->DisplayRollStringName(39302, DMC_LIGHTGREY, snd, 10+skill, roll+level, wismod);
+ check = (10 + skill) > (roll + level + wismod);
} else {
- skill = 0;
+ //the original engine has no random here
+ if (tgt != 255) {
+ skill -= tgt;
+ //if you want original behaviour: remove this
+ skill += core->Roll(1,100, snd->GetStat(IE_LUCK) );
+ } else {
+ skill = 0;
+ }
+ //and change this 50 to 0.
+ check = skill < 50;
}
- //and change this 50 to 0.
- if (skill<50) {
+ if (check) {
//noticed attempt
- displaymsg->DisplayConstantString(STR_PICKPOCKET_FAIL,0xffffff);
+ displaymsg->DisplayConstantString(STR_PICKPOCKET_FAIL, DMC_WHITE);
if (core->HasFeature(GF_STEAL_IS_ATTACK) ) {
- tar->LastAttacker = snd->GetGlobalID();
+ scr->AttackedBy(snd);
} else {
//pickpocket failed trigger
- tar->LastOpenFailed = snd->GetGlobalID();
+ tar->AddTrigger(TriggerEntry(trigger_pickpocketfailed, snd->GetGlobalID()));
}
Sender->ReleaseCurrentAction();
return;
@@ -4626,29 +4459,31 @@ void GameScript::PickPockets(Scriptable *Sender, Action* parameters)
int money=0;
//go for money too
if (scr->GetStat(IE_GOLD)>0) {
- money=RandomNumValue%(scr->GetStat(IE_GOLD)+1);
+ money = (RandomNumValue % scr->GetStat(IE_GOLD)) + 1;
}
if (!money) {
//no stuff to steal
- displaymsg->DisplayConstantString(STR_PICKPOCKET_NONE,0xffffff);
+ displaymsg->DisplayConstantString(STR_PICKPOCKET_NONE, DMC_WHITE);
Sender->ReleaseCurrentAction();
return;
}
CREItem *item = new CREItem();
- CreateItemCore(item, core->GoldResRef, money, 0, 0);
- if ( ASI_SUCCESS == snd->inventory.AddSlotItem(item, SLOT_ONLYINVENTORY)) {
- scr->SetBase(IE_GOLD,scr->GetBase(IE_GOLD)-money);
- } else {
+ if (!CreateItemCore(item, core->GoldResRef, money, 0, 0)) {
+ error("GameScript", "Failed to create pick-pocketed gold '%s' %dg.\n", core->GoldResRef, money);
+ }
+ scr->SetBase(IE_GOLD, scr->GetBase(IE_GOLD) - money);
+ if (ASI_SUCCESS != snd->inventory.AddSlotItem(item, SLOT_ONLYINVENTORY)) {
// drop it at my feet
- map->AddItemToLocation(Sender->Pos, item);
- if (((Actor *)Sender)->InParty) displaymsg->DisplayConstantString(STR_INVFULL_ITEMDROP, 0xbcefbc);
- Sender->ReleaseCurrentAction();
- return;
+ map->AddItemToLocation(snd->Pos, item);
+ ret = MIC_FULL;
}
}
- displaymsg->DisplayConstantString(STR_PICKPOCKET_DONE,0xffffff);
+ displaymsg->DisplayConstantString(STR_PICKPOCKET_DONE, DMC_WHITE);
DisplayStringCore(snd, VB_PP_SUCC, DS_CONSOLE|DS_CONST );
+ if (ret == MIC_FULL && snd->InParty) {
+ displaymsg->DisplayConstantString(STR_INVFULL_ITEMDROP, DMC_BG2XPGREEN);
+ }
Sender->ReleaseCurrentAction();
}
@@ -4763,6 +4598,16 @@ void GameScript::QuitGame(Scriptable* Sender, Action* parameters)
core->SetNextScript("QuitGame");
}
+//BG2 demo end, shows some pictures then goes to main screen
+void GameScript::DemoEnd(Scriptable* Sender, Action* parameters)
+{
+ ClearAllActions(Sender, parameters);
+ core->GetDictionary()->SetAt("QuitGame1", (ieDword)0);
+ core->GetDictionary()->SetAt("QuitGame2", (ieDword)0);
+ core->GetDictionary()->SetAt("QuitGame3", (ieDword)-1);
+ core->SetNextScript("QuitGame");
+}
+
void GameScript::StopMoving(Scriptable* Sender, Action* /*parameters*/)
{
if (Sender->Type!=ST_ACTOR) {
@@ -4803,7 +4648,10 @@ void GameScript::ApplyDamagePercent(Scriptable* Sender, Action* parameters)
} else {
damager=damagee;
}
- damagee->Damage(damagee->GetBase(IE_HITPOINTS)*parameters->int0Parameter/100, parameters->int1Parameter, damager);
+ //this, if the percent is calculated from the current hp
+ damagee->Damage((parameters->int0Parameter*damagee->Modified[IE_HITPOINTS])/100, parameters->int1Parameter, damager);
+ //this, if the percent is calculated from the max hp
+ //damagee->Damage(parameters->int0Parameter, parameters->int1Parameter, damager, MOD_PERCENT);
}
void GameScript::Damage(Scriptable* Sender, Action* parameters)
@@ -4820,7 +4668,7 @@ void GameScript::Damage(Scriptable* Sender, Action* parameters)
} else {
damager=damagee;
}
- int damage = damagee->LuckyRoll( (parameters->int1Parameter>>12)&15, (parameters->int1Parameter>>4)&255, parameters->int1Parameter&15, LR_DAMAGELUCK, damager);
+ int damage = damager->LuckyRoll( (parameters->int1Parameter>>12)&15, (parameters->int1Parameter>>4)&255, parameters->int1Parameter&15, LR_DAMAGELUCK, damagee);
int type=MOD_ADDITIVE;
switch(parameters->int0Parameter) {
case 2: //raise
@@ -4833,20 +4681,20 @@ void GameScript::Damage(Scriptable* Sender, Action* parameters)
type=MOD_PERCENT;
break;
}
- damagee->Damage( damage, type, damager );
+ //damagetype seems to be always 0
+ damagee->Damage( damage, 0, damager, type);
}
-/*
+
void GameScript::SetHomeLocation(Scriptable* Sender, Action* parameters)
{
Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] );
if (!tar || tar->Type!=ST_ACTOR) {
return;
}
- Movable *movable = (Movable *) tar; //not actor, though it is the only moveable
- movable->Destination = parameters->pointParameter;
+ Actor *movable = (Actor *) tar;
+ movable->HomeLocation = parameters->pointParameter;
//no movement should be started here, i think
}
-*/
void GameScript::SetMasterArea(Scriptable* /*Sender*/, Action* parameters)
{
@@ -4858,9 +4706,35 @@ void GameScript::Berserk(Scriptable* Sender, Action* /*parameters*/)
if (Sender->Type!=ST_ACTOR) {
return;
}
+
+ Map *map = Sender->GetCurrentArea();
+ if (!map) {
+ return;
+ }
+
Actor *act = (Actor *) Sender;
- act->SetBaseBit(IE_STATE_ID, STATE_BERSERK, true);
- act->Panic(NULL, PANIC_BERSERK);
+ Actor *target;
+
+ if (!act->GetStat(IE_BERSERKSTAGE2) && (core->Roll(1,100,0)<50) ) {
+ //anyone
+ target = GetNearestEnemyOf(map, act, ORIGIN_SEES_ENEMY);
+ } else {
+ target = GetNearestOf(map, act, ORIGIN_SEES_ENEMY);
+ }
+
+ if (!target) {
+ Sender->SetWait(6);
+ } else {
+ char Tmp[40];
+
+ //generate attack action
+ sprintf( Tmp, "NIDSpecial3()");
+ Action *newaction = GenerateActionDirect(Tmp, target);
+ if (newaction) {
+ Sender->AddActionInFront(newaction);
+ }
+ }
+ Sender->ReleaseCurrentAction();
}
void GameScript::Panic(Scriptable* Sender, Action* /*parameters*/)
@@ -4886,20 +4760,18 @@ void GameScript::RevealAreaOnMap(Scriptable* /*Sender*/, Action* parameters)
{
WorldMap *worldmap = core->GetWorldMap();
if (!worldmap) {
- printf("Can't find worldmap!\n");
- abort();
+ error("GameScript", "Can't find worldmap!\n");
}
// WMP_ENTRY_ADJACENT because otherwise revealed bg2 areas are unreachable from city gates
worldmap->SetAreaStatus(parameters->string0Parameter, WMP_ENTRY_VISIBLE|WMP_ENTRY_ADJACENT, BM_OR);
- displaymsg->DisplayConstantString(STR_WORLDMAPCHANGE, 0xc8ffc8);
+ displaymsg->DisplayConstantString(STR_WORLDMAPCHANGE, DMC_BG2XPGREEN);
}
void GameScript::HideAreaOnMap( Scriptable* /*Sender*/, Action* parameters)
{
WorldMap *worldmap = core->GetWorldMap();
if (!worldmap) {
- printf("Can't find worldmap!\n");
- abort();
+ error("GameScript", "Can't find worldmap!\n");
}
// WMP_ENTRY_ADJACENT because otherwise revealed bg2 areas are unreachable from city gates
worldmap->SetAreaStatus(parameters->string0Parameter, WMP_ENTRY_VISIBLE|WMP_ENTRY_ADJACENT, BM_NAND);
@@ -4911,7 +4783,7 @@ void GameScript::SendTrigger(Scriptable* Sender, Action* parameters)
if (!tar) {
return;
}
- tar->TriggerID=parameters->int0Parameter;
+ tar->AddTrigger(TriggerEntry(trigger_trigger, parameters->int0Parameter));
}
void GameScript::Shout( Scriptable* Sender, Action* parameters)
@@ -4957,8 +4829,7 @@ void GameScript::GiveOrder(Scriptable* Sender, Action* parameters)
{
Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] );
if (tar) {
- tar->LastOrderer = Sender->GetGlobalID();
- tar->LastOrder = parameters->int0Parameter;
+ tar->AddTrigger(TriggerEntry(trigger_receivedorder, Sender->GetGlobalID(), parameters->int0Parameter));
}
}
@@ -4983,12 +4854,7 @@ void GameScript::AttackOneRound( Scriptable* Sender, Action* parameters)
}
//using auto target!
Scriptable* tar;
- /*if (!parameters->objects[1]) {
- GameControl *gc = core->GetGameControl();
- tar = gc->GetTarget();
- } else {*/
- tar = GetStoredActorFromObject( Sender, parameters->objects[1], GA_NO_DEAD );
- /*}*/
+ tar = GetStoredActorFromObject( Sender, parameters->objects[1], GA_NO_DEAD );
if (!tar || (tar->Type != ST_ACTOR && tar->Type !=ST_DOOR && tar->Type !=ST_CONTAINER) ) {
Sender->ReleaseCurrentAction();
return;
@@ -5006,9 +4872,7 @@ void GameScript::AttackOneRound( Scriptable* Sender, Action* parameters)
AttackCore(Sender, tar, 0);
- if (Sender->CurrentActionState == 1) {
- //this is the LastDisarmFailed field, but this is an actor
- //Sender->LastTarget = 0;
+ if (Sender->CurrentActionState <= 1) {
Sender->ReleaseCurrentAction();
} else {
Sender->CurrentActionState--;
@@ -5023,12 +4887,7 @@ void GameScript::RunningAttackNoSound( Scriptable* Sender, Action* parameters)
}
//using auto target!
Scriptable* tar;
- /*if (!parameters->objects[1]) {
- GameControl *gc = core->GetGameControl();
- tar = gc->GetTarget();
- } else {*/
- tar = GetStoredActorFromObject( Sender, parameters->objects[1], GA_NO_DEAD );
- /*}*/
+ tar = GetStoredActorFromObject( Sender, parameters->objects[1], GA_NO_DEAD );
if (!tar || (tar->Type != ST_ACTOR && tar->Type !=ST_DOOR && tar->Type !=ST_CONTAINER) ) {
Sender->ReleaseCurrentAction();
return;
@@ -5051,12 +4910,7 @@ void GameScript::AttackNoSound( Scriptable* Sender, Action* parameters)
}
//using auto target!
Scriptable* tar;
- /*if (!parameters->objects[1]) {
- GameControl *gc = core->GetGameControl();
- tar = gc->GetTarget();
- } else {*/
- tar = GetStoredActorFromObject( Sender, parameters->objects[1], GA_NO_DEAD );
- /*}*/
+ tar = GetStoredActorFromObject( Sender, parameters->objects[1], GA_NO_DEAD );
if (!tar || (tar->Type != ST_ACTOR && tar->Type !=ST_DOOR && tar->Type !=ST_CONTAINER) ) {
Sender->ReleaseCurrentAction();
return;
@@ -5079,12 +4933,7 @@ void GameScript::RunningAttack( Scriptable* Sender, Action* parameters)
}
//using auto target!
Scriptable* tar;
- /*if (!parameters->objects[1]) {
- GameControl *gc = core->GetGameControl();
- tar = gc->GetTarget();
- } else {*/
- tar = GetStoredActorFromObject( Sender, parameters->objects[1], GA_NO_DEAD );
- /*}*/
+ tar = GetStoredActorFromObject( Sender, parameters->objects[1], GA_NO_DEAD );
if (!tar || (tar->Type != ST_ACTOR && tar->Type !=ST_DOOR && tar->Type !=ST_CONTAINER) ) {
Sender->ReleaseCurrentAction();
return;
@@ -5139,7 +4988,7 @@ void GameScript::ForceAttack( Scriptable* Sender, Action* parameters)
if (gc) {
//saving the target object ID from the gui variable
char Tmp[40];
- strncpy(Tmp,"NIDSpecial3()",sizeof(Tmp) );
+ strlcpy(Tmp, "NIDSpecial3()", sizeof(Tmp));
scr->AddAction( GenerateActionDirect(Tmp, (Actor *) tar) );
}
} else {
@@ -5176,7 +5025,11 @@ void GameScript::AttackReevaluate( Scriptable* Sender, Action* parameters)
AttackCore(Sender, tar, 0);
- Sender->CurrentActionState--;
+ if (Sender->CurrentActionState) {
+ Sender->CurrentActionState--;
+ } else {
+ Sender->ReleaseCurrentAction();
+ }
}
void GameScript::Explore( Scriptable* Sender, Action* /*parameters*/)
@@ -5270,7 +5123,7 @@ void GameScript::SetScriptName( Scriptable* Sender, Action* parameters)
//This is in seconds according to IESDP
void GameScript::AdvanceTime(Scriptable* /*Sender*/, Action* parameters)
{
- core->GetGame()->AdvanceTime(parameters->int0Parameter*1000/AI_UPDATE_TIME);
+ core->GetGame()->AdvanceTime(parameters->int0Parameter*AI_UPDATE_TIME);
}
//advance at least one day, then stop at next day/dusk/night/morning
@@ -5294,12 +5147,14 @@ void GameScript::DayNight(Scriptable* /*Sender*/, Action* parameters)
void GameScript::RestParty(Scriptable* Sender, Action* parameters)
{
Game *game = core->GetGame();
- game->RestParty(REST_NOAREA|REST_NOMOVE|REST_NOCRITTER, parameters->int0Parameter, parameters->int1Parameter);
+ game->RestParty(REST_NOAREA|REST_NOMOVE|REST_NOCRITTER|REST_NOSCATTER, parameters->int0Parameter, parameters->int1Parameter);
Sender->ReleaseCurrentAction();
}
-//doesn't advance game time, just refreshes spells of target
+//doesn't advance game time, just removes fatigue & refreshes spells of target
//this is a non-blocking action
+static EffectRef fx_fatigue_ref = { "FatigueModifier", -1 };
+
void GameScript::Rest(Scriptable* Sender, Action* /*parameters*/)
{
if (Sender->Type!=ST_ACTOR) {
@@ -5307,33 +5162,26 @@ void GameScript::Rest(Scriptable* Sender, Action* /*parameters*/)
}
Actor *actor = (Actor *) Sender;
actor->spellbook.ChargeAllSpells();
- //check if this should be a full heal
- actor->Heal(0);
- actor->fxqueue.RemoveExpiredEffects(0xffffffff);
+ actor->fxqueue.RemoveAllEffects(fx_fatigue_ref);
+ actor->SetBase(IE_FATIGUE,0);
}
-//doesn't advance game time (unsure), just refreshes spells of target
+//doesn't advance game time, just removes fatigue
void GameScript::RestNoSpells(Scriptable* Sender, Action* /*parameters*/)
{
if (Sender->Type!=ST_ACTOR) {
return;
}
Actor *actor = (Actor *) Sender;
- //check if this should be a full heal
- actor->Heal(0);
- actor->fxqueue.RemoveExpiredEffects(0xffffffff);
+ actor->fxqueue.RemoveAllEffects(fx_fatigue_ref);
+ actor->SetBase(IE_FATIGUE,0);
}
-//this is most likely advances time
+//this most likely advances time and heals whole party
void GameScript::RestUntilHealed(Scriptable* Sender, Action* /*parameters*/)
{
- if (Sender->Type!=ST_ACTOR) {
- return;
- }
- Actor *actor = (Actor *) Sender;
- actor->Heal(1);
- //not sure if this should remove timed effects
- //more like execute them hour by hour :>
+ core->GetGame()->RestParty(REST_NOSCATTER|REST_NOAREA, 0, 0);
+ Sender->ReleaseCurrentAction();
}
//iwd2
@@ -5387,6 +5235,10 @@ void GameScript::MarkSpellAndObject(Scriptable* Sender, Action* parameters)
}
Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1]);
+ if (!tar) {
+ // target died on us
+ return;
+ }
Actor *actor = NULL;
if (tar->Type == ST_ACTOR) {
actor = (Actor *) tar;
@@ -5544,15 +5396,12 @@ void GameScript::RandomFly(Scriptable* Sender, Action* /*parameters*/)
} else if (x>20) {
actor->SetOrientation(actor->GetOrientation()+1, false);
}
- //fly in this direction for 5 steps
- actor->MoveLine(5, GL_PASS, actor->GetOrientation() );
- //readding the action to the end of the queue
- //Sender->AddAction( parameters );
- //Sender->ReleaseCurrentAction();
+ //fly in this direction for 20 steps
+ actor->MoveLine(20, GL_PASS, actor->GetOrientation() );
}
//UseContainer uses the predefined target (like Nidspecial1 dialog hack)
-void GameScript::UseContainer(Scriptable* Sender, Action* /*parameters*/)
+void GameScript::UseContainer(Scriptable* Sender, Action* parameters)
{
if (Sender->Type != ST_ACTOR) {
Sender->ReleaseCurrentAction();
@@ -5568,14 +5417,30 @@ void GameScript::UseContainer(Scriptable* Sender, Action* /*parameters*/)
Actor *actor = (Actor *)Sender;
Container *container = core->GetCurrentContainer();
if (!container) {
- printMessage("GameScript","No container selected!", YELLOW);
+ Log(WARNING, "GameScript", "No container selected!");
+ Sender->ReleaseCurrentAction();
+ return;
+ }
+ if (parameters->int2Parameter > 20) {
+ Log(WARNING, "GameScript", "Could not get close enough to container!");
Sender->ReleaseCurrentAction();
return;
}
ieDword distance = PersonalDistance(Sender, container);
ieDword needed = MAX_OPERATING_DISTANCE;
- if (container->Type==IE_CONTAINER_PILE) {
+ // give up the strictness after 10 retries from the same spot
+ if (!parameters->int2Parameter) {
+ parameters->int1Parameter = distance;
+ parameters->int2Parameter = 1;
+ } else {
+ if (parameters->int1Parameter == (signed)distance) {
+ parameters->int2Parameter++;
+ } else {
+ parameters->int1Parameter = distance;
+ }
+ }
+ if (container->Type==IE_CONTAINER_PILE && parameters->int2Parameter < 10) {
needed = 0; // less than a search square (width)
}
if (distance<=needed)
@@ -5584,18 +5449,22 @@ void GameScript::UseContainer(Scriptable* Sender, Action* /*parameters*/)
if (!container->TryUnlock(actor)) {
//playsound can't open container
//display string, etc
- displaymsg->DisplayConstantString(STR_CONTLOCKED,0xd7d7be,container);
+ displaymsg->DisplayConstantString(STR_CONTLOCKED, DMC_LIGHTGREY, container);
Sender->ReleaseCurrentAction();
return;
}
- Actor *actor = (Actor *)Sender;
actor->SetModal(MS_NONE);
+ if (container->Trapped) {
+ container->AddTrigger(TriggerEntry(trigger_opened, actor->GetGlobalID()));
+ } else {
+ container->AddTrigger(TriggerEntry(trigger_harmlessopened, actor->GetGlobalID()));
+ }
container->TriggerTrap(0, actor->GetGlobalID());
core->SetCurrentContainer(actor, container, true);
Sender->ReleaseCurrentAction();
return;
}
- MoveNearerTo(Sender, container, needed);
+ MoveNearerTo(Sender, container, needed, 1);
}
//call the usecontainer action in target (not used)
@@ -5648,7 +5517,7 @@ void GameScript::FixEngineRoom(Scriptable* Sender, Action* /*parameters*/)
void GameScript::StartRainNow(Scriptable* /*Sender*/, Action* /*parameters*/)
{
- core->GetGame()->StartRainOrSnow( false, WB_RAIN|WB_LIGHTNING);
+ core->GetGame()->StartRainOrSnow( false, WB_RAIN|WB_RARELIGHTNING);
}
void GameScript::Weather(Scriptable* /*Sender*/, Action* parameters)
@@ -5659,7 +5528,7 @@ void GameScript::Weather(Scriptable* /*Sender*/, Action* parameters)
game->StartRainOrSnow( false, 0);
break;
case WB_RAIN:
- game->StartRainOrSnow( true, WB_RAIN|WB_LIGHTNING);
+ game->StartRainOrSnow( true, WB_RAIN|WB_RARELIGHTNING);
break;
case WB_SNOW:
game->StartRainOrSnow( true, WB_SNOW);
@@ -5723,6 +5592,20 @@ void GameScript::Hide(Scriptable* Sender, Action* /*parameters*/)
}
+static EffectRef fx_set_invisible_state_ref = { "State:Invisible", -1 };
+void GameScript::Unhide(Scriptable* Sender, Action* /*parameters*/)
+{
+ if (Sender->Type != ST_ACTOR) {
+ return;
+ }
+ Actor *actor = (Actor *) Sender;
+
+ if (actor->ModalState == MS_STEALTH) {
+ actor->SetModal(MS_NONE);
+ }
+ actor->fxqueue.RemoveAllEffects(fx_set_invisible_state_ref);
+}
+
void GameScript::Turn(Scriptable* Sender, Action* /*parameters*/)
{
if (Sender->Type!=ST_ACTOR) {
@@ -5839,7 +5722,7 @@ void GameScript::ExportParty(Scriptable* /*Sender*/, Action* parameters)
snprintf(FileName,_MAX_PATH,"%s%d",parameters->string0Parameter,i+1);
core->WriteCharacter(FileName, actor);
}
- displaymsg->DisplayConstantString(STR_EXPORTED, 0xbcefbc);
+ displaymsg->DisplayConstantString(STR_EXPORTED, DMC_BG2XPGREEN);
}
void GameScript::SaveGame(Scriptable* /*Sender*/, Action* parameters)
@@ -5865,7 +5748,7 @@ void GameScript::SaveGame(Scriptable* /*Sender*/, Action* parameters)
void GameScript::EscapeArea(Scriptable* Sender, Action* parameters)
{
if (InDebug&ID_ACTIONS) {
- printf("EscapeArea/EscapeAreaMove\n");
+ Log(MESSAGE, "Actions", "EscapeArea/EscapeAreaMove");
}
if (Sender->Type!=ST_ACTOR) {
Sender->ReleaseCurrentAction();
@@ -5893,7 +5776,7 @@ void GameScript::EscapeArea(Scriptable* Sender, Action* parameters)
void GameScript::EscapeAreaNoSee(Scriptable* Sender, Action* parameters)
{
if (InDebug&ID_ACTIONS) {
- printf("EscapeAreaNoSee\n");
+ Log(MESSAGE, "Actions", "EscapeAreaNoSee");
}
if (Sender->Type!=ST_ACTOR) {
Sender->ReleaseCurrentAction();
@@ -6050,10 +5933,10 @@ void GameScript::ChangeStoreMarkup(Scriptable* /*Sender*/, Action* parameters)
if (!store) {
store = core->SetCurrentStore(parameters->string0Parameter, 0);
} else {
- if (strnicmp(store->Name, parameters->string0Parameter, 8) ) {
+ if (strnicmp(store->Name, parameters->string0Parameter, sizeof(ieResRef)-1) ) {
//not the current store, we need some dirty hack
has_current = true;
- strnlwrcpy(current, store->Name, 8);
+ strnlwrcpy(current, store->Name, sizeof(ieResRef)-1);
owner = store->GetOwnerID();
}
}
@@ -6196,7 +6079,7 @@ void GameScript::BreakInstants(Scriptable* Sender, Action* /*parameters*/)
{
//don't do anything, apparently the point of this action is to
//delay the execution of further actions to the next AI cycle
- Sender->SetWait(1);
+ //Sender->SetWait(1);
Sender->ReleaseCurrentAction(); // this doesn't really need to block
}
@@ -6206,7 +6089,7 @@ void GameScript::PauseGame(Scriptable* Sender, Action* /*parameters*/)
GameControl *gc = core->GetGameControl();
if (gc) {
gc->SetDialogueFlags(DF_FREEZE_SCRIPTS, BM_OR);
- displaymsg->DisplayConstantString(STR_SCRIPTPAUSED,0xff0000);
+ displaymsg->DisplayConstantString(STR_SCRIPTPAUSED, DMC_RED);
}
// releasing this action allows actions to continue executing,
// so we force a wait
@@ -6224,12 +6107,11 @@ void GameScript::SetNoOneOnTrigger(Scriptable* Sender, Action* parameters)
ip = Sender->GetCurrentArea()->TMap->GetInfoPoint(parameters->objects[1]->objectName);
}
if (!ip || (ip->Type!=ST_TRIGGER && ip->Type!=ST_TRAVEL && ip->Type!=ST_PROXIMITY)) {
- printf("Script error: No Trigger Named \"%s\"\n", parameters->objects[1]->objectName);
+ Log(WARNING, "Actions", "Script error: No Trigger Named \"%s\"", parameters->objects[1]->objectName);
return;
}
- ip->LastEntered = 0;
- ip->LastTrigger = 0;
- ip->LastTriggerObject = 0;
+
+ ip->InitTriggers();
}
void GameScript::UseDoor(Scriptable* Sender, Action* parameters)
@@ -6246,7 +6128,8 @@ void GameScript::UseDoor(Scriptable* Sender, Action* parameters)
Sender->ReleaseCurrentAction(); // this is blocking, OpenDoor is not
}
-//this will force bashing the door
+//this will force bashing the door, if bend bars check is successful,
+//it will unlock the door and sets the broken flag
void GameScript::BashDoor(Scriptable* Sender, Action* parameters)
{
GameControl *gc = core->GetGameControl();
@@ -6259,37 +6142,41 @@ void GameScript::BashDoor(Scriptable* Sender, Action* parameters)
return;
}
+ Actor * actor = (Actor *) Sender;
+
Scriptable *target = GetActorFromObject(Sender, parameters->objects[1]);
- TileMap *tmap = Sender->GetCurrentArea()->TMap;
Door *door = NULL;
Container *container = NULL;
- Point pos;
+ Point *pos;
if (target->Type == ST_DOOR) {
- // FIXME: actually it chooses from two possible points
- pos = target->Pos;
- door = tmap->GetDoorByPosition(pos);
+ door = (Door *) target;
+ pos = door->toOpen;
+ Point *otherp = door->toOpen+1;
+ if (Distance(*pos, Sender)>Distance(*otherp, Sender)) {
+ pos=otherp;
+ }
} else if(target->Type == ST_CONTAINER) {
- pos = target->Pos;
- container = tmap->GetContainerByPosition(pos);
+ container = (Container *) target;
+ pos = &target->Pos;
} else {
Sender->ReleaseCurrentAction();
return;
}
- // TODO: "sets a field in the door/container to 1"
-
- if (SquaredPersonalDistance(pos, Sender) > MAX_OPERATING_DISTANCE*MAX_OPERATING_DISTANCE) {
- MoveNearerTo(Sender, pos, MAX_OPERATING_DISTANCE, 0);
+ if (SquaredPersonalDistance(*pos, Sender) > MAX_OPERATING_DISTANCE*MAX_OPERATING_DISTANCE) {
+ MoveNearerTo(Sender, *pos, MAX_OPERATING_DISTANCE, 0);
return;
}
+ //bashing makes the actor visible
+ actor->CureInvisibility();
gc->SetTargetMode(TARGET_MODE_ATTACK); //for bashing doors too
// try to bash it
if (door) {
- door->TryBashLock((Actor *) Sender);
+ door->TryBashLock(actor);
} else if (container) {
- container->TryBashLock((Actor *) Sender);
+ container->TryBashLock(actor);
}
Sender->ReleaseCurrentAction();
@@ -6348,7 +6235,8 @@ void GameScript::ChangeDestination(Scriptable* Sender, Action* parameters)
{
InfoPoint *ip = Sender->GetCurrentArea()->TMap->GetInfoPoint(parameters->objects[1]->objectName);
if (ip && (ip->Type==ST_TRAVEL) ) {
- strnlwrcpy(ip->Destination, parameters->string0Parameter, 32);
+ //alter the destination area, don't touch the entrance variable link
+ strnlwrcpy(ip->Destination, parameters->string0Parameter, sizeof(ieResRef)-1 );
}
}
@@ -6485,7 +6373,7 @@ void GameScript::UseItem(Scriptable* Sender, Action* parameters)
ieResRef itemres;
if (parameters->string0Parameter[0]) {
- Slot = act->inventory.FindItem(parameters->string0Parameter, 0);
+ Slot = act->inventory.FindItem(parameters->string0Parameter, IE_INV_ITEM_UNDROPPABLE);
//this IS in the original game code (ability)
header = parameters->int0Parameter;
flags = parameters->int1Parameter;
@@ -6508,7 +6396,7 @@ void GameScript::UseItem(Scriptable* Sender, Action* parameters)
unsigned int dist = GetItemDistance(itemres, header);
- if (PersonalDistance(tar->Pos, Sender) > dist) {
+ if (PersonalDistance(Sender, tar) > dist) {
MoveNearerTo(Sender, tar, dist);
return;
}
@@ -6564,7 +6452,7 @@ void GameScript::UseItemPoint(Scriptable* Sender, Action* parameters)
}
//addfeat will be able to remove feats too
-//(the second int parameter is a bitmode)
+//(the second int parameter is a value to add to the feat)
void GameScript::AddFeat(Scriptable* Sender, Action* parameters)
{
Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] );
@@ -6572,7 +6460,13 @@ void GameScript::AddFeat(Scriptable* Sender, Action* parameters)
return;
}
Actor *actor = (Actor *)tar;
- actor->SetFeat(parameters->int0Parameter, parameters->int1Parameter);
+ //value to add to the feat
+ int value = parameters->int1Parameter;
+ //default is increase by 1
+ if (!value) value = 1;
+ value += actor->GetFeat(parameters->int0Parameter);
+ //SetFeatValue will handle edges
+ actor->SetFeatValue(parameters->int0Parameter, value);
}
void GameScript::MatchHP(Scriptable* Sender, Action* parameters)
@@ -6794,7 +6688,8 @@ void GameScript::ProtectObject(Scriptable* Sender, Action* parameters)
Actor *scr = (Actor *)Sender;
Actor *actor = (Actor *)tar;
scr->LastFollowed = actor->GetGlobalID();
- scr->LastProtected = actor->GetGlobalID();
+ scr->LastProtectee = actor->GetGlobalID();
+ actor->LastProtector = scr->GetGlobalID();
//not exactly range
scr->FollowOffset.x = parameters->int0Parameter;
scr->FollowOffset.y = parameters->int0Parameter;
@@ -6990,13 +6885,41 @@ void GameScript::IncrementKillStat(Scriptable* Sender, Action* parameters)
SetVariable( Sender, variable, "GLOBAL", value );
}
+//this action uses the sceffect.ids (which should be covered by our cgtable.2da)
+//The original engines solved cg by hardcoding either vvcs or sparkles
+//so either we include sparkles as possible CG or just simulate all of these with projectiles
+//in any case, this action just creates an opcode (0xeb) and plays sound
+static EffectRef fx_iwd_casting_glow_ref = { "CastingGlow2", -1 };
+
void GameScript::SpellCastEffect(Scriptable* Sender, Action* parameters)
{
Scriptable* src = GetActorFromObject( Sender, parameters->objects[1] );
- if (!src) {
+ if (!src || src->Type!=ST_ACTOR) {
+ return;
+ }
+
+ ieDword sparkle = parameters->int0Parameter;
+
+ int opcode = EffectQueue::ResolveEffect(fx_iwd_casting_glow_ref);
+ Effect *fx = core->GetEffect(opcode);
+ if (!fx) {
+ //invalid effect name didn't resolve to opcode
return;
}
- //TODO: finish this
+
+ core->GetAudioDrv()->Play( parameters->string0Parameter, Sender->Pos.x,
+ Sender->Pos.y, 0 );
+
+ fx->ProbabilityRangeMax = 100;
+ fx->ProbabilityRangeMin = 0;
+ fx->Parameter2 = sparkle; //animation type
+ fx->TimingMode = FX_DURATION_INSTANT_LIMITED;
+ fx->Duration = parameters->int1Parameter * 15;
+ fx->Target = FX_TARGET_PRESET;
+ //int2param isn't actually used in the original engine
+
+ core->ApplyEffect(fx, (Actor *) src, src);
+ delete fx;
}
//this action plays a vvc animation over target
@@ -7025,9 +6948,14 @@ void GameScript::SpellHitEffectSprite(Scriptable* Sender, Action* parameters)
fx->Parameter2 = parameters->int0Parameter;
//height (not sure if this is in the opcode, but seems acceptable)
fx->Parameter1 = parameters->int1Parameter;
- fx->Probability1=100;
+ fx->ProbabilityRangeMax = 100;
+ fx->ProbabilityRangeMin = 0;
fx->TimingMode=FX_DURATION_INSTANT_PERMANENT_AFTER_BONUSES;
+ fx->PosX=tar->Pos.x;
+ fx->PosY=tar->Pos.y;
+ fx->Target = FX_TARGET_PRESET;
core->ApplyEffect(fx, (Actor *) tar, src);
+ delete fx;
}
void GameScript::SpellHitEffectPoint(Scriptable* Sender, Action* parameters)
@@ -7048,11 +6976,14 @@ void GameScript::SpellHitEffectPoint(Scriptable* Sender, Action* parameters)
fx->Parameter2 = parameters->int0Parameter;
//height (not sure if this is in the opcode, but seems acceptable)
fx->Parameter1 = parameters->int1Parameter;
- fx->Probability1=100;
+ fx->ProbabilityRangeMax = 100;
+ fx->ProbabilityRangeMin = 0;
fx->TimingMode=FX_DURATION_INSTANT_PERMANENT_AFTER_BONUSES;
fx->PosX=parameters->pointParameter.x;
fx->PosY=parameters->pointParameter.y;
+ fx->Target = FX_TARGET_PRESET;
core->ApplyEffect(fx, NULL, src);
+ delete fx;
}
@@ -7147,8 +7078,7 @@ void GameScript::SetToken2DA(Scriptable* /*Sender*/, Action* parameters)
AutoTable tm(parameters->string0Parameter);
if (!tm) {
- printStatus( "ERROR", LIGHT_RED );
- printf( "Cannot find %s.2da.\n", parameters->string0Parameter);
+ Log(ERROR, "Actions", "Cannot find %s.2da.", parameters->string0Parameter);
return;
}
@@ -7200,3 +7130,19 @@ void GameScript::SetNamelessDeath(Scriptable* Sender, Action* parameters)
}
sp->SetNamelessDeath(area, parameters->pointParameter, parameters->int1Parameter);
}
+
+// like GameScript::Kill, but forces chunking damage (disabling resurrection)
+void GameScript::ChunkCreature(Scriptable *Sender, Action* parameters)
+{
+ Scriptable* tar = GetActorFromObject(Sender, parameters->objects[1]);
+ if (!tar || tar->Type != ST_ACTOR) {
+ return;
+ }
+
+ Actor *target = (Actor *) tar;
+ Effect *fx = EffectQueue::CreateEffect(fx_death_ref, 0, 8, FX_DURATION_INSTANT_PERMANENT);
+ target->fxqueue.AddEffect(fx, false);
+ delete fx;
+}
+
+}
diff --git a/gemrb/core/GameScript/GSUtils.cpp b/gemrb/core/GameScript/GSUtils.cpp
index 9fe3c6c..9309311 100644
--- a/gemrb/core/GameScript/GSUtils.cpp
+++ b/gemrb/core/GameScript/GSUtils.cpp
@@ -23,29 +23,39 @@
#include "strrefs.h"
#include "defsounds.h"
+#include "ie_feats.h"
+#include "AmbientMgr.h"
#include "Audio.h"
+#include "CharAnimations.h"
#include "DialogHandler.h"
#include "DisplayMessage.h"
#include "Game.h"
#include "GameData.h"
+#include "GlobalTimer.h"
#include "Interface.h"
#include "Item.h"
#include "Map.h"
#include "Spell.h"
#include "StringMgr.h"
+#include "TableMgr.h"
#include "TileMap.h"
#include "Video.h"
+#include "WorldMap.h"
#include "GUI/GameControl.h"
#include "Scriptable/Container.h"
#include "Scriptable/Door.h"
#include "Scriptable/InfoPoint.h"
+#include "System/StringBuffer.h"
#include <cstdio>
+namespace GemRB {
+
//these tables will get freed by Core
Holder<SymbolMgr> triggersTable;
Holder<SymbolMgr> actionsTable;
+Holder<SymbolMgr> overrideTriggersTable;
Holder<SymbolMgr> overrideActionsTable;
Holder<SymbolMgr> objectsTable;
TriggerFunction triggers[MAX_TRIGGERS];
@@ -68,11 +78,13 @@ ieResRef *ObjectIDSTableNames;
int ObjectFieldsCount = 7;
int ExtraParametersCount = 0;
int InDebug = 0;
-int happiness[3][20];
int RandomNumValue;
// reaction modifiers (by reputation and charisma)
-int rmodrep[20];
-int rmodchr[25];
+#define MAX_REP_COLUMN 20
+#define MAX_CHR_COLUMN 25
+int rmodrep[MAX_REP_COLUMN];
+int rmodchr[MAX_CHR_COLUMN];
+int happiness[3][MAX_REP_COLUMN];
Gem_Polygon **polygons;
void InitScriptTables()
@@ -82,7 +94,7 @@ void InitScriptTables()
AutoTable tab("happy");
if (tab) {
for (int alignment=0;alignment<3;alignment++) {
- for (int reputation=0;reputation<20;reputation++) {
+ for (int reputation=0;reputation<MAX_REP_COLUMN;reputation++) {
happiness[alignment][reputation]=strtol(tab->QueryField(reputation,alignment), NULL, 0);
}
}
@@ -92,7 +104,7 @@ void InitScriptTables()
//initializing the reaction mod. reputation table
AutoTable rmr("rmodrep");
if (rmr) {
- for (int reputation=0; reputation<20; reputation++) {
+ for (int reputation=0; reputation<MAX_REP_COLUMN; reputation++) {
rmodrep[reputation] = strtol(rmr->QueryField(0, reputation), NULL, 0);
}
}
@@ -100,7 +112,7 @@ void InitScriptTables()
//initializing the reaction mod. charisma table
AutoTable rmc("rmodchr");
if (rmc) {
- for (int charisma=0; charisma<25; charisma++) {
+ for (int charisma=0; charisma<MAX_CHR_COLUMN; charisma++) {
rmodchr[charisma] = strtol(rmc->QueryField(0, charisma), NULL, 0);
}
}
@@ -109,17 +121,24 @@ void InitScriptTables()
int GetReaction(Actor *target, Scriptable *Sender)
{
int chr, rep, reaction;
+
chr = target->GetStat(IE_CHR)-1;
if (target->GetStat(IE_EA) == EA_PC) {
- rep = core->GetGame()->Reputation/10;
+ rep = core->GetGame()->Reputation/10-1;
} else {
- rep = target->GetStat(IE_REPUTATION);
+ //FIXME: shouldn't this be divided by 10?
+ rep = target->GetStat(IE_REPUTATION)-1;
}
+ if (rep<0) rep = 0;
+ else if (rep>=MAX_REP_COLUMN) rep=MAX_REP_COLUMN-1;
+ if (chr<0) chr = 0;
+ else if (chr>=MAX_CHR_COLUMN) chr=MAX_CHR_COLUMN-1;
+
reaction = 10 + rmodrep[rep] + rmodchr[chr];
// add -4 penalty when dealing with racial enemies
- if (Sender && target->GetRangerLevel() && Sender->Type == ST_ACTOR && target->IsRacialEnemy((Actor *)Sender)) {
- reaction -= 4;
+ if (Sender && target->GetRangerLevel() && (Sender->Type == ST_ACTOR) ) {
+ reaction -= target->GetRacialEnemyBonus((Actor *) Sender);
}
return reaction;
@@ -239,26 +258,11 @@ bool ResolveItemName(ieResRef itemres, Actor *act, ieDword Slot)
bool StoreHasItemCore(const ieResRef storename, const ieResRef itemname)
{
- bool had_nostore=false;
- bool has_current=false;
- ieResRef current;
- ieDword owner = 0;
CREItem item;
- Store *store = core->GetCurrentStore();
- if (!store) {
- had_nostore = true;
- store = core->SetCurrentStore(storename, 0);
- } else {
- if (strnicmp(store->Name, storename, 8) ) {
- //not the current store, we need some dirty hack
- has_current = true;
- strnlwrcpy(current, store->Name, 8);
- owner = store->GetOwnerID();
- }
- }
+ Store* store = gamedata->GetStore(storename);
if (!store) {
- printMessage("GameScript","Store cannot be opened!\n", LIGHT_RED);
+ Log(ERROR, "GameScript", "Store cannot be opened!");
return false;
}
@@ -267,15 +271,30 @@ bool StoreHasItemCore(const ieResRef storename, const ieResRef itemname)
if (store->FindItem(itemname, false) != (unsigned int)-1) {
ret=true;
}
- if (has_current) {
- //setting back old store (this will save our current store)
- core->SetCurrentStore(current, owner);
- } else if (had_nostore) {
- core->CloseCurrentStore();
- }
+ // Don't call gamedata->SaveStore, we don't change it, and it remains cached.
return ret;
}
+bool StoreGetItemCore(CREItem &item, const ieResRef storename, const ieResRef itemname)
+{
+ Store* store = gamedata->GetStore(storename);
+ if (!store) {
+ Log(ERROR, "GameScript", "Store cannot be opened!");
+ return false;
+ }
+
+ //RemoveItem doesn't use trigger, and hopefully this will always run on bags (with no triggers)
+ unsigned int idx = store->FindItem(itemname, false);
+ if (idx == (unsigned int) -1) return false;
+
+ STOItem *si = store->GetItem(idx, false);
+ memcpy( &item, si, sizeof( CREItem ) );
+ store->RemoveItem(idx);
+ //store changed, save it
+ gamedata->SaveStore(store);
+ return true;
+}
+
//don't pass this point by reference, it is subject to change
void ClickCore(Scriptable *Sender, Point point, int type, int speed)
{
@@ -310,6 +329,35 @@ void ClickCore(Scriptable *Sender, Point point, int type, int speed)
Sender->ReleaseCurrentAction();
}
+void PlaySequenceCore(Scriptable *Sender, Action *parameters, ieDword value)
+{
+ Scriptable* tar;
+
+ if (parameters->objects[1]) {
+ tar = GetActorFromObject( Sender, parameters->objects[1] );
+ if (!tar) {
+ //could be an animation
+ AreaAnimation* anim = Sender->GetCurrentArea( )->GetAnimation( parameters->objects[1]->objectName);
+ if (anim) {
+ //set animation's cycle to parameters->int0Parameter;
+ anim->sequence=value;
+ anim->frame=0;
+ //what else to be done???
+ anim->InitAnimation();
+ }
+ return;
+ }
+
+ } else {
+ tar = Sender;
+ }
+ if (tar->Type != ST_ACTOR) {
+ return;
+ }
+ Actor* actor = ( Actor* ) tar;
+ actor->SetStance( value );
+}
+
void TransformItemCore(Actor *actor, Action *parameters, bool onlyone)
{
int i = actor->inventory.GetSlotCount();
@@ -356,7 +404,31 @@ bool HasItemCore(Inventory *inventory, const ieResRef itemname, ieDword flags)
return false;
}
-void DisplayStringCore(Scriptable* Sender, int Strref, int flags)
+//finds and takes an item from a container in the given inventory
+bool GetItemContainer(CREItem &itemslot2, Inventory *inventory, const ieResRef itemname)
+{
+ int i=inventory->GetSlotCount();
+ while (i--) {
+ //maybe we could speed this up if we mark bag items with a flags bit
+ CREItem *itemslot = inventory->GetSlotItem(i);
+ if (!itemslot)
+ continue;
+ Item *item = gamedata->GetItem(itemslot->ItemResRef);
+ if (!item)
+ continue;
+ bool ret = core->CanUseItemType(SLOT_BAG,item,NULL);
+ gamedata->FreeItem(item, itemslot->ItemResRef);
+ if (!ret)
+ continue;
+ //the store is the same as the item's name
+ if (StoreGetItemCore(itemslot2, itemslot->ItemResRef, itemname)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void DisplayStringCore(Scriptable* const Sender, int Strref, int flags)
{
StringBlock sb;
char Sound[_MAX_PATH];
@@ -368,15 +440,15 @@ void DisplayStringCore(Scriptable* Sender, int Strref, int flags)
memset(&sb,0,sizeof(sb));
Sound[0]=0;
- printf( "Displaying string on: %s\n", Sender->GetScriptName() );
+ Log(MESSAGE, "GameScript", "Displaying string on: %s", Sender->GetScriptName() );
if (flags & DS_CONST) {
if (Sender->Type!=ST_ACTOR) {
- printMessage("GameScript","Verbal constant not supported for non actors!\n", LIGHT_RED);
+ Log(ERROR, "GameScript", "Verbal constant not supported for non actors!");
return;
}
Actor* actor = ( Actor* ) Sender;
if ((ieDword) Strref>=VCONST_COUNT) {
- printMessage("GameScript","Invalid verbal constant!\n", LIGHT_RED);
+ Log(ERROR, "GameScript", "Invalid verbal constant!");
return;
}
@@ -410,7 +482,7 @@ void DisplayStringCore(Scriptable* Sender, int Strref, int flags)
if(flags&DS_NONAME) {
displaymsg->DisplayString( sb.text );
} else {
- displaymsg->DisplayStringName( Strref, 0xf0f0f0, Sender, 0);
+ displaymsg->DisplayStringName( Strref, DMC_WHITE, Sender, 0);
}
}
if (sb.text[0] && strcmp(sb.text," ") && (flags & (DS_HEAD | DS_AREA))) {
@@ -441,7 +513,7 @@ int CanSee(Scriptable* Sender, Scriptable* target, bool range, int seeflag)
if (target->Type==ST_ACTOR) {
Actor *tar = (Actor *) target;
- if (!tar->ValidTarget(seeflag)) {
+ if (!tar->ValidTarget(seeflag, Sender)) {
return 0;
}
}
@@ -468,7 +540,7 @@ int CanSee(Scriptable* Sender, Scriptable* target, bool range, int seeflag)
}
}
- return map->IsVisible(target->Pos, Sender->Pos);
+ return map->IsVisibleLOS(target->Pos, Sender->Pos);
}
//non actors can see too (reducing function to LOS)
@@ -476,24 +548,36 @@ int CanSee(Scriptable* Sender, Scriptable* target, bool range, int seeflag)
int SeeCore(Scriptable* Sender, Trigger* parameters, int justlos)
{
//see dead
- int flags;
+ int flags = 0;
if (parameters->int0Parameter) {
- flags = GA_DETECT;
+ flags |= GA_DETECT;
} else {
- flags = GA_NO_DEAD;
+ flags |= GA_NO_DEAD;
}
Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter, flags );
/* don't set LastSeen if this isn't an actor */
if (!tar) {
return 0;
}
+
+ //Deactivated (hidden) creatures are not seen
+ //Check windspear quest (when garren leaves you alone with the kid)
+ if (! (tar->GetInternalFlag()&IF_VISIBLE)) {
+ return 0;
+ }
+
+ // ignore invisible targets for direct matching
+ if (! parameters->int0Parameter) {
+ flags |= GA_NO_HIDDEN;
+ }
+
//both are actors
if (CanSee(Sender, tar, true, flags) ) {
if (justlos) {
return 1;
}
- if (Sender->Type==ST_ACTOR && tar->Type==ST_ACTOR) {
+ if (Sender->Type==ST_ACTOR && tar->Type==ST_ACTOR && Sender!=tar) {
Actor* snd = ( Actor* ) Sender;
//additional checks for invisibility?
snd->LastSeen = tar->GetGlobalID();
@@ -506,7 +590,7 @@ int SeeCore(Scriptable* Sender, Trigger* parameters, int justlos)
//transfering item from Sender to target
//if target has no inventory, the item will be destructed
//if target can't get it, it will be dropped at its feet
-int MoveItemCore(Scriptable *Sender, Scriptable *target, const char *resref, int flags, int setflag)
+int MoveItemCore(Scriptable *Sender, Scriptable *target, const char *resref, int flags, int setflag, int count)
{
Inventory *myinv;
Map *map;
@@ -530,7 +614,18 @@ int MoveItemCore(Scriptable *Sender, Scriptable *target, const char *resref, int
return MIC_INVALID;
}
CREItem *item;
- myinv->RemoveItem(resref, flags, &item);
+ myinv->RemoveItem(resref, flags, &item, count);
+
+ //there was no item in the inventory itself, try with containers in the inventory
+ if (!item) {
+ item = new CREItem();
+
+ if (!GetItemContainer(*item, myinv, resref)) {
+ delete item;
+ item = NULL;
+ }
+ }
+
if (!item) {
// nothing was removed
return MIC_NOITEM;
@@ -550,18 +645,19 @@ int MoveItemCore(Scriptable *Sender, Scriptable *target, const char *resref, int
myinv = NULL;
break;
}
+ if (lostitem&&!gotitem) displaymsg->DisplayConstantString(STR_LOSTITEM, DMC_BG2XPGREEN);
+
if (!myinv) {
delete item;
- if (lostitem) displaymsg->DisplayConstantString(STR_LOSTITEM, 0xbcefbc);
return MIC_GOTITEM; // actually it was lost, not gained
}
if ( myinv->AddSlotItem(item, SLOT_ONLYINVENTORY) !=ASI_SUCCESS) {
// drop it at my feet
map->AddItemToLocation(target->Pos, item);
- if (gotitem) displaymsg->DisplayConstantString(STR_INVFULL_ITEMDROP, 0xbcefbc);
+ if (gotitem) displaymsg->DisplayConstantString(STR_INVFULL_ITEMDROP, DMC_BG2XPGREEN);
return MIC_FULL;
}
- if (gotitem) displaymsg->DisplayConstantString(STR_GOTITEM, 0xbcefbc);
+ if (gotitem&&!lostitem) displaymsg->DisplayConstantString(STR_GOTITEM, DMC_BG2XPGREEN);
return MIC_GOTITEM;
}
@@ -599,8 +695,8 @@ void CreateCreatureCore(Scriptable* Sender, Action* parameters, int flags)
}
if (!ab) {
- printMessage("GameScript","Failed to create creature! ",LIGHT_RED);
- printf("(missing creature file %s?)\n", parameters->string0Parameter);
+ Log(ERROR, "GameScript", "Failed to create creature! (missing creature file %s?)",
+ parameters->string0Parameter);
// maybe this should abort()?
return;
}
@@ -621,7 +717,11 @@ void CreateCreatureCore(Scriptable* Sender, Action* parameters, int flags)
case CC_OFFSCREEN:
{
Region vp = core->GetVideoDriver()->GetViewport();
- radius=vp.w/2; //actually it must be further divided by the tile size, hmm 16?
+ radius=vp.w/2;
+ //center of screen
+ pnt.x = vp.x+radius;
+ pnt.y = vp.y+vp.h/2;
+ break;
}
//falling through
case CC_OBJECT://use object + offset
@@ -642,8 +742,9 @@ void CreateCreatureCore(Scriptable* Sender, Action* parameters, int flags)
}
Map *map = Sender->GetCurrentArea();
- map->AddActor( ab );
- ab->SetPosition( pnt, flags&CC_CHECK_IMPASSABLE, radius );
+ map->AddActor( ab, true );
+ //radius adjusted to tile size
+ ab->SetPosition( pnt, flags&CC_CHECK_IMPASSABLE, radius/16, radius/12 );
ab->SetOrientation(parameters->int0Parameter, false );
//if string1 is animation, then we can't use it for a DV too
@@ -666,7 +767,7 @@ static ScriptedAnimation *GetVVCEffect(const char *effect, int iterations)
if (effect[0]) {
ScriptedAnimation* vvc = gamedata->GetScriptedAnimation(effect, false);
if (!vvc) {
- printMessage("GameScript","Failed to create effect.",LIGHT_RED);
+ Log(ERROR, "GameScript", "Failed to create effect.");
return NULL;
}
if (iterations) {
@@ -703,7 +804,7 @@ void ChangeAnimationCore(Actor *src, const char *resref, bool effect)
Actor *tar = gamedata->GetCreature(resref);
if (tar) {
Map *map = src->GetCurrentArea();
- map->AddActor( tar );
+ map->AddActor( tar, true );
Point pos = src->Pos;
tar->SetOrientation(src->GetOrientation(), false );
// make sure to copy the HP, to avoid things like magically-healing trolls
@@ -721,12 +822,14 @@ void EscapeAreaCore(Scriptable* Sender, const Point &p, const char* area, const
{
char Tmp[256];
- if ( !p.isempty() && PersonalDistance(p, Sender)>MAX_OPERATING_DISTANCE) {
- //MoveNearerTo will return 0, if the actor is in move
- //it will return 1 (the fourth parameter) if the target is unreachable
- if (!MoveNearerTo(Sender, p, MAX_OPERATING_DISTANCE,1) ) {
- if (!Sender->InMove()) printf("At least it said so...\n");
- return;
+ if (Sender->CurrentActionTicks<100) {
+ if ( !p.isempty() && PersonalDistance(p, Sender)>MAX_OPERATING_DISTANCE) {
+ //MoveNearerTo will return 0, if the actor is in move
+ //it will return 1 (the fourth parameter) if the target is unreachable
+ if (!MoveNearerTo(Sender, p, MAX_OPERATING_DISTANCE,1) ) {
+ if(!Sender->InMove()) print("At least it said so...");
+ return;
+ }
}
}
@@ -737,13 +840,12 @@ void EscapeAreaCore(Scriptable* Sender, const Point &p, const char* area, const
// last parameter is 'face', which should be passed from relevant action parameter..
sprintf( Tmp, "MoveBetweenAreas(\"%s\",[%hd.%hd],%d)", area, enter.x, enter.y, 0 );
}
- printMessage("GSUtils"," ", WHITE);
- printf("Executing %s in EscapeAreaCore\n", Tmp);
+ Log(MESSAGE, "GSUtils", "Executing %s in EscapeAreaCore", Tmp);
//drop this action, but add another (destroyself or movebetweenareas)
//between the arrival and the final escape, there should be a wait time
//that wait time could be handled here
if (wait) {
- printf("But wait a bit... (%d)\n", wait);
+ print("But wait a bit...(%d)", wait);
Sender->SetWait(wait);
}
Sender->ReleaseCurrentAction();
@@ -762,7 +864,7 @@ void GetTalkPositionFromScriptable(Scriptable* scr, Point &position)
position = ((Movable *) scr)->GetMostLikelyPosition();
break;
case ST_TRIGGER: case ST_PROXIMITY: case ST_TRAVEL:
- if (((InfoPoint *) scr)->Flags & TRAP_USEPOINT) {
+ if (((InfoPoint *) scr)->GetUsePoint() ) {
position=((InfoPoint *) scr)->UsePoint;
break;
}
@@ -789,7 +891,7 @@ void GetPositionFromScriptable(Scriptable* scr, Point &position, bool dest)
position = ((Movable *) scr)->GetMostLikelyPosition();
break;
case ST_TRIGGER: case ST_PROXIMITY: case ST_TRAVEL:
- if (((InfoPoint *) scr)->Flags & TRAP_USEPOINT) {
+ if (((InfoPoint *) scr)->GetUsePoint()) {
position=((InfoPoint *) scr)->UsePoint;
break;
}
@@ -798,25 +900,6 @@ void GetPositionFromScriptable(Scriptable* scr, Point &position, bool dest)
}
}
-int CheckInteract(const char *talker, const char *target)
-{
- AutoTable interact("interact");
- if(!interact)
- return 0;
- const char *value = interact->QueryField(talker, target);
- if(!value)
- return 0;
- switch(value[0]) {
- case 's':
- return I_SPECIAL;
- case 'c':
- return I_COMPLIMENT;
- case 'i':
- return I_INSULT;
- }
- return 0;
-}
-
static ieResRef PlayerDialogRes = "PLAYERx\0";
void BeginDialog(Scriptable* Sender, Action* parameters, int Flags)
@@ -825,7 +908,7 @@ void BeginDialog(Scriptable* Sender, Action* parameters, int Flags)
int seeflag = GA_NO_DEAD;
if (InDebug&ID_VARIABLES) {
- printf("BeginDialog core\n");
+ Log(MESSAGE, "GSUtils", "BeginDialog core");
}
if (Flags & BD_OWN) {
tar = GetStoredActorFromObject( Sender, parameters->objects[1], seeflag);
@@ -835,24 +918,26 @@ void BeginDialog(Scriptable* Sender, Action* parameters, int Flags)
scr = Sender;
}
if (!scr) {
- printMessage("GameScript"," ",LIGHT_RED);
- printf("Speaker for dialog couldn't be found (Sender: %s, Type: %d) Flags:%d.\n", Sender->GetScriptName(), Sender->Type, Flags);
+ Log(ERROR, "GameScript", "Speaker for dialog couldn't be found (Sender: %s, Type: %d) Flags:%d.",
+ Sender->GetScriptName(), Sender->Type, Flags);
Sender->ReleaseCurrentAction();
return;
}
if (!tar || tar->Type!=ST_ACTOR) {
- printMessage("GameScript"," ",LIGHT_RED);
- printf("Target for dialog couldn't be found (Sender: %s, Type: %d).\n", Sender->GetScriptName(), Sender->Type);
+ Log(ERROR, "GameScript", "Target for dialog couldn't be found (Sender: %s, Type: %d).",
+ Sender->GetScriptName(), Sender->Type);
if (Sender->Type == ST_ACTOR) {
- ((Actor *) Sender)->DebugDump();
+ ((Actor *) Sender)->dump();
}
- printf ("Target object: ");
+ StringBuffer buffer;
+ buffer.append("Target object: ");
if (parameters->objects[1]) {
- parameters->objects[1]->Dump();
+ parameters->objects[1]->dump(buffer);
} else {
- printf("<NULL>\n");
+ buffer.append("<NULL>\n");
}
+ Log(ERROR, "GameScript", buffer);
Sender->ReleaseCurrentAction();
return;
}
@@ -862,12 +947,12 @@ void BeginDialog(Scriptable* Sender, Action* parameters, int Flags)
speaker = NULL;
target = (Actor *) tar;
if ((Flags & BD_CHECKDIST) && !CanSee(scr, target, false, seeflag) ) {
- printMessage("GameScript"," ",LIGHT_RED);
- printf("CanSee returned false! Speaker (%s, type %d) and target are:\n", scr->GetScriptName(), scr->Type);
+ Log(ERROR, "GameScript", "CanSee returned false! Speaker (%s, type %d) and target are:",
+ scr->GetScriptName(), scr->Type);
if (scr->Type == ST_ACTOR) {
- ((Actor *) scr)->DebugDump();
+ ((Actor *) scr)->dump();
}
- ((Actor *) tar)->DebugDump();
+ ((Actor *) tar)->dump();
Sender->ReleaseCurrentAction();
return;
}
@@ -875,10 +960,11 @@ void BeginDialog(Scriptable* Sender, Action* parameters, int Flags)
if (scr->Type==ST_ACTOR) {
speaker = (Actor *) scr;
if (speaker->GetStat(IE_STATE_ID)&STATE_DEAD) {
- printMessage("GameScript"," ",LIGHT_RED);
- printf("Speaker is dead, cannot start dialogue. Speaker and target are:\n");
- speaker->DebugDump();
- target->DebugDump();
+ StringBuffer buffer;
+ buffer.append("Speaker is dead, cannot start dialogue. Speaker and target are:\n");
+ speaker->dump(buffer);
+ target->dump(buffer);
+ Log(ERROR, "GameScript", buffer);
Sender->ReleaseCurrentAction();
return;
}
@@ -922,7 +1008,7 @@ void BeginDialog(Scriptable* Sender, Action* parameters, int Flags)
GameControl* gc = core->GetGameControl();
if (!gc) {
- printMessage( "GameScript","Dialog cannot be initiated because there is no GameControl.", YELLOW );
+ Log(WARNING, "GameScript", "Dialog cannot be initiated because there is no GameControl.");
Sender->ReleaseCurrentAction();
return;
}
@@ -934,7 +1020,7 @@ void BeginDialog(Scriptable* Sender, Action* parameters, int Flags)
}
//check if we could manage to break it, not all dialogs are breakable!
if (gc->GetDialogueFlags()&DF_IN_DIALOG) {
- printMessage( "GameScript","Dialog cannot be initiated because there is already one.", YELLOW );
+ Log(WARNING, "GameScript", "Dialog cannot be initiated because there is already one.");
Sender->ReleaseCurrentAction();
return;
}
@@ -955,7 +1041,9 @@ void BeginDialog(Scriptable* Sender, Action* parameters, int Flags)
break;
case BD_SOURCE:
case BD_TARGET:
- if (swap) Dialog = scr->GetDialog();
+ // Don't check for the target being non-interruptible if we swapped speakers
+ // or if the speaker is the target, otherwise do (and request feedback on failure).
+ if (swap || speaker==target) Dialog = scr->GetDialog();
else Dialog = target->GetDialog(GD_FEEDBACK);
break;
case BD_RESERVED:
@@ -964,22 +1052,24 @@ void BeginDialog(Scriptable* Sender, Action* parameters, int Flags)
Dialog = ( const char * ) PlayerDialogRes;
break;
case BD_INTERACT: //using the source for the dialog
- const char* scriptingname = scr->GetScriptName();
-
- /* use interact.2da for short, inlined dialogue */
- int type = CheckInteract(scriptingname, target->GetScriptName());
- if(type) {
- //TODO increase interact counter in scr
- speaker->Interact(type);
- target->Response(type);
+ Game *game = core->GetGame();
+ if (game->BanterBlockFlag || game->BanterBlockTime) {
+ Log(MESSAGE, "GameScript", "Banterblock disabled interaction.");
Sender->ReleaseCurrentAction();
return;
}
+ const char* scriptingname = scr->GetScriptName();
+
/* banter dialogue */
pdtable.load("interdia");
- //Dialog is a borrowed reference, we cannot free pdtable while it is being used
+ //Dialog is a borrowed reference, and pdtable will be freed automagically
if (pdtable) {
- Dialog = pdtable->QueryField( scriptingname, "FILE" );
+ //5 is the magic number for the ToB expansion
+ if (game->Expansion==5) {
+ Dialog = pdtable->QueryField( scriptingname, "25FILE" );
+ } else {
+ Dialog = pdtable->QueryField( scriptingname, "FILE" );
+ }
}
break;
}
@@ -991,15 +1081,14 @@ void BeginDialog(Scriptable* Sender, Action* parameters, int Flags)
return;
}
- //maybe we should remove the action queue, but i'm unsure
- //no, we shouldn't even call this!
- //Sender->ReleaseCurrentAction();
-
// moved this here from InitDialog, because InitDialog doesn't know which side is which
// post-swap (and non-actors always have IF_NOINT set) .. also added a check that it's
// actually busy doing something, for the same reason
- if (target->GetInternalFlag()&IF_NOINT && (target->GetCurrentAction() || target->GetNextAction())) {
- displaymsg->DisplayConstantString(STR_TARGETBUSY,0xff0000);
+ Action *curact = target->GetCurrentAction();
+ if ((speaker != target) && (target->GetInternalFlag()&IF_NOINT) && \
+ (!curact && target->GetNextAction())) {
+ core->GetTokenDictionary()->SetAtCopy("TARGET", target->GetName(1));
+ displaymsg->DisplayConstantString(STR_TARGETBUSY, DMC_RED);
Sender->ReleaseCurrentAction();
return;
}
@@ -1013,7 +1102,8 @@ void BeginDialog(Scriptable* Sender, Action* parameters, int Flags)
if (!(Flags & BD_INTERRUPT)) {
// added CurrentAction as part of blocking action fixes
if (tar->GetCurrentAction() || tar->GetNextAction()) {
- displaymsg->DisplayConstantString(STR_TARGETBUSY,0xff0000);
+ core->GetTokenDictionary()->SetAtCopy("TARGET", target->GetName(1));
+ displaymsg->DisplayConstantString(STR_TARGETBUSY, DMC_RED);
Sender->ReleaseCurrentAction();
return;
}
@@ -1032,7 +1122,7 @@ void BeginDialog(Scriptable* Sender, Action* parameters, int Flags)
}
}
- int ret;
+ bool ret;
if (Dialog[0]) {
//increasing NumTimesTalkedTo or NumTimesInteracted
@@ -1046,40 +1136,62 @@ void BeginDialog(Scriptable* Sender, Action* parameters, int Flags)
ret = gc->dialoghandler->InitDialog( scr, tar, Dialog);
}
else {
- ret = -1;
+ ret = false;
}
- if (ret<0) {
- Sender->ReleaseCurrentAction();
+ Sender->ReleaseCurrentAction();
+
+ if (!ret) {
if (Flags & BD_NOEMPTY) {
return;
}
- displaymsg->DisplayConstantStringName(STR_NOTHINGTOSAY,0xff0000,tar);
+ displaymsg->DisplayConstantStringName(STR_NOTHINGTOSAY, DMC_RED, tar);
return;
}
+}
- //this is a bit fishy
- Sender->SetWait(1);
- Sender->ReleaseCurrentAction();
+static EffectRef fx_movetoarea_ref = { "MoveToArea", -1 };
+bool CreateMovementEffect(Actor* actor, const char *area, const Point &position)
+{
+ if (!strnicmp(area, actor->Area, 8) ) return false; //no need of this for intra area movement
+
+ Effect *fx = EffectQueue::CreateEffect(fx_movetoarea_ref, 0, 0, FX_DURATION_INSTANT_PERMANENT);
+ if (!fx) return false;
+ fx->SetPosition(position);
+ strnuprcpy(fx->Resource, area, 8);
+ core->ApplyEffect(fx, actor, actor);
+ delete fx;
+ return true;
}
void MoveBetweenAreasCore(Actor* actor, const char *area, const Point &position, int face, bool adjust)
{
- printMessage("GameScript", " ", WHITE);
- printf("MoveBetweenAreas: %s to %s [%d.%d] face: %d\n", actor->GetName(0), area,position.x,position.y, face);
+ Log(MESSAGE, "GameScript", "MoveBetweenAreas: %s to %s [%d.%d] face: %d",
+ actor->GetName(0), area,position.x,position.y, face);
+ Map* map1 = actor->GetCurrentArea();
Map* map2;
Game* game = core->GetGame();
- if (area[0]) { //do we need to switch area?
- Map* map1 = actor->GetCurrentArea();
+ if (area[0] && (!map1 || stricmp(area, map1->GetScriptName()))) { //do we need to switch area?
//we have to change the pathfinder
//to the target area if adjust==true
map2 = game->GetMap(area, false);
- if ( map1!=map2 ) {
- if (map1) {
- map1->RemoveActor( actor );
+ if (map1) {
+ map1->RemoveActor( actor );
+ }
+ map2->AddActor( actor, true );
+
+ // update the worldmap if needed
+ if (actor->InParty) {
+ WorldMap *worldmap = core->GetWorldMap();
+ unsigned int areaindex;
+ WMPAreaEntry *entry = worldmap->GetArea(area, areaindex);
+ if (entry) {
+ // make sure the area is marked as revealed and visited
+ if (!(entry->GetAreaStatus() & WMP_ENTRY_VISITED)) {
+ entry->SetAreaStatus(WMP_ENTRY_VISIBLE|WMP_ENTRY_VISITED, BM_OR);
+ }
}
- map2->AddActor( actor );
}
}
actor->SetPosition(position, adjust);
@@ -1108,6 +1220,10 @@ void MoveToObjectCore(Scriptable *Sender, Action *parameters, ieDword flags, boo
return;
}
Actor* actor = ( Actor* ) Sender;
+ Point dest = target->Pos;
+ if (target->Type == ST_TRIGGER && ((InfoPoint *)target)->GetUsePoint()) {
+ dest = ((InfoPoint *)target)->UsePoint;
+ }
if (untilsee && CanSee(actor, target, true, 0) ) {
Sender->ReleaseCurrentAction();
return;
@@ -1117,8 +1233,8 @@ void MoveToObjectCore(Scriptable *Sender, Action *parameters, ieDword flags, boo
return;
}
}
- if (!actor->InMove() || actor->Destination != target->Pos) {
- actor->WalkTo( target->Pos, flags, 0 );
+ if (!actor->InMove() || actor->Destination != dest) {
+ actor->WalkTo( dest, flags, 0 );
}
//hopefully this hack will prevent lockups
if (!actor->InMove()) {
@@ -1139,11 +1255,12 @@ void MoveToObjectCore(Scriptable *Sender, Action *parameters, ieDword flags, boo
Sender->ReleaseCurrentAction();
}
-void CreateItemCore(CREItem *item, const char *resref, int a, int b, int c)
+bool CreateItemCore(CREItem *item, const char *resref, int a, int b, int c)
{
//copy the whole resref, including the terminating zero
strnuprcpy(item->ItemResRef, resref, 8);
- core->ResolveRandomItem(item);
+ if (!core->ResolveRandomItem(item))
+ return false;
if (a==-1) {
//use the default charge counts of the item
Item *origitem = gamedata->GetItem(item->ItemResRef);
@@ -1160,68 +1277,87 @@ void CreateItemCore(CREItem *item, const char *resref, int a, int b, int c)
item->Usages[2]=(ieWord) c;
}
item->Flags=0;
+ item->Expired=0;
+ return true;
}
//It is possible to attack CONTAINERS/DOORS as well!!!
void AttackCore(Scriptable *Sender, Scriptable *target, int flags)
{
//this is a dangerous cast, make sure actor is Actor * !!!
+ assert(Sender && Sender->Type == ST_ACTOR);
Actor *actor = (Actor *) Sender;
- WeaponInfo wi;
- ITMExtHeader *header = NULL;
- ITMExtHeader *hittingheader = NULL;
- int tohit;
- ieDword Flags;
- int DamageBonus, CriticalBonus;
- int speed, style;
-
- //bool leftorright = (bool) ((attacksperround-attackcount)&1);
- bool leftorright = false;
+ // if held or disabled, etc, then cannot start or continue attacking
+ if (actor->Immobile()) {
+ actor->roundTime = 0;
+ Sender->ReleaseCurrentAction();
+ return;
+ }
+
+ // mislead and projected images can't attack
+ int puppet = actor->GetStat(IE_PUPPETMASTERTYPE);
+ if (puppet && puppet < 3) {
+ Log(DEBUG, "AttackCore", "Tried attacking with an illusionary copy: %s!", actor->GetName(1));
+ return;
+ }
+
Actor *tar = NULL;
- ieDword targetID = 0;
if (target->Type==ST_ACTOR) {
tar = (Actor *) target;
- targetID = tar->GetGlobalID();
+
+ // release if target is invisible to sender (because of death or invisbility spell)
+ if (tar->IsInvisibleTo(Sender) || (tar->GetSafeStat(IE_STATE_ID) & STATE_DEAD)){
+ actor->StopAttack();
+ Sender->ReleaseCurrentAction();
+ actor->AddTrigger(TriggerEntry(trigger_targetunreachable, tar->GetGlobalID()));
+ Log(WARNING, "AttackCore", "Tried attacking invisible/dead actor: %s!", tar->GetName(1));
+ return;
+ }
}
+
if (actor == tar) {
Sender->ReleaseCurrentAction();
+ Log(WARNING, "AttackCore", "Tried attacking itself: %s!", tar->GetName(1));
return;
}
+ WeaponInfo wi;
+ bool leftorright = false;
+ ITMExtHeader *header = actor->GetWeapon(wi, leftorright && actor->IsDualWielding());
//will return false on any errors (eg, unusable weapon)
- if (!actor->GetCombatDetails(tohit, leftorright, wi, header, hittingheader, Flags, DamageBonus, speed, CriticalBonus, style, tar)) {
- actor->SetStance(IE_ANI_READY);
+ if (!header || !actor->WeaponIsUsable(leftorright, header)) {
+ actor->StopAttack();
Sender->ReleaseCurrentAction();
+ actor->AddTrigger(TriggerEntry(trigger_unusable, tar->GetGlobalID()));
+ Log(WARNING, "AttackCore", "Weapon unusable: %s!", actor->GetName(1));
return;
}
- if (header) wi.range *= 10;
- else wi.range = 0;
+ unsigned int weaponrange = actor->GetWeaponRange(wi);
if ( target->Type == ST_DOOR || target->Type == ST_CONTAINER) {
- wi.range += 10;
+ weaponrange += 10;
}
if (!(flags&AC_NO_SOUND) ) {
- if (actor->LastTarget != targetID) {
+ if (!Sender->CurrentActionTicks) {
//play attack sound for party members
if (actor->InParty) {
//pick from all 5 possible verbal constants
actor->VerbalConstant(VB_ATTACK, 5);
- //DisplayStringCore(Sender, VB_ATTACK, DS_CONSOLE|DS_CONST );
}
//display attack message
- displaymsg->DisplayConstantStringAction(STR_ACTION_ATTACK,0xf0f0f0, Sender, target);
+ if (target->GetGlobalID() != Sender->LastTarget) {
+ displaymsg->DisplayConstantStringAction(STR_ACTION_ATTACK, DMC_WHITE, Sender, target);
+ }
}
}
- //action performed
- if(target->Type == ST_ACTOR) {
- actor->SetTarget( target );
- }
+
if ( Sender->GetCurrentArea()!=target->GetCurrentArea() ||
- (PersonalDistance(Sender, target) > wi.range) ||
- (!Sender->GetCurrentArea()->IsVisible(Sender->Pos, target->Pos))) {
- MoveNearerTo(Sender, target, wi.range);
+ (PersonalDistance(Sender, target) > weaponrange) ||
+ (!Sender->GetCurrentArea()->IsVisibleLOS(Sender->Pos, target->Pos)) ||
+ !CanSee(Sender, target, true, 0)) {
+ MoveNearerTo(Sender, target, weaponrange);
return;
} else if (target->Type == ST_DOOR) {
//Forcing a lock does not launch the trap...
@@ -1239,7 +1375,10 @@ void AttackCore(Scriptable *Sender, Scriptable *target, int flags)
Sender->ReleaseCurrentAction();
return;
}
+ //action performed
+ actor->FaceTarget(target);
+ Sender->LastTarget = target->GetGlobalID();
actor->PerformAttack(core->GetGame()->GameTime);
}
@@ -1264,8 +1403,8 @@ static int GetIdsValue(const char *&symbol, const char *idsname)
if (!valHook) {
//FIXME:missing ids file!!!
if (InDebug&ID_TRIGGERS) {
- printMessage("GameScript"," ",LIGHT_RED);
- printf("Missing IDS file %s for symbol %s!\n",idsname, symbol);
+ Log(ERROR, "GameScript", "Missing IDS file %s for symbol %s!",
+ idsname, symbol);
}
return -1;
}
@@ -1305,6 +1444,13 @@ static void ParseObject(const char *&str,const char *&src, Object *&object)
SKIP_ARGUMENT();
object = new Object();
switch (*src) {
+ case ')':
+ // missing parameter
+ // (for example, StartDialogueNoSet() in aerie.d)
+ Log(WARNING, "GSUtils", "ParseObject expected an object when parsing dialog");
+ // replace with Myself
+ object->objectFilters[0] = 1;
+ break;
case '"':
//Scriptable Name
src++;
@@ -1332,6 +1478,7 @@ static void ParseObject(const char *&str,const char *&src, Object *&object)
}
src++; //skipping (
if (*src==')') {
+ src++;
break;
}
Nesting++;
@@ -1357,17 +1504,16 @@ Action* GenerateActionCore(const char *src, const char *str, unsigned short acti
if (actionflags[newAction->actionID]&AF_DIRECT) {
Object *tmp = new Object();
tmp->objectFields[0] = -1;
- //tmp->objectFields[1] = core->GetGameControl()->targetID;
newAction->objects[objectCount++] = tmp;
}
//Here is the Action; Now we need to evaluate the parameters, if any
if (*str!=')') while (*str) {
if (*(str+1)!=':') {
- printf("Warning, parser was sidetracked: %s\n",str);
+ Log(WARNING, "GSUtils", "parser was sidetracked: %s", str);
}
switch (*str) {
default:
- printf("Invalid type: %s\n",str);
+ Log(WARNING, "GSUtils", "Invalid type: %s", str);
//str++;
delete newAction;
return NULL;
@@ -1460,7 +1606,7 @@ Action* GenerateActionCore(const char *src, const char *str, unsigned short acti
case 'o': //Object
if (objectCount==3) {
- printf("Invalid object count!\n");
+ Log(ERROR, "GSUtils", "Invalid object count!");
//abort();
delete newAction;
return NULL;
@@ -1514,7 +1660,7 @@ Action* GenerateActionCore(const char *src, const char *str, unsigned short acti
if (mergestrings) {
str++;
if (*str!='s') {
- printf("Invalid mergestrings:%s\n",str);
+ Log(ERROR, "GSUtils", "Invalid mergestrings:%s", str);
//abort();
delete newAction;
return NULL;
@@ -1558,7 +1704,7 @@ Action* GenerateActionCore(const char *src, const char *str, unsigned short acti
void GoNear(Scriptable *Sender, const Point &p)
{
if (Sender->GetCurrentAction()) {
- printMessage("GameScript","Target busy???\n",LIGHT_RED);
+ Log(ERROR, "GameScript", "Target busy???");
return;
}
char Tmp[256];
@@ -1567,13 +1713,13 @@ void GoNear(Scriptable *Sender, const Point &p)
Sender->AddActionInFront( action );
}
-void MoveNearerTo(Scriptable *Sender, Scriptable *target, int distance)
+void MoveNearerTo(Scriptable *Sender, Scriptable *target, int distance, int dont_release)
{
Point p;
Map *myarea, *hisarea;
if (Sender->Type != ST_ACTOR) {
- printMessage("GameScript","MoveNearerTo only works with actors\n",LIGHT_RED);
+ Log(ERROR, "GameScript", "MoveNearerTo only works with actors");
Sender->ReleaseCurrentAction();
return;
}
@@ -1584,7 +1730,7 @@ void MoveNearerTo(Scriptable *Sender, Scriptable *target, int distance)
target = myarea->GetTileMap()->GetTravelTo(hisarea->GetScriptName());
if (!target) {
- printMessage("GameScript", "MoveNearerTo failed to find an exit\n", YELLOW);
+ Log(WARNING, "GameScript", "MoveNearerTo failed to find an exit");
Sender->ReleaseCurrentAction();
return;
}
@@ -1605,7 +1751,7 @@ void MoveNearerTo(Scriptable *Sender, Scriptable *target, int distance)
distance += ((Actor *)target)->size*10;
}
- MoveNearerTo(Sender, p, distance, 0);
+ MoveNearerTo(Sender, p, distance, dont_release);
}
//It is not always good to release the current action if target is unreachable
@@ -1614,7 +1760,7 @@ void MoveNearerTo(Scriptable *Sender, Scriptable *target, int distance)
int MoveNearerTo(Scriptable *Sender, const Point &p, int distance, int dont_release)
{
if (Sender->Type != ST_ACTOR) {
- printMessage("GameScript","MoveNearerTo only works with actors\n",LIGHT_RED);
+ Log(ERROR, "GameScript", "MoveNearerTo only works with actors");
Sender->ReleaseCurrentAction();
return 0;
}
@@ -1644,9 +1790,7 @@ void FreeSrc(SrcVector *poi, const ieResRef key)
{
int res = SrcCache.DecRef((void *) poi, key, true);
if (res<0) {
- printMessage( "GameScript", "Corrupted Src cache encountered (reference count went below zero), ", LIGHT_RED );
- printf( "Src name is: %.8s\n", key);
- abort();
+ error("GameScript", "Corrupted Src cache encountered (reference count went below zero), Src name is: %.8s\n", key);
}
if (!res) {
delete poi;
@@ -1733,11 +1877,11 @@ Trigger *GenerateTriggerCore(const char *src, const char *str, int trIndex, int
//Here is the Trigger; Now we need to evaluate the parameters
if (*str!=')') while (*str) {
if (*(str+1)!=':') {
- printf("Warning, parser was sidetracked: %s\n",str);
+ Log(WARNING, "GSUtils", "parser was sidetracked: %s",str);
}
switch (*str) {
default:
- printf("Invalid type: %s\n",str);
+ Log(ERROR, "GSUtils", "Invalid type: %s", str);
//str++;
delete newTrigger;
return NULL;
@@ -1815,7 +1959,7 @@ Trigger *GenerateTriggerCore(const char *src, const char *str, int trIndex, int
else {
i=0;
}
- while (*src != '"') {
+ while (*src != '"' && *src != '#') {
if (*src == 0) {
delete newTrigger;
return NULL;
@@ -1833,7 +1977,7 @@ Trigger *GenerateTriggerCore(const char *src, const char *str, int trIndex, int
if (mergestrings) {
str++;
if (*str!='s') {
- printf("Invalid mergestrings:%s\n",str);
+ Log(ERROR, "GSUtils", "Invalid mergestrings:%s", str);
//abort();
delete newTrigger;
return NULL;
@@ -1851,7 +1995,7 @@ Trigger *GenerateTriggerCore(const char *src, const char *str, int trIndex, int
}
//reading the context string
i=0;
- while (*src != '"') {
+ while (*src != '"' && *src != '#') {
if (*src == 0) {
delete newTrigger;
return NULL;
@@ -1880,12 +2024,11 @@ void SetVariable(Scriptable* Sender, const char* VarName, const char* Context, i
char newVarName[8+33];
if (InDebug&ID_VARIABLES) {
- printf( "Setting variable(\"%s%s\", %d)\n", Context,
+ Log(DEBUG, "GSUtils", "Setting variable(\"%s%s\", %d)", Context,
VarName, value );
}
- strncpy( newVarName, Context, 6 );
- newVarName[6]=0;
+ strlcpy( newVarName, Context, 7 );
if (strnicmp( newVarName, "MYAREA", 6 ) == 0) {
Sender->GetCurrentArea()->locals->SetAt( VarName, value, NoCreate );
return;
@@ -1906,8 +2049,8 @@ void SetVariable(Scriptable* Sender, const char* VarName, const char* Context, i
map->locals->SetAt( VarName, value, NoCreate);
}
else if (InDebug&ID_VARIABLES) {
- printMessage("GameScript"," ",YELLOW);
- printf("Invalid variable %s %s in setvariable\n",Context, VarName);
+ Log(WARNING, "GameScript", "Invalid variable %s %s in setvariable",
+ Context, VarName);
}
}
else {
@@ -1927,31 +2070,30 @@ void SetVariable(Scriptable* Sender, const char* VarName, ieDword value)
}
if (InDebug&ID_VARIABLES) {
- printf( "Setting variable(\"%s\", %d)\n", VarName, value );
+ Log(DEBUG, "GSUtils", "Setting variable(\"%s\", %d)", VarName, value );
}
- strncpy( newVarName, VarName, 6 );
- newVarName[6]=0;
- if (strnicmp( newVarName, "MYAREA", 6 ) == 0) {
+ strlcpy( newVarName, VarName, 7 );
+ if (stricmp( newVarName, "MYAREA" ) == 0) {
Sender->GetCurrentArea()->locals->SetAt( poi, value, NoCreate );
return;
}
- if (strnicmp( newVarName, "LOCALS", 6 ) == 0) {
+ if (stricmp( newVarName, "LOCALS" ) == 0) {
Sender->locals->SetAt( poi, value, NoCreate );
return;
}
Game *game = core->GetGame();
- if (HasKaputz && !strnicmp(newVarName,"KAPUTZ",6) ) {
+ if (HasKaputz && !stricmp(newVarName,"KAPUTZ") ) {
game->kaputz->SetAt( poi, value, NoCreate );
return;
}
- if (strnicmp(newVarName,"GLOBAL",6) ) {
+ if (stricmp(newVarName,"GLOBAL") ) {
Map *map=game->GetMap(game->FindMap(newVarName));
if (map) {
map->locals->SetAt( poi, value, NoCreate);
}
else if (InDebug&ID_VARIABLES) {
- printMessage("GameScript"," ",YELLOW);
- printf("Invalid variable %s in setvariable\n",VarName);
+ Log(WARNING, "GameScript", "Invalid variable %s in setvariable",
+ VarName);
}
}
else {
@@ -1965,37 +2107,36 @@ ieDword CheckVariable(Scriptable* Sender, const char* VarName, bool *valid)
const char *poi;
ieDword value = 0;
- strncpy( newVarName, VarName, 6 );
- newVarName[6]=0;
+ strlcpy( newVarName, VarName, 7 );
poi = &VarName[6];
//some HoW triggers use a : to separate the scope from the variable name
if (*poi==':') {
poi++;
}
- if (strnicmp( newVarName, "MYAREA", 6 ) == 0) {
+ if (stricmp( newVarName, "MYAREA" ) == 0) {
Sender->GetCurrentArea()->locals->Lookup( poi, value );
if (InDebug&ID_VARIABLES) {
- printf("CheckVariable %s: %d\n",VarName, value);
+ print("CheckVariable %s: %d", VarName, value);
}
return value;
}
- if (strnicmp( newVarName, "LOCALS", 6 ) == 0) {
+ if (stricmp( newVarName, "LOCALS" ) == 0) {
Sender->locals->Lookup( poi, value );
if (InDebug&ID_VARIABLES) {
- printf("CheckVariable %s: %d\n",VarName, value);
+ print("CheckVariable %s: %d", VarName, value);
}
return value;
}
Game *game = core->GetGame();
- if (HasKaputz && !strnicmp(newVarName,"KAPUTZ",6) ) {
+ if (HasKaputz && !stricmp(newVarName,"KAPUTZ") ) {
game->kaputz->Lookup( poi, value );
if (InDebug&ID_VARIABLES) {
- printf("CheckVariable %s: %d\n",VarName, value);
+ print("CheckVariable %s: %d", VarName, value);
}
return value;
}
- if (strnicmp(newVarName,"GLOBAL",6) ) {
+ if (stricmp(newVarName,"GLOBAL") ) {
Map *map=game->GetMap(game->FindMap(newVarName));
if (map) {
map->locals->Lookup( poi, value);
@@ -2004,15 +2145,15 @@ ieDword CheckVariable(Scriptable* Sender, const char* VarName, bool *valid)
*valid=false;
}
if (InDebug&ID_VARIABLES) {
- printMessage("GameScript"," ",YELLOW);
- printf("Invalid variable %s in checkvariable\n",VarName);
+ Log(WARNING, "GameScript", "Invalid variable %s in checkvariable",
+ VarName);
}
}
} else {
game->locals->Lookup( poi, value );
}
if (InDebug&ID_VARIABLES) {
- printf("CheckVariable %s: %d\n",VarName, value);
+ print("CheckVariable %s: %d", VarName, value);
}
return value;
}
@@ -2022,31 +2163,30 @@ ieDword CheckVariable(Scriptable* Sender, const char* VarName, const char* Conte
char newVarName[8];
ieDword value = 0;
- strncpy(newVarName, Context, 6);
- newVarName[6]=0;
- if (strnicmp( newVarName, "MYAREA", 6 ) == 0) {
+ strlcpy(newVarName, Context, 7);
+ if (stricmp( newVarName, "MYAREA" ) == 0) {
Sender->GetCurrentArea()->locals->Lookup( VarName, value );
if (InDebug&ID_VARIABLES) {
- printf("CheckVariable %s%s: %d\n",Context, VarName, value);
+ print("CheckVariable %s%s: %d", Context, VarName, value);
}
return value;
}
- if (strnicmp( newVarName, "LOCALS", 6 ) == 0) {
+ if (stricmp( newVarName, "LOCALS" ) == 0) {
Sender->locals->Lookup( VarName, value );
if (InDebug&ID_VARIABLES) {
- printf("CheckVariable %s%s: %d\n",Context, VarName, value);
+ print("CheckVariable %s%s: %d", Context, VarName, value);
}
return value;
}
Game *game = core->GetGame();
- if (HasKaputz && !strnicmp(newVarName,"KAPUTZ",6) ) {
+ if (HasKaputz && !stricmp(newVarName,"KAPUTZ") ) {
game->kaputz->Lookup( VarName, value );
if (InDebug&ID_VARIABLES) {
- printf("CheckVariable %s%s: %d\n",Context, VarName, value);
+ print("CheckVariable %s%s: %d", Context, VarName, value);
}
return value;
}
- if (strnicmp(newVarName,"GLOBAL",6) ) {
+ if (stricmp(newVarName,"GLOBAL") ) {
Map *map=game->GetMap(game->FindMap(newVarName));
if (map) {
map->locals->Lookup( VarName, value);
@@ -2055,19 +2195,46 @@ ieDword CheckVariable(Scriptable* Sender, const char* VarName, const char* Conte
*valid=false;
}
if (InDebug&ID_VARIABLES) {
- printMessage("GameScript"," ",YELLOW);
- printf("Invalid variable %s %s in checkvariable\n",Context, VarName);
+ Log(WARNING, "GameScript", "Invalid variable %s %s in checkvariable",
+ Context, VarName);
}
}
} else {
game->locals->Lookup( VarName, value );
}
if (InDebug&ID_VARIABLES) {
- printf("CheckVariable %s%s: %d\n",Context, VarName, value);
+ print("CheckVariable %s%s: %d", Context, VarName, value);
}
return value;
}
+// checks if a variable exists in any context
+bool VariableExists(Scriptable *Sender, const char *VarName, const char *Context)
+{
+ ieDword value = 0;
+ char newVarName[8];
+ strlcpy(newVarName, Context, 7);
+ Game *game = core->GetGame();
+
+ if (Sender->GetCurrentArea()->locals->Lookup(VarName, value)) {
+ return true;
+ } else if (Sender->locals->Lookup(VarName, value)) {
+ return true;
+ } else if (HasKaputz && game->kaputz->Lookup(VarName, value)) {
+ return true;
+ } else if (game->locals->Lookup(VarName, value)) {
+ return true;
+ } else {
+ Map *map = game->GetMap(game->FindMap(newVarName));
+ if (map) {
+ if (map->locals->Lookup(VarName, value)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
int DiffCore(ieDword a, ieDword b, int diffmode)
{
switch (diffmode) {
@@ -2147,6 +2314,81 @@ int GetGroup(Actor *actor)
return type;
}
+Actor *GetNearestEnemyOf(Map *map, Actor *origin, int whoseeswho)
+{
+ //determining the allegiance of the origin
+ int type = GetGroup(origin);
+
+ //neutral has no enemies
+ if (type==2) {
+ return NULL;
+ }
+
+ Targets *tgts = new Targets();
+
+ int i = map->GetActorCount(true);
+ Actor *ac;
+ while (i--) {
+ ac=map->GetActor(i,true);
+ if (ac == origin) continue;
+
+ int distance = Distance(ac, origin);
+ if (whoseeswho&ENEMY_SEES_ORIGIN) {
+ if (!CanSee(ac, origin, true, GA_NO_DEAD)) {
+ continue;
+ }
+ }
+ if (whoseeswho&ORIGIN_SEES_ENEMY) {
+ if (!CanSee(ac, origin, true, GA_NO_DEAD)) {
+ continue;
+ }
+ }
+
+ if (type) { //origin is PC
+ if (ac->GetStat(IE_EA) >= EA_EVILCUTOFF) {
+ tgts->AddTarget(ac, distance, GA_NO_DEAD);
+ }
+ }
+ else {
+ if (ac->GetStat(IE_EA) <= EA_GOODCUTOFF) {
+ tgts->AddTarget(ac, distance, GA_NO_DEAD);
+ }
+ }
+ }
+ ac = (Actor *) tgts->GetTarget(0, ST_ACTOR);
+ delete tgts;
+ return ac;
+}
+
+Actor *GetNearestOf(Map *map, Actor *origin, int whoseeswho)
+{
+ Targets *tgts = new Targets();
+
+ int i = map->GetActorCount(true);
+ Actor *ac;
+ while (i--) {
+ ac=map->GetActor(i,true);
+ if (ac == origin) continue;
+
+ int distance = Distance(ac, origin);
+ if (whoseeswho&ENEMY_SEES_ORIGIN) {
+ if (!CanSee(ac, origin, true, GA_NO_DEAD)) {
+ continue;
+ }
+ }
+ if (whoseeswho&ORIGIN_SEES_ENEMY) {
+ if (!CanSee(ac, origin, true, GA_NO_DEAD)) {
+ continue;
+ }
+ }
+
+ tgts->AddTarget(ac, distance, GA_NO_DEAD);
+ }
+ ac = (Actor *) tgts->GetTarget(0, ST_ACTOR);
+ delete tgts;
+ return ac;
+}
+
Point GetEntryPoint(const char *areaname, const char *entryname)
{
Point p;
@@ -2172,8 +2414,7 @@ unsigned int GetSpellDistance(const ieResRef spellres, Scriptable *Sender)
Spell* spl = gamedata->GetSpell( spellres );
if (!spl) {
- printMessage("GameScript"," ",LIGHT_RED);
- printf("Spell couldn't be found:%.8s.\n", spellres);
+ Log(ERROR, "GameScript", "Spell couldn't be found:%.8s.", spellres);
return 0;
}
dist = spl->GetCastingDistance(Sender);
@@ -2184,7 +2425,7 @@ unsigned int GetSpellDistance(const ieResRef spellres, Scriptable *Sender)
}
gamedata->FreeSpell(spl, spellres, false);
- return dist*5; //FIXME: this empirical constant shouldn't be needed!
+ return dist*9; //FIXME: empirical constant to convert from points to (feet)
}
/* returns an item's casting distance, it depends on the used header, and targeting mode too
@@ -2195,8 +2436,7 @@ unsigned int GetItemDistance(const ieResRef itemres, int header)
Item* itm = gamedata->GetItem( itemres );
if (!itm) {
- printMessage("GameScript"," ",LIGHT_RED);
- printf("Item couldn't be found:%.8s.\n", itemres);
+ Log(ERROR, "GameScript", "Item couldn't be found:%.8s.", itemres);
return 0;
}
dist=itm->GetCastingDistance(header);
@@ -2223,8 +2463,7 @@ void SetupWishCore(Scriptable *Sender, int column, int picks)
AutoTable tm("wish");
if (!tm) {
- printStatus( "ERROR", LIGHT_RED );
- printf( "Cannot find wish.2da.\n");
+ Log(ERROR, "GameScript", "Cannot find wish.2da.");
return;
}
@@ -2268,6 +2507,36 @@ retry:
free(selects);
}
+void AmbientActivateCore(Scriptable *Sender, Action *parameters, int flag)
+{
+ AreaAnimation* anim = Sender->GetCurrentArea( )->GetAnimation( parameters->string0Parameter);
+ if (!anim) {
+ anim = Sender->GetCurrentArea( )->GetAnimation( parameters->objects[1]->objectName );
+ }
+ if (!anim) {
+ // iwd2 expects this behaviour in ar6001 by (de)activating sound_portal
+ AmbientMgr *ambientmgr = core->GetAudioDrv()->GetAmbientMgr();
+ if (flag) {
+ ambientmgr->activate(parameters->objects[1]->objectName);
+ } else {
+ ambientmgr->deactivate(parameters->objects[1]->objectName);
+ }
+ return;
+ }
+ int i;
+ if (flag) {
+ anim->Flags |= A_ANI_ACTIVE;
+ for (i=0; i<anim->animcount; i++) {
+ anim->animation[i]->Flags |= A_ANI_ACTIVE;
+ }
+ } else {
+ anim->Flags &= ~A_ANI_ACTIVE;
+ for (i=0; i<anim->animcount; i++) {
+ anim->animation[i]->Flags &= ~A_ANI_ACTIVE;
+ }
+ }
+}
+
#define MAX_ISLAND_POLYGONS 10
//read a polygon 2da
@@ -2307,3 +2576,261 @@ Gem_Polygon *GetPolygon2DA(ieDword index)
return polygons[index];
}
+inline static bool InterruptSpellcasting(Scriptable* Sender) {
+ if (Sender->Type != ST_ACTOR) return false;
+ Actor *caster = (Actor *) Sender;
+
+ // ouch, we got hit
+ if (Sender->InterruptCasting) {
+ int roll = 0;
+
+ // iwd2 does an extra concentration check first:
+ // d20 + Concentration Skill Level + Constitution bonus (+4 Combat casting feat) >= 15 + spell level
+ if (core->HasFeature(GF_3ED_RULES)) {
+ roll = core->Roll(1, 20, 0); // TODO: check if the original does a lucky roll
+ roll += caster->GetStat(IE_CONCENTRATION);
+ roll += caster->GetAbilityBonus(IE_CON);
+ if (caster->HasFeat(FEAT_COMBAT_CASTING)) {
+ roll += 4;
+ }
+ Spell* spl = gamedata->GetSpell(Sender->SpellResRef, true);
+ if (!spl) return false;
+ roll -= spl->SpellLevel;
+ gamedata->FreeSpell(spl, Sender->SpellResRef, false);
+ }
+ if (roll < 15) {
+ if (caster->InParty) {
+ displaymsg->DisplayConstantString(STR_SPELLDISRUPT, DMC_WHITE, Sender);
+ } else {
+ displaymsg->DisplayConstantStringName(STR_SPELL_FAILED, DMC_WHITE, Sender);
+ }
+ DisplayStringCore(Sender, VB_SPELL_DISRUPTED, DS_CONSOLE|DS_CONST );
+ return true;
+ }
+ }
+
+ // abort casting on invisible or dead targets
+ // not all spells should be interrupted on death - some for chunking, some for raising the dead
+ if (Sender->LastTarget) {
+ Actor *target = core->GetGame()->GetActorByGlobalID(Sender->LastTarget);
+ if (target) {
+ ieDword state = target->GetStat(IE_STATE_ID);
+ if (state & STATE_DEAD) {
+ if (state & ~(STATE_PETRIFIED|STATE_FROZEN)) {
+ Spell* spl = gamedata->GetSpell(Sender->SpellResRef, true);
+ if (!spl) return false;
+ SPLExtHeader *seh = spl->GetExtHeader(0); // potentially wrong, but none of the existing spells is problematic
+ if (seh && seh->Target != TARGET_DEAD) {
+ gamedata->FreeSpell(spl, Sender->SpellResRef, false);
+ if (caster->InParty) {
+ core->Autopause(AP_NOTARGET, caster);
+ }
+ caster->SetStance(IE_ANI_READY);
+ return true;
+ }
+ gamedata->FreeSpell(spl, Sender->SpellResRef, false);
+ }
+ }
+ }
+ }
+ return false;
+}
+
+// shared spellcasting action code for casting on scriptables
+void SpellCore(Scriptable *Sender, Action *parameters, int flags)
+{
+ ieResRef spellres;
+ int level = 0;
+
+ //resolve spellname
+ if (!ResolveSpellName( spellres, parameters) ) {
+ Sender->ReleaseCurrentAction();
+ return;
+ } else {
+ if (!Sender->SpellResRef[0] || stricmp(Sender->SpellResRef, spellres)) {
+ if (Sender->CurrentActionTicks) {
+ Log(WARNING, "GameScript", "SpellCore: Action (%d) lost spell somewhere!", parameters->actionID);
+ }
+ Sender->SetSpellResRef(spellres);
+ }
+ }
+ if (!Sender->CurrentActionTicks) {
+ parameters->int2Parameter = 1;
+ }
+
+ if ((flags&SC_AURA_CHECK) && parameters->int2Parameter && Sender->AuraPolluted()) {
+ return;
+ }
+
+ // use the passed level instead of the caster's casting level
+ if (flags&SC_SETLEVEL) {
+ if (parameters->string0Parameter[0]) {
+ level = parameters->int0Parameter;
+ } else {
+ level = parameters->int1Parameter;
+ }
+ }
+
+ Actor *act = NULL;
+ if (Sender->Type==ST_ACTOR) {
+ act = (Actor *) Sender;
+ }
+
+ //parse target
+ int seeflag = 0;
+ unsigned int dist = GetSpellDistance(spellres, Sender);
+ if ((flags&SC_NO_DEAD) && dist != 0xffffffff) {
+ seeflag = GA_NO_DEAD;
+ }
+
+ Scriptable* tar = GetStoredActorFromObject( Sender, parameters->objects[1], seeflag );
+ if (!tar) {
+ Sender->ReleaseCurrentAction();
+ if (act) {
+ act->SetStance(IE_ANI_READY);
+ }
+ return;
+ }
+
+ if (act) {
+ //move near to target
+ if ((flags&SC_RANGE_CHECK) && dist != 0xffffffff) {
+ if (PersonalDistance(tar, Sender) > dist || !Sender->GetCurrentArea()->IsVisibleLOS(Sender->Pos, tar->Pos)) {
+ MoveNearerTo(Sender, tar, dist);
+ return;
+ }
+ }
+
+ //face target
+ if (tar != Sender) {
+ act->SetOrientation( GetOrient( tar->Pos, act->Pos ), false );
+ }
+
+ //stop doing anything else
+ act->SetModal(MS_NONE);
+ }
+
+ int duration;
+ if (!parameters->int2Parameter) {
+ duration = Sender->CurrentActionState--;
+ } else {
+ duration = Sender->CastSpell( tar, flags&SC_DEPLETE, flags&SC_INSTANT, flags&SC_NOINTERRUPT );
+ }
+ if (duration == -1) {
+ // some kind of error
+ Sender->ReleaseCurrentAction();
+ return;
+ } else if (duration > 0) {
+ if (parameters->int2Parameter) {
+ Sender->CurrentActionState = duration;
+ parameters->int2Parameter = 0;
+ }
+ if (!(flags&SC_NOINTERRUPT) && InterruptSpellcasting(Sender)) {
+ Sender->ReleaseCurrentAction();
+ }
+ return;
+ }
+ if (!(flags&SC_NOINTERRUPT) && InterruptSpellcasting(Sender)) {
+ Sender->ReleaseCurrentAction();
+ return;
+ }
+
+ if (Sender->LastTarget) {
+ //if target was set, fire spell
+ Sender->CastSpellEnd(level, flags&SC_INSTANT);
+ } else if(!Sender->LastTargetPos.isempty()) {
+ //the target was converted to a point
+ Sender->CastSpellPointEnd(level, flags&SC_INSTANT);
+ } else {
+ Log(ERROR, "GameScript", "SpellCore: Action (%d) lost target somewhere!", parameters->actionID);
+ }
+ Sender->ReleaseCurrentAction();
+}
+
+
+// shared spellcasting action code for casting on the ground
+void SpellPointCore(Scriptable *Sender, Action *parameters, int flags)
+{
+ ieResRef spellres;
+ int level = 0;
+
+ //resolve spellname
+ if (!ResolveSpellName( spellres, parameters) ) {
+ Sender->ReleaseCurrentAction();
+ return;
+ } else {
+ if (!Sender->SpellResRef[0] || stricmp(Sender->SpellResRef, spellres)) {
+ if (Sender->CurrentActionTicks) {
+ Log(WARNING, "GameScript", "SpellPointCore: Action (%d) lost spell somewhere!", parameters->actionID);
+ }
+ Sender->SetSpellResRef(spellres);
+ }
+ }
+ if (!Sender->CurrentActionTicks) {
+ parameters->int2Parameter = 1;
+ }
+
+ if ((flags&SC_AURA_CHECK) && parameters->int2Parameter && Sender->AuraPolluted()) {
+ return;
+ }
+
+ // use the passed level instead of the caster's casting level
+ if (flags&SC_SETLEVEL) {
+ if (parameters->string0Parameter[0]) {
+ level = parameters->int0Parameter;
+ } else {
+ level = parameters->int1Parameter;
+ }
+ }
+
+ if(Sender->Type==ST_ACTOR) {
+ unsigned int dist = GetSpellDistance(spellres, Sender);
+
+ Actor *act = (Actor *) Sender;
+ //move near to target
+ if ((flags&SC_RANGE_CHECK) && (PersonalDistance(parameters->pointParameter, Sender) > dist || !Sender->GetCurrentArea()->IsVisibleLOS(Sender->Pos, parameters->pointParameter))) {
+ MoveNearerTo(Sender,parameters->pointParameter, dist, 0);
+ return;
+ }
+
+ //face target
+ act->SetOrientation( GetOrient( parameters->pointParameter, act->Pos ), false );
+ //stop doing anything else
+ act->SetModal(MS_NONE);
+ }
+
+ int duration;
+ if (!parameters->int2Parameter) {
+ duration = Sender->CurrentActionState--;
+ } else {
+ duration = Sender->CastSpellPoint( parameters->pointParameter, flags&SC_DEPLETE, flags&SC_INSTANT, flags&SC_NOINTERRUPT );
+ }
+ if (duration == -1) {
+ // some kind of error
+ Sender->ReleaseCurrentAction();
+ return;
+ } else if (duration > 0) {
+ if (parameters->int2Parameter) {
+ Sender->CurrentActionState = duration;
+ parameters->int2Parameter = 0;
+ }
+ if (!(flags&SC_NOINTERRUPT) && InterruptSpellcasting(Sender)) {
+ Sender->ReleaseCurrentAction();
+ }
+ return;
+ }
+ if (!(flags&SC_NOINTERRUPT) && InterruptSpellcasting(Sender)) {
+ Sender->ReleaseCurrentAction();
+ return;
+ }
+
+ if(!Sender->LastTargetPos.isempty()) {
+ //if target was set, fire spell
+ Sender->CastSpellPointEnd(level, flags&SC_INSTANT);
+ } else {
+ Log(ERROR, "GameScript", "SpellPointCore: Action (%d) lost target somewhere!", parameters->actionID);
+ }
+ Sender->ReleaseCurrentAction();
+}
+
+}
diff --git a/gemrb/core/GameScript/GSUtils.h b/gemrb/core/GameScript/GSUtils.h
index fe3a9bf..e8d2cf7 100644
--- a/gemrb/core/GameScript/GSUtils.h
+++ b/gemrb/core/GameScript/GSUtils.h
@@ -28,6 +28,8 @@
#include "Interface.h"
+namespace GemRB {
+
//indebug flags
#define ID_REFERENCE 1
#define ID_CUTSCENE 2
@@ -35,8 +37,13 @@
#define ID_ACTIONS 8
#define ID_TRIGGERS 16
+//whoseeswho for GetNearestEnemy:
+#define ENEMY_SEES_ORIGIN 1
+#define ORIGIN_SEES_ENEMY 2
+
extern Holder<SymbolMgr> triggersTable;
extern Holder<SymbolMgr> actionsTable;
+extern Holder<SymbolMgr> overrideTriggersTable;
extern Holder<SymbolMgr> overrideActionsTable;
extern Holder<SymbolMgr> objectsTable;
extern TriggerFunction triggers[MAX_TRIGGERS];
@@ -70,6 +77,7 @@ int GetHPPercent(Scriptable *Sender);
bool StoreHasItemCore(const ieResRef storename, const ieResRef itemname);
bool HasItemCore(Inventory *inventory, const ieResRef itemname, ieDword flags);
void ClickCore(Scriptable *Sender, Point point, int type, int speed);
+void PlaySequenceCore(Scriptable *Sender, Action *parameters, ieDword value);
void TransformItemCore(Actor *actor, Action *parameters, bool onlyone);
void CreateVisualEffectCore(Actor *target, const char *effect, int iterations);
void CreateVisualEffectCore(Scriptable *Sender, const Point &position, const char *effect, int iterations);
@@ -78,9 +86,9 @@ void BeginDialog(Scriptable* Sender, Action* parameters, int flags);
void ChangeAnimationCore(Actor *src, const char *resref, bool effect);
void PolymorphCopyCore(Actor *src, Actor *tar, bool base);
void CreateCreatureCore(Scriptable* Sender, Action* parameters, int flags);
-int MoveItemCore(Scriptable *Sender, Scriptable *target, const char *resref, int flags, int setflag);
+int MoveItemCore(Scriptable *Sender, Scriptable *target, const char *resref, int flags, int setflag, int count = 0);
void MoveToObjectCore(Scriptable *Sender, Action *parameters, ieDword flags, bool untilsee);
-void CreateItemCore(CREItem *item, const char *resref, int a, int b, int c);
+bool CreateItemCore(CREItem *item, const char *resref, int a, int b, int c);
void AttackCore(Scriptable *Sender, Scriptable *target, int flags);
void InitScriptTables();
void HandleBitMod(ieDword &value1, ieDword value2, int opcode);
@@ -90,7 +98,7 @@ GEM_EXPORT ieDword ResolveSpellNumber(const ieResRef spellres);
bool ResolveItemName(ieResRef itemres, Actor *act, ieDword Slot);
void EscapeAreaCore(Scriptable *Sender, const Point &p, const char *area, const Point &enter, int flags, int wait);
void GoNear(Scriptable *Sender, const Point &p);
-void MoveNearerTo(Scriptable *Sender, Scriptable *target, int distance);
+void MoveNearerTo(Scriptable *Sender, Scriptable *target, int distance, int dont_release=0);
int MoveNearerTo(Scriptable *Sender, const Point &p, int distance, int no_release);
#define NO_OPERATION -1
@@ -109,7 +117,8 @@ int MoveNearerTo(Scriptable *Sender, const Point &p, int distance, int no_releas
#define BINARY_LESS 11 //left has less bits than right
GEM_EXPORT int GetGroup(Actor *actor);
-
+GEM_EXPORT Actor *GetNearestOf(Map *map, Actor *origin, int whoseeswho);
+GEM_EXPORT Actor *GetNearestEnemyOf(Map *map, Actor *origin, int whoseeswho);
GEM_EXPORT void FreeSrc(SrcVector *poi, const ieResRef key);
GEM_EXPORT SrcVector *LoadSrc(const ieResRef resname);
Action *ParamCopy(Action *parameters);
@@ -120,16 +129,21 @@ Point GetEntryPoint(const char *areaname, const char *entryname);
GEM_EXPORT int CanSee(Scriptable* Sender, Scriptable* target, bool range, int nodead);
GEM_EXPORT int SeeCore(Scriptable* Sender, Trigger* parameters, int justlos);
GEM_EXPORT int DiffCore(ieDword a, ieDword b, int diffmode);
-GEM_EXPORT void DisplayStringCore(Scriptable* Sender, int Strref, int flags);
+GEM_EXPORT void DisplayStringCore(Scriptable* const Sender, int Strref, int flags);
GEM_EXPORT void SetVariable(Scriptable* Sender, const char* VarName, const char* Context, ieDword value);
+bool CreateMovementEffect(Actor* actor, const char *area, const Point &position);
GEM_EXPORT void MoveBetweenAreasCore(Actor* actor, const char *area, const Point &position, int face, bool adjust);
GEM_EXPORT ieDword CheckVariable(Scriptable* Sender, const char* VarName, bool *valid = NULL);
GEM_EXPORT ieDword CheckVariable(Scriptable* Sender, const char* VarName, const char* Context, bool *valid = NULL);
+GEM_EXPORT bool VariableExists(Scriptable *Sender, const char *VarName, const char *Context);
Action* GenerateActionCore(const char *src, const char *str, unsigned short actionID);
Trigger *GenerateTriggerCore(const char *src, const char *str, int trIndex, int negate);
-unsigned int GetSpellDistance(const ieResRef spellres, Scriptable *Sender);
+GEM_EXPORT unsigned int GetSpellDistance(const ieResRef spellres, Scriptable *Sender);
unsigned int GetItemDistance(const ieResRef itemres, int header);
void SetupWishCore(Scriptable *Sender, int column, int picks);
+void AmbientActivateCore(Scriptable *Sender, Action *parameters, int flag);
+void SpellCore(Scriptable *Sender, Action *parameters, int flags);
+void SpellPointCore(Scriptable *Sender, Action *parameters, int flags);
Gem_Polygon *GetPolygon2DA(ieDword index);
inline int Bones(ieDword value)
@@ -137,4 +151,6 @@ inline int Bones(ieDword value)
return core->Roll((value&0xf000)>>12, (value&0xff0)>>8, value&15);
}
+}
+
#endif
diff --git a/gemrb/core/GameScript/GameScript.cpp b/gemrb/core/GameScript/GameScript.cpp
index 47564c2..6205f57 100644
--- a/gemrb/core/GameScript/GameScript.cpp
+++ b/gemrb/core/GameScript/GameScript.cpp
@@ -29,6 +29,10 @@
#include "GameData.h"
#include "Interface.h"
#include "PluginMgr.h"
+#include "TableMgr.h"
+#include "System/StringBuffer.h"
+
+namespace GemRB {
//debug flags
// 1 - cache
@@ -94,12 +98,13 @@ static const TriggerLink triggernames[] = {
{"currentareais", GameScript::CurrentAreaIs, 0},//checks object
{"creaturehidden", GameScript::CreatureHidden, 0},//this is the engine level hiding feature, not the skill
{"creatureinarea", GameScript::AreaCheck, 0}, //pst, checks this object
- {"damagetaken", GameScript::HPLost, 0},
- {"damagetakengt", GameScript::HPLostGT, 0},
- {"damagetakenlt", GameScript::HPLostLT, 0},
+ {"damagetaken", GameScript::DamageTaken, 0},
+ {"damagetakengt", GameScript::DamageTakenGT, 0},
+ {"damagetakenlt", GameScript::DamageTakenLT, 0},
{"dead", GameScript::Dead, 0},
{"delay", GameScript::Delay, 0},
{"detect", GameScript::Detect, 0}, //so far i see no difference
+ {"detected", GameScript::Detected, 0}, //trap or secret door detected
{"die", GameScript::Die, 0},
{"died", GameScript::Died, 0},
{"difficulty", GameScript::Difficulty, 0},
@@ -148,9 +153,9 @@ static const TriggerLink triggernames[] = {
{"happiness", GameScript::Happiness, 0},
{"happinessgt", GameScript::HappinessGT, 0},
{"happinesslt", GameScript::HappinessLT, 0},
- {"harmlessclosed", GameScript::Closed, 0}, //pst, not sure
- {"harmlessentered", GameScript::HarmlessEntered, 0}, //???
- {"harmlessopened", GameScript::Opened, 0}, //pst, not sure
+ {"harmlessclosed", GameScript::HarmlessClosed, 0}, //pst
+ {"harmlessentered", GameScript::HarmlessEntered, 0}, //pst
+ {"harmlessopened", GameScript::HarmlessOpened, 0}, //pst
{"hasbounceeffects", GameScript::HasBounceEffects, 0},
{"hasimmunityeffects", GameScript::HasImmunityEffects, 0},
{"hasinnateability", GameScript::HaveSpell, 0}, //these must be the same
@@ -209,6 +214,7 @@ static const TriggerLink triggernames[] = {
{"isfacingsavedrotation", GameScript::IsFacingSavedRotation, 0},
{"isgabber", GameScript::IsGabber, 0},
{"isheartoffurymodeon", GameScript::NightmareModeOn, 0},
+ {"isinguardianmantle", GameScript::IsInGuardianMantle, 0},
{"islocked", GameScript::IsLocked, 0},
{"isextendednight", GameScript::IsExtendedNight, 0},
{"ismarkedspell", GameScript::IsMarkedSpell, 0},
@@ -225,6 +231,7 @@ static const TriggerLink triggernames[] = {
{"isweather", GameScript::IsWeather, 0}, //gemrb extension
{"itemisidentified", GameScript::ItemIsIdentified, 0},
{"joins", GameScript::Joins, 0},
+ {"killed", GameScript::Killed, 0},
{"kit", GameScript::Kit, 0},
{"knowspell", GameScript::KnowSpell, 0}, //gemrb specific
{"lastmarkedobject", GameScript::LastMarkedObject_Trigger, 0},
@@ -314,6 +321,9 @@ static const TriggerLink triggernames[] = {
{"partyitemcounteq", GameScript::NumItemsParty, 0},
{"partyitemcountgt", GameScript::NumItemsPartyGT, 0},
{"partyitemcountlt", GameScript::NumItemsPartyLT, 0},
+ {"partylevelvs", GameScript::NumCreatureVsParty, 0},
+ {"partylevelvsgt", GameScript::NumCreatureVsPartyGT, 0},
+ {"partylevelvslt", GameScript::NumCreatureVsPartyLT, 0},
{"partymemberdied", GameScript::PartyMemberDied, 0},
{"partyrested", GameScript::PartyRested, 0},
{"pccanseepoint", GameScript::PCCanSeePoint, 0},
@@ -345,6 +355,7 @@ static const TriggerLink triggernames[] = {
{"sequence", GameScript::Sequence, 0},
{"setlastmarkedobject", GameScript::SetLastMarkedObject, 0},
{"setmarkedspell", GameScript::SetMarkedSpell_Trigger, 0},
+ {"setspelltarget", GameScript::SetSpellTarget, 0},
{"specifics", GameScript::Specifics, 0},
{"spellcast", GameScript::SpellCast, 0},
{"spellcastinnate", GameScript::SpellCastInnate, 0},
@@ -355,6 +366,9 @@ static const TriggerLink triggernames[] = {
{"storehasitem", GameScript::StoreHasItem, 0},
{"stuffglobalrandom", GameScript::StuffGlobalRandom, 0},//hm, this is a trigger
{"subrace", GameScript::SubRace, 0},
+ {"summoninglimit", GameScript::SummoningLimit, 0},
+ {"summoninglimitgt", GameScript::SummoningLimitGT, 0},
+ {"summoninglimitlt", GameScript::SummoningLimitLT, 0},
{"systemvariable", GameScript::SystemVariable_Trigger, 0}, //gemrb
{"targetunreachable", GameScript::TargetUnreachable, 0},
{"team", GameScript::Team, 0},
@@ -382,6 +396,7 @@ static const TriggerLink triggernames[] = {
{"unselectablevariablegt", GameScript::UnselectableVariableGT, 0},
{"unselectablevariablelt", GameScript::UnselectableVariableLT, 0},
{"unusable",GameScript::Unusable, 0},
+ {"usedexit",GameScript::UsedExit, 0}, //pst unhardcoded trigger for protagonist teleport
{"vacant",GameScript::Vacant, 0},
{"walkedtotrigger", GameScript::WalkedToTrigger, 0},
{"wasindialog", GameScript::WasInDialog, 0},
@@ -465,7 +480,7 @@ static const ActionLink actionnames[] = {
{"changestoremarkup", GameScript::ChangeStoreMarkup, 0},//iwd2
{"changeteam", GameScript::SetTeam, 0}, //pst
{"changetilestate", GameScript::ChangeTileState, 0}, //bg2
- {"chunkcreature", GameScript::Kill, 0}, //should be more graphical
+ {"chunkcreature", GameScript::ChunkCreature, 0}, //should be more graphical
{"clearactions", GameScript::ClearActions, 0},
{"clearallactions", GameScript::ClearAllActions, 0},
{"clearpartyeffects", GameScript::ClearPartyEffects, 0},
@@ -506,11 +521,11 @@ static const ActionLink actionnames[] = {
{"debug", GameScript::Debug, 0},
{"debugoutput", GameScript::Debug, 0},
{"deletejournalentry", GameScript::RemoveJournalEntry, 0},
- {"demoend", GameScript::QuitGame, 0}, //same for now
+ {"demoend", GameScript::DemoEnd, 0}, //same for now
{"destroyalldestructableequipment", GameScript::DestroyAllDestructableEquipment, 0},
{"destroyallequipment", GameScript::DestroyAllEquipment, 0},
{"destroygold", GameScript::DestroyGold, 0},
- {"destroyitem", GameScript::DestroyItem, 0},
+ {"destroyitem", GameScript::DestroyItem, AF_INSTANT}, //Cespenar won't work without this hack So, do we really need instant.ids?
{"destroypartygold", GameScript::DestroyPartyGold, 0},
{"destroypartyitem", GameScript::DestroyPartyItem, 0},
{"destroyself", GameScript::DestroySelf, 0},
@@ -588,8 +603,12 @@ static const ActionLink actionnames[] = {
{"forcehide", GameScript::ForceHide, 0},
{"forceleavearealua", GameScript::ForceLeaveAreaLUA, 0},
{"forcemarkedspell", GameScript::ForceMarkedSpell, 0},
- {"forcespell", GameScript::ForceSpell, AF_BLOCKING},
- {"forcespellpoint", GameScript::ForceSpellPoint, AF_BLOCKING},
+ {"forcespell", GameScript::ForceSpell, AF_BLOCKING|AF_ALIVE},
+ {"forcespellpoint", GameScript::ForceSpellPoint, AF_BLOCKING|AF_ALIVE},
+ {"forcespellpointrange", GameScript::ForceSpellPointRange, AF_BLOCKING|AF_ALIVE},
+ {"forcespellpointrangeres", GameScript::ForceSpellPointRange, AF_BLOCKING|AF_ALIVE},
+ {"forcespellrange", GameScript::ForceSpellRange, AF_BLOCKING|AF_ALIVE},
+ {"forcespellrangeres", GameScript::ForceSpellRange, AF_BLOCKING|AF_ALIVE},
{"forceusecontainer", GameScript::ForceUseContainer,AF_BLOCKING},
{"formation", GameScript::Formation, AF_BLOCKING},
{"fullheal", GameScript::FullHeal, 0},
@@ -637,7 +656,7 @@ static const ActionLink actionnames[] = {
{"incinternal", GameScript::IncInternal, 0}, //pst
{"incrementinternal", GameScript::IncInternal, 0},//iwd
{"incmoraleai", GameScript::IncMoraleAI, 0},
- {"incrementchapter", GameScript::IncrementChapter, AF_BLOCKING},
+ {"incrementchapter", GameScript::IncrementChapter, 0},
{"incrementextraproficiency", GameScript::IncrementExtraProficiency, 0},
{"incrementglobal", GameScript::IncrementGlobal,AF_MERGESTRINGS},
{"incrementglobalonce", GameScript::IncrementGlobalOnce,AF_MERGESTRINGS},
@@ -737,10 +756,10 @@ static const ActionLink actionnames[] = {
{"randomwalk", GameScript::RandomWalk, AF_BLOCKING|AF_ALIVE},
{"randomwalkcontinuous", GameScript::RandomWalkContinuous, AF_BLOCKING|AF_ALIVE},
{"realsetglobaltimer", GameScript::RealSetGlobalTimer,AF_MERGESTRINGS},
- {"reallyforcespell", GameScript::ReallyForceSpell, AF_BLOCKING},
+ {"reallyforcespell", GameScript::ReallyForceSpell, AF_BLOCKING|AF_ALIVE},
{"reallyforcespelldead", GameScript::ReallyForceSpellDead, AF_BLOCKING},
- {"reallyforcespelllevel", GameScript::ReallyForceSpell, AF_BLOCKING},//this is the same action
- {"reallyforcespellpoint", GameScript::ReallyForceSpellPoint, AF_BLOCKING},
+ {"reallyforcespelllevel", GameScript::ReallyForceSpell, AF_BLOCKING|AF_ALIVE},//this is the same action
+ {"reallyforcespellpoint", GameScript::ReallyForceSpellPoint, AF_BLOCKING|AF_ALIVE},
{"recoil", GameScript::Recoil, AF_ALIVE},
{"regainpaladinhood", GameScript::RegainPaladinHood, 0},
{"regainrangerhood", GameScript::RegainRangerHood, 0},
@@ -764,6 +783,7 @@ static const ActionLink actionnames[] = {
{"returntosavedlocation", GameScript::ReturnToSavedLocation, AF_BLOCKING|AF_ALIVE},
{"returntosavedlocationdelete", GameScript::ReturnToSavedLocationDelete, AF_BLOCKING|AF_ALIVE},
{"returntosavedplace", GameScript::ReturnToSavedLocation, AF_BLOCKING|AF_ALIVE},
+ {"returntostartloc", GameScript::ReturnToStartLocation, AF_BLOCKING|AF_ALIVE}, // iwd2
{"revealareaonmap", GameScript::RevealAreaOnMap, 0},
{"runawayfrom", GameScript::RunAwayFrom,AF_BLOCKING|AF_ALIVE},
{"runawayfromnointerrupt", GameScript::RunAwayFromNoInterrupt,AF_BLOCKING|AF_ALIVE},
@@ -810,7 +830,7 @@ static const ActionLink actionnames[] = {
{"setglobaltimeronce", GameScript::SetGlobalTimerOnce,AF_MERGESTRINGS},
{"setglobaltimerrandom", GameScript::SetGlobalTimerRandom,AF_MERGESTRINGS},
{"setglobaltint", GameScript::SetGlobalTint, 0},
- {"sethomelocation", GameScript::SetSavedLocation, 0}, //bg2
+ {"sethomelocation", GameScript::SetHomeLocation, 0}, //bg2
{"sethp", GameScript::SetHP, 0},
{"sethppercent", GameScript::SetHPPercent, 0},
{"setinternal", GameScript::SetInternal, 0},
@@ -868,6 +888,7 @@ static const ActionLink actionnames[] = {
{"spellnodec", GameScript::SpellNoDec, AF_BLOCKING|AF_ALIVE},
{"spellpoint", GameScript::SpellPoint, AF_BLOCKING|AF_ALIVE},
{"spellpointnodec", GameScript::SpellPointNoDec, AF_BLOCKING|AF_ALIVE},
+ {"spellwait", GameScript::Spell, AF_BLOCKING|AF_ALIVE},
{"startcombatcounter", GameScript::StartCombatCounter, 0},
{"startcutscene", GameScript::StartCutScene, 0},
{"startcutsceneex", GameScript::StartCutScene, 0}, //pst (unknown)
@@ -914,7 +935,7 @@ static const ActionLink actionnames[] = {
{"takepartyitemnum", GameScript::TakePartyItemNum, 0},
{"takepartyitemrange", GameScript::TakePartyItemRange, 0},
{"teleportparty", GameScript::TeleportParty, 0},
- {"textscreen", GameScript::TextScreen, AF_BLOCKING},
+ {"textscreen", GameScript::TextScreen, 0},
{"timedmovetopoint", GameScript::TimedMoveToPoint,AF_BLOCKING|AF_ALIVE},
{"tomsstringdisplayer", GameScript::DisplayMessage, 0},
{"transformitem", GameScript::TransformItem, 0},
@@ -922,10 +943,11 @@ static const ActionLink actionnames[] = {
{"transformpartyitem", GameScript::TransformPartyItem, 0},
{"transformpartyitemall", GameScript::TransformPartyItemAll, 0},
{"triggeractivation", GameScript::TriggerActivation, 0},
- {"triggerwalkto", GameScript::MoveToObject,AF_BLOCKING|AF_ALIVE}, //something like this
+ {"triggerwalkto", GameScript::TriggerWalkTo,AF_BLOCKING|AF_ALIVE}, //something like this
{"turn", GameScript::Turn, 0},
{"turnamt", GameScript::TurnAMT, AF_BLOCKING}, //relative Face()
{"undoexplore", GameScript::UndoExplore, 0},
+ {"unhide", GameScript::Unhide, 0},
{"unhidegui", GameScript::UnhideGUI, 0},
{"unloadarea", GameScript::UnloadArea, 0},
{"unlock", GameScript::Unlock, 0},
@@ -1038,6 +1060,7 @@ static const ObjectLink objectnames[] = {
{"sixthnearestenemyof", GameScript::SixthNearestEnemyOf},
{"sixthnearestenemyoftype", GameScript::SixthNearestEnemyOfType},
{"sixthnearestmygroupoftype", GameScript::SixthNearestMyGroupOfType},
+ {"spelltarget", GameScript::SpellTarget},
{"strongestof", GameScript::StrongestOf},
{"strongestofmale", GameScript::StrongestOfMale},
{"tenthnearest", GameScript::TenthNearest},
@@ -1133,8 +1156,8 @@ static const IDSLink* FindIdentifier(const char* idsname)
}
}
- printMessage( "GameScript"," ", YELLOW );
- printf( "Couldn't assign ids target: %.*s\n", len, idsname );
+ Log(WARNING, "GameScript", "Couldn't assign ids target: %.*s",
+ len, idsname );
return NULL;
}
@@ -1259,21 +1282,55 @@ static void CleanupIEScript()
actionsTable.release();
objectsTable.release();
overrideActionsTable.release();
+ overrideTriggersTable.release();
if (ObjectIDSTableNames)
free(ObjectIDSTableNames);
ObjectIDSTableNames = NULL;
}
-void printFunction(Holder<SymbolMgr> table, int index)
+void printFunction(StringBuffer& buffer, Holder<SymbolMgr> table, int index)
{
const char *str = table->GetStringIndex(index);
int value = table->GetValueIndex(index);
int len = strchr(str,'(')-str;
if (len<0) {
- printf("%d %s\n", value, str);
+ buffer.appendFormatted("%d %s", value, str);
} else {
- printf("%d %.*s\n", value, len, str);
+ buffer.appendFormatted("%d %.*s", value, len, str);
+ }
+}
+
+void LoadActionFlags(const char *tableName, int flag, bool critical)
+{
+ int i, j;
+
+ int tableIndex = core->LoadSymbol(tableName);
+ if (tableIndex < 0) {
+ if (critical) {
+ error("GameScript", "Couldn't find %s symbols!\n",tableName);
+ } else {
+ return;
+ }
+ }
+ Holder<SymbolMgr> table = core->GetSymbol(tableIndex);
+ if (!table) {
+ error("GameScript", "Couldn't load %s symbols!\n",tableName);
+ }
+ j = table->GetSize();
+ while (j--) {
+ i = table->GetValueIndex( j );
+ if (i >= MAX_ACTIONS) {
+ Log(ERROR, "GameScript", "%s action %d (%s) is too high, ignoring",
+ tableName, i, table->GetStringIndex( j ) );
+ continue;
+ }
+ if (!actions[i]) {
+ Log(WARNING, "GameScript", "%s action %d (%s) doesn't exist, ignoring",
+ tableName, i, table->GetStringIndex( j ) );
+ continue;
+ }
+ actionflags[i] |= flag;
}
}
@@ -1294,18 +1351,18 @@ void InitializeIEScript()
int aT = core->LoadSymbol( "action" );
int oT = core->LoadSymbol( "object" );
int gaT = core->LoadSymbol( "gemact" );
+ int gtT = core->LoadSymbol( "gemtrig" );
AutoTable objNameTable("script");
if (tT < 0 || aT < 0 || oT < 0 || !objNameTable) {
- printMessage( "GameScript","A critical scripting file is missing!\n",LIGHT_RED );
- abort();
+ error("GameScript", "A critical scripting file is missing!\n");
}
triggersTable = core->GetSymbol( tT );
actionsTable = core->GetSymbol( aT );
objectsTable = core->GetSymbol( oT );
overrideActionsTable = core->GetSymbol( gaT );
+ overrideTriggersTable = core->GetSymbol( gtT );
if (!triggersTable || !actionsTable || !objectsTable || !objNameTable) {
- printMessage( "GameScript","A critical scripting file is damaged!\n",LIGHT_RED );
- abort();
+ error("GameScript", "A critical scripting file is damaged!\n");
}
int i;
@@ -1314,8 +1371,7 @@ void InitializeIEScript()
ObjectIDSCount = atoi( objNameTable->QueryField() );
if (ObjectIDSCount<0 || ObjectIDSCount>MAX_OBJECT_FIELDS) {
- printMessage("GameScript","The IDS Count shouldn't be more than 10!\n",LIGHT_RED);
- abort();
+ error("GameScript", "The IDS Count shouldn't be more than 10!\n");
}
ObjectIDSTableNames = (ieResRef *) malloc( sizeof(ieResRef) * ObjectIDSCount );
@@ -1333,8 +1389,7 @@ void InitializeIEScript()
}
MaxObjectNesting = atoi( objNameTable->QueryField( 1 ) );
if (MaxObjectNesting<0 || MaxObjectNesting>MAX_NESTING) {
- printMessage("GameScript","The Object Nesting Count shouldn't be more than 5!\n", LIGHT_RED);
- abort();
+ error("GameScript", "The Object Nesting Count shouldn't be more than 5!\n");
}
HasAdditionalRect = ( atoi( objNameTable->QueryField( 2 ) ) != 0 );
ExtraParametersCount = atoi( objNameTable->QueryField( 3 ) );
@@ -1349,37 +1404,42 @@ void InitializeIEScript()
memset( actionflags, 0, sizeof( actionflags ) );
memset( objects, 0, sizeof( objects ) );
- int j;
+ int j, max;
- j = triggersTable->GetSize();
- while (j--) {
+ max = triggersTable->GetSize();
+ for (j=0;j<max;j++) {
i = triggersTable->GetValueIndex( j );
const TriggerLink* poi = FindTrigger(triggersTable->GetStringIndex( j ));
- //maybe we should watch for this bit?
- //bool triggerflag = i & 0x4000;
+
+ bool was_condition = (i & 0x4000);
i &= 0x3fff;
if (i >= MAX_TRIGGERS) {
- printMessage("GameScript"," ", RED);
- printf("trigger %d (%s) is too high, ignoring\n", i, triggersTable->GetStringIndex( j ) );
+ Log(ERROR, "GameScript", "trigger %d (%s) is too high, ignoring",
+ i, triggersTable->GetStringIndex( j ) );
continue;
}
+
if (triggers[i]) {
if (poi && triggers[i]!=poi->Function) {
- printMessage("GameScript"," ", YELLOW);
- printf("%s is in collision with ", triggersTable->GetStringIndex( j ) );
- printFunction(triggersTable,triggersTable->FindValue(triggersTable->GetValueIndex( j )));
- //printFunction(triggersTable->GetStringIndex(triggersTable->FindValue(triggersTable->GetValueIndex( j )) ));
+ StringBuffer buffer;
+ buffer.appendFormatted("%s is in collision with ",
+ triggersTable->GetStringIndex( j ) );
+ printFunction(buffer, triggersTable, triggersTable->FindValue(triggersTable->GetValueIndex(j)));
+ Log(WARNING, "GameScript", buffer);
} else {
if (InDebug&ID_TRIGGERS) {
- printMessage("GameScript"," ", WHITE);
- printf("%s is a synonym of ", triggersTable->GetStringIndex( j ) );
- printFunction(triggersTable,triggersTable->FindValue(triggersTable->GetValueIndex( j )));
- //printFunction(triggersTable->GetStringIndex(triggersTable->FindValue(triggersTable->GetValueIndex( j ) ) ) );
+ StringBuffer buffer;
+ buffer.appendFormatted("%s is a synonym of ",
+ triggersTable->GetStringIndex( j ) );
+ printFunction(buffer, triggersTable, triggersTable->FindValue(triggersTable->GetValueIndex(j)));
+ Log(DEBUG, "GameScript", buffer);
}
}
continue; //we already found an alternative
}
+
if (poi == NULL) {
+ // missing trigger which might be resolved later
triggers[i] = NULL;
triggerflags[i] = 0;
missing_triggers.push_back(j);
@@ -1387,6 +1447,8 @@ void InitializeIEScript()
}
triggers[i] = poi->Function;
triggerflags[i] = poi->Flags;
+ if (was_condition)
+ triggerflags[i] |= TF_CONDITION;
}
for (l = missing_triggers.begin(); l!=missing_triggers.end();l++) {
@@ -1402,40 +1464,46 @@ void InitializeIEScript()
for (i = 0; triggernames[i].Name; i++) {
if (f == triggernames[i].Function) {
if (InDebug&ID_TRIGGERS) {
- printMessage("GameScript"," ", WHITE);
- printf("%s is a synonym of %s\n", triggersTable->GetStringIndex( j ), triggernames[i].Name );
+ Log(MESSAGE, "GameScript", "%s is a synonym of %s",
+ triggersTable->GetStringIndex( j ), triggernames[i].Name );
break;
}
}
}
continue;
}
- printMessage("GameScript","Couldn't assign function to trigger: ", YELLOW);
- printFunction(triggersTable,j);
-//->GetStringIndex(j) );
+
+ StringBuffer buffer;
+ buffer.append("Couldn't assign function to trigger: ");
+ printFunction(buffer, triggersTable, j);
+ Log(WARNING, "GameScript", buffer);
}
- j = actionsTable->GetSize();
- while (j--) {
+ max = actionsTable->GetSize();
+ for (j=0;j<max;j++) {
i = actionsTable->GetValueIndex( j );
if (i >= MAX_ACTIONS) {
- printMessage("GameScript"," ", RED);
- printf("action %d (%s) is too high, ignoring\n", i, actionsTable->GetStringIndex( j ) );
+ Log(ERROR, "GameScript", "action %d (%s) is too high, ignoring",
+ i, actionsTable->GetStringIndex( j ) );
continue;
}
const ActionLink* poi = FindAction( actionsTable->GetStringIndex( j ));
if (actions[i]) {
if (poi && actions[i]!=poi->Function) {
- printMessage("GameScript"," ", YELLOW);
- printf("%s is in collision with ", actionsTable->GetStringIndex( j ) );
- printFunction(actionsTable, actionsTable->FindValue(actionsTable->GetValueIndex(j)));
-//->GetStringIndex(actionsTable->FindValue(actionsTable->GetValueIndex( j )) ) );
+ StringBuffer buffer;
+
+ buffer.appendFormatted("%s is in collision with ",
+ actionsTable->GetStringIndex( j ) );
+ printFunction(buffer, actionsTable, actionsTable->FindValue(actionsTable->GetValueIndex(j)));
+ Log(WARNING, "GameScript", buffer);
} else {
if (InDebug&ID_ACTIONS) {
- printMessage("GameScript"," ", WHITE);
- printf("%s is a synonym of ", actionsTable->GetStringIndex( j ) );
- printFunction(actionsTable, actionsTable->FindValue(actionsTable->GetValueIndex( j )));
-//actionsTable->GetStringIndex(actionsTable->FindValue(actionsTable->GetValueIndex( j )) ) );
+ StringBuffer buffer;
+
+ buffer.appendFormatted("%s is a synonym of ",
+ actionsTable->GetStringIndex( j ) );
+ printFunction(buffer, actionsTable, actionsTable->FindValue(actionsTable->GetValueIndex(j)));
+ Log(DEBUG, "GameScript", buffer);
}
}
continue; //we already found an alternative
@@ -1455,29 +1523,85 @@ void InitializeIEScript()
* we add/replace some actions from gemact.ids
* right now you can't print or generate these actions!
*/
- j = overrideActionsTable->GetSize();
- while (j--) {
+ max = overrideActionsTable->GetSize();
+ for (j=0;j<max;j++) {
i = overrideActionsTable->GetValueIndex( j );
if (i >= MAX_ACTIONS) {
- printMessage("GameScript"," ", RED);
- printf("action %d (%s) is too high, ignoring\n", i, overrideActionsTable->GetStringIndex( j ) );
+ Log(ERROR, "GameScript", "action %d (%s) is too high, ignoring",
+ i, overrideActionsTable->GetStringIndex( j ) );
continue;
}
const ActionLink *poi = FindAction( overrideActionsTable->GetStringIndex( j ));
if (!poi) {
+ StringBuffer buffer;
+
+ buffer.append("Couldn't assign function to override action: ");
+ printFunction(buffer, overrideActionsTable, j);
continue;
}
- if (actions[i]) {
- printMessage("GameScript"," ", WHITE);
- printf("%s overrides existing action ", overrideActionsTable->GetStringIndex( j ) );
- printFunction( actionsTable, actionsTable->FindValue(overrideActionsTable->GetValueIndex( j )));
- //printFunction( actionsTable->GetStringIndex(actionsTable->FindValue(overrideActionsTable->GetValueIndex( j )) ) );
+ if (actions[i] && (actions[i]!=poi->Function || actionflags[i]!=poi->Flags) ) {
+ StringBuffer buffer;
+
+ buffer.appendFormatted("%s overrides existing action ",
+ overrideActionsTable->GetStringIndex( j ) );
+ int x = actionsTable->FindValue(i);
+ if (x>=0) {
+ printFunction(buffer, actionsTable, actionsTable->FindValue(i));
+ } else {
+ printFunction(buffer, overrideActionsTable, overrideActionsTable->FindValue(overrideActionsTable->GetValueIndex(j)));
+ }
+ Log(MESSAGE, "GameScript", buffer);
}
actions[i] = poi->Function;
actionflags[i] = poi->Flags;
}
}
+ if (overrideTriggersTable) {
+ /*
+ * we add/replace some actions from gemtrig.ids
+ * right now you can't print or generate these actions!
+ */
+ max = overrideTriggersTable->GetSize();
+ for (j=0;j<max;j++) {
+ i = overrideTriggersTable->GetValueIndex( j );
+ bool was_condition = (i & 0x4000);
+ i &= 0x3fff;
+ if (i >= MAX_TRIGGERS) {
+ Log(ERROR, "GameScript", "trigger %d (%s) is too high, ignoring",
+ i, overrideTriggersTable->GetStringIndex( j ) );
+ continue;
+ }
+ const TriggerLink *poi = FindTrigger( overrideTriggersTable->GetStringIndex( j ));
+ if (!poi) {
+ StringBuffer buffer;
+
+ buffer.append("Couldn't assign function to override trigger: ");
+ printFunction(buffer, overrideTriggersTable, j);
+ continue;
+ }
+ int tf = poi->Flags | (was_condition?TF_CONDITION:0);
+ if (triggers[i] && ( (triggers[i]!=poi->Function) || (triggerflags[i]!=tf) ) ) {
+ StringBuffer buffer;
+
+ buffer.appendFormatted("%s overrides existing trigger ",
+ overrideTriggersTable->GetStringIndex( j ) );
+ int x = triggersTable->FindValue(i);
+ if (x<0) x = triggersTable->FindValue(i|0x4000);
+ if (x>=0) {
+ printFunction(buffer, triggersTable, x);
+ } else {
+ x = overrideTriggersTable->FindValue(i);
+ if (x<0 || x>=j) x = overrideTriggersTable->FindValue(i|0x4000);
+ printFunction(buffer, overrideTriggersTable, x);
+ }
+ Log(MESSAGE, "GameScript", buffer);
+ }
+ triggers[i] = poi->Function;
+ triggerflags[i] = tf;
+ }
+ }
+
for (l = missing_actions.begin(); l!=missing_actions.end();l++) {
j = *l;
// found later as a different name
@@ -1491,39 +1615,42 @@ void InitializeIEScript()
for (i = 0; actionnames[i].Name; i++) {
if (f == actionnames[i].Function) {
if (InDebug&ID_ACTIONS) {
- printMessage("GameScript"," ", WHITE);
- printf("%s is a synonym of %s\n", actionsTable->GetStringIndex( j ), actionnames[i].Name );
+ Log(MESSAGE, "GameScript", "%s is a synonym of %s",
+ actionsTable->GetStringIndex( j ), actionnames[i].Name );
break;
}
}
}
continue;
}
- printMessage("GameScript","Couldn't assign function to action: ", YELLOW);
- printFunction(actionsTable,j);
- //printFunction(actionsTable->GetStringIndex(j) );
+ StringBuffer buffer;
+ buffer.append("Couldn't assign function to action: ");
+ printFunction(buffer, actionsTable, j);
+ Log(WARNING, "GameScript", buffer);
}
j = objectsTable->GetSize();
while (j--) {
i = objectsTable->GetValueIndex( j );
if (i >= MAX_OBJECTS) {
- printMessage("GameScript"," ", RED);
- printf("object %d (%s) is too high, ignoring\n", i, objectsTable->GetStringIndex( j ) );
+ Log(ERROR, "GameScript", "object %d (%s) is too high, ignoring",
+ i, objectsTable->GetStringIndex( j ) );
continue;
}
const ObjectLink* poi = FindObject( objectsTable->GetStringIndex( j ));
if (objects[i]) {
if (poi && objects[i]!=poi->Function) {
- printMessage("GameScript"," ", YELLOW);
- printf("%s is in collision with ", objectsTable->GetStringIndex( j ) );
- printFunction(objectsTable,objectsTable->FindValue(objectsTable->GetValueIndex( j )));
- //printFunction(objectsTable->GetStringIndex(objectsTable->FindValue(objectsTable->GetValueIndex( j )) ) );
+ StringBuffer buffer;
+ buffer.appendFormatted("%s is in collision with ",
+ objectsTable->GetStringIndex( j ) );
+ printFunction(buffer, objectsTable, objectsTable->FindValue(objectsTable->GetValueIndex(j)));
+ Log(WARNING, "GameScript", buffer);
} else {
- printMessage("GameScript"," ", WHITE);
- printf("%s is a synonym of ", objectsTable->GetStringIndex( j ) );
- printFunction(objectsTable, objectsTable->FindValue(objectsTable->GetValueIndex( j )));
- //printFunction(objectsTable->GetStringIndex(objectsTable->FindValue(objectsTable->GetValueIndex( j )) ) );
+ StringBuffer buffer;
+ buffer.appendFormatted("%s is a synonym of ",
+ objectsTable->GetStringIndex( j ) );
+ printFunction(buffer, objectsTable, objectsTable->FindValue(objectsTable->GetValueIndex(j)));
+ Log(DEBUG, "GameScript", buffer);
}
continue;
}
@@ -1547,42 +1674,48 @@ void InitializeIEScript()
if (f) {
for (i = 0; objectnames[i].Name; i++) {
if (f == objectnames[i].Function) {
- printMessage("GameScript"," ", WHITE);
- printf("%s is a synonym of %s\n", objectsTable->GetStringIndex( j ), objectnames[i].Name );
+ Log(MESSAGE, "GameScript", "%s is a synonym of %s",
+ objectsTable->GetStringIndex( j ), objectnames[i].Name );
break;
}
}
continue;
}
- printMessage("GameScript","Couldn't assign function to object: ", YELLOW);
- printFunction(objectsTable,j);
- //printFunction(objectsTable->GetStringIndex(j) );
+ StringBuffer buffer;
+ buffer.append("Couldn't assign function to object: ");
+ printFunction(buffer, objectsTable, j);
+ Log(WARNING, "GameScript", buffer);
}
- int instantTableIndex = core->LoadSymbol("instant");
- if (instantTableIndex < 0) {
- printMessage("GameScript", "Couldn't find instant symbols!\n", LIGHT_RED);
- abort();
- }
- Holder<SymbolMgr> instantTable = core->GetSymbol(instantTableIndex);
- if (!instantTable) {
- printMessage("GameScript", "Couldn't load instant symbols!\n", LIGHT_RED);
- abort();
- }
- j = instantTable->GetSize();
- while (j--) {
- i = instantTable->GetValueIndex( j );
- if (i >= MAX_ACTIONS) {
- printMessage("GameScript"," ", RED);
- printf("instant action %d (%s) is too high, ignoring\n", i, instantTable->GetStringIndex( j ) );
- continue;
+ LoadActionFlags("instant", AF_INSTANT, true);
+ LoadActionFlags("actsleep", AF_SLEEP, false);
+ LoadActionFlags("chase", AF_CHASE, false);
+
+ int savedTriggersIndex = core->LoadSymbol("svtriobj");
+ if (savedTriggersIndex < 0) {
+ // leaving this as not strictly necessary, for now
+ Log(WARNING, "GameScript", "Couldn't find saved trigger symbols!");
+ } else {
+ Holder<SymbolMgr> savedTriggersTable = core->GetSymbol(savedTriggersIndex);
+ if (!savedTriggersTable) {
+ error("GameScript", "Couldn't laod saved trigger symbols!\n");
}
- if (!actions[i]) {
- printMessage("GameScript"," ", YELLOW);
- printf("instant action %d (%s) doesn't exist, ignoring\n", i, instantTable->GetStringIndex( j ) );
- continue;
+ j = savedTriggersTable->GetSize();
+ while (j--) {
+ i = savedTriggersTable->GetValueIndex( j );
+ i &= 0x3fff;
+ if (i >= MAX_ACTIONS) {
+ Log(ERROR, "GameScript", "saved trigger %d (%s) is too high, ignoring",
+ i, savedTriggersTable->GetStringIndex( j ) );
+ continue;
+ }
+ if (!triggers[i]) {
+ Log(WARNING, "GameScript", "saved trigger %d (%s) doesn't exist, ignoring",
+ i, savedTriggersTable->GetStringIndex( j ) );
+ continue;
+ }
+ triggerflags[i] |= TF_SAVED;
}
- actionflags[i] |= AF_INSTANT;
}
}
@@ -1605,17 +1738,15 @@ GameScript::~GameScript(void)
//set 3. parameter to true if you want instant free
//and possible death
if (InDebug&ID_REFERENCE) {
- printf("One instance of %s is dropped from %d.\n", Name, BcsCache.RefCount(Name) );
+ Log(DEBUG, "GameScript", "One instance of %s is dropped from %d.", Name, BcsCache.RefCount(Name) );
}
int res = BcsCache.DecRef(script, Name, true);
if (res<0) {
- printMessage( "GameScript", "Corrupted Script cache encountered (reference count went below zero), ", LIGHT_RED );
- printf( "Script name is: %.8s\n", Name);
- abort();
+ error("GameScript", "Corrupted Script cache encountered (reference count went below zero), Script name is: %.8s\n", Name);
}
if (!res) {
- //printf("Freeing script %s because its refcount has reached 0.\n", Name);
+ //print("Freeing script %s because its refcount has reached 0.", Name);
script->Release();
}
script = NULL;
@@ -1631,7 +1762,7 @@ Script* GameScript::CacheScript(ieResRef ResRef, bool AIScript)
Script *newScript = (Script *) BcsCache.GetResource(ResRef);
if ( newScript ) {
if (InDebug&ID_REFERENCE) {
- printf("Caching %s for the %d. time\n", ResRef, BcsCache.RefCount(ResRef) );
+ Log(DEBUG, "GameScript", "Caching %s for the %d. time\n", ResRef, BcsCache.RefCount(ResRef) );
}
return newScript;
}
@@ -1642,14 +1773,14 @@ Script* GameScript::CacheScript(ieResRef ResRef, bool AIScript)
}
stream->ReadLine( line, 10 );
if (strncmp( line, "SC", 2 ) != 0) {
- printMessage( "GameScript","Not a Compiled Script file\n", YELLOW );
+ Log(WARNING, "GameScript", "Not a Compiled Script file");
delete( stream );
return NULL;
}
newScript = new Script( );
BcsCache.SetAt( ResRef, (void *) newScript );
if (InDebug&ID_REFERENCE) {
- printf("Caching %s for the %d. time\n", ResRef, BcsCache.RefCount(ResRef) );
+ Log(DEBUG, "GameScript", "Caching %s for the %d. time", ResRef, BcsCache.RefCount(ResRef) );
}
while (true) {
@@ -1725,12 +1856,12 @@ static Object* DecodeObject(const char* line)
oB->objectFields[i + ObjectFieldsCount] = ParseInt( line );
}
if (*line != 'O' || *(line + 1) != 'B') {
- printMessage( "GameScript","Got confused parsing object line: ", YELLOW );
- printf("%s\n", origline);
+ Log(WARNING, "GameScript", "Got confused parsing object line: %s", origline);
}
//let the object realize it has no future (in case of null objects)
- if (oB->ReadyToDie()) {
- oB = NULL;
+ if (oB->isNull()) {
+ oB->Release();
+ return NULL;
}
return oB;
}
@@ -1764,6 +1895,11 @@ static Trigger* ReadTrigger(DataStream* stream)
tR->objectParameter = DecodeObject( line );
stream->ReadLine( line, 1024 );
free( line );
+ //discard invalid triggers, so they won't cause a crash
+ if (tR->triggerID>=MAX_TRIGGERS) {
+ delete tR;
+ return NULL;
+ }
return tR;
}
@@ -1798,15 +1934,8 @@ bool GameScript::Update(bool *continuing, bool *done)
if (!script)
return false;
- //ieDword thisTime = core->GetGame()->Ticks;
- //if (( thisTime - lastRunTime ) < scriptRunDelay) {
- // return false;
- //}
-
- //lastRunTime = thisTime;
-
if(!(MySelf->GetInternalFlag()&IF_ACTIVE) ) {
- return true;
+ return false;
}
bool continueExecution = false;
@@ -1824,7 +1953,7 @@ bool GameScript::Update(bool *continuing, bool *done)
if (MySelf->GetInternalFlag()&IF_NOINT) {
// we presumably don't want any further execution?
if (done) *done = true;
- return true;
+ return false;
}
if (lastAction==a) {
@@ -1832,8 +1961,13 @@ bool GameScript::Update(bool *continuing, bool *done)
// this one is a bit more complicated, due to possible
// interactions with Continue() (lastAction here is always
// the first block encountered), needs more testing
- //if (done) *done = true;
- return true;
+ //HoW ar9708, djinni would become visible only if this is not commented out
+ //See: SEDJINNI.BCS
+ //BG2 on the other hand ... (eg. spirit trolls trollsp01 in ar1506)
+ if (core->HasFeature(GF_SKIPUPDATE_HACK)) {
+ if (done) *done = true;
+ }
+ return false;
}
//movetoobjectfollow would break if this isn't called
@@ -1849,16 +1983,13 @@ bool GameScript::Update(bool *continuing, bool *done)
}
continueExecution = ( rB->responseSet->Execute(MySelf) != 0);
if (continuing) *continuing = continueExecution;
- //clear triggers after response executed
- //MySelf->ClearTriggers();
if (!continueExecution) {
if (done) *done = true;
- break;
+ return true;
}
- //continueExecution = false;
}
}
- return true;
+ return continueExecution;
}
//IE simply takes the first action's object for cutscene object
@@ -1903,10 +2034,10 @@ void GameScript::EvaluateAllBlocks()
rS->responses[0]->Execute(target);
// TODO: this will break blocking instants, if there are any
target->ReleaseCurrentAction();
- } else if (InDebug&ID_CUTSCENE) {
- printMessage("GameScript","Failed to find CutSceneID target!\n",YELLOW);
+ } else if ((InDebug&ID_CUTSCENE) || !action->objects[1]) {
+ Log(WARNING, "GameScript", "Failed to find CutSceneID target!");
if (action->objects[1]) {
- action->objects[1]->Dump();
+ action->objects[1]->dump();
}
}
}
@@ -1959,14 +2090,14 @@ Response* GameScript::ReadResponse(DataStream* stream)
}
Response* rE = new Response();
rE->weight = 0;
- int count = stream->ReadLine( line, 1024 );
+ stream->ReadLine( line, 1024 );
char *poi;
rE->weight = (unsigned char)strtoul(line,&poi,10);
if (strncmp(poi,"AC",2)==0)
while (true) {
//not autofreed, because it is referenced by the Script
Action* aC = new Action(false);
- count = stream->ReadLine( line, 1024 );
+ stream->ReadLine( line, 1024 );
aC->actionID = (unsigned short)strtoul(line, NULL,10);
for (int i = 0; i < 3; i++) {
stream->ReadLine( line, 1024 );
@@ -1984,10 +2115,13 @@ Response* GameScript::ReadResponse(DataStream* stream)
strlwr(aC->string1Parameter);
if (aC->actionID>=MAX_ACTIONS) {
aC->actionID=0;
- printMessage("GameScript","Invalid script action ID!",LIGHT_RED);
+ Log(ERROR, "GameScript", "Invalid script action ID!");
} else {
if (actionflags[aC->actionID] & AF_SCRIPTLEVEL) {
- aC->int0Parameter = scriptlevel;
+ //can't set this here, because the same script may be loaded
+ //into different slots. Overwriting it with an invalid value
+ //just to find bugs faster
+ aC->int0Parameter = -1;
}
}
rE->actions.push_back( aC );
@@ -2042,7 +2176,7 @@ bool Condition::Evaluate(Scriptable* Sender)
if (result > 1) {
//we started an Or() block
if (ORcount) {
- printMessage( "GameScript","Unfinished OR block encountered!\n",YELLOW );
+ Log(WARNING, "GameScript", "Unfinished OR block encountered!");
}
ORcount = result;
subresult = false;
@@ -2060,7 +2194,7 @@ bool Condition::Evaluate(Scriptable* Sender)
}
}
if (ORcount) {
- printMessage( "GameScript","Unfinished OR block encountered!\n",YELLOW );
+ Log(WARNING, "GameScript", "Unfinished OR block encountered!");
}
return 1;
}
@@ -2069,7 +2203,7 @@ bool Condition::Evaluate(Scriptable* Sender)
int Trigger::Evaluate(Scriptable* Sender)
{
if (!this) {
- printMessage( "GameScript","Trigger evaluation fails due to NULL trigger.\n",LIGHT_RED );
+ Log(ERROR, "GameScript", "Trigger evaluation fails due to NULL trigger.");
return 0;
}
TriggerFunction func = triggers[triggerID];
@@ -2079,18 +2213,16 @@ int Trigger::Evaluate(Scriptable* Sender)
}
if (!func) {
triggers[triggerID] = GameScript::False;
- printMessage("GameScript"," ",YELLOW);
- printf("Unhandled trigger code: 0x%04x %s\n",
+ Log(WARNING, "GameScript", "Unhandled trigger code: 0x%04x %s",
triggerID, tmpstr );
return 0;
}
if (InDebug&ID_TRIGGERS) {
- printMessage("GameScript"," ",YELLOW);
- printf( "Executing trigger code: 0x%04x %s\n",
+ Log(WARNING, "GameScript", "Executing trigger code: 0x%04x %s",
triggerID, tmpstr );
}
int ret = func( Sender, this );
- if (flags & NEGATE_TRIGGER) {
+ if (flags & TF_NEGATE) {
return !ret;
}
return ret;
@@ -2156,9 +2288,9 @@ int Response::Execute(Scriptable* Sender)
return ret;
}
-void PrintAction(int actionID)
+void PrintAction(StringBuffer& buffer, int actionID)
{
- printf("Action: %d %s\n", actionID , actionsTable->GetValue(actionID) );
+ buffer.appendFormatted("Action: %d %s\n", actionID, actionsTable->GetValue(actionID));
}
void GameScript::ExecuteAction(Scriptable* Sender, Action* aC)
@@ -2173,8 +2305,8 @@ void GameScript::ExecuteAction(Scriptable* Sender, Action* aC)
if (scr) {
if (InDebug&ID_ACTIONS) {
- printMessage("GameScript"," ",YELLOW);
- printf("Sender: %s-->override: %s\n",Sender->GetScriptName(), scr->GetScriptName() );
+ Log(WARNING, "GameScript", "Sender: %s-->override: %s",
+ Sender->GetScriptName(), scr->GetScriptName() );
}
scr->ReleaseCurrentAction();
scr->AddAction(ParamCopyNoOverride(aC));
@@ -2188,17 +2320,18 @@ void GameScript::ExecuteAction(Scriptable* Sender, Action* aC)
scr->CurrentActionInterruptable = false;
}
} else {
- printMessage("GameScript","Actionoverride failed for object: \n",LIGHT_RED);
- aC->objects[0]->Dump();
+ Log(ERROR, "GameScript", "Actionoverride failed for object: ");
+ aC->objects[0]->dump();
}
aC->Release();
return;
}
if (InDebug&ID_ACTIONS) {
- printMessage("GameScript"," ",YELLOW);
- PrintAction(actionID);
- printf("Sender: %s\n",Sender->GetScriptName() );
+ StringBuffer buffer;
+ PrintAction(buffer, actionID);
+ buffer.appendFormatted("Sender: %s\n", Sender->GetScriptName());
+ Log(WARNING, "GameScript", buffer);
}
ActionFunction func = actions[actionID];
if (func) {
@@ -2208,7 +2341,7 @@ void GameScript::ExecuteAction(Scriptable* Sender, Action* aC)
Sender->Activate();
if (actionflags[actionID]&AF_ALIVE) {
if (Sender->GetInternalFlag()&IF_STOPATTACK) {
- printMessage("GameScript", "Aborted action due to death\n", YELLOW);
+ Log(WARNING, "GameScript", "Aborted action due to death");
Sender->ReleaseCurrentAction();
return;
}
@@ -2217,11 +2350,11 @@ void GameScript::ExecuteAction(Scriptable* Sender, Action* aC)
func( Sender, aC );
} else {
actions[actionID] = NoActionAtAll;
- printMessage("GameScript", "Unknown ", YELLOW);
- textcolor(YELLOW);
- PrintAction(actionID);
+ StringBuffer buffer;
+ buffer.append("Unknown ");
+ PrintAction(buffer, actionID);
+ Log(WARNING, "GameScript", buffer);
Sender->ReleaseCurrentAction();
- textcolor(WHITE);
return;
}
@@ -2229,9 +2362,11 @@ void GameScript::ExecuteAction(Scriptable* Sender, Action* aC)
if (actionflags[actionID] & AF_IMMEDIATE) {
//this action never entered the action queue, therefore shouldn't be freed
if (aC->GetRef()!=1) {
- printf("Immediate action got queued!\n");
- PrintAction(actionID);
- abort();
+ StringBuffer buffer;
+ buffer.append("Immediate action got queued!\n");
+ PrintAction(buffer, actionID);
+ Log(ERROR, "GameScript", buffer);
+ error("GameScript", "aborting...\n");
}
return;
}
@@ -2248,27 +2383,24 @@ Trigger* GenerateTrigger(char* String)
{
strlwr( String );
if (InDebug&ID_TRIGGERS) {
- printMessage("GameScript"," ",YELLOW);
- printf("Compiling:%s\n",String);
+ Log(WARNING, "GameScript", "Compiling:%s", String);
}
int negate = 0;
if (*String == '!') {
String++;
- negate = 1;
+ negate = TF_NEGATE;
}
int len = strlench(String,'(')+1; //including (
int i = triggersTable->FindString(String, len);
if (i<0) {
- printMessage("GameScript"," ",LIGHT_RED);
- printf("Invalid scripting trigger: %s\n", String);
+ Log(ERROR, "GameScript", "Invalid scripting trigger: %s", String);
return NULL;
}
char *src = String+len;
char *str = triggersTable->GetStringIndex( i )+len;
Trigger *trigger = GenerateTriggerCore(src, str, i, negate);
if (!trigger) {
- printMessage("GameScript"," ",LIGHT_RED);
- printf("Malformed scripting trigger: %s\n", String);
+ Log(ERROR, "GameScript", "Malformed scripting trigger: %s", String);
return NULL;
}
return trigger;
@@ -2278,8 +2410,7 @@ Action* GenerateAction(char* String)
{
strlwr( String );
if (InDebug&ID_ACTIONS) {
- printMessage("GameScript"," ",YELLOW);
- printf("Compiling:%s\n",String);
+ Log(WARNING, "GameScript", "Compiling:%s", String);
}
int len = strlench(String,'(')+1; //including (
char *src = String+len;
@@ -2296,8 +2427,7 @@ Action* GenerateAction(char* String)
if (i<0) {
i = actionsTable->FindString(String, len);
if (i < 0) {
- printMessage("GameScript"," ",LIGHT_RED);
- printf("Invalid scripting action: %s\n", String);
+ Log(ERROR, "GameScript", "Invalid scripting action: %s", String);
return NULL;
}
str = actionsTable->GetStringIndex( i )+len;
@@ -2305,8 +2435,7 @@ Action* GenerateAction(char* String)
}
Action *action = GenerateActionCore( src, str, actionID);
if (!action) {
- printMessage("GameScript"," ",LIGHT_RED);
- printf("Malformed scripting action: %s\n", String);
+ Log(ERROR, "GameScript", "Malformed scripting action: %s", String);
return NULL;
}
return action;
@@ -2315,6 +2444,7 @@ Action* GenerateAction(char* String)
Action* GenerateActionDirect(char *String, Scriptable *object)
{
Action* action = GenerateAction(String);
+ if (!action) return NULL;
Object *tmp = action->objects[1];
if (tmp && tmp->objectFields[0]==-1) {
tmp->objectFields[1] = object->GetGlobalID();
@@ -2323,8 +2453,36 @@ Action* GenerateActionDirect(char *String, Scriptable *object)
return action;
}
-/** Self-destructing object if it is empty */
-bool Object::ReadyToDie()
+void Object::dump() const
+{
+ StringBuffer buffer;
+ dump(buffer);
+ Log(DEBUG, "GameScript", buffer);
+}
+
+void Object::dump(StringBuffer& buffer) const
+{
+ int i;
+
+ GSASSERT( canary == (unsigned long) 0xdeadbeef, canary );
+ if(objectName[0]) {
+ buffer.appendFormatted("Object: %s\n",objectName);
+ return;
+ }
+ buffer.appendFormatted("IDS Targeting: ");
+ for(i=0;i<MAX_OBJECT_FIELDS;i++) {
+ buffer.appendFormatted("%d ",objectFields[i]);
+ }
+ buffer.append("\n");
+ buffer.append("Filters: ");
+ for(i=0;i<MAX_NESTING;i++) {
+ buffer.appendFormatted("%d ",objectFilters[i]);
+ }
+ buffer.append("\n");
+}
+
+/** Return true if object is null */
+bool Object::isNull()
{
if (objectName[0]!=0) {
return false;
@@ -2337,8 +2495,56 @@ bool Object::ReadyToDie()
return false;
}
}
- //commit suicide
- Release();
return true;
}
+void Trigger::dump() const
+{
+ StringBuffer buffer;
+ dump(buffer);
+ Log(DEBUG, "GameScript", buffer);
+}
+
+void Trigger::dump(StringBuffer& buffer) const
+{
+ GSASSERT( canary == (unsigned long) 0xdeadbeef, canary );
+ buffer.appendFormatted("Trigger: %d\n", triggerID);
+ buffer.appendFormatted("Int parameters: %d %d %d\n", int0Parameter, int1Parameter, int2Parameter);
+ buffer.appendFormatted("Point: [%d.%d]\n", pointParameter.x, pointParameter.y);
+ buffer.appendFormatted("String0: %s\n", string0Parameter);
+ buffer.appendFormatted("String1: %s\n", string1Parameter);
+ if (objectParameter) {
+ objectParameter->dump(buffer);
+ } else {
+ buffer.appendFormatted("No object\n");
+ }
+ buffer.appendFormatted("\n");
+}
+
+void Action::dump() const
+{
+ StringBuffer buffer;
+ dump(buffer);
+ Log(DEBUG, "GameScript", buffer);
+}
+
+void Action::dump(StringBuffer& buffer) const
+{
+ int i;
+
+ GSASSERT( canary == (unsigned long) 0xdeadbeef, canary );
+ buffer.appendFormatted("Int0: %d, Int1: %d, Int2: %d\n",int0Parameter, int1Parameter, int2Parameter);
+ buffer.appendFormatted("String0: %s, String1: %s\n", string0Parameter?string0Parameter:"<NULL>", string1Parameter?string1Parameter:"<NULL>");
+ for (i=0;i<3;i++) {
+ if (objects[i]) {
+ buffer.appendFormatted( "%d. ",i+1);
+ objects[i]->dump(buffer);
+ } else {
+ buffer.appendFormatted( "%d. Object - NULL\n",i+1);
+ }
+ }
+
+ buffer.appendFormatted("RefCount: %d\n", RefCount);
+}
+
+}
diff --git a/gemrb/core/GameScript/GameScript.h b/gemrb/core/GameScript/GameScript.h
index f0925d3..e4424c0 100644
--- a/gemrb/core/GameScript/GameScript.h
+++ b/gemrb/core/GameScript/GameScript.h
@@ -31,9 +31,13 @@
#include <cstdio>
#include <vector>
+namespace GemRB {
+
class Action;
class GameScript;
+class StringBuffer;
+
//escapearea flags
#define EA_DESTROY 1 //destroy actor at the exit (otherwise move to new place)
#define EA_NOSEE 2 //no need to see the exit
@@ -48,7 +52,8 @@ class GameScript;
#define DS_SPEECH 64
#define DS_AREA 128
-//verbal constant (bg2), we need a lookup table for other games
+//verbal constant (bg2), we have a lookup table (vcremap) for other games
+#define VB_INITIALMEET 0
#define VB_PANIC 1
#define VB_HAPPY 2
#define VB_UNHAPPY 3
@@ -59,6 +64,7 @@ class GameScript;
#define VB_DAMAGE 18
#define VB_DIE 19
#define VB_SELECT 26
+#define VB_COMMAND 32
#define VB_INSULT 44
#define VB_COMPLIMENT 47
#define VB_SPECIAL 50
@@ -66,13 +72,15 @@ class GameScript;
#define VB_REACT_S 54
#define VB_RESP_COMP 55
#define VB_RESP_INS 58
-#define VB_HOSTILE 59
-#define VB_DIALOG 60
+#define VB_HOSTILE 61
+#define VB_DIALOG 62
+#define VB_SELECT_RARE 63
#define VB_CRITHIT 65
#define VB_CRITMISS 66
#define VB_TIMMUNE 67
#define VB_INVENTORY 68
#define VB_PP_SUCC 69
+#define VB_SPELL_DISRUPTED 71
#define VB_BIO 74
//diffmode (iwd2)
@@ -97,8 +105,19 @@ class GameScript;
#define AC_NO_SOUND 1
#define AC_RUNNING 2
+//spelll core flags
+#define SC_NO_DEAD 1
+#define SC_RANGE_CHECK 2
+#define SC_DEPLETE 4
+#define SC_SETLEVEL 8
+#define SC_INSTANT 16
+#define SC_AURA_CHECK 32
+#define SC_NOINTERRUPT 64
+
//trigger flags stored in triggers in .bcs files
-#define NEGATE_TRIGGER 1
+#define TF_NEGATE 1 //negate trigger result
+#define TF_APPLIED 2 //set in living when trigger applied
+#define TF_ADDED 4 //set in scriptable when trigger added/applied
#define MAX_OBJECT_FIELDS 10
#define MAX_NESTING 5
@@ -106,8 +125,7 @@ class GameScript;
#define GSASSERT(f,c) \
if(!(f)) \
{ \
- printf("Assertion failed: %s [0x%08lX] Line %d",#f, c, __LINE__); \
- abort(); \
+ error("GSASSERT", "Assertion failed: %s [0x%08lX] Line %d\n",#f, c, __LINE__); \
}
typedef std::vector<ieDword> SrcVector;
@@ -146,7 +164,7 @@ class GEM_EXPORT Object {
public:
Object()
{
- objectName[0] = 0;
+ memset( objectName, 0, 65 );
memset( objectFields, 0, MAX_OBJECT_FIELDS * sizeof( int ) );
memset( objectFilters, 0, MAX_NESTING * sizeof( int ) );
@@ -165,46 +183,29 @@ public:
private:
volatile unsigned long canary;
public:
- void Dump()
- {
- int i;
-
- GSASSERT( canary == (unsigned long) 0xdeadbeef, canary );
- if(objectName[0]) {
- printf("Object: %s\n",objectName);
- return;
- }
- printf("IDS Targeting: ");
- for(i=0;i<MAX_OBJECT_FIELDS;i++) {
- printf("%d ",objectFields[i]);
- }
- printf("\n");
- printf("Filters: ");
- for(i=0;i<MAX_NESTING;i++) {
- printf("%d ",objectFilters[i]);
- }
- printf("\n");
- }
-
+ void dump() const;
+ void dump(StringBuffer&) const;
void Release()
{
GSASSERT( canary == (unsigned long) 0xdeadbeef, canary );
canary = 0xdddddddd;
delete this;
}
- bool ReadyToDie();
+ bool isNull();
};
class GEM_EXPORT Trigger {
public:
Trigger()
{
+ triggerID = 0;
flags = 0;
objectParameter = NULL;
- string0Parameter[0] = 0;
- string1Parameter[0] = 0;
+ memset(string0Parameter, 0, 65);
+ memset(string1Parameter, 0, 65);
int0Parameter = 0;
int1Parameter = 0;
+ int2Parameter = 0;
pointParameter.null();
canary = (unsigned long) 0xdeadbeef;
}
@@ -229,21 +230,8 @@ public:
private:
volatile unsigned long canary;
public:
- void Dump()
- {
- GSASSERT( canary == (unsigned long) 0xdeadbeef, canary );
- printf ("Trigger: %d\n", triggerID);
- printf ("Int parameters: %d %d %d\n", int0Parameter, int1Parameter, int2Parameter);
- printf ("Point: [%d.%d]\n", pointParameter.x, pointParameter.y);
- printf ("String0: %s\n", string0Parameter);
- printf ("String1: %s\n", string1Parameter);
- if (objectParameter) {
- objectParameter->Dump();
- } else {
- printf("No object\n");
- }
- printf("\n");
- }
+ void dump() const;
+ void dump(StringBuffer&) const;
void Release()
{
@@ -290,8 +278,8 @@ public:
objects[0] = NULL;
objects[1] = NULL;
objects[2] = NULL;
- string0Parameter[0] = 0;
- string1Parameter[0] = 0;
+ memset(string0Parameter, 0, 65);
+ memset(string1Parameter, 0, 65);
int0Parameter = 0;
pointParameter.null();
int1Parameter = 0;
@@ -329,32 +317,16 @@ public:
int GetRef() {
return RefCount;
}
- void Dump()
- {
- int i;
- GSASSERT( canary == (unsigned long) 0xdeadbeef, canary );
- printf("Int0: %d, Int1: %d, Int2: %d\n",int0Parameter, int1Parameter, int2Parameter);
- printf("String0: %s, String1: %s\n", string0Parameter?string0Parameter:"<NULL>", string1Parameter?string1Parameter:"<NULL>");
- for (i=0;i<3;i++) {
- if (objects[i]) {
- printf( "%d. ",i+1);
- objects[i]->Dump();
- } else {
- printf( "%d. Object - NULL\n",i+1);
- }
- }
-
- printf("RefCount: %d\n", RefCount);
- }
+ void dump() const;
+ void dump(StringBuffer&) const;
void Release()
{
GSASSERT( canary == (unsigned long) 0xdeadbeef, canary );
if (!RefCount) {
- printf( "WARNING!!! Double Freeing in %s: Line %d\n", __FILE__,
- __LINE__ );
- abort();
+ error("GameScript", "WARNING!!! Double Freeing in %s: Line %d\n", __FILE__,
+ __LINE__);
}
RefCount--;
if (!RefCount) {
@@ -367,9 +339,8 @@ public:
GSASSERT( canary == (unsigned long) 0xdeadbeef, canary );
RefCount++;
if (RefCount >= 65536) {
- printf( "Refcount increased to: %d in action %d\n", RefCount,
- actionID );
- abort();
+ error("GameScript", "Refcount increased to: %d in action %d\n", RefCount,
+ actionID);
}
}
};
@@ -386,7 +357,7 @@ public:
for (size_t c = 0; c < actions.size(); c++) {
if (actions[c]) {
if (actions[c]->GetRef()>2) {
- printf("Residue action %d with refcount %d\n", actions[c]->actionID, actions[c]->GetRef());
+ print("Residue action %d with refcount %d", actions[c]->actionID, actions[c]->GetRef());
}
actions[c]->Release();
actions[c] = NULL;
@@ -501,8 +472,9 @@ typedef void (* ActionFunction)(Scriptable*, Action*);
typedef Targets* (* ObjectFunction)(Scriptable *, Targets*, int ga_flags);
typedef int (* IDSFunction)(Actor *, int parameter);
-#define TF_NONE 0
+#define TF_NONE 0
#define TF_CONDITION 1 //this isn't a trigger, just a condition (0x4000)
+#define TF_SAVED 2 //trigger is in svtriobj.ids
#define TF_MERGESTRINGS 8 //same value as actions' mergestring
struct TriggerLink {
@@ -539,21 +511,23 @@ struct TriggerLink {
#define BD_ITEM 512 //talk to an item
#define BD_NOEMPTY 1024 //don't display '... has nothing to say to you'
-#define AF_NONE 0
-#define AF_IMMEDIATE 1
-#define AF_CONTINUE 2
-#define AF_MASK 3 //none, immediate or continue
-#define AF_BLOCKING 4
-#define AF_MERGESTRINGS 8
+#define AF_NONE 0
+#define AF_IMMEDIATE 1
+#define AF_CONTINUE 2
+#define AF_MASK 3 //none, immediate or continue
+#define AF_BLOCKING 4
+#define AF_MERGESTRINGS 8
//we could use this flag to restrict player scripts from using dangerous
//opcodes, it would be a very useful and easy to implement feature!
-#define AF_RESTRICTED 16
+#define AF_RESTRICTED 16
//#define AF_RESTRICTED_LEVEL2 32 //maybe we could use 2 bits for this???
-#define AF_SCRIPTLEVEL 64 //this hack will transfer scriptlevel to int0parameter at runtime (changecurrentscript relies on it)
-#define AF_INVALID 128
-#define AF_DIRECT 256 //this hack will transfer target from gamecontrol to object1 at compile time
-#define AF_ALIVE 512 //only alive actors can do this
-#define AF_INSTANT 1024
+#define AF_SCRIPTLEVEL 64 //this hack will transfer scriptlevel to int0parameter at runtime (changecurrentscript relies on it)
+#define AF_INVALID 128
+#define AF_DIRECT 256 //this hack will transfer target from gamecontrol to object1 at compile time
+#define AF_ALIVE 512 //only alive actors can do this
+#define AF_INSTANT 1024 //instant actions
+#define AF_CHASE 2048 // ??? actions involving movement ???
+#define AF_SLEEP 4096 //only awake actors can do this
struct ActionLink {
const char* Name;
@@ -571,9 +545,9 @@ struct IDSLink {
IDSFunction Function;
};
-#define MAX_TRIGGERS 0xFF
+#define MAX_TRIGGERS 0x100
#define MAX_ACTIONS 400
-#define MAX_OBJECTS 128
+#define MAX_OBJECTS 256
#define AI_SCRIPT_LEVEL 4 //the script level of special ai scripts
extern void SetScriptDebugMode(int arg);
@@ -671,12 +645,13 @@ public: //Script Functions
static int Contains(Scriptable* Sender, Trigger* parameters);
static int CreatureHidden( Scriptable* Sender, Trigger* parameters);
static int CurrentAreaIs(Scriptable* Sender, Trigger* parameters);
- //static int DamageTaken(Scriptable* Sender, Trigger* parameters);
- //static int DamageTakenGT(Scriptable* Sender, Trigger* parameters);
- //static int DamageTakenLT(Scriptable* Sender, Trigger* parameters);
+ static int DamageTaken(Scriptable* Sender, Trigger* parameters);
+ static int DamageTakenGT(Scriptable* Sender, Trigger* parameters);
+ static int DamageTakenLT(Scriptable* Sender, Trigger* parameters);
static int Dead(Scriptable* Sender, Trigger* parameters);
static int Delay(Scriptable* Sender, Trigger* parameters);
static int Detect(Scriptable* Sender, Trigger* parameters);
+ static int Detected(Scriptable* Sender, Trigger* parameters);
static int Die(Scriptable* Sender, Trigger* parameters);
static int Died(Scriptable* Sender, Trigger* parameters);
static int Difficulty(Scriptable* Sender, Trigger* parameters);
@@ -722,7 +697,9 @@ public: //Script Functions
static int Happiness(Scriptable* Sender, Trigger* parameters);
static int HappinessGT(Scriptable* Sender, Trigger* parameters);
static int HappinessLT(Scriptable* Sender, Trigger* parameters);
+ static int HarmlessClosed(Scriptable* Sender, Trigger* parameters);
static int HarmlessEntered(Scriptable* Sender, Trigger* parameters);
+ static int HarmlessOpened(Scriptable* Sender, Trigger* parameters);
static int HasBounceEffects(Scriptable* Sender, Trigger* parameters);
static int HasImmunityEffects(Scriptable* Sender, Trigger* parameters);
static int HasInnateAbility(Scriptable* Sender, Trigger* parameters);
@@ -772,6 +749,7 @@ public: //Script Functions
static int IsExtendedNight(Scriptable* Sender, Trigger* parameters);
static int IsFacingObject(Scriptable* Sender, Trigger* parameters);
static int IsFacingSavedRotation(Scriptable* Sender, Trigger* parameters);
+ static int IsInGuardianMantle(Scriptable* Sender, Trigger* parameters);
static int IsLocked(Scriptable* Sender, Trigger* parameters);
static int IsMarkedSpell(Scriptable* Sender, Trigger* parameters);
static int IsOverMe(Scriptable* Sender, Trigger* parameters);
@@ -786,6 +764,7 @@ public: //Script Functions
static int ItemIsIdentified(Scriptable* Sender, Trigger* parameters);
static int Joins(Scriptable* Sender, Trigger* parameters);
static int Kit(Scriptable* Sender, Trigger* parameters);
+ static int Killed(Scriptable* Sender, Trigger* parameters);
static int KnowSpell(Scriptable* Sender, Trigger* parameters);
static int LastMarkedObject_Trigger(Scriptable* Sender, Trigger* parameters);
static int LastPersonTalkedTo(Scriptable* Sender, Trigger* parameters);
@@ -893,6 +872,7 @@ public: //Script Functions
static int Sequence(Scriptable* Sender, Trigger* parameters);
static int SetLastMarkedObject(Scriptable* Sender, Trigger* parameters);
static int SetMarkedSpell_Trigger(Scriptable* Sender, Trigger* parameters);
+ static int SetSpellTarget(Scriptable* Sender, Trigger* parameters);
static int Specifics(Scriptable* Sender, Trigger* parameters);
static int SpellCast(Scriptable* Sender, Trigger* parameters);
static int SpellCastInnate(Scriptable* Sender, Trigger* parameters);
@@ -903,6 +883,9 @@ public: //Script Functions
static int StoreHasItem(Scriptable* Sender, Trigger* parameters);
static int StuffGlobalRandom(Scriptable* Sender, Trigger* parameters);
static int SubRace(Scriptable* Sender, Trigger* parameters);
+ static int SummoningLimit(Scriptable* Sender, Trigger* parameters);
+ static int SummoningLimitGT(Scriptable* Sender, Trigger* parameters);
+ static int SummoningLimitLT(Scriptable* Sender, Trigger* parameters);
static int SystemVariable_Trigger(Scriptable* Sender, Trigger* parameters);
static int TargetUnreachable(Scriptable* Sender, Trigger* parameters);
static int Team(Scriptable* Sender, Trigger* parameters);
@@ -929,6 +912,7 @@ public: //Script Functions
static int UnselectableVariableGT(Scriptable* Sender, Trigger* parameters);
static int UnselectableVariableLT(Scriptable* Sender, Trigger* parameters);
static int Unusable(Scriptable* Sender, Trigger* parameters);
+ static int UsedExit(Scriptable* Sender, Trigger* parameters);
static int Vacant(Scriptable* Sender, Trigger* parameters);
static int WalkedToTrigger(Scriptable* Sender, Trigger* parameters);
static int WasInDialog(Scriptable* Sender, Trigger* parameters);
@@ -998,6 +982,7 @@ public:
static void ChangeStatGlobal(Scriptable* Sender, Action* parameters);
static void ChangeStoreMarkup(Scriptable* Sender, Action* parameters);
static void ChangeTileState(Scriptable* Sender, Action* parameters);
+ static void ChunkCreature(Scriptable *Sender, Action* parameters);
static void ClearActions(Scriptable* Sender, Action* parameters);
static void ClearAllActions(Scriptable* Sender, Action* parameters);
static void ClearPartyEffects(Scriptable* Sender, Action* parameters);
@@ -1037,6 +1022,7 @@ public:
static void DayNight(Scriptable *Sender, Action* parameters);
static void Deactivate(Scriptable* Sender, Action* parameters);
static void Debug(Scriptable* Sender, Action* parameters);
+ static void DemoEnd(Scriptable* Sender, Action* parameters);
static void DestroyAllDestructableEquipment(Scriptable* Sender,
Action* parameters);
static void DestroyAllEquipment(Scriptable* Sender, Action* parameters);
@@ -1110,7 +1096,9 @@ public:
static void ForceLeaveAreaLUA(Scriptable* Sender, Action* parameters);
static void ForceMarkedSpell(Scriptable* Sender, Action* parameters);
static void ForceSpell(Scriptable* Sender, Action* parameters);
+ static void ForceSpellRange(Scriptable* Sender, Action* parameters);
static void ForceSpellPoint(Scriptable* Sender, Action* parameters);
+ static void ForceSpellPointRange(Scriptable* Sender, Action* parameters);
static void ForceUseContainer(Scriptable* Sender, Action* parameters);
static void Formation(Scriptable* Sender, Action* parameters);
static void FullHeal(Scriptable* Sender, Action* parameters);
@@ -1260,6 +1248,7 @@ public:
static void RestUntilHealed(Scriptable *Sender, Action* parameters);
static void ReturnToSavedLocation(Scriptable* Sender, Action* parameters);
static void ReturnToSavedLocationDelete(Scriptable* Sender, Action* parameters);
+ static void ReturnToStartLocation(Scriptable* Sender, Action* parameters);
static void RevealAreaOnMap(Scriptable* Sender, Action* parameters);
static void RunAwayFrom(Scriptable* Sender, Action* parameters);
static void RunAwayFromNoInterrupt(Scriptable* Sender, Action* parameters);
@@ -1301,6 +1290,7 @@ public:
static void SetGlobalTimerOnce(Scriptable* Sender, Action* parameters);
static void SetGlobalTimerRandom(Scriptable* Sender, Action* parameters);
static void SetGlobalTint(Scriptable* Sender, Action* parameters);
+ static void SetHomeLocation(Scriptable* Sender, Action* parameters);
static void SetHP(Scriptable* Sender, Action* parameters);
static void SetHPPercent(Scriptable* Sender, Action* parameters);
static void SetInternal(Scriptable* Sender, Action* parameters);
@@ -1399,9 +1389,11 @@ public:
static void TransformPartyItem(Scriptable* Sender, Action* parameters);
static void TransformPartyItemAll(Scriptable* Sender, Action* parameters);
static void TriggerActivation(Scriptable* Sender, Action* parameters);
+ static void TriggerWalkTo(Scriptable* Sender, Action* parameters);
static void Turn(Scriptable* Sender, Action* parameters);
static void TurnAMT(Scriptable* Sender, Action* parameters);
static void UndoExplore(Scriptable *Sender, Action *parameters);
+ static void Unhide(Scriptable* Sender, Action* parameters);
static void UnhideGUI(Scriptable* Sender, Action* parameters);
static void Unlock(Scriptable* Sender, Action* parameters);
static void UnlockScroll(Scriptable* Sender, Action* parameters);
@@ -1498,6 +1490,7 @@ public:
static Targets *SixthNearestEnemyOf(Scriptable *Sender, Targets *parameters, int ga_flags);
static Targets *SixthNearestEnemyOfType(Scriptable *Sender, Targets *parameters, int ga_flags);
static Targets *SixthNearestMyGroupOfType(Scriptable *Sender, Targets *parameters, int ga_flags);
+ static Targets *SpellTarget(Scriptable *Sender, Targets *parameters, int ga_flags);
static Targets *StrongestOf(Scriptable *Sender, Targets *parameters, int ga_flags);
static Targets *StrongestOfMale(Scriptable *Sender, Targets *parameters, int ga_flags);
static Targets *TenthNearest(Scriptable *Sender, Targets *parameters, int ga_flags);
@@ -1532,4 +1525,6 @@ GEM_EXPORT Trigger* GenerateTrigger(char* String);
void InitializeIEScript();
+}
+
#endif
diff --git a/gemrb/core/GameScript/Matching.cpp b/gemrb/core/GameScript/Matching.cpp
index be43aff..452fa89 100644
--- a/gemrb/core/GameScript/Matching.cpp
+++ b/gemrb/core/GameScript/Matching.cpp
@@ -24,13 +24,16 @@
#include "Interface.h"
#include "Game.h"
+#include "Map.h"
#include "TileMap.h"
#include "Scriptable/Container.h"
#include "Scriptable/Door.h"
#include "Scriptable/InfoPoint.h"
+namespace GemRB {
+
/* return a Targets object with a single scriptable inside */
-inline static Targets* ReturnScriptableAsTarget(Scriptable *sc)
+static inline Targets* ReturnScriptableAsTarget(Scriptable *sc)
{
if (!sc) return NULL;
Targets *tgts = new Targets();
@@ -39,7 +42,7 @@ inline static Targets* ReturnScriptableAsTarget(Scriptable *sc)
}
/* do IDS filtering: [PC], [ENEMY], etc */
-inline static bool DoObjectIDSCheck(Object *oC, Actor *ac, bool *filtered) {
+static inline bool DoObjectIDSCheck(Object *oC, Actor *ac, bool *filtered) {
for (int j = 0; j < ObjectIDSCount; j++) {
if (!oC->objectFields[j]) {
continue;
@@ -47,8 +50,7 @@ inline static bool DoObjectIDSCheck(Object *oC, Actor *ac, bool *filtered) {
*filtered = true;
IDSFunction func = idtargets[j];
if (!func) {
- printMessage("GameScript"," ", YELLOW);
- printf("Unimplemented IDS targeting opcode: %d\n", j);
+ Log(WARNING, "GameScript", "Unimplemented IDS targeting opcode: %d", j);
continue;
}
if (!func( ac, oC->objectFields[j] ) ) {
@@ -59,15 +61,27 @@ inline static bool DoObjectIDSCheck(Object *oC, Actor *ac, bool *filtered) {
}
/* do object filtering: Myself, LastAttackerOf(Player1), etc */
-inline static Targets *DoObjectFiltering(Scriptable *Sender, Targets *tgts, Object *oC, int ga_flags) {
+static inline Targets *DoObjectFiltering(Scriptable *Sender, Targets *tgts, Object *oC, int ga_flags) {
+ targetlist::iterator m;
+ const targettype *tt = tgts->GetFirstTarget(m, ST_ACTOR);
+ while (tt) {
+ Actor *target = (Actor *) tt->actor;
+ if (target->ValidTarget(GA_NO_DEAD)) {
+ tt = tgts->GetNextTarget(m, ST_ACTOR);
+ } else {
+ tt = tgts->RemoveTargetAt(m);
+ }
+ }
+
for (int i = 0; i < MaxObjectNesting; i++) {
int filterid = oC->objectFilters[i];
if (!filterid) break;
+ if (filterid < 0) continue;
ObjectFunction func = objects[filterid];
if (!func) {
- printMessage("GameScript"," ", YELLOW);
- printf("Unknown object filter: %d %s\n", filterid, objectsTable->GetValue(filterid));
+ Log(WARNING, "GameScript", "Unknown object filter: %d %s",
+ filterid, objectsTable->GetValue(filterid));
continue;
}
@@ -82,7 +96,7 @@ inline static Targets *DoObjectFiltering(Scriptable *Sender, Targets *tgts, Obje
static EffectRef fx_protection_creature_ref = { "Protection:Creature", -1 };
-inline static bool DoObjectChecks(Map *map, Scriptable *Sender, Actor *target, int &dist, bool ignoreinvis=false)
+static inline bool DoObjectChecks(Map *map, Scriptable *Sender, Actor *target, int &dist, bool ignoreinvis=false)
{
dist = SquaredMapDistance(Sender, target);
@@ -93,21 +107,8 @@ inline static bool DoObjectChecks(Map *map, Scriptable *Sender, Actor *target, i
Actor *source = (Actor *)Sender;
// Detect() ignores invisibility completely
- if (!ignoreinvis) {
- // TODO: move this stuff into a shared function so it can be used elsewhere?
-
- // SEEINVISIBLE skips these checks :-)
- if (source->Modified[IE_SEEINVISIBLE] == 0) {
- ieDword state = target->Modified[IE_STATE_ID];
- // check for invisibility
- if ((state & STATE_INVISIBLE) != 0) return false;
- // check for improved invisibility? probably not
- //if ((state & STATE_INVIS2) != 0) return false;
- }
-
- // maybe this should be setting an invis flag?
- // TODO: should SEEINVISIBLE ignore this? Detect()?
- if (target->Modified[IE_AVATARREMOVAL]) return false;
+ if (!ignoreinvis && target->IsInvisibleTo(source)) {
+ return false;
}
// visual range check
@@ -115,7 +116,7 @@ inline static bool DoObjectChecks(Map *map, Scriptable *Sender, Actor *target, i
if (dist > visualrange*visualrange) return false;
// LOS check
- if (!map->IsVisible(Sender->Pos, target->Pos)) return false;
+ if (!map->IsVisibleLOS(Sender->Pos, target->Pos)) return false;
// protection against creature
if (target->fxqueue.HasEffect(fx_protection_creature_ref)) {
@@ -142,13 +143,25 @@ static Targets* EvaluateObject(Map *map, Scriptable* Sender, Object* oC, int ga_
}
if (oC->objectName[0]) {
- //We want the object by its name... (doors/triggers don't play here!)
- Actor* aC = map->GetActor( oC->objectName, ga_flags );
+ //We want the object by its name...
+ Scriptable* aC = map->GetActor( oC->objectName, ga_flags );
/*if (!aC && (ga_flags&GA_GLOBAL) ) {
aC = FindActorNearby(oC->objectName, map, ga_flags );
}*/
+ //This order is the same as in GetActorObject
+ //TODO:merge them
+ if (!aC) {
+ aC = map->GetTileMap()->GetDoor(oC->objectName);
+ }
+ if (!aC) {
+ aC = map->GetTileMap()->GetContainer(oC->objectName);
+ }
+ if (!aC) {
+ aC = map->GetTileMap()->GetInfoPoint(oC->objectName);
+ }
+
//return here because object name/IDS targeting are mutually exclusive
return ReturnScriptableAsTarget(aC);
}
@@ -192,6 +205,8 @@ static Targets* EvaluateObject(Map *map, Scriptable* Sender, Object* oC, int ga_
if (ac == Sender) continue;
bool filtered = false;
if (DoObjectIDSCheck(oC, ac, &filtered)) {
+ // this is needed so eg. Range trigger gets a good object
+ // HACK: our parsing of Attack([0]) is broken
if (!filtered) {
// if no filters were applied..
assert(!tgts);
@@ -211,7 +226,8 @@ static Targets* EvaluateObject(Map *map, Scriptable* Sender, Object* oC, int ga_
Targets* GetAllObjects(Map *map, Scriptable* Sender, Object* oC, int ga_flags)
{
if (!oC) {
- return NULL;
+ //return all objects
+ return GetAllActors(Sender, ga_flags);
}
Targets* tgts = EvaluateObject(map, Sender, oC, ga_flags);
//if we couldn't find an endpoint by name or object qualifiers
@@ -235,10 +251,15 @@ Targets *GetAllActors(Scriptable *Sender, int ga_flags)
int i = map->GetActorCount(true);
Targets *tgts = new Targets();
+ //make sure that Sender is always first in the list, even if there
+ //are other (e.g. dead) targets at the same location
+ tgts->AddTarget(Sender, 0, ga_flags);
while (i--) {
Actor *ac = map->GetActor(i,true);
- int dist = Distance(Sender->Pos, ac->Pos);
- tgts->AddTarget((Scriptable *) ac, dist, ga_flags);
+ if (ac != Sender) {
+ int dist = Distance(Sender->Pos, ac->Pos);
+ tgts->AddTarget(ac, dist, ga_flags);
+ }
}
return tgts;
}
@@ -289,7 +310,7 @@ Scriptable* GetStoredActorFromObject(Scriptable* Sender, Object* oC, int ga_flag
// maybe store the target if it's an actor..
if (tar && tar->Type == ST_ACTOR) {
// .. but we only want objects created via objectFilters
- if (oC->objectFilters[0]) {
+ if (oC && oC->objectFilters[0]) {
Sender->CurrentActionTarget = tar->GetGlobalID();
}
}
@@ -300,16 +321,13 @@ Scriptable* GetActorFromObject(Scriptable* Sender, Object* oC, int ga_flags)
{
Scriptable *aC = NULL;
- if (!oC) {
- return NULL;
- }
Game *game = core->GetGame();
Targets *tgts = GetAllObjects(Sender->GetCurrentArea(), Sender, oC, ga_flags);
if (tgts) {
//now this could return other than actor objects
aC = tgts->GetTarget(0,-1);
delete tgts;
- if (aC || oC->objectFields[0]!=-1) {
+ if (aC || !oC || oC->objectFields[0]!=-1) {
return aC;
}
@@ -317,6 +335,10 @@ Scriptable* GetActorFromObject(Scriptable* Sender, Object* oC, int ga_flags)
return game->GetGlobalActorByGlobalID(oC->objectFields[1]);
}
+ if (!oC) {
+ return NULL;
+ }
+
if (oC->objectName[0]) {
// if you ActionOverride a global actor, they might not have a map :(
// TODO: don't allow this to happen?
@@ -416,8 +438,11 @@ int GetObjectCount(Scriptable* Sender, Object* oC)
// GetAllObjects will also return Myself (evaluates object filters)
// i believe we need the latter here
Targets* tgts = GetAllObjects(Sender->GetCurrentArea(), Sender, oC, 0);
- int count = tgts->Count();
- delete tgts;
+ int count = 0; // silly fallback to avoid potential crashes
+ if (tgts) {
+ count = tgts->Count();
+ delete tgts;
+ }
return count;
}
@@ -572,14 +597,17 @@ Targets *ClosestEnemySummoned(Scriptable *origin, Targets *parameters, int ga_fl
while ( t ) {
Actor *tmp = (Actor *) (t->actor);
if (tmp->GetStat(IE_SEX) != SEX_SUMMON) {
+ t = parameters->GetNextTarget(m, ST_ACTOR);
continue;
}
if (type) { //origin is PC
if (tmp->GetStat(IE_EA) <= EA_GOODCUTOFF) {
+ t = parameters->GetNextTarget(m, ST_ACTOR);
continue;
}
} else {
if (tmp->GetStat(IE_EA) >= EA_EVILCUTOFF) {
+ t = parameters->GetNextTarget(m, ST_ACTOR);
continue;
}
}
@@ -620,12 +648,12 @@ Targets *XthNearestEnemyOfType(Scriptable *origin, Targets *parameters, unsigned
Actor *actor = (Actor *) (t->actor);
// IDS targeting already did object checks (unless we need to override Detect?)
if (type) { //origin is PC
- if (actor->GetStat(IE_EA) <= EA_GOODCUTOFF) {
+ if (actor->GetStat(IE_EA) <= EA_EVILCUTOFF) {
t=parameters->RemoveTargetAt(m);
continue;
}
} else {
- if (actor->GetStat(IE_EA) >= EA_EVILCUTOFF) {
+ if (actor->GetStat(IE_EA) >= EA_GOODCUTOFF) {
t=parameters->RemoveTargetAt(m);
continue;
}
@@ -653,6 +681,7 @@ Targets *XthNearestEnemyOf(Targets *parameters, int count, int ga_flags)
Actor *ac;
while (i--) {
ac=map->GetActor(i,true);
+ if (ac == origin) continue;
int distance;
//int distance = Distance(ac, origin);
// TODO: if it turns out you need to check Sender here, beware you take the right distance!
@@ -672,3 +701,5 @@ Targets *XthNearestEnemyOf(Targets *parameters, int count, int ga_flags)
return XthNearestOf(parameters,count, ga_flags);
}
+
+}
diff --git a/gemrb/core/GameScript/Matching.h b/gemrb/core/GameScript/Matching.h
index a01fa22..3d99b41 100644
--- a/gemrb/core/GameScript/Matching.h
+++ b/gemrb/core/GameScript/Matching.h
@@ -24,6 +24,10 @@
#include "exports.h"
+namespace GemRB {
+
+class TileMap;
+
GEM_EXPORT Targets* GetAllObjects(Map *map, Scriptable* Sender, Object* oC, int ga_flags);
Targets* GetAllActors(Scriptable* Sender, int ga_flags);
Scriptable* GetActorFromObject(Scriptable* Sender, Object* oC, int ga_flags = 0);
@@ -44,4 +48,6 @@ bool MatchActor(Scriptable *Sender, ieDword ID, Object* oC);
int GetObjectCount(Scriptable* Sender, Object* oC);
int GetObjectLevelCount(Scriptable* Sender, Object* oC);
+}
+
#endif
diff --git a/gemrb/core/GameScript/Objects.cpp b/gemrb/core/GameScript/Objects.cpp
index 2cc9b3b..76f48aa 100644
--- a/gemrb/core/GameScript/Objects.cpp
+++ b/gemrb/core/GameScript/Objects.cpp
@@ -29,6 +29,8 @@
#include "Game.h"
#include "GUI/GameControl.h"
+namespace GemRB {
+
//-------------------------------------------------------------
// Object Functions
//-------------------------------------------------------------
@@ -136,9 +138,13 @@ Targets *GameScript::Gabber(Scriptable* /*Sender*/, Targets *parameters, int ga_
Targets *GameScript::LastTrigger(Scriptable *Sender, Targets *parameters, int ga_flags)
{
+ Scriptable *target = parameters->GetTarget(0, -1);
parameters->Clear();
- if (Sender->LastTriggerObject) {
- Actor *target = Sender->GetCurrentArea()->GetActorByGlobalID(Sender->LastTriggerObject);
+ if (target) {
+ target = Sender->GetCurrentArea()->GetActorByGlobalID(target->LastTrigger);
+ parameters->AddTarget(target, 0, ga_flags);
+ } else if (Sender->LastTrigger) {
+ target = Sender->GetCurrentArea()->GetActorByGlobalID(Sender->LastTrigger);
parameters->AddTarget(target, 0, ga_flags);
}
return parameters;
@@ -162,6 +168,24 @@ Targets *GameScript::LastMarkedObject(Scriptable *Sender, Targets *parameters, i
return parameters;
}
+Targets *GameScript::SpellTarget(Scriptable *Sender, Targets *parameters, int ga_flags)
+{
+ Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR);
+ if (!actor) {
+ if (Sender->Type==ST_ACTOR) {
+ actor = (Actor *) Sender;
+ }
+ }
+ parameters->Clear();
+ if (actor) {
+ Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastTarget);
+ if (target) {
+ parameters->AddTarget(target, 0, ga_flags);
+ }
+ }
+ return parameters;
+}
+
//actions should always use LastMarkedObject, because LastSeen could be deleted
Targets *GameScript::LastSeenBy(Scriptable *Sender, Targets *parameters, int ga_flags)
{
@@ -252,7 +276,7 @@ Targets *GameScript::ProtectorOf(Scriptable *Sender, Targets *parameters, int ga
}
}
parameters->Clear();
- if (actor) {
+ /*if (actor) {
ieWord tmp = actor->LastProtected;
Map *cm = Sender->GetCurrentArea();
int i = cm->GetActorCount(true);
@@ -262,6 +286,12 @@ Targets *GameScript::ProtectorOf(Scriptable *Sender, Targets *parameters, int ga
parameters->AddTarget(target, 0, ga_flags);
}
}
+ }*/
+ if (actor) {
+ Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastProtector);
+ if (target) {
+ parameters->AddTarget(target, 0, ga_flags);
+ }
}
return parameters;
}
@@ -276,7 +306,7 @@ Targets *GameScript::ProtectedBy(Scriptable *Sender, Targets *parameters, int ga
}
parameters->Clear();
if (actor) {
- Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastProtected);
+ Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastProtectee);
if (target) {
parameters->AddTarget(target, 0, ga_flags);
}
@@ -325,7 +355,7 @@ Targets *GameScript::LastAttackerOf(Scriptable *Sender, Targets *parameters, int
}
parameters->Clear();
if (actor) {
- Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastHitter);
+ Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastAttacker);
if (target) {
parameters->AddTarget(target, 0, ga_flags);
}
@@ -379,7 +409,7 @@ Targets *GameScript::LastTalkedToBy(Scriptable *Sender, Targets *parameters, int
}
parameters->Clear();
if (actor) {
- Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastTalkedTo);
+ Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastTalker);
if (target) {
parameters->AddTarget(target, 0, ga_flags);
}
@@ -517,76 +547,69 @@ Targets *GameScript::Player8Fill(Scriptable* /*Sender*/, Targets *parameters, in
return parameters;
}
-Targets *GameScript::BestAC(Scriptable* /*Sender*/, Targets *parameters, int ga_flags)
+//This filter works only on the Party - silly restriction, but the dataset expects this
+Targets *GameScript::StrongestOfMale(Scriptable* Sender, Targets *parameters, int ga_flags)
{
- targetlist::iterator m;
- const targettype *t = parameters->GetFirstTarget(m, ST_ACTOR);
- if (!t) {
- return parameters;
- }
- Scriptable *scr=t->actor;
- Actor *actor=(Actor *) scr;
- int bestac=actor->GetStat(IE_ARMORCLASS);
- // assignment in while
- while ( (t = parameters->GetNextTarget(m, ST_ACTOR) ) ) {
- actor = (Actor *) t->actor;
- int ac=actor->GetStat(IE_ARMORCLASS);
- if (bestac<ac) {
- bestac=ac;
- scr=t->actor;
+ Map* area = Sender->GetCurrentArea();
+ Game *game = core->GetGame();
+ Scriptable* scr = NULL;
+ int besthp = 0;
+ int i = game->GetPartySize(false);
+ while (i--) {
+ Actor *actor = game->GetPC(i, false);
+ if (actor->GetStat(IE_SEX)!=SEX_MALE) continue;
+ if(actor->GetCurrentArea() == area) {
+ int hp = actor->GetStat(IE_HITPOINTS);
+ if (!scr || besthp<hp) {
+ besthp=hp;
+ scr=actor;
+ }
}
}
-
parameters->Clear();
parameters->AddTarget(scr, 0, ga_flags);
return parameters;
}
-/*no idea why this object exists since the gender could be filtered easier*/
-Targets *GameScript::StrongestOfMale(Scriptable* /*Sender*/, Targets *parameters, int ga_flags)
+//This filter works only on the Party - silly restriction, but the dataset expects this
+Targets *GameScript::StrongestOf(Scriptable* Sender, Targets *parameters, int ga_flags)
{
- targetlist::iterator m;
- const targettype *t = parameters->GetFirstTarget(m, ST_ACTOR);
- if (!t) {
- return parameters;
- }
- int pos=-1;
- int worsthp=-1;
- Scriptable *scr = NULL;
- //assignment intentional
- while ( (t = parameters->GetNextTarget(m, ST_ACTOR) ) ) {
- Actor *actor = (Actor *) t->actor;
- if (actor->GetStat(IE_SEX)!=SEX_MALE) continue;
- int hp=actor->GetStat(IE_HITPOINTS);
- if ((pos==-1) || (worsthp<hp)) {
- worsthp=hp;
- scr=t->actor;
+ Map* area = Sender->GetCurrentArea();
+ Game *game = core->GetGame();
+ Scriptable* scr = NULL;
+ int besthp = 0;
+ int i = game->GetPartySize(false);
+ while (i--) {
+ Actor *actor = game->GetPC(i, false);
+ if(actor->GetCurrentArea() == area) {
+ int hp = actor->GetStat(IE_HITPOINTS);
+ if (!scr || besthp<hp) {
+ besthp=hp;
+ scr=actor;
+ }
}
}
parameters->Clear();
- if (scr) {
- parameters->AddTarget(scr, 0, ga_flags);
- }
+ parameters->AddTarget(scr, 0, ga_flags);
return parameters;
}
-Targets *GameScript::StrongestOf(Scriptable* /*Sender*/, Targets *parameters, int ga_flags)
+//This filter works only on the Party - silly restriction, but the dataset expects this
+Targets *GameScript::WeakestOf(Scriptable* Sender, Targets *parameters, int ga_flags)
{
- targetlist::iterator m;
- const targettype *t = parameters->GetFirstTarget(m, ST_ACTOR);
- if (!t) {
- return parameters;
- }
- Scriptable *scr=t->actor;
- Actor *actor=(Actor *) scr;
- int besthp=actor->GetStat(IE_HITPOINTS);
- // assignment in while
- while ( (t = parameters->GetNextTarget(m, ST_ACTOR) ) ) {
- actor = (Actor *) t->actor;
- int hp=actor->GetStat(IE_HITPOINTS);
- if (besthp<hp) {
- besthp=hp;
- scr=t->actor;
+ Map* area = Sender->GetCurrentArea();
+ Game *game = core->GetGame();
+ Scriptable* scr = NULL;
+ int worsthp = 0;
+ int i = game->GetPartySize(false);
+ while (i--) {
+ Actor *actor = game->GetPC(i, false);
+ if(actor->GetCurrentArea() == area) {
+ int hp = actor->GetStat(IE_HITPOINTS);
+ if (!scr || worsthp>hp) {
+ worsthp=hp;
+ scr=actor;
+ }
}
}
parameters->Clear();
@@ -594,23 +617,22 @@ Targets *GameScript::StrongestOf(Scriptable* /*Sender*/, Targets *parameters, in
return parameters;
}
-Targets *GameScript::WeakestOf(Scriptable* /*Sender*/, Targets *parameters, int ga_flags)
+//This filter works only on the Party - silly restriction, but the dataset expects this
+Targets *GameScript::BestAC(Scriptable* Sender, Targets *parameters, int ga_flags)
{
- targetlist::iterator m;
- const targettype *t = parameters->GetFirstTarget(m, ST_ACTOR);
- if (!t) {
- return parameters;
- }
- Scriptable *scr=t->actor;
- Actor *actor=(Actor *) scr;
- int worsthp=actor->GetStat(IE_HITPOINTS);
- // assignment in while
- while ( (t = parameters->GetNextTarget(m, ST_ACTOR) ) ) {
- actor = (Actor *) t->actor;
- int hp=actor->GetStat(IE_HITPOINTS);
- if (worsthp>hp) {
- worsthp=hp;
- scr=t->actor;
+ Map* area = Sender->GetCurrentArea();
+ Game *game = core->GetGame();
+ Scriptable* scr = NULL;
+ int bestac = 0;
+ int i = game->GetPartySize(false);
+ while (i--) {
+ Actor *actor = game->GetPC(i, false);
+ if(actor->GetCurrentArea() == area) {
+ int ac = actor->AC.GetTotal();
+ if (!scr || bestac>ac) {
+ bestac=ac;
+ scr=actor;
+ }
}
}
parameters->Clear();
@@ -618,23 +640,22 @@ Targets *GameScript::WeakestOf(Scriptable* /*Sender*/, Targets *parameters, int
return parameters;
}
-Targets *GameScript::WorstAC(Scriptable* /*Sender*/, Targets *parameters, int ga_flags)
+//This filter works only on the Party - silly restriction, but the dataset expects this
+Targets *GameScript::WorstAC(Scriptable* Sender, Targets *parameters, int ga_flags)
{
- targetlist::iterator m;
- const targettype *t = parameters->GetFirstTarget(m, ST_ACTOR);
- if (!t) {
- return parameters;
- }
- Scriptable *scr=t->actor;
- Actor *actor=(Actor *) scr;
- int worstac=actor->GetStat(IE_ARMORCLASS);
- // assignment in while
- while ( (t = parameters->GetNextTarget(m, ST_ACTOR) ) ) {
- actor = (Actor *) t->actor;
- int ac=actor->GetStat(IE_ARMORCLASS);
- if (worstac>ac) {
- worstac=ac;
- scr=t->actor;
+ Map* area = Sender->GetCurrentArea();
+ Game *game = core->GetGame();
+ Scriptable* scr = NULL;
+ int worstac = 0;
+ int i = game->GetPartySize(false);
+ while (i--) {
+ Actor *actor = game->GetPC(i, false);
+ if(actor->GetCurrentArea() == area) {
+ int ac = actor->AC.GetTotal();
+ if (!scr || worstac<ac) {
+ worstac=ac;
+ scr=actor;
+ }
}
}
parameters->Clear();
@@ -642,39 +663,19 @@ Targets *GameScript::WorstAC(Scriptable* /*Sender*/, Targets *parameters, int ga
return parameters;
}
+//This filter works only on the Party - silly restriction, but the dataset expects this
Targets *GameScript::MostDamagedOf(Scriptable* Sender, Targets *parameters, int ga_flags)
{
- //Original engines restrict this to the PCs...
- /*targetlist::iterator m;
- const targettype *t = parameters->GetFirstTarget(m, ST_ACTOR);
- if (!t) {
- return parameters;
- }
- Scriptable *scr = t->actor;
- Actor *actor=(Actor *) scr;
- int worsthp=actor->GetStat(IE_MAXHITPOINTS)-actor->GetBase(IE_HITPOINTS);
- // assignment in while
- while ( (t = parameters->GetNextTarget(m, ST_ACTOR) ) ) {
- actor = (Actor *) t->actor;
- int hp=actor->GetStat(IE_MAXHITPOINTS)-actor->GetBase(IE_HITPOINTS);
- if (worsthp>hp) {
- worsthp=hp;
- scr=t->actor;
- }
- }
- parameters->Clear();
- parameters->AddTarget(scr, 0, ga_flags);
- return parameters;*/
- Map* area = Sender->GetCurrentArea() ;
+ Map* area = Sender->GetCurrentArea();
Game *game = core->GetGame();
- Scriptable* scr = NULL ;
- int worsthp = 0xffff ;
+ Scriptable* scr = NULL;
+ int worsthp = 0;
int i = game->GetPartySize(false);
while (i--) {
Actor *actor = game->GetPC(i, false);
if(actor->GetCurrentArea() == area) {
int hp=actor->GetStat(IE_MAXHITPOINTS)-actor->GetBase(IE_HITPOINTS);
- if (worsthp>hp) {
+ if (!scr || hp>worsthp) {
worsthp=hp;
scr=actor;
}
@@ -684,23 +685,24 @@ Targets *GameScript::MostDamagedOf(Scriptable* Sender, Targets *parameters, int
parameters->AddTarget(scr, 0, ga_flags);
return parameters;
}
-Targets *GameScript::LeastDamagedOf(Scriptable* /*Sender*/, Targets *parameters, int ga_flags)
+
+//This filter works only on the Party - silly restriction, but the dataset expects this
+//For example the beholder01 script
+Targets *GameScript::LeastDamagedOf(Scriptable* Sender, Targets *parameters, int ga_flags)
{
- targetlist::iterator m;
- const targettype *t = parameters->GetFirstTarget(m, ST_ACTOR);
- if (!t) {
- return parameters;
- }
- Scriptable *scr = t->actor;
- Actor *actor = (Actor *) scr;
- int besthp=actor->GetStat(IE_MAXHITPOINTS)-actor->GetBase(IE_HITPOINTS);
- // assignment in while
- while ( (t = parameters->GetNextTarget(m, ST_ACTOR) ) ) {
- actor = (Actor *) t->actor;
- int hp=actor->GetStat(IE_MAXHITPOINTS)-actor->GetBase(IE_HITPOINTS);
- if (besthp<hp) {
- besthp=hp;
- scr=t->actor;
+ Map* area = Sender->GetCurrentArea();
+ Game *game = core->GetGame();
+ Scriptable* scr = NULL;
+ int besthp = 0;
+ int i = game->GetPartySize(false);
+ while (i--) {
+ Actor *actor = game->GetPC(i, false);
+ if(actor->GetCurrentArea() == area) {
+ int hp=actor->GetStat(IE_MAXHITPOINTS)-actor->GetBase(IE_HITPOINTS);
+ if (!scr || besthp<hp) {
+ besthp=hp;
+ scr=actor;
+ }
}
}
parameters->Clear();
@@ -1054,16 +1056,34 @@ inline bool idclass(Actor *actor, int parameter, bool iwd2) {
classes = all_bg_classes;
}
+ // FIXME: unhardcode this ugly mess
+ // in IWD2, mage_all = sorcerer or wizard
+ // fighter_all = fighter, paladin or ranger (but not monk)
+ // cleric_all = druid or cleric
+ // thief_all = thief
+ // bard_all = bard
+ // paladin_all = paladin
+ // druid_all = druid
+ // ranger_all = ranger
+
// we got one of the *_ALL values
if (parameter == classes[4]) {
// MAGE_ALL (also sorcerers)
value = actor->GetMageLevel() + actor->GetSorcererLevel();
} else if (parameter == classes[3]) {
// FIGHTER_ALL (also monks)
- value = actor->GetFighterLevel() + actor->GetMonkLevel();
+ if (iwd2) {
+ value = actor->GetFighterLevel() + actor->GetPaladinLevel() + actor->GetRangerLevel();
+ } else {
+ value = actor->GetFighterLevel() + actor->GetMonkLevel();
+ }
} else if (parameter == classes[1]) {
// CLERIC_ALL
- value = actor->GetClericLevel();
+ if (iwd2) {
+ value = actor->GetClericLevel() + actor->GetDruidLevel();
+ } else {
+ value = actor->GetClericLevel();
+ }
} else if (parameter == classes[7]) {
// THIEF_ALL
value = actor->GetThiefLevel();
@@ -1156,3 +1176,5 @@ int GameScript::ID_Specific(Actor *actor, int parameter)
int value = actor->GetStat(IE_SPECIFIC);
return parameter==value;
}
+
+}
diff --git a/gemrb/core/GameScript/Triggers.cpp b/gemrb/core/GameScript/Triggers.cpp
index da8f35e..0e4d620 100644
--- a/gemrb/core/GameScript/Triggers.cpp
+++ b/gemrb/core/GameScript/Triggers.cpp
@@ -25,10 +25,13 @@
#include "win32def.h"
+#include "AmbientMgr.h"
#include "Calendar.h"
#include "DialogHandler.h"
#include "Game.h"
#include "GameData.h"
+#include "Polygon.h"
+#include "TableMgr.h"
#include "Video.h"
#include "GUI/GameControl.h"
#include "math.h" //needs for acos
@@ -36,6 +39,8 @@
#include "Scriptable/Door.h"
#include "Scriptable/InfoPoint.h"
+namespace GemRB {
+
//-------------------------------------------------------------
// Trigger Functions
//-------------------------------------------------------------
@@ -49,7 +54,7 @@ int GameScript::Reaction(Scriptable* Sender, Trigger* parameters)
{
Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
if (!scr || scr->Type != ST_ACTOR) {
- parameters->Dump();
+ parameters->dump();
return 0;
}
int value = GetReaction(((Actor*) scr), Sender);
@@ -60,7 +65,7 @@ int GameScript::ReactionGT(Scriptable* Sender, Trigger* parameters)
{
Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
if (!scr || scr->Type != ST_ACTOR) {
- parameters->Dump();
+ parameters->dump();
return 0;
}
int value = GetReaction(((Actor*) scr), Sender);
@@ -71,7 +76,7 @@ int GameScript::ReactionLT(Scriptable* Sender, Trigger* parameters)
{
Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
if (!scr || scr->Type != ST_ACTOR) {
- parameters->Dump();
+ parameters->dump();
return 0;
}
int value = GetReaction(((Actor*) scr), Sender);
@@ -253,22 +258,15 @@ int GameScript::IsValidForPartyDialog(Scriptable* Sender, Trigger* parameters)
int GameScript::InParty(Scriptable* Sender, Trigger* parameters)
{
- Scriptable* scr;
+ int ret = InPartyAllowDead(Sender, parameters);
- if (parameters->objectParameter) {
- scr = GetActorFromObject( Sender, parameters->objectParameter );
- } else {
- scr = Sender;
- }
- if (!scr || scr->Type != ST_ACTOR) {
- return 0;
- }
- Actor *tar = (Actor *) scr;
- if (core->GetGame()->InParty( tar ) <0) {
- return 0;
+ if (!ret || core->HasFeature(GF_IN_PARTY_ALLOWS_DEAD)) {
+ return ret;
}
+
+ Actor *tar = (Actor *) Sender;
//don't allow dead, don't allow maze and similar effects
- if (tar->ValidTarget(GA_NO_DEAD|GA_NO_HIDDEN)) {
+ if (tar->ValidTarget(GA_NO_DEAD) && tar->GetStat(IE_AVATARREMOVAL) == 0) {
return 1;
}
return 0;
@@ -324,14 +322,36 @@ int GameScript::IsGabber(Scriptable* Sender, Trigger* parameters)
return 0;
}
+//returns true if the trap or infopoint is active
+//returns true if the actor is active
+//returns true if the sound source is active
+//returns true if container is active
int GameScript::IsActive(Scriptable* Sender, Trigger* parameters)
{
Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
if (!scr) {
+ AmbientMgr * ambientmgr = core->GetAudioDrv()->GetAmbientMgr();
+ if (ambientmgr->isActive(parameters->objectParameter->objectName) ) {
+ return 1;
+ }
return 0;
}
- if (scr->GetInternalFlag()&IF_ACTIVE) {
- return 1;
+
+ switch(scr->Type) {
+ default:
+ return 0;
+ case ST_ACTOR:
+ if( ((Actor *) scr)->Schedule(core->GetGame()->GameTime, true)) return 1;
+ return 0;
+ case ST_CONTAINER:
+ if ( ((Container *) scr)->Flags&CONT_DISABLED) return 0;
+ return 1;
+
+ case ST_PROXIMITY: case ST_TRIGGER: case ST_TRAVEL:
+ if ( ((InfoPoint *) scr)->Flags&(TRAP_DEACTIVATED|INFO_DOOR) ) {
+ return 0;
+ }
+ return 1;
}
return 0;
}
@@ -349,8 +369,8 @@ int GameScript::InTrap(Scriptable* Sender, Trigger* parameters)
}
/* checks if targeted actor is in the specified region
- GemRB allows different regions, referenced by int0Parameter
- The polygons are stored in island<nn>.2da files */
+ GemRB allows different regions, referenced by int0Parameter
+ The polygons are stored in island<nn>.2da files */
int GameScript::OnIsland(Scriptable* Sender, Trigger* parameters)
{
Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
@@ -778,13 +798,13 @@ int GameScript::GlobalTimerExpired(Scriptable* Sender, Trigger* parameters)
bool valid=true;
ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, parameters->string1Parameter, &valid );
- if (valid && value1) {
+ if (valid && (core->HasFeature(GF_ZERO_TIMER_IS_VALID) || value1)) {
if ( value1 < core->GetGame()->GameTime ) return 1;
}
return 0;
}
-//globaltimernotexpired returns false if the timer doesn't exist
+//globaltimernotexpired returns false if the timer doesn't exist or is zero
int GameScript::GlobalTimerNotExpired(Scriptable* Sender, Trigger* parameters)
{
bool valid=true;
@@ -797,36 +817,56 @@ int GameScript::GlobalTimerNotExpired(Scriptable* Sender, Trigger* parameters)
}
//globaltimerstarted returns false if the timer doesn't exist
-//is it the same as globaltimernotexpired?
int GameScript::GlobalTimerStarted(Scriptable* Sender, Trigger* parameters)
{
- bool valid=true;
-
- ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, parameters->string1Parameter, &valid );
- if (valid && value1) {
- if ( value1 > core->GetGame()->GameTime ) return 1;
+ bool valid = VariableExists(Sender, parameters->string0Parameter, parameters->string1Parameter);
+ if (valid) {
+ return 1;
}
return 0;
}
int GameScript::WasInDialog(Scriptable* Sender, Trigger* /*parameters*/)
{
- if (Sender->GetInternalFlag()&IF_WASINDIALOG) {
- Sender->SetBitTrigger(BT_WASINDIALOG);
- return 1;
- }
- return 0;
+ return Sender->MatchTrigger(trigger_wasindialog);
}
int GameScript::OnCreation(Scriptable* Sender, Trigger* /*parameters*/)
{
- if (Sender->GetInternalFlag()&IF_ONCREATION) {
- Sender->SetBitTrigger(BT_ONCREATION);
- return 1;
- }
+ return Sender->MatchTrigger(trigger_oncreation);
+}
+
+int GameScript::SummoningLimit(Scriptable* Sender, Trigger* parameters)
+{
+ Map *map = Sender->GetCurrentArea();
+ if (!map) return 0;
+
+ int sl = map->CountSummons(GA_NO_DEAD, SEX_SUMMON);
+ if (sl == parameters->int0Parameter) return 1;
+ return 0;
+}
+
+int GameScript::SummoningLimitGT(Scriptable* Sender, Trigger* parameters)
+{
+ Map *map = Sender->GetCurrentArea();
+ if (!map) return 0;
+
+ int sl = map->CountSummons(GA_NO_DEAD, SEX_SUMMON);
+ if (sl > parameters->int0Parameter) return 1;
return 0;
}
+int GameScript::SummoningLimitLT(Scriptable* Sender, Trigger* parameters)
+{
+ Map *map = Sender->GetCurrentArea();
+ if (!map) return 0;
+
+ int sl = map->CountSummons(GA_NO_DEAD, SEX_SUMMON);
+ if (sl < parameters->int0Parameter) return 1;
+ return 0;
+}
+
+
int GameScript::NumItemsParty(Scriptable* /*Sender*/, Trigger* parameters)
{
int cnt = 0;
@@ -1054,6 +1094,12 @@ int GameScript::HasItem(Scriptable* Sender, Trigger* parameters)
int GameScript::ItemIsIdentified(Scriptable* Sender, Trigger* parameters)
{
+ // hardcode the Nothing filtering exception (needed for most iwd2 dialog uses)
+ bool nothing = parameters->objectParameter[0].objectFilters[0] == 255;
+ if (nothing) {
+ // reset the filter to 19 LastTalkedToBy
+ parameters->objectParameter[0].objectFilters[0] = 19;
+ }
Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
if ( !scr || scr->Type!=ST_ACTOR) {
return 0;
@@ -1133,7 +1179,7 @@ int GameScript::Acquired(Scriptable * Sender, Trigger* parameters)
}
/** this trigger accepts a numeric parameter, this number is the same as inventory flags
- like: 1 - identified, 2 - unstealable, 4 - stolen, 8 - undroppable, etc. */
+ like: 1 - identified, 2 - unstealable, 4 - stolen, 8 - undroppable, etc. */
/** this is a GemRB extension */
int GameScript::PartyHasItem(Scriptable * /*Sender*/, Trigger* parameters)
{
@@ -1446,6 +1492,9 @@ int GameScript::Range(Scriptable* Sender, Trigger* parameters)
if (!scr) {
return 0;
}
+ if (Sender->GetCurrentArea() != scr->GetCurrentArea()) {
+ return 0;
+ }
int distance = SquaredMapDistance(Sender, scr);
return DiffCore(distance, (parameters->int0Parameter+1)*(parameters->int0Parameter+1), parameters->int1Parameter);
}
@@ -1466,7 +1515,7 @@ int GameScript::InLine(Scriptable* Sender, Trigger* parameters)
Scriptable* scr2 = map->GetActor( parameters->string0Parameter, 0 );
if (!scr2) {
scr2 = GetActorObject(map->GetTileMap(), parameters->string0Parameter);
- }
+ }
if (!scr2) {
return 0;
}
@@ -1549,319 +1598,86 @@ int GameScript::Or(Scriptable* /*Sender*/, Trigger* parameters)
int GameScript::TriggerTrigger(Scriptable* Sender, Trigger* parameters)
{
- if(Sender->TriggerID==(ieDword) parameters->int0Parameter) {
- Sender->AddTrigger (&Sender->TriggerID);
- return 1;
- }
- return 0;
+ return Sender->MatchTrigger(trigger_trigger, parameters->int0Parameter);
}
int GameScript::WalkedToTrigger(Scriptable* Sender, Trigger* parameters)
{
- Actor *target = Sender->GetCurrentArea()->GetActorByGlobalID(Sender->LastTrigger);
- if (!target) {
- return 0;
- }
- if (PersonalDistance(target, Sender) > 3*MAX_OPERATING_DISTANCE ) {
- return 0;
- }
- //now objects suicide themselves if they are empty objects
- //so checking an empty object is easier
- if (parameters->objectParameter == NULL) {
- Sender->AddTrigger (&Sender->LastTrigger);
- return 1;
- }
- if (MatchActor(Sender, Sender->LastTrigger, parameters->objectParameter)) {
- Sender->AddTrigger (&Sender->LastTrigger);
- return 1;
- }
- return 0;
+ return Sender->MatchTriggerWithObject(trigger_walkedtotrigger, parameters->objectParameter);
}
int GameScript::Clicked(Scriptable* Sender, Trigger* parameters)
{
- //now objects suicide themselves if they are empty objects
- //so checking an empty object is easier
- if (parameters->objectParameter == NULL) {
- if (Sender->LastTrigger) {
- Sender->AddTrigger (&Sender->LastTrigger);
- return 1;
- }
- return 0;
- }
- if (MatchActor(Sender, Sender->LastTrigger, parameters->objectParameter)) {
- Sender->AddTrigger (&Sender->LastTrigger);
- return 1;
- }
- return 0;
+ return Sender->MatchTriggerWithObject(trigger_clicked, parameters->objectParameter);
}
int GameScript::Disarmed(Scriptable* Sender, Trigger* parameters)
{
- switch(Sender->Type) {
- case ST_DOOR: case ST_CONTAINER: case ST_PROXIMITY:
- break;
- default:
- return 0;
- }
- if (parameters->objectParameter == NULL) {
- if (Sender->LastDisarmed) {
- Sender->AddTrigger (&Sender->LastDisarmed);
- return 1;
- }
- return 0;
- }
- if (MatchActor(Sender, Sender->LastDisarmed, parameters->objectParameter)) {
- Sender->AddTrigger (&Sender->LastDisarmed);
- return 1;
- }
- return 0;
+ return Sender->MatchTriggerWithObject(trigger_disarmed, parameters->objectParameter);
}
//stealing from a store failed, owner triggered
int GameScript::StealFailed(Scriptable* Sender, Trigger* parameters)
{
- switch(Sender->Type) {
- case ST_ACTOR:
- break;
- default:
- return 0;
- }
- // maybe check if Sender is a shopkeeper???
-
- if (parameters->objectParameter == NULL) {
- if (Sender->LastDisarmFailed) {
- Sender->AddTrigger (&Sender->LastDisarmFailed);
- return 1;
- }
- return 0;
- }
- if (MatchActor(Sender, Sender->LastDisarmFailed, parameters->objectParameter)) {
- Sender->AddTrigger (&Sender->LastDisarmFailed);
- return 1;
- }
- return 0;
+ return Sender->MatchTriggerWithObject(trigger_disarmfailed, parameters->objectParameter);
}
int GameScript::PickpocketFailed(Scriptable* Sender, Trigger* parameters)
{
- switch(Sender->Type) {
- case ST_ACTOR:
- break;
- default:
- return 0;
- }
- if (parameters->objectParameter == NULL) {
- if (Sender->LastOpenFailed) {
- Sender->AddTrigger (&Sender->LastOpenFailed);
- return 1;
- }
- return 0;
- }
- if (MatchActor(Sender, Sender->LastOpenFailed, parameters->objectParameter)) {
- Sender->AddTrigger (&Sender->LastOpenFailed);
- return 1;
- }
- return 0;
+ return Sender->MatchTriggerWithObject(trigger_pickpocketfailed, parameters->objectParameter);
}
int GameScript::PickLockFailed(Scriptable* Sender, Trigger* parameters)
{
- switch(Sender->Type) {
- case ST_DOOR: case ST_CONTAINER:
- break;
- default:
- return 0;
- }
- if (parameters->objectParameter == NULL) {
- if (Sender->LastPickLockFailed) {
- Sender->AddTrigger (&Sender->LastPickLockFailed);
- return 1;
- }
- return 0;
- }
- if (MatchActor(Sender, Sender->LastPickLockFailed, parameters->objectParameter)) {
- Sender->AddTrigger (&Sender->LastPickLockFailed);
- return 1;
- }
- return 0;
+ return Sender->MatchTriggerWithObject(trigger_picklockfailed, parameters->objectParameter);
}
int GameScript::OpenFailed(Scriptable* Sender, Trigger* parameters)
{
- switch(Sender->Type) {
- case ST_DOOR: case ST_CONTAINER:
- break;
- default:
- return 0;
- }
- if (parameters->objectParameter == NULL) {
- if (Sender->LastOpenFailed) {
- Sender->AddTrigger (&Sender->LastOpenFailed);
- return 1;
- }
- return 0;
- }
- if (MatchActor(Sender, Sender->LastOpenFailed, parameters->objectParameter
-)) {
- Sender->AddTrigger (&Sender->LastOpenFailed);
- return 1;
- }
- return 0;
+ return Sender->MatchTriggerWithObject(trigger_failedtoopen, parameters->objectParameter);
}
int GameScript::DisarmFailed(Scriptable* Sender, Trigger* parameters)
{
- switch(Sender->Type) {
- case ST_DOOR: case ST_CONTAINER: case ST_PROXIMITY:
- break;
- default:
- return 0;
- }
- if (parameters->objectParameter == NULL) {
- if (Sender->LastDisarmFailed) {
- Sender->AddTrigger (&Sender->LastDisarmFailed);
- return 1;
- }
- return 0;
- }
- if (MatchActor(Sender, Sender->LastDisarmFailed, parameters->objectParameter)) {
- Sender->AddTrigger (&Sender->LastDisarmFailed);
- return 1;
- }
- return 0;
+ return Sender->MatchTriggerWithObject(trigger_disarmfailed, parameters->objectParameter);
}
-//opened for doors/containers (using lastEntered)
+//opened for doors/containers
int GameScript::Opened(Scriptable* Sender, Trigger* parameters)
{
- Door *door;
-
- switch (Sender->Type) {
- case ST_DOOR:
- door = (Door *) Sender;
- if (!door->IsOpen()) {
- return 0;
- }
- break;
- case ST_CONTAINER:
- break;
- default:
- return 0;
- }
+ return Sender->MatchTriggerWithObject(trigger_opened, parameters->objectParameter);
+}
- if (parameters->objectParameter == NULL) {
- if (Sender->LastEntered) {
- Sender->AddTrigger (&Sender->LastEntered);
- return 1;
- }
- return 0;
- }
- if (MatchActor(Sender, Sender->LastEntered, parameters->objectParameter)) {
- Sender->AddTrigger (&Sender->LastEntered);
- return 1;
- }
- return 0;
+int GameScript::HarmlessOpened(Scriptable* Sender, Trigger* parameters)
+{
+ return Sender->MatchTriggerWithObject(trigger_harmlessopened, parameters->objectParameter);
}
-//closed for doors (using lastTrigger)
+//closed for doors
int GameScript::Closed(Scriptable* Sender, Trigger* parameters)
{
- if (Sender->Type != ST_DOOR) {
- return 0;
- }
- Door *door = (Door *) Sender;
- if (door->IsOpen()) {
- return 0;
- }
+ return Sender->MatchTriggerWithObject(trigger_closed, parameters->objectParameter);
+}
- if (parameters->objectParameter == NULL) {
- if (Sender->LastTrigger) {
- Sender->AddTrigger (&Sender->LastTrigger);
- return 1;
- }
- return 0;
- }
- if (MatchActor(Sender, Sender->LastTrigger, parameters->objectParameter)) {
- Sender->AddTrigger (&Sender->LastTrigger);
- return 1;
- }
- return 0;
+int GameScript::HarmlessClosed(Scriptable* Sender, Trigger* parameters)
+{
+ return Sender->MatchTriggerWithObject(trigger_harmlessclosed, parameters->objectParameter);
}
//unlocked for doors/containers (using lastUnlocked)
int GameScript::Unlocked(Scriptable* Sender, Trigger* parameters)
{
- Door *door;
-
- switch (Sender->Type) {
- case ST_DOOR:
- door = (Door *) Sender;
- if ((door->Flags&DOOR_LOCKED) ) {
- return 0;
- }
- break;
- case ST_CONTAINER:
- break;
- default:
- return 0;
- }
-
- if (parameters->objectParameter == NULL) {
- if (Sender->LastUnlocked) {
- Sender->AddTrigger (&Sender->LastUnlocked);
- return 1;
- }
- return 0;
- }
- if (MatchActor(Sender, Sender->LastUnlocked, parameters->objectParameter)) {
- Sender->AddTrigger (&Sender->LastUnlocked);
- return 1;
- }
- return 0;
+ return Sender->MatchTriggerWithObject(trigger_unlocked, parameters->objectParameter);
}
int GameScript::Entered(Scriptable* Sender, Trigger* parameters)
{
- if (Sender->Type != ST_PROXIMITY) {
- return 0;
- }
- InfoPoint *ip = (InfoPoint *) Sender;
- if (!ip->Trapped) {
- return 0;
- }
-
- if (parameters->objectParameter == NULL) {
- if (Sender->LastEntered) {
- Sender->AddTrigger (&Sender->LastEntered);
- return 1;
- }
- return 0;
- }
- if (MatchActor(Sender, Sender->LastEntered, parameters->objectParameter)) {
- Sender->AddTrigger (&Sender->LastEntered);
- return 1;
- }
- return 0;
+ return Sender->MatchTriggerWithObject(trigger_entered, parameters->objectParameter);
}
int GameScript::HarmlessEntered(Scriptable* Sender, Trigger* parameters)
{
- if (Sender->Type != ST_PROXIMITY) {
- return 0;
- }
- if (parameters->objectParameter == NULL) {
- if (Sender->LastEntered) {
- Sender->AddTrigger (&Sender->LastEntered);
- return 1;
- }
- return 0;
- }
- if (MatchActor(Sender, Sender->LastEntered, parameters->objectParameter)) {
- Sender->AddTrigger (&Sender->LastEntered);
- return 1;
- }
- return 0;
+ return Sender->MatchTriggerWithObject(trigger_harmlessentered, parameters->objectParameter);
}
int GameScript::IsOverMe(Scriptable* Sender, Trigger* parameters)
@@ -1896,14 +1712,15 @@ int GameScript::Dead(Scriptable* Sender, Trigger* parameters)
{
if (parameters->string0Parameter[0]) {
ieDword value;
- ieVariable Variable;
if (core->HasFeature( GF_HAS_KAPUTZ )) {
value = CheckVariable( Sender, parameters->string0Parameter, "KAPUTZ");
} else {
+ ieVariable Variable;
+
snprintf( Variable, 32, core->GetDeathVarFormat(), parameters->string0Parameter );
+ value = CheckVariable( Sender, Variable, "GLOBAL" );
}
- value = CheckVariable( Sender, Variable, "GLOBAL" );
if (value>0) {
return 1;
}
@@ -1944,68 +1761,32 @@ int GameScript::CreatureHidden(Scriptable* Sender, Trigger* /*parameters*/)
}
int GameScript::BecameVisible(Scriptable* Sender, Trigger* /*parameters*/)
{
- if (Sender->Type!=ST_ACTOR) {
- return 0;
- }
- Actor *act=(Actor *) Sender;
- if (act->GetInternalFlag()&IF_BECAMEVISIBLE) {
- //set trigger to erase
- act->SetBitTrigger(BT_BECAMEVISIBLE);
- return 1;
- }
- return 0;
+ return Sender->MatchTrigger(trigger_becamevisible);
}
int GameScript::Die(Scriptable* Sender, Trigger* /*parameters*/)
{
- if (Sender->Type!=ST_ACTOR) {
- return 0;
- }
- Actor *act=(Actor *) Sender;
- if (act->GetInternalFlag()&IF_JUSTDIED) {
- //set trigger to erase
- act->SetBitTrigger(BT_DIE);
- return 1;
- }
- return 0;
+ return Sender->MatchTrigger(trigger_die);
}
int GameScript::Died(Scriptable* Sender, Trigger* parameters)
{
- Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
- if (!tar || tar->Type!=ST_ACTOR) {
- return 0;
- }
- Actor *act=(Actor *) tar;
- if (act->GetInternalFlag()&IF_JUSTDIED) {
- //set trigger to erase
- act->SetBitTrigger(BT_DIE);
- return 1;
- }
- return 0;
+ return Sender->MatchTriggerWithObject(trigger_died, parameters->objectParameter);
}
-int GameScript::PartyMemberDied(Scriptable* /*Sender*/, Trigger* /*parameters*/)
+int GameScript::PartyMemberDied(Scriptable* Sender, Trigger* parameters)
{
- Game *game = core->GetGame();
- int i = game->PartyMemberDied();
- if (i==-1) {
- return 0;
- }
- //set trigger to erase
- game->GetPC(i,false)->SetBitTrigger(BT_DIE);
- return 1;
+ return Sender->MatchTriggerWithObject(trigger_partymemberdied, parameters->objectParameter);
}
-int GameScript::NamelessBitTheDust(Scriptable* /*Sender*/, Trigger* /*parameters*/)
+int GameScript::NamelessBitTheDust(Scriptable* Sender, Trigger* /*parameters*/)
{
- Actor* actor = core->GetGame()->GetPC(0, false);
- if (actor->GetInternalFlag()&IF_JUSTDIED) {
- //set trigger to clear
- actor->SetBitTrigger(BT_DIE);
- return 1;
- }
- return 0;
+ return Sender->MatchTrigger(trigger_namelessbitthedust);
+}
+
+int GameScript::Killed(Scriptable* Sender, Trigger* parameters)
+{
+ return Sender->MatchTriggerWithObject(trigger_killed, parameters->objectParameter);
}
int GameScript::Race(Scriptable* Sender, Trigger* parameters)
@@ -2083,14 +1864,14 @@ int GameScript::HPLT(Scriptable* Sender, Trigger* parameters)
}
//these triggers work on the current damage (not the last damage)
-/* they are identical to HPLost
+//actually, they use lastdamage
int GameScript::DamageTaken(Scriptable* Sender, Trigger* parameters)
{
if (Sender->Type!=ST_ACTOR) {
return 0;
}
Actor* actor = ( Actor* ) Sender;
- int damage = actor->GetStat(IE_MAXHITPOINTS)-actor->GetBase(IE_HITPOINTS);
+ int damage = actor->LastDamage;
if (damage==(int) parameters->int0Parameter) {
return 1;
}
@@ -2103,7 +1884,7 @@ int GameScript::DamageTakenGT(Scriptable* Sender, Trigger* parameters)
return 0;
}
Actor* actor = ( Actor* ) Sender;
- int damage = actor->GetStat(IE_MAXHITPOINTS)-actor->GetBase(IE_HITPOINTS);
+ int damage = actor->LastDamage;
if (damage>(int) parameters->int0Parameter) {
return 1;
}
@@ -2116,13 +1897,12 @@ int GameScript::DamageTakenLT(Scriptable* Sender, Trigger* parameters)
return 0;
}
Actor* actor = ( Actor* ) Sender;
- int damage = actor->GetStat(IE_MAXHITPOINTS)-actor->GetBase(IE_HITPOINTS);
+ int damage = actor->LastDamage;
if (damage<(int) parameters->int0Parameter) {
return 1;
}
return 0;
}
-*/
int GameScript::HPLost(Scriptable* Sender, Trigger* parameters)
{
@@ -2365,6 +2145,25 @@ int GameScript::SetLastMarkedObject(Scriptable* Sender, Trigger* parameters)
return 1;
}
+// TODO: should there be any more failure modes?
+int GameScript::SetSpellTarget(Scriptable* Sender, Trigger* parameters)
+{
+ if (Sender->Type != ST_ACTOR) {
+ return 0;
+ }
+ Actor *scr = (Actor *) Sender;
+
+ Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
+ if (!tar) {
+ // we got called with Nothing to invalidate the target
+ scr->LastTarget = 0;
+ scr->LastTargetPos.empty();
+ return 1;
+ }
+ scr->LastTarget = tar->GetGlobalID();
+ return 1;
+}
+
int GameScript::IsSpellTargetValid(Scriptable* Sender, Trigger* parameters)
{
if (Sender->Type != ST_ACTOR) {
@@ -2450,6 +2249,7 @@ int GameScript::See(Scriptable* Sender, Trigger* parameters)
if (Sender->Type==ST_ACTOR && see) {
Actor *act = (Actor *) Sender;
//save lastseen as lastmarked
+ //FIXME: what is this doing?
act->LastMarked = act->LastSeen;
//Sender->AddTrigger (&act->LastSeen);
}
@@ -2697,9 +2497,9 @@ int GameScript::OpenState(Scriptable* Sender, Trigger* parameters)
Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
if (!tar) {
if (InDebug&ID_TRIGGERS) {
- printMessage("GameScript"," ",LIGHT_RED);
- printf("Couldn't find door/container:%s\n", parameters->objectParameter? parameters->objectParameter->objectName:"<NULL>");
- printf("Sender: %s\n", Sender->GetScriptName() );
+ Log(ERROR, "GameScript", "Couldn't find door/container:%s",
+ parameters->objectParameter? parameters->objectParameter->objectName:"<NULL>");
+ print("Sender: %s", Sender->GetScriptName());
}
return 0;
}
@@ -2716,8 +2516,8 @@ int GameScript::OpenState(Scriptable* Sender, Trigger* parameters)
}
default:; //to remove a warning
}
- printMessage("GameScript"," ",LIGHT_RED);
- printf("Not a door/container:%s\n", tar->GetScriptName());
+ Log(ERROR, "GameScript", "Not a door/container:%s",
+ tar->GetScriptName());
return 0;
}
@@ -2725,9 +2525,9 @@ int GameScript::IsLocked(Scriptable * Sender, Trigger *parameters)
{
Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
if (!tar) {
- printMessage("GameScript"," ",LIGHT_RED);
- printf("Couldn't find door/container:%s\n", parameters->objectParameter? parameters->objectParameter->objectName:"<NULL>");
- printf("Sender: %s\n", Sender->GetScriptName() );
+ Log(ERROR, "GameScript", "Couldn't find door/container:%s",
+ parameters->objectParameter? parameters->objectParameter->objectName:"<NULL>");
+ print("Sender: %s", Sender->GetScriptName());
return 0;
}
switch(tar->Type) {
@@ -2743,8 +2543,8 @@ int GameScript::IsLocked(Scriptable * Sender, Trigger *parameters)
}
default:; //to remove a warning
}
- printMessage("GameScript"," ",LIGHT_RED);
- printf("Not a door/container:%s\n", tar->GetScriptName());
+ Log(ERROR, "GameScript", "Not a door/container:%s",
+ tar->GetScriptName());
return 0;
}
@@ -2773,15 +2573,11 @@ int GameScript::ClassLevel(Scriptable* Sender, Trigger* parameters)
return 0;
}
Actor* actor = ( Actor* ) tar;
-
- if (!ID_Class( actor, parameters->int0Parameter) )
- return 0;
- // FIXME: compare the requested level
- return actor->GetStat(IE_LEVEL) == (unsigned) parameters->int1Parameter;
+ return actor->GetLevelInClass(parameters->int0Parameter) == (unsigned) parameters->int1Parameter;
}
// iwd2 and pst have different order of parameters:
-// ClassLevelGT(Protagonist,MAGE,89)
+// ClassLevelGT(Protagonist,MAGE,10)
// LevelInClass(Myself,10,CLERIC)
int GameScript::LevelInClass(Scriptable* Sender, Trigger* parameters)
{
@@ -2793,11 +2589,7 @@ int GameScript::LevelInClass(Scriptable* Sender, Trigger* parameters)
return 0;
}
Actor* actor = ( Actor* ) tar;
-
- if (!ID_ClassMask( actor, parameters->int1Parameter) )
- return 0;
- // FIXME: compare the requested level
- return actor->GetStat(IE_LEVEL) == (unsigned) parameters->int0Parameter;
+ return actor->GetLevelInClass(parameters->int1Parameter) == (unsigned) parameters->int0Parameter;
}
int GameScript::LevelGT(Scriptable* Sender, Trigger* parameters)
@@ -2824,9 +2616,7 @@ int GameScript::ClassLevelGT(Scriptable* Sender, Trigger* parameters)
return 0;
}
Actor* actor = ( Actor* ) tar;
- if (!ID_Class( actor, parameters->int0Parameter) )
- return 0;
- return actor->GetStat(IE_LEVEL) > (unsigned) parameters->int1Parameter;
+ return actor->GetLevelInClass(parameters->int0Parameter) > (unsigned) parameters->int1Parameter;
}
int GameScript::LevelInClassGT(Scriptable* Sender, Trigger* parameters)
@@ -2839,10 +2629,7 @@ int GameScript::LevelInClassGT(Scriptable* Sender, Trigger* parameters)
return 0;
}
Actor* actor = ( Actor* ) tar;
-
- if (!ID_ClassMask( actor, parameters->int1Parameter) )
- return 0;
- return actor->GetStat(IE_LEVEL) > (unsigned) parameters->int0Parameter;
+ return actor->GetLevelInClass(parameters->int1Parameter) > (unsigned) parameters->int0Parameter;
}
int GameScript::LevelLT(Scriptable* Sender, Trigger* parameters)
@@ -2868,9 +2655,7 @@ int GameScript::ClassLevelLT(Scriptable* Sender, Trigger* parameters)
return 0;
}
Actor* actor = ( Actor* ) tar;
- if (!ID_Class( actor, parameters->int0Parameter) )
- return 0;
- return actor->GetStat(IE_LEVEL) < (unsigned) parameters->int1Parameter;
+ return actor->GetLevelInClass(parameters->int0Parameter) < (unsigned) parameters->int1Parameter;
}
int GameScript::LevelInClassLT(Scriptable* Sender, Trigger* parameters)
@@ -2883,10 +2668,7 @@ int GameScript::LevelInClassLT(Scriptable* Sender, Trigger* parameters)
return 0;
}
Actor* actor = ( Actor* ) tar;
-
- if (!ID_ClassMask( actor, parameters->int1Parameter) )
- return 0;
- return actor->GetStat(IE_LEVEL) < (unsigned) parameters->int0Parameter;
+ return actor->GetLevelInClass(parameters->int1Parameter) < (unsigned) parameters->int0Parameter;
}
int GameScript::UnselectableVariable(Scriptable* Sender, Trigger* parameters)
@@ -2918,7 +2700,10 @@ int GameScript::UnselectableVariableLT(Scriptable* Sender, Trigger* parameters)
int GameScript::AreaCheck(Scriptable* Sender, Trigger* parameters)
{
- if (!strnicmp(Sender->GetCurrentArea()->GetScriptName(), parameters->string0Parameter, 8)) {
+ Map *area = Sender->GetCurrentArea();
+ if (!area) return 0;
+
+ if (!strnicmp(area->GetScriptName(), parameters->string0Parameter, 8)) {
return 1;
}
return 0;
@@ -3030,12 +2815,18 @@ int GameScript::InMyArea(Scriptable* Sender, Trigger* parameters)
int GameScript::AreaType(Scriptable* Sender, Trigger* parameters)
{
Map *map=Sender->GetCurrentArea();
+ if (!map) {
+ return 1;
+ }
return (map->AreaType¶meters->int0Parameter)>0;
}
int GameScript::IsExtendedNight( Scriptable* Sender, Trigger* /*parameters*/)
{
Map *map=Sender->GetCurrentArea();
+ if (!map) {
+ return 1;
+ }
if (map->AreaType&AT_EXTENDED_NIGHT) {
return 1;
}
@@ -3045,12 +2836,18 @@ int GameScript::IsExtendedNight( Scriptable* Sender, Trigger* /*parameters*/)
int GameScript::AreaFlag(Scriptable* Sender, Trigger* parameters)
{
Map *map=Sender->GetCurrentArea();
+ if (!map) {
+ return 1;
+ }
return (map->AreaFlags¶meters->int0Parameter)>0;
}
int GameScript::AreaRestDisabled(Scriptable* Sender, Trigger* /*parameters*/)
{
Map *map=Sender->GetCurrentArea();
+ if (!map) {
+ return 1;
+ }
if (map->AreaFlags&2) {
return 1;
}
@@ -3113,17 +2910,32 @@ int GameScript::PartyCountAliveGT(Scriptable* /*Sender*/, Trigger* parameters)
int GameScript::LevelParty(Scriptable* /*Sender*/, Trigger* parameters)
{
- return core->GetGame()->GetPartyLevel(1)==parameters->int0Parameter;
+ int count = core->GetGame()->GetPartySize(1);
+
+ if (count) {
+ return core->GetGame()->GetPartyLevel(1)/count==parameters->int0Parameter;
+ }
+ return 0;
}
int GameScript::LevelPartyLT(Scriptable* /*Sender*/, Trigger* parameters)
{
- return core->GetGame()->GetPartyLevel(1)<parameters->int0Parameter;
+ int count = core->GetGame()->GetPartySize(1);
+
+ if (count) {
+ return core->GetGame()->GetPartyLevel(1)<parameters->int0Parameter;
+ }
+ return 0;
}
int GameScript::LevelPartyGT(Scriptable* /*Sender*/, Trigger* parameters)
{
- return core->GetGame()->GetPartyLevel(1)>parameters->int0Parameter;
+ int count = core->GetGame()->GetPartySize(1);
+
+ if (count) {
+ return core->GetGame()->GetPartyLevel(1)>parameters->int0Parameter;
+ }
+ return 0;
}
int GameScript::PartyGold(Scriptable* /*Sender*/, Trigger* parameters)
@@ -3397,18 +3209,7 @@ int GameScript::TimeLT(Scriptable* /*Sender*/, Trigger* parameters)
int GameScript::HotKey(Scriptable* Sender, Trigger* parameters)
{
- if (Sender->Type != ST_ACTOR) {
- return 0;
- }
- Actor *scr = (Actor *) Sender;
- // FIXME: this is never going to work on 64 bit archs ...
- int ret = (unsigned long) scr->HotKey == (unsigned long) parameters->int0Parameter;
- //probably we need to implement a trigger mechanism, clear
- //the hotkey only when the triggerblock was evaluated as true
- if (ret) {
- Sender->AddTrigger (&scr->HotKey);
- }
- return ret;
+ return Sender->MatchTrigger(trigger_hotkey, parameters->int0Parameter);
}
int GameScript::CombatCounter(Scriptable* /*Sender*/, Trigger* parameters)
@@ -3428,20 +3229,7 @@ int GameScript::CombatCounterLT(Scriptable* /*Sender*/, Trigger* parameters)
int GameScript::TrapTriggered(Scriptable* Sender, Trigger* parameters)
{
- if (Sender->Type != ST_TRIGGER) {
- return 0;
- }
-/* matchactor would do this, hmm
- Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
- if (!tar || tar->Type != ST_ACTOR) {
- return 0;
- }
-*/
- if (MatchActor(Sender, Sender->LastTrigger, parameters->objectParameter)) {
- Sender->AddTrigger (&Sender->LastTrigger);
- return 1;
- }
- return 0;
+ return Sender->MatchTriggerWithObject(trigger_traptriggered, parameters->objectParameter);
}
int GameScript::InteractingWith(Scriptable* Sender, Trigger* parameters)
@@ -3473,7 +3261,7 @@ int GameScript::LastPersonTalkedTo(Scriptable* Sender, Trigger* parameters)
return 0;
}
Actor *scr = (Actor *) Sender;
- if (MatchActor(Sender, scr->LastTalkedTo, parameters->objectParameter)) {
+ if (MatchActor(Sender, scr->LastTalker, parameters->objectParameter)) {
return 1;
}
return 0;
@@ -3525,82 +3313,27 @@ int GameScript::IsFacingObject(Scriptable* Sender, Trigger* parameters)
int GameScript::AttackedBy(Scriptable* Sender, Trigger* parameters)
{
- if (Sender->Type!=ST_ACTOR) {
- return 0;
- }
- Actor *scr = (Actor *) Sender;
- Targets *tgts = GetAllObjects(Sender->GetCurrentArea(), Sender, parameters->objectParameter, GA_NO_DEAD);
- int ret = 0;
- int AStyle = parameters->int0Parameter;
- //iterate through targets to get the actor
- if (tgts) {
- targetlist::iterator m;
- const targettype *tt = tgts->GetFirstTarget(m, ST_ACTOR);
- while (tt) {
- Actor *actor = (Actor *) tt->actor;
- //if (actor->LastTarget == scr->GetID()) {
- if (scr->LastAttacker == actor->GetGlobalID()) {
- if (!AStyle || (AStyle==actor->GetAttackStyle()) ) {
- scr->AddTrigger(&scr->LastAttacker);
- ret = 1;
- break;
- }
- }
- tt = tgts->GetNextTarget(m, ST_ACTOR);
- }
- }
- delete tgts;
- return ret;
+ return Sender->MatchTriggerWithObject(trigger_attackedby, parameters->objectParameter, parameters->int0Parameter);
}
int GameScript::TookDamage(Scriptable* Sender, Trigger* /*parameters*/)
{
- if (Sender->Type!=ST_ACTOR) {
- return 0;
- }
- Actor* actor = ( Actor* ) Sender;
- //zero damage doesn't count?
- if (actor->LastHitter && actor->LastDamage) {
- Sender->AddTrigger(&actor->LastHitter);
- return 1;
- }
- return 0;
+ return Sender->MatchTrigger(trigger_tookdamage);
}
int GameScript::HitBy(Scriptable* Sender, Trigger* parameters)
{
- if (Sender->Type!=ST_ACTOR) {
- return 0;
- }
- Actor* actor = ( Actor* ) Sender;
- if (parameters->int0Parameter) {
- if (!(parameters->int0Parameter&actor->LastDamageType) ) {
- return 0;
- }
- }
- if (MatchActor(Sender, actor->LastHitter, parameters->objectParameter)) {
- Sender->AddTrigger(&actor->LastHitter);
- return 1;
- }
- return 0;
+ return Sender->MatchTriggerWithObject(trigger_hitby, parameters->objectParameter, parameters->int0Parameter);
}
int GameScript::Heard(Scriptable* Sender, Trigger* parameters)
{
- if (Sender->Type!=ST_ACTOR) {
- return 0;
- }
- Actor* actor = ( Actor* ) Sender;
- if (parameters->int0Parameter) {
- if (parameters->int0Parameter!=actor->LastShout) {
- return 0;
- }
- }
- if (MatchActor(Sender, actor->LastHeard, parameters->objectParameter)) {
- Sender->AddTrigger(&actor->LastHeard);
- return 1;
- }
- return 0;
+ return Sender->MatchTriggerWithObject(trigger_heard, parameters->objectParameter, parameters->int0Parameter);
+}
+
+int GameScript::Detected(Scriptable* Sender, Trigger* parameters)
+{
+ return Sender->MatchTriggerWithObject(trigger_detected, parameters->objectParameter, parameters->int0Parameter);
}
int GameScript::LastMarkedObject_Trigger(Scriptable* Sender, Trigger* parameters)
@@ -3645,7 +3378,8 @@ int GameScript::HelpEX(Scriptable* Sender, Trigger* parameters)
return 0;
}
if (actor->GetStat(stat)==help->GetStat(stat) ) {
- Sender->AddTrigger(&actor->LastHelp);
+ // FIXME
+ //Sender->AddTrigger(&actor->LastHelp);
return 1;
}
return 0;
@@ -3653,59 +3387,22 @@ int GameScript::HelpEX(Scriptable* Sender, Trigger* parameters)
int GameScript::Help_Trigger(Scriptable* Sender, Trigger* parameters)
{
- if (Sender->Type!=ST_ACTOR) {
- return 0;
- }
- Actor* actor = ( Actor* ) Sender;
- if (MatchActor(Sender, actor->LastHelp, parameters->objectParameter)) {
- Sender->AddTrigger(&actor->LastHelp);
- return 1;
- }
- return 0;
+ return Sender->MatchTriggerWithObject(trigger_help, parameters->objectParameter);
}
int GameScript::ReceivedOrder(Scriptable* Sender, Trigger* parameters)
{
- if (MatchActor(Sender, Sender->LastOrderer, parameters->objectParameter) &&
- parameters->int0Parameter==Sender->LastOrder) {
- Sender->AddTrigger(&Sender->LastOrderer);
- return 1;
- }
- return 0;
+ return Sender->MatchTriggerWithObject(trigger_receivedorder, parameters->objectParameter, parameters->int0Parameter);
}
int GameScript::Joins(Scriptable* Sender, Trigger* parameters)
{
- if(Sender->Type!=ST_ACTOR) {
- return 0;
- }
- Actor * actor = ( Actor* ) Sender;
- //this trigger is sent only to PCs in a party
- if(!actor->PCStats) {
- return 0;
- }
- if (MatchActor(Sender, actor->PCStats->LastJoined, parameters->objectParameter)) {
- Sender->AddTrigger(&actor->PCStats->LastJoined);
- return 1;
- }
- return 0;
+ return Sender->MatchTriggerWithObject(trigger_joins, parameters->objectParameter);
}
int GameScript::Leaves(Scriptable* Sender, Trigger* parameters)
{
- if(Sender->Type!=ST_ACTOR) {
- return 0;
- }
- Actor * actor = ( Actor* ) Sender;
- //this trigger is sent only to PCs in a party
- if(!actor->PCStats) {
- return 0;
- }
- if (MatchActor(Sender, actor->PCStats->LastLeft, parameters->objectParameter)) {
- Sender->AddTrigger(&actor->PCStats->LastLeft);
- return 1;
- }
- return 0;
+ return Sender->MatchTriggerWithObject(trigger_leaves, parameters->objectParameter);
}
int GameScript::FallenPaladin(Scriptable* Sender, Trigger* /*parameters*/)
@@ -3805,11 +3502,8 @@ int GameScript::InWeaponRange(Scriptable* Sender, Trigger* parameters)
return 0;
}
-//this implementation returns only true if there is a bow wielded
-//but there is no ammo for it
-//if the implementation should sign 'no ranged attack possible'
-//then change some return values
-//in bg2/iwd2 it doesn't accept an object (the object parameter is gemrb ext.)
+//it is impossible to equip a bow without projectile (it will be fist)
+//So outofammo equals fist is equipped
int GameScript::OutOfAmmo(Scriptable* Sender, Trigger* parameters)
{
Scriptable* scr = Sender;
@@ -3820,45 +3514,32 @@ int GameScript::OutOfAmmo(Scriptable* Sender, Trigger* parameters)
return 0;
}
Actor *actor = (Actor *) scr;
- WeaponInfo wi;
- ITMExtHeader *header = actor->GetWeapon(wi, false);
- //no bow wielded?
- if (!header || header->AttackType!=ITEM_AT_BOW) {
- return 0;
- }
- //we either have a projectile (negative) or an empty bow (positive)
- //so we should find a negative slot, positive slot means: OutOfAmmo
- if (actor->inventory.GetEquipped()<0) {
- return 0;
+
+ //if a bow is equipped, but out of ammo, the core system will swap to fist anyway
+ if (actor->inventory.GetEquippedSlot() == actor->inventory.GetFistSlot()) {
+ return 1;
}
- //out of ammo
- return 1;
+
+ return 0;
}
-//returns true if a weapon is equipped (with more than 0 range)
-//if a bow is equipped without projectile, it is useless!
-//please notice how similar is this to OutOfAmmo
+//returns true if a weapon is equipped and target is in range
+//if a bow is equipped without projectile, it is useless (but it will be a fist)!
int GameScript::HaveUsableWeaponEquipped(Scriptable* Sender, Trigger* /*parameters*/)
{
if (Sender->Type!=ST_ACTOR) {
return 0;
}
Actor *actor = (Actor *) Sender;
- WeaponInfo wi;
- ITMExtHeader *header = actor->GetWeapon(wi, false);
-
- //bows are not usable (because if they are loaded, the equipped
- //weapon is the projectile)
- if (!header || header->AttackType==ITEM_AT_BOW) {
- return 0;
- }
- //only fist we have, it is not qualified as weapon?
+ //if a bow is equipped, but out of ammo, the core system will swap to fist anyway
if (actor->inventory.GetEquippedSlot() == actor->inventory.GetFistSlot()) {
return 0;
}
+
return 1;
}
+//if the equipped slot is not a fist, this is true
int GameScript::HasWeaponEquipped(Scriptable* Sender, Trigger* parameters)
{
Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
@@ -3866,7 +3547,7 @@ int GameScript::HasWeaponEquipped(Scriptable* Sender, Trigger* parameters)
return 0;
}
Actor* actor = ( Actor* ) tar;
- if (actor->inventory.GetEquippedSlot() == IW_NO_EQUIPPED) {
+ if (actor->inventory.GetEquippedSlot() == actor->inventory.GetFistSlot()) {
return 0;
}
return 1;
@@ -3996,7 +3677,7 @@ int GameScript::ChargeCount( Scriptable* Sender, Trigger* parameters)
return 0;
}
-// no idea if it checks only alive partymembers
+// no idea if it checks only alive partymembers or if it is average or not
int GameScript::CheckPartyLevel( Scriptable* /*Sender*/, Trigger* parameters)
{
if (core->GetGame()->GetPartyLevel(false)<parameters->int0Parameter) {
@@ -4008,7 +3689,13 @@ int GameScript::CheckPartyLevel( Scriptable* /*Sender*/, Trigger* parameters)
// no idea if it checks only alive partymembers
int GameScript::CheckPartyAverageLevel( Scriptable* /*Sender*/, Trigger* parameters)
{
- int level = core->GetGame()->GetPartyLevel(false);
+ Game *game = core->GetGame();
+
+ int count = game->GetPartySize(false);
+ int level = game->GetPartyLevel(false);
+
+ if (count) level/=count;
+
switch (parameters->int1Parameter) {
case DM_EQUAL:
if (level ==parameters->int0Parameter) {
@@ -4115,13 +3802,8 @@ int GameScript::Delay( Scriptable* Sender, Trigger* parameters)
if (delay<=1) {
return 1;
}
- ieDword time1=Sender->lastDelay/1000/delay;
- ieDword time2=Sender->lastRunTime/1000/delay;
- if (time1!=time2) {
- return 1;
- }
- return 0;
+ return (Sender->ScriptTicks % delay) <= Sender->IdleTicks;
}
int GameScript::TimeOfDay(Scriptable* /*Sender*/, Trigger* parameters)
@@ -4164,11 +3846,7 @@ int GameScript::RandomStatCheck(Scriptable* Sender, Trigger* parameters)
int GameScript::PartyRested(Scriptable* Sender, Trigger* /*parameters*/)
{
- if (Sender->GetInternalFlag()&IF_PARTYRESTED) {
- Sender->SetBitTrigger(BT_PARTYRESTED);
- return 1;
- }
- return 0;
+ return Sender->MatchTrigger(trigger_partyrested);
}
int GameScript::IsWeaponRanged(Scriptable* Sender, Trigger* parameters)
@@ -4249,7 +3927,7 @@ int GameScript::InMyGroup(Scriptable* Sender, Trigger* parameters)
return 1;
}
*/
- if ( ((Actor *) tar)->GetStat(IE_SPECIFIC)==((Actor *) tar)->GetStat(IE_SPECIFIC) ) {
+ if ( ((Actor *) tar)->GetStat(IE_SPECIFIC)==((Actor *) Sender)->GetStat(IE_SPECIFIC) ) {
return 1;
}
return 0;
@@ -4286,6 +3964,21 @@ int GameScript::Unusable(Scriptable* Sender, Trigger* parameters)
return ret;
}
+//returns true if the immunity flag is set
+//(attacker has to make a successful spell save to hit the target)
+int GameScript::IsInGuardianMantle(Scriptable* Sender, Trigger* parameters)
+{
+ Scriptable *tar = GetActorFromObject( Sender, parameters->objectParameter );
+ if (!tar || tar->Type != ST_ACTOR) {
+ return 0;
+ }
+ Actor* actor = ( Actor* ) tar;
+ if (actor->GetStat(IE_IMMUNITY)&IMM_GUARDIAN) {
+ return 1;
+ }
+ return 0;
+}
+
int GameScript::HasBounceEffects(Scriptable* Sender, Trigger* parameters)
{
Scriptable *tar = GetActorFromObject( Sender, parameters->objectParameter );
@@ -4344,61 +4037,22 @@ int GameScript::SystemVariable_Trigger(Scriptable* Sender, Trigger* parameters)
int GameScript::SpellCast(Scriptable* Sender, Trigger* parameters)
{
- if(parameters->int0Parameter) {
- unsigned int param = 2000+parameters->int0Parameter%1000;
- if (param!=Sender->LastSpellSeen) {
- return 0;
- }
- }
- if(MatchActor(Sender, Sender->LastCasterSeen, parameters->objectParameter)) {
- Sender->AddTrigger(&Sender->LastCasterSeen);
- return 1;
- }
- return 0;
+ return Sender->MatchTriggerWithObject(trigger_spellcast, parameters->objectParameter, parameters->int0Parameter);
}
int GameScript::SpellCastPriest(Scriptable* Sender, Trigger* parameters)
{
- if(parameters->int0Parameter) {
- unsigned int param = 1000+parameters->int0Parameter%1000;
- if (param!=Sender->LastSpellSeen) {
- return 0;
- }
- }
- if(MatchActor(Sender, Sender->LastCasterSeen, parameters->objectParameter)) {
- Sender->AddTrigger(&Sender->LastCasterSeen);
- return 1;
- }
- return 0;
+ return Sender->MatchTriggerWithObject(trigger_spellcastpriest, parameters->objectParameter, parameters->int0Parameter);
}
int GameScript::SpellCastInnate(Scriptable* Sender, Trigger* parameters)
{
- if(parameters->int0Parameter) {
- unsigned int param = 3000+parameters->int0Parameter%1000;
- if (param!=Sender->LastSpellSeen) {
- return 0;
- }
- }
- if(MatchActor(Sender, Sender->LastCasterSeen, parameters->objectParameter)) {
- Sender->AddTrigger(&Sender->LastCasterSeen);
- return 1;
- }
- return 0;
+ return Sender->MatchTriggerWithObject(trigger_spellcastinnate, parameters->objectParameter, parameters->int0Parameter);
}
int GameScript::SpellCastOnMe(Scriptable* Sender, Trigger* parameters)
{
- if(parameters->int0Parameter) {
- if ((ieDword) parameters->int0Parameter!=Sender->LastSpellOnMe) {
- return 0;
- }
- }
- if(MatchActor(Sender, Sender->LastCasterOnMe, parameters->objectParameter)) {
- Sender->AddTrigger(&Sender->LastCasterOnMe);
- return 1;
- }
- return 0;
+ return Sender->MatchTriggerWithObject(trigger_spellcastonme, parameters->objectParameter, parameters->int0Parameter);
}
int GameScript::CalendarDay(Scriptable* /*Sender*/, Trigger* parameters)
@@ -4429,15 +4083,55 @@ int GameScript::CalendarDayLT(Scriptable* /*Sender*/, Trigger* parameters)
}
//NT Returns true only if the active CRE was turned by the specified priest or paladin.
-int GameScript::TurnedBy(Scriptable* Sender, Trigger* /*parameters*/)
+int GameScript::TurnedBy(Scriptable* Sender, Trigger* parameters)
{
- if (Sender->Type!=ST_ACTOR) {
+ return Sender->MatchTriggerWithObject(trigger_turnedby, parameters->objectParameter);
+}
+
+//This is used for pst portals
+//usage: UsedExit(Protagonist, "sigil")
+//where sigil.2da contains all the exits that should trigger the teleport
+int GameScript::UsedExit(Scriptable* Sender, Trigger* parameters)
+{
+ Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
+ if (!scr || scr->Type != ST_ACTOR) {
return 0;
}
- Actor* actor = ( Actor* ) Sender;
- if (MatchActor(Sender, actor->LastTurner, NULL)) {
- Sender->AddTrigger(&actor->LastTurner);
+ Actor* actor = ( Actor* ) scr;
+
+ if (actor->GetInternalFlag()&IF_USEEXIT) {
+ return 0;
+ }
+
+ Map *ca = core->GetGame()->GetMap(actor->LastArea, false);
+
+ if (!ca) {
+ return 0;
+ }
+
+ InfoPoint *ip = ca->GetInfoPointByGlobalID(actor->UsedExit);
+ if (!ip || ip->Type!=ST_TRAVEL) {
+ return 0;
+ }
+
+ AutoTable tm(parameters->string0Parameter);
+ if (!tm) {
+ return 0;
+ }
+
+ int count = tm->GetRowCount();
+ for (int i=0;i<count;i++) {
+ const char *area = tm->QueryField( i, 0 );
+ if (strnicmp(actor->LastArea, area, 8) ) {
+ continue;
+ }
+ const char *exit = tm->QueryField( i, 1 );
+ if (strnicmp(ip->GetScriptName(), exit, 32) ) {
+ continue;
+ }
return 1;
}
return 0;
}
+
+}
diff --git a/gemrb/core/GlobalTimer.cpp b/gemrb/core/GlobalTimer.cpp
index 1f71723..d58fa45 100644
--- a/gemrb/core/GlobalTimer.cpp
+++ b/gemrb/core/GlobalTimer.cpp
@@ -26,6 +26,8 @@
#include "Video.h"
#include "GUI/GameControl.h"
+namespace GemRB {
+
GlobalTimer::GlobalTimer(void)
{
//AI_UPDATE_TIME: how many AI updates in a second
@@ -59,7 +61,9 @@ void GlobalTimer::Freeze()
unsigned long thisTime;
unsigned long advance;
- GetTime( thisTime );
+ UpdateAnimations(true);
+
+ thisTime = GetTickCount();
advance = thisTime - startTime;
if ( advance < interval) {
return;
@@ -69,7 +73,7 @@ void GlobalTimer::Freeze()
if (!game) {
return;
}
- game->RealTime+=advance;
+ game->RealTime++;
ieDword count = advance/interval;
// pst/bg2 do this, if you fix it for another game, wrap it in a check
@@ -107,17 +111,17 @@ void GlobalTimer::DoStep(int count)
if ( (x != goal.x) || (y != goal.y)) {
if (speed) {
if (x<goal.x) {
- x+=speed;
+ x+=speed*count;
if (x>goal.x) x=goal.x;
} else {
- x-=speed;
+ x-=speed*count;
if (x<goal.x) x=goal.x;
}
if (y<goal.y) {
- y+=speed;
+ y+=speed*count;
if (y>goal.y) y=goal.y;
} else {
- y-=speed;
+ y-=speed*count;
if (y<goal.y) y=goal.y;
}
} else {
@@ -134,14 +138,18 @@ void GlobalTimer::DoStep(int count)
shakeCounter=0;
}
if (shakeCounter) {
- x += (rand()%shakeX) - (shakeX>>1);
- y += (rand()%shakeY) - (shakeY>>1);
+ if (shakeX) {
+ x += rand()%shakeX;
+ }
+ if (shakeY) {
+ y += rand()%shakeY;
+ }
}
}
video->MoveViewportTo(x,y);
}
-void GlobalTimer::Update()
+bool GlobalTimer::Update()
{
Map *map;
Game *game;
@@ -153,18 +161,18 @@ void GlobalTimer::Update()
if (gc)
gc->UpdateScrolling();
- UpdateAnimations();
+ UpdateAnimations(false);
- GetTime( thisTime );
+ thisTime = GetTickCount();
if (!startTime) {
startTime = thisTime;
- return;
+ return false;
}
advance = thisTime - startTime;
if ( advance < interval) {
- return;
+ return false;
}
ieDword count = advance/interval;
DoStep(count);
@@ -187,15 +195,16 @@ void GlobalTimer::Update()
map->UpdateEffects();
if (thisTime) {
//this measures in-world time (affected by effects, actions, etc)
- game->AdvanceTime(count);
+ game->AdvanceTime(1);
}
}
//this measures time spent in the game (including pauses)
if (thisTime) {
- game->RealTime+=advance;
+ game->RealTime++;
}
end:
startTime = thisTime;
+ return true;
}
@@ -264,7 +273,7 @@ void GlobalTimer::AddAnimation(ControlAnimation* ctlanim, unsigned long time)
AnimationRef* anim;
unsigned long thisTime;
- GetTime( thisTime );
+ thisTime = GetTickCount();
time += thisTime;
// if there are no free animation reference objects,
@@ -305,10 +314,10 @@ void GlobalTimer::RemoveAnimation(ControlAnimation* ctlanim)
}
}
-void GlobalTimer::UpdateAnimations()
+void GlobalTimer::UpdateAnimations(bool paused)
{
unsigned long thisTime;
- GetTime( thisTime );
+ thisTime = GetTickCount();
while (animations.begin() + first_animation != animations.end()) {
AnimationRef* anim = animations[first_animation];
if (anim->ctlanim == NULL) {
@@ -317,7 +326,7 @@ void GlobalTimer::UpdateAnimations()
}
if (anim->time <= thisTime) {
- anim->ctlanim->UpdateAnimation();
+ anim->ctlanim->UpdateAnimation(paused);
first_animation++;
continue;
}
@@ -330,10 +339,12 @@ void GlobalTimer::ClearAnimations()
first_animation = (unsigned int) animations.size();
}
-void GlobalTimer::SetScreenShake(unsigned long shakeX, unsigned long shakeY,
+void GlobalTimer::SetScreenShake(int shakeX, int shakeY,
unsigned long Count)
{
this->shakeX = shakeX;
this->shakeY = shakeY;
shakeCounter = Count+1;
}
+
+}
diff --git a/gemrb/core/GlobalTimer.h b/gemrb/core/GlobalTimer.h
index ebf955c..dce3e95 100644
--- a/gemrb/core/GlobalTimer.h
+++ b/gemrb/core/GlobalTimer.h
@@ -27,6 +27,8 @@
#include <vector>
+namespace GemRB {
+
class ControlAnimation;
struct AnimationRef
@@ -45,7 +47,7 @@ private:
int fadeFromCounter, fadeFromMax;
unsigned long waitCounter;
int shakeCounter;
- unsigned long shakeX, shakeY;
+ int shakeX, shakeY;
unsigned int first_animation;
std::vector<AnimationRef*> animations;
//move viewport to this coordinate
@@ -54,25 +56,26 @@ private:
Region currentVP;
void DoFadeStep(ieDword count);
+ void UpdateAnimations(bool paused);
public:
GlobalTimer(void);
~GlobalTimer(void);
public:
void Init();
void Freeze();
- void Update();
+ bool Update();
bool ViewportIsMoving();
void DoStep(int count);
void SetMoveViewPort(ieDword x, ieDword y, int spd, bool center);
void SetFadeToColor(unsigned long Count);
void SetFadeFromColor(unsigned long Count);
void SetWait(unsigned long Count);
- void SetScreenShake(unsigned long shakeX, unsigned long shakeY,
- unsigned long Count);
+ void SetScreenShake(int shakeX, int shakeY, unsigned long Count);
void AddAnimation(ControlAnimation* ctlanim, unsigned long time);
void RemoveAnimation(ControlAnimation* ctlanim);
void ClearAnimations();
- void UpdateAnimations();
};
+}
+
#endif
diff --git a/gemrb/core/Holder.h b/gemrb/core/Holder.h
index 170a4c8..6e420f8 100644
--- a/gemrb/core/Holder.h
+++ b/gemrb/core/Holder.h
@@ -24,6 +24,8 @@
#include <cassert>
#include <cstddef>
+namespace GemRB {
+
template <class T>
class Held {
public:
@@ -81,6 +83,7 @@ public:
T* operator->() const { return ptr; }
bool operator!() const { return !ptr; }
#include "operatorbool.h"
+
OPERATOR_BOOL(Holder<T>,T,ptr)
T* get() const { return ptr; }
void release() {
@@ -92,4 +95,6 @@ protected:
T *ptr;
};
+}
+
#endif
diff --git a/gemrb/core/Image.cpp b/gemrb/core/Image.cpp
index 8b03e09..9918f94 100644
--- a/gemrb/core/Image.cpp
+++ b/gemrb/core/Image.cpp
@@ -21,6 +21,8 @@
#include "Interface.h"
#include "Video.h"
+namespace GemRB {
+
Image::Image(unsigned int w, unsigned int h)
: height(h), width(w), data(new Color[height*width])
{
@@ -45,3 +47,5 @@ Sprite2D* Image::GetSprite2D()
return core->GetVideoDriver()->CreateSprite(width, height, 32,
r.Mask, g.Mask, b.Mask, a.Mask, pixels);
}
+
+}
diff --git a/gemrb/core/Image.h b/gemrb/core/Image.h
index 9628d65..47d8011 100644
--- a/gemrb/core/Image.h
+++ b/gemrb/core/Image.h
@@ -22,6 +22,8 @@
#include "RGBAColor.h"
#include "exports.h"
+namespace GemRB {
+
class Sprite2D;
class GEM_EXPORT Image {
@@ -58,4 +60,6 @@ private:
Color *data;
};
+}
+
#endif
diff --git a/gemrb/core/ImageFactory.cpp b/gemrb/core/ImageFactory.cpp
index 17ad0d0..9a27510 100644
--- a/gemrb/core/ImageFactory.cpp
+++ b/gemrb/core/ImageFactory.cpp
@@ -23,6 +23,8 @@
#include "Interface.h"
#include "Video.h"
+namespace GemRB {
+
ImageFactory::ImageFactory(const char* ResRef, Sprite2D* bitmap_)
: FactoryObject( ResRef, IE_BMP_CLASS_ID ), bitmap(bitmap_)
{
@@ -40,3 +42,5 @@ Sprite2D* ImageFactory::GetSprite2D() const
return bitmap;
}
+
+}
diff --git a/gemrb/core/ImageFactory.h b/gemrb/core/ImageFactory.h
index c0576d9..4d94120 100644
--- a/gemrb/core/ImageFactory.h
+++ b/gemrb/core/ImageFactory.h
@@ -27,6 +27,8 @@
#include "FactoryObject.h"
#include "Sprite2D.h"
+namespace GemRB {
+
class GEM_EXPORT ImageFactory : public FactoryObject {
private:
Sprite2D* bitmap;
@@ -37,4 +39,6 @@ public:
Sprite2D* GetSprite2D() const;
};
+}
+
#endif
diff --git a/gemrb/core/ImageMgr.cpp b/gemrb/core/ImageMgr.cpp
index c38c486..bb239c6 100644
--- a/gemrb/core/ImageMgr.cpp
+++ b/gemrb/core/ImageMgr.cpp
@@ -26,6 +26,8 @@
#include "Interface.h"
#include "Video.h"
+namespace GemRB {
+
const TypeID ImageMgr::ID = { "ImageMgr" };
ImageMgr::ImageMgr(void)
@@ -42,9 +44,8 @@ Bitmap* ImageMgr::GetBitmap()
unsigned int width = GetWidth();
Bitmap *data = new Bitmap(width, height);
- printMessage("ImageMgr", "Don't know how to handle 24bit bitmap from ", WHITE);
- printf( "%s...", str->filename );
- printStatus( "ERROR", LIGHT_RED );
+ Log(ERROR, "ImageMgr", "Don't know how to handle 24bit bitmap from %s...",
+ str->filename );
Sprite2D *spr = GetSprite2D();
@@ -80,9 +81,8 @@ Image* ImageMgr::GetImage()
void ImageMgr::GetPalette(int /*colors*/, Color* /*pal*/)
{
- printMessage("ImageMgr", "Can't get non-existant palette from ", WHITE);
- printf("%s... ", str->filename);
- printStatus("ERROR", LIGHT_RED);
+ Log(ERROR, "ImageMgr", "Can't get non-existant palette from %s... ",
+ str->filename);
}
ImageFactory* ImageMgr::GetImageFactory(const char* ResRef)
@@ -90,3 +90,5 @@ ImageFactory* ImageMgr::GetImageFactory(const char* ResRef)
ImageFactory* fact = new ImageFactory( ResRef, GetSprite2D() );
return fact;
}
+
+}
diff --git a/gemrb/core/ImageMgr.h b/gemrb/core/ImageMgr.h
index 40d4709..41b92b4 100644
--- a/gemrb/core/ImageMgr.h
+++ b/gemrb/core/ImageMgr.h
@@ -29,6 +29,8 @@
#include "Sprite2D.h"
#include "System/DataStream.h"
+namespace GemRB {
+
class ImageFactory;
/**
@@ -65,4 +67,6 @@ public:
ImageFactory* GetImageFactory(const char* ResRef);
};
+}
+
#endif
diff --git a/gemrb/core/ImageWriter.cpp b/gemrb/core/ImageWriter.cpp
index 4c2eae7..b2bb476 100644
--- a/gemrb/core/ImageWriter.cpp
+++ b/gemrb/core/ImageWriter.cpp
@@ -18,6 +18,8 @@
#include "ImageWriter.h"
+namespace GemRB {
+
ImageWriter::ImageWriter(void)
{
}
@@ -25,3 +27,5 @@ ImageWriter::ImageWriter(void)
ImageWriter::~ImageWriter(void)
{
}
+
+}
diff --git a/gemrb/core/ImageWriter.h b/gemrb/core/ImageWriter.h
index a02a44b..3eb5766 100644
--- a/gemrb/core/ImageWriter.h
+++ b/gemrb/core/ImageWriter.h
@@ -23,6 +23,8 @@
#include "Sprite2D.h"
#include "System/DataStream.h"
+namespace GemRB {
+
class GEM_EXPORT ImageWriter : public Plugin {
public:
ImageWriter(void);
@@ -32,4 +34,6 @@ public:
virtual void PutImage(DataStream *output, Sprite2D *sprite) = 0;
};
+}
+
#endif
diff --git a/gemrb/core/IndexedArchive.cpp b/gemrb/core/IndexedArchive.cpp
new file mode 100644
index 0000000..660a232
--- /dev/null
+++ b/gemrb/core/IndexedArchive.cpp
@@ -0,0 +1,33 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "IndexedArchive.h"
+
+namespace GemRB {
+
+IndexedArchive::IndexedArchive(void)
+{
+}
+
+IndexedArchive::~IndexedArchive(void)
+{
+}
+
+}
diff --git a/gemrb/core/IndexedArchive.h b/gemrb/core/IndexedArchive.h
new file mode 100644
index 0000000..fb35725
--- /dev/null
+++ b/gemrb/core/IndexedArchive.h
@@ -0,0 +1,40 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef INDEXEDARCHIVE_H
+#define INDEXEDARCHIVE_H
+
+#include "globals.h"
+
+#include "Plugin.h"
+
+namespace GemRB {
+
+class GEM_EXPORT IndexedArchive : public Plugin {
+public:
+ IndexedArchive(void);
+ virtual ~IndexedArchive(void);
+ virtual int OpenArchive(const char* filename) = 0;
+ virtual DataStream* GetStream(unsigned long Resource, unsigned long Type) = 0;
+};
+
+}
+
+#endif
diff --git a/gemrb/core/IniSpawn.cpp b/gemrb/core/IniSpawn.cpp
index b7c1ee4..a997bb3 100644
--- a/gemrb/core/IniSpawn.cpp
+++ b/gemrb/core/IniSpawn.cpp
@@ -25,14 +25,18 @@
#include "win32def.h"
+#include "CharAnimations.h"
#include "Game.h"
#include "GameData.h"
#include "Interface.h"
#include "Map.h"
+#include "PluginMgr.h"
#include "GameScript/GSUtils.h"
#include "GameScript/Matching.h"
#include "Scriptable/Actor.h"
+namespace GemRB {
+
static const int StatValues[9]={
IE_EA, IE_FACTION, IE_TEAM, IE_GENERAL, IE_RACE, IE_CLASS, IE_SPECIFIC,
IE_SEX, IE_ALIGNMENT };
@@ -49,16 +53,30 @@ IniSpawn::IniSpawn(Map *owner)
eventspawns = NULL;
eventcount = 0;
last_spawndate = 0;
+ //high detail level by default
+ detail_level = 2;
+ core->GetDictionary()->Lookup("Detail Level", detail_level);
}
IniSpawn::~IniSpawn()
{
if (eventspawns) {
delete[] eventspawns;
+ eventspawns = NULL;
+ }
+
+ if (Locals) {
+ delete[] Locals;
+ Locals = NULL;
+ }
+
+ if (NamelessVar) {
+ delete[] NamelessVar;
+ NamelessVar = NULL;
}
}
-Holder<DataFileMgr> GetIniFile(const ieResRef DefaultArea)
+static Holder<DataFileMgr> GetIniFile(const ieResRef DefaultArea)
{
//the lack of spawn ini files is not a serious problem, happens all the time
if (!gamedata->Exists( DefaultArea, IE_INI_CLASS_ID)) {
@@ -70,19 +88,18 @@ Holder<DataFileMgr> GetIniFile(const ieResRef DefaultArea)
return NULL;
}
if (!core->IsAvailable( IE_INI_CLASS_ID )) {
- printStatus( "ERROR", LIGHT_RED );
- printMessage( "IniSpawn","No INI Importer Available.\n",LIGHT_RED );
+ Log(ERROR, "IniSpawn", "No INI Importer Available.");
return NULL;
}
PluginHolder<DataFileMgr> ini(IE_INI_CLASS_ID);
- ini->Open(inifile, true ); //autofree
+ ini->Open(inifile);
return ini;
}
/*** initializations ***/
-inline int CountElements(const char *s, char separator)
+static inline int CountElements(const char *s, char separator)
{
int ret = 1;
while(*s) {
@@ -92,7 +109,7 @@ inline int CountElements(const char *s, char separator)
return ret;
}
-inline void GetElements(const char *s, ieResRef *storage, int count)
+static inline void GetElements(const char *s, ieResRef *storage, int count)
{
while(count--) {
ieResRef *field = storage+count;
@@ -110,7 +127,7 @@ inline void GetElements(const char *s, ieResRef *storage, int count)
}
}
-inline void GetElements(const char *s, ieVariable *storage, int count)
+static inline void GetElements(const char *s, ieVariable *storage, int count)
{
while(count--) {
ieVariable *field = storage+count;
@@ -134,7 +151,7 @@ inline void GetElements(const char *s, ieVariable *storage, int count)
// BINARY_MORE 10 //left has more bits than right
// BINARY_LESS 11 //left has less bits than right
-int IniSpawn::GetDiffMode(const char *keyword)
+int IniSpawn::GetDiffMode(const char *keyword) const
{
if (!keyword) return NO_OPERATION; //-1
if (keyword[0]==0) return NO_OPERATION; //-1
@@ -142,36 +159,72 @@ int IniSpawn::GetDiffMode(const char *keyword)
if (!stricmp(keyword,"equal_to") ) return EQUALS; // 1
if (!stricmp(keyword,"less_than") ) return LESS_THAN; // 2
if (!stricmp(keyword,"greater_than") ) return GREATER_THAN; //3
- if (!stricmp(keyword,"greater_or_equal_to") ) return GREATER_THAN; //4 (gemrb ext)
+ if (!stricmp(keyword,"greater_or_equal_to") ) return GREATER_OR_EQUALS; //4 (gemrb ext)
if (!stricmp(keyword,"not_equal_to") ) return NOT_EQUALS; //5
return NO_OPERATION;
}
-//unimplemented tags:
-// check_crowd
-// good_mod, law_mod, lady_mod, murder_mod
+//unimplemented tags (* marks partially implemented, # marks not working in original either):
+//*check_crowd
// control_var
// spec_area
-// death_faction
-// death_team
+//*death_faction
+//*death_team
// check_by_view_port
-// do_not_spawn
-// time_of_day
+//*do_not_spawn
// hold_selected_point_key
// inc_spawn_point_index
-// find_safest_point
-// exit
-// spawn_time_of_day
+//*find_safest_point
+//#spawn_time_of_day
+// exit - similar to enter[spawn], this is a spawn branch type (on exiting an area?)
// PST only
-// auto_buddy
-// detail_level
-void IniSpawn::ReadCreature(DataFileMgr *inifile, const char *crittername, CritterEntry &critter)
+//*auto_buddy
+//*detail_level
+void IniSpawn::ReadCreature(DataFileMgr *inifile, const char *crittername, CritterEntry &critter) const
{
const char *s;
int ps;
memset(&critter,0,sizeof(critter));
+ //first assume it is a simple numeric value
+ critter.TimeOfDay = (ieDword) inifile->GetKeyAsInt(crittername,"time_of_day", 0xffffffff);
+
+ //at this point critter.TimeOfDay is usually 0xffffffff
+ s = inifile->GetKeyAsString(crittername,"time_of_day",NULL);
+ if (s && strlen(s)>=24) {
+ ieDword value = 0;
+ ieDword j = 1;
+ for(int i=0;i<24 && s[i];i++) {
+ if (s[i]=='0' || s[i]=='o') value |= j;
+ j<<=1;
+ }
+ //turn off individual bits marked by a 24 long string scheduling
+ //example: '0000xxxxxxxxxxxxxxxx00000000'
+ critter.TimeOfDay^=value;
+ }
+
+ if (inifile->GetKeyAsBool(crittername,"do_not_spawn",false)) {
+ //if the do not spawn flag is true, ignore this entry
+ return;
+ }
+
+ s = inifile->GetKeyAsString(crittername,"detail_level",NULL);
+ if (s) {
+ ieDword level;
+
+ switch(s[0]) {
+ case 'h': case 'H': level = 2; break;
+ case 'm': case 'M': level = 1; break;
+ default: level = 0; break;
+ }
+ //If the detail level is lower than this creature's detail level,
+ //skip this entry, creature_count is 0, so it will be ignored at evaluation of the spawn
+ if (level>detail_level) {
+ return;
+ }
+ }
+
//all specvars are using global, but sometimes it is explicitly given
s = inifile->GetKeyAsString(crittername,"spec_var",NULL);
if (s) {
@@ -205,8 +258,7 @@ void IniSpawn::ReadCreature(DataFileMgr *inifile, const char *crittername, Critt
critter.CreFile=new ieResRef[critter.creaturecount];
GetElements(s, critter.CreFile, critter.creaturecount);
} else {
- printMessage( "IniSpawn"," ", LIGHT_RED);
- printf("Invalid spawn entry: %s\n", crittername);
+ Log(ERROR, "IniSpawn", "Invalid spawn entry: %s", crittername);
}
s = inifile->GetKeyAsString(crittername,"point_select",NULL);
@@ -230,16 +282,25 @@ void IniSpawn::ReadCreature(DataFileMgr *inifile, const char *crittername, Critt
}
//parse the selected spawnpoint
int x,y,o;
+ if (sscanf(s,"[%d,%d:%d]", &x, &y, &o)==3) {
+ critter.SpawnPoint.x=(short) x;
+ critter.SpawnPoint.y=(short) y;
+ critter.Orientation=o;
+ } else
if (sscanf(s,"[%d.%d:%d]", &x, &y, &o)==3) {
critter.SpawnPoint.x=(short) x;
critter.SpawnPoint.y=(short) y;
critter.Orientation=o;
- } else {
- if (sscanf(s,"[%d.%d]", &x, &y)==2) {
- critter.SpawnPoint.x=(short) x;
- critter.SpawnPoint.y=(short) y;
- critter.Orientation=core->Roll(1,16,-1);
- }
+ } else
+ if (sscanf(s,"[%d,%d]", &x, &y)==2) {
+ critter.SpawnPoint.x=(short) x;
+ critter.SpawnPoint.y=(short) y;
+ critter.Orientation=core->Roll(1,16,-1);
+ } else
+ if (sscanf(s,"[%d.%d]", &x, &y)==2) {
+ critter.SpawnPoint.x=(short) x;
+ critter.SpawnPoint.y=(short) y;
+ critter.Orientation=core->Roll(1,16,-1);
}
}
@@ -401,6 +462,36 @@ void IniSpawn::ReadCreature(DataFileMgr *inifile, const char *crittername, Critt
if (inifile->GetKeyAsBool(crittername,"death_scriptname",false)) {
critter.Flags|=CF_DEATHVAR;
}
+ if (inifile->GetKeyAsBool(crittername,"death_faction",false)) {
+ critter.Flags|=CF_FACTION;
+ }
+ if (inifile->GetKeyAsBool(crittername,"death_team",false)) {
+ critter.Flags|=CF_TEAM;
+ }
+ ps = inifile->GetKeyAsInt(crittername,"good_mod",0);
+ if (ps) {
+ critter.Flags|=CF_GOOD;
+ critter.DeathCounters[DC_GOOD] = ps;
+ }
+ ps = inifile->GetKeyAsInt(crittername,"law_mod",0);
+ if (ps) {
+ critter.Flags|=CF_LAW;
+ critter.DeathCounters[DC_LAW] = ps;
+ }
+ ps = inifile->GetKeyAsInt(crittername,"lady_mod",0);
+ if (ps) {
+ critter.Flags|=CF_LADY;
+ critter.DeathCounters[DC_LADY] = ps;
+ }
+ ps = inifile->GetKeyAsInt(crittername,"murder_mod",0);
+ if (ps) {
+ critter.Flags|=CF_MURDER;
+ critter.DeathCounters[DC_MURDER] = ps;
+ }
+ if(inifile->GetKeyAsBool(crittername,"auto_buddy", false)) {
+ critter.Flags|=CF_BUDDY;
+ }
+
//don't spawn when spawnpoint is visible
if (inifile->GetKeyAsBool(crittername,"ignore_can_see",false)) {
critter.Flags|=CF_IGNORECANSEE;
@@ -429,7 +520,7 @@ void IniSpawn::ReadCreature(DataFileMgr *inifile, const char *crittername, Critt
}
}
-void IniSpawn::ReadSpawnEntry(DataFileMgr *inifile, const char *entryname, SpawnEntry &entry)
+void IniSpawn::ReadSpawnEntry(DataFileMgr *inifile, const char *entryname, SpawnEntry &entry) const
{
const char *s;
@@ -449,7 +540,7 @@ void IniSpawn::ReadSpawnEntry(DataFileMgr *inifile, const char *entryname, Spawn
}
/* set by action */
-void IniSpawn::SetNamelessDeath(const ieResRef area, Point &pos, ieDword state)
+void IniSpawn::SetNamelessDeath(const ieResRef area, Point &pos, ieDword state)
{
strnuprcpy(NamelessSpawnArea, area, 8);
NamelessSpawnPoint = pos;
@@ -504,6 +595,12 @@ void IniSpawn::InitSpawn(const ieResRef DefaultArea)
if (s) {
ReadSpawnEntry(inifile.get(), s, enterspawn);
}
+
+ s = inifile->GetKeyAsString("spawn_main","exit",NULL);
+ if (s) {
+ ReadSpawnEntry(inifile.get(), s, exitspawn);
+ }
+
s = inifile->GetKeyAsString("spawn_main","events",NULL);
if (s) {
eventcount = CountElements(s,',');
@@ -552,7 +649,7 @@ void IniSpawn::RespawnNameless()
}
}
-void IniSpawn::SpawnCreature(CritterEntry &critter)
+void IniSpawn::SpawnCreature(CritterEntry &critter) const
{
if (!critter.creaturecount) {
return;
@@ -639,7 +736,7 @@ void IniSpawn::SpawnCreature(CritterEntry &critter)
}
SetVariable(map, critter.SpecVar, critter.SpecContext, specvar+(ieDword) critter.SpecVarInc);
- map->AddActor(cre);
+ map->AddActor(cre, true);
for (x=0;x<9;x++) {
if (critter.SetSpec[x]) {
cre->SetBase(StatValues[x], critter.SetSpec[x]);
@@ -650,6 +747,43 @@ void IniSpawn::SpawnCreature(CritterEntry &critter)
if (critter.ScriptName[0]) {
cre->SetScriptName(critter.ScriptName);
}
+ //increases death variable
+ if (critter.Flags&CF_DEATHVAR) {
+ cre->AppearanceFlags|=APP_DEATHVAR;
+ }
+ //increases faction specific variable
+ if (critter.Flags&CF_FACTION) {
+ cre->AppearanceFlags|=APP_FACTION;
+ }
+ //increases team specific variable
+ if (critter.Flags&CF_TEAM) {
+ cre->AppearanceFlags|=APP_TEAM;
+ }
+ //increases good variable
+ if (critter.Flags&CF_GOOD) {
+ cre->DeathCounters[DC_GOOD] = critter.DeathCounters[DC_GOOD];
+ cre->AppearanceFlags|=APP_GOOD;
+ }
+ //increases law variable
+ if (critter.Flags&CF_LAW) {
+ cre->DeathCounters[DC_LAW] = critter.DeathCounters[DC_LAW];
+ cre->AppearanceFlags|=APP_LAW;
+ }
+ //increases lady variable
+ if (critter.Flags&CF_LADY) {
+ cre->DeathCounters[DC_LADY] = critter.DeathCounters[DC_LADY];
+ cre->AppearanceFlags|=APP_LADY;
+ }
+ //increases murder variable
+ if (critter.Flags&CF_MURDER) {
+ cre->DeathCounters[DC_MURDER] = critter.DeathCounters[DC_MURDER];
+ cre->AppearanceFlags|=APP_MURDER;
+ }
+ //triggers help from same group
+ if (critter.Flags&CF_BUDDY) {
+ cre->AppearanceFlags|=APP_BUDDY;
+ }
+
if (critter.OverrideScript[0]) {
cre->SetScript(critter.OverrideScript, SCR_OVERRIDE);
}
@@ -676,6 +810,15 @@ void IniSpawn::SpawnCreature(CritterEntry &critter)
}
}
+bool IniSpawn::Schedule(ieDword appearance, ieDword gametime) const
+{
+ ieDword bit = 1<<((gametime/AI_UPDATE_TIME)%7200/300);
+ if (appearance & bit) {
+ return true;
+ }
+ return false;
+}
+
void IniSpawn::SpawnGroup(SpawnEntry &event)
{
if (!event.critters) {
@@ -691,6 +834,9 @@ void IniSpawn::SpawnGroup(SpawnEntry &event)
for(int i=0;i<event.crittercount;i++) {
CritterEntry* critter = event.critters+i;
+ if (!Schedule(critter->TimeOfDay, last_spawndate) ) {
+ continue;
+ }
for(int j=0;j<critter->SpawnCount;j++) {
SpawnCreature(*critter);
}
@@ -707,6 +853,12 @@ void IniSpawn::InitialSpawn()
}
}
+//FIXME:call this at the right time (this feature is not explored yet, and unused in original dataset)
+void IniSpawn::ExitSpawn()
+{
+ SpawnGroup(exitspawn);
+}
+
//checks if a respawn event occurred
void IniSpawn::CheckSpawn()
{
@@ -714,3 +866,6 @@ void IniSpawn::CheckSpawn()
SpawnGroup(eventspawns[i]);
}
}
+
+
+}
diff --git a/gemrb/core/IniSpawn.h b/gemrb/core/IniSpawn.h
index 9a371b5..a839814 100644
--- a/gemrb/core/IniSpawn.h
+++ b/gemrb/core/IniSpawn.h
@@ -34,6 +34,8 @@
#include "DataFileMgr.h"
#include "Region.h"
+namespace GemRB {
+
class Map;
/**
@@ -51,6 +53,14 @@ class Map;
#define CF_SAFESTPOINT 128
#define CF_NO_DIFF_MASK 28
#define CF_CHECK_NAME 256
+#define CF_GOOD 512
+#define CF_LAW 1024
+#define CF_LADY 2048
+#define CF_MURDER 4096
+#define CF_FACTION 8192
+#define CF_TEAM 16384
+#define CF_BUDDY 0x8000
+
//spec ids flags
#define AI_EA 0
#define AI_FACTION 1
@@ -93,6 +103,8 @@ struct CritterEntry {
int Flags; //CF_IGNORENOSEE, CF_DEATHVAR, etc
int TotalQuantity; //total number
int SpawnCount; //create quantity
+ ieDword TimeOfDay; //spawn time of day (defaults to anytime)
+ ieByte DeathCounters[4]; //4 bytes
};
/**
@@ -143,26 +155,32 @@ private:
Point NamelessSpawnPoint;
int NamelessState;
SpawnEntry enterspawn;
+ SpawnEntry exitspawn;
int last_spawndate;
int eventcount;
SpawnEntry *eventspawns;
+ ieDword detail_level;
void ReadCreature(DataFileMgr *inifile,
- const char *crittername, CritterEntry &critter);
+ const char *crittername, CritterEntry &critter) const;
void ReadSpawnEntry(DataFileMgr *inifile,
- const char *entryname, SpawnEntry &entry);
+ const char *entryname, SpawnEntry &entry) const;
//spawns a single creature
- void SpawnCreature(CritterEntry &critter);
+ void SpawnCreature(CritterEntry &critter) const;
void SpawnGroup(SpawnEntry &event);
//gets the spec var operation code from a keyword
- int GetDiffMode(const char *keyword);
+ int GetDiffMode(const char *keyword) const;
+ bool Schedule(ieDword appearance, ieDword gametime) const;
public:
/* called by action of the same name */
void SetNamelessDeath(const ieResRef area, Point &pos, ieDword state);
void InitSpawn(const ieResRef DefaultArea);
void RespawnNameless();
void InitialSpawn();
+ void ExitSpawn();
void CheckSpawn();
};
+}
+
#endif // ! INISPAWN_H
diff --git a/gemrb/core/Interface.cpp b/gemrb/core/Interface.cpp
index c4db5c9..86c1b01 100644
--- a/gemrb/core/Interface.cpp
+++ b/gemrb/core/Interface.cpp
@@ -24,16 +24,17 @@
#include "Interface.h"
+#include "defsounds.h" // for DS_TOOLTIP
#include "exports.h"
#include "globals.h"
#include "strrefs.h"
#include "win32def.h"
+#include "ie_cursors.h"
#include "ActorMgr.h"
#include "AmbientMgr.h"
#include "AnimationMgr.h"
#include "ArchiveImporter.h"
-#include "Audio.h"
#include "Calendar.h"
#include "DataFileMgr.h"
#include "DialogHandler.h"
@@ -42,15 +43,18 @@
#include "EffectMgr.h"
#include "EffectQueue.h"
#include "Factory.h"
+#include "FontManager.h"
#include "Game.h"
#include "GameData.h"
+#include "GlobalTimer.h"
#include "ImageMgr.h"
#include "ItemMgr.h"
+#include "KeyMap.h"
#include "MapMgr.h"
#include "MoviePlayer.h"
#include "MusicMgr.h"
#include "Palette.h"
-#include "PluginMgr.h"
+#include "PluginLoader.h"
#include "PluginMgr.h"
#include "ProjectileServer.h"
#include "SaveGameIterator.h"
@@ -64,19 +68,23 @@
#include "SymbolMgr.h"
#include "TileMap.h"
#include "Video.h"
+#include "WindowMgr.h"
#include "WorldMapMgr.h"
#include "GameScript/GameScript.h"
#include "GUI/Button.h"
#include "GUI/Console.h"
+#include "GUI/EventMgr.h"
#include "GUI/GameControl.h"
#include "GUI/Label.h"
#include "GUI/MapControl.h"
+#include "GUI/Window.h"
#include "GUI/WorldMapControl.h"
#include "Scriptable/Container.h"
#include "System/FileStream.h"
#include "System/VFS.h"
+#include "System/StringBuffer.h"
-#if defined(__HAIKU__)
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -84,11 +92,9 @@
#include <time.h>
#include <vector>
-GEM_EXPORT Interface* core;
+namespace GemRB {
-#ifdef WIN32
-GEM_EXPORT HANDLE hConsole;
-#endif
+GEM_EXPORT Interface* core = NULL;
//use DialogF.tlk if the protagonist is female, that's why we leave space
static const char dialogtlk[] = "dialog.tlk\0";
@@ -106,15 +112,14 @@ static int **reputationmod = NULL;
static ieVariable IWD2DeathVarFormat = "_DEAD%s";
static ieVariable DeathVarFormat = "SPRITE_IS_DEAD%s";
-Interface::Interface(int iargc, char* iargv[])
+static ieWord IDT_FAILURE = 0;
+static ieWord IDT_CRITRANGE = 1;
+static ieWord IDT_CRITMULTI = 2;
+static ieWord IDT_SKILLPENALTY = 3;
+
+Interface::Interface()
{
- argc = iargc;
- argv = iargv;
-#ifdef WIN32
- hConsole = GetStdHandle( STD_OUTPUT_HANDLE );
-#endif
- textcolor( LIGHT_WHITE );
- printf( "GemRB Core Version v%s Loading...\n", VERSION_GEMRB );
+ Log(MESSAGE, "Core", "GemRB Core Version v%s Loading...", VERSION_GEMRB );
// default to the correct endianswitch
ieWord endiantest = 1;
@@ -139,6 +144,7 @@ Interface::Interface(int iargc, char* iargv[])
sgiterator = NULL;
game = NULL;
calendar = NULL;
+ keymap = NULL;
worldmap = NULL;
CurrentStore = NULL;
CurrentContainer = NULL;
@@ -169,7 +175,7 @@ Interface::Interface(int iargc, char* iargv[])
mousescrollspd = 10;
- strncpy( GameType, "auto", sizeof( GameType )-1);
+ GameType[0] = '\0';
ConsolePopped = false;
CheatFlag = false;
FogOfWar = 1;
@@ -180,12 +186,18 @@ Interface::Interface(int iargc, char* iargv[])
#else
CaseSensitive = false;
#endif
- GameOnCD = false;
SkipIntroVideos = false;
DrawFPS = false;
+ TouchScrollAreas = false;
+ UseSoftKeyboard = false;
KeepCache = false;
+ NumFingInfo = 2;
+ NumFingKboard = 3;
+ NumFingScroll = 2;
+ MouseFeedback = 0;
TooltipDelay = 100;
IgnoreOriginalINI = 0;
+ Bpp = 32;
FullScreen = 0;
GUIScriptsPath[0] = 0;
GamePath[0] = 0;
@@ -194,28 +206,30 @@ Interface::Interface(int iargc, char* iargv[])
PluginsPath[0] = 0;
CachePath[0] = 0;
GemRBOverridePath[0] = 0;
+ GemRBUnhardcodedPath[0] = 0;
GameName[0] = 0;
-
- strncpy( GameOverridePath, "override", sizeof(GameOverridePath) );
- strncpy( GameSoundsPath, "sounds", sizeof(GameSoundsPath) );
- strncpy( GameScriptsPath, "scripts", sizeof(GameScriptsPath) );
- strncpy( GamePortraitsPath, "portraits", sizeof(GamePortraitsPath) );
- strncpy( GameCharactersPath, "characters", sizeof(GameCharactersPath) );
- strncpy( GameDataPath, "data", sizeof(GameDataPath) );
- strncpy( INIConfig, "baldur.ini", sizeof(INIConfig) );
- strncpy( ButtonFont, "STONESML", sizeof(ButtonFont) );
- strncpy( TooltipFont, "STONESML", sizeof(TooltipFont) );
- strncpy( MovieFont, "STONESML", sizeof(MovieFont) );
- strncpy( ScrollCursorBam, "CURSARW", sizeof(ScrollCursorBam) );
- strncpy( GlobalScript, "BALDUR", sizeof(GlobalScript) );
- strncpy( WorldMapName[0], "WORLDMAP", sizeof(ieResRef) );
- memset( WorldMapName[1], 0, sizeof(ieResRef) );
- strncpy( Palette16, "MPALETTE", sizeof(Palette16) );
- strncpy( Palette32, "PAL32", sizeof(Palette32) );
- strncpy( Palette256, "MPAL256", sizeof(Palette256) );
+ CustomFontPath[0] = 0;
+ GameOverridePath[0] = 0;
+ GameSoundsPath[0] = 0;
+ GameScriptsPath[0] = 0;
+ GamePortraitsPath[0] = 0;
+ GameCharactersPath[0] = 0;
+ GameDataPath[0] = 0;
+
+ strlcpy( INIConfig, "baldur.ini", sizeof(INIConfig) );
+ CopyResRef( ButtonFont, "STONESML" );
+ CopyResRef( TooltipFont, "STONESML" );
+ CopyResRef( MovieFont, "STONESML" );
+ CopyResRef( ScrollCursorBam, "CURSARW" );
+ CopyResRef( GlobalScript, "BALDUR" );
+ CopyResRef( WorldMapName[0], "WORLDMAP" );
+ CopyResRef( WorldMapName[1], "" );
+ CopyResRef( Palette16, "MPALETTE" );
+ CopyResRef( Palette32, "PAL32" );
+ CopyResRef( Palette256, "MPAL256" );
strcpy( TooltipBackResRef, "\0" );
for (int size = 0; size < MAX_CIRCLE_SIZE; size++) {
- strcpy( GroundCircleBam[size], "\0" );
+ CopyResRef(GroundCircleBam[size], "");
GroundCircleScale[size] = 0;
}
TooltipColor.r = 0;
@@ -243,6 +257,8 @@ Interface::Interface(int iargc, char* iargv[])
update_scripts = false;
SpecialSpellsCount = -1;
SpecialSpells = NULL;
+ Encoding = "default";
+ TLKEncoding = "ISO-8859-1";
gamedata = new GameData();
}
@@ -269,7 +285,7 @@ static void ReleaseItemList(void *poi)
delete ((ItemList *) poi);
}
-void FreeAbilityTables()
+static void FreeAbilityTables()
{
if (strmod) {
free(strmod);
@@ -335,6 +351,7 @@ Interface::~Interface(void)
delete game;
delete calendar;
delete worldmap;
+ delete keymap;
FreeAbilityTables();
@@ -353,17 +370,20 @@ Interface::~Interface(void)
}
SurgeSpells.clear();
+ FreeResourceVector( Font, fonts );
+ // fonts need to be destroyed before TTF plugin
PluginMgr::Get()->RunCleanup();
ReleaseMemoryActor();
+ ReleaseMemorySpell();
EffectQueue_ReleaseMemory();
CharAnimations::ReleaseMemory();
- delete CurrentStore;
FreeResRefTable(DefSound, DSCount);
free( slottypes );
free( slotmatrix );
+ itemtypedata.clear();
delete sgiterator;
@@ -374,7 +394,6 @@ Interface::~Interface(void)
delete[] Cursors;
}
- FreeResourceVector( Font, fonts );
FreeResourceVector( Window, windows );
size_t i;
@@ -426,7 +445,9 @@ Interface::~Interface(void)
gamedata->FreePalette(InfoTextPalette);
}
- video->SetDragCursor(NULL);
+ video->SetCursor(NULL, VID_CUR_DRAG);
+ video->SetCursor(NULL, VID_CUR_UP);
+ video->SetCursor(NULL, VID_CUR_DOWN);
}
delete evntmgr;
@@ -468,6 +489,9 @@ Interface::~Interface(void)
// Removing all stuff from Cache, except bifs
if (!KeepCache) DelTree((const char *) CachePath, true);
+
+ AudioDriver.release();
+ video.release();
}
void Interface::SetWindowFrame(int i, Sprite2D *Picture)
@@ -608,6 +632,13 @@ void Interface::HandleEvents()
gc->UpdateTargetMode();
return;
}
+
+ if (EventFlag&EF_TEXTSCREEN) {
+ EventFlag&=~EF_TEXTSCREEN;
+ video->SetMouseEnabled(true);
+ guiscript->RunFunction( "TextScreen", "StartTextScreen" );
+ return;
+ }
}
/* handle main loop events that might destroy or create windows
@@ -647,7 +678,7 @@ void Interface::HandleFlags()
gc->ChangeMap(actor, true);
}
} else {
- printMessage("Core", "No game to enter...\n", LIGHT_RED);
+ Log(ERROR, "Core", "No game to enter...");
QuitFlag = QF_QUITGAME;
}
}
@@ -659,7 +690,7 @@ void Interface::HandleFlags()
}
}
-bool GenerateAbilityTables()
+static bool GenerateAbilityTables()
{
FreeAbilityTables();
@@ -768,6 +799,7 @@ bool Interface::ReadGameTimeTable()
Time.turn_sec = atoi(table->QueryField("TURN_SECONDS", "DURATION"));
Time.round_size = Time.round_sec * AI_UPDATE_TIME;
Time.rounds_per_turn = Time.turn_sec / Time.round_sec;
+ Time.attack_round_size = atoi(table->QueryField("ATTACK_ROUND", "DURATION"));
return true;
}
@@ -794,7 +826,7 @@ bool Interface::ReadSpecialSpells()
if (table) {
SurgeSpell ss;
for (i = 0; (unsigned)i < table->GetRowCount(); i++) {
- strncpy(ss.spell, table->QueryField(i, 0), 8);
+ CopyResRef(ss.spell, table->QueryField(i, 0));
ss.message = strtol(table->QueryField(i, 1), NULL, 0);
// comment ignored
SurgeSpells.push_back(ss);
@@ -806,7 +838,7 @@ bool Interface::ReadSpecialSpells()
return result;
}
-int Interface::GetSpecialSpell(ieResRef resref)
+int Interface::GetSpecialSpell(const ieResRef resref)
{
for (int i=0;i<SpecialSpellsCount;i++) {
if (!strnicmp(resref, SpecialSpells[i].resref, sizeof(ieResRef))) {
@@ -817,22 +849,27 @@ int Interface::GetSpecialSpell(ieResRef resref)
}
//disable spells based on some circumstances
-int Interface::CheckSpecialSpell(ieResRef resref, Actor *actor)
+int Interface::CheckSpecialSpell(const ieResRef resref, Actor *actor)
{
int sp = GetSpecialSpell(resref);
//the identify spell is always disabled on the menu
if (sp&SP_IDENTIFY) {
- return 1;
+ return SP_IDENTIFY;
}
//if actor is silenced, and spell cannot be cast in silence, disable it
if (actor->GetStat(IE_STATE_ID) & STATE_SILENCED ) {
if (!(sp&SP_SILENCE)) {
- return 1;
+ return SP_SILENCE;
}
}
+ // disable spells causing surges to be cast while in a surge (prevents nesting)
+ if (sp&SP_SURGE) {
+ return SP_SURGE;
+ }
+
return 0;
}
@@ -940,7 +977,7 @@ int Interface::GetItemTooltip(const ieResRef itemname, int header, int identifie
if (value && (value[header]>=0)) {
return value[header];
}
- Item *item = gamedata->GetItem(itemname);
+ Item *item = gamedata->GetItem(itemname, true);
if (!item) {
return -1;
}
@@ -1028,7 +1065,8 @@ bool Interface::ReadDamageTypeTable() {
di.resist_stat = TranslateStat(tm->QueryField(i, 1));
di.value = strtol(tm->QueryField(i, 2), (char **) NULL, 16);
di.iwd_mod_type = atoi(tm->QueryField(i, 3));
- DamageInfoMap.insert(std::make_pair <ieDword, DamageInfoStruct> ((ieDword)di.value, di));
+ di.reduction = atoi(tm->QueryField(i, 4));
+ DamageInfoMap.insert(std::make_pair ((ieDword)di.value, di));
}
return true;
@@ -1059,7 +1097,7 @@ bool Interface::ReadModalStates()
ModalStatesStruct ms;
for (unsigned short i = 0; i < table->GetRowCount(); i++) {
- strncpy(ms.spell, table->QueryField(i, 0), 8);
+ CopyResRef(ms.spell, table->QueryField(i, 0));
strncpy(ms.action, table->QueryField(i, 1), 16);
ms.entering_str = atoi(table->QueryField(i, 2));
ms.leaving_str = atoi(table->QueryField(i, 3));
@@ -1091,8 +1129,7 @@ void Interface::Main()
ieDword speed = 10;
vars->Lookup("Full Screen", FullScreen);
- video->CreateDisplay( Width, Height, Bpp, FullScreen);
- video->SetDisplayTitle( GameName, GameType );
+ video->CreateDisplay( Width, Height, Bpp, FullScreen, GameName);
vars->Lookup("Brightness Correction", brightness);
vars->Lookup("Gamma Correction", contrast);
vars->Lookup("Mouse Scroll Speed", speed);
@@ -1106,13 +1143,13 @@ void Interface::Main()
Font* fps = GetFont( ( unsigned int ) 0 );
char fpsstring[40]={"???.??? fps"};
unsigned long frame = 0, time, timebase;
- GetTime(timebase);
+ timebase = GetTickCount();
double frames = 0.0;
Palette* palette = CreatePalette( white, black );
do {
//don't change script when quitting is pending
- while (QuitFlag) {
+ while (QuitFlag && QuitFlag != QF_KILL) {
HandleFlags();
}
//eventflags are processed only when there is a game
@@ -1122,10 +1159,10 @@ void Interface::Main()
HandleGUIBehaviour();
GameLoop();
- DrawWindows();
+ DrawWindows(true);
if (DrawFPS) {
frame++;
- GetTime( time );
+ time = GetTickCount();
if (time - timebase > 1000) {
frames = ( frame * 1000.0 / ( time - timebase ) );
timebase = time;
@@ -1139,7 +1176,7 @@ void Interface::Main()
}
if (TickHook)
TickHook->call();
- } while (video->SwapBuffers() == GEM_OK);
+ } while (video->SwapBuffers() == GEM_OK && !(QuitFlag&QF_KILL));
gamedata->FreePalette( palette );
}
@@ -1153,8 +1190,7 @@ int Interface::ReadResRefTable(const ieResRef tablename, ieResRef *&data)
}
AutoTable tm(tablename);
if (!tm) {
- printStatus( "ERROR", LIGHT_RED );
- printf( "Cannot find %s.2da.\n",tablename );
+ Log(ERROR, "Core", "Cannot find %s.2da.", tablename);
return 0;
}
count = tm->GetRowCount();
@@ -1174,11 +1210,11 @@ int Interface::LoadSprites()
ieDword i;
int size;
if (!IsAvailable( IE_2DA_CLASS_ID )) {
- printf( "No 2DA Importer Available.\nTermination in Progress...\n" );
+ Log(ERROR, "Core", "No 2DA Importer Available.");
return GEM_ERROR;
}
- //loading cursors
+ Log(MESSAGE, "Core", "Loading Cursors...");
AnimationFactory* anim;
anim = (AnimationFactory*) gamedata->GetFactoryResource("cursors", IE_BAM_CLASS_ID);
if (anim)
@@ -1189,22 +1225,22 @@ int Interface::LoadSprites()
Cursors[i] = anim->GetFrame( 0, (ieByte) i );
}
}
- printMessage( "Core", "Loading Cursors...", WHITE );
// this is the last existing cursor type
if (CursorCount<IE_CURSOR_WAY) {
- printStatus( "ERROR", LIGHT_RED );
+ Log(ERROR, "Core", "Failed to load enough cursors (%d < %d).",
+ CursorCount, IE_CURSOR_WAY);
return GEM_ERROR;
}
- video->SetCursor( Cursors[0], Cursors[1] );
- printStatus( "OK", LIGHT_GREEN );
+ video->SetCursor( Cursors[0], VID_CUR_UP );
+ video->SetCursor( Cursors[1], VID_CUR_DOWN );
// Load fog-of-war bitmaps
anim = (AnimationFactory*) gamedata->GetFactoryResource("fogowar", IE_BAM_CLASS_ID);
- printMessage( "Core", "Loading Fog-Of-War bitmaps...", WHITE );
+ Log(MESSAGE, "Core", "Loading Fog-Of-War bitmaps...");
if (!anim || anim->GetCycleSize( 0 ) != 8) {
// unknown type of fog anim
- printStatus( "ERROR", LIGHT_RED );
+ Log(ERROR, "Core", "Failed to load Fog-of-War bitmaps.");
return GEM_ERROR;
}
@@ -1272,8 +1308,6 @@ int Interface::LoadSprites()
}
}
- printStatus( "OK", LIGHT_GREEN );
-
// Load ground circle bitmaps (PST only)
//block required due to msvc6.0 incompatibility
for (size = 0; size < MAX_CIRCLE_SIZE; size++) {
@@ -1281,8 +1315,7 @@ int Interface::LoadSprites()
anim = (AnimationFactory*) gamedata->GetFactoryResource(GroundCircleBam[size], IE_BAM_CLASS_ID);
if (!anim || anim->GetCycleCount() != 6) {
// unknown type of circle anim
- printMessage( "Core", "Loading Ground circle bitmaps...", WHITE );
- printStatus( "ERROR", LIGHT_RED );
+ Log(ERROR, "Core", "Loading Ground circle bitmaps...");
return GEM_ERROR;
}
@@ -1298,43 +1331,65 @@ int Interface::LoadSprites()
}
}
- printMessage( "Core", "Loading Ground circle bitmaps...", WHITE );
- printStatus( "OK", LIGHT_GREEN );
+ Log(MESSAGE, "Core", "Loading Ground circle bitmaps...");
- printMessage( "Core", "Loading Fonts...\n", WHITE );
+ Log(MESSAGE, "Core", "Loading Fonts...");
AutoTable tab("fonts");
if (!tab) {
- printStatus( "ERROR", LIGHT_RED );
- printf( "Cannot find fonts.2da.\nTermination in Progress...\n" );
+ Log(ERROR, "Core", "Cannot find fonts.2da.");
return GEM_ERROR;
- } else {
- PluginHolder<AnimationMgr> bamint(IE_BAM_CLASS_ID);
- if (!bamint) {
- printStatus( "ERROR", LIGHT_RED );
- printf( "No BAM Importer Available.\nTermination in Progress...\n" );
- return GEM_ERROR;
- }
- DataStream* str = NULL;
+ }
- int count = tab->GetRowCount();
- for (int i = 0; i < count; i++) {
- const char* ResRef = tab->QueryField( i, 0 );
- int needpalette = atoi( tab->QueryField( i, 1 ) );
- int first_char = atoi( tab->QueryField( i, 2 ) );
- str = gamedata->GetResource( ResRef, IE_BAM_CLASS_ID );
- if (!bamint->Open( str, true )) {
- continue;
- }
- Font* fnt = bamint->GetFont();
- if (!fnt) {
- continue;
+ int count = tab->GetRowCount();
+ const char* rowName = NULL;
+ for (int row = 0; row < count; row++) {
+ rowName = tab->GetRowName(row);
+ const char* ResRef = tab->QueryField(rowName, "RESREF");
+ int needpalette = atoi(tab->QueryField(rowName, "NEED_PALETTE"));
+
+ const char* font_name;
+ unsigned short font_size = 0;
+ FontStyle font_style = NORMAL;
+
+ if (CustomFontPath[0]) {
+ font_name = tab->QueryField( rowName, "FONT_NAME" );// map a font alternative to the BAM ResRef since CHUs contain hardcoded refrences.
+ font_size = atoi( tab->QueryField( rowName, "PT_SIZE" ) );// not available in BAM fonts.
+ font_style = (FontStyle)atoi( tab->QueryField( rowName, "STYLE" ) );// not available in BAM fonts.
+ }else{
+ font_name = ResRef;
+ }
+
+ // Do search for existing font here
+ Font* fnt = NULL;
+ for (size_t fntIdx = 0; fntIdx < fonts.size(); fntIdx++) {
+ if (stricmp(fonts[fntIdx]->GetName(), font_name) == 0
+ && fonts[fntIdx]->GetStyle() == font_style
+ && fonts[fntIdx]->GetPointSize() == font_size) {
+ fnt = fonts[fntIdx];
+ fnt->AddResRef(ResRef);
+ break;
}
- strnlwrcpy( fnt->ResRef, ResRef, 8 );
- if (needpalette) {
+ }
+ if (fnt) {
+ Log(MESSAGE, "Core", "Found existing font for %s.", ResRef);
+ // what about palette etc?
+ continue;
+ } else {
+ Palette* pal = NULL;
+ if (needpalette || (CustomFontPath[0] && strnicmp( font_name, ResRef, sizeof(ieResRef)-1) != 0 )) {//non-BAM fonts
Color fore = {0xff, 0xff, 0xff, 0};
Color back = {0x00, 0x00, 0x00, 0};
- if (!strnicmp( TooltipFont, ResRef, 8) ) {
+ if (CustomFontPath[0]) {
+ const char* colorString = tab->QueryField( rowName, "COLOR" );
+ unsigned long combinedColor = strtoul(colorString, NULL, 16);
+ ieByte* color = (ieByte*)&combinedColor;
+ fore.r = *color++;
+ fore.g = *color++;
+ fore.b = *color++;
+ fore.a = *color++;
+ }
+ if (!strnicmp(TooltipFont, ResRef, sizeof(ieResRef)-1)) {
if (TooltipColor.a==0xff) {
fore = TooltipColor;
} else {
@@ -1342,44 +1397,49 @@ int Interface::LoadSprites()
back = TooltipColor;
}
}
- Palette* pal = CreatePalette( fore, back );
- pal->CreateShadedAlphaChannel();
- fnt->SetPalette(pal);
- gamedata->FreePalette( pal );
+ pal = CreatePalette(fore, back);
}
- fnt->SetFirstChar( (ieByte) first_char );
- fonts.push_back( fnt );
+ ResourceHolder<FontManager> fntMgr(font_name);
+ if (fntMgr) fnt = fntMgr->GetFont(font_size, font_style, pal);
+ gamedata->FreePalette(pal);
}
- if (fonts.size() == 0) {
- printMessage( "Core", "No default font loaded! ", WHITE );
- printStatus( "ERROR", LIGHT_RED );
- return GEM_ERROR;
- }
- if (GetFont( ButtonFont ) == NULL) {
- printMessage( "Core", "ButtonFont not loaded: ", WHITE );
- printf("%s ", ButtonFont);
- printStatus( "WARNING", YELLOW );
- }
- if (GetFont( MovieFont ) == NULL) {
- printMessage( "Core", "MovieFont not loaded: ", WHITE );
- printf("%s ", MovieFont);
- printStatus( "WARNING", YELLOW );
- }
- if (GetFont( TooltipFont ) == NULL) {
- printMessage( "Core", "TooltipFont not loaded: ", WHITE );
- printf("%s ", TooltipFont);
- printStatus( "WARNING", YELLOW );
+ if (!fnt) {
+ Log(WARNING, "Core", "Unable to load font resource: %s", ResRef);
+ continue;
}
+
+ fnt->AddResRef(ResRef);
+ fnt->SetName(font_name);
+
+ fonts.push_back(fnt);
}
- printMessage( "Core", "Fonts Loaded...", WHITE );
- printStatus( "OK", LIGHT_GREEN );
+
+ if (fonts.size() == 0) {
+ Log(ERROR, "Core", "No default font loaded!");
+ return GEM_ERROR;
+ }
+
+ if (GetFont( ButtonFont ) == NULL) {
+ Log(WARNING, "Core", "ButtonFont not loaded: %s",
+ ButtonFont);
+ }
+ if (GetFont( MovieFont ) == NULL) {
+ Log(WARNING, "Core", "MovieFont not loaded: %s",
+ MovieFont);
+ }
+ if (GetFont( TooltipFont ) == NULL) {
+ Log(WARNING, "Core", "TooltipFont not loaded: %s",
+ TooltipFont);
+ }
+
+ Log(MESSAGE, "Core", "Fonts Loaded...");
if (TooltipBackResRef[0]) {
anim = (AnimationFactory*) gamedata->GetFactoryResource(TooltipBackResRef, IE_BAM_CLASS_ID);
- printMessage( "Core", "Initializing Tooltips...", WHITE );
+ Log(MESSAGE, "Core", "Initializing Tooltips...");
if (!anim) {
- printStatus( "ERROR", LIGHT_RED );
+ Log(ERROR, "Core", "Failed to initialize tooltips.");
return GEM_ERROR;
}
TooltipBack = new Sprite2D * [3];
@@ -1388,56 +1448,217 @@ int Interface::LoadSprites()
TooltipBack[i]->XPos = 0;
TooltipBack[i]->YPos = 0;
}
- printStatus( "OK", LIGHT_GREEN );
}
return GEM_OK;
}
-int Interface::Init()
+int Interface::Init(InterfaceConfig* config)
{
+ if (!config) {
+ Log(FATAL, "Core", "No Configuration context.");
+ return GEM_ERROR;
+ }
+
+ //once GemRB own format is working well, this might be set to 0
+ SaveAsOriginal = 1;
+
plugin_flags = new Variables();
plugin_flags->SetType( GEM_VARIABLES_INT );
- printMessage( "Core", "Initializing the Event Manager...", WHITE );
+ Log(MESSAGE, "Core", "Initializing the Event Manager...");
evntmgr = new EventMgr();
- printMessage( "Core", "Initializing Lists Dictionary...", WHITE );
lists = new Variables();
if (!lists) {
- printStatus( "ERROR", LIGHT_RED );
+ Log(FATAL, "Core", "Failed to allocate Lists dictionary.");
return GEM_ERROR;
}
lists->SetType( GEM_VARIABLES_POINTER );
- printMessage( "Core", "Initializing Variables Dictionary...", WHITE );
vars = new Variables();
if (!vars) {
- printStatus( "ERROR", LIGHT_RED );
+ Log(FATAL, "Core", "Failed to allocate Variables dictionary");
return GEM_ERROR;
}
vars->SetType( GEM_VARIABLES_INT );
vars->ParseKey(true);
- vars->SetAt( "Volume Ambients", 100 );
- vars->SetAt( "Volume Movie", 100 );
- vars->SetAt( "Volume Music", 100 );
- vars->SetAt( "Volume SFX", 100 );
- vars->SetAt( "Volume Voices", 100 );
- printStatus( "OK", LIGHT_GREEN );
+ const char* value = NULL;
+#define CONFIG_INT(key, var) \
+ value = config->GetValueForKey(key); \
+ if (value) \
+ var ( atoi( value ) ); \
+ value = NULL;
+
+ CONFIG_INT("Bpp", Bpp =);
+ vars->SetAt("BitsPerPixel", Bpp); //put into vars so that reading from game.ini wont overwrite
+ CONFIG_INT("CaseSensitive", CaseSensitive =);
+ CONFIG_INT("DoubleClickDelay", evntmgr->SetDCDelay);
+ CONFIG_INT("DrawFPS", DrawFPS = );
+ CONFIG_INT("EnableCheatKeys", EnableCheatKeys);
+ CONFIG_INT("EndianSwitch", DataStream::SetEndianSwitch);
+ CONFIG_INT("FogOfWar", FogOfWar = );
+ CONFIG_INT("FullScreen", FullScreen = );
+ vars->SetAt("Full Screen", FullScreen); //put into vars so that reading from game.ini wont overwrite
+ CONFIG_INT("GUIEnhancements", GUIEnhancements = );
+ CONFIG_INT("TouchScrollAreas", TouchScrollAreas = );
+ CONFIG_INT("Height", Height = );
+ CONFIG_INT("KeepCache", KeepCache = );
+ CONFIG_INT("MultipleQuickSaves", MultipleQuickSaves = );
+ CONFIG_INT("RepeatKeyDelay", evntmgr->SetRKDelay);
+ CONFIG_INT("SaveAsOriginal", SaveAsOriginal = );
+ CONFIG_INT("ScriptDebugMode", SetScriptDebugMode);
+ CONFIG_INT("SkipIntroVideos", SkipIntroVideos = );
+ CONFIG_INT("TooltipDelay", TooltipDelay = );
+ CONFIG_INT("Width", Width = );
+ CONFIG_INT("IgnoreOriginalINI", IgnoreOriginalINI = );
+ CONFIG_INT("UseSoftKeyboard", UseSoftKeyboard = );
+ CONFIG_INT("NumFingScroll", NumFingScroll = );
+ CONFIG_INT("NumFingKboard", NumFingKboard = );
+ CONFIG_INT("NumFingInfo", NumFingInfo = );
+ CONFIG_INT("MouseFeedback", MouseFeedback = );
+#undef CONFIG_INT
- if (!LoadConfig()) {
- return GEM_ERROR;
+#define CONFIG_STRING(key, var, default) \
+ value = config->GetValueForKey(key); \
+ if (value && value[0]) { \
+ strlcpy(var, value, sizeof(var)); \
+ } else if (default && default[0]) { \
+ strlcpy(var, default, sizeof(var)); \
+ } else var[0] = '\0'; \
+ value = NULL;
+
+ CONFIG_STRING("GameCharactersPath", GameCharactersPath, "characters");
+ CONFIG_STRING("GameDataPath", GameDataPath, "data");
+ // TODO: make CustomFontPath cross platform and possibly dynamic
+ CONFIG_STRING("CustomFontPath", CustomFontPath, "/usr/share/fonts/TTF");
+ CONFIG_STRING("GameName", GameName, GEMRB_STRING);
+ CONFIG_STRING("GameOverridePath", GameOverridePath, "override");
+ CONFIG_STRING("GamePortraitsPath", GamePortraitsPath, "portraits");
+ CONFIG_STRING("GameScriptsPath", GameScriptsPath, "scripts");
+ CONFIG_STRING("GameSoundsPath", GameSoundsPath, "sounds");
+ CONFIG_STRING("GameType", GameType, "auto");
+ // tob type is obsolete
+ if (stricmp( GameType, "tob" ) == 0) {
+ strlcpy( GameType, "bg2", sizeof(GameType) );
+ }
+
+#undef CONFIG_STRING
+
+// assumes that default value does not need to be resolved or fixed in any way
+#define CONFIG_PATH(key, var, default) \
+ value = config->GetValueForKey(key); \
+ if (value && value[0]) { \
+ strlcpy(var, value, sizeof(var)); \
+ ResolveFilePath(var); \
+ FixPath(var, true); \
+ } else if (default && default[0]) { \
+ strlcpy(var, default, sizeof(var)); \
+ } else var[0] = '\0'; \
+ value = NULL;
+
+ // Path configureation
+ CONFIG_PATH("GemRBPath", GemRBPath,
+ CopyGemDataPath(GemRBPath, _MAX_PATH));
+
+ CONFIG_PATH("CachePath", CachePath, "./Cache");
+ FixPath( CachePath, false );
+
+ CONFIG_PATH("GUIScriptsPath", GUIScriptsPath, GemRBPath);
+ CONFIG_PATH("GamePath", GamePath, "");
+
+ CONFIG_PATH("GemRBOverridePath", GemRBOverridePath, GemRBPath);
+ CONFIG_PATH("GemRBUnhardcodedPath", GemRBUnhardcodedPath, GemRBPath);
+#ifdef PLUGINDIR
+ CONFIG_PATH("PluginsPath", PluginsPath, PLUGINDIR);
+#else
+ CONFIG_PATH("PluginsPath", PluginsPath, "");
+ if (!PluginsPath[0]) {
+ PathJoin( PluginsPath, GemRBPath, "plugins", NULL );
+ }
+#endif
+
+ CONFIG_PATH("SavePath", SavePath, GamePath);
+#undef CONFIG_STRING
+
+#define CONFIG_STRING(key, var) \
+ value = config->GetValueForKey(key); \
+ if (value) \
+ var = value; \
+ value = NULL;
+
+ CONFIG_STRING("AudioDriver", AudioDriverName);
+ CONFIG_STRING("VideoDriver", VideoDriverName);
+ CONFIG_STRING("Encoding", Encoding);
+#undef CONFIG_STRING
+
+ value = config->GetValueForKey("ModPath");
+ if (value) {
+ for (char *path = strtok((char*)value,SPathListSeparator);
+ path;
+ path = strtok(NULL,SPathListSeparator)) {
+ ModPath.push_back(path);
+ ResolveFilePath(ModPath.back());
+ }
+ }
+ value = config->GetValueForKey("SkipPlugin");
+ if (value) {
+ plugin_flags->SetAt( value, PLF_SKIP );
+ }
+ value = config->GetValueForKey("DelayPlugin");
+ if (value) {
+ plugin_flags->SetAt( value, PLF_DELAY );
}
- printMessage( "Core", "Starting Plugin Manager...\n", WHITE );
+
+ int i = 0;
+ for(i = 0; i < MAX_CD; i++) {
+ char keyname[] = { 'C', 'D', char('1'+i), '\0' };
+ value = config->GetValueForKey(keyname);
+ if (value) {
+ for(char *path = strtok((char*)value, SPathListSeparator);
+ path;
+ path = strtok(NULL,SPathListSeparator)) {
+ CD[i].push_back(path);
+ ResolveFilePath(CD[i].back());
+ }
+ } else {
+ // nothing in config so create our own
+ char name[_MAX_PATH];
+
+ PathJoin(name, GamePath, keyname, NULL);
+ CD[i].push_back(name);
+ PathJoin(name, GamePath, GameDataPath, keyname, NULL);
+ CD[i].push_back(name);
+ }
+ }
+
+ if (!MakeDirectories(CachePath)) {
+ error("Core", "Unable to create cache directory '%s'", CachePath);
+ }
+
+ if ( StupidityDetector( CachePath )) {
+ Log(ERROR, "Core", "Cache path %s doesn't exist, not a folder or contains alien files!", CachePath );
+ return false;
+ }
+ if (!KeepCache) DelTree((const char *) CachePath, false);
+
+ Log(MESSAGE, "Core", "Starting Plugin Manager...");
PluginMgr *plugin = PluginMgr::Get();
- plugin->LoadPlugins(PluginsPath);
+#if TARGET_OS_MAC
+ // search the bundle plugins first
+ // since bundle plugins are loaded first dyld will give them precedence
+ // if duplicates are found in the PluginsPath
+ char bundlePluginsPath[_MAX_PATH];
+ CopyBundlePath(bundlePluginsPath, sizeof(bundlePluginsPath), PLUGINS);
+ ResolveFilePath(bundlePluginsPath);
+ LoadPlugins(bundlePluginsPath);
+#endif
+ LoadPlugins(PluginsPath);
if (plugin && plugin->GetPluginCount()) {
- printMessage( "Core", "Plugin Loading Complete...", WHITE );
- printStatus( "OK", LIGHT_GREEN );
+ Log(MESSAGE, "Core", "Plugin Loading Complete...");
} else {
- printMessage( "Core", "Plugin Loading Failed, check path...", YELLOW);
- printStatus( "ERROR", LIGHT_RED );
+ Log(FATAL, "Core", "Plugin Loading Failed, check path...");
return GEM_ERROR;
}
plugin->RunInitializers();
@@ -1445,125 +1666,153 @@ int Interface::Init()
time_t t;
t = time( NULL );
srand( ( unsigned int ) t );
-#ifdef _DEBUG
- FileStreamPtrCount = 0;
- CachedFileStreamPtrCount = 0;
-#endif
- printMessage( "Core", "GemRB Core Initialization...\n", WHITE );
- printStatus( "OK", LIGHT_GREEN );
- printMessage( "Core", "Initializing Video Driver...", WHITE );
+
+ Log(MESSAGE, "Core", "GemRB Core Initialization...");
+ Log(MESSAGE, "Core", "Initializing Video Driver...");
video = ( Video * ) PluginMgr::Get()->GetDriver(&Video::ID, VideoDriverName.c_str());
if (!video) {
- printStatus( "ERROR", LIGHT_RED );
- printf( "No Video Driver Available.\nTermination in Progress...\n" );
+ Log(FATAL, "Core", "No Video Driver Available.");
return GEM_ERROR;
}
if (video->Init() == GEM_ERROR) {
- printStatus( "ERROR", LIGHT_RED );
- printf( "Cannot Initialize Video Driver.\nTermination in Progress...\n" );
+ Log(FATAL, "Core", "Cannot Initialize Video Driver.");
return GEM_ERROR;
}
Color defcolor={255,255,255,200};
SetInfoTextColor(defcolor);
- printStatus( "OK", LIGHT_GREEN );
{
- printMessage( "Core", "Initializing Search Path...", WHITE );
+ Log(MESSAGE, "Core", "Initializing Search Path...");
if (!IsAvailable( PLUGIN_RESOURCE_DIRECTORY )) {
- printf( "no DirectoryImporter! " );
- printStatus( "ERROR", LIGHT_RED );
+ Log(FATAL, "Core", "no DirectoryImporter!");
return GEM_ERROR;
}
char path[_MAX_PATH];
PathJoin( path, CachePath, NULL);
- gamedata->AddSource(path, "Cache", PLUGIN_RESOURCE_DIRECTORY);
-
- PathJoin( path, GemRBOverridePath, "override", GameType, NULL);
- gamedata->AddSource(path, "GemRB Override", PLUGIN_RESOURCE_DIRECTORY);
+ if (!gamedata->AddSource(path, "Cache", PLUGIN_RESOURCE_DIRECTORY)) {
+ Log(FATAL, "Core", "The cache path couldn't be registered, please check!");
+ return GEM_ERROR;
+ }
size_t i;
for (i = 0; i < ModPath.size(); ++i)
- gamedata->AddSource(ModPath[i].c_str(), "Mod paths", PLUGIN_RESOURCE_DIRECTORY);
+ gamedata->AddSource(ModPath[i].c_str(), "Mod paths", PLUGIN_RESOURCE_CACHEDDIRECTORY);
+
+ PathJoin( path, GemRBOverridePath, "override", GameType, NULL);
+ if (!strcmp( GameType, "auto" ))
+ gamedata->AddSource(path, "GemRB Override", PLUGIN_RESOURCE_NULL);
+ else
+ gamedata->AddSource(path, "GemRB Override", PLUGIN_RESOURCE_CACHEDDIRECTORY);
PathJoin( path, GemRBOverridePath, "override", "shared", NULL);
- gamedata->AddSource(path, "shared GemRB Override", PLUGIN_RESOURCE_DIRECTORY);
+ gamedata->AddSource(path, "shared GemRB Override", PLUGIN_RESOURCE_CACHEDDIRECTORY);
PathJoin( path, GamePath, GameOverridePath, NULL);
- gamedata->AddSource(path, "Override", PLUGIN_RESOURCE_DIRECTORY);
+ gamedata->AddSource(path, "Override", PLUGIN_RESOURCE_CACHEDDIRECTORY);
+ //GAME sounds are intentionally not cached, in IWD there are directory structures,
+ //that are not cacheable, also it is totally pointless (this fixed charsounds in IWD)
PathJoin( path, GamePath, GameSoundsPath, NULL);
gamedata->AddSource(path, "Sounds", PLUGIN_RESOURCE_DIRECTORY);
PathJoin( path, GamePath, GameScriptsPath, NULL);
- gamedata->AddSource(path, "Scripts", PLUGIN_RESOURCE_DIRECTORY);
+ gamedata->AddSource(path, "Scripts", PLUGIN_RESOURCE_CACHEDDIRECTORY);
PathJoin( path, GamePath, GamePortraitsPath, NULL);
- gamedata->AddSource(path, "Portraits", PLUGIN_RESOURCE_DIRECTORY);
+ gamedata->AddSource(path, "Portraits", PLUGIN_RESOURCE_CACHEDDIRECTORY);
PathJoin( path, GamePath, GameDataPath, NULL);
- gamedata->AddSource(path, "Data", PLUGIN_RESOURCE_DIRECTORY);
+ gamedata->AddSource(path, "Data", PLUGIN_RESOURCE_CACHEDDIRECTORY);
//IWD2 movies are on the CD but not in the BIF
char *description = strdup("CD1/data");
for (i = 0; i < MAX_CD; i++) {
for (size_t j=0;j<CD[i].size();j++) {
- description[2]='1'+i;
+ description[2]='1'+i;
PathJoin( path, CD[i][j].c_str(), GameDataPath, NULL);
- gamedata->AddSource(path, description, PLUGIN_RESOURCE_DIRECTORY);
+ gamedata->AddSource(path, description, PLUGIN_RESOURCE_CACHEDDIRECTORY);
}
}
free(description);
- printStatus( "OK", LIGHT_GREEN );
+ // most of the old gemrb override files can be found here,
+ // so they have a lower priority than the game files and can more easily be modded
+ PathJoin( path, GemRBUnhardcodedPath, "unhardcoded", GameType, NULL);
+ if (!strcmp(GameType, "auto")) {
+ gamedata->AddSource(path, "GemRB Unhardcoded data", PLUGIN_RESOURCE_NULL);
+ } else {
+ gamedata->AddSource(path, "GemRB Unhardcoded data", PLUGIN_RESOURCE_CACHEDDIRECTORY);
+ }
+ PathJoin( path, GemRBUnhardcodedPath, "unhardcoded", "shared", NULL);
+ gamedata->AddSource(path, "shared GemRB Unhardcoded data", PLUGIN_RESOURCE_CACHEDDIRECTORY);
}
{
- printMessage( "Core", "Initializing KEY Importer...", WHITE );
+ Log(MESSAGE, "Core", "Initializing KEY Importer...");
char ChitinPath[_MAX_PATH];
PathJoin( ChitinPath, GamePath, "chitin.key", NULL );
if (!gamedata->AddSource(ChitinPath, "chitin.key", PLUGIN_RESOURCE_KEY)) {
- printStatus( "ERROR", LIGHT_RED );
+ Log(FATAL, "Core", "Failed to load \"chitin.key\"");
return GEM_ERROR;
}
- printStatus( "OK", LIGHT_GREEN );
}
- printMessage( "Core", "Initializing GUI Script Engine...", WHITE );
+ Log(MESSAGE, "Core", "Initializing GUI Script Engine...");
guiscript = PluginHolder<ScriptEngine>(IE_GUI_SCRIPT_CLASS_ID);
if (guiscript == NULL) {
- printStatus( "ERROR", LIGHT_RED );
+ Log(FATAL, "Core", "Missing GUI Script Engine.");
return GEM_ERROR;
}
if (!guiscript->Init()) {
- printStatus( "ERROR", LIGHT_RED );
+ Log(FATAL, "Core", "Failed to initialize GUI Script.");
return GEM_ERROR;
}
- printStatus( "OK", LIGHT_GREEN );
strcpy( NextScript, "Start" );
{
// re-set the gemrb override path, since we now have the correct GameType if 'auto' was used
char path[_MAX_PATH];
PathJoin( path, GemRBOverridePath, "override", GameType, NULL);
- gamedata->AddSource(path, "GemRB Override", PLUGIN_RESOURCE_DIRECTORY, RM_REPLACE_SAME_SOURCE);
+ gamedata->AddSource(path, "GemRB Override", PLUGIN_RESOURCE_CACHEDDIRECTORY, RM_REPLACE_SAME_SOURCE);
+ PathJoin( path, GemRBUnhardcodedPath, "unhardcoded", GameType, NULL);
+ gamedata->AddSource(path, "GemRB Unhardcoded data", PLUGIN_RESOURCE_CACHEDDIRECTORY, RM_REPLACE_SAME_SOURCE);
}
- printMessage( "Core", "Reading Game Options...\n", WHITE );
+ // Purposely add the font directory last since we will only ever need it at engine load time.
+ if (CustomFontPath[0]) gamedata->AddSource(CustomFontPath, "CustomFonts", PLUGIN_RESOURCE_DIRECTORY);
+
+ Log(MESSAGE, "Core", "Reading Game Options...");
if (!LoadGemRBINI()) {
- printf( "Cannot Load INI\nTermination in Progress...\n" );
+ Log(FATAL, "Core", "Cannot Load INI.");
return GEM_ERROR;
}
- //loading baldur.ini
+ // load the game ini (baldur.ini, torment.ini, icewind.ini ...)
+ // read from our version of the config if it is present
+ char ini_path[_MAX_PATH] = { '\0' };
+ char gemrbINI[_MAX_PATH] = { '\0' };
+ char tmp[_MAX_PATH] = { '\0' };
+ snprintf(gemrbINI, sizeof(gemrbINI), "gem-%s", INIConfig);
+ PathJoin(ini_path, GamePath, gemrbINI, NULL);
+ if (file_exists(ini_path)) {
+ strlcpy(tmp, INIConfig, sizeof(tmp));
+ strlcpy(INIConfig, gemrbINI, sizeof(INIConfig));
+ }
if (!IgnoreOriginalINI) {
- char ini_path[_MAX_PATH];
PathJoin( ini_path, GamePath, INIConfig, NULL );
- LoadINI( ini_path );
+ Log(MESSAGE,"Core", "Loading original game options from %s", ini_path);
+ }
+ if (!InitializeVarsWithINI(ini_path)) {
+ Log(WARNING, "Core", "Unable to set dictionary default values!");
+ }
+
+ // restore the game config name if we read it from our version
+ if (tmp[0]) {
+ strlcpy(INIConfig, tmp, sizeof(INIConfig));
}
- int i;
for (i = 0; i < 8; i++) {
if (INIConfig[i] == '.')
break;
@@ -1571,36 +1820,35 @@ int Interface::Init()
}
GameNameResRef[i] = 0;
- printMessage( "Core", "Creating Projectile Server...\n", WHITE );
+ Log(MESSAGE, "Core", "Reading Encoding Table...");
+ if (!LoadEncoding()) {
+ Log(ERROR, "Core", "Cannot Load Encoding.");
+ }
+
+ Log(MESSAGE, "Core", "Creating Projectile Server...");
projserv = new ProjectileServer();
if (!projserv->GetHighestProjectileNumber()) {
- printStatus( "ERROR", LIGHT_RED );
- printf( "No projectiles are available...\n" );
+ Log(ERROR, "Core", "No projectiles are available...");
}
- printMessage( "Core", "Checking for Dialogue Manager...", WHITE );
+ Log(MESSAGE, "Core", "Checking for Dialogue Manager...");
if (!IsAvailable( IE_TLK_CLASS_ID )) {
- printStatus( "ERROR", LIGHT_RED );
- printf( "No TLK Importer Available.\nTermination in Progress...\n" );
+ Log(FATAL, "Core", "No TLK Importer Available.");
return GEM_ERROR;
}
- printStatus( "OK", LIGHT_GREEN );
strings = PluginHolder<StringMgr>(IE_TLK_CLASS_ID);
- printMessage( "Core", "Loading Dialog.tlk file...", WHITE );
+ Log(MESSAGE, "Core", "Loading Dialog.tlk file...");
char strpath[_MAX_PATH];
PathJoin( strpath, GamePath, dialogtlk, NULL );
- FileStream* fs = new FileStream();
- if (!fs->Open( strpath, true )) {
- printStatus( "ERROR", LIGHT_RED );
- printf( "Cannot find Dialog.tlk.\nTermination in Progress...\n" );
- delete fs;
+ FileStream* fs = FileStream::OpenFile(strpath);
+ if (!fs) {
+ Log(FATAL, "Core", "Cannot find Dialog.tlk.");
return GEM_ERROR;
}
- printStatus( "OK", LIGHT_GREEN );
- strings->Open( fs, true );
+ strings->Open(fs);
{
- printMessage( "Core", "Loading Palettes...\n", WHITE );
+ Log(MESSAGE, "Core", "Loading Palettes...");
ResourceHolder<ImageMgr> pal16im(Palette16);
if (pal16im)
pal16 = pal16im->GetImage();
@@ -1611,42 +1859,37 @@ int Interface::Init()
if (pal256im)
pal256 = pal256im->GetImage();
if (!pal16 || !pal32 || !pal256) {
- printStatus( "ERROR", LIGHT_RED );
+ Log(FATAL, "Core", "No palettes found.");
return GEM_ERROR;
}
- printMessage( "Core", "Palettes Loaded\n", WHITE );
+ Log(MESSAGE, "Core", "Palettes Loaded");
}
if (!IsAvailable( IE_BAM_CLASS_ID )) {
- printStatus( "ERROR", LIGHT_RED );
- printf( "No BAM Importer Available.\nTermination in Progress...\n" );
+ Log(FATAL, "Core", "No BAM Importer Available.");
return GEM_ERROR;
}
- printMessage( "Core", "Initializing stock sounds...\n", WHITE );
+ Log(MESSAGE, "Core", "Initializing stock sounds...");
DSCount = ReadResRefTable ("defsound", DefSound);
if (DSCount == 0) {
- printStatus( "ERROR", LIGHT_RED );
- printf( "Cannot find defsound.2da.\nTermination in Progress...\n" );
+ Log(FATAL, "Core", "Cannot find defsound.2da.");
return GEM_ERROR;
}
- printStatus( "OK", LIGHT_GREEN );
- printMessage( "Core", "Broadcasting Event Manager...", WHITE );
+ Log(MESSAGE, "Core", "Broadcasting Event Manager...");
video->SetEventMgr( evntmgr );
- printStatus( "OK", LIGHT_GREEN );
- printMessage( "Core", "Initializing Window Manager...", WHITE );
+ Log(MESSAGE, "Core", "Initializing Window Manager...");
windowmgr = PluginHolder<WindowMgr>(IE_CHU_CLASS_ID);
if (windowmgr == NULL) {
- printStatus( "ERROR", LIGHT_RED );
+ Log(FATAL, "Core", "Failed to load Window Manager.");
return GEM_ERROR;
}
- printStatus( "OK", LIGHT_GREEN );
int ret = LoadSprites();
if (ret) return ret;
- printMessage( "Core", "Setting up the Console...", WHITE );
+ Log(MESSAGE, "Core", "Setting up the Console...");
QuitFlag = QF_CHANGESCRIPT;
console = new Console();
console->XPos = 0;
@@ -1659,54 +1902,50 @@ int Interface::Init()
Sprite2D *tmpsprite = GetCursorSprite();
if (!tmpsprite) {
- printStatus( "ERROR", LIGHT_RED );
+ Log(FATAL, "Core", "Failed to load cursor sprite.");
return GEM_ERROR;
}
console->SetCursor (tmpsprite);
- printStatus( "OK", LIGHT_GREEN );
- printMessage( "Core", "Starting up the Sound Driver...", WHITE );
+ Log(MESSAGE, "Core", "Starting up the Sound Driver...");
AudioDriver = ( Audio * ) PluginMgr::Get()->GetDriver(&Audio::ID, AudioDriverName.c_str());
if (AudioDriver == NULL) {
- printStatus( "ERROR", LIGHT_RED );
+ Log(FATAL, "Core", "Failed to load sound driver.");
return GEM_ERROR;
}
if (!AudioDriver->Init()) {
- printStatus( "ERROR", LIGHT_RED );
+ Log(FATAL, "Core", "Failed to initialize sound driver.");
return GEM_ERROR;
}
- printStatus( "OK", LIGHT_GREEN );
- printMessage( "Core", "Allocating SaveGameIterator...", WHITE );
+ Log(MESSAGE, "Core", "Allocating SaveGameIterator...");
sgiterator = new SaveGameIterator();
if (sgiterator == NULL) {
- printStatus( "ERROR", LIGHT_RED );
+ Log(FATAL, "Core", "Failed to allocate SaveGameIterator.");
return GEM_ERROR;
}
- printStatus( "OK", LIGHT_GREEN );
//no need of strdup, variables do copy the key!
vars->SetAt( "SkipIntroVideos", (unsigned long)SkipIntroVideos );
vars->SetAt( "GUIEnhancements", (unsigned long)GUIEnhancements );
+ vars->SetAt( "TouchScrollAreas", (unsigned long)TouchScrollAreas );
- printMessage( "Core", "Initializing Token Dictionary...", WHITE );
+ Log(MESSAGE, "Core", "Initializing Token Dictionary...");
tokens = new Variables();
if (!tokens) {
- printStatus( "ERROR", LIGHT_RED );
+ Log(FATAL, "Core", "Failed to allocate Token dictionary.");
return GEM_ERROR;
}
tokens->SetType( GEM_VARIABLES_STRING );
- printStatus( "OK", LIGHT_GREEN );
- printMessage( "Core", "Initializing Music Manager...", WHITE );
+ Log(MESSAGE, "Core", "Initializing Music Manager...");
music = PluginHolder<MusicMgr>(IE_MUS_CLASS_ID);
if (!music) {
- printStatus( "ERROR", LIGHT_RED );
+ Log(FATAL, "Core", "Failed to load Music Manager.");
return GEM_ERROR;
}
- printStatus( "OK", LIGHT_GREEN );
- printMessage("Core", "Loading music list...\n", WHITE );
+ Log(MESSAGE, "Core", "Loading music list...");
if (HasFeature( GF_HAS_SONGLIST )) {
ret = ReadMusicTable("songlist", 1);
} else {
@@ -1715,35 +1954,28 @@ int Interface::Init()
It should be: music.2da, first column is a .mus filename*/
ret = ReadMusicTable("music", 0);
}
- if (ret) {
- printStatus( "OK", LIGHT_GREEN );
- } else {
- printStatus( "NOT FOUND", YELLOW );
+ if (!ret) {
+ Log(WARNING, "Core", "Didn't find music list.");
}
- if (HasFeature( GF_RESDATA_INI )) {
- printMessage( "Core", "Loading resource data File...", WHITE );
+ int resdata = HasFeature( GF_RESDATA_INI );
+ if (resdata || HasFeature(GF_SOUNDS_INI) ) {
+ Log(MESSAGE, "Core", "Loading resource data File...");
INIresdata = PluginHolder<DataFileMgr>(IE_INI_CLASS_ID);
- DataStream* ds = gamedata->GetResource("resdata", IE_INI_CLASS_ID);
- if (!INIresdata->Open( ds, true )) {
- printStatus( "ERROR", LIGHT_RED );
- } else {
- printStatus( "OK", LIGHT_GREEN );
+ DataStream* ds = gamedata->GetResource(resdata? "resdata":"sounds", IE_INI_CLASS_ID);
+ if (!INIresdata->Open(ds)) {
+ Log(WARNING, "Core", "Failed to load resource data.");
}
}
if (HasFeature( GF_HAS_PARTY_INI )) {
- printMessage( "Core", "Loading precreated teams setup...\n",
- WHITE );
+ Log(MESSAGE, "Core", "Loading precreated teams setup...");
INIparty = PluginHolder<DataFileMgr>(IE_INI_CLASS_ID);
- FileStream* fs = new FileStream();
char tINIparty[_MAX_PATH];
PathJoin( tINIparty, GamePath, "Party.ini", NULL );
- fs->Open( tINIparty, true );
- if (!INIparty->Open( fs, true )) {
- printStatus( "ERROR", LIGHT_RED );
- } else {
- printStatus( "OK", LIGHT_GREEN );
+ FileStream* fs = FileStream::OpenFile( tINIparty );
+ if (!INIparty->Open(fs)) {
+ Log(WARNING, "Core", "Failed to load precreated teams.");
}
}
@@ -1752,151 +1984,127 @@ int Interface::Init()
}
if (HasFeature( GF_HAS_BEASTS_INI )) {
- printMessage( "Core", "Loading beasts definition File...\n",
- WHITE );
+ Log(MESSAGE, "Core", "Loading beasts definition File...");
INIbeasts = PluginHolder<DataFileMgr>(IE_INI_CLASS_ID);
- FileStream* fs = new FileStream();
char tINIbeasts[_MAX_PATH];
PathJoin( tINIbeasts, GamePath, "beast.ini", NULL );
// FIXME: crashes if file does not open
- fs->Open( tINIbeasts, true );
- if (!INIbeasts->Open( fs, true )) {
- printStatus( "ERROR", LIGHT_RED );
- } else {
- printStatus( "OK", LIGHT_GREEN );
+ FileStream* fs = FileStream::OpenFile( tINIbeasts );
+ if (!INIbeasts->Open(fs)) {
+ Log(WARNING, "Core", "Failed to load beast definitions.");
}
- printMessage( "Core", "Loading quests definition File...\n",
- WHITE );
+ Log(MESSAGE, "Core", "Loading quests definition File...");
INIquests = PluginHolder<DataFileMgr>(IE_INI_CLASS_ID);
- FileStream* fs2 = new FileStream();
char tINIquests[_MAX_PATH];
PathJoin( tINIquests, GamePath, "quests.ini", NULL );
// FIXME: crashes if file does not open
- fs2->Open( tINIquests, true );
- if (!INIquests->Open( fs2, true )) {
- printStatus( "ERROR", LIGHT_RED );
- } else {
- printStatus( "OK", LIGHT_GREEN );
+ FileStream* fs2 = FileStream::OpenFile( tINIquests );
+ if (!INIquests->Open(fs2)) {
+ Log(WARNING, "Core", "Failed to load quest definitions.");
}
}
game = NULL;
calendar = NULL;
+ keymap = NULL;
+ Log(MESSAGE, "Core", "Bringing up the Global Timer...");
timer = new GlobalTimer();
- printMessage( "Core", "Bringing up the Global Timer...", WHITE );
if (!timer) {
- printStatus( "ERROR", LIGHT_RED );
+ Log(FATAL, "Core", "Failed to create global timer.");
return GEM_ERROR;
}
- printStatus( "OK", LIGHT_GREEN );
+ Log(MESSAGE, "Core", "Initializing effects...");
ret = Init_EffectQueue();
- printMessage( "Core", "Initializing effects...", WHITE );
if (!ret) {
- printStatus( "ERROR", LIGHT_RED );
+ Log(FATAL, "Core", "Failed to initialize effects.");
return GEM_ERROR;
}
- printStatus( "OK", LIGHT_GREEN );
+ Log(MESSAGE, "Core", "Initializing Inventory Management...");
ret = InitItemTypes();
- printMessage( "Core", "Initializing Inventory Management...", WHITE );
if (!ret) {
- printStatus( "ERROR", LIGHT_RED );
+ Log(FATAL, "Core", "Failed to initialize inventory.");
return GEM_ERROR;
}
- printStatus( "OK", LIGHT_GREEN );
+ Log(MESSAGE, "Core", "Initializing string constants...");
displaymsg = new DisplayMessage();
- printMessage( "Core", "Initializing string constants...", WHITE );
if (!displaymsg) {
- printStatus( "ERROR", LIGHT_RED );
+ Log(FATAL, "Core", "Failed to initialize string constants.");
return GEM_ERROR;
}
- printStatus( "OK", LIGHT_GREEN );
+ Log(MESSAGE, "Core", "Initializing random treasure...");
ret = ReadRandomItems();
- printMessage( "Core", "Initializing random treasure...", WHITE );
- if (ret) {
- printStatus( "OK", LIGHT_GREEN );
- }
- else {
- printStatus( "ERROR", LIGHT_RED );
+ if (!ret) {
+ Log(WARNING, "Core", "Failed to initialize random treasure.");
}
+ Log(MESSAGE, "Core", "Initializing ability tables...");
ret = ReadAbilityTables();
- printMessage( "Core", "Initializing ability tables...", WHITE );
if (!ret) {
- printStatus( "ERROR", LIGHT_RED );
+ Log(FATAL, "Core", "Failed to initialize ability tables...");
return GEM_ERROR;
}
- printStatus( "OK", LIGHT_GREEN );
+ Log(MESSAGE, "Core", "Reading reputation mod table...");
ret = ReadReputationModTable();
- printMessage( "Core", "Reading reputation mod table...", WHITE);
- if (ret) {
- printStatus( "OK", LIGHT_GREEN );
- } else {
- printStatus( "NOT FOUND", LIGHT_RED );
+ if (!ret) {
+ Log(WARNING, "Core", "Failed to read reputation mod table.");
}
if ( gamedata->Exists("WMAPLAY", IE_2DA_CLASS_ID) ) {
+ Log(MESSAGE, "Core", "Initializing area aliases...");
ret = ReadAreaAliasTable( "WMAPLAY" );
- printMessage( "Core", "Initializing area aliases...", WHITE );
- if (ret) {
- printStatus( "OK", LIGHT_GREEN );
- }
- else {
- printStatus( "NOT FOUND", YELLOW );
+ if (!ret) {
+ Log(WARNING, "Core", "Failed to load area aliases...");
}
}
+ Log(MESSAGE, "Core", "Reading game time table...");
ret = ReadGameTimeTable();
- printMessage( "Core", "Reading game time table...", WHITE);
if (!ret) {
- printStatus( "ERROR", LIGHT_RED );
+ Log(FATAL, "Core", "Failed to read game time table...");
return GEM_ERROR;
}
- printStatus( "OK", LIGHT_GREEN );
+ Log(MESSAGE, "Core", "Reading special spells table...");
ret = ReadSpecialSpells();
- printMessage( "Core", "Reading special spells table...", WHITE);
- if (ret) {
- printStatus( "OK", LIGHT_GREEN );
- } else {
- printStatus( "NOT FOUND", YELLOW );
+ if (!ret) {
+ Log(WARNING, "Core", "Failed to load special spells.");
}
+ Log(MESSAGE, "Core", "Reading item tables...");
ret = ReadAuxItemTables();
- printMessage( "Core", "Reading item tables...", WHITE);
if (!ret) {
- printStatus( "ERROR", LIGHT_RED );
+ Log(FATAL, "Core", "Failed to read item tables...");
return GEM_ERROR;
}
- printStatus( "OK", LIGHT_GREEN );
ret = ReadDamageTypeTable();
- printMessage( "Core", "Reading damage type table...", WHITE);
+ Log(MESSAGE, "Core", "Reading damage type table...");
if (!ret) {
- printStatus( "ERROR", LIGHT_RED );
- } else {
- printStatus( "OK", LIGHT_GREEN );
+ Log(WARNING, "Core", "Reading damage type table...");
}
+ Log(MESSAGE, "Core", "Reading modal states table...");
ret = ReadModalStates();
- printMessage( "Core", "Reading modal states table...", WHITE);
if (!ret) {
- printStatus( "ERROR", LIGHT_RED );
- return GEM_ERROR;
- } else {
- printStatus( "OK", LIGHT_GREEN );
+ Log(ERROR, "Core", "Failed to modal states table...");
}
- printMessage( "Core", "Reading game script tables...", WHITE);
+ Log(MESSAGE, "Core", "Reading game script tables...");
InitializeIEScript();
- printStatus( "OK", LIGHT_GREEN );
- printMessage( "Core", "Core Initialization Complete!\n", WHITE );
+ Log(MESSAGE, "Core", "Initializing keymap tables...");
+ keymap = new KeyMap();
+ ret = keymap->InitializeKeyMap("keymap.ini", "keymap");
+ if (!ret) {
+ Log(WARNING, "Core", "Failed to initialize keymaps.");
+ }
+ Log(MESSAGE, "Core", "Core Initialization Complete!");
return GEM_OK;
}
@@ -1930,124 +2138,124 @@ const char* Interface::TypeExt(SClass_ID type) const
{
switch (type) {
case IE_2DA_CLASS_ID:
- return ".2da";
+ return "2da";
case IE_ACM_CLASS_ID:
- return ".acm";
+ return "acm";
case IE_ARE_CLASS_ID:
- return ".are";
+ return "are";
case IE_BAM_CLASS_ID:
- return ".bam";
+ return "bam";
case IE_BCS_CLASS_ID:
- return ".bcs";
+ return "bcs";
case IE_BS_CLASS_ID:
- return ".bs";
+ return "bs";
case IE_BIF_CLASS_ID:
- return ".bif";
+ return "bif";
case IE_BIO_CLASS_ID:
if (HasFeature(GF_BIOGRAPHY_RES)) {
- return ".res";
+ return "res";
}
- return ".bio";
+ return "bio";
case IE_BMP_CLASS_ID:
- return ".bmp";
+ return "bmp";
case IE_PNG_CLASS_ID:
- return ".png";
+ return "png";
case IE_CHR_CLASS_ID:
- return ".chr";
+ return "chr";
case IE_CHU_CLASS_ID:
- return ".chu";
+ return "chu";
case IE_CRE_CLASS_ID:
- return ".cre";
+ return "cre";
case IE_DLG_CLASS_ID:
- return ".dlg";
+ return "dlg";
case IE_EFF_CLASS_ID:
- return ".eff";
+ return "eff";
case IE_GAM_CLASS_ID:
- return ".gam";
+ return "gam";
case IE_IDS_CLASS_ID:
- return ".ids";
+ return "ids";
case IE_INI_CLASS_ID:
- return ".ini";
+ return "ini";
case IE_ITM_CLASS_ID:
- return ".itm";
+ return "itm";
case IE_MOS_CLASS_ID:
- return ".mos";
+ return "mos";
case IE_MUS_CLASS_ID:
- return ".mus";
+ return "mus";
case IE_MVE_CLASS_ID:
- return ".mve";
+ return "mve";
case IE_OGG_CLASS_ID:
- return ".ogg";
+ return "ogg";
case IE_PLT_CLASS_ID:
- return ".plt";
+ return "plt";
case IE_PRO_CLASS_ID:
- return ".pro";
+ return "pro";
case IE_SAV_CLASS_ID:
- return ".sav";
+ return "sav";
case IE_SPL_CLASS_ID:
- return ".spl";
+ return "spl";
case IE_SRC_CLASS_ID:
- return ".src";
+ return "src";
case IE_STO_CLASS_ID:
- return ".sto";
+ return "sto";
case IE_TIS_CLASS_ID:
- return ".tis";
+ return "tis";
case IE_TLK_CLASS_ID:
- return ".tlk";
+ return "tlk";
case IE_TOH_CLASS_ID:
- return ".toh";
+ return "toh";
case IE_TOT_CLASS_ID:
- return ".tot";
+ return "tot";
case IE_VAR_CLASS_ID:
- return ".var";
+ return "var";
case IE_VVC_CLASS_ID:
- return ".vvc";
+ return "vvc";
case IE_WAV_CLASS_ID:
- return ".wav";
+ return "wav";
case IE_WED_CLASS_ID:
- return ".wed";
+ return "wed";
case IE_WFX_CLASS_ID:
- return ".wfx";
+ return "wfx";
case IE_WMP_CLASS_ID:
- return ".wmp";
+ return "wmp";
}
return NULL;
}
@@ -2089,343 +2297,6 @@ ieDword Interface::HasFeature(int position) const
return GameFeatures[position>>5] & (1<<(position&31));
}
-/** Search directories and load a config file */
-bool Interface::LoadConfig(void)
-{
-#ifndef WIN32
- char path[_MAX_PATH];
- char name[_MAX_PATH];
-
- // Find directory where user stores GemRB configurations (~/.gemrb).
- // FIXME: Create it if it does not exist
- // Use current dir if $HOME is not defined (or bomb out??)
-
- char* s = getenv( "HOME" );
- if (s) {
- strcpy( UserDir, s );
- strcat( UserDir, "/."PACKAGE"/" );
- } else {
- strcpy( UserDir, "./" );
- }
-
- // Find basename of this program. It does the same as basename (3),
- // but that's probably missing on some archs
- s = strrchr( argv[0], PathDelimiter );
- if (s) {
- s++;
- } else {
- s = argv[0];
- }
-
- strcpy( name, s );
- //if (!name[0]) // FIXME: could this happen?
- // strcpy (name, PACKAGE); // ugly hack
-
- // If we were called as $0 -c <filename>, load config from filename
- if (argc > 2 && ! strcmp("-c", argv[1])) {
- if (LoadConfig( argv[2] )) {
- return true;
- } else {
- // Explicitly specified cfg file HAS to be present
- return false;
- }
- }
-
- // FIXME: temporary hack, to be deleted??
- if (LoadConfig( "GemRB.cfg" )) {
- return true;
- }
-
- PathJoin( path, UserDir, name, NULL );
- strcat( path, ".cfg" );
-
- if (LoadConfig( path )) {
- return true;
- }
-
-#ifdef SYSCONFDIR
- PathJoin( path, SYSCONFDIR, name, NULL );
- strcat( path, ".cfg" );
-
- if (LoadConfig( path )) {
- return true;
- }
-#endif
-
- // Don't try with default binary name if we have tried it already
- if (!strcmp( name, PACKAGE )) {
- return false;
- }
-
- PathJoin( path, UserDir, PACKAGE, NULL );
- strcat( path, ".cfg" );
-
- if (LoadConfig( path )) {
- return true;
- }
-
-#ifdef SYSCONFDIR
- PathJoin( path, SYSCONFDIR, PACKAGE, NULL );
- strcat( path, ".cfg" );
-
- if (LoadConfig( path )) {
- return true;
- }
-#endif
-
- return false;
-#else // WIN32
- // If we were called as $0 -c <filename>, load config from filename
- if (argc > 2 && ! strcmp("-c", argv[1])) {
- return LoadConfig( argv[2] );
- // Explicitly specified cfg file HAS to be present
- }
- strcpy( UserDir, ".\\" );
- return LoadConfig( "GemRB.cfg" );
-#endif// WIN32
-}
-
-bool Interface::LoadConfig(const char* filename)
-{
- FILE* config;
- size_t i;
-
- printMessage("Config","Trying to open ", WHITE);
- textcolor(LIGHT_WHITE);
- printf("%s ", filename);
- config = fopen( filename, "rb" );
- if (config == NULL) {
- printStatus("NOT FOUND", LIGHT_RED);
- return false;
- }
- char name[65], value[_MAX_PATH + 3];
-
- //once GemRB own format is working well, this might be set to 0
- SaveAsOriginal = 1;
-
- while (!feof( config )) {
- char rem;
-
- if (fread( &rem, 1, 1, config ) != 1)
- break;
-
- if (rem == '#') {
- //it should always return 0
- if (fscanf( config, "%*[^\r\n]%*[\r\n]" )!=0)
- break;
- continue;
- }
- fseek( config, -1, SEEK_CUR );
- memset(value,'\0',_MAX_PATH + 3);
- //the * element is not counted
- if (fscanf( config, "%64[^= ] = %[^\r\n]%*[\r\n]", name, value )!=2)
- continue;
- for (i=_MAX_PATH + 2; i > 0; i--) {
- if (value[i] == '\0') continue;
- if (value[i] == ' ') {
- value[i] = '\0';
- } else {
- break;
- }
- }
-
- if (false) {
-#define CONFIG_INT(str, var) \
- } else if (stricmp(name, str) == 0) { \
- var ( atoi(value) )
- CONFIG_INT("Bpp", Bpp = );
- CONFIG_INT("CaseSensitive", CaseSensitive = );
- CONFIG_INT("DoubleClickDelay", evntmgr->SetDCDelay);
- CONFIG_INT("DrawFPS", DrawFPS = );
- CONFIG_INT("EnableCheatKeys", EnableCheatKeys);
- CONFIG_INT("EndianSwitch", DataStream::SetEndianSwitch);
- CONFIG_INT("FogOfWar", FogOfWar = );
- CONFIG_INT("FullScreen", FullScreen = );
- CONFIG_INT("GUIEnhancements", GUIEnhancements = );
- CONFIG_INT("GameOnCD", GameOnCD = );
- CONFIG_INT("Height", Height = );
- CONFIG_INT("KeepCache", KeepCache = );
- CONFIG_INT("MultipleQuickSaves", GameControl::MultipleQuickSaves);
- CONFIG_INT("RepeatKeyDelay", evntmgr->SetRKDelay);
- CONFIG_INT("SaveAsOriginal", SaveAsOriginal = );
- CONFIG_INT("ScriptDebugMode", SetScriptDebugMode);
- CONFIG_INT("SkipIntroVideos", SkipIntroVideos = );
- CONFIG_INT("TooltipDelay", TooltipDelay = );
- CONFIG_INT("Width", Width = );
- CONFIG_INT("IgnoreOriginalINI", IgnoreOriginalINI = );
-#undef CONFIG_INT
-#define CONFIG_STRING(str, var) \
- } else if (stricmp(name, str) == 0) { \
- strncpy(var, value, sizeof(var))
- CONFIG_STRING("GameCharactersPath", GameCharactersPath);
- CONFIG_STRING("GameDataPath", GameDataPath);
- CONFIG_STRING("GameName", GameName);
- CONFIG_STRING("GameOverridePath", GameOverridePath);
- CONFIG_STRING("GamePortraitsPath", GamePortraitsPath);
- CONFIG_STRING("GameScriptsPath", GameScriptsPath);
- CONFIG_STRING("GameSoundsPath", GameSoundsPath);
- CONFIG_STRING("GameType", GameType);
-#undef CONFIG_STRING
-#define CONFIG_STRING(str, var) \
- } else if (stricmp(name, str) == 0) { \
- var = value
- CONFIG_STRING("AudioDriver", AudioDriverName);
- CONFIG_STRING("VideoDriver", VideoDriverName);
-#undef CONFIG_STRING
-#define CONFIG_PATH(str, var) \
- } else if (stricmp(name, str) == 0) { \
- strncpy(var, value, sizeof(var));
- CONFIG_PATH("CachePath", CachePath);
- CONFIG_PATH("GUIScriptsPath", GUIScriptsPath);
- CONFIG_PATH("GamePath", GamePath);
- CONFIG_PATH("GemRBOverridePath", GemRBOverridePath);
- CONFIG_PATH("GemRBPath", GemRBPath);
- CONFIG_PATH("PluginsPath", PluginsPath);
- CONFIG_PATH("SavePath", SavePath);
-#undef CONFIG_PATH
- } else if (stricmp( name, "ModPath" ) == 0) {
- for (char *path = strtok(value,SPathListSeparator);
- path;
- path = strtok(NULL,SPathListSeparator)) {
- ModPath.push_back(path);
- }
- } else if (stricmp( name, "SkipPlugin" ) == 0) {
- plugin_flags->SetAt( value, PLF_SKIP );
- } else if (stricmp( name, "DelayPlugin" ) == 0) {
- plugin_flags->SetAt( value, PLF_DELAY );
- } else {
- for(i=0;i<MAX_CD;i++) {
- char keyname[] = { 'C', 'D', '1'+i, '\0' };
- if (stricmp(name, keyname) == 0) {
- for(char *path = strtok(value, SPathListSeparator);
- path;
- path = strtok(NULL,SPathListSeparator)) {
- CD[i].push_back(path);
- }
- }
- }
- }
- }
- fclose( config );
-
- // WARNING: Don't move ResolveFilePath into the loop
- // Otherwise, it won't obey CaseSensitive set at the end
- // of the config file.
-
- if (stricmp( GameType, "tob" ) == 0) {
- strncpy( GameType, "bg2", sizeof(GameType) );
- }
-
-#ifdef DATADIR
- if (!GemRBPath[0]) {
- strcpy( GemRBPath, DATADIR );
- }
-#endif
- ResolveFilePath(GemRBPath);
-
- if (!GemRBOverridePath[0]) {
- strcpy( GemRBOverridePath, GemRBPath );
- } else {
- ResolveFilePath(GemRBOverridePath);
- }
-
- if (!PluginsPath[0]) {
-#ifdef PLUGINDIR
- strcpy( PluginsPath, PLUGINDIR );
-#else
- PathJoin( PluginsPath, GemRBPath, "plugins", NULL );
-#endif
- } else {
- ResolveFilePath( PluginsPath );
- }
-
- if (!GUIScriptsPath[0]) {
- strcpy( GUIScriptsPath, GemRBPath );
- } else {
- ResolveFilePath( GUIScriptsPath );
- }
-
- if (!GameName[0]) {
- strcpy( GameName, GEMRB_STRING );
- }
-
- ResolveFilePath( GamePath );
-
- if (!SavePath[0]) {
- // FIXME: maybe should use UserDir instead of GamePath
- strcpy( SavePath, GamePath );
- } else {
- ResolveFilePath( SavePath );
- }
-
- if (! CachePath[0]) {
- PathJoin( CachePath, UserDir, "Cache", NULL );
- } else {
- ResolveFilePath(CachePath);
- }
-
- for (i = 0; i < MAX_CD; ++i) {
- if (!CD[i].size()) {
- char cd[] = { 'C', 'D', '1'+i, '\0' };
- char name[_MAX_PATH];
-
- PathJoin(name, GamePath, cd, NULL);
- CD[i].push_back(name);
- } else {
- size_t cnt = CD[i].size();
- while(cnt--) {
- ResolveFilePath( CD[i][cnt] );
- }
- }
- }
-
- for (i = 0; i < ModPath.size(); ++i) {
- ResolveFilePath(ModPath[i]);
- }
-
- FixPath( GUIScriptsPath, true );
- FixPath( PluginsPath, true );
- FixPath( GemRBPath, true );
- FixPath( GemRBOverridePath, true );
-
- if (GamePath[0]) {
- FixPath( GamePath, true );
- }
-
- //FixPath( SavePath, false );
- //mkdir( SavePath, S_IREAD|S_IWRITE|S_IEXEC );
- //chmod( SavePath, S_IREAD|S_IWRITE|S_IEXEC );
- FixPath( SavePath, true );
-
- FixPath( CachePath, false );
- mkdir( CachePath, S_IREAD|S_IWRITE|S_IEXEC );
- chmod( CachePath, S_IREAD|S_IWRITE|S_IEXEC );
-
- printStatus( "OK", LIGHT_GREEN );
-
- // Missing GameType is a common users' error
- if (!GameType[0]) {
- printMessage("Config","GameType was not set in your config file.\n", LIGHT_RED);
- return false;
- }
-
- if ( StupidityDetector( CachePath )) {
- printMessage("Core"," ",LIGHT_RED);
- printf( "Cache path %s doesn't exist, not a folder or contains alien files!\n", CachePath );
- return false;
- }
- if (!KeepCache) DelTree((const char *) CachePath, false);
- FixPath( CachePath, true );
-
- return true;
-}
-
-static void upperlower(int upper, int lower)
-{
- pl_uppercase[lower]=(ieByte) upper;
- pl_lowercase[upper]=(ieByte) lower;
-}
-
static const char *game_flags[GF_COUNT+1]={
"HasKaputz", //0 GF_HAS_KAPUTZ
"AllStringsTagged", //1 GF_ALL_STRINGS_TAGGED
@@ -2489,6 +2360,19 @@ static const char *game_flags[GF_COUNT+1]={
"ForceAreaScript", //59GF_FORCE_AREA_SCRIPT
"AreaOverride", //60GF_AREA_OVERRIDE
"NoNewVariables", //61GF_NO_NEW_VARIABLES
+ "HasSoundsIni", //62GF_SOUNDS_INI
+ "HasNoNPCFlag", //63GF_USEPOINT_400
+ "HasUsePointFlag", //64GF_USEPOINT_200
+ "HasFloatMenu", //65GF_HAS_FLOAT_MENU
+ "RareActionSounds", //66GF_RARE_ACTION_VB
+ "NoUndroppable", //67GF_NO_UNDROPPABLE
+ "StartActive", //68GF_START_ACTIVE
+ "ClearUnusedArea", //69GF_CLEAR_UNUSED_AREA
+ "ImplicitAreaAnimBackground", //70GF_IMPLICIT_AREAANIM_BACKGROUND
+ "HealOn100Plus", //71GF_HEAL_ON_100PLUS
+ "InPartyAllowsDead", //72GF_IN_PARTY_ALLOWS_DEAD
+ "ZeroTimerIsValid", //73GF_ZERO_TIMER_IS_VALID
+ "SkipUpdateHack", //74GF_SKIPUPDATE_HACK
NULL //for our own safety, this marks the end of the pole
};
@@ -2497,22 +2381,18 @@ bool Interface::LoadGemRBINI()
{
DataStream* inifile = gamedata->GetResource( "gemrb", IE_INI_CLASS_ID );
if (! inifile) {
- printStatus( "ERROR", LIGHT_RED );
return false;
}
- printMessage( "Core", "Loading game type-specific GemRB setup...\n", WHITE );
- printf( "%s",inifile->originalfile);
+ Log(MESSAGE, "Core", "Loading game type-specific GemRB setup '%s'",
+ inifile->originalfile);
if (!IsAvailable( IE_INI_CLASS_ID )) {
- printStatus( "ERROR", LIGHT_RED );
- printf( "[Core]: No INI Importer Available.\n" );
+ Log(ERROR, "Core", "No INI Importer Available.");
return false;
}
PluginHolder<DataFileMgr> ini(IE_INI_CLASS_ID);
- ini->Open( inifile, true ); //autofree
-
- printStatus( "OK", LIGHT_GREEN );
+ ini->Open(inifile);
const char *s;
@@ -2569,8 +2449,7 @@ bool Interface::LoadGemRBINI()
const char *pos = strchr( s, '/' );
if (pos) {
GroundCircleScale[size] = atoi( pos+1 );
- strncpy( GroundCircleBam[size], s, pos - s );
- GroundCircleBam[size][pos - s] = '\0';
+ strlcpy( GroundCircleBam[size], s, pos - s + 1 );
} else {
strcpy( GroundCircleBam[size], s );
}
@@ -2592,10 +2471,45 @@ bool Interface::LoadGemRBINI()
if (s)
strcpy( Palette32, s );
- s = ini->GetKeyAsString( "resources", "Palette256", NULL );
- if (s)
- strcpy( Palette256, s );
+ s = ini->GetKeyAsString( "resources", "Palette256", NULL );
+ if (s)
+ strcpy( Palette256, s );
+
+ MaximumAbility = ini->GetKeyAsInt ("resources", "MaximumAbility", 25 );
+
+ RedrawTile = ini->GetKeyAsInt( "resources", "RedrawTile", 0 )!=0;
+
+ for (int i=0;i<GF_COUNT;i++) {
+ if (!game_flags[i]) {
+ error("Core", "Fix the game flags!\n");
+ }
+ SetFeature( ini->GetKeyAsInt( "resources", game_flags[i], 0 ), i );
+ //printMessage("Option", "", GREEN);
+ //print("%s = %s", game_flags[i], HasFeature(i)?"yes":"no");
+ }
+
+ ForceStereo = ini->GetKeyAsInt( "resources", "ForceStereo", 0 );
+
+ return true;
+}
+
+/** Load the encoding table selected in gemrb.cfg */
+bool Interface::LoadEncoding()
+{
+ DataStream* inifile = gamedata->GetResource( Encoding.c_str(), IE_INI_CLASS_ID );
+ if (! inifile) {
+ return false;
+ }
+
+ Log(MESSAGE, "Core", "Loading encoding definition for %s: '%s'", Encoding.c_str(),
+ inifile->originalfile);
+
+ PluginHolder<DataFileMgr> ini(IE_INI_CLASS_ID);
+ ini->Open(inifile);
+
+ TLKEncoding = ini->GetKeyAsString("encoding", "TLKEncoding", TLKEncoding.c_str());
+ const char *s;
unsigned int i = (unsigned int) ini->GetKeyAsInt ("charset", "CharCount", 0);
if (i>99) i=99;
while(i--) {
@@ -2605,27 +2519,14 @@ bool Interface::LoadGemRBINI()
if (s) {
const char *s2 = strchr(s,',');
if (s2) {
- upperlower(atoi(s), atoi(s2+1) );
+ unsigned char upper = atoi(s);
+ unsigned char lower = atoi(s2+1);
+ pl_uppercase[lower] = upper;
+ pl_lowercase[upper] = lower;
}
}
}
- MaximumAbility = ini->GetKeyAsInt ("resources", "MaximumAbility", 25 );
-
- RedrawTile = ini->GetKeyAsInt( "resources", "RedrawTile", 0 )!=0;
-
- for (i=0;i<GF_COUNT;i++) {
- if (!game_flags[i]) {
- printf("Fix the game flags!\n");
- abort();
- }
- SetFeature( ini->GetKeyAsInt( "resources", game_flags[i], 0 ), i );
- //printMessage("Option", "", GREEN);
- //printf("%s = %s\n", game_flags[i], HasFeature(i)?"yes":"no");
- }
-
- ForceStereo = ini->GetKeyAsInt( "resources", "ForceStereo", 0 );
-
return true;
}
@@ -2676,7 +2577,7 @@ Color* Interface::GetPalette(unsigned index, int colors, Color *pal) const
Font* Interface::GetFont(const char *ResRef) const
{
for (unsigned int i = 0; i < fonts.size(); i++) {
- if (strnicmp( fonts[i]->ResRef, ResRef, 8 ) == 0) {
+ if (fonts[i]->MatchesResRef(ResRef)) {
return fonts[i];
}
}
@@ -2725,17 +2626,57 @@ Actor *Interface::SummonCreature(const ieResRef resource, const ieResRef vvcres,
//TODO:
//decrease the number of summoned creatures with the number of already summoned creatures here
- //the summoned creatures have a special IE_SPECIFIC
+ //the summoned creatures have a special IE_SEX
+ Map *map;
+ if (target) {
+ map = target->GetCurrentArea();
+ } else if (Owner) {
+ map = Owner->GetCurrentArea();
+ } else {
+ map = game->GetCurrentArea();
+ }
- while(cnt--) {
- ab = gamedata->GetCreature(resource);
- if (!ab) {
+ if (map) while(cnt--) {
+ Actor *tmp = gamedata->GetCreature(resource);
+ if (!tmp) {
return NULL;
}
+ ieDword sex = tmp->GetStat(IE_SEX);
+ //TODO: make this external
+ int limit = 0;
+ switch (sex) {
+ case SEX_SUMMON: case SEX_SUMMON_DEMON:
+ limit = 5;
+ break;
+ case SEX_BOTH:
+ limit = 1;
+ break;
+ }
+
+ //if summoner is an actor, filter out opponent summons
+ //this is done by clearing the filter when appropriate
+ //non actors and neutrals can summon as much as they want
+ ieDword flag = GA_NO_DEAD|GA_NO_ALLY|GA_NO_ENEMY;
if (Owner && Owner->Type==ST_ACTOR) {
- ab->LastSummoner = Owner->GetGlobalID();
+ tmp->LastSummoner = Owner->GetGlobalID();
+ Actor *owner = (Actor *) Owner;
+ ieDword ea = owner->GetStat(IE_EA);
+ if (ea<=EA_GOODCUTOFF) {
+ flag &= ~GA_NO_ALLY;
+ } else if (ea>=EA_EVILCUTOFF) {
+ flag &= ~GA_NO_ENEMY;
+ }
+ }
+
+ if (limit && sexmod && map->CountSummons(flag, sex)>=limit) {
+ //summoning limit reached
+ displaymsg->DisplayConstantString(STR_SUMMONINGLIMIT, DMC_WHITE);
+ delete tmp;
+ break;
}
+
+ ab = tmp;
//Always use Base stats for the recently summoned creature
int enemyally;
@@ -2783,13 +2724,7 @@ Actor *Interface::SummonCreature(const ieResRef resource, const ieResRef vvcres,
ab->SetBase(IE_SEX, SEX_SUMMON);
}
- Map *map;
- if (target) {
- map = target->GetCurrentArea();
- } else {
- map = Owner->GetCurrentArea();
- }
- map->AddActor(ab);
+ map->AddActor(ab, true);
ab->SetPosition(position, true, 0);
ab->RefreshEffects(NULL);
@@ -2856,19 +2791,15 @@ bool Interface::LoadWindowPack(const char* name)
{
DataStream* stream = gamedata->GetResource( name, IE_CHU_CLASS_ID );
if (stream == NULL) {
- printMessage( "Interface", "Error: Cannot find ", LIGHT_RED );
- printf( "%s.chu\n", name );
+ Log(ERROR, "Interface", "Error: Cannot find %s.chu", name );
return false;
}
- if (!GetWindowMgr()->Open( stream, true )) {
- printMessage( "Interface", "Error: Cannot Load ", LIGHT_RED );
- printf( "%s.chu\n", name );
+ if (!GetWindowMgr()->Open(stream)) {
+ Log(ERROR, "Interface", "Error: Cannot Load %s.chu", name );
return false;
}
- strncpy( WindowPack, name, sizeof( WindowPack ) );
- WindowPack[sizeof( WindowPack ) - 1] = '\0';
-
+ CopyResRef( WindowPack, name );
return true;
}
@@ -2876,6 +2807,7 @@ bool Interface::LoadWindowPack(const char* name)
int Interface::LoadWindow(unsigned short WindowID)
{
unsigned int i;
+ GameControl *gc = GetGameControl ();
for (i = 0; i < windows.size(); i++) {
Window *win = windows[i];
@@ -2888,6 +2820,8 @@ int Interface::LoadWindow(unsigned short WindowID)
!strnicmp( WindowPack, win->WindowPack, sizeof(WindowPack) )) {
SetOnTop( i );
win->Invalidate();
+ if (gc)
+ gc->SetScrolling( false );
return i;
}
}
@@ -2911,6 +2845,8 @@ int Interface::LoadWindow(unsigned short WindowID)
windows[slot] = win;
}
win->Invalidate();
+ if (gc)
+ gc->SetScrolling( false );
return slot;
}
// FIXME: it's a clone of LoadWindow
@@ -2935,8 +2871,6 @@ int Interface::CreateWindow(unsigned short WindowID, int XPos, int YPos, unsigne
ResourceHolder<ImageMgr> mos(Background);
if (mos != NULL) {
win->SetBackGround( mos->GetSprite2D(), true );
- } else {
- printf( "[Core]: Cannot Load BackGround, skipping\n" );
}
}
@@ -2988,7 +2922,6 @@ void Interface::AddWindow(Window * win)
}
if(slot == -1) {
windows.push_back(win);
- slot=(int)windows.size()-1;
}
else
windows[slot] = win;
@@ -3040,26 +2973,9 @@ int Interface::AdjustScrolling(unsigned short WindowIndex,
return 0;
}
-/** Set the Text of a Control */
-int Interface::SetText(unsigned short WindowIndex,
- unsigned short ControlIndex, const char* string)
-{
- if (WindowIndex >= windows.size()) {
- return -1;
- }
- Window* win = windows[WindowIndex];
- if (win == NULL) {
- return -1;
- }
- Control* ctrl = win->GetControl( ControlIndex );
- if (ctrl == NULL) {
- return -1;
- }
- return ctrl->SetText( string );
-}
/** Set the Tooltip text of a Control */
int Interface::SetTooltip(unsigned short WindowIndex,
- unsigned short ControlIndex, const char* string)
+ unsigned short ControlIndex, const char* string, int Function)
{
if (WindowIndex >= windows.size()) {
return -1;
@@ -3072,6 +2988,12 @@ int Interface::SetTooltip(unsigned short WindowIndex,
if (ctrl == NULL) {
return -1;
}
+
+ if (Function) {
+ win->FunctionBar = true;
+ evntmgr->SetFunctionBar(win);
+ ctrl->SetFunctionNumber(Function-1);
+ }
return ctrl->SetTooltip( string );
}
@@ -3082,6 +3004,15 @@ void Interface::DisplayTooltip(int x, int y, Control *ctrl)
tooltip_x = x;
tooltip_y = y;
tooltip_currtextw = 0;
+ if (x && y && tooltip_ctrl != ctrl) {
+ // use a sound handle so we can stop previous unroll sounds
+ if (tooltip_sound) {
+ tooltip_sound->Stop();
+ tooltip_sound.release();
+ }
+ // exactly like PlaySound(DS_TOOLTIP) but storing the handle
+ tooltip_sound = AudioDriver->Play(DefSound[DS_TOOLTIP]);
+ }
tooltip_ctrl = ctrl;
}
@@ -3129,6 +3060,9 @@ int Interface::SetVisible(unsigned short WindowIndex, int visible)
case WINDOW_FRONT:
if (win->Visible==WINDOW_VISIBLE) {
evntmgr->AddWindow( win );
+ if (win->FunctionBar) {
+ evntmgr->SetFunctionBar( win );
+ }
}
win->Invalidate();
SetOnTop( WindowIndex );
@@ -3154,9 +3088,14 @@ int Interface::SetControlStatus(unsigned short WindowIndex,
if (Status&IE_GUI_CONTROL_FOCUSED) {
evntmgr->SetFocused( win, ctrl);
}
- if (ctrl->ControlType != ((Status >> 24) & 0xff) ) {
+
+ //check if the status parameter was intended to use with this control
+ //Focus will sadly break this at the moment, because it is common for all control types
+ int check = (Status >> 24) & 0xff;
+ if ( (check!=0x7f) && (ctrl->ControlType != check) ) {
return -2;
}
+
switch (ctrl->ControlType) {
case IE_GUI_BUTTON:
//Button
@@ -3165,6 +3104,8 @@ int Interface::SetControlStatus(unsigned short WindowIndex,
btn->SetState( ( unsigned char ) ( Status & 0x7f ) );
}
break;
+ case IE_GUI_WORLDMAP:
+ break;
default:
ctrl->Value = Status & 0x7f;
break;
@@ -3176,12 +3117,12 @@ int Interface::SetControlStatus(unsigned short WindowIndex,
int Interface::ShowModal(unsigned short WindowIndex, int Shadow)
{
if (WindowIndex >= windows.size()) {
- printMessage( "Core", "Window not found", LIGHT_RED );
+ Log(ERROR, "Core", "Window not found");
return -1;
}
Window* win = windows[WindowIndex];
if (win == NULL) {
- printMessage( "Core", "Window already freed", LIGHT_RED );
+ Log(ERROR, "Core", "Window already freed");
return -1;
}
win->Visible = WINDOW_FRONT;
@@ -3227,15 +3168,13 @@ void Interface::GameLoop(void)
update_scripts = !(gc->GetDialogueFlags() & DF_FREEZE_SCRIPTS);
}
- GSUpdate(update_scripts);
-
- //i'm not sure if this should be here
+ bool do_update = GSUpdate(update_scripts);
+ if ( gc && game && (game->selected.size() > 0) ) {
+ gc->ChangeMap(GetFirstSelectedPC(true), false);
+ }
//in multi player (if we ever get to it), only the server must call this
- if (update_scripts) {
- if ( game->selected.size() > 0 ) {
- gc->ChangeMap(GetFirstSelectedPC(true), false);
- }
+ if (do_update) {
// the game object will run the area scripts as well
game->UpdateScripts();
}
@@ -3301,7 +3240,7 @@ void Interface::HandleGUIBehaviour(void)
}
}
-void Interface::DrawWindows(void)
+void Interface::DrawWindows(bool allow_delete)
{
//here comes the REAL drawing of windows
if (ModalWindow) {
@@ -3319,10 +3258,12 @@ void Interface::DrawWindows(void)
Window* win = windows[t];
if (win != NULL) {
if (win->Visible == WINDOW_INVALID) {
- topwin.erase(topwin.begin()+i);
- evntmgr->DelWindow( win );
- delete win;
- windows[t]=NULL;
+ if (allow_delete) {
+ topwin.erase(topwin.begin()+i);
+ evntmgr->DelWindow( win );
+ delete win;
+ windows[t]=NULL;
+ }
} else if (win->Visible) {
win->DrawWindow();
}
@@ -3336,11 +3277,14 @@ void Interface::DrawTooltip ()
return;
Font* fnt = GetFont( TooltipFont );
+ if (!fnt) {
+ return;
+ }
char *tooltip_text = tooltip_ctrl->Tooltip;
int w1 = 0;
int w2 = 0;
- int strw = fnt->CalcStringWidth( tooltip_text ) + 8;
+ int strw = fnt->CalcStringWidth( (unsigned char*)tooltip_text ) + 8;
int w = strw;
int h = fnt->maxHeight;
@@ -3363,13 +3307,16 @@ void Interface::DrawTooltip ()
h = TooltipBack[0]->Height;
w1 = TooltipBack[1]->Width;
w2 = TooltipBack[2]->Width;
- w += TooltipMargin*2;
- strw += TooltipMargin*2;
+ int margins = TooltipMargin*2;
+ w += margins;
+ strw += margins;
+ int strwmax = TooltipBack[0]->Width - margins;
//multiline in case of too much text
- if (w>TooltipBack[0]->Width)
- strw=w=TooltipBack[0]->Width;
- else if (strw>TooltipBack[0]->Width)
- strw=TooltipBack[0]->Width;
+ if (w > TooltipBack[0]->Width) {
+ w = TooltipBack[0]->Width;
+ strw = strwmax;
+ } else if (strw > strwmax)
+ strw = strwmax;
}
int strx = tooltip_x - strw / 2;
@@ -3384,17 +3331,17 @@ void Interface::DrawTooltip ()
int x = strx + ((strw - w) / 2);
- // FIXME: take back[0] from center, not from left end
Region r2 = Region( x, y, w, h );
if (TooltipBack) {
- video->BlitSprite( TooltipBack[0], x + TooltipMargin, y, true, &r2 );
+ video->BlitSprite( TooltipBack[0], x + TooltipMargin - (TooltipBack[0]->Width - w) / 2, y, true, &r2 );
video->BlitSprite( TooltipBack[1], x, y, true );
video->BlitSprite( TooltipBack[2], x + w, y, true );
}
if (TooltipBack) {
- r2.x+=TooltipMargin;
- strx+=TooltipMargin;
+ r2.x += TooltipBack[1]->Width;
+ r2.w -= TooltipBack[2]->Width;
+ strx += TooltipMargin;
}
Region textr = Region( strx, y, strw, h );
fnt->Print( r2, textr, (ieByte *) tooltip_text, NULL,
@@ -3438,7 +3385,7 @@ int Interface::DelWindow(unsigned short WindowIndex)
}
Window* win = windows[WindowIndex];
if ((win == NULL) || (win->Visible==WINDOW_INVALID) ) {
- printMessage( "Core", "Window deleted again", LIGHT_RED );
+ Log(ERROR, "Core", "Window deleted again");
return -1;
}
if (win == ModalWindow) {
@@ -3489,7 +3436,7 @@ void Interface::PopupConsole()
/** Draws the Console */
void Interface::DrawConsole()
{
- console->Draw( 0, 0 );
+ console->Draw( 0, (Height * -1) + console->Height);
}
/** Get the Sound Manager */
@@ -3497,10 +3444,30 @@ SaveGameIterator* Interface::GetSaveGameIterator() const
{
return sgiterator;
}
-/** Sends a termination signal to the Video Driver */
-bool Interface::Quit(void)
+
+void Interface::AskAndExit()
+{
+ // if askExit is 1 then we are trying to quit a second time and should instantly do so
+ ieDword askExit = 0;
+ vars->Lookup("AskAndExit", askExit);
+ if (game && !askExit) {
+ if (ConsolePopped) {
+ PopupConsole();
+ }
+ SetPause(PAUSE_ON);
+ vars->SetAt("AskAndExit", 1);
+
+ LoadWindowPack("GUIOPT");
+ guiscript->RunFunction("GUIOPT", "OpenQuitMsgWindow");
+ Log(MESSAGE, "Info", "Press ctrl-c (or close the window) again to quit GemRB.\n");
+ } else {
+ ExitGemRB();
+ }
+}
+
+void Interface::ExitGemRB()
{
- return video->Quit();
+ QuitFlag |= QF_KILL;
}
/** Returns the variables dictionary */
Variables* Interface::GetDictionary() const
@@ -3533,7 +3500,7 @@ int Interface::LoadSymbol(const char* ResRef)
delete str;
return -1;
}
- if (!sm->Open( str, true )) {
+ if (!sm->Open(str)) {
return -1;
}
Symbol s;
@@ -3704,7 +3671,7 @@ int Interface::GetPortraits(TextArea* ta, bool smallorlarge)
if (!dir) {
return -1;
}
- printf( "Looking in %s\n", Path );
+ print("Looking in %s", Path);
do {
char *name = dir.GetName();
if (name[0] == '.')
@@ -3736,7 +3703,7 @@ int Interface::GetCharSounds(TextArea* ta)
if (!dir) {
return -1;
}
- printf( "Looking in %s\n", Path );
+ print("Looking in %s", Path);
do {
char *name = dir.GetName();
if (name[0] == '.')
@@ -3765,7 +3732,7 @@ int Interface::GetCharacters(TextArea* ta)
if (!dir) {
return -1;
}
- printf( "Looking in %s\n", Path );
+ print("Looking in %s", Path);
do {
char *name = dir.GetName();
if (name[0] == '.')
@@ -3782,47 +3749,118 @@ int Interface::GetCharacters(TextArea* ta)
return count;
}
-bool Interface::LoadINI(const char* filename)
+bool Interface::InitializeVarsWithINI(const char* iniFileName)
{
- FILE* config;
- config = fopen( filename, "rb" );
- if (config == NULL) {
+ if (!core->IsAvailable( IE_INI_CLASS_ID ))
return false;
+
+ DataFileMgr* defaults = NULL;
+ DataFileMgr* overrides = NULL;
+
+ PluginHolder<DataFileMgr> ini(IE_INI_CLASS_ID);
+ FileStream* iniStream = FileStream::OpenFile(iniFileName);
+ // if filename is not set we assume we are creating defaults without an INI
+ if (iniFileName[0] && !ini->Open(iniStream)) {
+ Log(WARNING, "Core", "Unable to read defaults from '%s'. Using GemRB default values.", iniFileName);
+ } else {
+ overrides = ini.get();
}
- char name[65], value[_MAX_PATH + 3];
- while (!feof( config )) {
- name[0] = 0;
- value[0] = 0;
- char rem;
- if (fread( &rem, 1, 1, config ) != 1)
- break;
+ PluginHolder<DataFileMgr> gemINI(IE_INI_CLASS_ID);
+ DataStream* gemINIStream = gamedata->GetResource( "defaults", IE_INI_CLASS_ID );
- if (( rem == '#' ) ||
- ( rem == '[' ) ||
- ( rem == '\r' ) ||
- ( rem == '\n' ) ||
- ( rem == ';' )) {
- if (rem == '\r') {
- fgetc( config );
- continue;
- } else if (rem == '\n')
- continue;
+ if (!gemINIStream || !gemINI->Open(gemINIStream)) {
+ Log(WARNING, "Core", "Unable to load GemRB default values.");
+ defaults = ini.get();
+ } else {
+ defaults = gemINI.get();
+ if (!overrides) {
+ overrides = defaults;
+ }
+ }
- //it should always return zero
- if (fscanf( config, "%*[^\r\n]%*[\r\n]" )!=0)
- break;
- continue;
+ for (int i = 0; i < defaults->GetTagsCount(); i++) {
+ const char* tag = defaults->GetTagNameByIndex(i);
+ for (int j = 0; j < defaults->GetKeysCount(tag); j++) {
+ ieDword nothing;
+ const char* key = defaults->GetKeyNameByIndex(tag, j);
+ //skip any existing entries. GemRB.cfg has priority
+ if (!vars->Lookup(key, nothing)) {
+ ieDword defaultVal = defaults->GetKeyAsInt(tag, key, 0);
+ vars->SetAt(key, overrides->GetKeyAsInt(tag, key, defaultVal));
+ }
}
- fseek( config, -1, SEEK_CUR );
- //the * element is not counted
- if (fscanf( config, "%[^=]=%[^\r\n]%*[\r\n]", name, value )!=2)
- continue;
- if (( value[0] >= '0' ) && ( value[0] <= '9' )) {
- vars->SetAt( name, atoi( value ) );
+ }
+
+ // handle a few special cases
+ if (!overrides->GetKeyAsInt("Config", "Sound", 1))
+ AudioDriverName = "null";
+
+ if (overrides->GetKeyAsInt("Game Options", "Cheats", 1)) {
+ EnableCheatKeys(1);
+ }
+
+ // copies
+ if (!overrides->GetKeyAsInt("Game Options", "Darkvision", 1)) {
+ vars->SetAt("Infravision", (ieDword)0);
+ }
+
+ if (!Width || !Height) {
+ Height = overrides->GetKeyAsInt("Config", "ConfigHeight", Height);
+ int tmpWidth = overrides->GetKeyAsInt("Config", "ConfigWidth", 0);
+ if (!tmpWidth) {
+ // Resolution is stored as width only. assume 4|3 ratio.
+ Width = overrides->GetKeyAsInt("Program Options", "Resolution", Width);
+ Height = 0.75 * Width;
+ }
+ }
+ return true;
+}
+
+/** Saves the gemrb config variables from the whitelist to gem-INIConfig
+ * If GamePath is not writable, it tries SavePath
+ */
+bool Interface::SaveConfig()
+{
+ char ini_path[_MAX_PATH] = { '\0' };
+ char gemrbINI[_MAX_PATH] = { '\0' };
+ if (strncmp(INIConfig, "gem-", 4)) {
+ snprintf(gemrbINI, sizeof(gemrbINI), "gem-%s", INIConfig);
+ }
+ PathJoin(ini_path, GamePath, gemrbINI, NULL);
+ FileStream *fs = new FileStream();
+ if (!fs->Create(ini_path)) {
+ PathJoin(ini_path, SavePath, gemrbINI, NULL);
+ if (!fs->Create(ini_path)) {
+ return false;
}
}
- fclose( config );
+
+ PluginHolder<DataFileMgr> defaultsINI(IE_INI_CLASS_ID);
+ DataStream* INIStream = gamedata->GetResource( "defaults", IE_INI_CLASS_ID );
+
+ if (INIStream && defaultsINI->Open(INIStream)) {
+ // dump the formatted default config options to the file
+ StringBuffer contents;
+ for (int i = 0; i < defaultsINI->GetTagsCount(); i++) {
+ const char* tag = defaultsINI->GetTagNameByIndex(i);
+ // write section header
+ contents.appendFormatted("[%s]\n", tag);
+ for (int j = 0; j < defaultsINI->GetKeysCount(tag); j++) {
+ const char* key = defaultsINI->GetKeyNameByIndex(tag, j);
+ ieDword value = 0;
+ bool found = vars->Lookup(key, value);
+ assert(found);
+ contents.appendFormatted("%s = %d\n", key, value);
+ }
+ }
+
+ fs->Write(contents.get().c_str(), contents.get().size());
+ } else {
+ Log(ERROR, "Core", "Unable to open GemRB defaults. Cannot determine what values to write to %s.", ini_path);
+ }
+
+ delete fs;
return true;
}
@@ -3833,7 +3871,7 @@ void Interface::SetCutSceneMode(bool active)
if (gc) {
// don't mess with controls/etc if we're already in a cutscene
- if (active == (gc->GetScreenFlags()&SF_CUTSCENE))
+ if (active == (bool)(gc->GetScreenFlags()&SF_CUTSCENE))
return;
gc->SetCutSceneMode( active );
@@ -3853,12 +3891,24 @@ void Interface::SetCutSceneMode(bool active)
bool Interface::InCutSceneMode() const
{
GameControl *gc = GetGameControl();
- if (!gc || (gc->GetDialogueFlags()&DF_IN_DIALOG) || (gc->GetScreenFlags()&SF_DISABLEMOUSE) ) {
+ if (!gc || (gc->GetDialogueFlags()&DF_IN_DIALOG) || (gc->GetScreenFlags()&(SF_DISABLEMOUSE|SF_CUTSCENE))) {
return true;
}
return false;
}
+/** Updates the Game Script Engine State */
+bool Interface::GSUpdate(bool update_scripts)
+{
+ if(update_scripts) {
+ return timer->Update();
+ }
+ else {
+ timer->Freeze();
+ return false;
+ }
+}
+
void Interface::QuitGame(int BackToMain)
{
SetCutSceneMode(false);
@@ -3912,6 +3962,7 @@ void Interface::LoadGame(SaveGame *sg, int ver_override)
// Yes, it uses goto. Other ways seemed too awkward for me.
+ gamedata->SaveAllStores();
strings->CloseAux();
tokens->RemoveAll(NULL); //clearing the token dictionary
@@ -3962,7 +4013,7 @@ void Interface::LoadGame(SaveGame *sg, int ver_override)
if (!gam_mgr)
goto cleanup;
- if (!gam_mgr->Open( gam_str, true ))
+ if (!gam_mgr->Open(gam_str))
goto cleanup;
new_game = gam_mgr->LoadGame(new Game(), ver_override);
@@ -3975,7 +4026,7 @@ void Interface::LoadGame(SaveGame *sg, int ver_override)
if (!wmp_mgr)
goto cleanup;
- if (!wmp_mgr->Open( wmp_str1, wmp_str2, true ))
+ if (!wmp_mgr->Open(wmp_str1, wmp_str2))
goto cleanup;
new_worldmap = wmp_mgr->GetWorldMapArray( );
@@ -3986,7 +4037,7 @@ void Interface::LoadGame(SaveGame *sg, int ver_override)
LoadProgress(20);
// Unpack SAV (archive) file to Cache dir
if (sav_str) {
- PluginHolder<ArchiveImporter> ai(IE_BIF_CLASS_ID);
+ PluginHolder<ArchiveImporter> ai(IE_SAV_CLASS_ID);
if (ai) {
if (ai->DecompressSaveGame(sav_str) != GEM_OK) {
goto cleanup;
@@ -4010,6 +4061,8 @@ void Interface::LoadGame(SaveGame *sg, int ver_override)
cleanup:
// Something went wrong, so try to clean after itself
+ error("Core", "Unable to load game.");
+
delete new_game;
delete new_worldmap;
@@ -4019,6 +4072,37 @@ cleanup:
delete sav_str;
}
+/* replace the current world map but sync areas available in old and new */
+void Interface::UpdateWorldMap(ieResRef wmResRef)
+{
+ DataStream* wmp_str = gamedata->GetResource(wmResRef, IE_WMP_CLASS_ID);
+ PluginHolder<WorldMapMgr> wmp_mgr(IE_WMP_CLASS_ID);
+
+ if (!wmp_str || !wmp_mgr || !wmp_mgr->Open(wmp_str, NULL)) {
+ Log(ERROR, "Core", "Could not update world map %s", wmResRef);
+ return;
+ }
+
+ WorldMapArray *new_worldmap = wmp_mgr->GetWorldMapArray();
+ WorldMap *wm = worldmap->GetWorldMap(0);
+ WorldMap *nwm = new_worldmap->GetWorldMap(0);
+
+ unsigned int i, ni;
+ unsigned int ec = wm->GetEntryCount();
+ //update status of the previously existing areas
+ for(i=0;i<ec;i++) {
+ WMPAreaEntry *ae = wm->GetEntry(i);
+ WMPAreaEntry *nae = nwm->GetArea(ae->AreaResRef, ni);
+ if (nae != NULL) {
+ nae->SetAreaStatus(ae->GetAreaStatus(), BM_SET);
+ }
+ }
+
+ delete worldmap;
+ worldmap = new_worldmap;
+ CopyResRef(WorldMapName[0], wmResRef);
+}
+
/* swapping out old resources */
void Interface::UpdateMasterScript()
{
@@ -4034,7 +4118,7 @@ void Interface::UpdateMasterScript()
DataStream *wmp_str1 = gamedata->GetResource( WorldMapName[0], IE_WMP_CLASS_ID );
DataStream *wmp_str2 = gamedata->GetResource( WorldMapName[1], IE_WMP_CLASS_ID );
- if (!wmp_mgr->Open( wmp_str1, wmp_str2, true )) {
+ if (!wmp_mgr->Open(wmp_str1, wmp_str2)) {
delete wmp_str1;
delete wmp_str2;
}
@@ -4089,9 +4173,12 @@ GameControl *Interface::GetGameControl() const
bool Interface::InitItemTypes()
{
+ int i;
+
if (slotmatrix) {
free(slotmatrix);
}
+
AutoTable it("itemtype");
ItemTypes = 0;
if (it) {
@@ -4105,7 +4192,7 @@ bool Interface::InitItemTypes()
}
//make sure unsigned int is 32 bits
slotmatrix = (ieDword *) malloc(ItemTypes * sizeof(ieDword) );
- for (int i=0;i<ItemTypes;i++) {
+ for (i=0;i<ItemTypes;i++) {
unsigned int value = 0;
unsigned int k = 1;
for (int j=0;j<InvSlotTypes;j++) {
@@ -4119,6 +4206,34 @@ bool Interface::InitItemTypes()
}
}
+ //itemtype data stores (armor failure and critical damage multipliers), critical range
+ itemtypedata.reserve(ItemTypes);
+ for (i=0;i<ItemTypes;i++) {
+ itemtypedata.push_back(std::vector<int>(4));
+ //default values in case itemdata is missing (it is needed only for iwd2)
+ if (slotmatrix[i] & SLOT_WEAPON) {
+ itemtypedata[i][IDT_FAILURE] = 0; // armor malus
+ itemtypedata[i][IDT_CRITRANGE] = 20; // crit range
+ itemtypedata[i][IDT_CRITMULTI] = 2; // crit multiplier
+ itemtypedata[i][IDT_SKILLPENALTY] = 0; // skill check malus
+ }
+ }
+ AutoTable af("itemdata");
+ if (af) {
+ int armcount = af->GetRowCount();
+ int colcount = af->GetColumnCount();
+ int j;
+ for (i = 0; i < armcount; i++) {
+ int itemtype = (ieWord) atoi( af->QueryField(i,0) );
+ if (itemtype<ItemTypes) {
+ // we don't need the itemtype column, since it is equal to the position
+ for (j=0; j < colcount-1; j++) {
+ itemtypedata[itemtype][j] = atoi(af->QueryField(i, j+1));
+ }
+ }
+ }
+ }
+
//slottype describes the inventory structure
Inventory::Init(HasFeature(GF_MAGICBIT));
AutoTable st("slottype");
@@ -4175,6 +4290,8 @@ bool Interface::InitItemTypes()
case SLOT_EFFECT_LEFT: Inventory::SetShieldSlot(i); break;
//head (for averting critical hit)
case SLOT_EFFECT_HEAD: Inventory::SetHeadSlot(i); break;
+ //armor slot
+ case SLOT_EFFECT_ITEM: Inventory::SetArmorSlot(i); break;
default:;
}
}
@@ -4250,6 +4367,60 @@ const char *Interface::QuerySlotResRef(unsigned int idx) const
return slottypes[idx].slotresref;
}
+int Interface::GetArmorFailure(unsigned int itemtype) const
+{
+ if (itemtype>=(unsigned int) ItemTypes) {
+ return 0;
+ }
+ if (slotmatrix[itemtype]&SLOT_ARMOUR) return itemtypedata[itemtype][IDT_FAILURE];
+ return 0;
+}
+
+int Interface::GetShieldFailure(unsigned int itemtype) const
+{
+ if (itemtype>=(unsigned int) ItemTypes) {
+ return 0;
+ }
+ if (slotmatrix[itemtype]&SLOT_SHIELD) return itemtypedata[itemtype][IDT_FAILURE];
+ return 0;
+}
+
+int Interface::GetArmorPenalty(unsigned int itemtype) const
+{
+ if (itemtype>=(unsigned int) ItemTypes) {
+ return 0;
+ }
+ if (slotmatrix[itemtype]&SLOT_ARMOUR) return itemtypedata[itemtype][IDT_SKILLPENALTY];
+ return 0;
+}
+
+int Interface::GetShieldPenalty(unsigned int itemtype) const
+{
+ if (itemtype>=(unsigned int) ItemTypes) {
+ return 0;
+ }
+ if (slotmatrix[itemtype]&SLOT_SHIELD) return itemtypedata[itemtype][IDT_SKILLPENALTY];
+ return 0;
+}
+
+int Interface::GetCriticalMultiplier(unsigned int itemtype) const
+{
+ if (itemtype>=(unsigned int) ItemTypes) {
+ return 2;
+ }
+ if (slotmatrix[itemtype]&SLOT_WEAPON) return itemtypedata[itemtype][IDT_CRITMULTI];
+ return 2;
+}
+
+int Interface::GetCriticalRange(unsigned int itemtype) const
+{
+ if (itemtype>=(unsigned int) ItemTypes) {
+ return 20;
+ }
+ if (slotmatrix[itemtype]&SLOT_WEAPON) return itemtypedata[itemtype][IDT_CRITRANGE];
+ return 20;
+}
+
// checks the itemtype vs. slottype, and also checks the usability flags
// vs. Actor's stats (alignment, class, race, kit etc.)
int Interface::CanUseItemType(int slottype, Item *item, Actor *actor, bool feedback, bool equipped) const
@@ -4269,14 +4440,14 @@ int Interface::CanUseItemType(int slottype, Item *item, Actor *actor, bool feedb
}
if (slottype&SLOT_SHIELD) {
//cannot equip twohanded in offhand
- if (feedback) displaymsg->DisplayConstantString(STR_NOT_IN_OFFHAND, 0xf0f0f0);
+ if (feedback) displaymsg->DisplayConstantString(STR_NOT_IN_OFFHAND, DMC_WHITE);
return 0;
}
}
if ( (unsigned int) item->ItemType>=(unsigned int) ItemTypes) {
//invalid itemtype
- if (feedback) displaymsg->DisplayConstantString(STR_WRONGITEMTYPE, 0xf0f0f0);
+ if (feedback) displaymsg->DisplayConstantString(STR_WRONGITEMTYPE, DMC_WHITE);
return 0;
}
@@ -4285,13 +4456,13 @@ int Interface::CanUseItemType(int slottype, Item *item, Actor *actor, bool feedb
//constant strings
int idx = actor->Unusable(item);
if (idx) {
- if (feedback) displaymsg->DisplayConstantString(idx, 0xf0f0f0);
+ if (feedback) displaymsg->DisplayConstantString(idx, DMC_WHITE);
return 0;
}
//custom strings
ieStrRef str = actor->Disabled(item->Name, item->ItemType);
if (str && !equipped) {
- if (feedback) displaymsg->DisplayString(str, 0xf0f0f0, 0);
+ if (feedback) displaymsg->DisplayString(str, DMC_WHITE, 0);
return 0;
}
}
@@ -4300,7 +4471,7 @@ int Interface::CanUseItemType(int slottype, Item *item, Actor *actor, bool feedb
int ret = (slotmatrix[item->ItemType]&slottype);
if (!ret) {
- if (feedback) displaymsg->DisplayConstantString(STR_WRONGITEMTYPE, 0xf0f0f0);
+ if (feedback) displaymsg->DisplayConstantString(STR_WRONGITEMTYPE, DMC_WHITE);
return 0;
}
@@ -4327,7 +4498,7 @@ int Interface::CanUseItemType(int slottype, Item *item, Actor *actor, bool feedb
}
if (!flg) {
- displaymsg->DisplayConstantString(STR_UNUSABLEITEM, 0xf0f0f0);
+ displaymsg->DisplayConstantString(STR_UNUSABLEITEM, DMC_WHITE);
return 0;
}
}
@@ -4415,7 +4586,7 @@ void Interface::RemoveFromCache(const ieResRef resref, SClass_ID ClassID)
{
char filename[_MAX_PATH];
- snprintf(filename, _MAX_PATH, "%s%.8s%s", CachePath, resref, TypeExt( ClassID ) );
+ PathJoinExt(filename, CachePath, resref, TypeExt(ClassID));
unlink ( filename);
}
@@ -4428,7 +4599,7 @@ bool Interface::StupidityDetector(const char* Pt)
strcpy( Path, Pt );
DirectoryIterator dir(Path);
if (!dir) {
- printf("\n**cannot open**\n");
+ print("\n**cannot open**");
return true;
}
do {
@@ -4440,11 +4611,11 @@ bool Interface::StupidityDetector(const char* Pt)
if (name[1] == '.' && name[2] == '\0')
continue;
}
- printf("\n**contains another dir**\n");
+ print("\n**contains another dir**");
return true; //a directory in there???
}
if (ProtectedExtension(name) ) {
- printf("\n**contains alien files**\n");
+ print("\n**contains alien files**");
return true; //an executable file in there???
}
} while (++dir);
@@ -4488,7 +4659,7 @@ void Interface::LoadProgress(int percent)
void Interface::ReleaseDraggedItem()
{
DraggedItem=NULL; //shouldn't free this
- video->SetDragCursor (NULL);
+ video->SetCursor (NULL, VID_CUR_DRAG);
}
void Interface::DragItem(CREItem *item, const ieResRef Picture)
@@ -4497,7 +4668,7 @@ void Interface::DragItem(CREItem *item, const ieResRef Picture)
//we shouldn't have a valid DraggedItem at this point.
//Anyway, if there is still a dragged item, it will be destroyed.
if (DraggedItem) {
- printMessage("Core","Forgot to call ReleaseDraggedItem when leaving inventory (item destroyed)!\n",YELLOW);
+ Log(WARNING, "Core", "Forgot to call ReleaseDraggedItem when leaving inventory (item destroyed)!");
delete DraggedItem;
}
DraggedItem = item;
@@ -4506,7 +4677,8 @@ void Interface::DragItem(CREItem *item, const ieResRef Picture)
if (item) {
DraggedCursor = gamedata->GetBAMSprite( Picture, 0, 0 );
}
- video->SetDragCursor (DraggedCursor);
+ video->SetCursor (DraggedCursor, VID_CUR_DRAG);
+ if (DraggedCursor) DraggedCursor->release();
}
}
@@ -4515,11 +4687,9 @@ void Interface::SetDraggedPortrait(int dp, int idx)
if (idx<0) idx=14;
DraggedPortrait = dp;
if (dp) {
- //hmm this might work?
- Cursors[idx]->acquire();
- video->SetDragCursor(Cursors[idx]);
+ video->SetCursor(Cursors[idx], VID_CUR_DRAG);
} else {
- video->SetDragCursor(NULL);
+ video->SetCursor(NULL, VID_CUR_DRAG);
}
}
@@ -4615,6 +4785,13 @@ CREItem *Interface::ReadItem(DataStream *str, CREItem *itm)
str->ReadWord( &itm->Usages[1] );
str->ReadWord( &itm->Usages[2] );
str->ReadDword( &itm->Flags );
+ //the stacked flag will be set by the engine if the item is indeed stacked
+ //this is to fix buggy saves so TakeItemNum works
+ //the equipped bit is also reset
+ itm->Flags&=~(IE_INV_ITEM_STACKED|IE_INV_ITEM_EQUIPPED);
+ if (GF_NO_UNDROPPABLE) {
+ itm->Flags&=~IE_INV_ITEM_UNDROPPABLE;
+ }
if (ResolveRandomItem(itm) ) {
return itm;
}
@@ -4635,6 +4812,10 @@ bool Interface::ResolveRandomItem(CREItem *itm)
void* lookup;
if ( !RtRows->Lookup( itm->ItemResRef, lookup ) ) {
+ if (!gamedata->Exists(itm->ItemResRef, IE_ITM_CLASS_ID)) {
+ Log(ERROR, "Interface", "Nonexistent random item (bad table entry) detected: %s", itm->ItemResRef);
+ return false;
+ }
return true;
}
ItemList *itemlist = (ItemList*)lookup;
@@ -4669,8 +4850,8 @@ bool Interface::ResolveRandomItem(CREItem *itm)
}
itm->Usages[0]=(ieWord) Roll(j,k,0);
}
- printMessage("Interface"," ",LIGHT_RED);
- printf("Loop detected while generating random item:%s\n",itm->ItemResRef);
+ Log(ERROR, "Interface", "Loop detected while generating random item:%s",
+ itm->ItemResRef);
return false;
}
@@ -4706,20 +4887,6 @@ Effect *Interface::GetFeatures(int count)
return new Effect[count];
}
-/*
-void Interface::FreeITMExt(ITMExtHeader *p, Effect *e)
-{
- delete [] p;
- delete [] e;
-}
-
-void Interface::FreeSPLExt(SPLExtHeader *p, Effect *e)
-{
- delete [] p;
- delete [] e;
-}
-*/
-
WorldMapArray *Interface::NewWorldMapArray(int count)
{
return new WorldMapArray(count);
@@ -4758,43 +4925,16 @@ Store *Interface::GetCurrentStore()
return CurrentStore;
}
-int Interface::CloseCurrentStore()
+void Interface::CloseCurrentStore()
{
- if ( !CurrentStore ) {
- return -1;
- }
- PluginHolder<StoreMgr> sm(IE_STO_CLASS_ID);
- if (sm == NULL) {
- return -1;
- }
- int size = sm->GetStoredFileSize (CurrentStore);
- if (size > 0) {
- //created streams are always autofree (close file on destruct)
- //this one will be destructed when we return from here
- FileStream str;
-
- str.Create( CurrentStore->Name, IE_STO_CLASS_ID );
- int ret = sm->PutStore (&str, CurrentStore);
- if (ret <0) {
- printMessage("Core"," ", YELLOW);
- printf("Store removed: %s\n", CurrentStore->Name);
- RemoveFromCache(CurrentStore->Name, IE_STO_CLASS_ID);
- }
- } else {
- printMessage("Core"," ", YELLOW);
- printf("Store removed: %s\n", CurrentStore->Name);
- RemoveFromCache(CurrentStore->Name, IE_STO_CLASS_ID);
- }
- //make sure the stream isn't connected to sm, or it will be double freed
- delete CurrentStore;
+ gamedata->SaveStore(CurrentStore);
CurrentStore = NULL;
- return 0;
}
Store *Interface::SetCurrentStore(const ieResRef resname, ieDword owner)
{
- if ( CurrentStore ) {
- if ( !strnicmp(CurrentStore->Name, resname, 8) ) {
+ if (CurrentStore) {
+ if (!strnicmp(CurrentStore->Name, resname, 8)) {
return CurrentStore;
}
@@ -4802,25 +4942,10 @@ Store *Interface::SetCurrentStore(const ieResRef resname, ieDword owner)
CloseCurrentStore();
}
- DataStream* str = gamedata->GetResource( resname, IE_STO_CLASS_ID );
- PluginHolder<StoreMgr> sm(IE_STO_CLASS_ID);
- if (sm == NULL) {
- delete ( str );
- return NULL;
- }
- if (!sm->Open( str, true )) {
- return NULL;
- }
-
- // FIXME - should use some already allocated in core
- // not really, only one store is open at a time, then it is
- // unloaded, we don't really have to cache it, it will be saved in
- // Cache anyway!
- CurrentStore = sm->GetStore( new Store() );
+ CurrentStore = gamedata->GetStore(resname);
if (CurrentStore == NULL) {
return NULL;
}
- strnlwrcpy(CurrentStore->Name, resname, 8);
if (owner) {
CurrentStore->SetOwnerID(owner);
}
@@ -4838,12 +4963,11 @@ int Interface::GetMouseScrollSpeed() {
ieStrRef Interface::GetRumour(const ieResRef dlgref)
{
PluginHolder<DialogMgr> dm(IE_DLG_CLASS_ID);
- dm->Open( gamedata->GetResource( dlgref, IE_DLG_CLASS_ID ), true );
+ dm->Open(gamedata->GetResource(dlgref, IE_DLG_CLASS_ID));
Dialog *dlg = dm->GetDialog();
if (!dlg) {
- printMessage("Interface"," ", LIGHT_RED);
- printf( "Cannot load dialog: %s\n", dlgref );
+ Log(ERROR, "Interface", "Cannot load dialog: %s", dlgref);
return (ieStrRef) -1;
}
Scriptable *pc=game->GetPC( game->GetSelectedPCSingle(), false );
@@ -4857,24 +4981,6 @@ ieStrRef Interface::GetRumour(const ieResRef dlgref)
return ret;
}
-void Interface::DoTheStoreHack(Store *s)
-{
- size_t size = s->PurchasedCategoriesCount * sizeof( ieDword );
- s->purchased_categories=(ieDword *) malloc(size);
-
- size = s->CuresCount * sizeof( STOCure );
- s->cures=(STOCure *) malloc(size);
-
- size = s->DrinksCount * sizeof( STODrink );
- s->drinks=(STODrink *) malloc(size);
-
- for(size=0;size<s->ItemsCount;size++) {
- STOItem *si = new STOItem();
- memset(si, 0, sizeof(STOItem) );
- s->items.push_back( si );
- }
-}
-
//plays stock sound listed in defsound.2da
void Interface::PlaySound(int index)
{
@@ -4900,7 +5006,7 @@ Actor *Interface::GetFirstSelectedPC(bool forced)
}
if (forced && !ret) {
- return game->FindPC((unsigned int) 0);
+ return game->FindPC((unsigned int) 1);
}
return ret;
}
@@ -4930,7 +5036,7 @@ Sprite2D *Interface::GetCursorSprite()
Sprite2D *Interface::GetScrollCursorSprite(int frameNum, int spriteNum)
{
- return gamedata->GetBAMSprite(ScrollCursorBam, frameNum, spriteNum);
+ return gamedata->GetBAMSprite(ScrollCursorBam, frameNum, spriteNum, true);
}
/* we should return -1 if it isn't gold, otherwise return the gold value */
@@ -4971,7 +5077,7 @@ void Interface::ApplySpellPoint(const ieResRef resname, Map* area, const Point &
return;
}
int header = spell->GetHeaderIndexFromLevel(level);
- Projectile *pro = spell->GetProjectile(caster, header, pos);
+ Projectile *pro = spell->GetProjectile(caster, header, level, pos);
pro->SetCaster(caster->GetGlobalID(), level);
area->AddProjectile(pro, caster->Pos, pos);
}
@@ -5001,6 +5107,10 @@ int Interface::ApplyEffectQueue(EffectQueue *fxqueue, Actor *actor, Scriptable *
return ApplyEffectQueue(fxqueue, actor, caster, p);
}
+//FIXME: AddAllEffects will directly apply the effects outside of the mechanisms of Actor::RefreshEffects
+//This means, pcf functions may not be executed when the effect is first applied
+//Adding this new effect block via RefreshEffects is possible, but that might apply existing effects twice
+
int Interface::ApplyEffectQueue(EffectQueue *fxqueue, Actor *actor, Scriptable *caster, Point p)
{
int res = fxqueue->CheckImmunity ( actor );
@@ -5040,6 +5150,14 @@ Effect *Interface::GetEffect(const ieResRef resname, int level, const Point &p)
// dealing with saved games
int Interface::SwapoutArea(Map *map)
{
+ //refuse to save ambush areas, for example
+ if (map->AreaFlags & AF_NOSAVE) {
+ Log(DEBUG, "Core", "Not saving area %s",
+ map->GetScriptName());
+ RemoveFromCache(map->GetScriptName(), IE_ARE_CLASS_ID);
+ return 0;
+ }
+
PluginHolder<MapMgr> mm(IE_ARE_CLASS_ID);
if (mm == NULL) {
return -1;
@@ -5053,13 +5171,13 @@ int Interface::SwapoutArea(Map *map)
str.Create( map->GetScriptName(), IE_ARE_CLASS_ID );
int ret = mm->PutArea (&str, map);
if (ret <0) {
- printMessage("Core"," ", YELLOW);
- printf("Area removed: %s\n", map->GetScriptName());
+ Log(WARNING, "Core", "Area removed: %s",
+ map->GetScriptName());
RemoveFromCache(map->GetScriptName(), IE_ARE_CLASS_ID);
}
} else {
- printMessage("Core"," ", YELLOW);
- printf("Area removed: %s\n", map->GetScriptName());
+ Log(WARNING, "Core", "Area removed: %s",
+ map->GetScriptName());
RemoveFromCache(map->GetScriptName(), IE_ARE_CLASS_ID);
}
//make sure the stream isn't connected to sm, or it will be double freed
@@ -5083,13 +5201,9 @@ int Interface::WriteCharacter(const char *name, Actor *actor)
{
FileStream str;
- if (!str.Create( Path, name, IE_CHR_CLASS_ID ))
- return -1;
-
- int ret = gm->PutActor(&str, actor, true);
- if (ret <0) {
- printMessage("Core"," ", YELLOW);
- printf("Character cannot be saved: %s\n", name);
+ if (!str.Create( Path, name, IE_CHR_CLASS_ID )
+ || (gm->PutActor(&str, actor, true) < 0)) {
+ Log(WARNING, "Core", "Character cannot be saved: %s", name);
return -1;
}
}
@@ -5123,13 +5237,11 @@ int Interface::WriteGame(const char *folder)
str.Create( folder, GameNameResRef, IE_GAM_CLASS_ID );
int ret = gm->PutGame (&str, game);
if (ret <0) {
- printMessage("Core"," ", YELLOW);
- printf("Game cannot be saved: %s\n", folder);
+ Log(WARNING, "Core", "Game cannot be saved: %s", folder);
return -1;
}
} else {
- printMessage("Core"," ", YELLOW);
- printf("Internal error, game cannot be saved: %s\n", folder);
+ Log(WARNING, "Core", "Internal error, game cannot be saved: %s", folder);
return -1;
}
return 0;
@@ -5170,8 +5282,7 @@ int Interface::WriteWorldMap(const char *folder)
ret = wmm->PutWorldMap (&str1, &str2, worldmap);
}
if (ret <0) {
- printMessage("Core"," ", YELLOW);
- printf("Internal error, worldmap cannot be saved: %s\n", folder);
+ Log(WARNING, "Core", "Internal error, worldmap cannot be saved: %s", folder);
return -1;
}
return 0;
@@ -5186,8 +5297,7 @@ int Interface::CompressSave(const char *folder)
if (!dir) {
return -1;
}
- //BIF and SAV are the same
- PluginHolder<ArchiveImporter> ai(IE_BIF_CLASS_ID);
+ PluginHolder<ArchiveImporter> ai(IE_SAV_CLASS_ID);
ai->CreateArchive( &str);
//.tot and .toh should be saved last, because they are updated when an .are is saved
@@ -5203,7 +5313,7 @@ int Interface::CompressSave(const char *folder)
char dtmp[_MAX_PATH];
dir.GetFullPath(dtmp);
FileStream fs;
- fs.Open(dtmp, true);
+ fs.Open(dtmp);
ai->AddToSaveGame(&str, &fs);
}
} while (++dir);
@@ -5226,15 +5336,20 @@ int Interface::GetStrengthBonus(int column, int value, int ex) const
if (value<0)
value = 0;
- else if (value>25)
- value = 25;
+ else if (value>MaximumAbility)
+ value = MaximumAbility;
- if (ex<0)
- ex=0;
- else if (ex>100)
- ex=100;
+ int bonus = 0;
+ // only 18 (human max) has the differentiating extension
+ if (value == 18 && !HasFeature(GF_3ED_RULES)) {
+ if (ex<0)
+ ex=0;
+ else if (ex>100)
+ ex=100;
+ bonus += strmodex[column*101+ex];
+ }
- return strmod[column*(MaximumAbility+1)+value]+strmodex[column*101+ex];
+ return strmod[column*(MaximumAbility+1)+value] + bonus;
}
//The maze columns are used only in the maze spell, no need to restrict them further
@@ -5250,7 +5365,7 @@ int Interface::GetDexterityBonus(int column, int value) const
{
//no dexmod in iwd2 and only one type of modifier
if (HasFeature(GF_3ED_RULES)) {
- return (value-10)/2;
+ return value/2-5;
}
//reaction, missile, ac
@@ -5262,9 +5377,12 @@ int Interface::GetDexterityBonus(int column, int value) const
int Interface::GetConstitutionBonus(int column, int value) const
{
- //no conmod in iwd2
+ //no conmod in iwd2 and also no regenation bonus
if (HasFeature(GF_3ED_RULES)) {
- return (value-10)/2;
+ if (column == STAT_CON_HP_REGEN) {
+ return 0;
+ }
+ return value/2-5;
}
//normal, warrior, minimum, regen hp, regen fatigue
@@ -5298,7 +5416,7 @@ int Interface::GetWisdomBonus(int column, int value) const
{
//no wismod in iwd2
if (HasFeature(GF_3ED_RULES)) {
- return (value-10)/2;
+ return value/2-5;
}
if (!HasFeature(GF_WISDOM_BONUS)) return 0;
@@ -5327,31 +5445,63 @@ int Interface::GetReputationMod(int column) const
return reputationmod[reputation][column];
}
-// -3, -2 if request is illegal or in cutscene
-// -1 if pause is already active
-// 0 if pause was not allowed
-// 1 if autopause happened
-int Interface::Autopause(ieDword flag)
+PauseSetting Interface::TogglePause()
{
GameControl *gc = GetGameControl();
- if (!gc) {
- return -3;
- }
- if (InCutSceneMode()) {
- return -2;
- }
- if (gc->GetDialogueFlags()&DF_FREEZE_SCRIPTS) {
- return -1;
+ if (!gc) return PAUSE_OFF;
+ PauseSetting pause = (PauseSetting)(~gc->GetDialogueFlags()&DF_FREEZE_SCRIPTS);
+ if (SetPause(pause)) return pause;
+ return (PauseSetting)(gc->GetDialogueFlags()&DF_FREEZE_SCRIPTS);
+}
+
+bool Interface::SetPause(PauseSetting pause, int flags)
+{
+ GameControl *gc = GetGameControl();
+
+ //don't allow soft pause in cutscenes and dialog
+ if (!(flags&PF_FORCED) && InCutSceneMode()) gc = NULL;
+
+ if (gc && ((bool)(gc->GetDialogueFlags()&DF_FREEZE_SCRIPTS) != (bool)pause)) { // already paused
+ int strref;
+ if (pause) {
+ strref = STR_PAUSED;
+ gc->SetDialogueFlags(DF_FREEZE_SCRIPTS, BM_OR);
+ } else {
+ strref = STR_UNPAUSED;
+ gc->SetDialogueFlags(DF_FREEZE_SCRIPTS, BM_NAND);
+ }
+ if (!(flags&PF_QUIET) ) {
+ if (pause) gc->SetDisplayText(strref, 0); // time 0 = removed instantly on unpause (for pst)
+ displaymsg->DisplayConstantString(strref, DMC_RED);
+ }
+ return true;
}
- ieDword autopause_flags = 0;
+ return false;
+}
+bool Interface::Autopause(ieDword flag, Scriptable* target)
+{
+ ieDword autopause_flags = 0;
vars->Lookup("Auto Pause State", autopause_flags);
- if (autopause_flags & (1<<flag)) {
- displaymsg->DisplayConstantString(STR_AP_UNUSABLE+flag, 0xff0000);
- gc->SetDialogueFlags(DF_FREEZE_SCRIPTS, BM_OR);
- return 1;
+
+ if ((autopause_flags & (1<<flag))) {
+ if (SetPause(PAUSE_ON, PF_QUIET)) {
+ displaymsg->DisplayConstantString(STR_AP_UNUSABLE+flag, DMC_RED);
+
+ ieDword autopause_center = 0;
+ vars->Lookup("Auto Pause Center", autopause_center);
+ if (autopause_center && target) {
+ Point screenPos = target->Pos;
+ core->GetVideoDriver()->ConvertToScreen(screenPos.x, screenPos.y);
+ GetGameControl()->Center(screenPos.x, screenPos.y);
+ if (target->Type == ST_ACTOR && ((Actor *)target)->GetStat(IE_EA) < EA_GOODCUTOFF) {
+ core->GetGame()->SelectActor((Actor *)target, true, SELECT_REPLACE);
+ }
+ }
+ return true;
+ }
}
- return 0;
+ return false;
}
void Interface::RegisterOpcodes(int count, const EffectDesc *opcodes)
@@ -5414,7 +5564,7 @@ ieDword *Interface::GetListFrom2DAInternal(const ieResRef resref)
ieDword* Interface::GetListFrom2DA(const ieResRef tablename)
{
- ieDword *list;
+ ieDword *list = NULL;
if (!lists->Lookup(tablename, (void *&) list)) {
list = GetListFrom2DAInternal(tablename);
@@ -5435,14 +5585,63 @@ ieDword Interface::TranslateStat(const char *stat_name)
int symbol = LoadSymbol( "stats" );
Holder<SymbolMgr> sym = GetSymbol( symbol );
+ if (!sym) {
+ error("Core", "Cannot load statistic name mappings.\n");
+ }
ieDword stat = (ieDword) sym->GetValue( stat_name );
if (stat==(ieDword) ~0) {
- printMessage("Core"," ",YELLOW);
- printf("Cannot translate symbol: %s\n", stat_name);
+ Log(WARNING, "Core", "Cannot translate symbol: %s", stat_name);
}
return stat;
}
+// Calculates an arbitrary stat bonus, based on tables.
+// the master table contains the table names (as row names) and the used stat
+// the subtables contain stat value/bonus pairs.
+// Optionally an override stat value can be specified (needed for use in pcfs).
+int Interface::ResolveStatBonus(Actor *actor, const char *tablename, ieDword flags, int value)
+{
+ int mastertable = gamedata->LoadTable( tablename );
+ Holder<TableMgr> mtm = gamedata->GetTable( mastertable );
+ if (!mtm) {
+ Log(ERROR, "Core", "Cannot resolve stat bonus.");
+ return -1;
+ }
+ int count = mtm->GetRowCount();
+ if (count< 1) {
+ return 0;
+ }
+ int ret = 0;
+ // tables for additive modifiers of bonus type
+ for (int i = 0; i < count; i++) {
+ tablename = mtm->GetRowName(i);
+ int checkcol = strtol(mtm->QueryField(i,1), NULL, 0);
+ unsigned int readcol = strtol(mtm->QueryField(i,2), NULL, 0);
+ int stat = TranslateStat(mtm->QueryField(i,0) );
+ if (!(flags&1)) {
+ value = actor->GetSafeStat(stat);
+ }
+ int table = gamedata->LoadTable( tablename );
+ Holder<TableMgr> tm = gamedata->GetTable( table );
+ if (!tm) continue;
+
+ int row;
+ if (checkcol == -1) {
+ // use the row names
+ char tmp[30];
+ snprintf(tmp, sizeof(tmp), "%d", value);
+ row = tm->GetRowIndex(tmp);
+ } else {
+ // use the checkcol column (default of 0)
+ row = tm->FindTableValue(checkcol, value, 0);
+ }
+ if (row>=0) {
+ ret += strtol(tm->QueryField(row, readcol), NULL, 0);
+ }
+ }
+ return ret;
+}
+
void Interface::WaitForDisc(int disc_number, const char* path)
{
GetDictionary()->SetAt( "WaitForDisc", (ieDword) disc_number );
@@ -5480,13 +5679,14 @@ void Interface::SetTickHook(EventHandler hook)
void Interface::SetNextScript(const char *script)
{
- strncpy( NextScript, script, sizeof(NextScript) );
+ strlcpy( NextScript, script, sizeof(NextScript) );
QuitFlag |= QF_CHANGESCRIPT;
}
void Interface::SanityCheck(const char *ver) {
if (strcmp(ver, VERSION_GEMRB)) {
- printf("version check failed: core version %s doesn't match caller's version %s\n", VERSION_GEMRB, ver);
- abort();
+ error("Core", "version check failed: core version %s doesn't match caller's version %s\n", VERSION_GEMRB, ver);
}
}
+
+}
diff --git a/gemrb/core/Interface.h b/gemrb/core/Interface.h
index af2c42a..7c3417d 100644
--- a/gemrb/core/Interface.h
+++ b/gemrb/core/Interface.h
@@ -26,22 +26,20 @@
#ifndef INTERFACE_H
#define INTERFACE_H
-//skip messy warnings in MSVC6
-#include "win32def.h"
-
#include "SClassID.h"
#include "exports.h"
+#include "Audio.h" // needed for _MSC_VER and SoundHandle (everywhere)
#include "Cache.h"
#include "Callback.h"
-#include "GlobalTimer.h"
#include "Holder.h"
+#include "InterfaceConfig.h"
#include <map>
#include <string>
+#include <vector>
#ifdef _MSC_VER // No SFINAE
-#include "Audio.h"
#include "DataFileMgr.h"
#include "MusicMgr.h"
#include "SaveGame.h"
@@ -49,8 +47,11 @@
#include "StringMgr.h"
#include "SymbolMgr.h"
#include "Video.h"
+#include "WindowMgr.h"
#endif
+namespace GemRB {
+
class Actor;
class Audio;
class CREItem;
@@ -67,9 +68,11 @@ class Factory;
class Font;
class Game;
class GameControl;
+class GlobalTimer;
class ITMExtHeader;
class Image;
class Item;
+class KeyMap;
class Label;
class Map;
class MusicMgr;
@@ -82,6 +85,7 @@ class SaveGameIterator;
class ScriptEngine;
class ScriptedAnimation;
class Spell;
+class Sprite2D;
class Store;
class StringMgr;
class SymbolMgr;
@@ -114,6 +118,7 @@ struct DamageInfoStruct {
unsigned int resist_stat;
unsigned int value;
int iwd_mod_type;
+ int reduction;
// maybe also add the ac bonus and/or the DL_ constants
};
@@ -131,6 +136,7 @@ struct TimeStruct {
unsigned int turn_sec;
unsigned int round_size; // in ticks
unsigned int rounds_per_turn;
+ unsigned int attack_round_size;
};
struct SpellDescType {
@@ -139,6 +145,7 @@ struct SpellDescType {
};
#define SP_IDENTIFY 1 //any spell that cannot be cast from the menu
#define SP_SILENCE 2 //any spell that can be cast in silence
+#define SP_SURGE 4 //any spell that cannot be cast during a wild surge
struct SurgeSpell {
ieResRef spell;
@@ -187,6 +194,7 @@ public:
#define QF_CHANGESCRIPT 4
#define QF_LOADGAME 8
#define QF_ENTERGAME 16
+#define QF_KILL 32
//events that are called out of drawwindow
//they wait until the condition is right
@@ -203,6 +211,7 @@ public:
#define EF_CREATEMAZE 1024 //call the maze generator
#define EF_RESETTARGET 2048 //reset the mouse cursor
#define EF_TARGETMODE 4096 //update the mouse cursor
+#define EF_TEXTSCREEN 8192 //start a textscreen
//autopause
#define AP_UNUSABLE 0
@@ -215,6 +224,11 @@ public:
#define AP_ENEMY 7
#define AP_TRAP 8
#define AP_SPELLCAST 9
+#define AP_GENERIC 10 //needed for Android stuff
+
+//pause flags
+#define PF_QUIET 1 //no feedback
+#define PF_FORCED 2 //pause even in cutscene/dialog
/** ea relations (derivated from 2 actor's EA value) */
#define EAR_FRIEND 0
@@ -267,6 +281,11 @@ enum PluginFlagsType {
PLF_DELAY
};
+enum PauseSetting {
+ PAUSE_OFF = 0,
+ PAUSE_ON = 1
+};
+
/**
* @class Interface
* Central interconnect for all GemRB parts, driving functions and utility functions possibly belonging to a better place
@@ -306,8 +325,6 @@ private:
Calendar * calendar;
WorldMapArray* worldmap;
ieDword GameFeatures[(GF_COUNT+31)/32];
- //ieDword GameFeatures; //the first 32 bits
- //ieDword GameFeatures2;//the second 32 bits
ieResRef ButtonFont;
ieResRef CursorBam;
ieResRef ScrollCursorBam;
@@ -325,11 +342,13 @@ private:
ieResRef Palette32;
ieResRef Palette256;
ieDword* slotmatrix; //itemtype vs slottype
+ std::vector<std::vector<int> > itemtypedata; //armor failure, critical multiplier, critical range
SlotType* slottypes;
int ItemTypes;
int tooltip_x;
int tooltip_y;
int tooltip_currtextw;
+ Holder<SoundHandle> tooltip_sound;
// the control owning the tooltip
Control* tooltip_ctrl;
// Currently dragged item or NULL
@@ -349,7 +368,10 @@ private:
EventHandler TickHook;
int SpecialSpellsCount;
SpellDescType *SpecialSpells;
+ KeyMap *keymap;
+ std::string Encoding;
public:
+ std::string TLKEncoding;
Holder<StringMgr> strings;
GlobalTimer * timer;
Palette *InfoTextPalette;
@@ -378,9 +400,9 @@ public:
TimeStruct Time;
std::vector<SurgeSpell> SurgeSpells;
public:
- Interface(int iargc, char *iargv[]);
+ Interface();
~Interface(void);
- int Init(void);
+ int Init(InterfaceConfig* config);
//TODO: Core Methods in Interface Class
void SetFeature(int value, int position);
/* don't rely on the exact return value of this function */
@@ -418,6 +440,7 @@ public:
/** Loads a Window in the Window Manager */
int LoadWindow(unsigned short WindowID);
/** Creates a Window in the Window Manager */
+ bool IsPresentingModalWindow() {return (bool)(ModalWindow);};
#ifdef WIN32
#ifdef CreateWindow
#undef CreateWindow
@@ -432,10 +455,8 @@ public:
int GetControl(unsigned short WindowIndex, unsigned long ControlID) const;
/** Adjust the scrolling of the control (if applicable) */
int AdjustScrolling(unsigned short WindowIndex, unsigned short ControlIndex, short x, short y);
- /** Set the Text of a Control */
- int SetText(unsigned short WindowIndex, unsigned short ControlIndex, const char * string);
/** Set the Tooltip text of a Control */
- int SetTooltip(unsigned short WindowIndex, unsigned short ControlIndex, const char * string);
+ int SetTooltip(unsigned short WindowIndex, unsigned short ControlIndex, const char * string, int Function = 0);
/** sets tooltip to be displayed */
void DisplayTooltip(int x, int y, Control* ctrl);
/** Actually draws tooltip on the screen. Called from SDLVideoDriver */
@@ -495,15 +516,7 @@ public:
/** returns true if in cutscene mode */
bool InCutSceneMode() const;
/** Updates the Game Script Engine State */
- void GSUpdate(bool update_scripts)
- {
- if(update_scripts) {
- timer->Update();
- }
- else {
- timer->Freeze();
- }
- }
+ bool GSUpdate(bool update_scripts);
/** Get the Party INI Interpreter */
DataFileMgr * GetPartyINI() const
{
@@ -532,6 +545,12 @@ public:
return calendar;
}
+ /** Gets the KeyMap class */
+ KeyMap * GetKeyMap() const
+ {
+ return keymap;
+ }
+
/** Gets the WorldMap class, returns the current worldmap or the first worldmap containing the area*/
WorldMap * GetWorldMap(const char *area = NULL);
void SetWindowFrame(int i, Sprite2D *Picture);
@@ -547,6 +566,8 @@ public:
/** load saved game by index (-1 is default), ver_override is an optional parameter
to override the saved game's version */
void LoadGame(SaveGame *save, int ver_override);
+ /** reloads the world map from a resource file */
+ void UpdateWorldMap(ieResRef wmResRef);
/** fix changes in global script/worldmap*/
void UpdateMasterScript();
/*reads the filenames of the portraits folder into a list */
@@ -564,6 +585,12 @@ public:
ieDword QuerySlotFlags(unsigned int idx) const;
ieDword QuerySlotEffects(unsigned int idx) const;
const char * QuerySlotResRef(unsigned int idx) const;
+ int GetArmorFailure(unsigned int itemtype) const;
+ int GetShieldFailure(unsigned int itemtype) const;
+ int GetArmorPenalty(unsigned int itemtype) const;
+ int GetShieldPenalty(unsigned int itemtype) const;
+ int GetCriticalMultiplier(unsigned int itemtype) const;
+ int GetCriticalRange(unsigned int itemtype) const;
/*returns true if an itemtype is acceptable for a slottype, also checks the usability flags */
int CanUseItemType(int slottype, Item *item, Actor *actor=NULL, bool feedback=false, bool equipped=false) const;
/*removes single file from cache*/
@@ -595,7 +622,7 @@ public:
int CloseCurrentContainer();
void SetCurrentContainer(Actor *actor, Container *arg, bool flag=false);
Store *GetCurrentStore();
- int CloseCurrentStore();
+ void CloseCurrentStore();
Store *SetCurrentStore(const ieResRef resname, ieDword owner);
void SetMouseScrollSpeed(int speed);
int GetMouseScrollSpeed();
@@ -609,7 +636,6 @@ public:
void FreeITMExt(ITMExtHeader *p, Effect *e);
void FreeSPLExt(SPLExtHeader *p, Effect *e);
WorldMapArray *NewWorldMapArray(int count);
- void DoTheStoreHack(Store *s);
/** plays stock gui sound referenced by index */
void PlaySound(int idx);
/** returns the first selected PC, if forced is set, then it returns
@@ -653,8 +679,12 @@ public:
int WriteWorldMap(const char *folder);
/** saves the .are and .sto files to the destination folder */
int CompressSave(const char *folder);
- /** receives an autopause reason, returns 1 if pause was triggered by this call, -1 if it was already triggered */
- int Autopause(ieDword reason);
+ /** toggles the pause. returns either PAUSE_ON or PAUSE_OFF to reflect the script state after toggling. */
+ PauseSetting TogglePause();
+ /** returns true the passed pause setting was applied. false otherwise. */
+ bool SetPause(PauseSetting pause, int flags = 0);
+ /** receives an autopause reason, returns true if autopause was accepted and successful */
+ bool Autopause(ieDword flag, Scriptable *target);
/** registers engine opcodes */
void RegisterOpcodes(int count, const EffectDesc *opcodes);
/** reads a list of resrefs into an array, returns array size */
@@ -678,6 +708,8 @@ public:
ieDword *GetListFrom2DA(const ieResRef resref);
/** translates a stat symbol to numeric value */
ieDword TranslateStat(const char *stat_name);
+ /** resolves a stat bonus based on multiple stats */
+ int ResolveStatBonus(Actor *actor, const char *tablename, ieDword flags = 0, int value = 0);
/** Opens CD prompt window and waits for the specified disc */
void WaitForDisc(int disc_number, const char* path);
/** Returns the music playlist corresponding to the provided type */
@@ -687,16 +719,18 @@ public:
void StripLine(char * string, size_t size);
/** Returns the DeathVarFormat of the day */
static const char *GetDeathVarFormat();
- int CheckSpecialSpell(ieResRef resref, Actor *actor);
- int GetSpecialSpell(ieResRef resref);
+ int CheckSpecialSpell(const ieResRef resref, Actor *actor);
+ int GetSpecialSpell(const ieResRef resref);
int GetSpecialSpellsCount() { return SpecialSpellsCount; }
SpellDescType *GetSpecialSpells() { return SpecialSpells; }
+ /** Saves config variables to a file */
+ bool SaveConfig();
private:
int LoadSprites();
- bool LoadConfig(void);
- bool LoadConfig(const char *filename);
bool LoadGemRBINI();
- bool LoadINI(const char * filename);
+ /** Load the encoding table selected in gemrb.cfg */
+ bool LoadEncoding();
+ bool InitializeVarsWithINI(const char * iniFileName);
bool InitItemTypes();
bool ReadRandomItems();
bool ReadItemTable(const ieResRef item, const char *Prefix);
@@ -732,12 +766,11 @@ public:
char GamePortraitsPath[_MAX_PATH];
char GameCharactersPath[_MAX_PATH];
char GemRBOverridePath[_MAX_PATH];
+ char GemRBUnhardcodedPath[_MAX_PATH];
ieResRef GameNameResRef;
ieResRef GoldResRef; //MISC07.itm
Variables *RtRows;
- char UserDir[_MAX_PATH];
- int argc;
- char **argv;
+ char CustomFontPath[_MAX_PATH];
char GameName[_MAX_PATH];
char GameType[_MAX_PATH];
char GemRBPath[_MAX_PATH];
@@ -753,18 +786,22 @@ public:
unsigned int TooltipDelay;
int IgnoreOriginalINI;
unsigned int FogOfWar;
- bool CaseSensitive, GameOnCD, SkipIntroVideos, DrawFPS;
- bool GUIEnhancements;
+ bool CaseSensitive, SkipIntroVideos, DrawFPS;
+ bool TouchScrollAreas, UseSoftKeyboard;
+ unsigned short NumFingScroll, NumFingKboard, NumFingInfo;
+ int MouseFeedback;
+ int GUIEnhancements;
bool KeepCache;
+ bool MultipleQuickSaves;
Variables *plugin_flags;
/** The Main program loop */
void Main(void);
/** returns true if the game is paused */
bool IsFreezed();
/** Draws the Visible windows in the Windows Array */
- void DrawWindows(void);
- /** Sends a termination signal to the Video Driver */
- bool Quit(void);
+ void DrawWindows(bool allow_delete = false);
+ void AskAndExit();
+ void ExitGemRB(void);
/** CheatKey support */
inline void EnableCheatKeys(int Flag)
{
@@ -799,13 +836,10 @@ public:
Audio* GetAudioDrv(void) const;
void SetTickHook(EventHandler);
-
-#ifdef _DEBUG
- int FileStreamPtrCount;
- int CachedFileStreamPtrCount;
-#endif
};
extern GEM_EXPORT Interface * core;
+}
+
#endif
diff --git a/gemrb/core/InterfaceConfig.cpp b/gemrb/core/InterfaceConfig.cpp
new file mode 100644
index 0000000..fc8f91f
--- /dev/null
+++ b/gemrb/core/InterfaceConfig.cpp
@@ -0,0 +1,232 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2013 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "globals.h"
+
+#include "InterfaceConfig.h"
+
+#include "System/FileStream.h"
+
+// needed for unused std::string version of GetValueForKey
+//#include <algorithm>
+
+namespace GemRB {
+
+InterfaceConfig::InterfaceConfig(int /*argc*/, char** /**argv[]*/)
+{
+ // currently the base class has no CLI options.
+ configVars = new StringMap();
+ configVars->init(50, 10);
+
+ // default to the correct endianswitch
+ ieWord endiantest = 1;
+ if (((char *)&endiantest)[1] == 1) {
+ // big-endian
+ DataStream::SetEndianSwitch(true);
+ }
+}
+
+InterfaceConfig::~InterfaceConfig()
+{
+ delete configVars;
+}
+
+void InterfaceConfig::SetKeyValuePair(const char* key, const char* value)
+{
+ // lowercase the key so that the key is not case sensitive
+ char* keyCopy = strdup(key);
+ for (char* c = keyCopy; *c != '\0'; ++c) *c = tolower(*c);
+ configVars->set(keyCopy, value);
+ free(keyCopy);
+}
+
+const char* InterfaceConfig::GetValueForKey(const char* key) const
+{
+ const char* value = NULL;
+ if (key) {
+ // lowercase the key so that the key is not case sensitive
+ char* keyCopy = strdup(key);
+ for (char* c = keyCopy; *c != '\0'; ++c) *c = tolower(*c);
+ if (configVars->get(keyCopy)) {
+ value = configVars->get(keyCopy)->c_str();
+ }
+ free(keyCopy);
+ }
+ return value;
+}
+/*
+Currently unused. does not compile under MSVC.
+
+FIXME: if we need this we should consider having one version of GetValueForKey call the other
+
+const std::string* InterfaceConfig::GetValueForKey(std::string* key) const
+{
+ const std::string* value = NULL;
+ if (key) {
+ std::string* keyCopy = key;
+ std::transform(keyCopy->begin(), keyCopy->end(), keyCopy->begin(),
+ (int(*)(int)) std::tolower);
+ value = configVars->get(keyCopy->c_str());
+ delete keyCopy;
+ }
+ return value;
+}
+*/
+CFGConfig::CFGConfig(int argc, char *argv[])
+ : InterfaceConfig(argc, argv)
+{
+ isValid = false;
+ FileStream* config = new FileStream();
+ // skip arg0 (it is just gemrb)
+ for (int i=1; i < argc; i++) {
+ if (stricmp(argv[i], "-c") == 0) {
+ const char* filename = argv[++i];
+
+ if (!config->Open(filename)) {
+ // Explicitly specified cfg file HAS to be present
+ Log(FATAL, "Config", "Failed to open config file \"%s\".", filename);
+ }
+ isValid = InitWithINIData(config);
+ }
+ }
+ if (!isValid) {
+ // nothing passed in on CLI, so search for gemrb.cfg
+ char datadir[_MAX_PATH];
+ char path[_MAX_PATH];
+ char name[_MAX_PATH];
+
+ // Find basename of this program. It does the same as basename (3),
+ // but that's probably missing on some archs
+ char* appName = strrchr( argv[0], PathDelimiter );
+ if (appName) {
+ appName++;
+ } else {
+ appName = argv[0];
+ }
+
+ strcpy( name, appName );
+ assert(name[0]);
+
+#if TARGET_OS_MAC
+ // CopyGemDataPath would give us bundle resources dir
+ CopyHomePath(datadir, _MAX_PATH);
+ PathAppend(datadir, PACKAGE);
+#else
+ CopyGemDataPath(datadir, _MAX_PATH);
+#endif
+ PathJoinExt( path, datadir, name, "cfg" );
+
+#define ATTEMPT_INIT \
+if (config->Open(path) \
+ && InitWithINIData(config)) { \
+ goto done; \
+ }
+
+ ATTEMPT_INIT;
+
+#ifdef SYSCONFDIR
+ PathJoinExt( path, SYSCONFDIR, name, "cfg" );
+ ATTEMPT_INIT
+#endif
+
+ // Don't try with default binary name if we have tried it already
+ if (strcmp( name, PACKAGE ) != 0) {
+ PathJoinExt( path, datadir, PACKAGE, "cfg" );
+
+ ATTEMPT_INIT;
+
+#ifdef SYSCONFDIR
+ PathJoinExt( path, SYSCONFDIR, PACKAGE, "cfg" );
+ ATTEMPT_INIT;
+#endif
+ }
+ // if all else has failed try current directory
+ PathJoinExt(path, "./", PACKAGE, "cfg");
+ ATTEMPT_INIT;
+ }
+#undef ATTEMPT_INIT
+done:
+ delete config;
+}
+
+CFGConfig::~CFGConfig()
+{}
+
+bool CFGConfig::InitWithINIData(DataStream* const cfgStream)
+{
+ if (cfgStream == NULL) {
+ return false;
+ }
+
+ if (isValid) {
+ Log(WARNING, "Config", "attempting to replace config values with contents of %s", cfgStream->filename);
+ } else {
+ Log(MESSAGE, "Config", "attempting to initialize config with %s", cfgStream->filename);
+ }
+
+ isValid = false;
+ int lineno = 0;
+ char line[1024];
+ while (cfgStream->Remains()) {
+ char *key, *keyend, *value, *valueend;
+
+ if (cfgStream->ReadLine(line, _MAX_PATH) == -1) {
+ break;
+ }
+ lineno++;
+
+ // skip leading blanks from name
+ key = line;
+ key += strspn( line, " \t\r\n" );
+
+ // ignore empty or comment lines
+ if (*key == '\0' || *key == '#') {
+ continue;
+ }
+
+ value = strchr( key, '=' );
+ if (!value || value == key) {
+ Log(WARNING, "Config", "Invalid line %d", lineno);
+ continue;
+ }
+
+ // trim trailing blanks from name
+ keyend = value;
+ while (keyend > key && strchr( "= \t", *keyend )) {
+ *keyend-- = '\0';
+ }
+
+ value++;
+ // skip leading blanks
+ value += strspn( value, " \t");
+
+ // trim trailing blanks from value
+ valueend = value + strlen( value ) - 1;
+ while (valueend >= value && strchr( " \t\r\n", *valueend )) {
+ *valueend-- = '\0';
+ }
+ SetKeyValuePair(key, value);
+ }
+ isValid = true;
+ return true;
+}
+
+}
+
diff --git a/gemrb/core/InterfaceConfig.h b/gemrb/core/InterfaceConfig.h
new file mode 100644
index 0000000..bb2bf80
--- /dev/null
+++ b/gemrb/core/InterfaceConfig.h
@@ -0,0 +1,66 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2013 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef __GemRB__InterfaceConfig__
+#define __GemRB__InterfaceConfig__
+
+#include "exports.h"
+
+#include "StringMap.h"
+
+#include "System/DataStream.h"
+
+namespace GemRB {
+
+class GEM_EXPORT InterfaceConfig
+{
+private:
+ StringMap* configVars;
+
+public:
+ InterfaceConfig(int argc, char *argv[]);
+ virtual ~InterfaceConfig();
+
+ void SetKeyValuePair(const char* key, const char* value);
+ const char* GetValueForKey(const char* key) const;
+ //const std::string* GetValueForKey(std::string* key) const;
+};
+
+// the defacto config class
+// any platform can use it, but many will want to have their own
+// that coan create a InterfaceConfig instance from non cfg sources
+class GEM_EXPORT CFGConfig : public InterfaceConfig
+{
+private:
+ bool isValid;
+
+private:
+ bool InitWithINIData(DataStream* const cfgStream);
+
+public:
+ CFGConfig(int argc, char *argv[]);
+ ~CFGConfig();
+
+ bool IsValidConfig() {return isValid;};
+};
+
+}
+
+#endif /* defined(__GemRB__InterfaceConfig__) */
diff --git a/gemrb/core/Inventory.cpp b/gemrb/core/Inventory.cpp
index 0879437..73b5f4a 100644
--- a/gemrb/core/Inventory.cpp
+++ b/gemrb/core/Inventory.cpp
@@ -26,16 +26,21 @@
#include "win32def.h"
#include "strrefs.h"
+#include "CharAnimations.h"
#include "DisplayMessage.h"
#include "Game.h"
#include "GameData.h"
#include "Interface.h"
#include "Item.h"
+#include "Map.h"
#include "ScriptEngine.h"
#include "Scriptable/Actor.h"
+#include "System/StringBuffer.h"
#include <cstdio>
+namespace GemRB {
+
static int SLOT_HEAD = -1;
static int SLOT_MAGIC = -1;
static int SLOT_FIST = -1;
@@ -48,6 +53,7 @@ static int LAST_QUICK = -1;
static int SLOT_INV = -1;
static int LAST_INV = -1;
static int SLOT_LEFT = -1;
+static int SLOT_ARMOR = -1;
//IWD2 style slots
static bool IWD2 = false;
@@ -55,9 +61,7 @@ static int MagicBit = 0;
static void InvalidSlot(int slot)
{
- printMessage("Inventory"," ",LIGHT_RED);
- printf("Invalid slot: %d!\n",slot);
- abort();
+ error("Inventory", "Invalid slot: %d!\n", slot);
}
//This inline function returns both an item pointer and the slot data.
@@ -81,6 +85,7 @@ void Inventory::Init(int mb)
SLOT_QUICK=-1;
LAST_QUICK=-1;
SLOT_LEFT=-1;
+ SLOT_ARMOR=-1;
//TODO: set this correctly
IWD2 = false;
MagicBit = mb;
@@ -152,12 +157,16 @@ CREItem *Inventory::GetItem(unsigned int slot)
return item;
}
-//This hack sets the charge counters for non-rechargeable items,
-//if their charge is zero
-inline void HackCharges(CREItem *item)
+//Make sure the item attributes are valid
+//we don't update all flags here because some need to be set later (like
+//unmovable items in containers (e.g. the bg2 protal key) so that they
+//can actually be picked up)
+void Inventory::SanitizeItem(CREItem *item)
{
- Item *itm = gamedata->GetItem( item->ItemResRef );
+ Item *itm = gamedata->GetItem(item->ItemResRef, true);
if (itm) {
+ //This hack sets the charge counters for non-rechargeable items,
+ //if their charge is zero
for (int i=0;i<3;i++) {
if (item->Usages[i]) {
continue;
@@ -172,6 +181,19 @@ inline void HackCharges(CREItem *item)
}
}
}
+
+ //auto identify basic items
+ if (!itm->LoreToID) {
+ item->Flags |= IE_INV_ITEM_IDENTIFIED;
+ }
+
+ //if item is stacked mark it as so
+ if (itm->MaxStackAmount) {
+ item->Flags |= IE_INV_ITEM_STACKED;
+ }
+
+ item->MaxStackAmount = itm->MaxStackAmount;
+
gamedata->FreeItem( itm, item->ItemResRef, false );
}
}
@@ -180,13 +202,10 @@ void Inventory::AddItem(CREItem *item)
{
if (!item) return; //invalid items get no slot
Slots.push_back(item);
- HackCharges(item);
- //this will update the flags (needed for unmovable items in containers)
- //but those *can* be picked up (like the bg2 portal key), so we skip it
- //Changed=true;
+ SanitizeItem(item);
}
-void Inventory::CalculateWeight()
+void Inventory::CalculateWeight() const
{
if (!Changed) {
return;
@@ -198,7 +217,7 @@ void Inventory::CalculateWeight()
continue;
}
if (slot->Weight == -1) {
- Item *itm = gamedata->GetItem( slot->ItemResRef );
+ Item *itm = gamedata->GetItem(slot->ItemResRef, true);
if (itm) {
//simply adding the item flags to the slot
slot->Flags |= (itm->Flags<<8);
@@ -222,30 +241,20 @@ void Inventory::CalculateWeight()
slot->Flags |= IE_INV_ITEM_STOLEN;
}
- //auto identify basic items
- if (!itm->LoreToID) {
- slot->Flags |= IE_INV_ITEM_IDENTIFIED;
- }
-
- //if item is stacked mark it as so
- if (itm->StackAmount) {
- slot->Flags |= IE_INV_ITEM_STACKED;
- }
-
slot->Weight = itm->Weight;
- slot->StackAmount = itm->StackAmount;
+
gamedata->FreeItem( itm, slot->ItemResRef, false );
}
else {
- printMessage( "Inventory", " ", LIGHT_RED);
- printf("Invalid item: %s!\n", slot->ItemResRef);
+ Log(ERROR, "Inventory", "Invalid item: %s!",
+ slot->ItemResRef);
slot->Weight = 0;
}
} else {
slot->Flags &= ~IE_INV_ITEM_ACQUIRED;
}
if (slot->Weight > 0) {
- Weight += slot->Weight * ((slot->Usages[0] && slot->StackAmount > 1) ? slot->Usages[0] : 1);
+ Weight += slot->Weight * ((slot->Usages[0] && slot->MaxStackAmount) ? slot->Usages[0] : 1);
}
}
Changed = false;
@@ -257,7 +266,7 @@ void Inventory::AddSlotEffects(ieDword index)
const Item *itm = GetItemPointer(index, slot);
if (!itm) {
- printMessage("Inventory","Invalid item equipped...\n",LIGHT_RED);
+ Log(ERROR, "Inventory", "Invalid item equipped...");
return;
}
ItemExcl|=itm->ItemExcl;
@@ -303,10 +312,9 @@ void Inventory::SetInventoryType(int arg)
void Inventory::SetSlotCount(unsigned int size)
{
if (Slots.size()) {
- printf("Inventory size changed???\n");
+ error("Core", "Inventory size changed???\n");
//we don't allow reassignment,
//if you want this, delete the previous Slots here
- abort();
}
Slots.assign((size_t) size, NULL);
}
@@ -350,11 +358,12 @@ int Inventory::CountItems(const char *resref, bool stacks) const
continue;
}
if (resref && resref[0]) {
- if (!strnicmp(resref, item->ItemResRef, 8) )
+ if (strnicmp(resref, item->ItemResRef, 8) )
continue;
}
if (stacks && (item->Flags&IE_INV_ITEM_STACKED) ) {
count+=item->Usages[0];
+ assert(count!=0);
}
else {
count++;
@@ -407,12 +416,14 @@ void Inventory::KillSlot(unsigned int index)
return;
}
RemoveSlotEffects( index );
- Item *itm = gamedata->GetItem(item->ItemResRef);
+ Item *itm = gamedata->GetItem(item->ItemResRef, true);
//this cannot happen, but stuff happens!
if (!itm) {
+ error("Inventory", "Invalid item: %s!", item->ItemResRef);
return;
}
ItemExcl &= ~itm->ItemExcl;
+ int eqslot = GetEquippedSlot();
switch (effect) {
case SLOT_EFFECT_LEFT:
@@ -420,23 +431,24 @@ void Inventory::KillSlot(unsigned int index)
break;
case SLOT_EFFECT_MISSILE:
//getting a new projectile of the same type
- if (Equipped + SLOT_MELEE == (int) index) {
+ if (eqslot == (int) index) {
if (Equipped < 0) {
//always get the projectile weapon header (this quiver was equipped)
ITMExtHeader *header = itm->GetWeaponHeader(true);
Equipped = FindRangedProjectile(header->ProjectileQualifier);
if (Equipped!=IW_NO_EQUIPPED) {
- EquipItem(Equipped+SLOT_MELEE);
+ EquipItem(GetEquippedSlot());
} else {
- EquipItem(SLOT_FIST);
+ EquipBestWeapon(EQUIP_MELEE);
}
}
}
UpdateWeaponAnimation();
break;
+ case SLOT_EFFECT_MAGIC:
case SLOT_EFFECT_MELEE:
// reset Equipped if it was the removed item
- if (Equipped+SLOT_MELEE == (int)index)
+ if (eqslot == (int)index)
Equipped = IW_NO_EQUIPPED;
else if (Equipped < 0) {
//always get the projectile weapon header (this is a bow, because Equipped is negative)
@@ -447,14 +459,14 @@ void Inventory::KillSlot(unsigned int index)
int weaponslot = FindTypedRangedWeapon(type);
CREItem *item2 = Slots[weaponslot];
if (item2) {
- Item *itm2 = gamedata->GetItem(item2->ItemResRef);
+ Item *itm2 = gamedata->GetItem(item2->ItemResRef, true);
if (itm2) {
if (type == header->ProjectileQualifier) {
Equipped = FindRangedProjectile(header->ProjectileQualifier);
if (Equipped!=IW_NO_EQUIPPED) {
- EquipItem(Equipped+SLOT_MELEE);
+ EquipItem(GetEquippedSlot());
} else {
- EquipItem(SLOT_FIST);
+ EquipBestWeapon(EQUIP_MELEE);
}
}
gamedata->FreeItem(itm2, item2->ItemResRef, false);
@@ -529,7 +541,7 @@ unsigned int Inventory::DestroyItem(const char *resref, ieDword flags, ieDword c
if (count && (destructed>=count) )
break;
}
- if (Changed && Owner && Owner->InParty) displaymsg->DisplayConstantString(STR_LOSTITEM, 0xbcefbc);
+ if (Changed && Owner && Owner->InParty) displaymsg->DisplayConstantString(STR_LOSTITEM, DMC_BG2XPGREEN);
return destructed;
}
@@ -566,7 +578,7 @@ CREItem *Inventory::RemoveItem(unsigned int slot, unsigned int count)
//flags set disable item transfer
//except for undroppable and equipped, which are opposite (and shouldn't be set)
-int Inventory::RemoveItem(const char *resref, unsigned int flags, CREItem **res_item)
+int Inventory::RemoveItem(const char *resref, unsigned int flags, CREItem **res_item, int count)
{
size_t slot = Slots.size();
unsigned int mask = (flags^(IE_INV_ITEM_UNDROPPABLE|IE_INV_ITEM_EQUIPPED));
@@ -588,7 +600,7 @@ int Inventory::RemoveItem(const char *resref, unsigned int flags, CREItem **res_
if (resref[0] && strnicmp(item->ItemResRef, resref, 8) ) {
continue;
}
- *res_item=RemoveItem( (unsigned int) slot, 0);
+ *res_item=RemoveItem( (unsigned int) slot, count);
return (int) slot;
}
*res_item = NULL;
@@ -606,7 +618,7 @@ void Inventory::SetSlotItem(CREItem* item, unsigned int slot)
delete Slots[slot];
}
- HackCharges(item);
+ SanitizeItem(item);
Slots[slot] = item;
@@ -637,30 +649,7 @@ int Inventory::AddSlotItem(CREItem* item, int slot, int slottype)
return ASI_SUCCESS;
}
- CREItem *myslot = Slots[slot];
- if (ItemsAreCompatible( myslot, item )) {
- //calculate with the max movable stock
- int chunk = item->Usages[0];
- int newamount = myslot->Usages[0]+chunk;
- if (newamount>myslot->StackAmount) {
- newamount=myslot->StackAmount;
- chunk = item->Usages[0]-newamount;
- }
- if (!chunk) {
- return -1;
- }
- myslot->Flags |= IE_INV_ITEM_ACQUIRED;
- myslot->Usages[0] = (ieWord) (myslot->Usages[0] + chunk);
- item->Usages[0] = (ieWord) (item->Usages[0] - chunk);
- Changed = true;
- EquipItem(slot);
- if (item->Usages[0] == 0) {
- delete item;
- return ASI_SUCCESS;
- }
- return ASI_PARTIAL;
- }
- return ASI_FAILED;
+ return MergeItems(slot, item);
}
bool which;
@@ -745,6 +734,7 @@ int Inventory::AddStoreItem(STOItem* item, int action)
}
item->PurchasedAmount--;
}
+ CalculateWeight();
return ret;
}
@@ -753,7 +743,7 @@ bool Inventory::ItemsAreCompatible(CREItem* target, CREItem* source) const
{
if (!target) {
//this isn't always ok, please check!
- printMessage("Inventory","Null item encountered by ItemsAreCompatible()",YELLOW);
+ Log(WARNING, "Inventory", "Null item encountered by ItemsAreCompatible()");
return true;
}
@@ -786,9 +776,11 @@ int Inventory::DepleteItem(ieDword flags)
//if flags = 0 then weapons are not depleted
if (!flags) {
- Item *itm = gamedata->GetItem( item->ItemResRef );
- if (!itm)
+ Item *itm = gamedata->GetItem(item->ItemResRef, true);
+ if (!itm) {
+ Log(WARNING, "Inventory", "Invalid item to deplete: %s!", item->ItemResRef);
continue;
+ }
//if the item is usable in weapon slot, then it is weapon
int weapon = core->CanUseItemType( SLOT_WEAPON, itm );
gamedata->FreeItem( itm, item->ItemResRef, false );
@@ -806,7 +798,7 @@ int Inventory::DepleteItem(ieDword flags)
// if flags is 0, skips undroppable items
// if flags is IE_INV_ITEM_UNDROPPABLE, doesn't skip undroppable items
// TODO: once all callers have been checked, this can be reversed to make more sense
-int Inventory::FindItem(const char *resref, unsigned int flags) const
+int Inventory::FindItem(const char *resref, unsigned int flags, unsigned int skip) const
{
unsigned int mask = (flags^IE_INV_ITEM_UNDROPPABLE);
if (core->HasFeature(GF_NO_DROP_CAN_MOVE) ) {
@@ -823,7 +815,11 @@ int Inventory::FindItem(const char *resref, unsigned int flags) const
if (resref[0] && strnicmp(item->ItemResRef, resref, 8) ) {
continue;
}
- return (int) i;
+ if (skip) {
+ skip--;
+ } else {
+ return (int) i;
+ }
}
return -1;
}
@@ -915,7 +911,7 @@ bool Inventory::DropItemAtLocation(const char *resref, unsigned int flags, Map *
return dropped;
}
-CREItem *Inventory::GetSlotItem(unsigned int slot) const
+CREItem *Inventory::GetSlotItem(ieDword slot) const
{
if (slot >= Slots.size() ) {
InvalidSlot(slot);
@@ -933,7 +929,7 @@ ieDword Inventory::GetItemFlag(unsigned int slot) const
return item->Flags;
}
-bool Inventory::ChangeItemFlag(unsigned int slot, ieDword arg, int op)
+bool Inventory::ChangeItemFlag(ieDword slot, ieDword arg, int op)
{
CREItem *item = GetSlotItem(slot);
if (!item) {
@@ -951,7 +947,7 @@ bool Inventory::ChangeItemFlag(unsigned int slot, ieDword arg, int op)
//this is the low level equipping
//all checks have been made previously
-bool Inventory::EquipItem(unsigned int slot)
+bool Inventory::EquipItem(ieDword slot)
{
ITMExtHeader *header;
@@ -968,9 +964,9 @@ bool Inventory::EquipItem(unsigned int slot)
// add effects of an item just being equipped to actor's effect queue
int effect = core->QuerySlotEffects( slot );
- Item *itm = gamedata->GetItem(item->ItemResRef);
+ Item *itm = gamedata->GetItem(item->ItemResRef, true);
if (!itm) {
- printf("Invalid item Equipped: %s Slot: %d\n", item->ItemResRef, slot);
+ print("Invalid item Equipped: %s Slot: %d", item->ItemResRef, slot);
return false;
}
switch (effect) {
@@ -980,27 +976,32 @@ bool Inventory::EquipItem(unsigned int slot)
UpdateShieldAnimation(itm);
break;
case SLOT_EFFECT_MELEE:
- //if weapon is ranged, then find quarrel for it and equip that
- slot -= SLOT_MELEE;
- weaponslot = slot;
+ //if weapon is bow, then find quarrel for it and equip that
+ weaponslot = GetWeaponQuickSlot(slot);
EquippedHeader = 0;
header = itm->GetExtHeader(EquippedHeader);
- if (header && header->AttackType == ITEM_AT_BOW) {
- //find the ranged projectile associated with it.
- slot = FindRangedProjectile(header->ProjectileQualifier);
- EquippedHeader = itm->GetWeaponHeaderNumber(true);
- } else if (header && header->AttackType == ITEM_AT_PROJECTILE) {
- EquippedHeader = itm->GetWeaponHeaderNumber(true);
- } else {
- EquippedHeader = itm->GetWeaponHeaderNumber(false);
- }
- header = itm->GetExtHeader(EquippedHeader);
if (header) {
- SetEquippedSlot(slot, EquippedHeader);
- if (slot != IW_NO_EQUIPPED) {
- Owner->SetupQuickSlot(ACT_WEAPON1+weaponslot, slot+SLOT_MELEE, EquippedHeader);
+ if (header->AttackType == ITEM_AT_BOW) {
+ //find the ranged projectile associated with it, this returns equipped code
+ Equipped = FindRangedProjectile(header->ProjectileQualifier);
+ //this is the real item slot of the quarrel
+ slot = Equipped + SLOT_MELEE;
+ } else {
+ //this is always 0-3
+ Equipped = weaponslot;
+ slot = GetWeaponSlot(weaponslot);
+ }
+ if (Equipped != IW_NO_EQUIPPED) {
+ Owner->SetupQuickSlot(ACT_WEAPON1+weaponslot, slot, EquippedHeader);
+ }
+ SetEquippedSlot(Equipped, EquippedHeader);
+ //don't clear effect in case of a launcher, we need to find it and add its effects too
+ //slot is 'negative' for launchers
+ if ((int) Equipped>=0) {
+ effect = 0; // SetEquippedSlot will already call AddSlotEffects
+ } else {
+ effect = SLOT_EFFECT_MISSILE;
}
- effect = 0; // SetEquippedSlot will already call AddSlotEffects
UpdateWeaponAnimation();
}
break;
@@ -1050,7 +1051,7 @@ bool Inventory::EquipItem(unsigned int slot)
//the removecurse flag will check if it is possible to move the item to the inventory
//after a remove curse spell
-bool Inventory::UnEquipItem(unsigned int slot, bool removecurse)
+bool Inventory::UnEquipItem(ieDword slot, bool removecurse)
{
CREItem *item = GetSlotItem(slot);
if (!item) {
@@ -1103,10 +1104,10 @@ int Inventory::FindRangedProjectile(unsigned int type) const
int Inventory::FindRangedWeapon() const
{
if (Equipped>=0) return SLOT_FIST;
- return FindSlotRangedWeapon(Equipped+SLOT_MELEE);
+ return FindSlotRangedWeapon(GetEquippedSlot());
}
-int Inventory::FindSlotRangedWeapon(unsigned int slot) const
+int Inventory::FindSlotRangedWeapon(ieDword slot) const
{
if ((int)slot >= SLOT_MELEE) return SLOT_FIST;
CREItem *Slot;
@@ -1186,6 +1187,13 @@ void Inventory::SetInventorySlot(int arg)
LAST_INV=arg;
}
+void Inventory::SetArmorSlot(int arg)
+{
+ if (SLOT_ARMOR==-1) {
+ SLOT_ARMOR=arg;
+ }
+}
+
//multiple shield slots are allowed
//but in this case they should be interspersed with melee slots
void Inventory::SetShieldSlot(int arg)
@@ -1218,6 +1226,19 @@ int Inventory::GetWeaponSlot()
return SLOT_MELEE;
}
+int Inventory::GetWeaponQuickSlot(int weaponslot)
+{
+ int slot = weaponslot-SLOT_MELEE;
+ if (IWD2 && (slot>=0 && slot<=7) ) slot/=2;
+ return slot;
+}
+
+int Inventory::GetWeaponSlot(int quickslot)
+{
+ if (IWD2 && (quickslot>=0 && quickslot<=3) ) quickslot*=2;
+ return quickslot+SLOT_MELEE;
+}
+
int Inventory::GetQuickSlot()
{
return SLOT_QUICK;
@@ -1228,13 +1249,23 @@ int Inventory::GetInventorySlot()
return SLOT_INV;
}
+int Inventory::GetArmorSlot()
+{
+ return SLOT_ARMOR;
+}
+
//if shield slot is empty, call again for fist slot!
int Inventory::GetShieldSlot() const
{
if (IWD2) {
+ //actually, in IWD2, the equipped slot never becomes IW_NO_EQUIPPED, it is always 0-3
+ //this is just a hack to prevent invalid shots from happening
+ if (Equipped == IW_NO_EQUIPPED) return SLOT_MELEE+1;
+
if (Equipped>=0 && Equipped<=3) {
return Equipped*2+SLOT_MELEE+1;
}
+ //still, what about magic weapons...
return -1;
}
return SLOT_LEFT;
@@ -1246,8 +1277,8 @@ int Inventory::GetEquippedSlot() const
return SLOT_FIST;
}
if (IWD2 && Equipped>=0) {
- //i've absolutely NO idea what is this 4 (Avenger)
- //Equipped should be 0-3 in iWD2, no???
+ //Equipped should never become IW_NO_EQUIPPED, this is just a hack to cover the bug
+ //about it still becoming invalid
if (Equipped >= 4) {
return SLOT_MELEE;
}
@@ -1268,14 +1299,17 @@ bool Inventory::SetEquippedSlot(ieWordSigned slotcode, ieWord header)
}
//if it is an illegal code, make it fist
- if ((size_t) (slotcode+SLOT_MELEE)>Slots.size()) {
+ if ((size_t) (GetWeaponSlot(slotcode))>Slots.size()) {
slotcode=IW_NO_EQUIPPED;
}
+ int oldslot = GetEquippedSlot();
+ int newslot = GetWeaponSlot(slotcode);
+
//unequipping (fist slot will be used now)
- if (slotcode == IW_NO_EQUIPPED || !HasItemInSlot("",slotcode+SLOT_MELEE)) {
+ if (slotcode == IW_NO_EQUIPPED || !HasItemInSlot("", newslot)) {
if (Equipped != IW_NO_EQUIPPED) {
- RemoveSlotEffects( SLOT_MELEE+Equipped);
+ RemoveSlotEffects( oldslot);
}
Equipped = IW_NO_EQUIPPED;
//fist slot equipping effects
@@ -1286,18 +1320,18 @@ bool Inventory::SetEquippedSlot(ieWordSigned slotcode, ieWord header)
//equipping a weapon, but remove its effects first
if (Equipped != IW_NO_EQUIPPED) {
- RemoveSlotEffects( SLOT_MELEE+Equipped);
+ RemoveSlotEffects( oldslot);
}
Equipped = slotcode;
- int effects = core->QuerySlotEffects( SLOT_MELEE+Equipped );
+ int effects = core->QuerySlotEffects( newslot);
if (effects) {
- CREItem* item = GetSlotItem(SLOT_MELEE+Equipped);
+ CREItem* item = GetSlotItem(newslot);
item->Flags|=IE_INV_ITEM_EQUIPPED;
if (item->Flags & IE_INV_ITEM_CURSED) {
item->Flags|=IE_INV_ITEM_UNDROPPABLE;
}
- AddSlotEffects( SLOT_MELEE+Equipped);
+ AddSlotEffects(newslot);
}
UpdateWeaponAnimation();
return true;
@@ -1337,6 +1371,9 @@ CREItem *Inventory::GetUsedWeapon(bool leftorright, int &slot) const
//we don't want to return fist for shield slot
return NULL;
}
+ } else {
+ // nothing in the shield slot, so nothing in the right hand, so just quit
+ return NULL;
}
}
slot = GetEquippedSlot();
@@ -1381,7 +1418,7 @@ int Inventory::FindCandidateSlot(int slottype, size_t first_slot, const char *re
}
// check if the item fits in this slot, we use the cached
// stackamount value
- if (item->Usages[0]<item->StackAmount) {
+ if (item->Usages[0]<item->MaxStackAmount) {
return (int) i;
}
}
@@ -1398,8 +1435,19 @@ void Inventory::AddSlotItemRes(const ieResRef ItemResRef, int SlotID, int Charge
TmpItem->Usages[1]=(ieWord) Charge1;
TmpItem->Usages[2]=(ieWord) Charge2;
TmpItem->Flags=0;
- if (core->ResolveRandomItem(TmpItem) && gamedata->Exists(TmpItem->ItemResRef, IE_ITM_CLASS_ID)) {
- AddSlotItem( TmpItem, SlotID );
+ if (core->ResolveRandomItem(TmpItem)) {
+ int ret = AddSlotItem( TmpItem, SlotID );
+ if (ret != ASI_SUCCESS) {
+ // put the remainder on the ground
+ Map *area = core->GetGame()->GetCurrentArea();
+ if (area) {
+ // create or reuse the existing pile
+ area->AddItemToLocation(Owner->Pos, TmpItem);
+ } else {
+ Log(ERROR, "Inventory", "AddSlotItemRes: argh, no area and the inventory is full, bailing out!");
+ delete TmpItem;
+ }
+ }
} else {
delete TmpItem;
}
@@ -1416,7 +1464,7 @@ void Inventory::SetSlotItemRes(const ieResRef ItemResRef, int SlotID, int Charge
TmpItem->Usages[1]=(ieWord) Charge1;
TmpItem->Usages[2]=(ieWord) Charge2;
TmpItem->Flags=0;
- if (core->ResolveRandomItem(TmpItem) && gamedata->Exists(TmpItem->ItemResRef, IE_ITM_CLASS_ID)) {
+ if (core->ResolveRandomItem(TmpItem)) {
SetSlotItem( TmpItem, SlotID );
} else {
delete TmpItem;
@@ -1428,6 +1476,38 @@ void Inventory::SetSlotItemRes(const ieResRef ItemResRef, int SlotID, int Charge
CalculateWeight();
}
+ieWord Inventory::GetShieldItemType() const
+{
+ ieWord ret;
+ CREItem *Slot;
+ int slotNum = GetShieldSlot();
+
+ if (slotNum < 0) {
+ return 0xffff;
+ }
+ const Item *itm = GetItemPointer(slotNum, Slot);
+ if (!itm) return 0xffff;
+ ret = itm->ItemType;
+ gamedata->FreeItem(itm, Slot->ItemResRef);
+ return ret;
+}
+
+ieWord Inventory::GetArmorItemType() const
+{
+ ieWord ret;
+ CREItem *Slot;
+ int slotNum = GetArmorSlot();
+
+ if (slotNum < 0) {
+ return 0xffff;
+ }
+ const Item *itm = GetItemPointer(slotNum, Slot);
+ if (!itm) return 0xffff;
+ ret = itm->ItemType;
+ gamedata->FreeItem(itm, Slot->ItemResRef);
+ return ret;
+}
+
void Inventory::BreakItemSlot(ieDword slot)
{
ieResRef newItem;
@@ -1446,9 +1526,16 @@ void Inventory::BreakItemSlot(ieDword slot)
SetSlotItemRes(newItem, slot, 0,0,0);
}
-void Inventory::dump()
+void Inventory::dump() const
+{
+ StringBuffer buffer;
+ dump(buffer);
+ Log(DEBUG, "Inventory", buffer);
+}
+
+void Inventory::dump(StringBuffer& buffer) const
{
- printf( "INVENTORY:\n" );
+ buffer.append( "INVENTORY:\n" );
for (unsigned int i = 0; i < Slots.size(); i++) {
CREItem* itm = Slots[i];
@@ -1456,13 +1543,13 @@ void Inventory::dump()
continue;
}
- printf ( "%2u: %8.8s - (%d %d %d) Fl:0x%x Wt: %d x %dLb\n", i, itm->ItemResRef, itm->Usages[0], itm->Usages[1], itm->Usages[2], itm->Flags, itm->StackAmount, itm->Weight );
+ buffer.appendFormatted( "%2u: %8.8s - (%d %d %d) Fl:0x%x Wt: %d x %dLb\n", i, itm->ItemResRef, itm->Usages[0], itm->Usages[1], itm->Usages[2], itm->Flags, itm->MaxStackAmount, itm->Weight );
}
- printf( "Equipped: %d\n", Equipped );
+ buffer.appendFormatted( "Equipped: %d\n", Equipped );
Changed = true;
CalculateWeight();
- printf( "Total weight: %d\n", Weight );
+ buffer.appendFormatted( "Total weight: %d\n", Weight );
}
void Inventory::EquipBestWeapon(int flags)
@@ -1484,6 +1571,10 @@ void Inventory::EquipBestWeapon(int flags)
for(i=SLOT_RANGED;i<LAST_RANGED;i++) {
const Item *itm = GetItemPointer(i, Slot);
if (!itm) continue;
+ //cannot change equipment when holding a cursed weapon
+ if (Slot->Flags & IE_INV_ITEM_CURSED) {
+ return;
+ }
//best ranged
int tmp = itm->GetDamagePotential(true, header);
if (tmp>damage) {
@@ -1499,6 +1590,10 @@ void Inventory::EquipBestWeapon(int flags)
for(i=SLOT_MELEE;i<=LAST_MELEE;i++) {
const Item *itm = GetItemPointer(i, Slot);
if (!itm) continue;
+ //cannot change equipment when holding a cursed weapon
+ if (Slot->Flags & IE_INV_ITEM_CURSED) {
+ return;
+ }
//best ranged
int tmp = itm->GetDamagePotential(true, header);
if (tmp>damage) {
@@ -1515,6 +1610,10 @@ void Inventory::EquipBestWeapon(int flags)
for(i=SLOT_MELEE;i<=LAST_MELEE;i++) {
const Item *itm = GetItemPointer(i, Slot);
if (!itm) continue;
+ //cannot change equipment when holding a cursed weapon
+ if (Slot->Flags & IE_INV_ITEM_CURSED) {
+ return;
+ }
//the Slot flag is enough for this
//though we need animation type/damagepotential anyway
if (Slot->Flags&IE_INV_ITEM_BOW) continue;
@@ -1673,7 +1772,7 @@ void Inventory::UpdateWeaponAnimation()
si = GetSlotItem( (ieDword) slot );
}
if (si) {
- Item* it = gamedata->GetItem(si->ItemResRef);
+ Item* it = gamedata->GetItem(si->ItemResRef, true);
if (core->CanUseItemType(SLOT_WEAPON, it))
twoweapon = true;
gamedata->FreeItem(it, si->ItemResRef, false);
@@ -1737,7 +1836,7 @@ int Inventory::WhyCantEquip(int slot, int twohanded) const
//see GetShieldSlot
int otherslot;
if (IWD2) {
- otherslot = ++i;
+ otherslot = i+1;
} else {
otherslot = SLOT_LEFT;
}
@@ -1750,7 +1849,7 @@ int Inventory::WhyCantEquip(int slot, int twohanded) const
if (twohanded) {
if (IWD2) {
- if (slot>=SLOT_MELEE&&slot<=LAST_MELEE && (slot&1) ) {
+ if (slot>=SLOT_MELEE&&slot<=LAST_MELEE && (slot-SLOT_MELEE)&1) {
return STR_NOT_IN_OFFHAND;
}
} else {
@@ -1778,7 +1877,7 @@ void Inventory::ChargeAllItems(int hours)
continue;
}
- Item *itm = gamedata->GetItem( item->ItemResRef );
+ Item *itm = gamedata->GetItem(item->ItemResRef, true);
if (!itm)
continue;
for(int h=0;h<CHARGE_COUNTERS;h++) {
@@ -1795,7 +1894,7 @@ void Inventory::ChargeAllItems(int hours)
}
}
-#define ITM_STEALING (IE_INV_ITEM_UNSTEALABLE | IE_INV_ITEM_MOVABLE | IE_INV_ITEM_EQUIPPED)
+#define ITM_STEALING (IE_INV_ITEM_UNSTEALABLE | IE_INV_ITEM_MOVABLE | IE_INV_ITEM_EQUIPPED) //0x442
unsigned int Inventory::FindStealableItem()
{
unsigned int slot;
@@ -1804,7 +1903,7 @@ unsigned int Inventory::FindStealableItem()
slot = core->Roll(1, Slots.size(),-1);
inc = slot&1?1:-1;
- printf("Start Slot: %d, increment: %d\n", slot, inc);
+ print("Start Slot: %d, increment: %d", slot, inc);
//as the unsigned value underflows, it will be greater than Slots.size()
for(;slot<Slots.size(); slot+=inc) {
CREItem *item = Slots[slot];
@@ -1813,7 +1912,9 @@ unsigned int Inventory::FindStealableItem()
//bit 1 is stealable slot
if (!(core->QuerySlotFlags(slot)&1) ) continue;
//can't steal equipped weapon
- if ((unsigned int) (Equipped+SLOT_MELEE) == core->QuerySlot(slot)) continue;
+ int realslot = core->QuerySlot(slot);
+ if (GetEquippedSlot() == realslot) continue;
+ if (GetShieldSlot() == realslot) continue;
//can't steal flagged items
if ((item->Flags & ITM_STEALING) != IE_INV_ITEM_MOVABLE) continue;
return slot;
@@ -1826,31 +1927,58 @@ unsigned int Inventory::FindStealableItem()
// If an item with bit 25 set is equipped in a helmet slot, aversion is disabled
bool Inventory::ProvidesCriticalAversion()
{
- for (size_t i = 0; i < Slots.size(); i++) {
+ int maxSlot = (int) Slots.size();
+ for (int i = 0; i < maxSlot; i++) {
CREItem *item = Slots[i];
- if (!item || ! (item->Flags & IE_INV_ITEM_EQUIPPED)) {
+ if (!item || ((i>=SLOT_INV) && (i<=LAST_INV))) { // ignore items in the backpack
+ continue;
+ }
+ // weapon, but not equipped
+ if (!((i == SLOT_ARMOR) || (i == SLOT_HEAD)) && !(item->Flags & IE_INV_ITEM_EQUIPPED)) {
continue;
}
- Item *itm = gamedata->GetItem(item->ItemResRef);
+ Item *itm = gamedata->GetItem(item->ItemResRef, true);
if (!itm) {
continue;
}
+ //if the item is worn on head, toggle crits must be 0, otherwise it must be 1
+ //this flag is only stored in the item header, so we need to make some efforts
+ //to get to it (TODO convince ToBEx to move this bit into the accessible range?) - low 24 bits
+ ieDword flag = itm->Flags;
+ gamedata->FreeItem( itm, item->ItemResRef, false );
+ bool togglesCrits = (flag&IE_ITEM_TOGGLE_CRITS);
+ bool isHelmet = (i == SLOT_HEAD);
+ if (togglesCrits ^ isHelmet) return true;
+ }
+ return false;
+}
- for (int h = 0; h < itm->ExtHeaderCount; h++) {
- ITMExtHeader *header = itm->GetExtHeader(h);
- if ((int)i == SLOT_HEAD) {
- if (header && (header->RechargeFlags & IE_ITEM_TOGGLE_CRITS)) {
- return false;
- } else {
- return true;
- }
- } else {
- if (header && (header->RechargeFlags & IE_ITEM_TOGGLE_CRITS)) {
- return true;
- }
- }
+int Inventory::MergeItems(int slot, CREItem *item)
+{
+ CREItem *slotitem = Slots[slot];
+ if (slotitem->MaxStackAmount && ItemsAreCompatible(slotitem, item)) {
+ //calculate with the max movable stock
+ int chunk = item->Usages[0];
+ if (slotitem->Usages[0] + chunk > slotitem->MaxStackAmount) {
+ chunk = slotitem->MaxStackAmount - slotitem->Usages[0];
+ }
+ if (chunk<=0) {
+ return ASI_FAILED;
}
+
+ slotitem->Flags |= IE_INV_ITEM_ACQUIRED;
+ slotitem->Usages[0] = (ieWord) (slotitem->Usages[0] + chunk);
+ item->Usages[0] = (ieWord) (item->Usages[0] - chunk);
+ Changed = true;
+ EquipItem(slot);
+ if (item->Usages[0] == 0) {
+ delete item;
+ return ASI_SUCCESS;
+ }
+ return ASI_PARTIAL;
}
- return false;
+ return ASI_FAILED;
+}
+
}
diff --git a/gemrb/core/Inventory.h b/gemrb/core/Inventory.h
index dae7d4c..adafca7 100644
--- a/gemrb/core/Inventory.h
+++ b/gemrb/core/Inventory.h
@@ -37,7 +37,10 @@
#include <vector>
+namespace GemRB {
+
class Map;
+class StringBuffer;
//AddSlotItem return values
#define ASI_FAILED 0
@@ -135,12 +138,13 @@ struct ItemExtHeader {
ieByte Target;
ieByte TargetNumber;
ieWord Range;
- ieWord ProjectileType;
+ //This was commented out in ITMExtHeader
+ //ieWord ProjectileType;
ieWord Speed;
ieWord THAC0Bonus;
ieWord DiceSides;
ieWord DiceThrown;
- ieWord DamageBonus;
+ ieWordSigned DamageBonus; //this must be signed!!!
ieWord DamageType;
ieWord FeatureCount;
ieWord FeatureOffset;
@@ -170,15 +174,15 @@ public:
ieWord Usages[CHARGE_COUNTERS];
ieDword Flags;
// 2 cached values from associated item. LEAVE IT SIGNED!
- /** Weight of items in the stack */
+ /** Weight of each item in the stack */
int Weight;
- /** Amount of items in this stack */
- int StackAmount;
+ /** Maximum amount of items in this stack */
+ int MaxStackAmount;
CREItem()
{
Weight=-1; //invalid weight
- StackAmount=0;
+ MaxStackAmount=0;
}
};
@@ -192,9 +196,10 @@ private:
std::vector<CREItem*> Slots;
Actor* Owner;
int InventoryType;
- int Changed;
+ /// Flag indicating whether weight needs to be recalculated
+ mutable int Changed;
/** Total weight of all items in Inventory */
- int Weight;
+ mutable int Weight;
ieWordSigned Equipped;
ieWord EquippedHeader;
@@ -218,11 +223,11 @@ public:
bool HasItemInSlot(const char *resref, unsigned int slot) const;
/** returns true if contains one itemtype equipped */
bool HasItemType(ieDword type) const;
- /** Looks for a particular item in the inventory. */
- /* flags: see ieCREItemFlagBits */
+ /** Looks for a particular item in the inventory.
+ * flags: see ieCREItemFlagBits */
bool HasItem(const char *resref, ieDword flags) const;
- void CalculateWeight(void);
+ void CalculateWeight(void) const;
void SetInventoryType(int arg);
void SetOwner(Actor* act) { Owner = act; }
@@ -237,7 +242,7 @@ public:
* If count !=0 it splits the item and returns only requested amount */
CREItem* RemoveItem(unsigned int slot, unsigned int count = 0);
/** returns slot of removed item, you can delete the removed item */
- int RemoveItem(const char* resref, unsigned int flags, CREItem **res_item);
+ int RemoveItem(const char* resref, unsigned int flags, CREItem **res_item, int count = 0);
/** adds CREItem to the inventory. If slot == -1, finds
** first eligible slot, eventually splitting the item to
@@ -266,7 +271,7 @@ public:
//charges recharging items
void ChargeAllItems(int hours);
/** Finds the first slot of named item, if resref is empty, finds the first filled! slot */
- int FindItem(const char *resref, unsigned int flags) const;
+ int FindItem(const char *resref, unsigned int flags, unsigned int skip=0) const;
bool DropItemAtLocation(unsigned int slot, unsigned int flags, Map *map, const Point &loc);
bool DropItemAtLocation(const char *resref, unsigned int flags, Map *map, const Point &loc);
bool SetEquippedSlot(ieWordSigned slotcode, ieWord header);
@@ -301,10 +306,16 @@ public:
void SetSlotItemRes(const ieResRef ItemResRef, int Slot, int Charge0=1, int Charge1=0, int Charge2=0);
/** Adds item to slot*/
void AddSlotItemRes(const ieResRef ItemResRef, int Slot, int Charge0=1, int Charge1=0, int Charge2=0);
+ /** returns the itemtype held in the left hand */
+ ieWord GetShieldItemType() const;
+ /** returns the itemtype of the item in the armor slot, mostly used in IWD2 */
+ ieWord GetArmorItemType() const;
/** breaks the item (weapon) in slot */
void BreakItemSlot(ieDword slot);
/** Lists all items in the Inventory on terminal for debugging */
- void dump();
+ void dump() const;
+ /// List all items in the Inventory to the given buffer */
+ void dump(StringBuffer&) const;
/** Equips best weapon */
void EquipBestWeapon(int flags);
/** returns the struct of the usable items, returns true if there are more */
@@ -321,8 +332,11 @@ public:
unsigned int FindStealableItem();
/** checks if any equipped item provides critical hit aversion */
bool ProvidesCriticalAversion();
+ /** tries to merge the passed item with the on in the passed slot */
+ int MergeItems(int slot, CREItem *item);
//setting important constants
static void Init(int mb);
+ static void SetArmorSlot(int arg);
static void SetHeadSlot(int arg);
static void SetFistSlot(int arg);
static void SetMagicSlot(int arg);
@@ -331,10 +345,13 @@ public:
static void SetQuickSlot(int arg);
static void SetInventorySlot(int arg);
static void SetShieldSlot(int arg);
+ static int GetArmorSlot();
static int GetHeadSlot();
static int GetFistSlot();
static int GetMagicSlot();
static int GetWeaponSlot();
+ static int GetWeaponQuickSlot(int weaponslot);
+ static int GetWeaponSlot(int quickslot);
static int GetRangedSlot();
static int GetQuickSlot();
static int GetInventorySlot();
@@ -342,10 +359,13 @@ private:
int FindRangedProjectile(unsigned int type) const;
// called by KillSlot
void RemoveSlotEffects( /*CREItem* slot*/ ieDword slot );
- void KillSlot(ieDword index);
+ void KillSlot(unsigned int index);
inline Item *GetItemPointer(ieDword slot, CREItem *&Slot) const;
void UpdateWeaponAnimation();
void UpdateShieldAnimation(Item *it);
+ void SanitizeItem(CREItem *item);
};
+}
+
#endif
diff --git a/gemrb/core/Item.cpp b/gemrb/core/Item.cpp
index 0c9eed4..8f1cdda 100644
--- a/gemrb/core/Item.cpp
+++ b/gemrb/core/Item.cpp
@@ -29,6 +29,8 @@
#include "Projectile.h"
#include "ProjectileServer.h"
+namespace GemRB {
+
ITMExtHeader::ITMExtHeader(void)
{
features = NULL;
@@ -69,7 +71,11 @@ EffectQueue *Item::GetEffectBlock(Scriptable *self, const Point &pos, int usage,
features = equipping_features;
count = EquippingFeatureCount;
}
+
+ //collecting all self affecting effects in a single queue, so the random value is rolled only once
EffectQueue *fxqueue = new EffectQueue();
+ EffectQueue *selfqueue = new EffectQueue();
+ Actor *target = (self->Type==ST_ACTOR)?(Actor *) self:NULL;
for (int i=0;i<count;i++) {
Effect *fx = features+i;
@@ -85,15 +91,20 @@ EffectQueue *Item::GetEffectBlock(Scriptable *self, const Point &pos, int usage,
fx->Projectile = pro;
fxqueue->AddEffect( fx );
} else {
- Actor *target = (self->Type==ST_ACTOR)?(Actor *) self:NULL;
+ //Actor *target = (self->Type==ST_ACTOR)?(Actor *) self:NULL;
fx->Projectile = 0;
fx->PosX=pos.x;
fx->PosY=pos.y;
if (target) {
- core->ApplyEffect(fx, target, self);
+ //core->ApplyEffect(fx, target, self);
+ selfqueue->AddEffect(fx);
}
}
}
+ if (target && selfqueue->GetEffectsCount()) {
+ core->ApplyEffectQueue(selfqueue, target, self);
+ }
+ delete selfqueue;
//adding a pulse effect for weapons (PST)
//if it is an equipping effect block
@@ -176,7 +187,7 @@ int Item::UseCharge(ieWord *Charges, int header, bool expend) const
int type = ieh->ChargeDepletion;
int ccount = 0;
- if ((header>=CHARGE_COUNTERS) || (header<0/*weapon header*/)) {
+ if ((header>=CHARGE_COUNTERS) || (header<0) || MaxStackAmount) {
header = 0;
}
ccount=Charges[header];
@@ -240,9 +251,59 @@ unsigned int Item::GetCastingDistance(int idx) const
{
ITMExtHeader *seh = GetExtHeader(idx);
if (!seh) {
- printMessage("Item", "Cannot retrieve item header!!! ",RED);
- printf("required header: %d, maximum: %d\n", idx, (int) ExtHeaderCount);
+ Log(ERROR, "Item", "Cannot retrieve item header!!! required header: %d, maximum: %d",
+ idx, (int) ExtHeaderCount);
return 0;
}
return (unsigned int) seh->Range;
}
+
+static EffectRef fx_damage_ref = { "Damage", -1 };
+// returns a vector with details about any extended headers containing fx_damage
+std::vector<DMGOpcodeInfo> Item::GetDamageOpcodesDetails(ITMExtHeader *header) const
+{
+ ieDword damage_opcode = EffectQueue::ResolveEffect(fx_damage_ref);
+ std::multimap<ieDword, DamageInfoStruct>::iterator it;
+ std::vector<DMGOpcodeInfo> damage_opcodes;
+ if (!header) return damage_opcodes;
+ for (int i=0; i< header->FeatureCount; i++) {
+ Effect *fx = header->features+i;
+ if (fx->Opcode == damage_opcode) {
+ // it's not the same damagetype, these are different values, so we need a translation
+ // 0-3 -> 0 (crushing)
+ // 2^16+[0-3] -> 1 (acid)
+ // 2^17+[0-3] -> 2 (cold)
+ // 2^18+[0-3] -> 4 (electricity)
+ // and so on. Should be fine up until DAMAGE_MAGICFIRE, where we may start making wrong lookups
+ ieDword damagetype = fx->Parameter2;
+ if (damagetype < 4) {
+ damagetype = 0;
+ } else {
+ // 2^(log2(damagetype)-15-1)
+ int pow = 0;
+ while (damagetype) {
+ damagetype = damagetype>>1;
+ pow++;
+ }
+ damagetype = 1<<(pow - 17);
+ }
+ it = core->DamageInfoMap.find(damagetype);
+ if (it == core->DamageInfoMap.end()) {
+ print("Unhandled damagetype: %d", damagetype);
+ continue;
+ }
+ DMGOpcodeInfo damage;
+ // it's lower case instead of title case, but let's see how long it takes for anyone to notice - 26.12.2012
+ damage.TypeName = core->GetString(it->second.strref, 0);
+ damage.DiceThrown = fx->DiceThrown;
+ damage.DiceSides = fx->DiceSides;
+ damage.DiceBonus = fx->Parameter1;
+ damage.Chance = fx->ProbabilityRangeMax - fx->ProbabilityRangeMin;
+ damage_opcodes.push_back(damage);
+ }
+ }
+ return damage_opcodes;
+}
+
+
+}
diff --git a/gemrb/core/Item.h b/gemrb/core/Item.h
index d395268..6109bbe 100644
--- a/gemrb/core/Item.h
+++ b/gemrb/core/Item.h
@@ -33,6 +33,10 @@
#include "EffectQueue.h"
+#include <vector>
+
+namespace GemRB {
+
class Projectile;
// Item Flags bits
@@ -51,17 +55,19 @@ class Projectile;
#define IE_ITEM_CONVERSABLE 0x00000800
#define IE_ITEM_PULSATING 0x00001000
#define IE_ITEM_UNSELLABLE ( IE_ITEM_CRITICAL | IE_ITEM_STOLEN )
-
-//modder extensions
+//tobex modder extensions, please note, these are not copied into the local slot bits
#define IE_ITEM_NO_DISPEL 0x01000000 //disables destruction by dispelling
#define IE_ITEM_TOGGLE_CRITS 0x02000000 //toggles critical hit avertion
+#define IE_ITEM_NO_INVIS 0x04000000 //don't target invisible
+
//Extended header recharge flags
#define IE_ITEM_USESTRENGTH 1 //weapon
#define IE_ITEM_BREAKABLE 2 //weapon
+#define IE_ITEM_USEDEXTERITY 4 //gemrb weapon (move this if tobex implements it elsewhere)
#define IE_ITEM_HOSTILE 0x400 //equipment
#define IE_ITEM_RECHARGE 0x800 //equipment
-#define IE_ITEM_IGNORESHIELD 0x10000 //weapon
+#define IE_ITEM_BYPASS 0x10000 //weapon (bypass shield and armor bonus)
#define IE_ITEM_KEEN 0x20000 //weapon
//modder extensions
@@ -101,6 +107,15 @@ class Projectile;
//items caster level is hardcoded to 10
#define ITEM_CASTERLEVEL 10
+
+struct DMGOpcodeInfo {
+ const char *TypeName;
+ int DiceThrown;
+ int DiceSides;
+ int DiceBonus;
+ int Chance;
+};
+
/**
* @class ITMExtHeader
* Header for special effects and uses of an Item.
@@ -180,7 +195,7 @@ public:
ieByte unknown3;
ieDword KitUsability;
ieDword Price;
- ieWord StackAmount;
+ ieWord MaxStackAmount;
ieResRef ItemIcon;
ieWord LoreToID;
ieResRef GroundIcon;
@@ -262,7 +277,11 @@ public:
int GetWeaponHeaderNumber(bool ranged) const;
int GetEquipmentHeaderNumber(int cnt) const;
unsigned int GetCastingDistance(int header) const;
+ // returns a vector with details about any extended headers containing fx_damage with a 100% probability
+ std::vector<DMGOpcodeInfo> GetDamageOpcodesDetails(ITMExtHeader *header) const;
private:
};
+}
+
#endif // ! ITEM_H
diff --git a/gemrb/core/ItemMgr.cpp b/gemrb/core/ItemMgr.cpp
index 5701189..6b5db2f 100644
--- a/gemrb/core/ItemMgr.cpp
+++ b/gemrb/core/ItemMgr.cpp
@@ -20,6 +20,8 @@
#include "ItemMgr.h"
+namespace GemRB {
+
ItemMgr::ItemMgr(void)
{
}
@@ -27,3 +29,5 @@ ItemMgr::ItemMgr(void)
ItemMgr::~ItemMgr(void)
{
}
+
+}
diff --git a/gemrb/core/ItemMgr.h b/gemrb/core/ItemMgr.h
index 1013689..bc8c02d 100644
--- a/gemrb/core/ItemMgr.h
+++ b/gemrb/core/ItemMgr.h
@@ -32,6 +32,8 @@
#include "Plugin.h"
#include "System/DataStream.h"
+namespace GemRB {
+
/**
* @class ItemMgr
* Abstract loader for Item objects
@@ -41,8 +43,10 @@ class GEM_EXPORT ItemMgr : public Plugin {
public:
ItemMgr(void);
virtual ~ItemMgr(void);
- virtual bool Open(DataStream* stream, bool autoFree = true) = 0;
+ virtual bool Open(DataStream* stream) = 0;
virtual Item* GetItem(Item *s) = 0;
};
+}
+
#endif
diff --git a/gemrb/core/KeyMap.cpp b/gemrb/core/KeyMap.cpp
new file mode 100644
index 0000000..1ae6237
--- /dev/null
+++ b/gemrb/core/KeyMap.cpp
@@ -0,0 +1,162 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2009 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "KeyMap.h"
+#include "win32def.h"
+#include "Interface.h"
+#include "TableMgr.h"
+#include "ScriptEngine.h"
+#include "System/FileStream.h"
+
+namespace GemRB {
+
+#define KEYLENGTH 64
+
+Function::Function(const char *m, const char *f, int g)
+{
+ //make sure the module an function names are no longer than 32 characters, or they will be truncated
+ strlcpy(module, m, sizeof(module));
+ strlcpy(function, f, sizeof(function));
+ group = g;
+}
+
+KeyMap::KeyMap()
+{
+ keymap.SetType(GEM_VARIABLES_POINTER);
+}
+
+void ReleaseFunction(void *fun)
+{
+ delete (Function *) fun;
+}
+
+KeyMap::~KeyMap()
+{
+ keymap.RemoveAll(ReleaseFunction);
+}
+
+bool KeyMap::InitializeKeyMap(const char *inifile, const char *tablefile)
+{
+ AutoTable kmtable(tablefile);
+
+ if (!kmtable) {
+ return false;
+ }
+
+ char tINIkeymap[_MAX_PATH];
+ PathJoin( tINIkeymap, core->GamePath, inifile, NULL );
+ FileStream* config = FileStream::OpenFile( tINIkeymap );
+
+ if (config == NULL) {
+ Log(WARNING, "KeyMap", "There is no '%s' file...", inifile);
+ return false;
+ }
+ char name[KEYLENGTH+1], value[_MAX_PATH + 3];
+ while (config->Remains()) {
+ char line[_MAX_PATH];
+
+ if (config->ReadLine(line, _MAX_PATH) == -1)
+ break;
+
+ if ((line[0] == '#') ||
+ ( line[0] == '[' ) ||
+ ( line[0] == '\r' ) ||
+ ( line[0] == '\n' ) ||
+ ( line[0] == ';' )) {
+ continue;
+ }
+
+ name[0] = 0;
+ value[0] = 0;
+
+ //ignore possible space after the =, sadly we cannot do the same with
+ //spaces before it
+ if (sscanf( line, "%[^=]= %[^\r\n]", name, value )!=2)
+ continue;
+
+ strnlwrcpy(name,name,KEYLENGTH);
+ //remove trailing spaces (bg1 ini file contains them)
+ char *nameend = name + strlen( name ) - 1;
+ while (nameend >= name && strchr( " \t\r\n", *nameend )) {
+ *nameend-- = '\0';
+ }
+
+ //change internal spaces to underscore
+ for(int c=0;c<KEYLENGTH;c++) if (name[c]==' ') name[c]='_';
+
+ int l = strlen(value);
+ Function *fun;
+ void *tmp;
+
+ if (l<0 || l>1 || keymap.Lookup(value, tmp) ) {
+ print("Ignoring key %s", value);
+ continue;
+ }
+
+ const char *module;
+ const char *function;
+ const char *group;
+
+ if (kmtable->GetRowIndex(name)>=0 ) {
+ module = kmtable->QueryField(name, "MODULE");
+ function = kmtable->QueryField(name, "FUNCTION");
+ group = kmtable->QueryField(name, "GROUP");
+ } else {
+ module = kmtable->QueryField("Default","MODULE");
+ function = kmtable->QueryField("Default","FUNCTION");
+ group = kmtable->QueryField("Default","GROUP");
+ print("Adding key %s with function %s::%s", value, module, function);
+ }
+ fun = new Function(module, function, atoi(group));
+ keymap.SetAt(value, fun);
+ }
+ delete config;
+ return true;
+}
+
+//group can be:
+//main gamecontrol
+bool KeyMap::ResolveKey(int key, int group)
+{
+ Function *fun;
+ void *tmp;
+ char keystr[2];
+
+ keystr[0]=(char) key;
+ keystr[1]=0;
+
+ Log(MESSAGE, "KeyMap", "Looking up key: %c(%s) ", key, keystr);
+
+ if (!keymap.Lookup(keystr, tmp) ) {
+ return false;
+ }
+ fun = (Function *) tmp;
+
+ if (fun->group!=group) {
+ return false;
+ }
+
+ Log(MESSAGE, "KeyMap", "RunFunction(%s::%s)", fun->module, fun->function);
+ core->GetGUIScriptEngine()->RunFunction(fun->module, fun->function);
+ return true;
+}
+
+
+}
diff --git a/gemrb/core/KeyMap.h b/gemrb/core/KeyMap.h
new file mode 100644
index 0000000..fbcc6ed
--- /dev/null
+++ b/gemrb/core/KeyMap.h
@@ -0,0 +1,52 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2009 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef KEYMAP_H
+#define KEYMAP_H
+
+#include "exports.h"
+#include "Variables.h"
+
+namespace GemRB {
+
+class Variables;
+
+class GEM_EXPORT KeyMap {
+private:
+ Variables keymap;
+public:
+ KeyMap();
+ ~KeyMap();
+ bool InitializeKeyMap(const char *inifile, const char *keyfile);
+ bool ResolveKey(int key, int group);
+};
+
+class Function {
+public:
+ ieVariable module;
+ ieVariable function;
+ int group;
+
+ Function(const char *m, const char *f, int g);
+};
+
+}
+
+#endif
diff --git a/gemrb/core/LRUCache.cpp b/gemrb/core/LRUCache.cpp
index afb72ac..1bf0529 100644
--- a/gemrb/core/LRUCache.cpp
+++ b/gemrb/core/LRUCache.cpp
@@ -23,6 +23,8 @@
#include <cassert>
#include <cstdio>
+namespace GemRB {
+
struct VarEntry {
VarEntry* prev;
VarEntry* next;
@@ -217,3 +219,5 @@ void testLRUCache()
assert(!c.getLRU(1, k2, p));
}
+
+}
diff --git a/gemrb/core/LRUCache.h b/gemrb/core/LRUCache.h
index 31add80..9d01fd0 100644
--- a/gemrb/core/LRUCache.h
+++ b/gemrb/core/LRUCache.h
@@ -25,6 +25,8 @@
#include "Variables.h"
+namespace GemRB {
+
struct VarEntry;
class GEM_EXPORT LRUCache {
@@ -56,4 +58,6 @@ private:
+}
+
#endif
diff --git a/gemrb/core/Makefile.am b/gemrb/core/Makefile.am
index 26bea79..6c7db5d 100644
--- a/gemrb/core/Makefile.am
+++ b/gemrb/core/Makefile.am
@@ -28,6 +28,7 @@ libgemrb_core_la_SOURCES = \
Factory.cpp \
FactoryObject.cpp \
Font.cpp \
+ FontManager.cpp \
GUI/Button.cpp \
GUI/Console.cpp \
GUI/Control.cpp \
@@ -51,15 +52,19 @@ libgemrb_core_la_SOURCES = \
GameScript/Objects.cpp \
GameScript/Triggers.cpp \
GlobalTimer.cpp \
+ FileCache.cpp \
Image.cpp \
ImageFactory.cpp \
ImageMgr.cpp \
ImageWriter.cpp \
+ IndexedArchive.cpp \
IniSpawn.cpp \
Interface.cpp \
+ InterfaceConfig.cpp \
Inventory.cpp \
Item.cpp \
ItemMgr.cpp \
+ KeyMap.cpp \
LRUCache.cpp \
Map.cpp \
MapMgr.cpp \
@@ -69,6 +74,7 @@ libgemrb_core_la_SOURCES = \
PalettedImageMgr.cpp \
Particles.cpp \
Plugin.cpp \
+ PluginLoader.cpp \
PluginMgr.cpp \
Polygon.cpp \
Projectile.cpp \
@@ -83,6 +89,7 @@ libgemrb_core_la_SOURCES = \
SaveGameMgr.cpp \
ScriptEngine.cpp \
Scriptable/Actor.cpp \
+ Scriptable/CombatInfo.cpp \
Scriptable/Container.cpp \
Scriptable/Door.cpp \
Scriptable/InfoPoint.cpp \
@@ -99,10 +106,17 @@ libgemrb_core_la_SOURCES = \
StoreMgr.cpp \
StringMgr.cpp \
SymbolMgr.cpp \
- System/CachedFileStream.cpp \
+ System/Logger/File.cpp \
+ System/Logger/MessageWindowLogger.cpp \
+ System/Logger/Stdio.cpp \
System/DataStream.cpp \
System/FileStream.cpp \
+ System/Logger.cpp \
+ System/Logging.cpp \
System/MemoryStream.cpp \
+ System/SlicedStream.cpp \
+ System/String.cpp \
+ System/StringBuffer.cpp \
System/VFS.cpp \
TableMgr.cpp \
Tile.cpp \
diff --git a/gemrb/core/Map.cpp b/gemrb/core/Map.cpp
index f89036c..1d6cc3f 100644
--- a/gemrb/core/Map.cpp
+++ b/gemrb/core/Map.cpp
@@ -30,6 +30,7 @@
#include "DisplayMessage.h"
#include "Game.h"
#include "GameData.h"
+#include "IniSpawn.h"
#include "Interface.h"
#include "MapMgr.h"
#include "MusicMgr.h"
@@ -37,21 +38,28 @@
#include "Palette.h"
#include "Particles.h"
#include "PathFinder.h"
+#include "PluginMgr.h"
#include "Projectile.h"
+#include "SaveGameIterator.h"
#include "ScriptedAnimation.h"
#include "TileMap.h"
#include "Video.h"
#include "WorldMap.h"
#include "strrefs.h"
+#include "ie_cursors.h"
#include "GameScript/GSUtils.h"
#include "GUI/GameControl.h"
+#include "GUI/Window.h"
#include "Scriptable/Container.h"
#include "Scriptable/Door.h"
#include "Scriptable/InfoPoint.h"
+#include "System/StringBuffer.h"
#include <cmath>
#include <cassert>
+namespace GemRB {
+
#define YESNO(x) ( (x)?"Yes":"No")
// TODO: fix this hardcoded resource reference
@@ -73,7 +81,7 @@ static int LargeFog;
static TerrainSounds *terrainsounds=NULL;
static int tsndcount = -1;
-void ReleaseSpawnGroup(void *poi)
+static void ReleaseSpawnGroup(void *poi)
{
delete (SpawnGroup *) poi;
}
@@ -95,7 +103,7 @@ void Map::ReleaseMemory()
}
}
-inline static AnimationObjectType SelectObject(Actor *actor, int q, AreaAnimation *a, ScriptedAnimation *sca, Particles *spark, Projectile *pro)
+static inline AnimationObjectType SelectObject(Actor *actor, int q, AreaAnimation *a, ScriptedAnimation *sca, Particles *spark, Projectile *pro)
{
int actorh;
if (actor) {
@@ -148,7 +156,7 @@ inline static AnimationObjectType SelectObject(Actor *actor, int q, AreaAnimatio
//returns true if creature must be embedded in the area
//npcs in saved game shouldn't be embedded either
-inline static bool MustSave(Actor *actor)
+static inline bool MustSave(Actor *actor)
{
if (actor->Persistent()) {
return false;
@@ -159,12 +167,12 @@ inline static bool MustSave(Actor *actor)
}
//Preload spawn group entries (creature resrefs that reference groups of creatures)
-void InitSpawnGroups()
+static void InitSpawnGroups()
{
ieResRef GroupName;
int i;
- AutoTable tab("spawngrp");
+ AutoTable tab("spawngrp", true);
Spawns.RemoveAll(NULL);
Spawns.SetType( GEM_VARIABLES_POINTER );
@@ -193,7 +201,7 @@ void InitSpawnGroups()
}
//Preload the searchmap configuration
-void InitPathFinder()
+static void InitPathFinder()
{
PathFinderInited = true;
tsndcount = 0;
@@ -229,7 +237,7 @@ void InitPathFinder()
}
}
-void AddLOS(int destx, int desty, int slot)
+static void AddLOS(int destx, int desty, int slot)
{
for (int i=0;i<MaxVisibility;i++) {
int x = ((destx*i + MaxVisibility/2) / MaxVisibility) * 16;
@@ -243,7 +251,7 @@ void AddLOS(int destx, int desty, int slot)
}
}
-void InitExplore()
+static void InitExplore()
{
LargeFog = !core->HasFeature(GF_SMALL_FOG);
@@ -334,6 +342,7 @@ Map::Map(void)
MasterArea = core->GetGame()->MasterArea(scriptName);
Background = NULL;
BgDuration = 0;
+ LastGoCloser = 0;
}
Map::~Map(void)
@@ -342,6 +351,13 @@ Map::~Map(void)
free( MapSet );
free( SrchMap );
+
+ //close the current container if it was owned by this map, this avoids a crash
+ Container *c = core->GetCurrentContainer();
+ if (c && c->GetCurrentArea()==this) {
+ core->CloseCurrentContainer();
+ }
+
delete TMap;
delete INISpawn;
aniIterator aniidx;
@@ -462,16 +478,22 @@ void Map::MoveToNewArea(const char *area, const char *entrance, unsigned int dir
memcpy (game->PreviousArea, entry->AreaName, 8);
}
- core->GetGameControl()->AutoSave();
+ //perform autosave
+ core->GetSaveGameIterator()->CreateSaveGame(0, false);
}
Map* map = game->GetMap(area, false);
if (!map) {
- printMessage("Map", " ", LIGHT_RED);
- printf("Invalid map: %s\n",area);
+ Log(ERROR, "Map", "Invalid map: %s", area);
command[0]=0;
return;
}
- Entrance* ent = map->GetEntrance( entrance );
+ Entrance* ent = NULL;
+ if (entrance[0]) {
+ ent = map->GetEntrance( entrance );
+ if (!ent) {
+ Log(ERROR, "Map", "Invalid entrance '%s' for area %s", entrance, area);
+ }
+ }
int X,Y, face;
if (!ent) {
// no entrance found, try using direction flags
@@ -480,22 +502,25 @@ void Map::MoveToNewArea(const char *area, const char *entrance, unsigned int dir
// ok, so the original engine tries these in a different order
// (north first, then south) but it doesn't seem to matter
- if (direction & 0x1) { // north
+ if (direction & ADIRF_NORTH) {
X = map->TMap->XCellCount * 32;
Y = 0;
- } else if (direction & 0x2) { // east
+ } else if (direction & ADIRF_EAST) {
X = map->TMap->XCellCount * 64;
Y = map->TMap->YCellCount * 32;
- } else if (direction & 0x4) { // south
+ } else if (direction & ADIRF_SOUTH) {
X = map->TMap->XCellCount * 32;
Y = map->TMap->YCellCount * 64;
- } else if (direction & 0x8) { // west
+ } else if (direction & ADIRF_WEST) {
X = 0;
Y = map->TMap->YCellCount * 32;
+ } else if (direction & ADIRF_CENTER) {
+ X = map->TMap->XCellCount * 32;
+ Y = map->TMap->YCellCount * 32;
} else {
// crashes in original engine
- printMessage("Map", " ", YELLOW);
- printf( "WARNING!!! EntryPoint '%s' does not exist and direction %d is invalid\n", entrance, direction );
+ Log(WARNING, "Map", "WARNING!!! EntryPoint '%s' does not exist and direction %d is invalid",
+ entrance, direction);
X = map->TMap->XCellCount * 64;
Y = map->TMap->YCellCount * 64;
}
@@ -512,11 +537,14 @@ void Map::MoveToNewArea(const char *area, const char *entrance, unsigned int dir
while (i--) {
Actor *pc = game->GetPC(i,false);
if (pc->GetCurrentArea()==this) {
- pc->UseExit(0);
- pc->ClearPath();
- pc->ClearActions();
- pc->AddAction( GenerateAction( command ) );
- pc->ProcessActions(true);
+ pc->MovementCommand(command);
+ }
+ }
+ i = game->GetNPCCount();
+ while(i--) {
+ Actor *npc = game->GetNPC(i);
+ if ((npc->GetCurrentArea()==this) && (npc->GetStat(IE_EA)<EA_GOODCUTOFF) ) {
+ npc->MovementCommand(command);
}
}
return;
@@ -530,20 +558,20 @@ void Map::MoveToNewArea(const char *area, const char *entrance, unsigned int dir
continue;
}
if (pc->GetCurrentArea()==this) {
- pc->UseExit(0);
- pc->ClearPath();
- pc->ClearActions();
- pc->AddAction( GenerateAction( command ) );
- pc->ProcessActions(true);
+ pc->MovementCommand(command);
+ }
+ }
+ i = game->GetNPCCount();
+ while(i--) {
+ Actor *npc = game->GetNPC(i);
+ if (npc->IsSelected() && (npc->GetCurrentArea()==this)) {
+ npc->MovementCommand(command);
}
}
return;
}
- actor->ClearPath();
- actor->ClearActions();
- actor->AddAction( GenerateAction( command ) );
- actor->ProcessActions(true);
+ actor->MovementCommand(command);
}
void Map::UseExit(Actor *actor, InfoPoint *ip)
@@ -553,7 +581,10 @@ void Map::UseExit(Actor *actor, InfoPoint *ip)
int EveryOne = ip->CheckTravel(actor);
switch(EveryOne) {
case CT_GO_CLOSER:
- displaymsg->DisplayConstantString(STR_WHOLEPARTY,0xffffff); //white
+ if (LastGoCloser<game->Ticks) {
+ displaymsg->DisplayConstantString(STR_WHOLEPARTY, DMC_WHITE); //white
+ LastGoCloser = game->Ticks+6000;
+ }
if (game->EveryoneStopped()) {
ip->Flags&=~TRAP_RESET; //exit triggered
}
@@ -572,9 +603,10 @@ void Map::UseExit(Actor *actor, InfoPoint *ip)
return;
}
if (ip->Scripts[0]) {
- ip->LastTriggerObject = ip->LastTrigger = ip->LastEntered = actor->GetGlobalID();
+ ip->AddTrigger(TriggerEntry(trigger_entered, actor->GetGlobalID()));
+ // FIXME
ip->ExecuteScript( 1 );
- ip->ProcessActions(true);
+ ip->ProcessActions();
}
}
@@ -610,6 +642,9 @@ void Map::UpdateScripts()
}
}
+ GenerateQueues();
+ SortQueues();
+
// if masterarea, then we allow 'any' actors
// if not masterarea, we allow only players
// if (!GetActorCount(MasterArea) ) {
@@ -626,19 +661,20 @@ void Map::UpdateScripts()
}
// fuzzie added this check because some area scripts (eg, AR1600 when
- // escaping Brynnlaw) were executing after they were meant to be done,
+ // escaping Brynnlaw) were executing after they were meant to be done,
// and this seems the nicest way of handling that for now - it's quite
// possibly wrong (so if you have problems, revert this and find
// another way)
if (has_pcs) {
//Run all the Map Scripts (as in the original)
//The default area script is in the last slot anyway
- ExecuteScript( MAX_SCRIPTS );
+ //ExecuteScript( MAX_SCRIPTS );
+ Update();
}
-
+
//Execute Pending Actions
//if it is only here, then the drawing will fail
- ProcessActions(false);
+ ProcessActions();
// If scripts frozen, return.
// This fixes starting a new IWD game. The above ProcessActions pauses the
@@ -650,8 +686,10 @@ void Map::UpdateScripts()
int q=Qcount[PR_SCRIPT];
Game *game = core->GetGame();
- Actor *timestop_owner = game->timestop_owner;
- bool timestop = game->timestop_end>game->GameTime;
+ bool timestop = game->IsTimestopActive();
+ if (!timestop) {
+ game->timestop_owner = NULL;
+ }
while (q--) {
Actor* actor = queue[PR_SCRIPT][q];
@@ -660,25 +698,39 @@ void Map::UpdateScripts()
actor->no_more_steps = true;
continue;
}
- if (timestop && actor!=timestop_owner && actor->Modified[IE_DISABLETIMESTOP] ) {
+
+ //FIXME:we need a better timestop hack, actors shouldn't abort moving after a timestop expired
+ if (game->TimeStoppedFor(actor)) {
actor->no_more_steps = true;
+ actor->ClearPath(); //HACK: prevents jumping when timestop ends
continue;
}
//Avenger moved this here from ApplyAllEffects (this one modifies the effect queue)
//.. but then fuzzie moved this here from UpdateActorState, because otherwise
//immobile actors (see check below) never become mobile again!
+ //Avenger again: maybe this should be before the timestop check above
+ //definitely try to move it up if you experience freezes after timestop
actor->fxqueue.Cleanup();
//if the actor is immobile, don't run the scripts
//FIXME: this is not universaly true, only some states have this effect
if (!game->StateOverrideFlag && !game->StateOverrideTime) {
- if (/*actor->Immobile() ||*/ actor->GetStat(IE_STATE_ID) & STATE_SLEEP) {
+ //it looks like STATE_SLEEP allows scripts, probably it is STATE_HELPLESS what disables scripts
+ //if that isn't true either, remove this block completely
+ if (actor->GetStat(IE_STATE_ID) & STATE_HELPLESS) {
actor->no_more_steps = true;
+ //FIXME:obviously we miss the ClearPath hack here (but we need a better one)
continue;
}
}
+
+ //FIXME: we need a better immobile hack, the actors used to retain their target
+ //and resume moving after the hold effect stopped
actor->no_more_steps = false;
+ if (actor->Immobile()) {
+ actor->ClearPath(); //HACK: prevents jumping when effect ends
+ }
/*
* we run scripts all at once because one of the actions in ProcessActions
@@ -691,7 +743,7 @@ void Map::UpdateScripts()
* point, etc), but i did it this way for now because it seems least painful
* and we should probably be staggering the script executions anyway
*/
- actor->ExecuteScript( MAX_SCRIPTS );
+ actor->Update();
}
@@ -707,15 +759,9 @@ void Map::UpdateScripts()
Actor* actor = queue[PR_SCRIPT][q];
if (actor->no_more_steps) continue;
- actor->ProcessActions(false);
-
actor->UpdateActorState(game->GameTime);
- actor->inventory.CalculateWeight();
- actor->SetBase( IE_ENCUMBRANCE, actor->inventory.GetWeight() );
-
- //TODO:calculate actor speed!
- int speed = (int) actor->GetStat(IE_MOVEMENTRATE);
+ int speed = actor->CalculateSpeed(false);
if (speed) {
speed = 1500/speed;
}
@@ -731,7 +777,7 @@ void Map::UpdateScripts()
} else if (avatar->WalkScale) {
speed = avatar->WalkScale;
} else {
- //printf("no walkscale for anim %d!\n", actor->BaseStats[IE_ANIMATION_ID]);
+ //print("no walkscale for anim %d!", actor->BaseStats[IE_ANIMATION_ID]);
}
}
}
@@ -767,10 +813,7 @@ void Map::UpdateScripts()
Door* door = TMap->GetDoor( doorCount++ );
if (!door)
break;
- if (door->Scripts[0])
- door->ExecuteScript( 1 );
- //Execute Pending Actions
- door->ProcessActions(false);
+ door->Update();
}
//Check if we need to start some container scripts
@@ -779,10 +822,7 @@ void Map::UpdateScripts()
Container* container = TMap->GetContainer( containerCount++ );
if (!container)
break;
- if (container->Scripts[0])
- container->ExecuteScript( 1 );
- //Execute Pending Actions
- container->ProcessActions(false);
+ container->Update();
}
//Check if we need to start some trap scripts
@@ -799,15 +839,7 @@ void Map::UpdateScripts()
//If this InfoPoint is a Switch Trigger
if (ip->Type == ST_TRIGGER) {
- //Check if this InfoPoint was activated
- if (ip->LastTrigger) {
- if (wasActive && ip->Scripts[0]) {
- //Run the InfoPoint script
- ip->ExecuteScript( 1 );
- }
- }
- //Execute Pending Actions
- ip->ProcessActions(false);
+ ip->Update();
continue;
}
@@ -824,7 +856,7 @@ void Map::UpdateScripts()
if(ip->Entered(actor)) {
//if trap triggered, then mark actor
actor->SetInTrap(ipCount);
- wasActive|=TRAP_USEPOINT;
+ wasActive|=_TRAP_USEPOINT;
}
} else {
//ST_TRAVEL
@@ -844,15 +876,17 @@ void Map::UpdateScripts()
}
if (wasActive) {
- ip->ExecuteScript( 1 );
//Play the PST specific enter sound
- if (wasActive&TRAP_USEPOINT) {
+ if (wasActive&_TRAP_USEPOINT) {
core->GetAudioDrv()->Play(ip->EnterWav, ip->TrapLaunch.x, ip->TrapLaunch.y);
}
+ ip->Update();
}
- //Execute Pending Actions
- ip->ProcessActions(false);
}
+
+ UpdateSpawns();
+ GenerateQueues();
+ SortQueues();
}
void Map::ResolveTerrainSound(ieResRef &sound, Point &Pos) {
@@ -862,7 +896,7 @@ void Map::ResolveTerrainSound(ieResRef &sound, Point &Pos) {
memcpy(sound, terrainsounds[i].Sounds[type], sizeof(ieResRef) );
return;
}
- }
+ }
}
bool Map::DoStepForActor(Actor *actor, int speed, ieDword time) {
@@ -883,7 +917,7 @@ bool Map::DoStepForActor(Actor *actor, int speed, ieDword time) {
if (!actor->Immobile()) {
no_more_steps = actor->DoStep( speed, time );
if (actor->BlocksSearchMap()) {
- BlockSearchMap( actor->Pos, actor->size, actor->InParty?PATH_MAP_PC:PATH_MAP_NPC);
+ BlockSearchMap( actor->Pos, actor->size, actor->IsPartyMember()?PATH_MAP_PC:PATH_MAP_NPC);
}
}
}
@@ -901,7 +935,7 @@ void Map::ClearSearchMapFor( Movable *actor ) {
int i=0;
while(nearActors[i]!=NULL) {
if(nearActors[i]!=actor && nearActors[i]->BlocksSearchMap())
- BlockSearchMap( nearActors[i]->Pos, nearActors[i]->size, nearActors[i]->InParty?PATH_MAP_PC:PATH_MAP_NPC);
+ BlockSearchMap( nearActors[i]->Pos, nearActors[i]->size, nearActors[i]->IsPartyMember()?PATH_MAP_PC:PATH_MAP_NPC);
++i;
}
free(nearActors);
@@ -1069,7 +1103,15 @@ void Map::DrawMap(Region screen)
}
if (!bgoverride) {
- int rain;
+ int rain, flags;
+
+ if (game->IsTimestopActive()) {
+ flags = TILE_GREY;
+ }
+ else if (AreaFlags&AF_DREAM) {
+ flags = TILE_SEPIA;
+ } else flags = 0;
+
if (HasWeather()) {
//zero when the weather particles are all gone
rain = game->weather->GetPhase()-P_EMPTY;
@@ -1077,16 +1119,12 @@ void Map::DrawMap(Region screen)
rain = 0;
}
- TMap->DrawOverlays( screen, rain );
+ TMap->DrawOverlays( screen, rain, flags );
//Draw Outlines
DrawHighlightables( screen );
}
- Region vp = video->GetViewport();
- //if it is only here, then the scripting will fail?
- GenerateQueues();
- SortQueues();
//drawing queues 1 and 0
//starting with lower priority
//so displayed, but inactive actors (dead) will be drawn over
@@ -1103,6 +1141,10 @@ void Map::DrawMap(Region screen)
Projectile *pro = GetNextProjectile(proidx);
Particles *spark = GetNextSpark(spaidx);
+ // TODO: In at least HOW/IWD2 actor ground circles will be hidden by
+ // an area animation with height > 0 even if the actors themselves are not
+ // hidden by it.
+
while (actor || a || sca || spark || pro) {
switch(SelectObject(actor,q,a,sca,spark,pro)) {
case AOT_ACTOR:
@@ -1121,7 +1163,7 @@ void Map::DrawMap(Region screen)
Color tint = LightMap->GetPixel( sca->XPos / 16, sca->YPos / 12);
tint.a = 255;
- bool endReached = sca->Draw(screen, Pos, tint, this, 0, -1);
+ bool endReached = sca->Draw(screen, Pos, tint, this, 0, -1, 0);
if (endReached) {
delete( sca );
scaidx=vvcCells.erase(scaidx);
@@ -1168,7 +1210,7 @@ void Map::DrawMap(Region screen)
spark = GetNextSpark(spaidx);
break;
default:
- abort();
+ error("Map", "Trying to draw unknown animation type.\n");
}
}
@@ -1261,11 +1303,10 @@ void Map::AddAnimation(AreaAnimation* panim)
anim->InitAnimation();
aniIterator iter;
-
+
int Height = anim->GetHeight();
-printf("Adding %s at height %d, Pos: %d.%d\n", anim->Name, Height, anim->Pos.x, anim->Pos.y);
for(iter=animations.begin(); (iter!=animations.end()) && ((*iter)->GetHeight()<Height); iter++) ;
- animations.insert(iter, anim);
+ animations.insert(iter, anim);
}
//reapplying all of the effects on the actors of this map
@@ -1284,20 +1325,44 @@ void Map::Shout(Actor* actor, int shoutID, unsigned int radius)
while (i--) {
Actor *listener = actors[i];
+ // skip the shouter, so gpshout's InMyGroup(LastHeardBy(Myself)) can get two distinct actors
+ if (listener == actor) {
+ continue;
+ }
+
if (radius) {
if (Distance(actor->Pos, listener->Pos)>radius) {
continue;
}
}
if (shoutID) {
+ listener->AddTrigger(TriggerEntry(trigger_heard, actor->GetGlobalID(), shoutID));
listener->LastHeard = actor->GetGlobalID();
- listener->LastShout = shoutID;
} else {
+ listener->AddTrigger(TriggerEntry(trigger_help, actor->GetGlobalID()));
listener->LastHelp = actor->GetGlobalID();
}
}
}
+int Map::CountSummons(ieDword flags, ieDword sex)
+{
+ int count = 0;
+
+ size_t i = actors.size();
+ while (i--) {
+ Actor *actor = actors[i];
+
+ if (!actor->ValidTarget(flags) ) {
+ continue;
+ }
+ if (actor->GetStat(IE_SEX)==sex) {
+ count++;
+ }
+ }
+ return count;
+}
+
bool Map::AnyEnemyNearPoint(const Point &p)
{
ieDword gametime = core->GetGame()->GameTime;
@@ -1305,15 +1370,22 @@ bool Map::AnyEnemyNearPoint(const Point &p)
while (i--) {
Actor *actor = actors[i];
- if (actor->Schedule(gametime, true) ) {
+ if (!actor->Schedule(gametime, true) ) {
+ continue;
+ }
+ if (actor->IsDead() ) {
+ continue;
+ }
+ if (actor->GetStat(IE_AVATARREMOVAL)) {
continue;
}
if (Distance(actor->Pos, p) > SPAWN_RANGE) {
continue;
}
- if (actor->GetStat(IE_EA)<EA_EVILCUTOFF) {
+ if (actor->GetStat(IE_EA)<=EA_EVILCUTOFF) {
continue;
}
+
return true;
}
return false;
@@ -1334,19 +1406,27 @@ void Map::ActorSpottedByPlayer(Actor *actor)
}
}
- if (!(actor->GetInternalFlag()&IF_STOPATTACK)) {
+ if (!(actor->GetInternalFlag()&IF_STOPATTACK) && !core->GetGame()->AnyPCInCombat()) {
if (actor->Modified[IE_EA]>=EA_EVILCUTOFF) {
- core->Autopause(AP_ENEMY);
+ core->Autopause(AP_ENEMY, actor);
}
}
}
-void Map::AddActor(Actor* actor)
+//call this once, after area was loaded
+void Map::InitActors()
+{
+ size_t i = actors.size();
+ while(i--) {
+ Actor* actor = actors[i];
+
+ actor->SetMap(this);
+ InitActor(actor);
+ }
+}
+
+void Map::InitActor(Actor *actor)
{
- //setting the current area for the actor as this one
- strnlwrcpy(actor->Area, scriptName, 8);
- actor->SetMap(this);
- actors.push_back( actor );
//if a visible aggressive actor was put on the map, it is an autopause reason
//guess game is always loaded? if not, then we'll crash
ieDword gametime = core->GetGame()->GameTime;
@@ -1359,7 +1439,19 @@ void Map::AddActor(Actor* actor)
snprintf(key, sizeof(key),"%s_visited", scriptName);
core->GetGame()->locals->SetAt(key, 1);
}
+}
+void Map::AddActor(Actor* actor, bool init)
+{
+ //setting the current area for the actor as this one
+ strnlwrcpy(actor->Area, scriptName, 8);
+ if (!HasActor(actor)) {
+ actors.push_back( actor );
+ }
+ if (init) {
+ actor->SetMap(this);
+ InitActor(actor);
+ }
}
bool Map::AnyPCSeesEnemy()
@@ -1393,9 +1485,10 @@ void Map::DeleteActor(int i)
ClearSearchMapFor( actor );
//remove the area reference from the actor
actor->SetMap(NULL);
+ CopyResRef(actor->Area, "");
//don't destroy the object in case it is a persistent object
//otherwise there is a dead reference causing a crash on save
- if (!game->InStore(actor) ) {
+ if (game->InStore(actor) < 0) {
delete actor;
}
}
@@ -1469,7 +1562,6 @@ Actor* Map::GetActorByGlobalID(ieDword objectID)
*/
Actor* Map::GetActor(const Point &p, int flags)
{
- ieDword gametime = core->GetGame()->GameTime;
size_t i = actors.size();
while (i--) {
Actor* actor = actors[i];
@@ -1479,9 +1571,6 @@ Actor* Map::GetActor(const Point &p, int flags)
if (!actor->ValidTarget(flags) ) {
continue;
}
- if (!actor->Schedule(gametime, true) ) {
- continue;
- }
return actor;
}
return NULL;
@@ -1489,7 +1578,6 @@ Actor* Map::GetActor(const Point &p, int flags)
Actor* Map::GetActorInRadius(const Point &p, int flags, unsigned int radius)
{
- ieDword gametime = core->GetGame()->GameTime;
size_t i = actors.size();
while (i--) {
Actor* actor = actors[i];
@@ -1499,35 +1587,27 @@ Actor* Map::GetActorInRadius(const Point &p, int flags, unsigned int radius)
if (!actor->ValidTarget(flags) ) {
continue;
}
- if (!actor->Schedule(gametime, true) ) {
- continue;
- }
return actor;
}
return NULL;
}
//maybe consider using a simple list
-Actor **Map::GetAllActorsInRadius(const Point &p, int flags, unsigned int radius)
+Actor **Map::GetAllActorsInRadius(const Point &p, int flags, unsigned int radius, Scriptable *see)
{
ieDword count = 1;
- size_t i;
-
- ieDword gametime = core->GetGame()->GameTime;
- i = actors.size();
+ size_t i = actors.size();
while (i--) {
Actor* actor = actors[i];
if (PersonalDistance( p, actor ) > radius)
continue;
- if (!actor->ValidTarget(flags) ) {
- continue;
- }
- if (!actor->Schedule(gametime, true) ) {
+ if (!actor->ValidTarget(flags, see) ) {
continue;
}
if (!(flags&GA_NO_LOS)) {
- if (!IsVisible(actor->Pos, p)) {
+ //line of sight visibility
+ if (!IsVisibleLOS(actor->Pos, p)) {
continue;
}
}
@@ -1545,11 +1625,8 @@ Actor **Map::GetAllActorsInRadius(const Point &p, int flags, unsigned int radius
if (!actor->ValidTarget(flags) ) {
continue;
}
- if (!actor->Schedule(gametime, true) ) {
- continue;
- }
if (!(flags&GA_NO_LOS)) {
- if (!IsVisible(actor->Pos, p)) {
+ if (!IsVisibleLOS(actor->Pos, p)) {
continue;
}
}
@@ -1626,11 +1703,18 @@ void Map::PurgeArea(bool items)
int i=(int) actors.size();
while (i--) {
Actor *ac = actors[i];
+ //we're going to drop the map from memory so clear the reference
+ ac->SetMap(NULL);
if (ac->Modified[IE_STATE_ID]&STATE_NOSAVE) {
if (ac->Modified[IE_MC_FLAGS] & MC_KEEP_CORPSE) {
continue;
}
+
+ if (ac->RemovalTime > core->GetGame()->GameTime) {
+ continue;
+ }
+
//don't delete persistent actors
if (ac->Persistent()) {
continue;
@@ -1900,11 +1984,16 @@ void Map::GenerateQueues()
if ((stance == IE_ANI_TWITCH) && (internalFlag&IF_IDLE) ) {
priority = PR_DISPLAY; //display
} else {
- priority = PR_SCRIPT; //run scripts and display
+ //if actor is unscheduled, don't run its scripts
+ if (actor->Schedule(gametime, false) ) {
+ priority = PR_SCRIPT; //run scripts and display
+ } else {
+ priority = PR_IGNORE; //don't run scripts for out of schedule actors
+ }
}
} else {
//dead actors are always visible on the map, but run no scripts
- if (stance == IE_ANI_TWITCH || stance == IE_ANI_DIE) {
+ if ((stance == IE_ANI_TWITCH) || (stance == IE_ANI_DIE) ) {
priority = PR_DISPLAY;
} else {
//isvisible flag is false (visibilitymap) here,
@@ -2056,7 +2145,7 @@ Spawn *Map::AddSpawn(char* Name, int XPos, int YPos, ieResRef *creatures, unsign
void Map::AddEntrance(char* Name, int XPos, int YPos, short Face)
{
Entrance* ent = new Entrance();
- strncpy( ent->Name, Name, 32 );
+ strlcpy( ent->Name, Name, sizeof(ent->Name) );
ent->Pos.x = (ieWord) XPos;
ent->Pos.y = (ieWord) YPos;
ent->Face = (ieWord) Face;
@@ -2092,24 +2181,29 @@ void Map::RemoveActor(Actor* actor)
size_t i=actors.size();
while (i--) {
if (actors[i] == actor) {
+ //clear previous walk path
+ actor->ClearPath();
ClearSearchMapFor(actor);
+ actor->SetMap(NULL);
+ CopyResRef(actor->Area, "");
actors.erase( actors.begin()+i );
return;
}
}
- printMessage("Map","RemoveActor: actor not found?",YELLOW);
+ Log(WARNING, "Map", "RemoveActor: actor not found?");
}
//returns true if none of the partymembers are on the map
+//and noone is trying to follow the party out
bool Map::CanFree()
{
size_t i=actors.size();
while (i--) {
- if (actors[i]->InParty) {
+ if (actors[i]->IsPartyMember()) {
return false;
}
- if (actors[i]->GetInternalFlag()&(IF_ACTIVE|IF_USEEXIT) ) {
+ if (actors[i]->GetInternalFlag()&IF_USEEXIT) {
return false;
}
}
@@ -2118,37 +2212,40 @@ bool Map::CanFree()
return true;
}
-void Map::DebugDump(bool show_actors) const
+void Map::dump(bool show_actors) const
{
+ StringBuffer buffer;
size_t i;
- printf( "DebugDump of Area %s:\n", scriptName );
- printf ("Scripts:");
+ buffer.appendFormatted( "Debugdump of Area %s:\n", scriptName );
+ buffer.append("Scripts:");
for (i = 0; i < MAX_SCRIPTS; i++) {
const char* poi = "<none>";
if (Scripts[i]) {
poi = Scripts[i]->GetName();
}
- printf( " %.8s", poi );
+ buffer.appendFormatted( " %.8s", poi );
}
- printf( "Area Global ID: %d\n", GetGlobalID());
- printf( "OutDoor: %s\n", YESNO(AreaType & AT_OUTDOOR ) );
- printf( "Day/Night: %s\n", YESNO(AreaType & AT_DAYNIGHT ) );
- printf( "Extended night: %s\n", YESNO(AreaType & AT_EXTENDED_NIGHT ) );
- printf( "Weather: %s\n", YESNO(AreaType & AT_WEATHER ) );
- printf( "Area Type: %d\n", AreaType & (AT_CITY|AT_FOREST|AT_DUNGEON) );
- printf( "Can rest: %s\n", YESNO(AreaType & AT_CAN_REST) );
+ buffer.append("\n");
+ buffer.appendFormatted( "Area Global ID: %d\n", GetGlobalID());
+ buffer.appendFormatted( "OutDoor: %s\n", YESNO(AreaType & AT_OUTDOOR ) );
+ buffer.appendFormatted( "Day/Night: %s\n", YESNO(AreaType & AT_DAYNIGHT ) );
+ buffer.appendFormatted( "Extended night: %s\n", YESNO(AreaType & AT_EXTENDED_NIGHT ) );
+ buffer.appendFormatted( "Weather: %s\n", YESNO(AreaType & AT_WEATHER ) );
+ buffer.appendFormatted( "Area Type: %d\n", AreaType & (AT_CITY|AT_FOREST|AT_DUNGEON) );
+ buffer.appendFormatted( "Can rest: %s\n", YESNO(AreaType & AT_CAN_REST) );
if (show_actors) {
- printf("\n");
+ buffer.append("\n");
i = actors.size();
while (i--) {
if (!(actors[i]->GetInternalFlag()&(IF_JUSTDIED|IF_REALLYDIED))) {
- printf("Actor: %s at %d.%d\n", actors[i]->GetName(1), actors[i]->Pos.x, actors[i]->Pos.y);
+ buffer.appendFormatted("Actor: %s at %d.%d\n", actors[i]->GetName(1), actors[i]->Pos.x, actors[i]->Pos.y);
}
}
}
+ Log(DEBUG, "Map", buffer);
}
/******************************************************************************/
@@ -2198,27 +2295,27 @@ void Map::SetupNode(unsigned int x, unsigned int y, unsigned int size, unsigned
InternalStack.push( ( x << 16 ) | y );
}
-bool Map::AdjustPositionX(Point &goal, unsigned int radius)
+bool Map::AdjustPositionX(Point &goal, unsigned int radiusx, unsigned int radiusy)
{
unsigned int minx = 0;
- if ((unsigned int) goal.x > radius)
- minx = goal.x - radius;
- unsigned int maxx = goal.x + radius + 1;
+ if ((unsigned int) goal.x > radiusx)
+ minx = goal.x - radiusx;
+ unsigned int maxx = goal.x + radiusx + 1;
if (maxx > Width)
maxx = Width;
for (unsigned int scanx = minx; scanx < maxx; scanx++) {
- if ((unsigned int) goal.y >= radius) {
- if (GetBlocked( scanx, goal.y - radius ) & PATH_MAP_PASSABLE) {
+ if ((unsigned int) goal.y >= radiusy) {
+ if (GetBlocked( scanx, goal.y - radiusy ) & PATH_MAP_PASSABLE) {
goal.x = (ieWord) scanx;
- goal.y = (ieWord) (goal.y - radius);
+ goal.y = (ieWord) (goal.y - radiusy);
return true;
}
}
- if (goal.y + radius < Height) {
- if (GetBlocked( scanx, goal.y + radius ) & PATH_MAP_PASSABLE) {
+ if (goal.y + radiusy < Height) {
+ if (GetBlocked( scanx, goal.y + radiusy ) & PATH_MAP_PASSABLE) {
goal.x = (ieWord) scanx;
- goal.y = (ieWord) (goal.y + radius);
+ goal.y = (ieWord) (goal.y + radiusy);
return true;
}
}
@@ -2226,25 +2323,25 @@ bool Map::AdjustPositionX(Point &goal, unsigned int radius)
return false;
}
-bool Map::AdjustPositionY(Point &goal, unsigned int radius)
+bool Map::AdjustPositionY(Point &goal, unsigned int radiusx, unsigned int radiusy)
{
unsigned int miny = 0;
- if ((unsigned int) goal.y > radius)
- miny = goal.y - radius;
- unsigned int maxy = goal.y + radius + 1;
+ if ((unsigned int) goal.y > radiusy)
+ miny = goal.y - radiusy;
+ unsigned int maxy = goal.y + radiusy + 1;
if (maxy > Height)
maxy = Height;
for (unsigned int scany = miny; scany < maxy; scany++) {
- if ((unsigned int) goal.x >= radius) {
- if (GetBlocked( goal.x - radius, scany ) & PATH_MAP_PASSABLE) {
- goal.x = (ieWord) (goal.x - radius);
+ if ((unsigned int) goal.x >= radiusx) {
+ if (GetBlocked( goal.x - radiusx, scany ) & PATH_MAP_PASSABLE) {
+ goal.x = (ieWord) (goal.x - radiusx);
goal.y = (ieWord) scany;
return true;
}
}
- if (goal.x + radius < Width) {
- if (GetBlocked( goal.x + radius, scany ) & PATH_MAP_PASSABLE) {
- goal.x = (ieWord) (goal.x + radius);
+ if (goal.x + radiusx < Width) {
+ if (GetBlocked( goal.x + radiusx, scany ) & PATH_MAP_PASSABLE) {
+ goal.x = (ieWord) (goal.x + radiusx);
goal.y = (ieWord) scany;
return true;
}
@@ -2253,12 +2350,8 @@ bool Map::AdjustPositionY(Point &goal, unsigned int radius)
return false;
}
-void Map::AdjustPosition(Point &goal, unsigned int radius)
+void Map::AdjustPosition(Point &goal, unsigned int radiusx, unsigned int radiusy)
{
- unsigned int maxr = Width;
- if (maxr < Height) {
- maxr = Height;
- }
if ((unsigned int) goal.x > Width) {
goal.x = (ieWord) Width;
}
@@ -2266,23 +2359,29 @@ void Map::AdjustPosition(Point &goal, unsigned int radius)
goal.y = (ieWord) Height;
}
- for (; radius < maxr; radius++) {
+ while(radiusx<Width || radiusy<Height) {
//lets make it slightly random where the actor will appear
if (rand()&1) {
- if (AdjustPositionX(goal, radius)) {
+ if (AdjustPositionX(goal, radiusx, radiusy)) {
return;
}
- if (AdjustPositionY(goal, radius)) {
+ if (AdjustPositionY(goal, radiusy, radiusx)) {
return;
}
} else {
- if (AdjustPositionY(goal, radius)) {
+ if (AdjustPositionY(goal, radiusx, radiusy)) {
return;
}
- if (AdjustPositionX(goal, radius)) {
+ if (AdjustPositionX(goal, radiusx, radiusy)) {
return;
}
}
+ if (radiusx<Width) {
+ radiusx++;
+ }
+ if (radiusy<Height) {
+ radiusy++;
+ }
}
}
@@ -2315,8 +2414,8 @@ PathNode* Map::RunAway(const Point &s, const Point &d, unsigned int size, unsign
InternalStack.pop();
unsigned int x = pos >> 16;
unsigned int y = pos & 0xffff;
- long tx = ( x - goal.x );
- long ty = ( y - goal.y );
+ long tx = (long) x - goal.x;
+ long ty = (long) y - goal.y;
unsigned int distance = (unsigned int) sqrt( ( double ) ( tx* tx + ty* ty ) );
if (dist<distance) {
best.x=(ieWord) x;
@@ -2326,7 +2425,6 @@ PathNode* Map::RunAway(const Point &s, const Point &d, unsigned int size, unsign
unsigned int Cost = MapSet[y * Width + x] + NormalCost;
if (Cost > PathLen) {
- //printf("Path not found!\n");
break;
}
SetupNode( x - 1, y - 1, size, Cost );
@@ -2438,12 +2536,27 @@ PathNode* Map::GetLine(const Point &start, int Steps, int Orientation, int flags
{
Point dest=start;
- unsigned int st = Steps>=MaxVisibility?MaxVisibility-1:Steps;
- int p = VisibilityPerimeter*Orientation/MAX_ORIENT;
- dest.x += VisibilityMasks[st][p].x;
- dest.y += VisibilityMasks[st][p].y;
- //FIXME: calculate dest based on distance and orientation
- return GetLine(start, dest, Steps, Orientation, flags);
+ double xoff, yoff, mult;
+ if (Orientation <= 4) {
+ xoff = -Orientation / 4.0;
+ } else if (Orientation <= 12) {
+ xoff = -1.0 + (Orientation - 4) / 4.0;
+ } else {
+ xoff = 1.0 - (Orientation - 12) / 4.0;
+ }
+
+ if (Orientation <= 8) {
+ yoff = 1.0 - Orientation / 4.0;
+ } else {
+ yoff = -1.0 + (Orientation - 8) / 4.0;
+ }
+
+ mult = 1.0 / (fabs(xoff) > fabs(yoff) ? fabs(xoff) : fabs(yoff));
+
+ dest.x += Steps * mult * xoff + 0.5;
+ dest.y += Steps * mult * yoff + 0.5;
+
+ return GetLine(start, dest, 2, Orientation, flags);
}
PathNode* Map::GetLine(const Point &start, const Point &dest, int Speed, int Orientation, int flags)
@@ -2459,16 +2572,6 @@ PathNode* Map::GetLine(const Point &start, const Point &dest, int Speed, int Ori
int Count = 0;
int Max = Distance(start,dest);
for (int Steps = 0; Steps<Max; Steps++) {
- if (!Count) {
- StartNode->Next = new PathNode;
- StartNode->Next->Parent = StartNode;
- StartNode = StartNode->Next;
- StartNode->Next = NULL;
- Count=Speed;
- } else {
- Count--;
- }
-
Point p;
p.x = (ieWord) start.x + ((dest.x - start.x) * Steps / Max);
p.y = (ieWord) start.y + ((dest.y - start.y) * Steps / Max);
@@ -2483,6 +2586,16 @@ PathNode* Map::GetLine(const Point &start, const Point &dest, int Speed, int Ori
return Return;
}
+ if (!Count) {
+ StartNode->Next = new PathNode;
+ StartNode->Next->Parent = StartNode;
+ StartNode = StartNode->Next;
+ StartNode->Next = NULL;
+ Count=Speed;
+ } else {
+ Count--;
+ }
+
StartNode->x = p.x;
StartNode->y = p.y;
StartNode->orient = Orientation;
@@ -2556,7 +2669,7 @@ PathNode* Map::FindPathNear(const Point &s, const Point &d, unsigned int size, u
// we are within the minimum distance of the goal
Point ourpos(x*16 + 8, y*12 + 6);
// sight check is *slow* :(
- if (!sight || IsVisible(ourpos, d)) {
+ if (!sight || IsVisibleLOS(ourpos, d)) {
// we got all the way to a suitable goal!
goal = Point(x, y);
found_path = true;
@@ -2669,12 +2782,12 @@ PathNode* Map::FindPath(const Point &s, const Point &d, unsigned int size, int M
if (pos == pos2) {
//We've found _a_ path
- //printf("GOAL!!!\n");
+ //print("GOAL!!!");
break;
}
unsigned int Cost = MapSet[y * Width + x] + NormalCost;
if (Cost > 65500) {
- //printf("Path not found!\n");
+ //print("Path not found!");
break;
}
SetupNode( x - 1, y - 1, size, Cost );
@@ -2767,7 +2880,7 @@ bool Map::IsVisible(const Point &pos, int explored)
}
//point a is visible from point b (searchmap)
-bool Map::IsVisible(const Point &s, const Point &d)
+bool Map::IsVisibleLOS(const Point &s, const Point &d)
{
int sX=s.x/16;
int sY=s.y/12;
@@ -2828,8 +2941,8 @@ int Map::WhichEdge(const Point &s)
unsigned int sX=s.x/16;
unsigned int sY=s.y/12;
if (!(GetBlocked( sX, sY )&PATH_MAP_TRAVEL)) {
- printMessage("Map"," ",YELLOW);
- printf("This isn't a travel region [%d.%d]?\n",sX, sY);
+ Log(DEBUG, "Map", "This isn't a travel region [%d.%d]?",
+ sX, sY);
return -1;
}
sX*=Height;
@@ -2898,48 +3011,48 @@ void Map::LoadIniSpawn()
INISpawn->InitSpawn(WEDResRef);
}
-void Map::SpawnCreature(const Point &pos, const char *CreName, int radius)
+bool Map::SpawnCreature(const Point &pos, const char *creResRef, int radiusx, int radiusy, int *difficulty, unsigned int *creCount)
{
- SpawnGroup *sg=NULL;
- Actor *creature;
- void* lookup;
- if ( !Spawns.Lookup( CreName, lookup) ) {
- creature = gamedata->GetCreature(CreName);
- if ( creature ) {
- AddActor(creature);
- creature->SetPosition( pos, true, radius );
- creature->RefreshEffects(NULL);
+ bool spawned = false;
+ SpawnGroup *sg = NULL;
+ void *lookup;
+ bool first = (creCount ? *creCount == 0 : true);
+ int level = (difficulty ? *difficulty : core->GetGame()->GetPartyLevel(true));
+ int count = 1;
+
+ if (Spawns.Lookup(creResRef, lookup)) {
+ sg = (SpawnGroup *) lookup;
+ if (level >= (int) sg->Level) {
+ count = sg->Count;
+ } else if (!first) {
+ count = 0;
}
- return;
}
- sg = (SpawnGroup*)lookup;
- unsigned int count = 0;
- int amount = core->GetGame()->GetPartyLevel(true);
- // if the difficulty is too high, distribute it equally over all the
- // critters and summon as many as the summed difficulty allows
- if (amount - (signed)sg->Level < 0) {
- unsigned int share = sg->Level/sg->Count;
- amount -= share;
- if (amount < 0) {
- // a single critter is also too powerful
- return;
- }
- while (amount >= 0) {
- count++;
- amount -= share;
- }
- } else {
- count = sg->Count;
+
+ while (count--) {
+ Actor *creature = gamedata->GetCreature(sg ? sg->ResRefs[count] : creResRef);
+ if (creature) {
+ // ensure a minimum power level, since many creatures have this as 0
+ int cpl = creature->Modified[IE_XP] ? creature->Modified[IE_XP] : 1;
+
+ //SpawnGroups normally are all or nothing but make sure we spawn
+ //at least one creature if this is the first
+ if (level >= cpl || sg || first) {
+ AddActor(creature, true);
+ creature->SetPosition(pos, true, radiusx, radiusy);
+ creature->RefreshEffects(NULL);
+ if (difficulty && !sg) *difficulty -= cpl;
+ if (creCount) (*creCount)++;
+ spawned = true;
+ }
+ }
}
- while ( count-- ) {
- creature = gamedata->GetCreature(sg->ResRefs[count]);
- if ( creature ) {
- AddActor(creature);
- creature->SetPosition( pos, true, radius );
- creature->RefreshEffects(NULL);
- }
+ if (spawned && sg && difficulty) {
+ *difficulty -= sg->Level;
}
+
+ return spawned;
}
void Map::TriggerSpawn(Spawn *spawn)
@@ -2948,23 +3061,60 @@ void Map::TriggerSpawn(Spawn *spawn)
if (!spawn->Enabled) {
return;
}
+ //temporarily disabled?
+ if ((spawn->Method & (SPF_NOSPAWN|SPF_WAIT)) == (SPF_NOSPAWN|SPF_WAIT)) {
+ return;
+ }
+
//check schedule
- ieDword bit = 1<<((core->GetGame()->GameTime/AI_UPDATE_TIME)%7200/300);
+ ieDword time = core->GetGame()->GameTime;
+ ieDword bit = 1<<((time/AI_UPDATE_TIME)%7200/300);
if (!(spawn->appearance & bit)) {
return;
}
//check day or night chance
- if (rand()%100>spawn->DayChance) {
+ bool day = core->GetGame()->IsDay();
+ int chance = rand() % 100;
+ if ((day && chance > spawn->DayChance) ||
+ (!day && chance > spawn->NightChance)) {
+ spawn->NextSpawn = time + spawn->Frequency * AI_UPDATE_TIME * 60;
+ spawn->Method |= SPF_WAIT;
return;
}
- // the difficulty check is done in SpawnCreature
//create spawns
- for(unsigned int i = 0;i<spawn->Count;i++) {
- SpawnCreature(spawn->Pos, spawn->Creatures[i], 0);
+ int difficulty = spawn->Difficulty * core->GetGame()->GetPartyLevel(true);
+ unsigned int spawncount = 0, i = 0;
+ while (difficulty >= 0 && spawncount < spawn->Maximum) {
+ if (!SpawnCreature(spawn->Pos, spawn->Creatures[i], 0, 0, &difficulty, &spawncount)) {
+ break;
+ }
+ if (++i >= spawn->Count) {
+ i = 0;
+ }
+
}
//disable spawnpoint
- spawn->Enabled = 0;
+ if (spawn->Method & SPF_ONCE || !(spawn->Method & SPF_NOSPAWN)) {
+ spawn->Enabled = 0;
+ } else {
+ spawn->NextSpawn = time + spawn->Frequency * AI_UPDATE_TIME * 60;
+ spawn->Method |= SPF_WAIT;
+ }
+}
+
+void Map::UpdateSpawns()
+{
+ ieDword time = core->GetGame()->GameTime;
+ for (std::vector<Spawn *>::iterator it = spawns.begin() ; it != spawns.end(); ++it) {
+ Spawn *spawn = *it;
+ if ((spawn->Method & (SPF_NOSPAWN|SPF_WAIT)) == (SPF_NOSPAWN|SPF_WAIT)) {
+ //only reactivate the spawn point if the party cannot currently see it
+ if (spawn->NextSpawn < time && !IsVisible(spawn->Pos, false)) {
+ spawn->Method &= ~SPF_WAIT;
+ }
+ }
+ }
}
//--------restheader----------------
@@ -2976,35 +3126,40 @@ current) is compared against (party level * rest header difficulty). If it's
greater, the spawning is aborted. If all the other conditions are true, at
least one creature is summoned, regardless the difficulty cap.
*/
-bool Map::Rest(const Point &pos, int hours, int day)
+int Map::CheckRestInterruptsAndPassTime(const Point &pos, int hours, int day)
{
if (!RestHeader.CreatureNum || !RestHeader.Enabled || !RestHeader.Maximum) {
- return false;
+ core->GetGame()->AdvanceTime(hours*300*AI_UPDATE_TIME);
+ return 0;
}
//based on ingame timer
int chance=day?RestHeader.DayChance:RestHeader.NightChance;
- int spawncount = 1;
+ bool interrupt = rand()%100 < chance;
+ unsigned int spawncount = 0;
int spawnamount = core->GetGame()->GetPartyLevel(true) * RestHeader.Difficulty;
if (spawnamount < 1) spawnamount = 1;
for (int i=0;i<hours;i++) {
- if ( rand()%100<chance ) {
+ if (interrupt) {
int idx = rand()%RestHeader.CreatureNum;
Actor *creature = gamedata->GetCreature(RestHeader.CreResRef[idx]);
- if (!creature) continue;
- // ensure a minimum power level, since many creatures have this as 0
- int cpl = creature->Modified[IE_XP] ? creature->Modified[IE_XP] : 1;
+ if (!creature) {
+ core->GetGame()->AdvanceTime(300*AI_UPDATE_TIME);
+ continue;
+ }
- displaymsg->DisplayString( RestHeader.Strref[idx], 0x00404000, IE_STR_SOUND );
- while (spawnamount > 0 && spawncount <= RestHeader.Maximum) {
- SpawnCreature(pos, RestHeader.CreResRef[idx], 20);
- spawnamount -= cpl;
- spawncount++;
+ displaymsg->DisplayString( RestHeader.Strref[idx], DMC_GOLD, IE_STR_SOUND );
+ while (spawnamount > 0 && spawncount < RestHeader.Maximum) {
+ if (!SpawnCreature(pos, RestHeader.CreResRef[idx], 20, 20, &spawnamount, &spawncount)) {
+ break;
+ }
}
- return true;
+ return hours-i;
}
+ // advance the time in hourly steps, so an interruption is timed properly
+ core->GetGame()->AdvanceTime(300*AI_UPDATE_TIME);
}
- return false;
+ return 0;
}
//--------explored bitmap-----------
@@ -3239,10 +3394,57 @@ void Map::MoveVisibleGroundPiles(const Point &Pos)
unsigned int i=c->inventory.GetSlotCount();
while (i--) {
CREItem *item = c->RemoveItem(i, 0);
- othercontainer->AddItem(item);
+ int count = othercontainer->inventory.CountItems(item->ItemResRef, 0);
+ if (count == 0) {
+ othercontainer->AddItem(item);
+ continue;
+ }
+ // ensure slots are stacked fully before adding new ones
+ int skipped = count;
+ while (count) {
+ int slot = othercontainer->inventory.FindItem(item->ItemResRef, 0, --count);
+ CREItem *otheritem = othercontainer->inventory.GetSlotItem(slot);
+ if (otheritem->Usages[0] == otheritem->MaxStackAmount) {
+ // already full (or nonstackable), nothing to do here
+ skipped--;
+ continue;
+ }
+ if (othercontainer->inventory.MergeItems(slot, item) != ASI_SUCCESS) {
+ // the merge either failed (add whole) or went over the limit (add remainder)
+ othercontainer->AddItem(item);
+ }
+ skipped = 1; // just in case we would be eligible for the safety net below
+ break;
+ }
+ // all found slots were already unsuitable, so just dump the item to a new one
+ if (!skipped) {
+ othercontainer->AddItem(item);
+ }
}
}
}
+
+ // reshuffle the items so they are sorted
+ unsigned int i = othercontainer->inventory.GetSlotCount();
+ if (i < 3) {
+ // nothing to do
+ return;
+ }
+
+ // sort by removing all items that have copies and readding them at the end
+ while (i--) {
+ CREItem *item = othercontainer->inventory.GetSlotItem(i);
+ int count = othercontainer->inventory.CountItems(item->ItemResRef, 0);
+ if (count == 1) continue;
+
+ while (count) {
+ int slot = othercontainer->inventory.FindItem(item->ItemResRef, 0, --count);
+ assert (slot != -1);
+ // containers don't really care about position, so every new item is placed at the last spot
+ CREItem *item = othercontainer->RemoveItem(slot, 0);
+ othercontainer->AddItem(item);
+ }
+ }
}
Container *Map::GetPile(Point position)
@@ -3313,14 +3515,16 @@ bool Map::HasWeather()
if ((AreaType & (AT_WEATHER|AT_OUTDOOR) ) != (AT_WEATHER|AT_OUTDOOR) ) {
return false;
}
- return true;
+ ieDword tmp = 1;
+ core->GetDictionary()->Lookup("Weather", tmp);
+ return !!tmp;
}
int Map::GetWeather()
{
if (Rain>=core->Roll(1,100,0) ) {
if (Lightning>=core->Roll(1,100,0) ) {
- return WB_LIGHTNING|WB_RAIN;
+ return WB_RARELIGHTNING|WB_RAIN;
}
return WB_RAIN;
}
@@ -3438,22 +3642,22 @@ bool Map::DisplayTrackString(Actor *target)
int skill = target->GetStat(IE_TRACKING);
skill += (target->GetStat(IE_LEVEL)/3)*5 + target->GetStat(IE_WIS)*5;
if (core->Roll(1, 100, trackDiff) > skill) {
- displaymsg->DisplayConstantStringName(STR_TRACKINGFAILED, 0xd7d7be, target);
+ displaymsg->DisplayConstantStringName(STR_TRACKINGFAILED, DMC_LIGHTGREY, target);
return true;
}
if (trackFlag) {
char * str = core->GetString( trackString);
core->GetTokenDictionary()->SetAt( "CREATURE", str);
- displaymsg->DisplayConstantStringName(STR_TRACKING, 0xd7d7be, target);
+ displaymsg->DisplayConstantStringName(STR_TRACKING, DMC_LIGHTGREY, target);
return false;
}
- displaymsg->DisplayStringName(trackString, 0xd7d7be, target, 0);
+ displaymsg->DisplayStringName(trackString, DMC_LIGHTGREY, target, 0);
return false;
}
// returns a lightness level in the range of [0-100]
// since the lightmap is much smaller than the area, we need to interpolate
-unsigned int Map::GetLightLevel(const Point &Pos)
+unsigned int Map::GetLightLevel(const Point &Pos) const
{
Color c = LightMap->GetPixel(Pos.x/16, Pos.y/12);
// at night/dusk/dawn the lightmap color is adjusted by the color overlay. (Only get's darker.)
@@ -3498,7 +3702,7 @@ Animation *AreaAnimation::GetAnimationPiece(AnimationFactory *af, int animCycle)
if (!anim)
anim = af->GetCycle( 0 );
if (!anim) {
- printf("Cannot load animation: %s\n", BAM);
+ print("Cannot load animation: %s", BAM);
return NULL;
}
//this will make the animation stop when the game is stopped
@@ -3520,7 +3724,7 @@ void AreaAnimation::InitAnimation()
AnimationFactory* af = ( AnimationFactory* )
gamedata->GetFactoryResource( BAM, IE_BAM_CLASS_ID );
if (!af) {
- printf("Cannot load animation: %s\n", BAM);
+ print("Cannot load animation: %s", BAM);
return;
}
@@ -3597,29 +3801,39 @@ bool AreaAnimation::Schedule(ieDword gametime) const
int AreaAnimation::GetHeight() const
{
if (Flags&A_ANI_BACKGROUND) return -9999;
+ if (core->HasFeature(GF_IMPLICIT_AREAANIM_BACKGROUND) && height <= 0)
+ return -9999;
return Pos.y+height;
- //FIXME: this is obviously a hack that is destined to crash, also useless, so
- //See ar9101 in HoW and ar0602 in bg2 before committing anything
- //return Pos.y+height-animation[0][0].GetFrame(0)->Height;
}
+
void AreaAnimation::Draw(const Region &screen, Map *area)
{
Video* video = core->GetVideoDriver();
//always draw the animation tinted because tint is also used for
//transparency
- Color tint = {255,255,255,255-(ieByte) transparency};
+ ieByte inverseTransparency = 255-transparency;
+ Color tint = {255,255,255,inverseTransparency};
if ((Flags&A_ANI_NO_SHADOW)) {
tint = area->LightMap->GetPixel( Pos.x / 16, Pos.y / 12);
- tint.a = 255-(ieByte) transparency;
+ tint.a = inverseTransparency;
}
- if (!(Flags&A_ANI_NO_WALL)) {
- if (!covers) {
- covers=(SpriteCover **) calloc( animcount, sizeof(SpriteCover *) );
- }
+ bool covered = true;
+
+ // TODO: This needs more testing. The HOW ar9101 roast seems to need it.
+ // The conditional on height<=0 is unverified.
+ if (core->HasFeature(GF_IMPLICIT_AREAANIM_BACKGROUND) && height <= 0)
+ covered = false;
+
+ if (Flags&A_ANI_NO_WALL)
+ covered = false;
+
+ if (covered && !covers) {
+ covers=(SpriteCover **) calloc( animcount, sizeof(SpriteCover *) );
}
+
int ac = animcount;
while (ac--) {
Animation *anim = animation[ac];
@@ -3627,6 +3841,8 @@ void AreaAnimation::Draw(const Region &screen, Map *area)
if(covers) {
if(!covers[ac] || !covers[ac]->Covers(Pos.x, Pos.y, frame->XPos, frame->YPos, frame->Width, frame->Height)) {
delete covers[ac];
+ // TODO: Should this build a sprite cover with base point
+ // Pos.x,Pos.y, or with Pos.y,Pos.y+height ?
covers[ac] = area->BuildSpriteCover(Pos.x, Pos.y, -anim->animArea.x,
-anim->animArea.y, anim->animArea.w, anim->animArea.h, 0);
}
@@ -3651,7 +3867,7 @@ bool Map::ChangeMap(bool day_or_night)
//using the ARE class for this because ChangeMap is similar to LoadMap
//it loads the lightmap and the minimap too, besides swapping the tileset
if (!mM->ChangeMap(this, day_or_night) && !day_or_night) {
- printMessage("Map", "Invalid night lightmap, falling back to day lightmap.\n", YELLOW);
+ Log(WARNING, "Map", "Invalid night lightmap, falling back to day lightmap.");
mM->ChangeMap(this, 1);
DayNight = day_or_night;
}
@@ -3664,34 +3880,42 @@ void Map::SeeSpellCast(Scriptable *caster, ieDword spell)
return;
}
- LastCasterSeen = caster->GetGlobalID();
- LastSpellSeen = spell;
+ // FIXME: this seems clearly wrong, but matches old gemrb behaviour
+ unsigned short triggerType = trigger_spellcast;
+ if (spell >= 3000)
+ triggerType = trigger_spellcastinnate;
+ else if (spell < 2000)
+ triggerType = trigger_spellcastpriest;
+
+ caster->AddTrigger(TriggerEntry(triggerType, caster->GetGlobalID(), spell));
size_t i = actors.size();
while (i--) {
Actor* witness = actors[i];
if (CanSee(witness, caster, true, 0)) {
- witness->LastSpellSeen=LastSpellSeen;
- witness->LastCasterSeen=LastCasterSeen;
+ caster->AddTrigger(TriggerEntry(triggerType, caster->GetGlobalID(), spell));
}
}
}
-short unsigned int Map::GetInternalSearchMap(int x, int y) {
+short unsigned int Map::GetInternalSearchMap(int x, int y) const
+{
if ((unsigned)x >= Width || (unsigned)y >= Height) {
return 0;
}
return SrchMap[x+y*Width];
}
-void Map::SetInternalSearchMap(int x, int y, int value) {
+void Map::SetInternalSearchMap(int x, int y, int value)
+{
if ((unsigned)x >= Width || (unsigned)y >= Height) {
return;
}
SrchMap[x+y*Width] = value;
}
-void Map::SetBackground(const ieResRef &bgResRef, ieDword duration) {
+void Map::SetBackground(const ieResRef &bgResRef, ieDword duration)
+{
Video* video = core->GetVideoDriver();
ResourceHolder<ImageMgr> bmp(bgResRef);
@@ -3702,3 +3926,6 @@ void Map::SetBackground(const ieResRef &bgResRef, ieDword duration) {
Background = bmp->GetSprite2D();
BgDuration = duration;
}
+
+}
+
diff --git a/gemrb/core/Map.h b/gemrb/core/Map.h
index 7e830c6..df535fc 100644
--- a/gemrb/core/Map.h
+++ b/gemrb/core/Map.h
@@ -18,39 +18,46 @@
*
*/
-class Map;
-
#ifndef MAP_H
#define MAP_H
#include "exports.h"
#include "globals.h"
-#include "Bitmap.h"
-#include "Image.h"
-#include "IniSpawn.h"
-#include "SpriteCover.h"
#include "Scriptable/Scriptable.h"
#include <queue>
+namespace GemRB {
+
class Actor;
class Ambient;
class Animation;
class AnimationFactory;
+class Bitmap;
+class CREItem;
class GameControl;
+class Image;
+class IniSpawn;
+class Palette;
class Particles;
struct PathNode;
class Projectile;
class ScriptedAnimation;
+class SpriteCover;
class TileMap;
class Wall_Polygon;
//distance of actors from spawn point
#define SPAWN_RANGE 400
+//spawn flags
+#define SPF_NOSPAWN 0x0001 //if set don't span if WAIT is set
+#define SPF_ONCE 0x0002 //only spawn a single time
+#define SPF_WAIT 0x0004 //spawn temporarily disabled
+
//area flags
-#define AF_SAVE 1
+#define AF_NOSAVE 1
#define AF_TUTORIAL 2
#define AF_DEADMAGIC 4
#define AF_DREAM 8
@@ -71,7 +78,7 @@ class Wall_Polygon;
#define A_ANI_NO_SHADOW 4 //lightmap doesn't affect it
#define A_ANI_PLAYONCE 8 //stop after endframe
#define A_ANI_SYNC 16 //synchronised draw (skip frames if needed)
-#define A_ANI_32 32
+#define A_ANI_RANDOM_START 32 //starts with a random frame in the start range
#define A_ANI_NO_WALL 64 //draw after walls (walls don't cover it)
#define A_ANI_NOT_IN_FOG 0x80 //not visible in fog of war
#define A_ANI_BACKGROUND 0x100 //draw before actors (actors cover it)
@@ -83,6 +90,17 @@ class Wall_Polygon;
//creature area flags
#define AF_CRE_NOT_LOADED 1
#define AF_NAME_OVERRIDE 8
+//same flags in IWD2
+#define AF_SEEN_PARTY 2
+#define AF_INVULNERABLE 4
+#define AF_ENABLED 8
+
+//direction flags (used in AreaLinks)
+#define ADIRF_NORTH 0x01
+#define ADIRF_EAST 0x02
+#define ADIRF_SOUTH 0x04
+#define ADIRF_WEST 0x08
+#define ADIRF_CENTER 0x10 //not in the original engine
//getline flags
#define GL_NORMAL 0
@@ -126,7 +144,7 @@ public:
Point Pos;
ieWord color;
char *text;
- MapNote() { text=NULL; }
+ MapNote() { text=NULL; strref=0; Pos.empty(); color=0; }
~MapNote() { if(text) free(text); }
};
@@ -146,7 +164,8 @@ public:
ieDword appearance;
ieWord DayChance;
ieWord NightChance;
- Spawn() { Creatures=NULL; }
+ ieDword NextSpawn;
+ Spawn() { Creatures=NULL; NextSpawn = 0; }
~Spawn() { if(Creatures) free(Creatures); }
unsigned int GetCreatureCount() { return Count; }
};
@@ -189,7 +208,7 @@ public:
ieWord transparency;
ieWordSigned height;
//these are on one dword
- ieWord unknown3c;
+ ieWord startFrameRange;
ieByte skipcycle;
ieByte startchance;
ieDword unknown48;
@@ -247,6 +266,7 @@ public:
ieResRef Dream[2];
Sprite2D *Background;
ieDword BgDuration;
+ ieDword LastGoCloser;
private:
ieStrRef trackString;
@@ -276,7 +296,7 @@ public:
static void ReleaseMemory();
/** prints useful information on console */
- void DebugDump(bool show_actors=0) const;
+ void dump(bool show_actors=0) const;
TileMap *GetTileMap() { return TMap; }
/* gets the signal of daylight changes */
bool ChangeMap(bool day_or_night);
@@ -324,7 +344,11 @@ public:
void ActivateWallgroups(unsigned int baseindex, unsigned int count, int flg);
void Shout(Actor* actor, int shoutID, unsigned int radius);
void ActorSpottedByPlayer(Actor *actor);
- void AddActor(Actor* actor);
+ void InitActors();
+ void InitActor(Actor *actor);
+ void AddActor(Actor* actor, bool init);
+ //counts the summons already in the area
+ int CountSummons(ieDword flag, ieDword sex);
//returns true if an enemy is near P (used in resting/saving)
bool AnyEnemyNearPoint(const Point &p);
bool GetBlocked(unsigned int x, unsigned int y, unsigned int size);
@@ -336,7 +360,7 @@ public:
Actor* GetActorByGlobalID(ieDword objectID);
Actor* GetActor(const Point &p, int flags);
Actor* GetActorInRadius(const Point &p, int flags, unsigned int radius);
- Actor **GetAllActorsInRadius(const Point &p, int flags, unsigned int radius);
+ Actor **GetAllActorsInRadius(const Point &p, int flags, unsigned int radius, Scriptable *see=NULL);
Actor* GetActor(const char* Name, int flags);
Actor* GetActor(int i, bool any);
Actor* GetActorByDialog(const char* resref);
@@ -412,7 +436,7 @@ public:
void UpdateFog();
//PathFinder
/* Finds the nearest passable point */
- void AdjustPosition(Point &goal, unsigned int radius=0);
+ void AdjustPosition(Point &goal, unsigned int radiusx=0, unsigned int radiusy=0);
/* Finds the path which leads the farthest from d */
PathNode* RunAway(const Point &s, const Point &d, unsigned int size, unsigned int PathLen, int flags);
/* Returns true if there is no path to d */
@@ -430,7 +454,7 @@ public:
/* returns false if point isn't visible on visibility/explored map */
bool IsVisible(const Point &s, int explored);
/* returns false if point d cannot be seen from point d due to searchmap */
- bool IsVisible(const Point &s, const Point &d);
+ bool IsVisibleLOS(const Point &s, const Point &d);
/* returns edge direction of map boundary, only worldmap regions */
int WhichEdge(const Point &s);
@@ -447,10 +471,10 @@ public:
MapNote *GetMapNote(const Point &point);
unsigned int GetMapNoteCount() { return (unsigned int) mapnotes.size(); }
//restheader
- /* May spawn creature(s), returns true in case of an interrupted rest */
- bool Rest(const Point &pos, int hours, int day);
+ /* May spawn creature(s), returns the remaining number of (unrested) hours for interrupted rest */
+ int CheckRestInterruptsAndPassTime(const Point &pos, int hours, int day);
/* Spawns creature(s) in radius of position */
- void SpawnCreature(const Point &pos, const char *CreName, int radius = 0);
+ bool SpawnCreature(const Point &pos, const char *creResRef, int radiusx = 0, int radiusy = 0, int *difficulty = NULL, unsigned int *creCount = NULL);
//spawns
void LoadIniSpawn();
@@ -463,16 +487,20 @@ public:
Spawn *GetSpawnRadius(const Point &point, unsigned int radius);
unsigned int GetSpawnCount() { return (unsigned int) spawns.size(); }
void TriggerSpawn(Spawn *spawn);
+
//move some or all players to a new area
void MoveToNewArea(const char *area, const char *entrance, unsigned int direction, int EveryOne, Actor *actor);
bool HasWeather();
int GetWeather();
void ClearTrap(Actor *actor, ieDword InTrap);
+
+ //tracking stuff
void SetTrackString(ieStrRef strref, int flg, int difficulty);
//returns true if tracking failed
bool DisplayTrackString(Actor *actor);
- unsigned int GetLightLevel(const Point &Pos);
- unsigned short GetInternalSearchMap(int x, int y);
+
+ unsigned int GetLightLevel(const Point &Pos) const;
+ unsigned short GetInternalSearchMap(int x, int y) const;
void SetInternalSearchMap(int x, int y, int value);
void SetBackground(const ieResRef &bgResref, ieDword duration);
private:
@@ -491,9 +519,12 @@ private:
//actor uses travel region
void UseExit(Actor *pc, InfoPoint *ip);
//separated position adjustment, so their order could be randomised */
- bool AdjustPositionX(Point &goal, unsigned int radius);
- bool AdjustPositionY(Point &goal, unsigned int radius);
+ bool AdjustPositionX(Point &goal, unsigned int radiusx, unsigned int radiusy);
+ bool AdjustPositionY(Point &goal, unsigned int radiusx, unsigned int radiusy);
void DrawPortal(InfoPoint *ip, int enable);
+ void UpdateSpawns();
};
+}
+
#endif
diff --git a/gemrb/core/MapMgr.cpp b/gemrb/core/MapMgr.cpp
index dba36b2..743b3d8 100644
--- a/gemrb/core/MapMgr.cpp
+++ b/gemrb/core/MapMgr.cpp
@@ -20,6 +20,8 @@
#include "MapMgr.h"
+namespace GemRB {
+
MapMgr::MapMgr(void)
{
}
@@ -27,3 +29,5 @@ MapMgr::MapMgr(void)
MapMgr::~MapMgr(void)
{
}
+
+}
diff --git a/gemrb/core/MapMgr.h b/gemrb/core/MapMgr.h
index c709e70..4ef3d85 100644
--- a/gemrb/core/MapMgr.h
+++ b/gemrb/core/MapMgr.h
@@ -27,10 +27,12 @@
#ifndef MAPMGR_H
#define MAPMGR_H
-#include "Map.h"
#include "Plugin.h"
-#include "Scriptable/Scriptable.h"
-#include "System/DataStream.h"
+
+namespace GemRB {
+
+class DataStream;
+class Map;
/**
* @class MapMgr
@@ -41,7 +43,7 @@ class GEM_EXPORT MapMgr : public Plugin {
public:
MapMgr(void);
virtual ~MapMgr(void);
- virtual bool Open(DataStream* stream, bool autoFree = true) = 0;
+ virtual bool Open(DataStream* stream) = 0;
virtual bool ChangeMap(Map *map, bool day_or_night) = 0;
virtual Map* GetMap(const char* ResRef, bool day_or_night) = 0;
@@ -49,4 +51,6 @@ public:
virtual int PutArea(DataStream* stream, Map *map) = 0;
};
+}
+
#endif
diff --git a/gemrb/core/MoviePlayer.cpp b/gemrb/core/MoviePlayer.cpp
index f171681..1cbb62a 100644
--- a/gemrb/core/MoviePlayer.cpp
+++ b/gemrb/core/MoviePlayer.cpp
@@ -20,6 +20,8 @@
#include "MoviePlayer.h"
+namespace GemRB {
+
const TypeID MoviePlayer::ID = { "MoviePlayer" };
MoviePlayer::MoviePlayer(void)
@@ -29,3 +31,5 @@ MoviePlayer::MoviePlayer(void)
MoviePlayer::~MoviePlayer(void)
{
}
+
+}
diff --git a/gemrb/core/MoviePlayer.h b/gemrb/core/MoviePlayer.h
index b52a3fc..39b34b3 100644
--- a/gemrb/core/MoviePlayer.h
+++ b/gemrb/core/MoviePlayer.h
@@ -33,6 +33,8 @@
#include "Resource.h"
+namespace GemRB {
+
/**
* @class MoviePlayer
* Abstract loader and player for videos
@@ -47,4 +49,6 @@ public:
virtual void CallBackAtFrames(ieDword cnt, ieDword *frames, ieDword *strrefs) = 0;
};
+}
+
#endif
diff --git a/gemrb/core/MusicMgr.cpp b/gemrb/core/MusicMgr.cpp
index 592b84b..72720ce 100644
--- a/gemrb/core/MusicMgr.cpp
+++ b/gemrb/core/MusicMgr.cpp
@@ -20,6 +20,8 @@
#include "MusicMgr.h"
+namespace GemRB {
+
MusicMgr::MusicMgr()
{
}
@@ -31,3 +33,5 @@ bool MusicMgr::Init()
{
return true;
}
+
+}
diff --git a/gemrb/core/MusicMgr.h b/gemrb/core/MusicMgr.h
index 0386500..c0581bf 100644
--- a/gemrb/core/MusicMgr.h
+++ b/gemrb/core/MusicMgr.h
@@ -23,6 +23,8 @@
#include "Plugin.h"
+namespace GemRB {
+
class GEM_EXPORT MusicMgr : public Plugin {
public:
MusicMgr();
@@ -46,4 +48,6 @@ public:
virtual bool CurrentPlayList(const char* name) = 0;
};
+}
+
#endif
diff --git a/gemrb/core/Palette.cpp b/gemrb/core/Palette.cpp
index 11690f1..e866b1c 100644
--- a/gemrb/core/Palette.cpp
+++ b/gemrb/core/Palette.cpp
@@ -22,6 +22,8 @@
#include "Interface.h"
+namespace GemRB {
+
#define MINCOL 2
#define MUL 2
@@ -47,6 +49,16 @@ void Palette::CreateShadedAlphaChannel()
alpha = true;
}
+void Palette::Brighten()
+{
+ for (int i = 0; i<256;i++) {
+ col[i].r = (col[i].r+256)/2;
+ col[i].g = (col[i].g+256)/2;
+ col[i].b = (col[i].b+256)/2;
+ col[i].a = (col[i].a+256)/2;
+ }
+}
+
Palette* Palette::Copy()
{
Palette* pal = new Palette(col, alpha);
@@ -241,3 +253,5 @@ void Palette::SetupGlobalRGBModification(const Palette* src,
for (i = 2; i < 256; ++i)
applyMod(src->col[i],col[i],mod);
}
+
+}
diff --git a/gemrb/core/Palette.h b/gemrb/core/Palette.h
index ba857d1..6d5781e 100644
--- a/gemrb/core/Palette.h
+++ b/gemrb/core/Palette.h
@@ -26,6 +26,8 @@
#include <cassert>
+namespace GemRB {
+
enum PaletteType {
PAL_MAIN,
PAL_WEAPON,
@@ -85,6 +87,7 @@ public:
}
void CreateShadedAlphaChannel();
+ void Brighten();
void SetupPaperdollColours(const ieDword* Colors, unsigned int type);
void SetupRGBModification(const Palette* src, const RGBModifier* mods,
@@ -99,4 +102,6 @@ private:
};
+}
+
#endif
diff --git a/gemrb/core/PalettedImageMgr.cpp b/gemrb/core/PalettedImageMgr.cpp
index 8851760..14459fb 100644
--- a/gemrb/core/PalettedImageMgr.cpp
+++ b/gemrb/core/PalettedImageMgr.cpp
@@ -18,6 +18,8 @@
#include "PalettedImageMgr.h"
+namespace GemRB {
+
const TypeID PalettedImageMgr::ID = { "PalettedImageMgr" };
PalettedImageMgr::PalettedImageMgr(void)
@@ -27,3 +29,5 @@ PalettedImageMgr::PalettedImageMgr(void)
PalettedImageMgr::~PalettedImageMgr(void)
{
}
+
+}
diff --git a/gemrb/core/PalettedImageMgr.h b/gemrb/core/PalettedImageMgr.h
index f6ea798..4aed266 100644
--- a/gemrb/core/PalettedImageMgr.h
+++ b/gemrb/core/PalettedImageMgr.h
@@ -23,6 +23,8 @@
#include "Sprite2D.h"
#include "System/DataStream.h"
+namespace GemRB {
+
class ImageFactory;
/**
@@ -46,4 +48,6 @@ public:
virtual Sprite2D* GetSprite2D(unsigned int type, ieDword paletteIndex[8]) = 0;
};
+}
+
#endif
diff --git a/gemrb/core/Particles.cpp b/gemrb/core/Particles.cpp
index ce3195f..df519c7 100644
--- a/gemrb/core/Particles.cpp
+++ b/gemrb/core/Particles.cpp
@@ -20,9 +20,13 @@
#include "Particles.h"
+#include "CharAnimations.h"
+#include "Game.h"
#include "Interface.h"
+#include "TableMgr.h"
#include "Video.h"
-#include "Game.h"
+
+namespace GemRB {
Color sparkcolors[MAX_SPARK_COLOR][MAX_SPARK_PHASE];
bool inited = false;
@@ -31,7 +35,7 @@ bool inited = false;
static int spark_color_indices[SPARK_COUNT]={12,5,0,6,1,8,2,7,9,3,4,10,11};
-void TranslateColor(const char *value, Color &color)
+static void TranslateColor(const char *value, Color &color)
{
int r = 0;
int g = 0;
@@ -50,7 +54,7 @@ void TranslateColor(const char *value, Color &color)
color.b=b;
}
-void InitSparks()
+static void InitSparks()
{
int i,j;
AutoTable tab("sprklclr");
@@ -385,3 +389,5 @@ int Particles::Update()
}
return drawn;
}
+
+}
diff --git a/gemrb/core/Particles.h b/gemrb/core/Particles.h
index fb9cf8a..f9ef253 100644
--- a/gemrb/core/Particles.h
+++ b/gemrb/core/Particles.h
@@ -32,6 +32,8 @@
#include "Region.h"
+namespace GemRB {
+
class CharAnimations;
class Scriptable;
@@ -118,7 +120,7 @@ public:
private:
Element *points;
ieDword timetolive;
- ieDword target; //could be 0, in that case target is pos
+// ieDword target; //could be 0, in that case target is pos
ieWord size; //spark number
ieWord last_insert;//last spark idx added
Scriptable *owner; //could be area or game or actor
@@ -134,4 +136,6 @@ private:
CharAnimations *fragments;
};
+}
+
#endif // ! PARTICLES_H
diff --git a/gemrb/core/PathFinder.h b/gemrb/core/PathFinder.h
index b8b6ca7..e4269bb 100644
--- a/gemrb/core/PathFinder.h
+++ b/gemrb/core/PathFinder.h
@@ -20,6 +20,8 @@
#ifndef PATHFINDER_H
#define PATHFINDER_H
+namespace GemRB {
+
//searchmap conversion bits
enum {
@@ -49,4 +51,6 @@ struct PathNode {
unsigned int orient;
};
+}
+
#endif
diff --git a/gemrb/core/Plugin.cpp b/gemrb/core/Plugin.cpp
index 97aa567..7c030be 100644
--- a/gemrb/core/Plugin.cpp
+++ b/gemrb/core/Plugin.cpp
@@ -20,6 +20,8 @@
#include "Plugin.h"
+namespace GemRB {
+
Plugin::Plugin(void)
{
}
@@ -27,3 +29,5 @@ Plugin::Plugin(void)
Plugin::~Plugin(void)
{
}
+
+}
diff --git a/gemrb/core/Plugin.h b/gemrb/core/Plugin.h
index 1212103..a46ed3d 100644
--- a/gemrb/core/Plugin.h
+++ b/gemrb/core/Plugin.h
@@ -31,11 +31,12 @@
#include "exports.h"
#include "Holder.h"
-#include "PluginMgr.h"
#include "TypeID.h"
#include <cstddef>
+namespace GemRB {
+
/**
* @class Plugin
* Base class for all GemRB plugins
@@ -47,19 +48,6 @@ public:
virtual ~Plugin(void);
};
-template <class T>
-class PluginHolder : public Holder<T> {
-public:
- PluginHolder()
- {
- }
- PluginHolder(PluginID id)
- : Holder<T>(static_cast<T*>(PluginMgr::Get()->GetPlugin(id)))
- {
- }
- ~PluginHolder()
- {
- }
-};
+}
#endif
diff --git a/gemrb/core/PluginLoader.cpp b/gemrb/core/PluginLoader.cpp
new file mode 100644
index 0000000..db10401
--- /dev/null
+++ b/gemrb/core/PluginLoader.cpp
@@ -0,0 +1,235 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "PluginLoader.h"
+
+#include "SClassID.h" // For PluginID
+#include "win32def.h"
+
+#include "Variables.h"
+#include "Interface.h"
+#include "PluginMgr.h"
+
+#include <cstdio>
+#include <cstdlib>
+#include <list>
+#include <set>
+
+#ifdef WIN32
+#include <io.h>
+#include <windows.h>
+#else
+#include <sys/types.h>
+#include <dirent.h>
+#include <fnmatch.h>
+#include <dlfcn.h>
+#endif
+
+#ifdef HAVE_FORBIDDEN_OBJECT_TO_FUNCTION_CAST
+# include <assert.h>
+#endif
+
+namespace GemRB {
+
+#ifdef WIN32
+typedef HMODULE LibHandle;
+#else
+typedef void *LibHandle;
+#endif
+
+namespace GemRB {
+
+class PluginMgr;
+
+}
+
+struct PluginDesc {
+ LibHandle handle;
+ PluginID ID;
+ const char *Description;
+ bool (*Register)(PluginMgr*);
+};
+
+typedef const char* (*Version_t)(void);
+typedef const char* (*Description_t)(void);
+typedef PluginID (*ID_t)();
+typedef bool (* Register_t)(PluginMgr*);
+
+#ifdef HAVE_FORBIDDEN_OBJECT_TO_FUNCTION_CAST
+typedef void *(* voidvoid)(void);
+static inline voidvoid my_dlsym(void *handle, const char *symbol)
+{
+ void *value = dlsym(handle,symbol);
+ voidvoid ret;
+ assert(sizeof(ret)==sizeof(value) );
+ memcpy(&ret, &value, sizeof(ret) );
+ return ret;
+}
+#else
+#define my_dlsym dlsym
+#endif
+
+#ifdef WIN32
+#define FREE_PLUGIN( handle ) FreeLibrary( handle )
+#define GET_PLUGIN_SYMBOL( handle, name ) GetProcAddress( handle, name )
+#define PRINT_DLERROR
+#else
+#define FREE_PLUGIN( handle ) dlclose( handle )
+#define GET_PLUGIN_SYMBOL( handle, name ) my_dlsym( handle, name )
+#define PRINT_DLERROR Log(MESSAGE, "PluginLoader", "Error: %s", dlerror() )
+#endif
+
+/** Return names of all *.so or *.dll files in the given directory */
+#ifdef WIN32
+static bool FindFiles( char* path, std::list<char*> &files )
+{
+ //The windows _findfirst/_findnext functions allow the use of wildcards so we'll use them :)
+ struct _finddata_t c_file;
+ long hFile;
+ strcat( path, "*.dll" );
+ if (( hFile = ( long ) _findfirst( path, &c_file ) ) == -1L) //If there is no file matching our search
+ return false;
+
+ do {
+ files.push_back( strdup( c_file.name ));
+ } while (_findnext( hFile, &c_file ) == 0);
+
+ _findclose( hFile );
+ return true;
+}
+
+#else // ! WIN32
+
+bool static FindFiles( char* path, std::list<char*> &files )
+{
+ DirectoryIterator dir(path);
+ if (!dir) //If we cannot open the Directory
+ return false;
+
+ do {
+ const char *name = dir.GetName();
+ if (fnmatch( "*.so", name, 0 ) != 0) //If the current file has no ".so" extension, skip it
+ continue;
+ files.push_back( strdup( name ));
+ } while (++dir);
+
+ return true;
+}
+#endif // ! WIN32
+
+void LoadPlugins(char* pluginpath)
+{
+ std::set<PluginID> libs;
+
+ Log(MESSAGE, "PluginMgr", "Loading Plugins from %s", pluginpath);
+
+ char path[_MAX_PATH];
+ strcpy( path, pluginpath );
+
+ std::list< char * > files;
+ if (! FindFiles( path, files ))
+ return;
+
+ //Iterate through all the available modules to load
+ int file_count = files.size (); // keeps track of first-pass files
+ while (! files.empty()) {
+ char* file = files.front();
+ files.pop_front();
+ file_count--;
+
+ PathJoin( path, pluginpath, file, NULL );
+
+
+ ieDword flags = 0;
+ core->plugin_flags->Lookup (file, flags);
+
+ // module is sent to the back
+ if ((flags == PLF_DELAY) && (file_count >= 0)) {
+ Log(MESSAGE, "PluginLoader", "Loading \"%s\" delayed.", path);
+ files.push_back( file );
+ continue;
+ }
+
+ // module is skipped
+ if (flags == PLF_SKIP) {
+ Log(MESSAGE, "PluginLoader", "Loading \"%s\" skipped.", path);
+ continue;
+ }
+
+
+
+ // Try to load the Module
+#ifdef WIN32
+ HMODULE hMod = LoadLibrary( path );
+#else
+ // Note: the RTLD_GLOBAL is necessary to export symbols to modules
+ // which python may have to dlopen (-wjp, 20060716)
+ // (to reproduce, try 'import bz2' or another .so module)
+ void* hMod = dlopen( path, RTLD_NOW | RTLD_GLOBAL );
+#endif
+ if (hMod == NULL) {
+ Log(ERROR, "PluginLoader", "Cannot Load \"%s\", skipping...", path);
+ PRINT_DLERROR;
+ continue;
+ }
+
+ //printStatus( "OK", LIGHT_GREEN );
+ //using C bindings, so we don't need to jump through extra hoops
+ //with the symbol name
+ Version_t LibVersion = ( Version_t ) GET_PLUGIN_SYMBOL( hMod, "GemRBPlugin_Version" );
+ Description_t Description = ( Description_t ) GET_PLUGIN_SYMBOL( hMod, "GemRBPlugin_Description" );
+ ID_t ID = ( ID_t ) GET_PLUGIN_SYMBOL( hMod, "GemRBPlugin_ID" );
+ Register_t Register = ( Register_t ) GET_PLUGIN_SYMBOL( hMod, "GemRBPlugin_Register" );
+
+ //printMessage( "PluginMgr", "Checking Plugin Version...", WHITE );
+ if (LibVersion==NULL) {
+ Log(ERROR, "PluginLoader", "Skipping invalid plugin \"%s\".", path);
+ FREE_PLUGIN( hMod );
+ continue;
+ }
+ if (strcmp(LibVersion(), VERSION_GEMRB) ) {
+ Log(ERROR, "PluginLoader", "Skipping plugin \"%s\" with version mistmatch.", path);
+ FREE_PLUGIN( hMod );
+ continue;
+ }
+
+ PluginDesc desc = { hMod, ID(), Description(), Register };
+
+ //printStatus( "OK", LIGHT_GREEN );
+ //printMessage( "PluginMgr", "Loading Exports for ", WHITE );
+ if (libs.find(desc.ID) != libs.end()) {
+ Log(WARNING, "PluginLoader", "Plug-in \"%s\" already loaded!", path);
+ FREE_PLUGIN( hMod );
+ continue;
+ }
+ if (desc.Register != NULL) {
+ if (!desc.Register(PluginMgr::Get())) {
+ Log(WARNING, "PluginLoader", "Plugin Registration Failed! Perhaps a duplicate?");
+ FREE_PLUGIN( hMod );
+ }
+ }
+ libs.insert(desc.ID);
+
+ Log(MESSAGE, "PluginLoader", "Loaded plugin \"%s\" (%s).", desc.Description, file);
+
+ // We do not need the basename anymore now
+ free( file );
+ }
+}
+
+}
diff --git a/gemrb/core/PluginLoader.h b/gemrb/core/PluginLoader.h
new file mode 100644
index 0000000..04f87ef
--- /dev/null
+++ b/gemrb/core/PluginLoader.h
@@ -0,0 +1,36 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef PLUGINLOADER_H
+#define PLUGINLOADER_H
+
+namespace GemRB {
+
+/**
+ * Loads GemRB plugins from shared libraries or DLLs.
+ *
+ * It goes over all appropriately named files in PluginPath directory
+ * and tries to load them one after another.
+ */
+void LoadPlugins(char* pluginpath);
+
+}
+
+#endif
diff --git a/gemrb/core/PluginMgr.cpp b/gemrb/core/PluginMgr.cpp
index 8b31b15..0d1459f 100644
--- a/gemrb/core/PluginMgr.cpp
+++ b/gemrb/core/PluginMgr.cpp
@@ -14,60 +14,16 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- *
*/
#include "PluginMgr.h"
#include "win32def.h"
-#include "Interface.h"
#include "Plugin.h"
#include "ResourceDesc.h"
-#include "Variables.h" // FIXME: this should be in Interface.h instead
-
-#include <cstdio>
-#include <cstdlib>
-#ifdef WIN32
-#include <io.h>
-#include <windows.h>
-#else
-#include <sys/types.h>
-#include <dirent.h>
-#include <fnmatch.h>
-#include <dlfcn.h>
-#endif
-typedef const char* (*Version_t)(void);
-typedef const char* (*Description_t)(void);
-typedef PluginID (*ID_t)();
-typedef bool (* Register_t)(PluginMgr*);
-
-#ifdef HAVE_FORBIDDEN_OBJECT_TO_FUNCTION_CAST
-#include <assert.h>
-typedef void *(* voidvoid)(void);
-inline voidvoid my_dlsym(void *handle, const char *symbol)
-{
- void *value = dlsym(handle,symbol);
- voidvoid ret;
- assert(sizeof(ret)==sizeof(value) );
- memcpy(&ret, &value, sizeof(ret) );
- return ret;
-}
-#else
-#define my_dlsym dlsym
-#endif
-
-#ifdef WIN32
-#define FREE_PLUGIN( handle ) FreeLibrary( handle )
-#define GET_PLUGIN_SYMBOL( handle, name ) GetProcAddress( handle, name )
-#define PRINT_DLERROR
-#else
-#define FREE_PLUGIN( handle ) dlclose( handle )
-#define GET_PLUGIN_SYMBOL( handle, name ) my_dlsym( handle, name )
-#define PRINT_DLERROR printf( "%s\n", dlerror() )
-#endif
+namespace GemRB {
PluginMgr *PluginMgr::Get()
{
@@ -79,172 +35,10 @@ PluginMgr::PluginMgr()
{
}
-void PluginMgr::LoadPlugins(char* pluginpath)
+PluginMgr::~PluginMgr()
{
- printMessage( "PluginMgr", "Loading Plugins from ", WHITE );
- printf( "%s\n", pluginpath );
-
- char path[_MAX_PATH];
- strcpy( path, pluginpath );
-
- std::list< char * > files;
- if (! FindFiles( path, files ))
- return;
-
- //Iterate through all the available modules to load
- int file_count = files.size (); // keeps track of first-pass files
- while (! files.empty()) {
- char* file = files.front();
- files.pop_front();
- file_count--;
-
- PathJoin( path, pluginpath, file, NULL );
- printBracket( "PluginMgr", LIGHT_WHITE );
- printf( ": Loading: " );
- textcolor( LIGHT_WHITE );
- printf( "%s", path );
- textcolor( WHITE );
- printf( "..." );
-
-
- ieDword flags = 0;
- core->plugin_flags->Lookup (file, flags);
-
- // module is sent to the back
- if ((flags == PLF_DELAY) && (file_count >= 0)) {
- printStatus( "DELAYING", YELLOW );
- files.push_back( file );
- continue;
- }
-
- // We do not need the basename anymore now
- free( file );
-
- // module is skipped
- if (flags == PLF_SKIP) {
- printStatus( "SKIPPING", YELLOW );
- continue;
- }
-
-
-
- // Try to load the Module
-#ifdef WIN32
- HMODULE hMod = LoadLibrary( path );
-#else
- // Note: the RTLD_GLOBAL is necessary to export symbols to modules
- // which python may have to dlopen (-wjp, 20060716)
- // (to reproduce, try 'import bz2' or another .so module)
- void* hMod = dlopen( path, RTLD_NOW | RTLD_GLOBAL );
-#endif
- if (hMod == NULL) {
- printBracket( "ERROR", LIGHT_RED );
- printf( "\nCannot Load Module, Skipping...\n" );
- PRINT_DLERROR;
- continue;
- }
-
- //printStatus( "OK", LIGHT_GREEN );
- //using C bindings, so we don't need to jump through extra hoops
- //with the symbol name
- Version_t LibVersion = ( Version_t ) GET_PLUGIN_SYMBOL( hMod, "GemRBPlugin_Version" );
- Description_t Description = ( Description_t ) GET_PLUGIN_SYMBOL( hMod, "GemRBPlugin_Description" );
- ID_t ID = ( ID_t ) GET_PLUGIN_SYMBOL( hMod, "GemRBPlugin_ID" );
- Register_t Register = ( Register_t ) GET_PLUGIN_SYMBOL( hMod, "GemRBPlugin_Register" );
-
- //printMessage( "PluginMgr", "Checking Plugin Version...", WHITE );
- if (LibVersion==NULL) {
- printStatus( "ERROR", LIGHT_RED );
- printf( "Invalid Plug-in, Skipping...\n" );
- FREE_PLUGIN( hMod );
- continue;
- }
- if (strcmp(LibVersion(), VERSION_GEMRB) ) {
- printStatus( "ERROR", LIGHT_RED );
- printf( "Plug-in Version not valid, Skipping...\n" );
- FREE_PLUGIN( hMod );
- continue;
- }
-
- PluginDesc desc = { hMod, ID(), Description(), Register };
-
- //printStatus( "OK", LIGHT_GREEN );
- //printMessage( "PluginMgr", "Loading Exports for ", WHITE );
- printf( " " );
- textcolor( LIGHT_WHITE );
- printf( "%s", desc.Description );
- textcolor( WHITE );
- printf( "..." );
- printStatus( "OK", LIGHT_GREEN );
- if (libs.find(desc.ID) != libs.end()) {
- printMessage( "PluginMgr", "Plug-in Already Loaded! ", WHITE );
- printStatus( "SKIPPING", YELLOW );
- FREE_PLUGIN( hMod );
- continue;
- }
- if (desc.Register != NULL) {
- if (!desc.Register(this)) {
- printMessage( "PluginMgr", "Plug-in Registration Failed! Perhaps a duplicate? ", WHITE );
- printStatus( "SKIPPING", YELLOW );
- FREE_PLUGIN( hMod );
- }
- }
- libs[desc.ID] = desc;
- }
}
-PluginMgr::~PluginMgr(void)
-{
-//don't free the shared libraries in debug mode, so valgrind can resolve the stack trace
-#ifndef _DEBUG
- for (unsigned int i = 0; i < libs.size(); i++) {
-#ifdef WIN32
- FreeLibrary(libs[i].handle);
-#else
- // dlclose(libs[i].handle);
-#endif
- }
-#endif
-}
-
-#ifdef WIN32
-bool
-PluginMgr::FindFiles( char* path, std::list<char*> &files )
-{
- //The windows _findfirst/_findnext functions allow the use of wildcards so we'll use them :)
- struct _finddata_t c_file;
- long hFile;
- strcat( path, "*.dll" );
- if (( hFile = ( long ) _findfirst( path, &c_file ) ) == -1L) //If there is no file matching our search
- return false;
-
- do {
- files.push_back( strdup( c_file.name ));
- } while (_findnext( hFile, &c_file ) == 0);
-
- _findclose( hFile );
- return true;
-}
-
-#else // ! WIN32
-
-bool
-PluginMgr::FindFiles( char* path, std::list<char*> &files )
-{
- DirectoryIterator dir(path);
- if (!dir) //If we cannot open the Directory
- return false;
-
- do {
- const char *name = dir.GetName();
- if (fnmatch( "*.so", name, 0 ) != 0) //If the current file has no ".so" extension, skip it
- continue;
- files.push_back( strdup( name ));
- } while (++dir);
-
- return true;
-}
-#endif // ! WIN32
bool PluginMgr::IsAvailable(SClass_ID plugintype) const
{
@@ -319,3 +113,5 @@ Plugin* PluginMgr::GetDriver(const TypeID* type, const char* name)
return iter->second();
return map.begin()->second();
}
+
+}
diff --git a/gemrb/core/PluginMgr.h b/gemrb/core/PluginMgr.h
index ff0d88c..6451fa0 100644
--- a/gemrb/core/PluginMgr.h
+++ b/gemrb/core/PluginMgr.h
@@ -32,6 +32,7 @@
#include "globals.h"
#include "iless.h"
#include "win32def.h"
+#include "Holder.h"
#include "ResourceDesc.h"
@@ -40,11 +41,7 @@
#include <map>
#include <vector>
-#ifdef WIN32
-typedef HINSTANCE LibHandle;
-#else
-typedef void *LibHandle;
-#endif
+namespace GemRB {
class Plugin;
class Resource;
@@ -64,19 +61,11 @@ public:
public:
/** Return global instance of PluginMgr */
static PluginMgr* Get();
- void LoadPlugins(char* pluginpath);
private:
PluginMgr();
public: // HACK: MSVC6 is buggy.
- ~PluginMgr(void);
+ ~PluginMgr();
private:
- struct PluginDesc {
- LibHandle handle;
- PluginID ID;
- const char *Description;
- bool (*Register)(PluginMgr*);
- };
- std::map< PluginID, PluginDesc> libs;
std::map< SClass_ID, PluginFunc> plugins;
std::map< const TypeID*, std::vector<ResourceDesc> > resources;
/** Array of initializer functions */
@@ -86,12 +75,10 @@ private:
typedef std::map<const char*, PluginFunc, iless> driver_map;
std::map<const TypeID*, driver_map> drivers;
public:
- /** Return names of all *.so or *.dll files in the given directory */
- bool FindFiles( char* path, std::list< char* > &files);
+ size_t GetPluginCount() const { return plugins.size(); }
bool IsAvailable(SClass_ID plugintype) const;
Plugin* GetPlugin(SClass_ID plugintype) const;
- size_t GetPluginCount() const { return plugins.size(); }
/**
* Register class plugin.
@@ -150,4 +137,21 @@ public:
Plugin* GetDriver(const TypeID* type, const char* name);
};
+template <class T>
+class PluginHolder : public Holder<T> {
+public:
+ PluginHolder()
+ {
+ }
+ PluginHolder(PluginID id)
+ : Holder<T>(static_cast<T*>(PluginMgr::Get()->GetPlugin(id)))
+ {
+ }
+ ~PluginHolder()
+ {
+ }
+};
+
+}
+
#endif
diff --git a/gemrb/core/Polygon.cpp b/gemrb/core/Polygon.cpp
index 2128a1d..23b02ef 100644
--- a/gemrb/core/Polygon.cpp
+++ b/gemrb/core/Polygon.cpp
@@ -27,6 +27,8 @@
#include <cstring>
#include <vector>
+namespace GemRB {
+
Gem_Polygon::Gem_Polygon(Point* points, unsigned int cnt, Region *bbox)
{
if (cnt) {
@@ -123,20 +125,20 @@ bool Gem_Polygon::PointIn(int tx, int ty) const
// returns twice the area of triangle a, b, c.
// (can also be negative depending on orientation of a,b,c)
-inline int area2(const Point& a, const Point& b, const Point& c)
+static inline int area2(const Point& a, const Point& b, const Point& c)
{
return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
}
// return (c is to the left of a-b)
-inline bool left(const Point& a, const Point& b, const Point& c)
+static inline bool left(const Point& a, const Point& b, const Point& c)
{
return (area2(a, b, c) > 0);
}
// { return (c is collinear with a-b)
-inline bool collinear(const Point& a, const Point& b, const Point& c)
+static inline bool collinear(const Point& a, const Point& b, const Point& c)
{
return (area2(a, b, c) == 0);
}
@@ -219,15 +221,13 @@ struct ScanlineInt {
};
-
void Gem_Polygon::ComputeTrapezoids()
{
if (count < 3) return;
//the loader never should load such a large polygon,
//because the polygon count is supposed to be a 16 bit value
if (count > 65535) {
- printMessage("Polygon", "Invalid Polygon!\n", LIGHT_RED);
- abort();
+ error("Polygon", "Invalid Polygon!\n");
}
trapezoids.clear();
@@ -385,3 +385,5 @@ bool Wall_Polygon::PointCovered(int tx, int ty) const
return PointCovered(p);
}
+
+}
diff --git a/gemrb/core/Polygon.h b/gemrb/core/Polygon.h
index 505a91f..1db144f 100644
--- a/gemrb/core/Polygon.h
+++ b/gemrb/core/Polygon.h
@@ -27,6 +27,8 @@
#include <list>
+namespace GemRB {
+
class GEM_EXPORT Trapezoid {
public:
int y1, y2;
@@ -78,4 +80,6 @@ public:
Point base0, base1;
};
+}
+
#endif
diff --git a/gemrb/core/PolymorphCache.h b/gemrb/core/PolymorphCache.h
index b97c11b..2c8cf0d 100644
--- a/gemrb/core/PolymorphCache.h
+++ b/gemrb/core/PolymorphCache.h
@@ -21,6 +21,8 @@
#include "ie_types.h"
+namespace GemRB {
+
struct GEM_EXPORT PolymorphCache {
ieResRef Resource;
ieDword *stats;
@@ -31,4 +33,6 @@ struct GEM_EXPORT PolymorphCache {
}
};
+}
+
#endif
diff --git a/gemrb/core/Projectile.cpp b/gemrb/core/Projectile.cpp
index b63f075..34462dd 100644
--- a/gemrb/core/Projectile.cpp
+++ b/gemrb/core/Projectile.cpp
@@ -22,17 +22,23 @@
#include "win32def.h"
-#include "Audio.h"
+#include "AnimationFactory.h"
#include "DisplayMessage.h"
#include "Game.h"
#include "GameData.h"
+#include "GlobalTimer.h"
+#include "Image.h"
#include "Interface.h"
#include "ProjectileServer.h"
+#include "Scriptable/Actor.h"
+#include "Sprite2D.h"
#include "Video.h"
#include <cmath>
#include <cstdlib>
+namespace GemRB {
+
//to get gradient color
//apparently pst doesn't have the small palette correctly
#define PALSIZE 32
@@ -250,7 +256,7 @@ void Projectile::GetPaletteCopy(Animation *anim[], Palette *&pal)
}
}
-void Projectile::SetBlend()
+void Projectile::SetBlend(int brighten)
{
GetPaletteCopy(travel, palette);
if (!palette)
@@ -258,6 +264,9 @@ void Projectile::SetBlend()
if (!palette->alpha) {
palette->CreateShadedAlphaChannel();
}
+ if (brighten) {
+ palette->Brighten();
+ }
}
//create another projectile with type-1 (iterate magic missiles and call lightning)
@@ -311,7 +320,7 @@ void Projectile::Setup()
if(ExtFlags&PEF_TEXT) {
Actor *act = area->GetActorByGlobalID(Caster);
if(act) {
- displaymsg->DisplayStringName(StrRef,0xd7d7be,act,0);
+ displaymsg->DisplayStringName(StrRef, DMC_LIGHTGREY, act,0);
}
}
@@ -409,7 +418,7 @@ void Projectile::Setup()
light = core->GetVideoDriver()->CreateLight(LightX, LightZ);
}
if (TFlags&PTF_BLEND) {
- SetBlend();
+ SetBlend(TFlags&PTF_BRIGHTEN);
}
if (SFlags&PSF_FLYING) {
ZPos = FLY_HEIGHT;
@@ -435,6 +444,10 @@ Actor *Projectile::GetTarget()
effects->SetOwner(target);
return target;
}
+ if (!effects) {
+ return target;
+ }
+
int res = effects->CheckImmunity ( target );
//resisted
if (!res) {
@@ -446,6 +459,8 @@ Actor *Projectile::GetTarget()
}
effects->SetOwner(original);
return target;
+ } else {
+ Log(DEBUG, "Projectile", "GetTarget: Target not set or dummy, using caster!");
}
target = area->GetActorByGlobalID(Caster);
if (target) {
@@ -463,6 +478,7 @@ void Projectile::SetDelay(int delay)
//copied from Actor.cpp
#define ATTACKROLL 20
#define WEAPON_FIST 0
+#define WEAPON_BYPASS 0x10000
bool Projectile::FailedIDS(Actor *target) const
{
@@ -507,9 +523,10 @@ bool Projectile::FailedIDS(Actor *target) const
}
//handle attack type here, weapon depends on it too?
- int tohit = caster->GetToHit(0, WEAPON_FIST, target);
+ int tohit = caster->GetToHit(WEAPON_FIST, target);
//damage type, should be generic?
- int defense = target->GetDefense(0, caster);
+ // ignore the armor bonus
+ int defense = target->GetDefense(0, WEAPON_BYPASS, caster);
if(target->IsReverseToHit()) {
fail = roll + defense < tohit;
} else {
@@ -525,6 +542,7 @@ bool Projectile::FailedIDS(Actor *target) const
void Projectile::Payload()
{
Actor *target;
+ Scriptable *Owner;
if(Shake) {
core->timer->SetScreenShake( Shake, Shake, Shake);
@@ -532,7 +550,7 @@ void Projectile::Payload()
}
//allow area affecting projectile with a spell
- if(!(effects || (!Target && FailSpell[0]))) {
+ if(!(effects || SuccSpell[0] || (!Target && FailSpell[0]))) {
return;
}
@@ -553,14 +571,22 @@ void Projectile::Payload()
} else {
target = area->GetActorByGlobalID(Caster);
}
- Actor *source = area->GetActorByGlobalID(Caster);
- if (effects) {
- if (source) {
- effects->SetOwner(source);
- } else {
- effects->SetOwner(target);
- }
- }
+ }
+ Actor *source = area->GetActorByGlobalID(Caster);
+ InfoPoint *source2 = area->GetInfoPointByGlobalID(Caster);
+ Container *source3 = area->GetContainerByGlobalID(Caster);
+ Door *source4 = area->GetDoorByGlobalID(Caster);
+ if (source) {
+ Owner = source;
+ } else if (source2) {
+ Owner = (Scriptable *) source2;
+ } else if (source3) {
+ Owner = (Scriptable *) source3;
+ } else if (source4) {
+ Owner = (Scriptable *) source4;
+ } else {
+ Log(WARNING, "Projectile", "Payload: Caster not found, using target!");
+ Owner = target;
}
if (target) {
@@ -568,7 +594,7 @@ void Projectile::Payload()
if (FailedIDS(target)) {
if (FailSpell[0]) {
if (Target) {
- core->ApplySpell(FailSpell, target, effects->GetOwner(), Level);
+ core->ApplySpell(FailSpell, target, Owner, Level);
} else {
//no Target, using the fake target as owner
core->ApplySpellPoint(FailSpell, area, Destination, target, Level);
@@ -577,7 +603,7 @@ void Projectile::Payload()
} else {
//apply this spell on the target when the projectile succeeds
if (SuccSpell[0]) {
- core->ApplySpell(SuccSpell, target, effects->GetOwner(), Level);
+ core->ApplySpell(SuccSpell, target, Owner, Level);
}
if(ExtFlags&PEF_RGB) {
@@ -585,7 +611,10 @@ void Projectile::Payload()
RGB >> 8, RGB >> 16, RGB >> 24);
}
- effects->AddAllEffects(target, Destination);
+ if (effects) {
+ effects->SetOwner(Owner);
+ effects->AddAllEffects(target, Destination);
+ }
}
}
@@ -1271,9 +1300,9 @@ void Projectile::SpawnFragment(Point &dest)
{
Projectile *pro = server->GetProjectileByIndex(Extension->FragProjIdx);
if (pro) {
- if (Extension->AFlags&PAF_SECONDARY) {
- pro->SetEffectsCopy(effects);
- }
+// if (Extension->AFlags&PAF_SECONDARY) {
+// pro->SetEffectsCopy(effects);
+// }
pro->SetCaster(Caster, Level);
if (pro->ExtFlags&PEF_RANDOM) {
dest.x+=core->Roll(1,Extension->TileX, -Extension->TileX/2);
@@ -1352,7 +1381,8 @@ void Projectile::DrawExplosion(const Region &screen)
//warning: this projectile doesn't inherit any effects, so its payload function
//won't be doing anything (any effect of PAF_SECONDARY?)
- if (Extension->FragProjIdx) {
+ //remove PAF_SECONDARY if it is buggy, but that will break the 'HOLD' projectile
+ if ((Extension->AFlags&PAF_SECONDARY) && Extension->FragProjIdx) {
if (apflags&APF_TILED) {
int i,j;
int radius = Extension->ExplosionRadius;
@@ -1606,6 +1636,7 @@ void Projectile::DrawTravel(const Region &screen)
//Area tint
if (TFlags&PTF_TINT) {
tint = area->LightMap->GetPixel( Pos.x / 16, Pos.y / 12);
+ tint.a = 255;
flag |= BLIT_TINTED;
}
@@ -1761,3 +1792,5 @@ void Projectile::Cleanup()
phase=P_EXPIRED;
}
+
+}
diff --git a/gemrb/core/Projectile.h b/gemrb/core/Projectile.h
index 16e899d..d46635c 100644
--- a/gemrb/core/Projectile.h
+++ b/gemrb/core/Projectile.h
@@ -32,11 +32,14 @@
#include "ie_types.h"
#include "CharAnimations.h" //contains MAX_ORIENT
+#include "EffectQueue.h"
#include "Map.h"
#include "Palette.h"
#include "PathFinder.h"
#include "Audio.h"
+namespace GemRB {
+
//this is the height of the projectile when Spark Flag Fly = 1
#define FLY_HEIGHT 50
//this is supposed to move the projectile to the background
@@ -67,7 +70,8 @@
#define PTF_TINT 8 //tint projectile
#define PTF_SHADOW 32 //has shadow bam
#define PTF_LIGHT 64 //has light shadow
-#define PTF_BLEND 128 //blend colours
+#define PTF_BLEND 128 //blend colours (use alpha)
+#define PTF_BRIGHTEN 256 //brighten alpha
//projectile extended travel flags (gemrb specific)
#define PEF_BOUNCE 1 //bounce from walls (lightning bolt)
@@ -359,7 +363,7 @@ private:
void CreateOrientedAnimations(Animation **anims, AnimationFactory *af, int Seq);
void GetPaletteCopy(Animation *anim[], Palette *&pal);
void GetSmokeAnim();
- void SetBlend();
+ void SetBlend(int brighten);
//apply spells and effects on the target, only in single travel mode
//area effect projectiles call a separate single travel projectile for each affected target
void Payload();
@@ -402,5 +406,6 @@ private:
void SetupPalette(Animation *anim[], Palette *&pal, const ieByte *gradients);
};
-#endif // PROJECTILE_H
+}
+#endif // PROJECTILE_H
diff --git a/gemrb/core/ProjectileMgr.cpp b/gemrb/core/ProjectileMgr.cpp
index d732a1d..e7c8977 100644
--- a/gemrb/core/ProjectileMgr.cpp
+++ b/gemrb/core/ProjectileMgr.cpp
@@ -20,6 +20,8 @@
#include "ProjectileMgr.h"
+namespace GemRB {
+
ProjectileMgr::ProjectileMgr(void)
{
}
@@ -27,3 +29,5 @@ ProjectileMgr::ProjectileMgr(void)
ProjectileMgr::~ProjectileMgr(void)
{
}
+
+}
diff --git a/gemrb/core/ProjectileMgr.h b/gemrb/core/ProjectileMgr.h
index 2233d1f..c28ffa8 100644
--- a/gemrb/core/ProjectileMgr.h
+++ b/gemrb/core/ProjectileMgr.h
@@ -25,12 +25,16 @@
#include "Projectile.h"
#include "System/DataStream.h"
+namespace GemRB {
+
class GEM_EXPORT ProjectileMgr : public Plugin {
public:
ProjectileMgr(void);
virtual ~ProjectileMgr(void);
- virtual bool Open(DataStream* stream, bool autoFree = true) = 0;
+ virtual bool Open(DataStream* stream) = 0;
virtual Projectile* GetProjectile( Projectile *) = 0;
};
+}
+
#endif
diff --git a/gemrb/core/ProjectileServer.cpp b/gemrb/core/ProjectileServer.cpp
index c3a2e80..97b0818 100644
--- a/gemrb/core/ProjectileServer.cpp
+++ b/gemrb/core/ProjectileServer.cpp
@@ -22,9 +22,12 @@
#include "GameData.h"
#include "Interface.h"
+#include "PluginMgr.h"
#include "ProjectileMgr.h"
#include "SymbolMgr.h"
+namespace GemRB {
+
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
@@ -121,7 +124,7 @@ Projectile *ProjectileServer::GetProjectile(unsigned int idx)
delete ( str );
return CreateDefaultProjectile(idx);
}
- if (!sm->Open( str, true )) {
+ if (!sm->Open(str)) {
return CreateDefaultProjectile(idx);
}
Projectile *pro = new Projectile();
@@ -218,7 +221,7 @@ unsigned int ProjectileServer::PrepareSymbols(Holder<SymbolMgr> projlist) {
unsigned int value = projlist->GetValueIndex(rows);
if (value>MAX_PROJ_IDX) {
//value = MAX_PROJ_IDX;
- printMessage("ProjectileServer","Too high projectilenumber\n", YELLOW);
+ Log(WARNING, "ProjectileServer", "Too high projectilenumber");
continue; // ignore
}
if (value>(unsigned int) count) {
@@ -238,8 +241,7 @@ void ProjectileServer::AddSymbols(Holder<SymbolMgr> projlist) {
}
if (value >= (unsigned int)projectilecount) {
// this should never happen!
- printMessage("ProjectileServer","Too high projectilenumber while adding projectiles\n", RED);
- abort();
+ error("ProjectileServer", "Too high projectilenumber while adding projectiles\n");
}
strnuprcpy(projectiles[value].resname, projlist->GetStringIndex(rows), 8);
}
@@ -294,7 +296,7 @@ int ProjectileServer::GetExplosionFlags(unsigned int idx)
{
if (explosioncount==-1) {
if (InitExplosion()<0) {
- printMessage("ProjectileServer","Problem with explosions\n", RED);
+ Log(ERROR, "ProjectileServer", "Problem with explosions");
explosioncount=0;
}
}
@@ -309,7 +311,7 @@ ieResRef const *ProjectileServer::GetExplosion(unsigned int idx, int type)
{
if (explosioncount==-1) {
if (InitExplosion()<0) {
- printMessage("ProjectileServer","Problem with explosions\n", RED);
+ Log(ERROR, "ProjectileServer", "Problem with explosions");
explosioncount=0;
}
}
@@ -323,3 +325,5 @@ ieResRef const *ProjectileServer::GetExplosion(unsigned int idx, int type)
return ret;
}
+
+}
diff --git a/gemrb/core/ProjectileServer.h b/gemrb/core/ProjectileServer.h
index d53f99c..34960ec 100644
--- a/gemrb/core/ProjectileServer.h
+++ b/gemrb/core/ProjectileServer.h
@@ -23,9 +23,10 @@
#include "exports.h"
-#include "PluginMgr.h"
#include "Projectile.h"
+namespace GemRB {
+
class SymbolMgr;
//the number of resrefs in areapro.2da (before the flags field)
@@ -94,4 +95,6 @@ private:
};
#endif // PROJSERVER_H
+}
+
diff --git a/gemrb/core/Region.cpp b/gemrb/core/Region.cpp
index 0ab46be..216ee44 100644
--- a/gemrb/core/Region.cpp
+++ b/gemrb/core/Region.cpp
@@ -20,6 +20,8 @@
#include "Region.h"
+namespace GemRB {
+
/*************** point ****************************/
Point::Point(void)
{
@@ -27,25 +29,6 @@ Point::Point(void)
//memset(this, 0, sizeof(*this));
}
-Point::~Point(void)
-{
-}
-
-Point::Point(const Point& pnt)
-{
- x=pnt.x;
- y=pnt.y;
- //memcpy(this, &pnt, sizeof(*this));
-}
-
-Point& Point::operator=(const Point& pnt)
-{
- x = pnt.x;
- y = pnt.y;
- //memcpy(this, &pnt, sizeof(*this));
- return *this;
-}
-
bool Point::operator==(const Point& pnt)
{
if (( x == pnt.x ) && ( y == pnt.y )) {
@@ -113,27 +96,6 @@ Region::Region(void)
x = y = w = h = 0;
}
-Region::~Region(void)
-{
-}
-
-Region::Region(const Region& rgn)
-{
- x = rgn.x;
- y = rgn.y;
- w = rgn.w;
- h = rgn.h;
-}
-
-Region& Region::operator=(const Region& rgn)
-{
- x = rgn.x;
- y = rgn.y;
- w = rgn.w;
- h = rgn.h;
- return *this;
-}
-
bool Region::operator==(const Region& rgn)
{
if (( x == rgn.x ) && ( y == rgn.y ) && ( w == rgn.w ) && ( h == rgn.h )) {
@@ -222,3 +184,5 @@ void Region::Normalize()
h -= y;
}
}
+
+}
diff --git a/gemrb/core/Region.h b/gemrb/core/Region.h
index 675663b..32e23cc 100644
--- a/gemrb/core/Region.h
+++ b/gemrb/core/Region.h
@@ -31,6 +31,8 @@
#include "exports.h"
#include "ie_types.h"
+namespace GemRB {
+
/**
* @class Point
* Point in 2d-space: [x, y]
@@ -39,11 +41,8 @@
class GEM_EXPORT Point {
public:
Point(void);
- Point(const Point& pnt);
Point(short x, short y);
- ~Point(void);
- Point& operator=(const Point& pnt);
bool operator==(const Point &pnt);
bool operator!=(const Point &pnt);
@@ -76,14 +75,11 @@ public:
class GEM_EXPORT Region {
public:
Region(void);
- ~Region(void);
int x;
int y;
int w;
int h;
- Region(const Region& rgn);
Region(const Point& p, int w, int h);
- Region& operator=(const Region& rgn);
bool operator==(const Region& rgn);
bool operator!=(const Region& rgn);
Region(int x, int y, int w, int h);
@@ -93,4 +89,6 @@ public:
void Normalize();
};
+}
+
#endif // ! REGION_H
diff --git a/gemrb/core/Resource.cpp b/gemrb/core/Resource.cpp
index 5e9bac6..3b198df 100644
--- a/gemrb/core/Resource.cpp
+++ b/gemrb/core/Resource.cpp
@@ -22,6 +22,8 @@
#include "System/DataStream.h"
+namespace GemRB {
+
Resource::Resource(void)
{
str = NULL;
@@ -33,3 +35,5 @@ Resource::~Resource(void)
delete( str );
}
}
+
+}
diff --git a/gemrb/core/Resource.h b/gemrb/core/Resource.h
index a5f81f8..fcf004a 100644
--- a/gemrb/core/Resource.h
+++ b/gemrb/core/Resource.h
@@ -31,6 +31,8 @@
#include <cstddef>
+namespace GemRB {
+
class DataStream;
/**
@@ -54,4 +56,6 @@ public:
virtual bool Open(DataStream* stream) = 0;
};
+}
+
#endif
diff --git a/gemrb/core/ResourceDesc.cpp b/gemrb/core/ResourceDesc.cpp
index 309ecc8..6d48d5b 100644
--- a/gemrb/core/ResourceDesc.cpp
+++ b/gemrb/core/ResourceDesc.cpp
@@ -20,6 +20,8 @@
#include "ResourceDesc.h"
+namespace GemRB {
+
ResourceDesc::ResourceDesc(const TypeID* type, CreateFunc create, const char *ext, ieWord keyType)
: type(type), ext(ext), keyType(keyType), create(create)
{
@@ -48,3 +50,5 @@ Resource* ResourceDesc::Create(DataStream *stream) const
{
return create(stream);
}
+
+}
diff --git a/gemrb/core/ResourceDesc.h b/gemrb/core/ResourceDesc.h
index 74a75c1..e8423ac 100644
--- a/gemrb/core/ResourceDesc.h
+++ b/gemrb/core/ResourceDesc.h
@@ -25,6 +25,8 @@
#include "exports.h"
#include "ie_types.h"
+namespace GemRB {
+
class DataStream;
class Resource;
class TypeID;
@@ -57,4 +59,6 @@ public:
Resource* Create(DataStream*) const;
};
+}
+
#endif
diff --git a/gemrb/core/ResourceManager.cpp b/gemrb/core/ResourceManager.cpp
index 95c131e..eb50990 100644
--- a/gemrb/core/ResourceManager.cpp
+++ b/gemrb/core/ResourceManager.cpp
@@ -25,6 +25,9 @@
#include "Resource.h"
#include "ResourceDesc.h"
#include "ResourceSource.h"
+#include "System/StringBuffer.h"
+
+namespace GemRB {
ResourceManager::ResourceManager()
{
@@ -39,6 +42,7 @@ bool ResourceManager::AddSource(const char *path, const char *description, Plugi
{
PluginHolder<ResourceSource> source(type);
if (!source->Open(path, description)) {
+ Log(WARNING, "ResourceManager", "Invalid path given: %s (%s)", path, description);
return false;
}
@@ -55,11 +59,11 @@ bool ResourceManager::AddSource(const char *path, const char *description, Plugi
return true;
}
-static void PrintPossibleFiles(const char* ResRef, const TypeID *type)
+static void PrintPossibleFiles(StringBuffer& buffer, const char* ResRef, const TypeID *type)
{
const std::vector<ResourceDesc>& types = PluginMgr::Get()->GetResourceDesc(type);
for (size_t j = 0; j < types.size(); j++) {
- printf("%s%s ", ResRef, types[j].GetExt());
+ buffer.appendFormatted("%s.%s ", ResRef, types[j].GetExt());
}
}
@@ -74,9 +78,8 @@ bool ResourceManager::Exists(const char *ResRef, SClass_ID type, bool silent) co
}
}
if (!silent) {
- printMessage( "ResourceManager", "Searching for ", WHITE );
- printf( "%s%s...", ResRef, core->TypeExt( type ) );
- printStatus( "NOT FOUND", YELLOW );
+ Log(WARNING, "ResourceManager", "'%s.%s' not found...",
+ ResRef, core->TypeExt(type));
}
return false;
}
@@ -95,11 +98,11 @@ bool ResourceManager::Exists(const char *ResRef, const TypeID *type, bool silent
}
}
if (!silent) {
- printMessage( "ResourceManager", "Searching for ", WHITE );
- printf( "%s... ", ResRef );
- printf("Tried ");
- PrintPossibleFiles(ResRef,type);
- printStatus( "NOT FOUND", YELLOW );
+ StringBuffer buffer;
+ buffer.appendFormatted("Couldn't find '%s'... ", ResRef);
+ buffer.append("Tried ");
+ PrintPossibleFiles(buffer, ResRef,type);
+ Log(WARNING, "ResourceManager", buffer);
}
return false;
}
@@ -108,21 +111,19 @@ DataStream* ResourceManager::GetResource(const char* ResRef, SClass_ID type, boo
{
if (ResRef[0] == '\0')
return NULL;
- if (!silent) {
- printMessage( "ResourceManager", "Searching for ", WHITE );
- printf( "%s%s...", ResRef, core->TypeExt( type ) );
- }
for (size_t i = 0; i < searchPath.size(); i++) {
DataStream *ds = searchPath[i]->GetResource(ResRef, type);
if (ds) {
if (!silent) {
- printStatus( searchPath[i]->GetDescription(), GREEN );
+ Log(MESSAGE, "ResourceManager", "Found '%s.%s' in '%s'.",
+ ResRef, core->TypeExt(type), searchPath[i]->GetDescription());
}
return ds;
}
}
if (!silent) {
- printStatus( "ERROR", LIGHT_RED );
+ Log(ERROR, "ResourceManager", "Couldn't find '%s.%s'.",
+ ResRef, core->TypeExt(type));
}
return NULL;
}
@@ -132,8 +133,7 @@ Resource* ResourceManager::GetResource(const char* ResRef, const TypeID *type, b
if (ResRef[0] == '\0')
return NULL;
if (!silent) {
- printMessage( "ResourceManager", "Searching for ", WHITE );
- printf( "%s... ", ResRef );
+ Log(MESSAGE, "ResourceManager", "Searching for '%s'...", ResRef);
}
const std::vector<ResourceDesc> &types = PluginMgr::Get()->GetResourceDesc(type);
for (size_t j = 0; j < types.size(); j++) {
@@ -143,8 +143,8 @@ Resource* ResourceManager::GetResource(const char* ResRef, const TypeID *type, b
Resource *res = types[j].Create(str);
if (res) {
if (!silent) {
- printf( "%s%s...", ResRef, types[j].GetExt() );
- printStatus( searchPath[i]->GetDescription(), GREEN );
+ Log(MESSAGE, "ResourceManager", "Found '%s.%s' in '%s'.",
+ ResRef, types[j].GetExt(), searchPath[i]->GetDescription());
}
return res;
}
@@ -152,9 +152,13 @@ Resource* ResourceManager::GetResource(const char* ResRef, const TypeID *type, b
}
}
if (!silent) {
- printf("Tried ");
- PrintPossibleFiles(ResRef,type);
- printStatus( "ERROR", LIGHT_RED );
+ StringBuffer buffer;
+ buffer.appendFormatted("Couldn't find '%s'... ", ResRef);
+ buffer.append("Tried ");
+ PrintPossibleFiles(buffer, ResRef,type);
+ Log(WARNING, "ResourceManager", buffer);
}
return NULL;
}
+
+}
diff --git a/gemrb/core/ResourceManager.h b/gemrb/core/ResourceManager.h
index 7fcbe2d..de7c30d 100644
--- a/gemrb/core/ResourceManager.h
+++ b/gemrb/core/ResourceManager.h
@@ -32,6 +32,8 @@
#include "ResourceSource.h"
#endif
+namespace GemRB {
+
#define RM_REPLACE_SAME_SOURCE 1
class DataStream;
@@ -67,4 +69,6 @@ private:
std::vector<Holder<ResourceSource> > searchPath;
};
+}
+
#endif
diff --git a/gemrb/core/ResourceSource.cpp b/gemrb/core/ResourceSource.cpp
index 2fae650..4d25d38 100644
--- a/gemrb/core/ResourceSource.cpp
+++ b/gemrb/core/ResourceSource.cpp
@@ -20,6 +20,8 @@
#include "ResourceSource.h"
+namespace GemRB {
+
ResourceSource::ResourceSource(void)
{
}
@@ -27,3 +29,5 @@ ResourceSource::ResourceSource(void)
ResourceSource::~ResourceSource(void)
{
}
+
+}
diff --git a/gemrb/core/ResourceSource.h b/gemrb/core/ResourceSource.h
index 11608b9..e497e7b 100644
--- a/gemrb/core/ResourceSource.h
+++ b/gemrb/core/ResourceSource.h
@@ -27,6 +27,8 @@
#include "Plugin.h"
+namespace GemRB {
+
class DataStream;
class ResourceDesc;
@@ -44,4 +46,6 @@ protected:
char *description;
};
+}
+
#endif
diff --git a/gemrb/core/SaveGame.h b/gemrb/core/SaveGame.h
index ce7460d..94f8310 100644
--- a/gemrb/core/SaveGame.h
+++ b/gemrb/core/SaveGame.h
@@ -25,9 +25,12 @@
#include "Holder.h"
#include "ResourceManager.h"
-#include "System/FileStream.h"
+#include "System/VFS.h"
+
+namespace GemRB {
class ImageMgr;
+class Sprite2D;
class GEM_EXPORT SaveGame : public Held<SaveGame> {
public:
@@ -82,4 +85,6 @@ private:
ResourceManager manager;
};
+}
+
#endif
diff --git a/gemrb/core/SaveGameIterator.cpp b/gemrb/core/SaveGameIterator.cpp
index ced734a..51d35cb 100644
--- a/gemrb/core/SaveGameIterator.cpp
+++ b/gemrb/core/SaveGameIterator.cpp
@@ -29,11 +29,16 @@
#include "ImageMgr.h"
#include "ImageWriter.h"
#include "Interface.h"
+#include "PluginMgr.h"
#include "SaveGameMgr.h"
+#include "Sprite2D.h"
+#include "TableMgr.h"
#include "Video.h"
#include "GUI/GameControl.h"
+#include "Scriptable/Actor.h"
+#include "System/FileStream.h"
-#if defined(__HAIKU__)
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -41,6 +46,8 @@
#include <set>
#include <time.h>
+namespace GemRB {
+
const TypeID SaveGame::ID = { "SaveGame" };
/** Extract date from save game ds into Date. */
@@ -94,10 +101,10 @@ static void ParseGameDate(DataStream *ds, char *Date)
SaveGame::SaveGame(const char* path, const char* name, const char* prefix, const char* slotname, int pCount, int saveID)
{
- strncpy( Prefix, prefix, sizeof( Prefix ) );
- strncpy( Path, path, sizeof( Path ) );
- strncpy( Name, name, sizeof( Name ) );
- strncpy( SlotName, slotname, sizeof( SlotName ) );
+ strlcpy( Prefix, prefix, sizeof( Prefix ) );
+ strlcpy( Path, path, sizeof( Path ) );
+ strlcpy( Name, name, sizeof( Name ) );
+ strlcpy( SlotName, slotname, sizeof( SlotName ) );
PortraitCount = pCount;
SaveID = saveID;
char nPath[_MAX_PATH];
@@ -227,8 +234,8 @@ static bool IsSaveGameSlot(const char* Path, const char* slotname)
if (cnt != 2) {
//The matcher didn't match: either this is not a valid dir
//or the SAVEGAME_DIRECTORY_MATCHER needs updating.
- printMessage( "SaveGameIterator", " ", LIGHT_RED );
- printf( "Invalid savegame directory '%s' in %s.\n", slotname, Path );
+ Log(ERROR, "SaveGameIterator", "Invalid savegame directory '%s' in %s.",
+ slotname, Path);
return false;
}
@@ -240,23 +247,20 @@ static bool IsSaveGameSlot(const char* Path, const char* slotname)
PathJoinExt(ftmp, dtmp, core->GameNameResRef, "bmp");
if (access( ftmp, R_OK )) {
- printMessage("SaveGameIterator"," ",YELLOW);
- printf("Ignoring slot %s because of no appropriate preview!\n", dtmp);
+ Log(WARNING, "SaveGameIterator", "Ignoring slot %s because of no appropriate preview!", dtmp);
return false;
}
PathJoinExt(ftmp, dtmp, core->WorldMapName[0], "wmp");
if (access( ftmp, R_OK )) {
- printMessage("SaveGameIterator"," ",YELLOW);
- printf("Ignoring slot %s because of no appropriate worldmap!\n", dtmp);
+ Log(WARNING, "SaveGameIterator", "Ignoring slot %s because of no appropriate worldmap!", dtmp);
return false;
}
/* we might need something here as well
PathJoinExt(ftmp, dtmp, core->WorldMapName[1], "wmp");
if (access( ftmp, R_OK )) {
- printMessage("SaveGameIterator"," ",YELLOW);
- printf("Ignoring slot %s because of no appropriate worldmap!\n", dtmp);
+ Log(WARNING, "SaveGameIterator", "Ignoring slot %s because of no appropriate worldmap!", dtmp);
return false;
}
*/
@@ -275,8 +279,10 @@ bool SaveGameIterator::RescanSaveGames()
DirectoryIterator dir(Path);
// create the save game directory at first access
if (!dir) {
- mkdir(Path,S_IWRITE|S_IREAD|S_IEXEC);
- chmod(Path,S_IWRITE|S_IREAD|S_IEXEC);
+ if (!MakeDirectories(Path)) {
+ Log(ERROR, "SaveGameIterator", "Unable to create save game directory '%s'", Path);
+ return false;
+ }
dir.Rewind();
}
if (!dir) { //If we cannot open the Directory
@@ -334,7 +340,7 @@ Holder<SaveGame> SaveGameIterator::BuildSaveGame(const char *slotname)
int cnt = sscanf( slotname, SAVEGAME_DIRECTORY_MATCHER, &savegameNumber, savegameName );
//maximum pathlength == 240, without 8+3 filenames
if ( (cnt != 2) || (strlen(Path)>240) ) {
- printf( "Invalid savegame directory '%s' in %s.\n", slotname, Path );
+ Log(WARNING, "SaveGame" "Invalid savegame directory '%s' in %s.", slotname, Path );
return NULL;
}
@@ -405,6 +411,8 @@ static bool DoSaveGame(const char *Path)
}
}
+ gamedata->SaveAllStores();
+
//compress files in cache named: .STO and .ARE
//no .CRE would be saved in cache
if (core->CompressSave(Path)) {
@@ -423,7 +431,7 @@ static bool DoSaveGame(const char *Path)
PluginHolder<ImageWriter> im(PLUGIN_IMAGE_WRITER_BMP);
if (!im) {
- printMessage( "SaveGameIterator", "Couldn't create the BMPWriter!\n", LIGHT_RED );
+ Log(ERROR, "SaveGameIterator", "Couldn't create the BMPWriter!");
return false;
}
@@ -448,37 +456,44 @@ static bool DoSaveGame(const char *Path)
return true;
}
-int CanSave()
+static int CanSave()
{
//some of these restrictions might not be needed
Store * store = core->GetCurrentStore();
if (store) {
+ displaymsg->DisplayConstantString(STR_CANTSAVESTORE, DMC_BG2XPGREEN);
return 1; //can't save while store is open
}
GameControl *gc = core->GetGameControl();
if (!gc) {
+ displaymsg->DisplayConstantString(STR_CANTSAVE, DMC_BG2XPGREEN);
return -1; //no gamecontrol!!!
}
if (gc->GetDialogueFlags()&DF_IN_DIALOG) {
- return 2; //can't save while in dialog?
+ displaymsg->DisplayConstantString(STR_CANTSAVEDIALOG, DMC_BG2XPGREEN);
+ return 2; //can't save while in dialog
}
//TODO: can't save while in combat
Game *game = core->GetGame();
if (!game) {
+ displaymsg->DisplayConstantString(STR_CANTSAVE, DMC_BG2XPGREEN);
return -1;
}
if (game->CombatCounter) {
+ displaymsg->DisplayConstantString(STR_CANTSAVECOMBAT, DMC_BG2XPGREEN);
return 3;
}
Map *map = game->GetCurrentArea();
if (!map) {
+ displaymsg->DisplayConstantString(STR_CANTSAVE, DMC_BG2XPGREEN);
return -1;
}
- if (map->AreaFlags&AF_SAVE) {
+ if (map->AreaFlags&AF_NOSAVE) {
//cannot save in area
+ displaymsg->DisplayConstantString(STR_CANTSAVEMONS, DMC_BG2XPGREEN);
return 4;
}
@@ -488,27 +503,39 @@ int CanSave()
//TODO: can't save while (party) actors are in helpless states
if (actor->GetStat(IE_STATE_ID) & STATE_NOSAVE) {
//some actor is in nosave state
+ displaymsg->DisplayConstantString(STR_CANTSAVENOCTRL, DMC_BG2XPGREEN);
return 5;
}
if (actor->GetCurrentArea()!=map) {
//scattered
+ displaymsg->DisplayConstantString(STR_CANTSAVE, DMC_BG2XPGREEN);
return 6;
}
+
+ if (map->AnyEnemyNearPoint(actor->Pos)) {
+ displaymsg->DisplayConstantString( STR_CANTSAVEMONS, DMC_BG2XPGREEN );
+ return 7;
+ }
+
}
- //TODO: can't save while AOE spells are in effect
- //TODO: can't save while IF_NOINT is set on any actor
+ //TODO: can't save while AOE spells are in effect -> CANTSAVE
+ //TODO: can't save while IF_NOINT is set on any actor -> CANTSAVEDIALOG2 (dialog about to start)
+ //TODO: can't save during a rest, chapter information or movie -> CANTSAVEMOVIE
return 0;
}
-static void CreateSavePath(char *Path, int index, const char *slotname)
+static bool CreateSavePath(char *Path, int index, const char *slotname) WARN_UNUSED;
+static bool CreateSavePath(char *Path, int index, const char *slotname)
{
PathJoin( Path, core->SavePath, SaveDir(), NULL );
//if the path exists in different case, don't make it again
- mkdir(Path,S_IWRITE|S_IREAD|S_IEXEC);
- chmod(Path,S_IWRITE|S_IREAD|S_IEXEC);
+ if (!MakeDirectory(Path)) {
+ Log(ERROR, "SaveGameIterator", "Unable to create save game directory '%s'", Path);
+ return false;
+ }
//keep the first part we already determined existing
char dir[_MAX_PATH];
@@ -516,8 +543,11 @@ static void CreateSavePath(char *Path, int index, const char *slotname)
PathJoin(Path, Path, dir, NULL);
//this is required in case the old slot wasn't recognised but still there
core->DelTree(Path, false);
- mkdir(Path,S_IWRITE|S_IREAD|S_IEXEC);
- chmod(Path,S_IWRITE|S_IREAD|S_IEXEC);
+ if (!MakeDirectory(Path)) {
+ Log(ERROR, "SaveGameIterator", "Unable to create save game directory '%s'", Path);
+ return false;
+ }
+ return true;
}
int SaveGameIterator::CreateSaveGame(int index, bool mqs)
@@ -548,11 +578,18 @@ int SaveGameIterator::CreateSaveGame(int index, bool mqs)
}
}
char Path[_MAX_PATH];
- CreateSavePath(Path, index, slotname);
GameControl *gc = core->GetGameControl();
+ if (!CreateSavePath(Path, index, slotname)) {
+ displaymsg->DisplayConstantString(STR_CANTSAVE, DMC_BG2XPGREEN);
+ if (gc) {
+ gc->SetDisplayText(STR_CANTSAVE, 30);
+ }
+ return -1;
+ }
+
if (!DoSaveGame(Path)) {
- displaymsg->DisplayConstantString(STR_CANTSAVE, 0xbcefbc);
+ displaymsg->DisplayConstantString(STR_CANTSAVE, DMC_BG2XPGREEN);
if (gc) {
gc->SetDisplayText(STR_CANTSAVE, 30);
}
@@ -561,12 +598,12 @@ int SaveGameIterator::CreateSaveGame(int index, bool mqs)
// Save succesful / Quick-save succesful
if (qsave) {
- displaymsg->DisplayConstantString(STR_QSAVESUCCEED, 0xbcefbc);
+ displaymsg->DisplayConstantString(STR_QSAVESUCCEED, DMC_BG2XPGREEN);
if (gc) {
gc->SetDisplayText(STR_QSAVESUCCEED, 30);
}
} else {
- displaymsg->DisplayConstantString(STR_SAVESUCCEED, 0xbcefbc);
+ displaymsg->DisplayConstantString(STR_SAVESUCCEED, DMC_BG2XPGREEN);
if (gc) {
gc->SetDisplayText(STR_SAVESUCCEED, 30);
}
@@ -605,10 +642,16 @@ int SaveGameIterator::CreateSaveGame(Holder<SaveGame> save, const char *slotname
}
char Path[_MAX_PATH];
- CreateSavePath(Path, index, slotname);
+ if (!CreateSavePath(Path, index, slotname)) {
+ displaymsg->DisplayConstantString(STR_CANTSAVE, DMC_BG2XPGREEN);
+ if (gc) {
+ gc->SetDisplayText(STR_CANTSAVE, 30);
+ }
+ return -1;
+ }
if (!DoSaveGame(Path)) {
- displaymsg->DisplayConstantString(STR_CANTSAVE, 0xbcefbc);
+ displaymsg->DisplayConstantString(STR_CANTSAVE, DMC_BG2XPGREEN);
if (gc) {
gc->SetDisplayText(STR_CANTSAVE, 30);
}
@@ -616,7 +659,7 @@ int SaveGameIterator::CreateSaveGame(Holder<SaveGame> save, const char *slotname
}
// Save succesful
- displaymsg->DisplayConstantString(STR_SAVESUCCEED, 0xbcefbc);
+ displaymsg->DisplayConstantString(STR_SAVESUCCEED, DMC_BG2XPGREEN);
if (gc) {
gc->SetDisplayText(STR_SAVESUCCEED, 30);
}
@@ -632,3 +675,5 @@ void SaveGameIterator::DeleteSaveGame(Holder<SaveGame> game)
core->DelTree( game->GetPath(), false ); //remove all files from folder
rmdir( game->GetPath() );
}
+
+}
diff --git a/gemrb/core/SaveGameIterator.h b/gemrb/core/SaveGameIterator.h
index 765ad9e..d990782 100644
--- a/gemrb/core/SaveGameIterator.h
+++ b/gemrb/core/SaveGameIterator.h
@@ -27,7 +27,9 @@
#include <vector>
-#define SAVEGAME_DIRECTORY_MATCHER "%d - %[A-Za-z0-9- _]"
+namespace GemRB {
+
+#define SAVEGAME_DIRECTORY_MATCHER "%d - %[A-Za-z0-9- _+*#%&|()=!?]"
class GEM_EXPORT SaveGameIterator {
private:
@@ -48,4 +50,6 @@ private:
void PruneQuickSave(const char *folder);
};
+}
+
#endif
diff --git a/gemrb/core/SaveGameMgr.cpp b/gemrb/core/SaveGameMgr.cpp
index f7e6164..f916b2a 100644
--- a/gemrb/core/SaveGameMgr.cpp
+++ b/gemrb/core/SaveGameMgr.cpp
@@ -20,6 +20,8 @@
#include "SaveGameMgr.h"
+namespace GemRB {
+
SaveGameMgr::SaveGameMgr(void)
{
}
@@ -27,3 +29,5 @@ SaveGameMgr::SaveGameMgr(void)
SaveGameMgr::~SaveGameMgr(void)
{
}
+
+}
diff --git a/gemrb/core/SaveGameMgr.h b/gemrb/core/SaveGameMgr.h
index 20cb911..613d275 100644
--- a/gemrb/core/SaveGameMgr.h
+++ b/gemrb/core/SaveGameMgr.h
@@ -24,15 +24,19 @@
#include "Plugin.h"
#include "System/DataStream.h"
+namespace GemRB {
+
class GEM_EXPORT SaveGameMgr : public Plugin {
public:
SaveGameMgr(void);
virtual ~SaveGameMgr(void);
- virtual bool Open(DataStream* stream, bool autoFree = true) = 0;
+ virtual bool Open(DataStream* stream) = 0;
virtual Game* LoadGame(Game *newGame, int ver_override = 0) = 0;
virtual int GetStoredFileSize(Game *game) = 0;
virtual int PutGame(DataStream* stream, Game *game) = 0;
};
+}
+
#endif
diff --git a/gemrb/core/ScriptEngine.cpp b/gemrb/core/ScriptEngine.cpp
index 9c3bdb6..588ac39 100644
--- a/gemrb/core/ScriptEngine.cpp
+++ b/gemrb/core/ScriptEngine.cpp
@@ -20,6 +20,8 @@
#include "ScriptEngine.h"
+namespace GemRB {
+
ScriptEngine::ScriptEngine(void)
{
}
@@ -27,3 +29,5 @@ ScriptEngine::ScriptEngine(void)
ScriptEngine::~ScriptEngine(void)
{
}
+
+}
diff --git a/gemrb/core/ScriptEngine.h b/gemrb/core/ScriptEngine.h
index 94ec6b6..259c41e 100644
--- a/gemrb/core/ScriptEngine.h
+++ b/gemrb/core/ScriptEngine.h
@@ -23,6 +23,10 @@
#include "Plugin.h"
+namespace GemRB {
+
+class Point;
+
class GEM_EXPORT ScriptEngine : public Plugin {
public:
ScriptEngine(void);
@@ -32,9 +36,12 @@ public:
/** Load Script */
virtual bool LoadScript(const char* filename) = 0;
/** Run Function */
- virtual bool RunFunction(const char *ModuleName, const char* FunctionName, bool error=true, int intparam=-1) = 0;
+ virtual bool RunFunction(const char *ModuleName, const char* FunctionName, bool report_error=true, int intparam=-1) = 0;
+ virtual bool RunFunction(const char* Modulename, const char* FunctionName, bool report_error, Point) = 0;
/** Exec a single String */
virtual void ExecString(const char* string) = 0;
};
+}
+
#endif
diff --git a/gemrb/core/Scriptable/Actor.cpp b/gemrb/core/Scriptable/Actor.cpp
index 9704647..c318324 100644
--- a/gemrb/core/Scriptable/Actor.cpp
+++ b/gemrb/core/Scriptable/Actor.cpp
@@ -30,11 +30,14 @@
#include "opcode_params.h"
#include "win32def.h"
-#include "Audio.h" //pst (react to death sounds)
+#include "Bitmap.h"
+#include "DataFileMgr.h"
#include "DialogHandler.h" // checking for dialog
#include "Game.h"
+#include "GlobalTimer.h"
#include "DisplayMessage.h"
#include "GameData.h"
+#include "Image.h"
#include "Interface.h"
#include "Item.h"
#include "PolymorphCache.h" // stupid polymorph cache hack
@@ -42,15 +45,19 @@
#include "ProjectileServer.h"
#include "ScriptEngine.h"
#include "Spell.h"
+#include "Sprite2D.h"
#include "TableMgr.h"
#include "Video.h"
#include "damages.h"
#include "GameScript/GSUtils.h" //needed for DisplayStringCore
#include "GameScript/GameScript.h"
#include "GUI/GameControl.h"
+#include "System/StringBuffer.h"
#include <cassert>
+namespace GemRB {
+
//configurable?
ieDword ref_lightness = 43;
@@ -73,7 +80,7 @@ static const Color magenta = {
0xff, 0x00, 0xff, 0xff
};
-static int sharexp = SX_DIVIDE;
+static int sharexp = SX_DIVIDE|SX_COMBAT;
static int classcount = -1;
static int extraslots = -1;
static char **clericspelltables = NULL;
@@ -83,15 +90,25 @@ static char **classabilities = NULL;
static int *turnlevels = NULL;
static int *booktypes = NULL;
static int *xpbonus = NULL;
+static int *defaultprof = NULL;
+static int *castingstat = NULL;
static int xpbonustypes = -1;
static int xpbonuslevels = -1;
static int **levelslots = NULL;
static int *dualswap = NULL;
-static int *maxhpconbon = NULL;
+static int *multi = NULL;
+static int *maxLevelForHpRoll = NULL;
static int *skillstats = NULL;
static int *skillabils = NULL;
static int skillcount = -1;
+static int **afcomments = NULL;
+static int afcount = -1;
static ieVariable CounterNames[4]={"GOOD","LAW","LADY","MURDER"};
+//I keep the zero index the same as core rules (default setting)
+static int dmgadjustments[6]={0, -50, -25, 0, 50, 100}; //default, easy, normal, core rules, hard, nightmare
+//XP adjustments on easy setting (need research on the amount)
+//Seems like bg1 halves xp, bg2 doesn't have any impact
+static int xpadjustments[6]={0, 0, 0, 0, 0, 0};
static int FistRows = -1;
static int *wmlevels[20];
@@ -101,7 +118,22 @@ static FistResType *fistres = NULL;
static int *fistresclass = NULL;
static ieResRef DefaultFist = {"FIST"};
+//verbal constant specific data
static int VCMap[VCONST_COUNT];
+static ieDword sel_snd_freq = 0;
+static ieDword cmd_snd_freq = 0;
+static ieDword crit_hit_scr_shake = 1;
+static ieDword bored_time = 3000;
+static ieDword footsteps = 1;
+static ieDword always_dither = 1;
+static ieDword GameDifficulty = DIFF_CORE;
+static ieDword NoExtraDifficultyDmg = 0;
+//the chance to issue one of the rare select verbal constants
+#define RARE_SELECT_CHANCE 5
+//these are the max number of select sounds -- the size of the pool to choose from
+#define NUM_RARE_SELECT_SOUNDS 2 //in bg and pst it is actually 4 TODO: check
+#define NUM_SELECT_SOUNDS 6 //in bg1 this is 4 but doesn't need to be checked
+#define NUM_MC_SELECT_SOUNDS 4 //number of main charater select sounds
//item usability array
struct ItemUseType {
@@ -112,10 +144,16 @@ struct ItemUseType {
ieByte which; //which item dword should be used (1 = kit)
};
+static ieResRef featspells[ES_COUNT];
static ItemUseType *itemuse = NULL;
static int usecount = -1;
+//static ieDword *kituse = NULL;
+//static int kitcount = -1;
static bool pstflags = false;
static bool nocreate = false;
+static bool third = false;
+static bool raresnd = false;
+static bool iwd2class = false;
//used in many places, but different in engines
static ieDword state_invisible = STATE_INVISIBLE;
@@ -131,27 +169,38 @@ static int animcount = -1;
static int fiststat = IE_CLASS;
//conversion for 3rd ed
-static int isclass[11]={0,0,0,0,0,0,0,0,0,0,0};
+static int isclass[ISCLASSES]={0,0,0,0,0,0,0,0,0,0,0,0,0};
-static const int mcwasflags[11] = {
+static const int mcwasflags[ISCLASSES] = {
MC_WAS_FIGHTER, MC_WAS_MAGE, MC_WAS_THIEF, 0, 0, MC_WAS_CLERIC,
- MC_WAS_DRUID, 0, 0, MC_WAS_RANGER, 0};
-static const char *isclassnames[11] = {
+ MC_WAS_DRUID, 0, 0, MC_WAS_RANGER, 0, 0, 0};
+static const char *isclassnames[ISCLASSES] = {
"FIGHTER", "MAGE", "THIEF", "BARBARIAN", "BARD", "CLERIC",
- "DRUID", "MONK", "PALADIN", "RANGER", "SORCERER" };
+ "DRUID", "MONK", "PALADIN", "RANGER", "SORCERER", "CLASS12", "CLASS13" };
+static const int levelslotsiwd2[ISCLASSES]={IE_LEVELFIGHTER, IE_LEVELMAGE, IE_LEVELTHIEF,
+ IE_LEVELBARBARIAN, IE_LEVELBARD, IE_LEVELCLERIC, IE_LEVELDRUID, IE_LEVELMONK,
+ IE_LEVELPALADIN, IE_LEVELRANGER, IE_LEVELSORCERER, IE_LEVELCLASS12, IE_LEVELCLASS13};
+#define BGCLASSCNT 23
//fighter is the default level here
//fixme, make this externalized
-static const int levelslotsbg[21]={ISFIGHTER, ISMAGE, ISFIGHTER, ISCLERIC, ISTHIEF,
- ISBARD, ISPALADIN, 0, 0, 0, 0, ISDRUID, ISRANGER, 0,0,0,0,0,0,ISSORCERER, ISMONK};
-static const int levelslotsiwd2[11]={IE_LEVELFIGHTER,IE_LEVELMAGE,IE_LEVELTHIEF,
- IE_LEVELBARBARIAN,IE_LEVELBARD,IE_LEVELCLERIC,IE_LEVELDRUID,IE_LEVELMONK,
- IE_LEVELPALADIN,IE_LEVELRANGER,IE_LEVELSORCEROR};
-static const unsigned int classesiwd2[ISCLASSES]={5, 11, 9, 1, 2, 3, 4, 6, 7, 8, 10};
+//this map could probably be auto-generated BG2 class ID -> ISCLASS
+static const int levelslotsbg[BGCLASSCNT]={ISFIGHTER, ISMAGE, ISFIGHTER, ISCLERIC, ISTHIEF,
+ ISBARD, ISPALADIN, 0, 0, 0, 0, ISDRUID, ISRANGER, 0,0,0,0,0,0,ISSORCERER, ISMONK,
+ ISCLASS12, ISCLASS13};
+//this map could probably be auto-generated (isClass -> IWD2 class ID)
+//autogenerating for non IWD2 now!!!
+static unsigned int classesiwd2[ISCLASSES]={5, 11, 9, 1, 2, 3, 4, 6, 7, 8, 10, 12, 13};
+//this map could probably be auto-generated (isClass -> IWD2 book ID)
+static const int booksiwd2[ISCLASSES]={-1, IE_IWD2_SPELL_WIZARD, -1, -1,
+ IE_IWD2_SPELL_BARD, IE_IWD2_SPELL_CLERIC, IE_IWD2_SPELL_DRUID, -1,
+ IE_IWD2_SPELL_PALADIN, IE_IWD2_SPELL_RANGER, IE_IWD2_SPELL_SORCERER, -1, -1};
//stat values are 0-255, so a byte is enough
static ieByte featstats[MAX_FEATS]={0
};
+static ieByte featmax[MAX_FEATS]={0
+};
//holds the wspecial table for weapon prof bonuses
#define WSPECIAL_COLS 3
@@ -185,8 +234,9 @@ ActionButtonRow DefaultButtons = {ACT_TALK, ACT_WEAPON1, ACT_WEAPON2,
ACT_QSLOT3, ACT_INNATE};
static int QslotTranslation = false;
static int DeathOnZeroStat = true;
+static int IWDSound = false;
static ieDword TranslucentShadows = 0;
-static int ProjectileSize = 0; //the size of the projectile immunity bitfield (dwords)
+static int ProjectileSize = 0; //the size of the projectile immunity bitfield (dwords)
static const char iwd2gemrb[32] = {
0,0,20,2,22,25,0,14,
@@ -257,10 +307,60 @@ static int hc_flags[OVERLAY_COUNT];
static int *mxsplwis = NULL;
static int spllevels;
+// thieving skill dexterity and race boni vectors
+std::vector<std::vector<int> > skilldex;
+std::vector<std::vector<int> > skillrac;
+
+// iwd2 class to-hit and apr tables read into a single object
+std::map<char *, std::vector<BABTable> > IWD2HitTable;
+typedef std::map<char *, std::vector<BABTable> >::iterator IWD2HitTableIter;
+std::map<int, char *> BABClassMap; // maps classis (not id!) to the BAB table
+
//for every game except IWD2 we need to reverse TOHIT
static int ReverseToHit=true;
static int CheckAbilities=false;
+static EffectRef fx_sleep_ref = { "State:Helpless", -1 };
+static EffectRef fx_cleave_ref = { "Cleave", -1 };
+static EffectRef fx_tohit_vs_creature_ref = { "ToHitVsCreature", -1 };
+static EffectRef fx_damage_vs_creature_ref = { "DamageVsCreature", -1 };
+static EffectRef fx_mirrorimage_ref = { "MirrorImageModifier", -1 };
+static EffectRef fx_set_charmed_state_ref = { "State:Charmed", -1 };
+static EffectRef fx_cure_sleep_ref = { "Cure:Sleep", -1 };
+static EffectRef fx_damage_bonus_modifier_ref = { "DamageBonusModifier2", -1 };
+//bg2 and iwd1
+static EffectRef control_creature_ref = { "ControlCreature", -1 };
+//iwd2
+static EffectRef control_undead_ref = { "ControlUndead2", -1 };
+static EffectRef fx_cure_poisoned_state_ref = { "Cure:Poison", -1 };
+static EffectRef fx_cure_hold_state_ref = { "Cure:Hold", -1 };
+static EffectRef fx_cure_stun_state_ref = { "Cure:Stun", -1 };
+static EffectRef fx_remove_portrait_icon_ref = { "Icon:Remove", -1 };
+static EffectRef fx_unpause_caster_ref = { "Cure:CasterHold", -1 };
+static EffectRef fx_ac_vs_creature_type_ref = { "ACVsCreatureType", -1 };
+static EffectRef fx_puppetmarker_ref = { "PuppetMarker", -1 };
+static EffectRef fx_stoneskin_ref = { "StoneSkinModifier", -1 };
+static EffectRef fx_stoneskin2_ref = { "StoneSkin2Modifier", -1 };
+static EffectRef fx_aegis_ref = { "Aegis", -1 };
+static EffectRef fx_cloak_ref = { "Overlay", -1 };
+static EffectRef fx_damage_ref = { "Damage", -1 };
+static EffectRef fx_melee_ref = { "SetMeleeEffect", -1 };
+static EffectRef fx_ranged_ref = { "SetRangedEffect", -1 };
+static EffectRef fx_cant_use_item_ref = { "CantUseItem", -1 };
+static EffectRef fx_cant_use_item_type_ref = { "CantUseItemType", -1 };
+static EffectRef fx_remove_invisible_state_ref = { "ForceVisible", -1 };
+static EffectRef fx_remove_sanctuary_ref = { "Cure:Sanctuary", -1 };
+static EffectRef fx_disable_button_ref = { "DisableButton", -1 };
+static EffectRef fx_damage_reduction_ref = { "DamageReduction", -1 };
+static EffectRef fx_missile_damage_reduction_ref = { "MissileDamageReduction", -1 };
+
+//used by iwd2
+static ieResRef resref_cripstr={"cripstr"};
+static ieResRef resref_dirty={"dirty"};
+
+static const int weapon_damagetype[] = {DAMAGE_CRUSHING, DAMAGE_PIERCING,
+ DAMAGE_CRUSHING, DAMAGE_SLASHING, DAMAGE_MISSILE, DAMAGE_STUNNING};
+
//internal flags for calculating to hit
#define WEAPON_FIST 0
#define WEAPON_MELEE 1
@@ -268,6 +368,18 @@ static int CheckAbilities=false;
#define WEAPON_STYLEMASK 15
#define WEAPON_LEFTHAND 16
#define WEAPON_USESTRENGTH 32
+#define WEAPON_FINESSE 64
+#define WEAPON_BYPASS 0x10000
+#define WEAPON_KEEN 0x20000
+
+static int avBase, avStance;
+struct avType {
+ ieResRef avresref;
+ AutoTable avtable;
+ int stat;
+};
+static avType *avPrefix;
+static int avCount = -1;
/* counts the on bits in a number */
ieDword bitcount (ieDword n)
@@ -299,7 +411,12 @@ void ReleaseMemoryActor()
delete [] itemuse;
itemuse = NULL;
}
-
+/*
+ if (kituse) {
+ delete [] kituse;
+ kituse = NULL;
+ }
+*/
if (itemanim) {
delete [] itemanim;
itemanim = NULL;
@@ -333,24 +450,15 @@ Actor::Actor()
LongStrRef = (ieStrRef) -1;
ShortStrRef = (ieStrRef) -1;
- LastProtected = 0;
- LastFollowed = 0;
- LastCommander = 0;
- LastHelp = 0;
- LastSeen = 0;
- LastMarked = 0;
- LastMarkedSpell = 0;
- LastHeard = 0;
+ playedCommandSound = false;
+
PCStats = NULL;
- LastCommand = 0; //used by order
- LastShout = 0; //used by heard
LastDamage = 0;
LastDamageType = 0;
- LastTurner = 0;
LastExit = 0;
- HotKey = 0;
attackcount = 0;
secondround = 0;
+ //AttackStance = IE_ANI_ATTACK;
attacksperround = 0;
nextattack = 0;
nextWalk = 0;
@@ -364,6 +472,8 @@ Actor::Actor()
modalTime = 0;
modalSpellLingering = 0;
panicMode = PANIC_NONE;
+ nextComment = 0;
+ nextBored = 0;
inventory.SetInventoryType(INVENTORY_CREATURE);
Equipped = 0;
@@ -385,6 +495,7 @@ Actor::Actor()
ProjectileSize=32;
}
}
+ multiclass = 0;
projectileImmunity = (ieDword *) calloc(ProjectileSize,sizeof(ieDword));
AppearanceFlags = 0;
SetDeathVar = IncKillCount = UnknownField = 0;
@@ -406,13 +517,17 @@ Actor::Actor()
//set it to a neutral value
ModalSpell[0] = '*';
LingeringModalSpell[0] = '*';
+ BackstabResRef[0] = '*';
//this one is not saved
GotLUFeedback = false;
RollSaves();
WMLevelMod = 0;
+ TicksLastRested = 0;
polymorphCache = NULL;
memset(&wildSurgeMods, 0, sizeof(wildSurgeMods));
+ AC.SetOwner(this);
+ ToHit.SetOwner(this);
}
Actor::~Actor(void)
@@ -468,11 +583,13 @@ void Actor::SetName(const char* ptr, unsigned char type)
if (type!=2) {
LongName = ( char * ) realloc( LongName, len );
memcpy( LongName, ptr, len );
+ LongName[len-1]=0;
core->StripLine( LongName, len );
}
if (type!=1) {
ShortName = ( char * ) realloc( ShortName, len );
memcpy( ShortName, ptr, len );
+ ShortName[len-1]=0;
core->StripLine( ShortName, len );
}
}
@@ -510,8 +627,7 @@ void Actor::SetAnimationID(unsigned int AnimID)
if (core->HasFeature(GF_ONE_BYTE_ANIMID) ) {
if ((AnimID&0xf000)==0xe000) {
if (BaseStats[IE_COLORCOUNT]) {
- printMessage("Actor"," ",YELLOW);
- printf("Animation ID %x is supposed to be real colored (no recoloring), patched creature\n", AnimID);
+ Log(WARNING, "Actor", "Animation ID %x is supposed to be real colored (no recoloring), patched creature", AnimID);
}
BaseStats[IE_COLORCOUNT]=0;
}
@@ -520,8 +636,7 @@ void Actor::SetAnimationID(unsigned int AnimID)
if(anims->ResRef[0] == 0) {
delete anims;
anims = NULL;
- printMessage("Actor", " ",LIGHT_RED);
- printf("Missing animation for %s\n",LongName);
+ Log(ERROR, "Actor", "Missing animation for %s", LongName);
return;
}
anims->SetOffhandRef(ShieldRef);
@@ -552,8 +667,7 @@ void Actor::SetAnimationID(unsigned int AnimID)
if (anim && anim[0]) {
SetBase(IE_MOVEMENTRATE, anim[0]->GetFrameCount()) ;
} else {
- printMessage("Actor", "Unable to determine movement rate for animation ", YELLOW);
- printf("%04x!\n", AnimID);
+ Log(WARNING, "Actor", "Unable to determine movement rate for animation %04x!", AnimID);
}
}
@@ -597,6 +711,9 @@ void Actor::SetCircleSize()
} else if (Modified[IE_STATE_ID] & STATE_PANIC) {
color = &yellow;
color_index = 5;
+ } else if (Modified[IE_CHECKFORBERSERK]) {
+ color = &yellow;
+ color_index = 5;
} else if (gc && gc->dialoghandler->targetID == GetGlobalID() && (gc->GetDialogueFlags()&DF_IN_DIALOG)) {
color = &white;
color_index = 3; //?? made up
@@ -612,10 +729,13 @@ void Actor::SetCircleSize()
color = &green;
color_index = 0;
break;
-
+ case EA_EVILCUTOFF:
+ color = &yellow;
+ color_index = 5;
+ break;
case EA_ENEMY:
case EA_GOODBUTRED:
- case EA_EVILCUTOFF:
+ case EA_CHARMEDPC:
color = &red;
color_index = 1;
break;
@@ -683,7 +803,10 @@ static void ApplyClab_internal(Actor *actor, const char *clab, int level, bool r
#define BG2_KITMASK 0xffffc000
#define KIT_BASECLASS 0x4000
+#define KIT_SWASHBUCKLER 0x100000
+#define KIT_BARBARIAN 0x40000000
+//TODO: make kitlist column 6 stored internally
static ieDword GetKitIndex (ieDword kit, const char *resref="kitlist")
{
int kitindex = 0;
@@ -692,9 +815,7 @@ static ieDword GetKitIndex (ieDword kit, const char *resref="kitlist")
kitindex = kit&0xfff;
}
- // carefully looking for kit by the usability flag
- // since the barbarian kit id clashes with the no-kit value
- if (kitindex == 0 && kit != KIT_BASECLASS) {
+ if (kitindex == 0) {
Holder<TableMgr> tm = gamedata->GetTable(gamedata->LoadTable(resref) );
if (tm) {
kitindex = tm->FindTableValue(6, kit);
@@ -707,6 +828,19 @@ static ieDword GetKitIndex (ieDword kit, const char *resref="kitlist")
return (ieDword)kitindex;
}
+static ieDword GetKitUsability(ieDword kit, const char *resref="kitlist")
+{
+ if ((kit&BG2_KITMASK) == KIT_BASECLASS) {
+ int kitindex = kit&0xfff;
+ Holder<TableMgr> tm = gamedata->GetTable(gamedata->LoadTable(resref) );
+ if (tm) {
+ return strtol(tm->QueryField(kitindex, 6), NULL, 0 );
+ }
+ }
+ if (kit&KIT_BASECLASS) return 0;
+ return kit;
+}
+
//applies a kit on the character (only bg2)
bool Actor::ApplyKit(bool remove)
{
@@ -730,7 +864,7 @@ bool Actor::ApplyKit(bool remove)
ieDword msk = 1;
for(unsigned int i=1;(i<(unsigned int) classcount) && (msk<=multiclass);i++) {
if (multiclass & msk) {
- max = GetClassLevel(levelslotsbg[i]);
+ max = GetLevelInClass(i);
// don't apply/remove the old kit clab if the kit is disabled
if (i==kitclass && !IsDualClassed()) {
ApplyClab(clab, max, remove);
@@ -744,10 +878,10 @@ bool Actor::ApplyKit(bool remove)
}
//single class
ieDword cls = GetStat(IE_CLASS);
- if (cls<(ieDword) classcount) {
+ if (cls>=(ieDword) classcount) {
return false;
}
- max = GetClassLevel(levelslotsbg[cls]);
+ max = GetLevelInClass(cls);
if (kitclass==cls) {
ApplyClab(clab, max, remove);
} else {
@@ -776,13 +910,25 @@ void Actor::ApplyClab(const char *clab, ieDword max, bool remove)
void pcf_morale (Actor *actor, ieDword /*oldValue*/, ieDword /*newValue*/)
{
if ((actor->Modified[IE_MORALE]<=actor->Modified[IE_MORALEBREAK]) && (actor->Modified[IE_MORALEBREAK] != 0) ) {
- //TODO: current attacker should be passed instead of NULL
- actor->Panic(NULL, core->Roll(1,3,0) );
+ actor->Panic(core->GetGame()->GetActorByGlobalID(actor->LastAttacker), core->Roll(1,3,0) );
+ } else if (actor->Modified[IE_STATE_ID]&STATE_PANIC) {
+ // recover from panic, since morale has risen again
+ // but only if we have really just recovered, so panic from other
+ // sources isn't affected
+ if ((actor->Modified[IE_MORALE]-1 == actor->Modified[IE_MORALEBREAK]) || (actor->Modified[IE_MORALEBREAK] == 0) ) {
+ actor->SetBaseBit(IE_STATE_ID, STATE_PANIC, false);
+ }
}
//for new colour
actor->SetCircleSize();
}
+void pcf_berserk(Actor *actor, ieDword /*oldValue*/, ieDword /*newValue*/)
+{
+ //needs for new color
+ actor->SetCircleSize();
+}
+
void pcf_ea (Actor *actor, ieDword /*oldValue*/, ieDword newValue)
{
if (actor->Selected && (newValue>EA_GOODCUTOFF) ) {
@@ -816,13 +962,16 @@ void pcf_level (Actor *actor, ieDword oldValue, ieDword newValue)
void pcf_class (Actor *actor, ieDword /*oldValue*/, ieDword newValue)
{
- actor->InitButtons(newValue, true);
+ //Call forced initbuttons in old style systems, and soft initbuttons
+ //in case of iwd2. Maybe we need a custom quickslots flag here.
+ actor->InitButtons(newValue, !iwd2class);
int sorcerer=0;
if (newValue<(ieDword) classcount) {
switch(booktypes[newValue]) {
- case 2: sorcerer = 1<<IE_SPELL_TYPE_WIZARD; break;
- case 3: sorcerer = 1<<IE_SPELL_TYPE_PRIEST; break;
+ case 2: sorcerer = 1<<IE_SPELL_TYPE_WIZARD; break; //sorcerer
+ case 3: sorcerer = 1<<IE_SPELL_TYPE_PRIEST; break; //divine caster with sorc. style spells
+ case 5: sorcerer = 1<<IE_IWD2_SPELL_SHAPE; break; //divine caster with sorc style shapes (iwd2 druid)
default: break;
}
}
@@ -935,20 +1084,32 @@ void pcf_stat_int(Actor *actor, ieDword /*oldValue*/, ieDword newValue)
pcf_stat(actor, newValue, IE_INT);
}
-void pcf_stat_wis(Actor *actor, ieDword /*oldValue*/, ieDword newValue)
+void pcf_stat_wis(Actor *actor, ieDword oldValue, ieDword newValue)
{
pcf_stat(actor, newValue, IE_WIS);
+ if (third) {
+ int oldBonus = actor->GetAbilityBonus(IE_WIS, oldValue);
+ actor->Modified[IE_SAVEWILL] += actor->GetAbilityBonus(IE_WIS) - oldBonus;
+ }
}
-void pcf_stat_dex(Actor *actor, ieDword /*oldValue*/, ieDword newValue)
+void pcf_stat_dex(Actor *actor, ieDword oldValue, ieDword newValue)
{
pcf_stat(actor, newValue, IE_DEX);
+ if (third) {
+ int oldBonus = actor->GetAbilityBonus(IE_DEX, oldValue);
+ actor->Modified[IE_SAVEREFLEX] += actor->GetAbilityBonus(IE_DEX) - oldBonus;
+ }
}
-void pcf_stat_con(Actor *actor, ieDword /*oldValue*/, ieDword newValue)
+void pcf_stat_con(Actor *actor, ieDword oldValue, ieDword newValue)
{
pcf_stat(actor, newValue, IE_CON);
pcf_hitpoint(actor, 0, actor->BaseStats[IE_HITPOINTS]);
+ if (third) {
+ int oldBonus = actor->GetAbilityBonus(IE_CON, oldValue);
+ actor->Modified[IE_SAVEFORTITUDE] += actor->GetAbilityBonus(IE_CON) - oldBonus;
+ }
}
void pcf_stat_cha(Actor *actor, ieDword /*oldValue*/, ieDword newValue)
@@ -967,7 +1128,7 @@ void pcf_xp(Actor *actor, ieDword /*oldValue*/, ieDword /*newValue*/)
ieDword NeedsLevelUp = 0;
core->GetDictionary()->Lookup(varname, NeedsLevelUp);
if (NeedsLevelUp == 1) {
- displaymsg->DisplayConstantStringName(STR_LEVELUP, 0xffffff, actor);
+ displaymsg->DisplayConstantStringName(STR_LEVELUP, DMC_WHITE, actor);
actor->GotLUFeedback = true;
}
}
@@ -996,7 +1157,7 @@ static void handle_overlay(Actor *actor, ieDword idx)
// always draw it for party members; the rest must not be invisible to have it;
// this is just a guess, maybe there are extra conditions (MC_HIDDEN? IE_AVATARREMOVAL?)
- if (hc_flags[idx] & HC_INVISIBLE && (!actor->InParty && actor->Modified[IE_STATE_ID] & STATE_INVISIBLE)) {
+ if (hc_flags[idx] & HC_INVISIBLE && (!actor->InParty && actor->Modified[IE_STATE_ID] & state_invisible)) {
return;
}
@@ -1089,20 +1250,22 @@ void pcf_web(Actor *actor, ieDword oldValue, ieDword newValue)
//de/activates the spell bounce background
void pcf_bounce(Actor *actor, ieDword oldValue, ieDword newValue)
{
- if (newValue&1) {
+ if (newValue) {
handle_overlay(actor, OV_BOUNCE);
return;
}
- if (oldValue&1) {
+ if (oldValue) {
//it seems we have to remove it abruptly
actor->RemoveVVCell(hc_overlays[OV_BOUNCE], false);
}
}
-//no separate values (changes are permanent)
-void pcf_fatigue(Actor *actor, ieDword /*oldValue*/, ieDword newValue)
+//spell casting or other buttons disabled/reenabled
+void pcf_dbutton(Actor *actor, ieDword /*oldValue*/, ieDword /*newValue*/)
{
- actor->BaseStats[IE_FATIGUE]=newValue;
+ if (actor->IsSelected()) {
+ core->SetEventFlag( EF_ACTION );
+ }
}
//no separate values (changes are permanent)
@@ -1128,16 +1291,16 @@ void pcf_armorlevel(Actor *actor, ieDword /*oldValue*/, ieDword newValue)
}
static int maximum_values[MAX_STATS]={
-32767,32767,20,100,100,100,100,25,10,25,25,25,25,25,100,100,//0f
-100,100,100,100,100,100,100,100,100,100,255,255,255,255,100,100,//1f
+32767,32767,20,100,100,100,100,25,10,25,25,25,25,25,200,200,//0f
+200,200,200,200,200,100,100,100,100,100,255,255,255,255,100,100,//1f
200,200,MAX_LEVEL,255,25,100,25,25,25,25,25,999999999,999999999,999999999,25,25,//2f
200,255,200,100,100,200,200,25,5,100,1,1,100,1,1,0,//3f
-511,1,1,1,MAX_LEVEL,MAX_LEVEL,1,9999,25,100,100,255,1,20,20,25,//4f
+511,1,1,1,MAX_LEVEL,MAX_LEVEL,1,9999,25,200,200,255,1,20,20,25,//4f
25,1,1,255,25,25,255,255,25,255,255,255,255,255,255,255,//5f
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,//6f
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,//7f
-255,255,255,255,255,255,255,100,100,100,255,5,5,255,1,1,//8f
-1,25,25,30,1,1,1,25,0,100,100,1,255,255,255,255,//9f
+255,255,255,255,255,255,255,100,100,100,999999,5,5,999999,1,1,//8f
+1,25,25,255,1,1,1,25,0,100,100,1,255,255,255,255,//9f
255,255,255,255,255,255,20,255,255,1,20,255,999999999,999999999,1,1,//af
999999999,999999999,0,0,20,0,0,0,0,0,0,0,0,0,0,0,//bf
0,0,0,0,0,0,0,25,25,255,255,255,255,65535,0,0,//cf - 207
@@ -1152,7 +1315,7 @@ static PostChangeFunctionType post_change_functions[MAX_STATS]={
pcf_hitpoint, pcf_maxhitpoint, NULL, NULL, NULL, NULL, NULL, NULL,
NULL,NULL,NULL,NULL, NULL, NULL, NULL, NULL, //0f
NULL,NULL,NULL,NULL, NULL, NULL, NULL, NULL,
-NULL,NULL,NULL,NULL, NULL, NULL, pcf_fatigue, pcf_intoxication, //1f
+NULL,NULL,NULL,NULL, NULL, NULL, NULL, pcf_intoxication, //1f
NULL,NULL,pcf_level,NULL, pcf_stat_str, NULL, pcf_stat_int, pcf_stat_wis,
pcf_stat_dex,pcf_stat_con,pcf_stat_cha,NULL, pcf_xp, pcf_gold, pcf_morale, NULL, //2f
NULL,NULL,NULL,NULL, NULL, NULL, NULL, NULL,
@@ -1166,7 +1329,7 @@ NULL,NULL,NULL,NULL, NULL, NULL, NULL, NULL, //6f
NULL,NULL,NULL,NULL, NULL, NULL, NULL, NULL,
NULL,NULL,NULL,NULL, NULL, NULL, NULL, NULL, //7f
NULL,NULL,NULL,NULL, NULL, NULL, NULL, NULL,
-NULL,NULL,NULL,NULL, NULL, NULL, NULL, NULL, //8f
+NULL,NULL,NULL,NULL, NULL, NULL, pcf_berserk, NULL, //8f
NULL,NULL,NULL,NULL, NULL, NULL, NULL, NULL,
NULL,NULL,NULL,NULL, NULL, NULL, NULL, NULL, //9f
NULL,NULL,NULL,NULL, NULL, NULL, NULL, NULL,
@@ -1174,9 +1337,9 @@ NULL,NULL,NULL,NULL, NULL, NULL, NULL, NULL, //af
NULL,NULL,NULL,NULL, pcf_morale, pcf_bounce, NULL, NULL,
NULL,NULL,NULL,NULL, NULL, NULL, NULL, NULL, //bf
NULL,NULL,NULL,NULL, NULL, NULL, NULL, NULL,
-NULL,NULL,NULL,NULL, NULL, pcf_animid,pcf_state, pcf_extstate, //cf
+NULL,NULL,NULL,NULL, pcf_dbutton, pcf_animid,pcf_state, pcf_extstate, //cf
pcf_color,pcf_color,pcf_color,pcf_color, pcf_color, pcf_color, pcf_color, NULL,
-NULL,NULL,NULL,pcf_armorlevel, NULL, NULL, NULL, NULL, //df
+NULL,NULL,pcf_dbutton,pcf_armorlevel, NULL, NULL, NULL, NULL, //df
NULL,NULL,NULL,NULL, NULL, NULL, NULL, NULL,
pcf_class,NULL,pcf_ea,NULL, NULL, NULL, NULL, NULL, //ef
pcf_level,pcf_level,pcf_level,pcf_level, pcf_level, pcf_level, pcf_level, pcf_level,
@@ -1225,6 +1388,12 @@ void Actor::ReleaseMemory()
free(classabilities);
classabilities=NULL;
}
+
+ if (defaultprof) {
+ free(defaultprof);
+ defaultprof=NULL;
+ }
+
if (turnlevels) {
free(turnlevels);
turnlevels=NULL;
@@ -1235,6 +1404,11 @@ void Actor::ReleaseMemory()
booktypes=NULL;
}
+ if (castingstat) {
+ free(castingstat);
+ castingstat=NULL;
+ }
+
if (xpbonus) {
free(xpbonus);
xpbonus=NULL;
@@ -1254,9 +1428,13 @@ void Actor::ReleaseMemory()
free(dualswap);
dualswap=NULL;
}
- if (maxhpconbon) {
- free(maxhpconbon);
- maxhpconbon=NULL;
+ if (multi) {
+ free(multi);
+ multi=NULL;
+ }
+ if (maxLevelForHpRoll) {
+ free(maxLevelForHpRoll);
+ maxLevelForHpRoll=NULL;
}
if (skillstats) {
free(skillstats);
@@ -1267,6 +1445,16 @@ void Actor::ReleaseMemory()
skillabils=NULL;
}
+ if (afcomments) {
+ for(i=0;i<afcount;i++) {
+ if(afcomments[i]) {
+ free(afcomments[i]);
+ }
+ }
+ free(afcomments);
+ afcomments=NULL;
+ }
+
if (wspecial) {
for (i=0; i<=wspecial_max; i++) {
if (wspecial[i]) {
@@ -1334,6 +1522,10 @@ void Actor::ReleaseMemory()
free(wmlevels[i]);
wmlevels[i]=NULL;
}
+ skilldex.clear();
+ skillrac.clear();
+ IWD2HitTable.clear();
+ BABClassMap.clear();
}
if (GUIBTDefaults) {
free (GUIBTDefaults);
@@ -1345,13 +1537,6 @@ void Actor::ReleaseMemory()
classcount = -1;
}
-#define COL_HATERACE 0 //ranger type racial enemy
-#define COL_CLERIC_SPELL 1 //cleric spells
-#define COL_MAGE_SPELL 2 //mage spells
-#define COL_STARTXP 3 //starting xp
-#define COL_BARD_SKILL 4 //bard skills
-#define COL_THIEF_SKILL 5 //thief skills
-
#define COL_MAIN 0
#define COL_SPARKS 1
#define COL_GRADIENT 2
@@ -1359,7 +1544,15 @@ void Actor::ReleaseMemory()
/* returns the ISCLASS for the class based on name */
int IsClassFromName (const char* name)
{
- //TODO: is there a better way of doing this?
+ //TODO: convert this mess to a std::map
+ // iwd2 has some different names
+ if (third) {
+ if (strcmp(name, "ROGUE") == 0) {
+ return ISTHIEF;
+ } else if (strcmp(name, "WIZARD") == 0) {
+ return ISMAGE;
+ }
+ }
for (int i=0; i<ISCLASSES; i++) {
if (strcmp(name, isclassnames[i]) == 0)
return i;
@@ -1367,12 +1560,43 @@ int IsClassFromName (const char* name)
return -1;
}
+GEM_EXPORT void UpdateActorConfig()
+{
+ core->GetDictionary()->Lookup("Critical Hit Screen Shake", crit_hit_scr_shake);
+ core->GetDictionary()->Lookup("Selection Sounds Frequency", sel_snd_freq);
+ core->GetDictionary()->Lookup("Command Sounds Frequency", cmd_snd_freq);
+ core->GetDictionary()->Lookup("Bored Timeout", bored_time);
+ core->GetDictionary()->Lookup("Footsteps", footsteps);
+ //FIXME: Drop all actors' SpriteCover.
+ //the actor will change dithering only after selected/moved (its spritecover was updated)
+ core->GetDictionary()->Lookup("Always Dither", always_dither);
+
+ //Handle Game Difficulty and Nightmare Mode
+ GameDifficulty = 0;
+ core->GetDictionary()->Lookup("Nightmare Mode", GameDifficulty);
+ if (GameDifficulty) {
+ GameDifficulty = DIFF_NIGHTMARE;
+ } else {
+ GameDifficulty = 0;
+ core->GetDictionary()->Lookup("Difficulty Level", GameDifficulty);
+ }
+ if (GameDifficulty>DIFF_NIGHTMARE) GameDifficulty = DIFF_NIGHTMARE;
+
+ // iwd has a config option for leniency
+ core->GetDictionary()->Lookup("Suppress Extra Difficulty Damage", NoExtraDifficultyDmg);
+}
+
static void InitActorTables()
{
int i, j;
- pstflags = core->HasFeature(GF_PST_STATE_FLAGS);
- nocreate = core->HasFeature(GF_NO_NEW_VARIABLES);
+ UpdateActorConfig();
+ pstflags = !!core->HasFeature(GF_PST_STATE_FLAGS);
+ nocreate = !!core->HasFeature(GF_NO_NEW_VARIABLES);
+ third = !!core->HasFeature(GF_3ED_RULES);
+ raresnd = !!core->HasFeature(GF_RARE_ACTION_VB);
+ iwd2class = !!core->HasFeature(GF_LEVELSLOT_PER_CLASS);
+
if (pstflags) {
state_invisible=STATE_PST_INVIS;
} else {
@@ -1380,16 +1604,17 @@ static void InitActorTables()
}
if (core->HasFeature(GF_CHALLENGERATING)) {
- sharexp=SX_DIVIDE|SX_CR;
+ sharexp=SX_DIVIDE|SX_COMBAT|SX_CR;
} else {
- sharexp=SX_DIVIDE;
+ sharexp=SX_DIVIDE|SX_COMBAT;
}
ReverseToHit = core->HasFeature(GF_REVERSE_TOHIT);
CheckAbilities = core->HasFeature(GF_CHECK_ABILITIES);
DeathOnZeroStat = core->HasFeature(GF_DEATH_ON_ZERO_STAT);
+ IWDSound = core->HasFeature(GF_SOUNDS_INI);
//this table lists various level based xp bonuses
- AutoTable tm("xpbonus");
+ AutoTable tm("xpbonus", true);
if (tm) {
xpbonustypes = tm->GetRowCount();
if (xpbonustypes == 0) {
@@ -1419,26 +1644,33 @@ static void InitActorTables()
turnlevels = (int *) calloc(classcount, sizeof(int));
booktypes = (int *) calloc(classcount, sizeof(int));
classabilities = (char **) calloc(classcount, sizeof(char*));
+ defaultprof = (int *) calloc(classcount, sizeof(int));
+ castingstat = (int *) calloc(classcount, sizeof(int));
ieDword bitmask = 1;
for(i = 0; i<classcount; i++) {
const char *field;
- int turnlevel = atoi(tm->QueryField( i, 7));
- turnlevels[i]=turnlevel;
+ const char *rowname = tm->GetRowName(i);
- field = tm->QueryField( i, 0 );
+ field = tm->QueryField(rowname, "DRUIDSPELL");
if (field[0]!='*') {
isclass[ISDRUID] |= bitmask;
druidspelltables[i]=strdup(field);
}
- field = tm->QueryField( i, 1 );
+ field = tm->QueryField(rowname, "CLERICSPELL");
if (field[0]!='*') {
- isclass[ISCLERIC] |= bitmask;
- clericspelltables[i]=strdup(field);
+ // iwd2 has no DRUIDSPELL
+ if (third && !strnicmp(field, "MXSPLDRD", 8)) {
+ isclass[ISDRUID] |= bitmask;
+ druidspelltables[i]=strdup(field);
+ } else {
+ isclass[ISCLERIC] |= bitmask;
+ clericspelltables[i]=strdup(field);
+ }
}
- field = tm->QueryField( i, 2 );
+ field = tm->QueryField(rowname, "MAGESPELL");
if (field[0]!='*') {
isclass[ISMAGE] |= bitmask;
wizardspelltables[i]=strdup(field);
@@ -1446,41 +1678,51 @@ static void InitActorTables()
// field 3 holds the starting xp
- field = tm->QueryField( i, 4 );
+ field = tm->QueryField(rowname, "BARDSKILL");
if (field[0]!='*') {
isclass[ISBARD] |= bitmask;
}
- field = tm->QueryField( i, 5 );
+ field = tm->QueryField(rowname, "THIEFSKILL");
if (field[0]!='*') {
isclass[ISTHIEF] |= bitmask;
}
- field = tm->QueryField( i, 6 );
+ field = tm->QueryField(rowname, "LAYHANDS");
if (field[0]!='*') {
isclass[ISPALADIN] |= bitmask;
}
- // field 7 holds the turn undead level
+ field = tm->QueryField(rowname, "TURNLEVEL");
+ turnlevels[i]=atoi(field);
- field = tm->QueryField( i, 8 );
+ field = tm->QueryField(rowname, "BOOKTYPE");
booktypes[i]=atoi(field);
- //if booktype == 3 then it is a 'divine sorceror' class
+ //if booktype == 3 then it is a 'divine sorcerer' class
//we shouldn't hardcode iwd2 classes this heavily
if (booktypes[i]==2) {
isclass[ISSORCERER] |= bitmask;
}
- field = tm->QueryField( i, 9 );
+ if (third) {
+ field = tm->QueryField(rowname, "CASTING"); // COL_HATERACE but different name
+ castingstat[i] = atoi(field);
+ }
+
+ field = tm->QueryField(rowname, "HATERACE");
if (field[0]!='*') {
isclass[ISRANGER] |= bitmask;
}
- field = tm->QueryField( i, 10 );
+ field = tm->QueryField(rowname, "ABILITIES");
if (!strnicmp(field, "CLABMO", 6)) {
isclass[ISMONK] |= bitmask;
}
classabilities[i]=strdup(field);
+
+ field = tm->QueryField(rowname, "NO_PROF");
+ defaultprof[i]=atoi(field);
+
bitmask <<=1;
}
} else {
@@ -1554,18 +1796,19 @@ static void InitActorTables()
}
tm.load("qslots");
- GUIBTDefaults = (ActionButtonRow *) calloc( classcount,sizeof(ActionButtonRow) );
+ GUIBTDefaults = (ActionButtonRow *) calloc( classcount+1,sizeof(ActionButtonRow) );
- for (i = 0; i < classcount; i++) {
+ //leave room for default row at 0
+ for (i = 0; i <= classcount; i++) {
memcpy(GUIBTDefaults+i, &DefaultButtons, sizeof(ActionButtonRow));
- if (tm) {
+ if (tm && i) {
for (int j=0;j<MAX_QSLOTS;j++) {
- GUIBTDefaults[i][j+3]=(ieByte) atoi( tm->QueryField(i,j) );
+ GUIBTDefaults[i][j+3]=(ieByte) atoi( tm->QueryField(i-1,j) );
}
}
}
- tm.load("qslot2");
+ tm.load("qslot2", true);
if (tm) {
extraslots = tm->GetRowCount();
OtherGUIButtons = (ActionButtonRow2 *) calloc( extraslots, sizeof (ActionButtonRow2) );
@@ -1581,6 +1824,13 @@ static void InitActorTables()
}
}
+ tm.load("mdfeats", true);
+ if (tm) {
+ for (i=0; i<ES_COUNT; i++) {
+ strnuprcpy(featspells[i], tm->QueryField(i,0), sizeof(ieResRef)-1 );
+ }
+ }
+
tm.load("itemuse");
if (tm) {
usecount = tm->GetRowCount();
@@ -1598,7 +1848,7 @@ static void InitActorTables()
}
}
- tm.load("itemanim");
+ tm.load("itemanim", true);
if (tm) {
animcount = tm->GetRowCount();
itemanim = new ItemAnimType[animcount];
@@ -1608,7 +1858,13 @@ static void InitActorTables()
}
}
- tm.load("mxsplwis");
+ // iwd2 has mxsplbon instead, since all casters get a bonus with high enough stats (which are not always wisdom)
+ // luckily, they both use the same format
+ if (third) {
+ tm.load("mxsplbon");
+ } else {
+ tm.load("mxsplwis");
+ }
if (tm) {
spllevels = tm->GetColumnCount(0);
int max = core->GetMaximumAbility();
@@ -1623,79 +1879,153 @@ static void InitActorTables()
}
}
- tm.load("featreq");
+ tm.load("featreq", true);
if (tm) {
- unsigned int tmp;
+ unsigned int stat, max;
for(i=0;i<MAX_FEATS;i++) {
- //we need the MULTIPLE column only
- //it stores the FEAT_* stat index, and could be taken multiple
- //times
- tmp = core->TranslateStat(tm->QueryField(i,0));
- if (tmp>=MAX_STATS) {
- printMessage("Actor","Invalid stat value in featreq.2da",YELLOW);
+ //we need the MULTIPLE and MAX_LEVEL columns
+ //MULTIPLE: the FEAT_* stat index
+ //MAX_LEVEL: how many times it could be taken
+ stat = core->TranslateStat(tm->QueryField(i,0));
+ if (stat>=MAX_STATS) {
+ Log(WARNING, "Actor", "Invalid stat value in featreq.2da");
}
- featstats[i] = (ieByte) tmp;
+ max = atoi(tm->QueryField(i,1));
+ //boolean feats can only be taken once, the code requires featmax for them too
+ if (stat && (max<1)) max=1;
+ featstats[i] = (ieByte) stat;
+ featmax[i] = (ieByte) max;
}
}
- //default all hp con bonuses to 9; this should be updated below
- //TODO: check iwd2
- maxhpconbon = (int *) calloc(classcount, sizeof(int));
- for (i = 0; i < classcount; i++) {
- maxhpconbon[i] = 9;
- }
+ maxLevelForHpRoll = (int *) calloc(classcount, sizeof(int));
tm.load("classes");
- if (tm && !core->HasFeature(GF_LEVELSLOT_PER_CLASS)) {
+ if (!tm) {
+ error("Actor", "Missing classes.2da!");
+ }
+ if (iwd2class) {
+ //kitcount = 0;
+ // we need to set up much less here due to a saner class/level system in 3ed
+ Log(MESSAGE, "Actor", "Examining IWD2-style classes.2da");
+ AutoTable tht;
+ for (i=0; i<classcount; i++) {
+ const char *classname = tm->GetRowName(i);
+ int classis = IsClassFromName(classname);
+ ieDword classID = atoi(tm->QueryField(classname, "ID"));
+ ieDword classcol = atoi(tm->QueryField(classname, "CLASS")); // only real classes have this column at 0
+ if (classcol) {
+ //kitcount++;
+ continue;
+ }
+
+ // set up the tohit/apr tables
+ char tohit[9];
+ strnuprcpy(tohit, tm->QueryField(classname, "TOHIT"), 8);
+ BABClassMap[classis] = strdup(tohit);
+ // the tables repeat, but we need to only load one copy
+ // FIXME: the attempt at skipping doesn't work!
+ IWD2HitTableIter it = IWD2HitTable.find(tohit);
+ if (it == IWD2HitTable.end()) {
+ tht.load(tohit, true);
+ if (!tht || !tohit[0]) {
+ error("Actor", "TOHIT table for %s does not exist!", classname);
+ }
+ ieDword row;
+ BABTable bt;
+ std::vector<BABTable> btv;
+ btv.reserve(tht->GetRowCount());
+ for (row = 0; row < tht->GetRowCount(); row++) {
+ bt.level = atoi(tht->GetRowName(row));
+ bt.bab = atoi(tht->QueryField(row, 0));
+ bt.apr = atoi(tht->QueryField(row, 1));
+ btv.push_back(bt);
+ }
+ IWD2HitTable.insert(std::make_pair (BABClassMap[classis], btv));
+ }
+
+ StringBuffer buffer;
+ buffer.appendFormatted("\tID: %d, ", classID);
+ buffer.appendFormatted("Name: %s, ", classname);
+ buffer.appendFormatted("Classis: %d, ", classis);
+ buffer.appendFormatted("ToHit: %s ", tohit);
+
+ //TODO: generate classesiwd2 here, so it can be unhardcoded
+ Log(DEBUG, "Actor", buffer);
+ }
+ /*
+ //pass two: iwd2 kit usabilities
+ kituse = (ieDword *) calloc(kitcount, sizeof(ieDword) );
+ int idx = 0;
+ for(i=0;i<classcount;i++) {
+ const char *classname = tm->GetRowName(i);
+ ieDword classcol = atoi(tm->QueryField(classname, "CLASS") );
+ ieDword usability = strtoul(tm->QueryField(classname, "USABILITY"), NULL, 0 );
+ if (!classcol) continue;
+ kituse[j++]=usability;
+ }
+ */
+ } else {
AutoTable hptm;
//iwd2 just uses levelslotsiwd2 instead
- printf("Examining classes.2da\n");
+ Log(MESSAGE, "Actor", "Examining classes.2da");
//when searching the levelslots, you must search for
//levelslots[BaseStats[IE_CLASS]-1] as there is no class id of 0
levelslots = (int **) calloc(classcount, sizeof(int*));
dualswap = (int *) calloc(classcount, sizeof(int));
+ multi = (int *) calloc(classcount, sizeof(int));
ieDword tmpindex;
+
+ memset(classesiwd2, 0 , sizeof(classesiwd2) );
for (i=0; i<classcount; i++) {
+ const char* classname = tm->GetRowName(i);
//make sure we have a valid classid, then decrement
//it to get the correct array index
- tmpindex = atoi(tm->QueryField(i, 5));
+ tmpindex = atoi(tm->QueryField(classname, "ID"));
if (!tmpindex)
continue;
tmpindex--;
- printf("\tID: %d ", tmpindex);
+ StringBuffer buffer;
+ buffer.appendFormatted("\tID: %d ", tmpindex);
//only create the array if it isn't yet made
//i.e. barbarians would overwrite fighters in bg2
if (levelslots[tmpindex]) {
- printf ("Already Found!\n");
+ buffer.appendFormatted("Already Found!");
+ Log(DEBUG, "Actor", buffer);
continue;
}
- const char* classname = tm->GetRowName(i);
- printf("Name: %s ", classname);
+ buffer.appendFormatted("Name: %s ", classname);
int classis = 0;
//default all levelslots to 0
levelslots[tmpindex] = (int *) calloc(ISCLASSES, sizeof(int));
//single classes only worry about IE_LEVEL
- ieDword tmpclass = atoi(tm->QueryField(i, 4));
+ long tmpclass = 0;
+ valid_number(tm->QueryField(classname, "MULTI"), tmpclass);
+ multi[tmpindex] = (ieDword) tmpclass;
if (!tmpclass) {
classis = IsClassFromName(classname);
if (classis>=0) {
- printf("Classis: %d ", classis);
+ //store the original class ID as iwd2 compatible ISCLASS (internal class number)
+ classesiwd2[classis] = tmpindex+1;
+
+ buffer.appendFormatted("Classis: %d ", classis);
levelslots[tmpindex][classis] = IE_LEVEL;
- //get the max hp con bonus
- hptm.load(tm->QueryField(i, 6));
+ //get the last level when we can roll for HP
+ hptm.load(tm->QueryField(classname, "HP"), true);
if (hptm) {
int tmphp = 0;
int rollscolumn = hptm->GetColumnIndex("ROLLS");
while (atoi(hptm->QueryField(tmphp, rollscolumn)))
tmphp++;
- printf("TmpHP: %d ", tmphp);
- if (tmphp) maxhpconbon[tmpindex] = tmphp;
+ buffer.appendFormatted("HPROLLMAXLVL: %d", tmphp);
+ if (tmphp) maxLevelForHpRoll[tmpindex] = tmphp;
}
}
+ Log(DEBUG, "Actor", buffer);
continue;
}
@@ -1718,7 +2048,7 @@ static void InitActorTables()
break;
if ((1<<j)&tmpclass) {
//save the IE_LEVEL information
- const char* currentname = tm->GetRowName((ieDword)(tm->FindTableValue(5, j+1)));
+ const char* currentname = tm->GetRowName((ieDword)(tm->FindTableValue("ID", j+1)));
classis = IsClassFromName(currentname);
if (classis>=0) {
//search for the current class in the split of the names to get it's
@@ -1732,21 +2062,21 @@ static void InitActorTables()
levelslots[tmpindex][classis] = tmplevel;
}
}
- printf("Classis: %d ", classis);
+ buffer.appendFormatted("Classis: %d ", classis);
- //warrior take presedence
+ //warrior take precedence
if (!foundwarrior) {
foundwarrior = (classis==ISFIGHTER||classis==ISRANGER||classis==ISPALADIN||
classis==ISBARBARIAN);
- hptm.load(tm->QueryField(currentname, "HP"));
+ hptm.load(tm->QueryField(currentname, "HP"), true);
if (hptm) {
int tmphp = 0;
int rollscolumn = hptm->GetColumnIndex("ROLLS");
while (atoi(hptm->QueryField(tmphp, rollscolumn)))
tmphp++;
//make sure we at least set the first class
- if ((tmphp>maxhpconbon[tmpindex])||foundwarrior||numfound==0)
- maxhpconbon[tmpindex]=tmphp;
+ if ((tmphp>maxLevelForHpRoll[tmpindex])||foundwarrior||numfound==0)
+ maxLevelForHpRoll[tmpindex]=tmphp;
}
}
}
@@ -1754,14 +2084,15 @@ static void InitActorTables()
//save the MC_WAS_ID of the first class in the dual-class
if (numfound==0 && tmpbits==2) {
if (strcmp(classnames[0], currentname) == 0) {
- dualswap[tmpindex] = strtol(tm->QueryField(classname, "MC_WAS_ID"), NULL, 0);
+ dualswap[tmpindex] = strtol(tm->QueryField(currentname, "MC_WAS_ID"), NULL, 0);
}
} else if (numfound==1 && tmpbits==2 && !dualswap[tmpindex]) {
- dualswap[tmpindex] = strtol(tm->QueryField(classname, "MC_WAS_ID"), NULL, 0);
+ dualswap[tmpindex] = strtol(tm->QueryField(currentname, "MC_WAS_ID"), NULL, 0);
}
numfound++;
}
}
+
if (classnames) {
for (ieDword j=0; j<tmpbits; j++) {
if (classnames[j]) {
@@ -1771,8 +2102,11 @@ static void InitActorTables()
free(classnames);
classnames = NULL;
}
- printf("HPCON: %d ", maxhpconbon[tmpindex]);
- printf("DS: %d\n", dualswap[tmpindex]);
+
+ buffer.appendFormatted("HPROLLMAXLVL: %d ", maxLevelForHpRoll[tmpindex]);
+ buffer.appendFormatted("DS: %d ", dualswap[tmpindex]);
+ buffer.appendFormatted("MULTI: %d", multi[tmpindex]);
+ Log(DEBUG, "Actor", buffer);
}
/*this could be enabled to ensure all levelslots are filled with at least 0's;
*however, the access code should ensure this never happens
@@ -1782,7 +2116,7 @@ static void InitActorTables()
}
}*/
}
- printf("Finished examining classes.2da\n");
+ Log(MESSAGE, "Actor", "Finished examining classes.2da");
//pre-cache hit/damage/speed bonuses for weapons
tm.load("wspecial");
@@ -1814,15 +2148,19 @@ static void InitActorTables()
tmp = atoi(tm->QueryField(i, j));
//negative values relate to x/2, so we adjust them
//positive values relate to x, so we must times by 2
- if (tmp<0) tmp = -2*tmp-1;
- else tmp *= 2;
+ if (tmp<0) {
+ tmp = -2*tmp-1;
+ }
+ else {
+ tmp *= 2;
+ }
wspattack[i][j] = tmp;
}
}
}
//dual-wielding table
- tm.load("wstwowpn");
+ tm.load("wstwowpn", true);
if (tm) {
wsdualwield = (int **) calloc(STYLE_MAX+1, sizeof(int *));
int cols = tm->GetColumnCount();
@@ -1835,7 +2173,7 @@ static void InitActorTables()
}
//two-handed table
- tm.load("wstwohnd");
+ tm.load("wstwohnd", true);
if (tm) {
wstwohanded = (int **) calloc(STYLE_MAX+1, sizeof(int *));
int cols = tm->GetColumnCount();
@@ -1847,8 +2185,8 @@ static void InitActorTables()
}
}
- //two-handed table
- tm.load("wsshield");
+ //shield table
+ tm.load("wsshield", true);
if (tm) {
wsswordshield = (int **) calloc(STYLE_MAX+1, sizeof(int *));
int cols = tm->GetColumnCount();
@@ -1860,7 +2198,7 @@ static void InitActorTables()
}
}
- //two-handed table
+ //single-handed table
tm.load("wssingle");
if (tm) {
wssingle = (int **) calloc(STYLE_MAX+1, sizeof(int *));
@@ -1874,14 +2212,14 @@ static void InitActorTables()
}
//unhardcoded monk bonus table
- tm.load("monkbon");
+ tm.load("monkbon", true);
if (tm) {
monkbon_rows = tm->GetRowCount();
monkbon_cols = tm->GetColumnCount();
monkbon = (int **) calloc(monkbon_rows, sizeof(int *));
for (unsigned i=0; i<monkbon_rows; i++) {
monkbon[i] = (int *) calloc(monkbon_cols, sizeof(int));
- for (unsigned j=0; j<monkbon_cols; j++) {
+ for (unsigned j=0; j<monkbon_cols; j++) {
monkbon[i][j] = atoi(tm->QueryField(i, j));
}
}
@@ -1891,7 +2229,7 @@ static void InitActorTables()
for(i=0;i<20;i++) {
wmlevels[i]=(int *) calloc(MAX_LEVEL,sizeof(int) );
}
- tm.load("lvlmodwm");
+ tm.load("lvlmodwm", true);
if (tm) {
int maxrow = tm->GetRowCount();
for (i=0;i<20;i++) {
@@ -1921,20 +2259,128 @@ static void InitActorTables()
}
}
- //initializing the skill->stats conversion table (used in iwd2)
- tm.load("skillsta");
- if (tm) {
- int rowcount = tm->GetRowCount();
- skillcount = rowcount;
- if (rowcount) {
- skillstats = (int *) malloc(rowcount * sizeof(int) );
- skillabils = (int *) malloc(rowcount * sizeof(int) );
- while(rowcount--) {
- skillstats[rowcount]=core->TranslateStat(tm->QueryField(rowcount,0));
- skillabils[rowcount]=core->TranslateStat(tm->QueryField(rowcount,1));
- }
- }
+ //initializing the skill->stats conversion table (used in iwd2)
+ tm.load("skillsta", true);
+ if (tm) {
+ int rowcount = tm->GetRowCount();
+ skillcount = rowcount;
+ if (rowcount) {
+ skillstats = (int *) malloc(rowcount * sizeof(int) );
+ skillabils = (int *) malloc(rowcount * sizeof(int) );
+ while(rowcount--) {
+ skillstats[rowcount]=core->TranslateStat(tm->QueryField(rowcount,0));
+ skillabils[rowcount]=core->TranslateStat(tm->QueryField(rowcount,1));
+ }
+ }
+ }
+
+ //initializing area flag comments
+ tm.load("comment");
+ if (tm) {
+ int rowcount = tm->GetRowCount();
+ afcount = rowcount;
+ if (rowcount) {
+ afcomments = (int **) calloc(rowcount, sizeof(int *) );
+ while(rowcount--) {
+ afcomments[rowcount]=(int *) malloc(3*sizeof(int) );
+ for(i=0;i<3;i++) {
+ afcomments[rowcount][i] = strtol(tm->QueryField(rowcount,i), NULL, 0);
+ }
+ }
+ }
+ }
+
+ // dexterity modifier for thieving skills
+ tm.load("skilldex");
+ if (tm) {
+ int skilldexNCols = tm->GetColumnCount();
+ int skilldexNRows = tm->GetRowCount();
+ skilldex.reserve(skilldexNRows);
+
+ for (i = 0; i < skilldexNRows; i++) {
+ skilldex.push_back (std::vector<int>());
+ skilldex[i].reserve(skilldexNCols+1);
+ for(j = -1; j < skilldexNCols; j++) {
+ if (j == -1) {
+ skilldex[i].push_back (atoi(tm->GetRowName(i)));
+ } else {
+ skilldex[i].push_back (atoi(tm->QueryField(i, j)));
+ }
+ }
+ }
+ }
+
+ // race modifier for thieving skills
+ tm.load("skillrac");
+ int value = 0;
+ int racetable = core->LoadSymbol("race");
+ Holder<SymbolMgr> race = NULL;
+ if (racetable != -1) {
+ race = core->GetSymbol(racetable);
+ }
+ if (tm) {
+ int cols = tm->GetColumnCount();
+ int rows = tm->GetRowCount();
+ skillrac.reserve(rows);
+
+ for (i = 0; i < rows; i++) {
+ skillrac.push_back (std::vector<int>());
+ skillrac[i].reserve(cols+1);
+ for(j = -1; j < cols; j++) {
+ if (j == -1) {
+ // figure out the value from the race name
+ if (racetable == -1) {
+ value = 0;
+ } else {
+ value = race->GetValue(tm->GetRowName(i));
+ }
+ skillrac[i].push_back (value);
+ } else {
+ skillrac[i].push_back (atoi(tm->QueryField(i, j)));
+ }
+ }
+ }
+ }
+
+ //difficulty level based modifiers
+ tm.load("difflvls");
+ if (tm) {
+ memset(xpadjustments, 0, sizeof(xpadjustments) );
+ memset(dmgadjustments, 0, sizeof(dmgadjustments) );
+ for (i=0; i<6; i++) {
+ dmgadjustments[i] = atoi(tm->QueryField(0, i) );
+ xpadjustments[i] = atoi(tm->QueryField(1, i) );
+ }
+ }
+
+ //preload stat derived animation tables
+ tm.load("avprefix");
+ delete [] avPrefix;
+ avBase = 0;
+ avCount = -1;
+ if (tm) {
+ int count = tm->GetRowCount();
+ if (count> 0 && count<8) {
+ avCount = count-1;
+ avPrefix = new avType[count];
+ avBase = strtoul(tm->QueryField(0),NULL, 0);
+ const char *poi = tm->QueryField(0,1);
+ if (*poi!='*') {
+ avStance = strtoul(tm->QueryField(0,1),NULL, 0);
+ } else {
+ avStance = -1;
+ }
+ for (i=0;i<avCount;i++) {
+ strnuprcpy(avPrefix[i].avresref, tm->QueryField(i+1), 8);
+ avPrefix[i].avtable.load(avPrefix[i].avresref);
+ if (avPrefix[i].avtable) {
+ avPrefix[i].stat = core->TranslateStat(avPrefix[i].avtable->QueryField(0));
+ } else {
+ avPrefix[i].stat = -1;
}
+ }
+ }
+ }
}
void Actor::SetLockedPalette(const ieDword *gradients)
@@ -1969,14 +2415,117 @@ void Actor::AddAnimation(const ieResRef resource, int gradient, int height, int
AddVVCell(sca);
}
+ieDword Actor::GetSpellFailure(bool arcana) const
+{
+ ieDword base = arcana?Modified[IE_SPELLFAILUREMAGE]:Modified[IE_SPELLFAILUREPRIEST];
+ if (HasSpellState(SS_DOMINATION)) base += 100;
+ if (HasSpellState(SS_BLINK)) base += 20;
+ // IWD2 has this as 20, other games as 50
+ if (HasSpellState(SS_DEAF)) {
+ base += 20;
+ if (!third) base += 30;
+ }
+ if (!arcana) return base;
+
+ ieDword armor = GetTotalArmorFailure();
+
+ if (armor) {
+ ieDword feat = GetFeat(FEAT_ARMORED_ARCANA);
+ if (armor<feat) armor = 0;
+ else armor -= feat;
+ }
+
+ return base+armor*5;
+}
+
+//dexterity AC (the lesser the better), do another negation for 3ED rules
+int Actor::GetDexterityAC() const
+{
+ if (!third) {
+ return core->GetDexterityBonus(STAT_DEX_AC, GetStat(IE_DEX));
+ }
+
+ int dexbonus = GetAbilityBonus(IE_DEX);
+ if (dexbonus) {
+ // the maximum dexterity bonus isn't stored,
+ // but can reliably be calculated from 8-spell failure (except for robes, which have no limit)
+ ieWord armtype = inventory.GetArmorItemType();
+ int armor = (int) core->GetArmorFailure(armtype);
+
+ if (armor) {
+ armor = 8-armor;
+ if (dexbonus>armor) {
+ dexbonus = armor;
+ }
+ }
+
+ //blindness negates the dexbonus
+ if ((GetStat(IE_STATE_ID)&STATE_BLIND) && !HasFeat(FEAT_BLIND_FIGHT)) {
+ dexbonus = 0;
+ }
+ }
+ return dexbonus;
+}
+
+//wisdom AC bonus for 3ed light monks
+int Actor::GetWisdomAC() const
+{
+ if (!third || !GetStat(IE_LEVELMONK)) {
+ return 0;
+ }
+
+ int bonus = 0;
+ //if the monk has a shield equipped, no bonus
+ int itemtype = inventory.GetShieldItemType();
+ //items with critical range are weapons, not shields, so they are ok
+ //empty hand is also ok
+ if (itemtype == 0xffff && !core->GetShieldPenalty(itemtype)) {
+ bonus = GetAbilityBonus(IE_WIS);
+ }
+ return bonus;
+}
+
+//Returns the personal critical damage type in a binary compatible form (PST)
+int Actor::GetCriticalType() const
+{
+ long ret = 0;
+ AutoTable tm("crits", true);
+ if (!tm) return 0;
+ //the ID of this PC (first 2 rows are empty)
+ int row = BaseStats[IE_SPECIFIC];
+ //defaults to 0
+ valid_number(tm->QueryField(row, 1), ret);
+ return (int) ret;
+}
+
+//Plays personal critical damage animation for PST PC's melee attacks
+void Actor::PlayCritDamageAnimation(int type)
+{
+ AutoTable tm("crits");
+ if (!tm) return;
+ //the ID's are in column 1, selected by specifics by GetCriticalType
+ int row = tm->FindTableValue (1, type);
+ if (row>=0) {
+ //the animations are listed in column 0
+ AddAnimation(tm->QueryField(row, 0), -1, 0, AA_PLAYONCE);
+ }
+}
+
void Actor::PlayDamageAnimation(int type, bool hit)
{
int i;
- printf("Damage animation type: %d\n", type);
+ Log(COMBAT, "Actor", "Damage animation type: %d", type);
- switch(type) {
- case 0: case 1: case 2: case 3: //blood
+ switch(type&255) {
+ case 0:
+ //PST specific personal criticals
+ if (type&0xff00) {
+ PlayCritDamageAnimation(type>>8);
+ break;
+ }
+ //fall through
+ case 1: case 2: case 3: //blood
i = anims->GetBloodColor();
if (!i) i = d_gradient[type];
if(hit) {
@@ -2017,21 +2566,28 @@ void Actor::PlayDamageAnimation(int type, bool hit)
}
}
+ieDword Actor::ClampStat(unsigned int StatIndex, ieDword Value) const
+{
+ if (StatIndex < MAX_STATS) {
+ if ((signed) Value < -100) {
+ Value = (ieDword) -100;
+ } else {
+ if (maximum_values[StatIndex] > 0) {
+ if ( (signed) Value > maximum_values[StatIndex]) {
+ Value = (ieDword) maximum_values[StatIndex];
+ }
+ }
+ }
+ }
+ return Value;
+}
+
bool Actor::SetStat(unsigned int StatIndex, ieDword Value, int pcf)
{
if (StatIndex >= MAX_STATS) {
return false;
}
- if ( (signed) Value<-100) {
- Value = (ieDword) -100;
- }
- else {
- if ( maximum_values[StatIndex]>0) {
- if ( (signed) Value>maximum_values[StatIndex]) {
- Value = (ieDword) maximum_values[StatIndex];
- }
- }
- }
+ Value = ClampStat(StatIndex, Value);
unsigned int previous = GetSafeStat(StatIndex);
if (Modified[StatIndex]!=Value) {
@@ -2072,12 +2628,7 @@ bool Actor::SetBase(unsigned int StatIndex, ieDword Value)
ieDword diff = Modified[StatIndex]-BaseStats[StatIndex];
//maximize the base stat
- if ( maximum_values[StatIndex]) {
- if ( (signed) Value>maximum_values[StatIndex]) {
- Value = (ieDword) maximum_values[StatIndex];
- }
- }
-
+ Value = ClampStat(StatIndex, Value);
BaseStats[StatIndex] = Value;
//if already initialized, then the modified stats
@@ -2094,12 +2645,7 @@ bool Actor::SetBaseNoPCF(unsigned int StatIndex, ieDword Value)
ieDword diff = Modified[StatIndex]-BaseStats[StatIndex];
//maximize the base stat
- if ( maximum_values[StatIndex]) {
- if ( (signed) Value>maximum_values[StatIndex]) {
- Value = (ieDword) maximum_values[StatIndex];
- }
- }
-
+ Value = ClampStat(StatIndex, Value);
BaseStats[StatIndex] = Value;
//if already initialized, then the modified stats
@@ -2179,6 +2725,52 @@ void Actor::DisablePortraitIcon(ieByte icon)
}
}
+
+//hack to get the proper casting sounds of copied images
+ieDword Actor::GetCGGender()
+{
+ ieDword gender = Modified[IE_SEX];
+ if (gender == SEX_ILLUSION) {
+ Actor *master = core->GetGame()->GetActorByGlobalID(Modified[IE_PUPPETMASTERID]);
+ if (master) {
+ gender = master->Modified[IE_SEX];
+ }
+ }
+
+ return gender;
+}
+
+#define PI_PROJIMAGE 77
+
+void Actor::CheckPuppet(Actor *puppet, ieDword type)
+{
+ if (!puppet) return;
+ if (puppet->Modified[IE_STATE_ID]&STATE_DEAD) return;
+
+ switch(type) {
+ case 1:
+ Modified[IE_STATE_ID] |= state_invisible;
+ //also set the improved invisibility flag where available
+ if (!pstflags) {
+ Modified[IE_STATE_ID]|=STATE_INVIS2;
+ }
+ break;
+ case 2:
+ if (InterruptCasting) {
+ // dispel the projected image if there is any
+ puppet->DestroySelf();
+ return;
+ }
+ Modified[IE_HELD]=1;
+ AddPortraitIcon(PI_PROJIMAGE);
+ Modified[IE_STATE_ID]|=STATE_HELPLESS;
+ break;
+ }
+ Modified[IE_PUPPETTYPE] = type;
+ Modified[IE_PUPPETID] = puppet->GetGlobalID();
+}
+
+
/** call this after load, to apply effects */
void Actor::RefreshEffects(EffectQueue *fx)
{
@@ -2219,6 +2811,8 @@ void Actor::RefreshEffects(EffectQueue *fx)
if (PCStats) {
memset( PCStats->PortraitIcons, -1, sizeof(PCStats->PortraitIcons) );
}
+ AC.ResetAll();
+ ToHit.ResetAll(); // effects can result in the change of any of the boni, so we need to reset all
if (fx) {
fx->SetOwner(this);
@@ -2230,6 +2824,8 @@ void Actor::RefreshEffects(EffectQueue *fx)
//also clear the spell bonuses just given, they will be
//recalculated below again
spellbook.ClearBonus();
+ //AC.ResetAll(); // TODO: check if this is needed
+ //ToHit.ResetAll();
}
unsigned int i;
@@ -2242,15 +2838,74 @@ void Actor::RefreshEffects(EffectQueue *fx)
if (vvcShields[i] && vvcShields[i]->effect_owned) vvcShields[i]->active = false;
}
+ // apply palette changes not caused by persistent effects
+ if (Modified[IE_STATE_ID] & STATE_PETRIFIED) {
+ SetLockedPalette(fullstone);
+ } else if (Modified[IE_STATE_ID] & STATE_FROZEN) {
+ SetLockedPalette(fullwhite);
+ }
+
+ // give the 3ed save bonus before applying the effects, since they may do extra rolls
+ if (third) {
+ Modified[IE_SAVEWILL] += GetAbilityBonus(IE_WIS);
+ Modified[IE_SAVEREFLEX] += GetAbilityBonus(IE_DEX);
+ Modified[IE_SAVEFORTITUDE] += GetAbilityBonus(IE_CON);
+ // paladins add their charisma modifier to all saving throws
+ if (GetPaladinLevel()) {
+ Modified[IE_SAVEWILL] += GetAbilityBonus(IE_CHR);
+ Modified[IE_SAVEREFLEX] += GetAbilityBonus(IE_CHR);
+ Modified[IE_SAVEFORTITUDE] += GetAbilityBonus(IE_CHR);
+ }
+ }
+
fxqueue.ApplyAllEffects( this );
+
+ if (previous[IE_PUPPETID]) {
+ CheckPuppet(core->GetGame()->GetActorByGlobalID(previous[IE_PUPPETID]), previous[IE_PUPPETTYPE]);
+ }
+
//move this further down if needed
PrevStats = NULL;
+ for (std::list<TriggerEntry>::iterator m = triggers.begin(); m != triggers.end (); m++) {
+ m->flags |= TEF_PROCESSED_EFFECTS;
+
+ // snap out of charm if the charmer hurt us
+ if (m->triggerID == trigger_attackedby) {
+ Actor *attacker = core->GetGame()->GetActorByGlobalID(LastAttacker);
+ if (attacker) {
+ int revertToEA = 0;
+ if (Modified[IE_EA] == EA_CHARMED && attacker->GetStat(IE_EA) <= EA_GOODCUTOFF) {
+ revertToEA = EA_ENEMY;
+ } else if (Modified[IE_EA] == EA_CHARMEDPC && attacker->GetStat(IE_EA) >= EA_EVILCUTOFF) {
+ revertToEA = EA_PC;
+ }
+ if (revertToEA) {
+ // remove only the plain charm effect
+ Effect *charmfx = fxqueue.HasEffectWithParam(fx_set_charmed_state_ref, 1);
+ if (!charmfx) charmfx = fxqueue.HasEffectWithParam(fx_set_charmed_state_ref, 1001);
+ if (charmfx) {
+ SetStat(IE_EA, revertToEA, 1);
+ fxqueue.RemoveEffect(charmfx);
+ }
+ }
+ }
+ }
+ }
+ // we need to recalc these, since the stats or equipped gear may have changed (and this is relevant in iwd2)
+ AC.SetWisdomBonus(GetWisdomAC());
+ AC.SetDexterityBonus(GetDexterityAC()); // FIXME: but the effects may reset this too and we shouldn't touch it in that case (flatfooted!)
+
// IE_CLASS is >classcount for non-PCs/NPCs
- if (BaseStats[IE_CLASS] <= (ieDword)classcount)
+ if (BaseStats[IE_CLASS] > 0 && BaseStats[IE_CLASS] < (ieDword)classcount)
RefreshPCStats();
- for (i=0;i<MAX_STATS;i++) {
+ //if the animation ID was not modified by any effect, it may still be modified by something else
+ if (Modified[IE_ANIMATION_ID] == BaseStats[IE_ANIMATION_ID]) {
+ UpdateAnimationID(true);
+ }
+
+ for (i=0;i<MAX_STATS;i++) {
if (first || Modified[i]!=previous[i]) {
PostChangeFunctionType f = post_change_functions[i];
if (f) {
@@ -2258,11 +2913,26 @@ void Actor::RefreshEffects(EffectQueue *fx)
}
}
}
- //add wisdom bonus spells
- if (!spellbook.IsIWDSpellBook() && mxsplwis) {
- int level = Modified[IE_WIS];
- if (level--) {
- spellbook.BonusSpells(IE_SPELL_TYPE_PRIEST, spllevels, mxsplwis+spllevels*level);
+ //add wisdom/casting_ability bonus spells
+ if (mxsplwis) {
+ if (spellbook.IsIWDSpellBook()) {
+ // check each class separately for the casting stat and booktype (luckily there is no bonus for domain spells)
+ for (i=0; i < ISCLASSES; i++) {
+ int level = GetClassLevel(i);
+ int booktype = booksiwd2[i]; // ieIWD2SpellType
+ if (!level || booktype == -1) {
+ continue;
+ }
+ level = Modified[castingstat[classesiwd2[i]]];
+ if (level--) {
+ spellbook.BonusSpells(booktype, spllevels, mxsplwis+spllevels*level);
+ }
+ }
+ } else {
+ int level = Modified[IE_WIS];
+ if (level--) {
+ spellbook.BonusSpells(IE_SPELL_TYPE_PRIEST, spllevels, mxsplwis+spllevels*level);
+ }
}
}
@@ -2275,58 +2945,145 @@ void Actor::RefreshEffects(EffectQueue *fx)
}
}
-// refresh stats on creatures (PC or NPC) with a valid class (not animals etc)
-// internal use only, and this is maybe a stupid name :)
-void Actor::RefreshPCStats() {
- //calculate hp bonus
+int Actor::GetProficiency(int proftype) const
+{
+ switch(proftype) {
+ case -2: //hand to hand old style
+ return 1;
+ case -1: //no proficiency
+ return 0;
+ default:
+ //bg1 style proficiencies
+ if(proftype>=0 && proftype<=IE_EXTRAPROFICIENCY20-IE_PROFICIENCYBASTARDSWORD) {
+ return GetStat(IE_PROFICIENCYBASTARDSWORD+proftype);
+ }
+
+ //bg2 style proficiencies
+ if (proftype>=IE_PROFICIENCYBASTARDSWORD && proftype<=IE_EXTRAPROFICIENCY20) {
+ return GetStat(proftype);
+ }
+ return 0;
+ }
+}
+
+// recalculates the constitution bonus to hp and adds it to the stat
+void Actor::RefreshHP() {
+ // calculate the hp bonus for each level
+ // single-classed characters:
+ // apply full constitution bonus for levels up (and including) to maxLevelForHpRoll
+ // dual-classed characters:
+ // while inactive, there is no consititution bonus and hp gain AT ALL
+ // afterwards, the same applies as for single-classed characters again
+ // consititution bonus is NOT taken from the max of classes
+ // multi-classed characters:
+ // apply the highest constitution bonus for levels up (and including) to maxLevelForHpRoll (already the max of the classes)
+ // BUT divide it by the number of classes (ideally the last one to levelup should get all the fractions)
+ // for levels after maxLevelForHpRoll there is NO constitution bonus anymore
+ // IN IWD2, it's a simple level*conbon calculation without any fiddling
int bonus;
+ // this is wrong for dual-classed (so we override it later)
+ // and sometimes marginally wrong for multi-classed (but we usually round the average up)
int bonlevel = GetXPLevel(true);
- int oldlevel, oldbonus;
- oldlevel = oldbonus = 0;
ieDword bonindex = BaseStats[IE_CLASS]-1;
//we must limit the levels to the max allowable
- if (bonlevel>maxhpconbon[bonindex])
- bonlevel = maxhpconbon[bonindex];
+ if (third) {
+ bonlevel = Modified[IE_CLASSLEVELSUM];
+ } else {
+ if (bonlevel>maxLevelForHpRoll[bonindex]) {
+ bonlevel = maxLevelForHpRoll[bonindex];
+ }
+ }
+ if (IsDualClassed()) {
+ int oldbonus = 0;
- if (IsDualInactive()) {
- //we apply the inactive hp bonus if it's better than the new hp bonus, so that we
- //never lose hp, only gain, on leveling
- oldlevel = IsDualSwap() ? BaseStats[IE_LEVEL] : BaseStats[IE_LEVEL2];
+ // just the old consititution bonus
+ int oldlevel = IsDualSwap() ? BaseStats[IE_LEVEL] : BaseStats[IE_LEVEL2];
bonlevel = IsDualSwap() ? BaseStats[IE_LEVEL2] : BaseStats[IE_LEVEL];
- oldlevel = (oldlevel > maxhpconbon[bonindex]) ? maxhpconbon[bonindex] : oldlevel;
+ oldlevel = (oldlevel > maxLevelForHpRoll[bonindex]) ? maxLevelForHpRoll[bonindex] : oldlevel;
+ // give the bonus only for the levels where there were actually rolls
+ // if we wanted to be really strict, the old bonindex and max roll level would need to be looked up
+ if (oldlevel == maxLevelForHpRoll[bonindex]) {
+ bonlevel = 0;
+ } else {
+ bonlevel -= oldlevel; // the actual number of "rolling" levels for the new bonus
+ if (bonlevel+oldlevel > maxLevelForHpRoll[bonindex]) {
+ bonlevel = maxLevelForHpRoll[bonindex] - oldlevel;
+ }
+ }
+ if (bonlevel < 0) bonlevel = 0;
if (Modified[IE_MC_FLAGS] & (MC_WAS_FIGHTER|MC_WAS_RANGER)) {
oldbonus = core->GetConstitutionBonus(STAT_CON_HP_WARRIOR, Modified[IE_CON]);
} else {
oldbonus = core->GetConstitutionBonus(STAT_CON_HP_NORMAL, Modified[IE_CON]);
}
+ bonus = oldbonus * oldlevel;
+
+ // but if the class is already reactivated ...
+ if (!IsDualInactive()) {
+ // add in the bonus for the levels of the new class
+ // since there are no warrior to warrior dual-classes, just invert the previous check to get the right conmod
+ if (Modified[IE_MC_FLAGS] & (MC_WAS_FIGHTER|MC_WAS_RANGER)) {
+ bonus += bonlevel * core->GetConstitutionBonus(STAT_CON_HP_NORMAL, Modified[IE_CON]);
+ } else {
+ bonus += GetHpAdjustment(bonlevel);
+ }
+ }
+ } else {
+ bonus = GetHpAdjustment(bonlevel);
}
- // warrior (fighter, barbarian, ranger, or paladin) or not
- // GetClassLevel now takes into consideration inactive dual-classes
- bonus = GetHpAdjustment(bonlevel);
- oldbonus *= oldlevel;
- bonus = (oldbonus > bonus) ? oldbonus : bonus;
+ if (bonus<0 && (Modified[IE_MAXHITPOINTS]+bonus)<=0) {
+ bonus=1-Modified[IE_MAXHITPOINTS];
+ }
+
+ //toughness feat bonus (could be unhardcoded as a max hp bonus based on level if you want)
+ bonus += Modified[IE_FEAT_TOUGHNESS]*3;
+
+ //we still apply the maximum bonus to dead characters, but don't apply
+ //to current HP, or we'd have dead characters showing as having hp
+ Modified[IE_MAXHITPOINTS]+=bonus;
+ // applying the bonus to the current hitpoints is trickier, since we don't want to cause regeneration
+ /* the following is not reliable, since the hp may become exactly oldmax via other means too
+ ieDword oldmax = Modified[IE_MAXHITPOINTS];
+ if (!(BaseStats[IE_STATE_ID]&STATE_DEAD)) {
+ // for now only apply it to fully healed actors iff the bonus is positive (fixes starting hp)
+ if (BaseStats[IE_HITPOINTS] == oldmax && bonus > 0) {
+ BaseStats[IE_HITPOINTS] += bonus;
+ }
+ }*/
+}
+
+// refresh stats on creatures (PC or NPC) with a valid class (not animals etc)
+// internal use only, and this is maybe a stupid name :)
+void Actor::RefreshPCStats() {
+ RefreshHP();
+ Game *game = core->GetGame();
//morale recovery every xth AI cycle
int mrec = GetStat(IE_MORALERECOVERYTIME);
if (mrec) {
- if (!(core->GetGame()->GameTime%mrec)) {
- NewBase(IE_MORALE,1,MOD_ADDITIVE);
+ if (!(game->GameTime%mrec)) {
+ int morale = (signed) BaseStats[IE_MORALE];
+ if (morale < 10) {
+ NewBase(IE_MORALE, 1, MOD_ADDITIVE);
+ } else if (morale > 10) {
+ NewBase(IE_MORALE, (ieDword) -1, MOD_ADDITIVE);
+ }
}
}
- if (bonus<0 && (Modified[IE_MAXHITPOINTS]+bonus)<=0) {
- bonus=1-Modified[IE_MAXHITPOINTS];
- }
-
//get the wspattack bonuses for proficiencies
WeaponInfo wi;
ITMExtHeader *header = GetWeapon(wi, false);
ieDword stars;
int dualwielding = IsDualWielding();
- if (header && (wi.prof <= MAX_STATS)) {
- stars = GetStat(wi.prof)&PROFS_MASK;
+ stars = GetProficiency(wi.prof)&PROFS_MASK;
+
+ //tenser's transformation makes the actor have at least proficient in any weapon
+ if (!stars && HasSpellState(SS_TENSER)) stars = 1;
+
+ if (header) {
if (stars >= (unsigned)wspattack_rows) {
stars = wspattack_rows-1;
}
@@ -2338,37 +3095,93 @@ void Actor::RefreshPCStats() {
tmplevel = 0;
}
- //HACK: attacks per round bonus for monks should only apply to fists
- if (isclass[ISMONK]&(1<<BaseStats[IE_CLASS])) {
- unsigned int level = GetMonkLevel()-1;
- if (level < monkbon_cols) {
- SetBase(IE_NUMBEROFATTACKS, 2 + monkbon[0][level]);
- }
- } else {
- //wspattack appears to only effect warriors
- int defaultattacks = 2 + 2*dualwielding;
- if (stars) {
- if (tmplevel) {
- SetBase(IE_NUMBEROFATTACKS, defaultattacks+wspattack[stars][tmplevel]);
+ //wspattack appears to only effect warriors
+ int defaultattacks = 2 + 2*dualwielding;
+ if (stars) {
+ // In bg2 the proficiency and warrior level bonus is added after effects, so also ranged weapons are affected,
+ // since their rate of fire (apr) is set using an effect with a flat modifier.
+ // SetBase will compensate only for the difference between the current two stats, not considering the default
+ // example: actor with a bow gets 4 due to the equipping effect, while the wspatck bonus is 0-3
+ // the adjustment results in a base of 2-5 (2+[0-3]) and the modified stat degrades to 4+(4-[2-5]) = 8-[2-5] = 3-6
+ // instead of 4+[0-3] = 4-7
+ // For a master ranger at level 14, the difference ends up as 2 (1 apr).
+ // FIXME: but this isn't universally true or improved haste couldn't double the total apr! For the above case, we're half apr off.
+ if (tmplevel) {
+ int mod = Modified[IE_NUMBEROFATTACKS] - BaseStats[IE_NUMBEROFATTACKS];
+ BaseStats[IE_NUMBEROFATTACKS] = defaultattacks+wspattack[stars][tmplevel];
+ if (GetAttackStyle() == WEAPON_RANGED) { // FIXME: should actually check if a set-apr opcode variant was used
+ Modified[IE_NUMBEROFATTACKS] += wspattack[stars][tmplevel]; // no default
} else {
- SetBase(IE_NUMBEROFATTACKS, defaultattacks);
+ Modified[IE_NUMBEROFATTACKS] = BaseStats[IE_NUMBEROFATTACKS] + mod;
}
} else {
- // unproficient user - force defaultattacks
- SetStat(IE_NUMBEROFATTACKS, defaultattacks, 0);
+ SetBase(IE_NUMBEROFATTACKS, defaultattacks); // TODO: check if this shouldn't get +wspattack[stars][0]
}
+ } else {
+ // unproficient user - force defaultattacks
+ SetBase(IE_NUMBEROFATTACKS, defaultattacks);
}
}
- //we still apply the maximum bonus to dead characters, but don't apply
- //to current HP, or we'd have dead characters showing as having hp
- Modified[IE_MAXHITPOINTS]+=bonus;
-// if(BaseStats[IE_STATE_ID]&STATE_DEAD)
-// bonus = 0;
-// BaseStats[IE_HITPOINTS]+=bonus;
-
// apply the intelligence and wisdom bonus to lore
Modified[IE_LORE] += core->GetLoreBonus(0, Modified[IE_INT]) + core->GetLoreBonus(0, Modified[IE_WIS]);
+
+ UpdateFatigue();
+
+ // regenerate actors with high enough constitution
+ int rate = core->GetConstitutionBonus(STAT_CON_HP_REGEN, Modified[IE_CON]);
+ if (rate && !(game->GameTime % (rate*AI_UPDATE_TIME))) {
+ NewBase(IE_HITPOINTS, 1, MOD_ADDITIVE);
+ }
+
+ // adjust thieving skills with dex and race
+ // table header is in this order:
+ // PICK_POCKETS OPEN_LOCKS FIND_TRAPS MOVE_SILENTLY HIDE_IN_SHADOWS DETECT_ILLUSION SET_TRAPS
+ Modified[IE_PICKPOCKET] += GetSkillBonus(1);
+ Modified[IE_LOCKPICKING] += GetSkillBonus(2);
+ Modified[IE_TRAPS] += GetSkillBonus(3);
+ Modified[IE_STEALTH] += GetSkillBonus(4);
+ Modified[IE_HIDEINSHADOWS] += GetSkillBonus(5);
+ Modified[IE_DETECTILLUSIONS] += GetSkillBonus(6);
+ Modified[IE_SETTRAPS] += GetSkillBonus(7);
+}
+
+// add fatigue every 4 hours since resting and check if the actor is penalised for it
+void Actor::UpdateFatigue()
+{
+ Game *game = core->GetGame();
+ if (!InParty || !game->GameTime) {
+ return;
+ }
+ // do icons here, so they persist for more than a tick
+ int LuckMod = core->ResolveStatBonus(this, "fatigue") ; // fatigmod.2da
+ if (LuckMod) {
+ AddPortraitIcon(39); //PI_FATIGUE from FXOpcodes.cpp
+ } else {
+ DisablePortraitIcon(39); //PI_FATIGUE from FXOpcodes.cpp
+ }
+
+ ieDword FatigueLevel = (game->GameTime - TicksLastRested) / 18000; // 18000 == 4 hours
+ int FatigueBonus = core->GetConstitutionBonus(STAT_CON_FATIGUE, Modified[IE_CON]);
+ FatigueLevel = (signed)FatigueLevel - FatigueBonus >= 0 ? FatigueLevel - FatigueBonus : 0;
+ FatigueLevel = ClampStat(IE_FATIGUE, FatigueLevel);
+
+ // don't run on init or we automatically make the character supertired
+ if (FatigueLevel != BaseStats[IE_FATIGUE] && TicksLastRested) {
+ int OldLuckMod = LuckMod;
+ NewBase(IE_FATIGUE, FatigueLevel, MOD_ABSOLUTE);
+ LuckMod = core->ResolveStatBonus(this, "fatigue") ; // fatigmod.2da
+ BaseStats[IE_LUCK] += LuckMod-OldLuckMod;
+ if (LuckMod < 0) {
+ VerbalConstant(VB_TIRED, 1);
+ }
+ } else if (!TicksLastRested) {
+ //if someone changed FatigueLevel, or loading a game, reset
+ TicksLastRested = game->GameTime - 18000 * BaseStats[IE_FATIGUE];
+ if (LuckMod < 0) {
+ VerbalConstant(VB_TIRED, 1);
+ }
+ }
}
void Actor::RollSaves()
@@ -2473,13 +3286,23 @@ void Actor::Interact(int type)
int start;
int count;
- switch(type) {
- case I_INSULT: start=VB_INSULT; count=3; break;
- case I_COMPLIMENT: start=VB_COMPLIMENT; count=3; break;
- case I_SPECIAL: start=VB_SPECIAL; count=3; break;
+ switch(type&0xff) {
+ case I_INSULT: start=VB_INSULT; break;
+ case I_COMPLIMENT: start=VB_COMPLIMENT; break;
+ case I_SPECIAL: start=VB_SPECIAL; break;
+ case I_INSULT_RESP: start=VB_RESP_INS; break;
+ case I_COMPL_RESP: start=VB_RESP_COMP; break;
default:
return;
}
+ if (type&0xff00) {
+ //PST style fixed slots
+ start+=((type&0xff00)>>8)-1;
+ count = 1;
+ } else {
+ //BG1 style random slots
+ count = 3;
+ }
VerbalConstant(start, count);
}
@@ -2497,39 +3320,40 @@ ieStrRef Actor::GetVerbalConstant(int index) const
return StrRefs[idx];
}
-void Actor::VerbalConstant(int start, int count)
+void Actor::VerbalConstant(int start, int count) const
{
- ieStrRef vc;
-
- count=rand()%count;
-
- while(count>=0 && (!(vc = GetVerbalConstant(start+count)) || (vc==(ieStrRef) -1)) ) {
- count--;
+ if (start!=VB_DIE) {
+ //can't talk when dead
+ if (Modified[IE_STATE_ID] & (STATE_CANTLISTEN)) return;
}
- if(count>=0) {
- DisplayStringCore(this, start+count, DS_CONSOLE|DS_CONST );
- }
-}
-
-void Actor::Response(int type)
-{
- int start;
- int count;
- ieStrRef vc;
- switch(type) {
- case I_INSULT: start=VB_RESP_INS; count=3; break;
- case I_COMPLIMENT: start=VB_RESP_COMP; count=3; break;
- default:
- return;
+ //If we are main character (has SoundSet) we have to check a corresponding wav file exists
+ if (PCStats && PCStats->SoundSet[0]) {
+ ieResRef soundref;
+ ResolveStringConstant(soundref, start+count-1);
+ while (count > 0 && !gamedata->Exists(soundref, IE_WAV_CLASS_ID, true)) {
+ count--;
+ ResolveStringConstant(soundref, start+count-1);
+ }
+ if (count > 0){
+ DisplayStringCore((Scriptable *const) this, start + rand()%count, DS_CONSOLE|DS_CONST|DS_SPEECH);
+ }
+ } else { //If we are anyone else we have to check there is a corresponding strref
+ while(count > 0 && GetVerbalConstant(start+count-1) == (ieStrRef) -1 ) {
+ count--;
+ }
+ if(count > 0) {
+ DisplayStringCore((Scriptable *const) this, GetVerbalConstant(start+rand()%count), DS_CONSOLE|DS_SPEECH);
+ }
}
+}
- count=rand()%count;
- while(count && ((vc = GetVerbalConstant(start+count))!=(ieStrRef) -1)) {
- count--;
- }
- if(count>=0) {
- DisplayStringCore(this, start+count, DS_CONSOLE|DS_CONST );
+void Actor::DisplayStringOrVerbalConstant(int str, int vcstat, int vccount) const {
+ int strref = displaymsg->GetStringReference(str);
+ if (strref != -1) {
+ DisplayStringCore((Scriptable *const) this, strref, DS_CONSOLE);
+ } else {
+ VerbalConstant(vcstat, vccount);
}
}
@@ -2544,10 +3368,10 @@ void Actor::ReactToDeath(const char * deadname)
const char *value = tm->QueryField (scriptName, deadname);
switch (value[0]) {
case '0':
- DisplayStringCore(this, VB_REACT, DS_CONSOLE|DS_CONST );
+ VerbalConstant(VB_REACT, 1);
break;
case '1':
- DisplayStringCore(this, VB_REACT_S, DS_CONSOLE|DS_CONST );
+ VerbalConstant(VB_REACT_S, 1);
break;
default:
{
@@ -2559,7 +3383,7 @@ void Actor::ReactToDeath(const char * deadname)
while(*value && *value!=',') value++;
if (*value==',') value++;
}
- strncpy(resref, value, 8);
+ CopyResRef(resref, value);
for(count=0;count<8 && resref[count]!=',';count++) {};
resref[count]=0;
@@ -2573,47 +3397,265 @@ void Actor::ReactToDeath(const char * deadname)
}
}
+//issue area specific comments
+void Actor::GetAreaComment(int areaflag) const
+{
+ for(int i=0;i<afcount;i++) {
+ if (afcomments[i][0]&areaflag) {
+ int vc = afcomments[i][1];
+ if (afcomments[i][2]) {
+ if (!core->GetGame()->IsDay()) {
+ vc++;
+ }
+ }
+ VerbalConstant(vc, 1);
+ return;
+ }
+ }
+}
+
+static int CheckInteract(const char *talker, const char *target)
+{
+ AutoTable interact("interact");
+ if(!interact)
+ return 0;
+ const char *value = interact->QueryField(talker, target);
+ if(!value)
+ return 0;
+
+ int tmp = 0;
+ int x = 0;
+ int ln = strlen(value);
+
+ if (ln>1) {
+ //we round the length up, so the last * will be also chosen
+ x = core->Roll(1,(ln+1)/2,-1)*2;
+ //convert '1', '2' and '3' to 0x100,0x200,0x300 respectively, all the rest becomes 0
+ //it is no problem if we hit the zero terminator in case of an odd length
+ tmp = value[x+1]-'0';
+ if ((ieDword) tmp>3) tmp=0;
+ tmp <<= 8;
+ }
+
+ switch(value[x]) {
+ case '*':
+ return I_DIALOG;
+ case 's':
+ return tmp+I_SPECIAL;
+ case 'c':
+ return tmp+I_COMPLIMENT;
+ case 'i':
+ return tmp+I_INSULT;
+ case 'I':
+ return tmp+I_INSULT_RESP;
+ case 'C':
+ return tmp+I_COMPL_RESP;
+ }
+ return I_NONE;
+}
+
+int Actor::HandleInteract(Actor *target)
+{
+ int type = CheckInteract(scriptName, target->GetScriptName());
+
+ //no interaction at all
+ if (type==I_NONE) return -1;
+ //banter dialog interaction
+ if (type==I_DIALOG) return 0;
+
+ Interact(type);
+ switch(type)
+ {
+ case I_COMPLIMENT:
+ target->Interact(I_COMPL_RESP);
+ break;
+ case I_INSULT:
+ target->Interact(I_INSULT_RESP);
+ break;
+ }
+ return 1;
+}
+
+bool Actor::GetPartyComment()
+{
+ Game *game = core->GetGame();
+
+ //don't even bother
+ if (game->NpcInParty<2) return false;
+ ieDword size = game->GetPartySize(true);
+ //don't even bother, again
+ if (size<2) return false;
+
+ if(core->Roll(1,2,-1)) {
+ return false;
+ }
+
+ for(unsigned int i=core->Roll(1,size,0);i<2*size;i++) {
+ Actor *target = game->GetPC(i%size, true);
+ if (target==this) continue;
+ if (target->BaseStats[IE_MC_FLAGS]&MC_EXPORTABLE) continue; //not NPC
+ if (target->GetCurrentArea()!=GetCurrentArea()) continue;
+
+ //simplified interact
+ switch(HandleInteract(target)) {
+ case -1: return false;
+ case 1: return true;
+ default:
+ //V2 interact
+ char Tmp[40];
+ LastTalker = target->GetGlobalID();
+ strlcpy(Tmp, "Interact([-1])", sizeof(Tmp));
+ Action *action = GenerateActionDirect(Tmp, target);
+ if (action) {
+ AddActionInFront(action);
+ } else {
+ Log(ERROR, "Actor", "Cannot generate banter action");
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
//call this only from gui selects
-void Actor::SelectActor()
+void Actor::PlaySelectionSound()
{
- DisplayStringCore(this, VB_SELECT+core->Roll(1,3,-1), DS_CONSOLE|DS_CONST );
+ playedCommandSound = false;
+ switch (sel_snd_freq) {
+ case 0:
+ return;
+ case 1:
+ if (core->Roll(1,100,0) > 20) return;
+ default:;
+ }
+
+ //drop the rare selection comment 5% of the time
+ if (InParty && core->Roll(1,100,0) <= RARE_SELECT_CHANCE){
+ //rare select on main character for BG1 won't work atm
+ VerbalConstant(VB_SELECT_RARE, NUM_RARE_SELECT_SOUNDS);
+ } else {
+ //checks if we are main character to limit select sounds
+ if (PCStats && PCStats->SoundSet[0]) {
+ VerbalConstant(VB_SELECT, NUM_MC_SELECT_SOUNDS);
+ } else {
+ VerbalConstant(VB_SELECT, NUM_SELECT_SOUNDS);
+ }
+ }
+}
+
+#define SEL_ACTION_COUNT_COMMON 3
+#define SEL_ACTION_COUNT_ALL 7
+
+//call this when a PC receives a command from GUI
+void Actor::CommandActor()
+{
+ switch (cmd_snd_freq) {
+ case 0:
+ return;
+ case 1:
+ if (playedCommandSound) return;
+ playedCommandSound = true;
+ case 2:
+ //PST has 4 states and rare sounds
+ if (raresnd) {
+ if (core->Roll(1,100,0)>50) return;
+ }
+ default:;
+ }
+ //if GF_RARE_ACTION_VB is set, don't select the last 4 options frequently
+ VerbalConstant(VB_COMMAND,(raresnd && core->Roll(1, 100,0)<75)?SEL_ACTION_COUNT_COMMON:SEL_ACTION_COUNT_ALL);
+}
+
+//Generates an idle action (party banter, area comment, bored)
+void Actor::IdleActions(bool nonidle)
+{
+ //only party [N]PCs talk
+ if (!InParty) return;
+ //if they got an area
+ Map *map = GetCurrentArea();
+ if (!map) return;
+ //and not in panic
+ if (panicMode!=PANIC_NONE) return;
+
+ Game *game = core->GetGame();
+ //there is no combat
+ if (game->CombatCounter) return;
+ //and they are on the current area
+ if (map!=game->GetCurrentArea()) return;
+
+ ieDword time = game->GameTime;
+
+ //don't mess with cutscenes, dialogue, or when scripts disabled us
+ if (core->InCutSceneMode() || game->BanterBlockFlag || (game->BanterBlockTime>time) ) {
+ return;
+ }
+
+ //drop an area comment, party oneliner or initiate party banter (with Interact)
+ //party comments have a priority, but they happen half of the time, at most
+ if (nextComment<time) {
+ if (nextComment && !Immobile()) {
+ if (!GetPartyComment()) {
+ GetAreaComment(map->AreaType);
+ }
+ }
+ nextComment = time+core->Roll(5,1000,bored_time/2);
+ return;
+ }
+
+ //drop the bored one liner is there was no action for some time
+ if (nonidle || !nextBored || InMove() || Immobile()) {
+ //if not in party or bored timeout is disabled, don't bother to set the new time
+ if (InParty && bored_time) {
+ nextBored=time+core->Roll(1,30,bored_time);
+ }
+ } else {
+ if (nextBored<time) {
+ int x = bored_time / 10;
+ if (x<10) x = 10;
+ nextBored = time+core->Roll(1,30,x);
+ VerbalConstant(VB_BORED, 1);
+ }
+ }
+}
+
+bool Actor::OverrideActions()
+{
+ //TODO:: implement forced actions that mess with scripting (panic, confusion, etc)
+ return false;
}
void Actor::Panic(Scriptable *attacker, int panicmode)
{
if (GetStat(IE_STATE_ID)&STATE_PANIC) {
- printf("Already paniced\n");
+ print("Already paniced");
//already in panic
return;
}
if (InParty) core->GetGame()->SelectActor(this, false, SELECT_NORMAL);
- SetBaseBit(IE_STATE_ID, STATE_PANIC, true);
- DisplayStringCore(this, VB_PANIC, DS_CONSOLE|DS_CONST );
+ VerbalConstant(VB_PANIC, 1 );
Action *action;
char Tmp[40];
- //FIXME: GenerateActionDirect should work on any scriptable
- //they just need global ID
if (panicmode == PANIC_RUNAWAY && (!attacker || attacker->Type!=ST_ACTOR)) {
panicmode = PANIC_RANDOMWALK;
}
switch(panicmode) {
case PANIC_RUNAWAY:
- strncpy(Tmp,"RunAwayFromNoInterrupt([-1])", sizeof(Tmp) );
- action = GenerateActionDirect(Tmp, (Actor *) attacker);
+ strlcpy(Tmp, "RunAwayFromNoInterrupt([-1])", sizeof(Tmp));
+ action = GenerateActionDirect(Tmp, attacker);
+ SetBaseBit(IE_STATE_ID, STATE_PANIC, true);
break;
case PANIC_RANDOMWALK:
- strncpy(Tmp,"RandomWalk()", sizeof(Tmp) );
+ strlcpy(Tmp, "RandomWalk()", sizeof(Tmp));
action = GenerateAction( Tmp );
+ SetBaseBit(IE_STATE_ID, STATE_PANIC, true);
break;
case PANIC_BERSERK:
- if (Modified[IE_EA]<EA_GOODCUTOFF) {
- strncpy(Tmp,"GroupAttack('[EVILCUTOFF]'", sizeof(Tmp) );
- } else {
- strncpy(Tmp,"GroupAttack('[GOODCUTOFF]'", sizeof(Tmp) );
- }
+ strlcpy(Tmp, "Berserk()", sizeof(Tmp));
action = GenerateAction( Tmp );
+ BaseStats[IE_CHECKFORBERSERK]=3;
+ //SetBaseBit(IE_STATE_ID, STATE_BERSERK, true);
break;
default:
return;
@@ -2621,7 +3663,7 @@ void Actor::Panic(Scriptable *attacker, int panicmode)
if (action) {
AddActionInFront(action);
} else {
- printMessage("Actor","Cannot generate panic action\n", RED);
+ Log(ERROR, "Actor", "Cannot generate panic action");
}
}
@@ -2646,18 +3688,23 @@ void Actor::DialogInterrupt()
/* this part is unsure */
if (Modified[IE_EA]>=EA_EVILCUTOFF) {
- DisplayStringCore(this, VB_HOSTILE, DS_CONSOLE|DS_CONST );
+ VerbalConstant(VB_HOSTILE, 1 );
} else {
- DisplayStringCore(this, VB_DIALOG, DS_CONSOLE|DS_CONST );
+ if (TalkCount) {
+ VerbalConstant(VB_DIALOG, 1);
+ } else {
+ VerbalConstant(VB_INITIALMEET, 1);
+ }
}
}
-static EffectRef fx_cure_sleep_ref = { "Cure:Sleep", -1 };
-
-void Actor::GetHit()
+void Actor::GetHit(int damage, int spellLevel)
{
- SetStance( IE_ANI_DAMAGE );
- DisplayStringCore(this, VB_DAMAGE, DS_CONSOLE|DS_CONST );
+ if (!Immobile() && !(InternalFlags & IF_REALLYDIED)) {
+ SetStance( IE_ANI_DAMAGE );
+ }
+ VerbalConstant(VB_DAMAGE, 1 );
+
if (Modified[IE_STATE_ID]&STATE_SLEEP) {
if (Modified[IE_EXTSTATE_ID]&EXTSTATE_NO_WAKEUP) {
return;
@@ -2665,9 +3712,36 @@ void Actor::GetHit()
Effect *fx = EffectQueue::CreateEffect(fx_cure_sleep_ref, 0, 0, FX_DURATION_INSTANT_PERMANENT);
fxqueue.AddEffect(fx);
}
+ if (CheckCastingInterrupt(damage, spellLevel)) {
+ InterruptCasting = true;
+ }
+}
+
+// TODO: check that this isn't the same thing we have in GSUtils (that one is missing a debug string in the original)
+bool Actor::CheckCastingInterrupt(int damage, int spellLevel)
+{
+ if (!third) {
+ return true;
+ }
+ int roll = core->Roll(1, 20, 0);
+ int concentration = Modified[IE_CONCENTRATION];
+ int bonus = 4; // combat casting bonus for when injured
+ if (BaseStats[IE_HITPOINTS] == Modified[IE_HITPOINTS]) {
+ bonus = 0;
+ }
+ // ~Spell Disruption check (d20 + Concentration + Combat Casting bonus) %d + %d + %d vs. (10 + damageTaken + spellLevel) = 10 + %d + %d.~
+ if (GameScript::ID_ClassMask(this, 0x6ee)) { // 0x6ee == CLASSMASK_GROUP_CASTERS
+ // no spam for noncasters
+ displaymsg->DisplayRollStringName(39842, DMC_LIGHTGREY, this, roll, concentration, bonus, damage, spellLevel);
+ }
+ int chance = (roll + concentration + bonus) > (10 + damage + spellLevel);
+ if (chance) {
+ return false;
+ }
+ return true;
}
-bool Actor::HandleCastingStance(const ieResRef SpellResRef, bool deplete)
+bool Actor::HandleCastingStance(const ieResRef SpellResRef, bool deplete, bool instant)
{
if (deplete) {
if (! spellbook.HaveSpell( SpellResRef, HS_DEPLETE )) {
@@ -2675,54 +3749,143 @@ bool Actor::HandleCastingStance(const ieResRef SpellResRef, bool deplete)
return true;
}
}
- SetStance(IE_ANI_CAST);
+ if (!instant) {
+ SetStance(IE_ANI_CAST);
+ }
return false;
}
-static EffectRef fx_sleep_ref = { "State:Helpless", -1 };
+bool Actor::AttackIsStunning(int damagetype) const {
+ //stunning damagetype
+ if (damagetype & DAMAGE_STUNNING) {
+ return true;
+ }
+
+ //cheese to avoid one shotting newbie player
+/* FIXME: decode exact conditions
+ if ( InParty && (Modified[IE_MAXHITPOINTS]<20) && (damage>Modified[IE_MAXHITPOINTS]) ) {
+ return true;
+ }
+*/
+ return false;
+}
+
+bool Actor::CheckSilenced()
+{
+ if (!(Modified[IE_STATE_ID] & STATE_SILENCED)) return false;
+ if (HasFeat(FEAT_SUBVOCAL_CASTING)) return false;
+ if (HasSpellState(SS_VOCALIZE)) return false;
+ return true;
+}
+
+void Actor::CheckCleave()
+{
+ int cleave = GetFeat(FEAT_CLEAVE);
+ //feat level 1 only enables one cleave per round
+ if ((cleave==1) && fxqueue.HasEffect(fx_cleave_ref) ) {
+ cleave = 0;
+ }
+ if(cleave) {
+ Effect * fx = EffectQueue::CreateEffect(fx_cleave_ref, attackcount, 0, FX_DURATION_INSTANT_LIMITED);
+ if (fx) {
+ fx->Duration = core->Time.round_sec;
+ core->ApplyEffect(fx, this, this);
+ delete fx;
+ // ~Cleave feat adds another level %d attack.~
+ // FIXME: probably uses the same tohit as the previous attack
+ displaymsg->DisplayRollStringName(39846, DMC_LIGHTGREY, this, ToHit.GetTotal());
+ }
+ }
+}
+
//returns actual damage
-int Actor::Damage(int damage, int damagetype, Scriptable *hitter, int modtype)
+int Actor::Damage(int damage, int damagetype, Scriptable *hitter, int modtype, int critical, int saveflags)
{
//won't get any more hurt
if (InternalFlags & IF_REALLYDIED) {
return 0;
}
+ // hidden creatures are immune too, iwd2 Targos palisade attack relies on it (12cspn1a.bcs)
+ if (Modified[IE_AVATARREMOVAL]) {
+ return 0;
+ }
//add lastdamagetype up ? maybe
+ //FIXME: what does original do?
LastDamageType|=damagetype;
- if(hitter && hitter->Type==ST_ACTOR) {
- LastHitter=hitter->GetGlobalID();
- } else {
- //Maybe it should be something impossible like 0xffff, and use 'Someone'
- LastHitter=GetGlobalID();
+ Actor *act=NULL;
+ if (!hitter) {
+ // TODO: check this
+ hitter = area->GetActorByGlobalID(LastHitter);
+ }
+
+ if (hitter) {
+ if (hitter->Type==ST_ACTOR) {
+ act = (Actor *) hitter;
+ }
}
switch(modtype)
{
case MOD_ADDITIVE:
+ //bonus against creature should only affect additive damages or spells like harm would be deadly
+ if (damage && act) {
+ damage += act->fxqueue.BonusAgainstCreature(fx_damage_vs_creature_ref, this);
+ }
break;
case MOD_ABSOLUTE:
damage = GetBase(IE_HITPOINTS) - damage;
break;
case MOD_PERCENT:
- damage = GetStat(IE_MAXHITPOINTS) * 100 / damage;
+ damage = GetStat(IE_MAXHITPOINTS) * damage / 100;
break;
default:
//this shouldn't happen
- printMessage("Actor","Invalid damagetype!\n",RED);
+ Log(ERROR, "Actor", "Invalid damagetype!");
return 0;
}
int resisted = 0;
- ModifyDamage (this, hitter, damage, resisted, damagetype, NULL, false);
+ if (!(saveflags&SF_BYPASS_MIRROR_IMAGE)) {
+ int mirrorimages = Modified[IE_MIRRORIMAGES];
+ if (mirrorimages) {
+ if (LuckyRoll(1,mirrorimages+1,0) != 1) {
+ fxqueue.DecreaseParam1OfEffect(fx_mirrorimage_ref, 1);
+ Modified[IE_MIRRORIMAGES]--;
+ damage = 0;
+ }
+ }
+ }
+
+ if (!(saveflags&SF_IGNORE_DIFFICULTY)) {
+ // adjust enemy damage according to difficulty settings:
+ // -50%, -25%, 0, 50%, 100%, 150%
+ if (Modified[IE_EA] < EA_GOODCUTOFF) {
+ int adjustmentPercent = dmgadjustments[GameDifficulty];
+ if (!NoExtraDifficultyDmg || adjustmentPercent < 0) {
+ damage += (damage * adjustmentPercent)/100;
+ }
+ }
+ }
+
+ if (damage) {
+ ModifyDamage (hitter, damage, resisted, damagetype);
+ }
DisplayCombatFeedback(damage, resisted, damagetype, hitter);
+ if (damage>0) {
+ // instant chunky death if the actor is petrified or frozen
+ if (Modified[IE_STATE_ID] & (STATE_FROZEN|STATE_PETRIFIED) && !Modified[IE_DISABLECHUNKING] && (GameDifficulty > DIFF_NORMAL) ) {
+ damage = 123456; // arbitrarily high for death; won't be displayed
+ LastDamageType |= DAMAGE_CHUNKING;
+ }
+ }
+
if (BaseStats[IE_HITPOINTS] <= (ieDword) damage) {
// common fists do normal damage, but cause sleeping for a round instead of death
- if ((damagetype & DAMAGE_STUNNING) && Modified[IE_MINHITPOINTS] <= 0) {
- NewBase(IE_HITPOINTS, 1, MOD_ABSOLUTE);
+ if (Modified[IE_MINHITPOINTS]<=0 && AttackIsStunning(damagetype) ) {
// stack unconsciousness carefully to avoid replaying the stance changing
Effect *sleep = fxqueue.HasEffectWithParamPair(fx_sleep_ref, 0, 0);
if (sleep) {
@@ -2733,41 +3896,38 @@ int Actor::Damage(int damage, int damagetype, Scriptable *hitter, int modtype)
core->ApplyEffect(fx, this, this);
delete fx;
}
- } else {
- if (damage) {
- GetHit();
- }
- NewBase(IE_HITPOINTS, (ieDword) -damage, MOD_ADDITIVE);
+ //reduce damage to keep 1 hp
+ damage = Modified[IE_HITPOINTS]-1;
}
- } else {
- if (damage) {
- GetHit();
- }
- NewBase(IE_HITPOINTS, (ieDword) -damage, MOD_ADDITIVE);
+ }
- // also apply reputation damage if we hurt (but not killed) an innocent
- if (Modified[IE_CLASS] == CLASS_INNOCENT) {
- Actor *act=NULL;
- if (!hitter) {
- hitter = area->GetActorByGlobalID(LastHitter);
- }
+ // can be negative if we're healing on 100%+ resistance
+ if (damage != 0) {
+ NewBase(IE_HITPOINTS, (ieDword) -damage, MOD_ADDITIVE);
+ }
- if (hitter) {
- if (hitter->Type==ST_ACTOR) {
- act = (Actor *) hitter;
- }
- }
+ // also apply reputation damage if we hurt (but not killed) an innocent
+ if (Modified[IE_CLASS] == CLASS_INNOCENT && !core->InCutSceneMode()) {
+ if (act && act->GetStat(IE_EA) <= EA_CONTROLLABLE) {
+ core->GetGame()->SetReputation(core->GetGame()->Reputation + core->GetReputationMod(1));
+ }
+ }
- if (act && act->GetStat(IE_EA) <= EA_CONTROLLABLE) {
- core->GetGame()->SetReputation(core->GetGame()->Reputation + core->GetReputationMod(1));
- }
+ int chp = (signed) BaseStats[IE_HITPOINTS];
+ if (damage > 0) {
+ //if this kills us, check if attacker could cleave
+ if (act && (damage>chp)) {
+ act->CheckCleave();
}
+ GetHit(damage, 3); // FIXME: carry over the correct spellLevel
+ //fixme: implement applytrigger, copy int0 into LastDamage there
+ LastDamage = damage;
+ AddTrigger(TriggerEntry(trigger_tookdamage, damage)); // FIXME: lastdamager? LastHitter is not set for spell damage
+ AddTrigger(TriggerEntry(trigger_hitby, LastHitter, damagetype)); // FIXME: lastdamager? LastHitter is not set for spell damage
}
- LastDamage=damage;
InternalFlags|=IF_ACTIVE;
- int chp = (signed) BaseStats[IE_HITPOINTS];
- int damagelevel = 0;
+ int damagelevel = 0; //FIXME: this level is never used
if (damage<10) {
damagelevel = 1;
} else {
@@ -2787,7 +3947,7 @@ int Actor::Damage(int damage, int damagetype, Scriptable *hitter, int modtype)
PlayDamageAnimation(DL_DISINTEGRATE+damagelevel);
} else {
if (chp<-10) {
- PlayDamageAnimation(DL_CRITICAL);
+ PlayDamageAnimation(critical<<8);
} else {
PlayDamageAnimation(DL_BLOOD+damagelevel);
}
@@ -2795,10 +3955,10 @@ int Actor::Damage(int damage, int damagetype, Scriptable *hitter, int modtype)
if (InParty) {
if (chp<(signed) Modified[IE_MAXHITPOINTS]/10) {
- core->Autopause(AP_WOUNDED);
+ core->Autopause(AP_WOUNDED, this);
}
if (damage>0) {
- core->Autopause(AP_HIT);
+ core->Autopause(AP_HIT, this);
core->SetEventFlag(EF_PORTRAIT);
}
}
@@ -2820,8 +3980,7 @@ void Actor::DisplayCombatFeedback (unsigned int damage, int resisted, int damage
}
if (damage > 0 && resisted != DR_IMMUNE) {
- printMessage("Actor", " ", GREEN);
- printf("%d damage taken.\n", damage);
+ Log(COMBAT, "Actor", "%d %s damage taken.\n", damage, type_name);
if (detailed) {
// 3 choices depending on resistance and boni
@@ -2836,17 +3995,17 @@ void Actor::DisplayCombatFeedback (unsigned int damage, int resisted, int damage
if (resisted < 0) {
//Takes <AMOUNT> <TYPE> damage from <DAMAGER> (<RESISTED> damage bonus)
core->GetTokenDictionary()->SetAtCopy( "RESISTED", abs(resisted));
- displaymsg->DisplayConstantStringName(STR_DAMAGE3, 0xffffff, this);
+ displaymsg->DisplayConstantStringName(STR_DAMAGE3, DMC_WHITE, this);
} else if (resisted > 0) {
//Takes <AMOUNT> <TYPE> damage from <DAMAGER> (<RESISTED> damage resisted)
core->GetTokenDictionary()->SetAtCopy( "RESISTED", abs(resisted));
- displaymsg->DisplayConstantStringName(STR_DAMAGE2, 0xffffff, this);
+ displaymsg->DisplayConstantStringName(STR_DAMAGE2, DMC_WHITE, this);
} else {
//Takes <AMOUNT> <TYPE> damage from <DAMAGER>
- displaymsg->DisplayConstantStringName(STR_DAMAGE1, 0xffffff, this);
+ displaymsg->DisplayConstantStringName(STR_DAMAGE1, DMC_WHITE, this);
}
} else if (core->HasFeature(GF_ONSCREEN_TEXT) ) {
- if(0) printf("TODO: pst floating text\n");
+ if(0) print("TODO: pst floating text");
} else if (!displaymsg->HasStringReference(STR_DAMAGE2) || !hitter || hitter->Type != ST_ACTOR) {
// bg1 and iwd
// or any traps or self-infliction (also for bg1)
@@ -2854,30 +4013,29 @@ void Actor::DisplayCombatFeedback (unsigned int damage, int resisted, int damage
char tmp[64];
const char* msg = core->GetString(displaymsg->GetStringReference(STR_DAMAGE1), 0);
snprintf(tmp, sizeof(tmp), "%s (%d)", msg, damage);
- displaymsg->DisplayStringName(tmp, 0xffffff, this);
+ displaymsg->DisplayStringName(tmp, DMC_WHITE, this);
} else { //bg2
//<DAMAGER> did <AMOUNT> damage to <DAMAGEE>
core->GetTokenDictionary()->SetAtCopy( "DAMAGEE", GetName(1) );
// wipe the DAMAGER token, so we can color it
core->GetTokenDictionary()->SetAtCopy( "DAMAGER", "" );
core->GetTokenDictionary()->SetAtCopy( "AMOUNT", damage);
- displaymsg->DisplayConstantStringName(STR_DAMAGE2, 0xffffff, hitter);
+ displaymsg->DisplayConstantStringName(STR_DAMAGE2, DMC_WHITE, hitter);
}
} else {
if (resisted == DR_IMMUNE) {
- printMessage("Actor", " ", GREEN);
- printf("is immune to damage type: %s.\n", type_name);
+ Log(COMBAT, "Actor", "is immune to damage type: %s.\n", type_name);
if (hitter && hitter->Type == ST_ACTOR) {
if (detailed) {
//<DAMAGEE> was immune to my <TYPE> damage
core->GetTokenDictionary()->SetAtCopy( "DAMAGEE", GetName(1) );
core->GetTokenDictionary()->SetAtCopy( "TYPE", type_name );
- displaymsg->DisplayConstantStringName(STR_DAMAGE_IMMUNITY, 0xffffff, hitter);
+ displaymsg->DisplayConstantStringName(STR_DAMAGE_IMMUNITY, DMC_WHITE, hitter);
} else if (displaymsg->HasStringReference(STR_DAMAGE_IMMUNITY) && displaymsg->HasStringReference(STR_DAMAGE1)) {
// bg2
//<DAMAGEE> was immune to my damage.
core->GetTokenDictionary()->SetAtCopy( "DAMAGEE", GetName(1) );
- displaymsg->DisplayConstantStringName(STR_DAMAGE_IMMUNITY, 0xffffff, hitter);
+ displaymsg->DisplayConstantStringName(STR_DAMAGE_IMMUNITY, DMC_WHITE, hitter);
} // else: other games don't display anything
}
} else {
@@ -2885,11 +4043,9 @@ void Actor::DisplayCombatFeedback (unsigned int damage, int resisted, int damage
}
}
- //PST hit sounds
+ //Play hit sounds, for pst, resdata contains the armor level
DataFileMgr *resdata = core->GetResDataINI();
- if (resdata) {
- PlayHitSound(resdata, damagetype, false);
- }
+ PlayHitSound(resdata, damagetype, false);
}
void Actor::PlayWalkSound()
@@ -2897,118 +4053,165 @@ void Actor::PlayWalkSound()
ieDword thisTime;
ieResRef Sound;
- GetTime(thisTime);
+ thisTime = GetTickCount();
if (thisTime<nextWalk) return;
int cnt = anims->GetWalkSoundCount();
if (!cnt) return;
cnt=core->Roll(1,cnt,-1);
- strnuprcpy(Sound, anims->GetWalkSound(), sizeof(ieResRef) );
+ strnuprcpy(Sound, anims->GetWalkSound(), sizeof(ieResRef)-1 );
area->ResolveTerrainSound(Sound, Pos);
- if (cnt) {
- int len = strlen(Sound);
- if (len<8) {
- Sound[len]=cnt+0x60;
+
+ if (Sound[0] != '*') {
+ if (cnt) {
+ int l = strlen(Sound);
+ if (l < 8) {
+ Sound[l] = cnt + 0x60; // append 'a'-'g'
+ Sound[l+1] = 0;
+ }
}
+ unsigned int len = 0;
+ core->GetAudioDrv()->Play( Sound,Pos.x,Pos.y, 0, &len );
+ nextWalk = thisTime + len;
}
- unsigned int len = 0;
- core->GetAudioDrv()->Play( Sound,Pos.x,Pos.y, 0, &len );
- nextWalk = thisTime + len;
}
-//Play PST specific hit sounds (HIT_0<dtype><armor>)
+//Play hit sounds (HIT_0<dtype><armor>)
void Actor::PlayHitSound(DataFileMgr *resdata, int damagetype, bool suffix)
{
int type;
+ bool levels = true;
switch(damagetype) {
- case DAMAGE_SLASHING: type = 1; break; //slashing
- case DAMAGE_PIERCING: type = 2; break; //piercing
+ case DAMAGE_PIERCING: type = 1; break; //piercing
+ case DAMAGE_SLASHING: type = 2; break; //slashing
case DAMAGE_CRUSHING: type = 3; break; //crushing
case DAMAGE_MISSILE: type = 4; break; //missile
+ case DAMAGE_ELECTRICITY: type = 5; levels = false; break; //electricity
+ case DAMAGE_COLD: type = 6; levels = false; break; //cold
+ case DAMAGE_MAGIC: type = 7; levels = false; break;
+ case DAMAGE_STUNNING: type = -3; break;
default: return; //other
}
ieResRef Sound;
- char section[12];
- unsigned int animid=BaseStats[IE_ANIMATION_ID];
- if(core->HasFeature(GF_ONE_BYTE_ANIMID)) {
- animid&=0xff;
- }
+ int armor = 0;
- snprintf(section,10,"%d", animid);
+ if (resdata) {
+ char section[12];
+ unsigned int animid=BaseStats[IE_ANIMATION_ID];
+ if(core->HasFeature(GF_ONE_BYTE_ANIMID)) {
+ animid&=0xff;
+ }
- int armor = resdata->GetKeyAsInt(section, "armor",0);
- if (armor<0 || armor>35) return;
+ snprintf(section,10,"%d", animid);
- snprintf(Sound,8,"HIT_0%d%c%c",type, armor+'A', suffix?'1':0);
+ if (type<0) {
+ type = -type;
+ } else {
+ armor = resdata->GetKeyAsInt(section, "armor",0);
+ }
+ if (armor<0 || armor>35) return;
+ } else {
+ //hack for stun (always first armortype)
+ if (type<0) {
+ type = -type;
+ } else {
+ armor = Modified[IE_ARMOR_TYPE];
+ }
+ }
+ if (levels) {
+ snprintf(Sound,9,"HIT_0%d%c%c",type, armor+'A', suffix?'1':0);
+ } else {
+ snprintf(Sound,9,"HIT_0%d%c",type, suffix?'1':0);
+ }
core->GetAudioDrv()->Play( Sound,Pos.x,Pos.y );
}
//Just to quickly inspect debug maximum values
#if 0
-void Actor::DumpMaxValues()
+void Actor::dumpMaxValues()
{
int symbol = core->LoadSymbol( "stats" );
- SymbolMgr *sym = core->GetSymbol( symbol );
+ if (symbol !=-1) {
+ SymbolMgr *sym = core->GetSymbol( symbol );
- for(int i=0;i<MAX_STATS;i++) {
- printf("%d (%s) %d\n", i, sym->GetValue(i), maximum_values[i]);
+ for(int i=0;i<MAX_STATS;i++) {
+ print("%d(%s) %d", i, sym->GetValue(i), maximum_values[i]);
+ }
}
}
#endif
-void Actor::DebugDump()
+void Actor::dump() const
+{
+ StringBuffer buffer;
+ dump(buffer);
+ Log(DEBUG, "Actor", buffer);
+}
+
+void Actor::dump(StringBuffer& buffer) const
{
unsigned int i;
- printf( "Debugdump of Actor %s (%s, %s):\n", LongName, ShortName, GetName(-1) );
- printf ("Scripts:");
+ buffer.appendFormatted( "Debugdump of Actor %s (%s, %s):\n", LongName, ShortName, GetName(-1) );
+ buffer.append("Scripts:");
for (i = 0; i < MAX_SCRIPTS; i++) {
const char* poi = "<none>";
if (Scripts[i]) {
poi = Scripts[i]->GetName();
}
- printf( " %.8s", poi );
- }
- printf( "\nArea: %.8s ", Area );
- printf( "Dialog: %.8s\n", Dialog );
- printf( "Global ID: %d PartySlot: %d\n", GetGlobalID(), InParty);
- printf( "Script name:%.32s Current action: %d\n", scriptName, CurrentAction ? CurrentAction->actionID : -1);
- printf( "TalkCount: %d ", TalkCount );
- printf( "Allegiance: %d current allegiance:%d\n", BaseStats[IE_EA], Modified[IE_EA] );
- printf( "Class: %d current class:%d\n", BaseStats[IE_CLASS], Modified[IE_CLASS] );
- printf( "Race: %d current race:%d\n", BaseStats[IE_RACE], Modified[IE_RACE] );
- printf( "Gender: %d current gender:%d\n", BaseStats[IE_SEX], Modified[IE_SEX] );
- printf( "Specifics: %d current specifics:%d\n", BaseStats[IE_SPECIFIC], Modified[IE_SPECIFIC] );
- printf( "Alignment: %x current alignment:%x\n", BaseStats[IE_ALIGNMENT], Modified[IE_ALIGNMENT] );
- printf( "Morale: %d current morale:%d\n", BaseStats[IE_MORALE], Modified[IE_MORALE] );
- printf( "Moralebreak:%d Morale recovery:%d\n", Modified[IE_MORALEBREAK], Modified[IE_MORALERECOVERYTIME] );
- printf( "Visualrange:%d (Explorer: %d)\n", Modified[IE_VISUALRANGE], Modified[IE_EXPLORE] );
- printf( "Levels: %d/%d/%d (average %d)\n", Modified[IE_LEVEL], Modified[IE_LEVEL2], Modified[IE_LEVEL3], GetXPLevel(true) );
- printf( "current HP:%d\n", BaseStats[IE_HITPOINTS] );
- printf( "Mod[IE_ANIMATION_ID]: 0x%04X\n", Modified[IE_ANIMATION_ID] );
- printf( "Colors: ");
+ buffer.appendFormatted( " %.8s", poi );
+ }
+ buffer.append("\n");
+ buffer.appendFormatted("Area: %.8s ", Area );
+ buffer.appendFormatted("Dialog: %.8s\n", Dialog );
+ buffer.appendFormatted("Global ID: %d PartySlot: %d\n", GetGlobalID(), InParty);
+ buffer.appendFormatted("Script name:%.32s Current action: %d Total: %ld\n", scriptName, CurrentAction ? CurrentAction->actionID : -1, (long) actionQueue.size());
+ buffer.appendFormatted("Int. Flags: 0x%x ", InternalFlags);
+ buffer.appendFormatted("MC Flags: 0x%x ", Modified[IE_MC_FLAGS]);
+ buffer.appendFormatted("TalkCount: %d \n", TalkCount );
+ buffer.appendFormatted("Allegiance: %d current allegiance:%d\n", BaseStats[IE_EA], Modified[IE_EA] );
+ buffer.appendFormatted("Class: %d current class:%d\n", BaseStats[IE_CLASS], Modified[IE_CLASS] );
+ buffer.appendFormatted("Race: %d current race:%d\n", BaseStats[IE_RACE], Modified[IE_RACE] );
+ buffer.appendFormatted("Gender: %d current gender:%d\n", BaseStats[IE_SEX], Modified[IE_SEX] );
+ buffer.appendFormatted("Specifics: %d current specifics:%d\n", BaseStats[IE_SPECIFIC], Modified[IE_SPECIFIC] );
+ buffer.appendFormatted("Alignment: %x current alignment:%x\n", BaseStats[IE_ALIGNMENT], Modified[IE_ALIGNMENT] );
+ buffer.appendFormatted("Morale: %d current morale:%d\n", BaseStats[IE_MORALE], Modified[IE_MORALE] );
+ buffer.appendFormatted("Moralebreak:%d Morale recovery:%d\n", Modified[IE_MORALEBREAK], Modified[IE_MORALERECOVERYTIME] );
+ buffer.appendFormatted("Visualrange:%d (Explorer: %d)\n", Modified[IE_VISUALRANGE], Modified[IE_EXPLORE] );
+
+ //this works for both level slot style
+ buffer.appendFormatted("Levels (average: %d):\n", GetXPLevel(true));
+ for (i = 0;i<ISCLASSES;i++) {
+ int level = GetClassLevel(i);
+ if (level) {
+ buffer.appendFormatted("%s: %d ", isclassnames[i], level);
+ }
+ }
+ buffer.appendFormatted("\n");
+
+ buffer.appendFormatted("current HP:%d\n", BaseStats[IE_HITPOINTS] );
+ buffer.appendFormatted("Mod[IE_ANIMATION_ID]: 0x%04X ResRef:%.8s\n", Modified[IE_ANIMATION_ID], anims->ResRef );
+ buffer.appendFormatted("TURNUNDEADLEVEL: %d current: %d\n", BaseStats[IE_TURNUNDEADLEVEL], Modified[IE_TURNUNDEADLEVEL]);
+ buffer.appendFormatted("Colors: ");
if (core->HasFeature(GF_ONE_BYTE_ANIMID) ) {
for(i=0;i<Modified[IE_COLORCOUNT];i++) {
- printf(" %d", Modified[IE_COLORS+i]);
+ buffer.appendFormatted(" %d", Modified[IE_COLORS+i]);
}
- }
- else {
+ } else {
for(i=0;i<7;i++) {
- printf(" %d", Modified[IE_COLORS+i]);
+ buffer.appendFormatted(" %d", Modified[IE_COLORS+i]);
}
}
- printf( "\nWaitCounter: %d\n", (int) GetWait());
- printf( "LastTarget: %d %s\n", LastTarget, GetActorNameByID(LastTarget));
- printf( "LastTalked: %d %s\n", LastTalkedTo, GetActorNameByID(LastTalkedTo));
- inventory.dump();
- spellbook.dump();
- fxqueue.dump();
-#if 0
- DumpMaxValues();
-#endif
+ buffer.append("\n");
+ buffer.appendFormatted("WaitCounter: %d\n", (int) GetWait());
+ buffer.appendFormatted("LastTarget: %d %s\n", LastTarget, GetActorNameByID(LastTarget));
+ buffer.appendFormatted("LastTalked: %d %s\n", LastTalker, GetActorNameByID(LastTalker));
+ inventory.dump(buffer);
+ spellbook.dump(buffer);
+ fxqueue.dump(buffer);
}
const char* Actor::GetActorNameByID(ieDword ID) const
@@ -3039,6 +4242,15 @@ void Actor::SetMap(Map *map)
//This hack is to delay the equipping effects until the actor has
//an area (and the game object is also existing)
if (effinit) {
+ //already initialized, no need of updating stuff
+ if (InternalFlags & IF_GOTAREA) return;
+ InternalFlags |= IF_GOTAREA;
+
+ //apply feats
+ ApplyFeats();
+ //apply persistent feat spells
+ ApplyExtraSettings();
+
int SlotCount = inventory.GetSlotCount();
for (int Slot = 0; Slot<SlotCount;Slot++) {
int slottype = core->QuerySlotEffects( Slot );
@@ -3060,24 +4272,34 @@ void Actor::SetMap(Map *map)
//find a quiver for the bow, etc
if (Equipped!=IW_NO_EQUIPPED) {
inventory.EquipItem( Equipped+inventory.GetWeaponSlot());
- SetEquippedQuickSlot( inventory.GetEquipped(), EquippedHeader );
+ } else {
+ inventory.EquipItem(inventory.GetFistSlot());
}
+ SetEquippedQuickSlot( inventory.GetEquipped(), EquippedHeader );
}
}
-void Actor::SetPosition(const Point &position, int jump, int radius)
+void Actor::SetPosition(const Point &position, int jump, int radiusx, int radiusy)
{
PathTries = 0;
ClearPath();
- Point p;
+ Point p, q;
p.x = position.x/16;
p.y = position.y/12;
+ q = p;
if (jump && !(Modified[IE_DONOTJUMP] & DNJ_FIT) && size ) {
- GetCurrentArea()->AdjustPosition( p, radius );
+ Map *map = GetCurrentArea();
+ //clear searchmap so we won't block ourselves
+ map->ClearSearchMapFor(this);
+ map->AdjustPosition( p, radiusx, radiusy );
+ }
+ if (p==q) {
+ MoveTo( position );
+ } else {
+ p.x = p.x * 16 + 8;
+ p.y = p.y * 12 + 6;
+ MoveTo( p );
}
- p.x = p.x * 16 + 8;
- p.y = p.y * 12 + 6;
- MoveTo( p );
}
/* this is returning the level of the character for xp calculations
@@ -3094,33 +4316,33 @@ ieDword Actor::GetXPLevel(int modified) const
stats = BaseStats;
}
- float classcount = 0;
+ int clscount = 0;
float average = 0;
- if (core->HasFeature(GF_LEVELSLOT_PER_CLASS)) {
+ if (iwd2class) {
// iwd2
- for (int i=0; i < 11; i++) {
- if (stats[levelslotsiwd2[i]] > 0) classcount++;
+ for (int i=0; i < ISCLASSES; i++) {
+ if (stats[levelslotsiwd2[i]] > 0) clscount++;
}
- average = stats[IE_CLASSLEVELSUM] / classcount + 0.5;
- }
- else {
- int levels[3]={stats[IE_LEVEL], stats[IE_LEVEL2], stats[IE_LEVEL3]};
+ average = stats[IE_CLASSLEVELSUM] / (float) clscount + 0.5;
+ } else {
+ unsigned int levels[3]={stats[IE_LEVEL], stats[IE_LEVEL2], stats[IE_LEVEL3]};
average = levels[0];
- classcount = 1;
+ clscount = 1;
if (IsDualClassed()) {
// dualclassed
if (levels[1] > 0) {
- classcount++;
+ clscount++;
average += levels[1];
}
}
else if (IsMultiClassed()) {
- //classcount is the number of on bits in the MULTI field
- classcount = bitcount (multiclass);
- for (int i=1; i<classcount; i++)
+ //clscount is the number of on bits in the MULTI field
+ clscount = bitcount (multiclass);
+ assert(clscount && clscount <= 3);
+ for (int i=1; i<clscount; i++)
average += levels[i];
} //else single classed
- average = average / classcount + 0.5;
+ average = average / (float) clscount + 0.5;
}
return ieDword(average);
}
@@ -3128,7 +4350,7 @@ ieDword Actor::GetXPLevel(int modified) const
// returns the guessed caster level by passed spell type
// FIXME: add iwd2 support (should be more precise, as there are more class types)
// FIXME: add more logic for cross-type kits (like avengers)?
-ieDword Actor::GetBaseCasterLevel(int spelltype) const
+ieDword Actor::GetBaseCasterLevel(int spelltype, int flags) const
{
int level = 0;
@@ -3147,7 +4369,7 @@ ieDword Actor::GetBaseCasterLevel(int spelltype) const
break;
}
// if nothing was found, use the average level
- if (!level) level = GetXPLevel(true);
+ if (!level && !flags) level = GetXPLevel(true);
return level;
}
@@ -3163,9 +4385,9 @@ int Actor::GetWildMod(int level)
core->GetTokenDictionary()->SetAtCopy("LEVELDIF", abs(WMLevelMod));
if (WMLevelMod > 0) {
- displaymsg->DisplayConstantStringName(STR_CASTER_LVL_INC, 0xffffff, this);
+ displaymsg->DisplayConstantStringName(STR_CASTER_LVL_INC, DMC_WHITE, this);
} else if (WMLevelMod < 0) {
- displaymsg->DisplayConstantStringName(STR_CASTER_LVL_DEC, 0xffffff, this);
+ displaymsg->DisplayConstantStringName(STR_CASTER_LVL_DEC, DMC_WHITE, this);
}
}
return WMLevelMod;
@@ -3194,17 +4416,45 @@ ieDword Actor::GetCasterLevel(int spelltype)
return level + CastingLevelBonus(level, spelltype);
}
-/** maybe this would be more useful if we calculate with the strength too
-*/
-int Actor::GetEncumbrance()
+// this works properly with disabled dualclassed actors, since it ends up in GetClassLevel
+ieDword Actor::GetAnyActiveCasterLevel() const
{
- return inventory.GetWeight();
+ int strict = 1;
+ // only player classes will have levels in the correct slots
+ if (BaseStats[IE_CLASS] == 0 || BaseStats[IE_CLASS] >= (ieDword) classcount) {
+ strict = 0;
+ }
+ return GetBaseCasterLevel(IE_SPL_PRIEST, strict) + GetBaseCasterLevel(IE_SPL_WIZARD, strict);
}
-//bg2 and iwd1
-static EffectRef control_creature_ref = { "ControlCreature", -1 };
-//iwd2
-static EffectRef control_undead_ref = { "ControlUndead2", -1 };
+int Actor::CalculateSpeed(bool feedback)
+{
+ int speed = GetStat(IE_MOVEMENTRATE);
+ if (BaseStats[IE_EA] > EA_GOODCUTOFF && !third) {
+ // cheating bastards (drow in ar2401 for example)
+ return speed;
+ }
+
+ inventory.CalculateWeight();
+ int encumbrance = inventory.GetWeight();
+ SetStat(IE_ENCUMBRANCE, encumbrance, false);
+ int maxweight = GetMaxEncumbrance();
+
+ if(encumbrance<=maxweight) {
+ return speed;
+ }
+ if(encumbrance<=maxweight*2) {
+ if (feedback) {
+ displaymsg->DisplayConstantStringName(STR_HALFSPEED, DMC_WHITE, this);
+ //print slow speed
+ }
+ return speed/2;
+ }
+ if (feedback) {
+ displaymsg->DisplayConstantStringName(STR_CANTMOVE, DMC_WHITE, this);
+ }
+ return 0;
+}
//receive turning
void Actor::Turn(Scriptable *cleric, ieDword turnlevel)
@@ -3231,12 +4481,12 @@ void Actor::Turn(Scriptable *cleric, ieDword turnlevel)
if (Modified[IE_GENERAL]!=GEN_UNDEAD) {
level = GetPaladinLevel();
if (evilcleric && level) {
- LastTurner = cleric->GetGlobalID();
+ AddTrigger(TriggerEntry(trigger_turnedby, cleric->GetGlobalID()));
if (turnlevel >= level+TURN_DEATH_LVL_MOD) {
if (gamedata->Exists("panic", IE_SPL_CLASS_ID)) {
core->ApplySpell("panic", this, cleric, level);
} else {
- printf("Panic from turning!\n");
+ print("Panic from turning!");
Panic(cleric, PANIC_RUNAWAY);
}
}
@@ -3246,7 +4496,7 @@ void Actor::Turn(Scriptable *cleric, ieDword turnlevel)
//determine alignment (if equals, then no turning)
- LastTurner = cleric->GetGlobalID();
+ AddTrigger(TriggerEntry(trigger_turnedby, cleric->GetGlobalID()));
//determine panic or destruction/control
//we get the modified level
@@ -3267,7 +4517,7 @@ void Actor::Turn(Scriptable *cleric, ieDword turnlevel)
}
Die(cleric);
} else if (turnlevel >= level+TURN_PANIC_LVL_MOD) {
- printf("Panic from turning!\n");
+ print("Panic from turning!");
Panic(cleric, PANIC_RUNAWAY);
}
}
@@ -3288,12 +4538,12 @@ void Actor::Resurrect()
ClearActions();
ClearPath();
SetStance(IE_ANI_EMERGE);
+ Game *game = core->GetGame();
//readjust death variable on resurrection
if (core->HasFeature(GF_HAS_KAPUTZ) && (AppearanceFlags&APP_DEATHVAR)) {
ieVariable DeathVar;
snprintf(DeathVar,sizeof(ieVariable),"%s_DEAD",scriptName);
- Game *game=core->GetGame();
ieDword value=0;
game->kaputz->Lookup(DeathVar, value);
@@ -3301,14 +4551,41 @@ void Actor::Resurrect()
game->kaputz->SetAt(DeathVar, value-1);
}
}
+ ResetCommentTime();
//clear effects?
}
-static EffectRef fx_cure_poisoned_state_ref = { "Cure:Poison", -1 };
-static EffectRef fx_cure_hold_state_ref = { "Cure:Hold", -1 };
-static EffectRef fx_cure_stun_state_ref = { "Cure:Stun", -1 };
-static EffectRef fx_remove_portrait_icon_ref = { "Icon:Remove", -1 };
-static EffectRef fx_unpause_caster_ref = { "Cure:CasterHold", -1 };
+const char *GetVarName(const char *table, int value)
+{
+ int symbol = core->LoadSymbol( table );
+ if (symbol!=-1) {
+ Holder<SymbolMgr> sym = core->GetSymbol( symbol );
+ return sym->GetValue( value );
+ }
+ return NULL;
+}
+
+void Actor::SendDiedTrigger()
+{
+ if (!area) return;
+ Actor **neighbours = area->GetAllActorsInRadius(Pos, GA_NO_LOS|GA_NO_DEAD, GetSafeStat(IE_VISUALRANGE));
+ Actor **poi = neighbours;
+ ieDword ea = Modified[IE_EA];
+ while (*poi) {
+ (*poi)->AddTrigger(TriggerEntry(trigger_died, GetGlobalID()));
+
+ // allies take a hit on morale and nobody cares about neutrals
+ int pea = (*poi)->GetStat(IE_EA);
+ if (ea < EA_GOODCUTOFF && pea < EA_GOODCUTOFF) {
+ (*poi)->NewBase(IE_MORALE, (ieDword) -1, MOD_ADDITIVE);
+ } else if (ea > EA_EVILCUTOFF && pea > EA_EVILCUTOFF) {
+ (*poi)->NewBase(IE_MORALE, (ieDword) -1, MOD_ADDITIVE);
+ }
+
+ poi++;
+ }
+ free(neighbours);
+}
void Actor::Die(Scriptable *killer)
{
@@ -3321,10 +4598,9 @@ void Actor::Die(Scriptable *killer)
//Can't simply set Selected to false, game has its own little list
Game *game = core->GetGame();
game->SelectActor(this, false, SELECT_NORMAL);
- game->OutAttack(GetGlobalID());
- displaymsg->DisplayConstantStringName(STR_DEATH, 0xffffff, this);
- DisplayStringCore(this, VB_DIE, DS_CONSOLE|DS_CONST );
+ displaymsg->DisplayConstantStringName(STR_DEATH, DMC_WHITE, this);
+ VerbalConstant(VB_DIE, 1 );
// remove poison, hold, casterhold, stun and its icon
Effect *newfx;
@@ -3350,25 +4626,36 @@ void Actor::Die(Scriptable *killer)
if (area)
area->ClearSearchMapFor(this);
- //JUSTDIED will be removed when the Die() trigger executed
+ //JUSTDIED will be removed after the first script check
//otherwise it is the same as REALLYDIED
InternalFlags|=IF_REALLYDIED|IF_JUSTDIED;
- SetStance( IE_ANI_DIE );
+ //remove IDLE so the actor gets a chance to die properly
+ InternalFlags&=~IF_IDLE;
+ if (GetStance() != IE_ANI_DIE) {
+ SetStance(IE_ANI_DIE);
+ }
+ AddTrigger(TriggerEntry(trigger_die));
+ SendDiedTrigger();
Actor *act=NULL;
if (!killer) {
+ // TODO: is this right?
killer = area->GetActorByGlobalID(LastHitter);
}
if (killer) {
if (killer->Type==ST_ACTOR) {
act = (Actor *) killer;
+ // for unknown reasons the original only sends the trigger if the killer is ok
+ if (act && !(act->GetStat(IE_STATE_ID)&(STATE_DEAD|STATE_PETRIFIED|STATE_FROZEN))) {
+ killer->AddTrigger(TriggerEntry(trigger_killed, GetGlobalID()));
+ }
}
}
if (InParty) {
game->PartyMemberDied(this);
- core->Autopause(AP_DEAD);
+ core->Autopause(AP_DEAD, this);
} else {
if (act) {
if (act->InParty) {
@@ -3395,7 +4682,7 @@ void Actor::Die(Scriptable *killer)
//give experience to party
game->ShareXP(Modified[IE_XPVALUE], sharexp );
- if (!InParty && act && act->GetStat(IE_EA) <= EA_CONTROLLABLE) {
+ if (!InParty && act && act->GetStat(IE_EA) <= EA_CONTROLLABLE && !core->InCutSceneMode()) {
// adjust reputation if the corpse was:
// an innocent, a member of the Flaming Fist or something evil
int repmod = 0;
@@ -3413,9 +4700,7 @@ void Actor::Die(Scriptable *killer)
}
}
- //moved clear actions after xp is given
- //it clears some triggers, including the LastHitter
- ClearActions();
+ ReleaseCurrentAction();
ClearPath();
SetModal( MS_NONE );
@@ -3424,10 +4709,14 @@ void Actor::Die(Scriptable *killer)
// death variables are updated at the moment of death
if (KillVar[0]) {
- //don't use the raw killVar here
+ //don't use the raw killVar here (except when the flags explicitly ask for it)
if (core->HasFeature(GF_HAS_KAPUTZ) ) {
if (AppearanceFlags&APP_DEATHTYPE) {
- snprintf(varname, 32, "KILL_%s", KillVar);
+ if (AppearanceFlags&APP_ADDKILL) {
+ snprintf(varname, 32, "KILL_%s", KillVar);
+ } else {
+ snprintf(varname, 32, "%s", KillVar);
+ }
game->kaputz->Lookup(varname, value);
game->kaputz->SetAt(varname, value+1, nocreate);
}
@@ -3436,6 +4725,34 @@ void Actor::Die(Scriptable *killer)
game->locals->SetAt(KillVar, 1, nocreate);
}
}
+
+ if (core->HasFeature(GF_HAS_KAPUTZ) && (AppearanceFlags&APP_FACTION) ) {
+ value = 0;
+ const char *tmp = GetVarName("faction", BaseStats[IE_FACTION]);
+ if (tmp && tmp[0]) {
+ if (AppearanceFlags&APP_ADDKILL) {
+ snprintf(varname, 32, "KILL_%s", tmp);
+ } else {
+ snprintf(varname, 32, "%s", tmp);
+ }
+ game->kaputz->Lookup(varname, value);
+ game->kaputz->SetAt(varname, value+1, nocreate);
+ }
+ }
+ if (core->HasFeature(GF_HAS_KAPUTZ) && (AppearanceFlags&APP_TEAM) ) {
+ value = 0;
+ const char *tmp = GetVarName("team", BaseStats[IE_TEAM]);
+ if (tmp && tmp[0]) {
+ if (AppearanceFlags&APP_ADDKILL) {
+ snprintf(varname, 32, "KILL_%s", tmp);
+ } else {
+ snprintf(varname, 32, "%s", tmp);
+ }
+ game->kaputz->Lookup(varname, value);
+ game->kaputz->SetAt(varname, value+1, nocreate);
+ }
+ }
+
if (IncKillVar[0]) {
value = 0;
game->locals->Lookup(IncKillVar, value);
@@ -3490,7 +4807,7 @@ void Actor::Die(Scriptable *killer)
j=APP_GOOD;
for(i=0;i<4;i++) {
if (AppearanceFlags&j) {
- ieDword value = 0;
+ value = 0;
game->locals->Lookup(CounterNames[i], value);
game->locals->SetAt(CounterNames[i], value+DeathCounters[i], nocreate);
}
@@ -3511,7 +4828,7 @@ void Actor::Die(Scriptable *killer)
Map *area = GetCurrentArea();
if (area) {
- ieDword value = 0;
+ value = 0;
area->locals->Lookup(varname, value);
// i am guessing that we shouldn't decrease below 0
if (value > 0) {
@@ -3521,6 +4838,7 @@ void Actor::Die(Scriptable *killer)
}
//a plot critical creature has died (iwd2)
+ //FIXME: BG2 uses the same field for special creatures (alternate melee damage)
if (BaseStats[IE_MC_FLAGS]&MC_PLOT_CRITICAL) {
core->GetGUIScriptEngine()->RunFunction("GUIWORLD", "DeathWindowPlot", false);
}
@@ -3530,6 +4848,12 @@ void Actor::Die(Scriptable *killer)
void Actor::SetPersistent(int partyslot)
{
+ if (partyslot<0) {
+ //demote actor to be saved in area (after moving between areas)
+ InParty = 0;
+ InternalFlags&=~IF_FROMGAME;
+ return;
+ }
InParty = (ieByte) partyslot;
InternalFlags|=IF_FROMGAME;
//if an actor is coming from a game, it should have these too
@@ -3539,6 +4863,7 @@ void Actor::SetPersistent(int partyslot)
void Actor::DestroySelf()
{
InternalFlags|=IF_CLEANUP;
+ RemovalTime = 0;
// clear search map so that a new actor can immediately go there
// (via ChangeAnimationCore)
if (area)
@@ -3550,10 +4875,9 @@ bool Actor::CheckOnDeath()
if (InternalFlags&IF_CLEANUP) {
return true;
}
- if (InternalFlags&IF_JUSTDIED) {
- if (lastRunTime == 0 || CurrentAction || GetNextAction()) {
- return false; //actor is currently dying, let him die first
- }
+ // FIXME
+ if (InternalFlags&IF_JUSTDIED || CurrentAction || GetNextAction()) {
+ return false; //actor is currently dying, let him die first
}
if (!(InternalFlags&IF_REALLYDIED) ) {
return false;
@@ -3577,6 +4901,11 @@ bool Actor::CheckOnDeath()
// items seem to be dropped at the moment of death
// .. but this can't go in Die() because that is called
// from effects and dropping items might change effects!
+
+ // disintegration destroys normal items if difficulty level is high enough (the stat hack is just for differentiation)
+ if ((BaseStats[IE_SPELLDURATIONMODPRIEST]==1) && (LastDamageType & DAMAGE_MAGIC) && (GameDifficulty>DIFF_CORE) ) {
+ inventory.DestroyItem("", IE_INV_ITEM_DESTRUCTIBLE, (ieDword) ~0);
+ }
DropItem("",0);
//remove all effects that are not 'permanent after death' here
@@ -3586,8 +4915,15 @@ bool Actor::CheckOnDeath()
// party actors are never removed
if (Persistent()) return false;
- if (Modified[IE_MC_FLAGS]&MC_REMOVE_CORPSE) return true;
+ //TODO: verify removal times
+ ieDword time = core->GetGame()->GameTime;
+ if (Modified[IE_MC_FLAGS]&MC_REMOVE_CORPSE) {
+ RemovalTime = time;
+ return true;
+ }
if (Modified[IE_MC_FLAGS]&MC_KEEP_CORPSE) return false;
+ RemovalTime = time + (7200 * AI_UPDATE_TIME); // keep corpse around for a day
+
//if chunked death, then return true
if (LastDamageType&DAMAGE_CHUNKING) {
//play chunky animation
@@ -3632,8 +4968,11 @@ void Actor::GetItemSlotInfo(ItemExtHeader *item, int which, int header)
}
const CREItem *slot = inventory.GetSlotItem(idx);
if (!slot) return; //quick item slot is empty
- Item *itm = gamedata->GetItem(slot->ItemResRef);
- if (!itm) return; //quick item slot contains invalid item resref
+ Item *itm = gamedata->GetItem(slot->ItemResRef, true);
+ if (!itm) {
+ Log(WARNING, "Actor", "Invalid quick slot item: %s!", slot->ItemResRef);
+ return; //quick item slot contains invalid item resref
+ }
ITMExtHeader *ext_header = itm->GetExtHeader(headerindex);
//item has no extended header, or header index is wrong
if (!ext_header) return;
@@ -3674,9 +5013,8 @@ void Actor::ReinitQuickSlots()
int i=sizeof(PCStats->QSlots);
while (i--) {
int slot;
- int which;
- if (i<0) which = ACT_WEAPON4+i+1;
- else which = PCStats->QSlots[i];
+ int which = IWD2GemrbQslot(i);
+
switch (which) {
case ACT_WEAPON1:
case ACT_WEAPON2:
@@ -3691,6 +5029,13 @@ void Actor::ReinitQuickSlots()
case ACT_QSLOT3: slot = inventory.GetQuickSlot()+2; break;
case ACT_QSLOT4: slot = inventory.GetQuickSlot()+3; break;
case ACT_QSLOT5: slot = inventory.GetQuickSlot()+4; break;
+ case ACT_IWDQITEM: slot = inventory.GetQuickSlot(); break;
+ case ACT_IWDQITEM+1: slot = inventory.GetQuickSlot()+1; break;
+ case ACT_IWDQITEM+2: slot = inventory.GetQuickSlot()+2; break;
+ case ACT_IWDQITEM+3: slot = inventory.GetQuickSlot()+3; break;
+ case ACT_IWDQITEM+4: slot = inventory.GetQuickSlot()+4; break;
+ // the rest are unavailable - only three slots in the actual inventory layout, 5 in the class for pst
+ // case ACT_IWDQITEM+9:
default:
slot = 0;
}
@@ -3717,12 +5062,17 @@ void Actor::ReinitQuickSlots()
//these are always present
CheckWeaponQuickSlot(0);
CheckWeaponQuickSlot(1);
+ if (version==22) {
+ CheckWeaponQuickSlot(2);
+ CheckWeaponQuickSlot(3);
+ } else {
//disabling quick weapon slots for certain classes
- for(i=0;i<2;i++) {
- int which = ACT_WEAPON3+i;
- // Assuming that ACT_WEAPON3 and 4 are always in the first two spots
- if (PCStats->QSlots[i+3]!=which) {
- SetupQuickSlot(which, 0xffff, 0xffff);
+ for(i=0;i<2;i++) {
+ int which = ACT_WEAPON3+i;
+ // Assuming that ACT_WEAPON3 and 4 are always in the first two spots
+ if (PCStats->QSlots[i+3]!=which) {
+ SetupQuickSlot(which, 0xffff, 0xffff);
+ }
}
}
}
@@ -3744,7 +5094,7 @@ void Actor::CheckWeaponQuickSlot(unsigned int which)
if (core->QuerySlotEffects(slot) == SLOT_EFFECT_MISSILE) {
const CREItem *slotitm = inventory.GetSlotItem(slot);
assert(slotitm);
- Item *itm = gamedata->GetItem(slotitm->ItemResRef);
+ Item *itm = gamedata->GetItem(slotitm->ItemResRef, true);
assert(itm);
ITMExtHeader *ext_header = itm->GetExtHeader(header);
if (ext_header) {
@@ -3765,16 +5115,30 @@ void Actor::CheckWeaponQuickSlot(unsigned int which)
}
//if dual stuff needs to be handled on load too, improve this method with it
-int Actor::GetHpAdjustment(int multiplier)
+int Actor::GetHpAdjustment(int multiplier) const
{
int val;
+ // only player classes get this bonus
+ if (BaseStats[IE_CLASS] == 0 || BaseStats[IE_CLASS] >= (ieDword) classcount) {
+ return 0;
+ }
+
+ // GetClassLevel/IsWarrior takes into consideration inactive dual-classes, so those would fail here
if (IsWarrior()) {
val = core->GetConstitutionBonus(STAT_CON_HP_WARRIOR,Modified[IE_CON]);
} else {
val = core->GetConstitutionBonus(STAT_CON_HP_NORMAL,Modified[IE_CON]);
}
- return val * multiplier;
+
+ // ensure the change does not kill the actor
+ if (BaseStats[IE_HITPOINTS] + val*multiplier <= 0) {
+ // leave them with 1hp/level worth of hp
+ // note: we return the adjustment and the actual setting of hp happens later
+ return multiplier - BaseStats[IE_HITPOINTS];
+ } else {
+ return val * multiplier;
+ }
}
void Actor::InitStatsOnLoad()
@@ -3792,16 +5156,55 @@ void Actor::InitStatsOnLoad()
Deactivate();
InternalFlags|=IF_REALLYDIED;
} else {
- SetStance( IE_ANI_AWAKE );
+ if (BaseStats[IE_STATE_ID] & STATE_SLEEP) {
+ SetStance( IE_ANI_SLEEP );
+ } else {
+ SetStance( IE_ANI_AWAKE );
+ }
}
inventory.CalculateWeight();
CreateDerivedStats();
Modified[IE_CON]=BaseStats[IE_CON]; // used by GetHpAdjustment
ieDword hp = BaseStats[IE_HITPOINTS] + GetHpAdjustment(GetXPLevel(false));
BaseStats[IE_HITPOINTS]=hp;
+
SetupFist();
//initial setup of modified stats
- memcpy(Modified,BaseStats, sizeof(Modified));
+ memcpy(Modified, BaseStats, sizeof(Modified));
+}
+
+//most feats are simulated via spells (feat<xx>)
+void Actor::ApplyFeats()
+{
+ ieResRef feat;
+
+ for(int i=0;i<MAX_FEATS;i++) {
+ int level = GetFeat(i);
+ snprintf(feat, sizeof(ieResRef), "FEAT%02x", i);
+ if (level) {
+ if (gamedata->Exists(feat, IE_SPL_CLASS_ID, true)) {
+ core->ApplySpell(feat, this, this, level);
+ }
+ }
+ }
+ //apply scripted feats
+ if (InParty) {
+ core->GetGUIScriptEngine()->RunFunction("LUCommon","ApplyFeats", true, InParty);
+ } else {
+ core->GetGUIScriptEngine()->RunFunction("LUCommon","ApplyFeats", true, GetGlobalID());
+ }
+}
+
+void Actor::ApplyExtraSettings()
+{
+ if (!PCStats) return;
+ for (int i=0;i<ES_COUNT;i++) {
+ if (featspells[i] && featspells[i][0]!='*') {
+ if (PCStats->ExtraSettings[i]) {
+ core->ApplySpell(featspells[i], this, this, PCStats->ExtraSettings[i]);
+ }
+ }
+ }
}
void Actor::SetupQuickSlot(unsigned int which, int slot, int headerindex)
@@ -3812,15 +5215,19 @@ void Actor::SetupQuickSlot(unsigned int which, int slot, int headerindex)
core->SetEventFlag(EF_ACTION);
}
-bool Actor::ValidTarget(int ga_flags) const
+bool Actor::ValidTarget(int ga_flags, Scriptable *checker) const
{
//scripts can still see this type of actor
+ //assuming that unscheduled actors can never be valid targets
+ Game *game = core->GetGame();
+ if (game) {
+ ieDword gametime = game->GameTime;
+ if (!Schedule(gametime, true)) return false;
+ }
+
if (ga_flags&GA_NO_HIDDEN) {
- if (Modified[IE_AVATARREMOVAL]) return false;
- if (Modified[IE_EA]>EA_GOODCUTOFF && Modified[IE_STATE_ID]&state_invisible) {
- return false;
- }
+ if (IsInvisibleTo(checker)) return false;
}
if (ga_flags&GA_NO_ALLY) {
@@ -3842,18 +5249,22 @@ bool Actor::ValidTarget(int ga_flags) const
break;
case GA_TALK:
//can't talk to dead
- if (Modified[IE_STATE_ID] & STATE_CANTLISTEN) return false;
+ if (Modified[IE_STATE_ID] & (STATE_CANTLISTEN^STATE_SLEEP)) return false;
//can't talk to hostile
if (Modified[IE_EA]>=EA_EVILCUTOFF) return false;
break;
}
if (ga_flags&GA_NO_DEAD) {
- if (InternalFlags&IF_JUSTDIED) return false;
+ if (InternalFlags&IF_REALLYDIED) return false;
if (Modified[IE_STATE_ID] & STATE_DEAD) return false;
}
if (ga_flags&GA_SELECT) {
if (UnselectableTimer) return false;
if (Immobile()) return false;
+ if (Modified[IE_STATE_ID] & STATE_CONFUSED) return false;
+ if (Modified[IE_STATE_ID] & STATE_BERSERK) {
+ if (Modified[IE_CHECKFORBERSERK]) return false;
+ }
}
return true;
}
@@ -3878,7 +5289,7 @@ void Actor::GetNextAnimation()
if (RowNum<0)
RowNum = CharAnimations::GetAvatarsCount() - 1;
int NewAnimID = CharAnimations::GetAvatarStruct(RowNum)->AnimID;
- printf ("AnimID: %04X\n", NewAnimID);
+ print("AnimID: %04X", NewAnimID);
SetBase( IE_ANIMATION_ID, NewAnimID);
}
@@ -3888,7 +5299,7 @@ void Actor::GetPrevAnimation()
if (RowNum>=CharAnimations::GetAvatarsCount() )
RowNum = 0;
int NewAnimID = CharAnimations::GetAvatarStruct(RowNum)->AnimID;
- printf ("AnimID: %04X\n", NewAnimID);
+ print("AnimID: %04X", NewAnimID);
SetBase( IE_ANIMATION_ID, NewAnimID);
}
@@ -3902,12 +5313,15 @@ ITMExtHeader *Actor::GetRangedWeapon(WeaponInfo &wi) const
if (!wield) {
return NULL;
}
- Item *item = gamedata->GetItem(wield->ItemResRef);
+ Item *item = gamedata->GetItem(wield->ItemResRef, true);
if (!item) {
+ Log(WARNING, "Actor", "Missing or invalid ranged weapon item: %s!", wield->ItemResRef);
return NULL;
}
- //The magic of the bow and the arrow add up?
- wi.enchantment += item->Enchantment;
+ //The magic of the bow and the arrow do not add up
+ if (item->Enchantment > wi.enchantment) {
+ wi.enchantment = item->Enchantment;
+ }
wi.itemflags = wield->Flags;
//wi.range is not set, the projectile has no effect on range?
@@ -3921,12 +5335,13 @@ int Actor::IsDualWielding() const
int slot;
//if the shield slot is a weapon, we're dual wielding
const CREItem *wield = inventory.GetUsedWeapon(true, slot);
- if (!wield) {
+ if (!wield || slot == inventory.GetFistSlot()) {
return 0;
}
- Item *itm = gamedata->GetItem( wield->ItemResRef );
+ Item *itm = gamedata->GetItem(wield->ItemResRef, true);
if (!itm) {
+ Log(WARNING, "Actor", "Missing or invalid wielded weapon item: %s!", wield->ItemResRef);
return 0;
}
@@ -3948,14 +5363,17 @@ ITMExtHeader *Actor::GetWeapon(WeaponInfo &wi, bool leftorright) const
if (!wield) {
return 0;
}
- Item *item = gamedata->GetItem(wield->ItemResRef);
+ Item *item = gamedata->GetItem(wield->ItemResRef, true);
if (!item) {
+ Log(WARNING, "Actor", "Missing or invalid weapon item: %s!", wield->ItemResRef);
return 0;
}
wi.enchantment = item->Enchantment;
wi.itemflags = wield->Flags;
wi.prof = item->WeaProf;
+ wi.critmulti = core->GetCriticalMultiplier(item->ItemType);
+ wi.critrange = core->GetCriticalRange(item->ItemType);
//select first weapon header
ITMExtHeader *which;
@@ -3966,6 +5384,7 @@ ITMExtHeader *Actor::GetWeapon(WeaponInfo &wi, bool leftorright) const
} else {
wi.backstabbing = false;
}
+ wi.wflags |= WEAPON_RANGED;
} else {
which = item->GetWeaponHeader(false);
// any melee weapon usable by a single class thief is game (UAI does not affect this)
@@ -3977,6 +5396,11 @@ ITMExtHeader *Actor::GetWeapon(WeaponInfo &wi, bool leftorright) const
}
}
+ if (which && (which->RechargeFlags&IE_ITEM_KEEN)) {
+ //this is correct, the threat range is only increased by one in the original engine
+ wi.critrange--;
+ }
+
//make sure we use 'false' in this freeitem
//so 'which' won't point into invalid memory
gamedata->FreeItem(item, wield->ItemResRef, false);
@@ -3988,7 +5412,6 @@ ITMExtHeader *Actor::GetWeapon(WeaponInfo &wi, bool leftorright) const
}
wi.range = which->Range+1;
return which;
- //return which->Range+1;
}
void Actor::GetNextStance()
@@ -3996,7 +5419,7 @@ void Actor::GetNextStance()
static int Stance = IE_ANI_AWAKE;
if (--Stance < 0) Stance = MAX_ANIMS-1;
- printf ("StanceID: %d\n", Stance);
+ print("StanceID: %d", Stance);
SetStance( Stance );
}
@@ -4013,13 +5436,20 @@ int Actor::LearnSpell(const ieResRef spellname, ieDword flags)
return LSR_INVALID; //not existent spell
}
- if (flags & LS_STATS) {
+ //innates are always memorized when gained
+ if (spell->SpellType==IE_SPL_INNATE) {
+ flags|=LS_MEMO;
+ }
+
+ ieDword kit = GetStat(IE_KIT);
+
+ if ((flags & LS_STATS) && (GameDifficulty>DIFF_NORMAL) ) {
// chance to learn roll
int roll = LuckyRoll(1, 100, 0);
// adjust the roll for specialist mages
// doesn't work in bg1, since its spells don't have PrimaryType set (0 is NONE)
- if (GetKitIndex(BaseStats[IE_KIT]) && spell->PrimaryType) {
- if ((signed)BaseStats[IE_KIT] == 1<<(spell->PrimaryType+5)) { // +5 since the kit values start at 0x40
+ if (!third && GetKitIndex(kit) && spell->PrimaryType) {
+ if (kit == (unsigned) 1<<(spell->PrimaryType+5)) { // +5 since the kit values start at 0x40
roll += 15;
} else {
roll -= 15;
@@ -4031,7 +5461,8 @@ int Actor::LearnSpell(const ieResRef spellname, ieDword flags)
}
}
- int explev = spellbook.LearnSpell(spell, flags&LS_MEMO);
+ int clsmsk = GetBookMask();
+ int explev = spellbook.LearnSpell(spell, flags&LS_MEMO, clsmsk, kit );
int tmp = spell->SpellName;
if (flags&LS_LEARN) {
core->GetTokenDictionary()->SetAt("SPECIALABILITYNAME", core->GetString(tmp));
@@ -4052,7 +5483,7 @@ int Actor::LearnSpell(const ieResRef spellname, ieDword flags)
return LSR_INVALID;
}
if (tmp) {
- displaymsg->DisplayConstantStringName(tmp, 0xbcefbc, this);
+ displaymsg->DisplayConstantStringName(tmp, DMC_BG2XPGREEN, this);
}
if (flags&LS_ADDXP && !(flags&LS_NOXP)) {
int xp = CalculateExperience(XP_LEARNSPELL, explev);
@@ -4073,7 +5504,8 @@ const char *Actor::GetDialog(int flags) const
if ( (InternalFlags & IF_NOINT) && CurrentAction) {
if (flags>1) {
- displaymsg->DisplayConstantString(STR_TARGETBUSY,0xff0000);
+ core->GetTokenDictionary()->SetAtCopy("TARGET", ShortName);
+ displaymsg->DisplayConstantString(STR_TARGETBUSY, DMC_RED);
}
return NULL;
}
@@ -4117,7 +5549,7 @@ void Actor::SetModal(ieDword newstate, bool force)
if (IsSelected()) {
// display the turning-off message
if (ModalState != MS_NONE) {
- displaymsg->DisplayStringName(core->ModalStates[ModalState].leaving_str, 0xffffff, this, IE_STR_SOUND|IE_STR_SPEECH);
+ displaymsg->DisplayStringName(core->ModalStates[ModalState].leaving_str, DMC_WHITE, this, IE_STR_SOUND|IE_STR_SPEECH);
}
// when called with the same state twice, toggle to MS_NONE
@@ -4166,19 +5598,17 @@ int Actor::GetAttackStyle() const
void Actor::AttackedBy( Actor *attacker)
{
- LastAttacker = attacker->GetGlobalID();
- Game * game = core->GetGame();
- game->InAttack(GetGlobalID() );
- game->InAttack(LastAttacker);
+ AddTrigger(TriggerEntry(trigger_attackedby, attacker->GetGlobalID()));
+ if (attacker->GetStat(IE_EA) != EA_PC && Modified[IE_EA] != EA_PC) {
+ LastAttacker = attacker->GetGlobalID();
+ }
+ if (InParty) {
+ core->Autopause(AP_ATTACKED, this);
+ }
}
-void Actor::SetTarget( Scriptable *target)
+void Actor::FaceTarget( Scriptable *target)
{
- if (target->Type==ST_ACTOR) {
- Actor *tar = (Actor *) target;
- LastTarget = tar->GetGlobalID();
- tar->AttackedBy(this);
- }
SetOrientation( GetOrient( target->Pos, Pos ), false );
}
@@ -4186,11 +5616,11 @@ void Actor::SetTarget( Scriptable *target)
void Actor::StopAttack()
{
SetStance(IE_ANI_READY);
+ lastattack = 0;
secondround = 0;
- core->GetGame()->OutAttack(GetGlobalID());
- InternalFlags|=IF_TARGETGONE; //this is for the trigger!
+ //InternalFlags|=IF_TARGETGONE; //this is for the trigger!
if (InParty) {
- core->Autopause(AP_NOTARGET);
+ core->Autopause(AP_NOTARGET, this);
}
}
@@ -4205,10 +5635,135 @@ int Actor::Immobile() const
if (GetStat(IE_STATE_ID) & STATE_STILL) {
return 1;
}
+ Game *game = core->GetGame();
+ if (game && game->TimeStoppedFor(this)) {
+ return 1;
+ }
return 0;
}
+ieDword Actor::GetNumberOfAttacks()
+{
+ int bonus = 0;
+
+ if (third) {
+ int base = SetBaseAPRandAB (true);
+ // add the offhand extra attack
+ // TODO: check effects too
+ bonus = 2 * IsDualWielding();
+ return base + bonus;
+ } else {
+ if (monkbon != NULL && Equipped == IW_NO_EQUIPPED) {
+ unsigned int level = GetMonkLevel();
+ if (level>=monkbon_cols) level=monkbon_cols-1;
+ if (level>0) {
+ bonus = monkbon[0][level-1];
+ }
+ }
+
+ return GetStat(IE_NUMBEROFATTACKS)+bonus;
+ }
+}
+static const int BaseAttackBonusDecrement = 5; // iwd2; number of tohit points for another attack per round
+static int SetLevelBAB(int level, ieDword index)
+{
+ if (!level) {
+ return 0;
+ }
+ assert(index < BABClassMap.size());
+
+ IWD2HitTableIter table = IWD2HitTable.find(BABClassMap[index]);
+ assert(table != IWD2HitTable.end());
+ return table->second[level-1].bab;
+}
+
+// return the base APR derived from the base attack bonus, which we have to construct here too
+//NOTE: this doesn't break iwd2 monsters, since they have their level stored as fighters (if not more)
+int Actor::SetBaseAPRandAB(bool CheckRapidShot)
+{
+ int pBAB = 0;
+ int pBABDecrement = BaseAttackBonusDecrement;
+ ieDword MonkLevel = 0;
+ ieDword LevelSum = 0;
+ int i;
+
+ if (!third) {
+ ToHit.SetBase(BaseStats[IE_TOHIT]);
+ return 0;
+ }
+
+ for (i = 0; i<ISCLASSES; i++) {
+ int level = GetClassLevel(i);
+ if (level) {
+ // silly monks, always wanting to be special
+ if (i == ISMONK) {
+ MonkLevel = level;
+ if (MonkLevel+LevelSum == Modified[IE_CLASSLEVELSUM]) {
+ // only the monk left to check, so skip the rest
+ break;
+ } else {
+ continue;
+ }
+ }
+ pBAB += SetLevelBAB(level, i);
+ LevelSum += level;
+ if (LevelSum == Modified[IE_CLASSLEVELSUM]) {
+ // skip to apr calc, no need to check the other classes
+ ToHit.SetBase(pBAB);
+ ToHit.SetBABDecrement(pBABDecrement);
+ return BAB2APR(pBAB, pBABDecrement, CheckRapidShot);
+ }
+ }
+ }
+
+ if (MonkLevel) {
+ // act as a rogue unless barefisted and without armor
+ // multiclassed monks only use their monk levels when determining barefisted bab
+ // check the spell failure instead of the skill penalty, since otherwise leather armor would also be treated as none
+ if (Equipped != IW_NO_EQUIPPED || GetTotalArmorFailure()) {
+ pBAB += SetLevelBAB(MonkLevel, ISTHIEF);
+ } else {
+ pBABDecrement = 3;
+ pBAB = SetLevelBAB(MonkLevel, ISMONK);
+ }
+ LevelSum += MonkLevel;
+ }
+
+ assert(LevelSum == Modified[IE_CLASSLEVELSUM]);
+ ToHit.SetBase(pBAB);
+ ToHit.SetBABDecrement(pBABDecrement);
+ return BAB2APR(pBAB, pBABDecrement, CheckRapidShot);
+}
+
+int Actor::BAB2APR(int pBAB, int pBABDecrement, int CheckRapidShot) const
+{
+ if (CheckRapidShot && HasSpellState(SS_RAPIDSHOT)) {
+ WeaponInfo wi;
+ ITMExtHeader *HittingHeader = GetRangedWeapon(wi);
+ if (HittingHeader) {
+ ieDword AttackTypeLowBits = HittingHeader->AttackType & 0xFF; // this is done by the original; leaving in case we expand
+ if (AttackTypeLowBits == ITEM_AT_BOW || AttackTypeLowBits == ITEM_AT_PROJECTILE) {
+ // rapid shot gives another attack and since it is computed from the BAB, we just increase that ...
+ // but monk get their speedy handy work only for fists, so we can't use the passed pBABDecrement
+ pBAB += BaseAttackBonusDecrement;
+ }
+ }
+ }
+
+ int APR = (pBAB - 1) / pBABDecrement + 1;
+ //FIXME: why is it not using the other IWD2HitTable column? Less moddable this way
+ // the original hardcoded this, but we can do better - all the data is already in the tables
+ // HOWEVER, what to do with multiclass characters? -> check the monk table, since it is prone to have the highest values?
+ // additionally, 5 is the real max, but not without dualwielding or effects
+ if (APR > 4) {
+ APR = 4;
+ }
+ // NOTE: we currently double the value, since it is stored doubled in other games and effects rely on it
+ // if you want to change it, don't forget to do the same for the bonus in GetNumberOfAttacks
+ return APR*2;
+}
+
//calculate how many attacks will be performed
//in the next round
//only called when Game thinks we are in attack
@@ -4218,50 +5773,15 @@ void Actor::InitRound(ieDword gameTime)
lastInit = gameTime;
secondround = !secondround;
- //roundTime will equal 0 if we aren't attacking something
- if (roundTime) {
- //only perform calculations at the beginning of the round!
- if (((gameTime-roundTime)%core->Time.round_size != 0) || \
- (roundTime == lastInit)) {
- return;
- }
- }
-
//reset variables used in PerformAttack
attackcount = 0;
attacksperround = 0;
nextattack = 0;
lastattack = 0;
- //we set roundTime to zero on any of the following returns, because this
- //is guaranteed to be the start of a round, and we only want roundTime
- //if we are attacking this round
- if (InternalFlags&IF_STOPATTACK) {
- core->GetGame()->OutAttack(GetGlobalID());
- roundTime = 0;
- return;
- }
-
- if (!LastTarget) {
- StopAttack();
- roundTime = 0;
- return;
- }
-
- //if held or disabled, etc, then cannot continue attacking
- ieDword state = GetStat(IE_STATE_ID);
- if (state&STATE_CANTMOVE) {
- roundTime = 0;
- return;
- }
- if (Immobile()) {
- roundTime = 0;
- return;
- }
-
//add one for second round to get an extra attack only if we
//are x/2 attacks per round
- attackcount = GetStat(IE_NUMBEROFATTACKS);
+ attackcount = GetNumberOfAttacks();
if (secondround) {
attackcount++;
}
@@ -4278,21 +5798,49 @@ void Actor::InitRound(ieDword gameTime)
roundTime = gameTime;
//print a little message :)
- printMessage("InitRound", " ", WHITE);
- printf("Name: %s | Attacks: %d | Start: %d\n", ShortName, attacksperround, gameTime);
+ Log(MESSAGE, "InitRound", "Name: %s | Attacks: %d | Start: %d",
+ ShortName, attacksperround, gameTime);
// this might not be the right place, but let's give it a go
if (attacksperround && InParty) {
- core->Autopause(AP_ENDROUND);
+ core->Autopause(AP_ENDROUND, this);
+ }
+}
+
+// a simplified check from GetCombatDetails for use in AttackCore
+bool Actor::WeaponIsUsable(bool leftorright, ITMExtHeader *header) const
+{
+ WeaponInfo wi;
+ if (!header) {
+ header = GetWeapon(wi, leftorright && IsDualWielding());
+ if (!header) {
+ return false;
+ }
+ }
+ ITMExtHeader *rangedheader;
+ switch(header->AttackType) {
+ case ITEM_AT_MELEE:
+ case ITEM_AT_PROJECTILE: //throwing weapon
+ break;
+ case ITEM_AT_BOW:
+ rangedheader = GetRangedWeapon(wi);
+ if (!rangedheader) {
+ return false;
+ }
+ break;
+ default:
+ //item is unsuitable for fight
+ return false;
}
+ return true;
}
bool Actor::GetCombatDetails(int &tohit, bool leftorright, WeaponInfo& wi, ITMExtHeader *&header, ITMExtHeader *&hittingheader, \
- ieDword &Flags, int &DamageBonus, int &speed, int &CriticalBonus, int &style, Actor *target) const
+ int &DamageBonus, int &speed, int &CriticalBonus, int &style, Actor *target)
{
- tohit = GetStat(IE_TOHIT);
- speed = -GetStat(IE_PHYSICALSPEED);
- bool dualwielding = IsDualWielding();
+ SetBaseAPRandAB(true);
+ speed = -(int)GetStat(IE_PHYSICALSPEED);
+ ieDword dualwielding = IsDualWielding();
header = GetWeapon(wi, leftorright && dualwielding);
if (!header) {
return false;
@@ -4303,23 +5851,25 @@ bool Actor::GetCombatDetails(int &tohit, bool leftorright, WeaponInfo& wi, ITMEx
ITMExtHeader *rangedheader = NULL;
int THAC0Bonus = hittingheader->THAC0Bonus;
DamageBonus = hittingheader->DamageBonus;
+
switch(hittingheader->AttackType) {
case ITEM_AT_MELEE:
- Flags = WEAPON_MELEE;
+ wi.wflags = WEAPON_MELEE;
break;
case ITEM_AT_PROJECTILE: //throwing weapon
- Flags = WEAPON_RANGED;
+ wi.wflags = WEAPON_RANGED;
break;
case ITEM_AT_BOW:
rangedheader = GetRangedWeapon(wi);
if (!rangedheader) {
//display out of ammo verbal constant if there is any???
- //DisplayStringCore(this, VB_OUTOFAMMO, DS_CONSOLE|DS_CONST );
+ //VerbalConstant(VB_OUTOFAMMO, 1 );
//SetStance(IE_ANI_READY);
//set some trigger?
return false;
}
- Flags = WEAPON_RANGED;
+ wi.wflags = WEAPON_RANGED;
+ wi.launcherdmgbon = DamageBonus; // save the original (launcher) bonus
//The bow can give some bonuses, but the core attack is made by the arrow.
hittingheader = rangedheader;
THAC0Bonus += rangedheader->THAC0Bonus;
@@ -4327,11 +5877,19 @@ bool Actor::GetCombatDetails(int &tohit, bool leftorright, WeaponInfo& wi, ITMEx
break;
default:
//item is unsuitable for fight
- //SetStance(IE_ANI_READY);
+ wi.wflags = 0;
return false;
}//melee or ranged
+ if (ReverseToHit) THAC0Bonus = -THAC0Bonus;
+ ToHit.SetWeaponBonus(THAC0Bonus);
+
+ //TODO easier copying of recharge flags into wflags
//this flag is set by the bow in case of projectile launcher.
- if (header->RechargeFlags&IE_ITEM_USESTRENGTH) Flags|=WEAPON_USESTRENGTH;
+ if (header->RechargeFlags&IE_ITEM_USESTRENGTH) wi.wflags|=WEAPON_USESTRENGTH;
+ // this flag is set in dagger/shortsword by the loader
+ if (header->RechargeFlags&IE_ITEM_USEDEXTERITY) wi.wflags|=WEAPON_FINESSE;
+ //also copy these flags (they match their WEAPON_ counterparts)
+ wi.wflags|=header->RechargeFlags&(IE_ITEM_KEEN|IE_ITEM_BYPASS);
// get our dual wielding modifier
if (dualwielding) {
@@ -4341,33 +5899,59 @@ bool Actor::GetCombatDetails(int &tohit, bool leftorright, WeaponInfo& wi, ITMEx
DamageBonus += GetStat(IE_DAMAGEBONUSRIGHT);
}
}
+ DamageBonus += GetStat(IE_DAMAGEBONUS);
leftorright = leftorright && dualwielding;
- if (leftorright) Flags|=WEAPON_LEFTHAND;
+ if (leftorright) wi.wflags|=WEAPON_LEFTHAND;
//add in proficiency bonuses
- ieDword stars;
- if (wi.prof && (wi.prof <= MAX_STATS)) {
- stars = GetStat(wi.prof)&PROFS_MASK;
+ ieDword stars = GetProficiency(wi.prof)&PROFS_MASK;
- //hit/damage/speed bonuses from wspecial
- if ((signed)stars > wspecial_max) {
- stars = wspecial_max;
+ //tenser's transformation makes the actor proficient in any weapons
+ if (!stars && HasSpellState(SS_TENSER)) stars = 1;
+
+ //hit/damage/speed bonuses from wspecial (with tohit inverted in adnd)
+ if ((signed)stars > wspecial_max) {
+ stars = wspecial_max;
+ }
+
+ int prof = 0;
+ if (wi.wflags&WEAPON_BYPASS) {
+ //FIXME:this type of weapon ignores all armor, -4 is for balance?
+ //or i just got lost a negation somewhere
+ prof += -4;
+ } else {
+ // everyone is proficient with fists
+ if (Equipped != IW_NO_EQUIPPED) {
+ prof += wspecial[stars][0];
+ }
+ }
+ wi.profdmgbon = wspecial[stars][1];
+ DamageBonus += wi.profdmgbon;
+ speed += wspecial[stars][2];
+ // add non-proficiency penalty, which is missing from the table in non-iwd2
+ // stored negative
+ if (stars == 0 && !third) {
+ ieDword clss = BaseStats[IE_CLASS];
+ //Is it a PC class?
+ if (clss < (ieDword) classcount) {
+ // but skip fists, since they don't have a proficiency
+ if (Equipped != IW_NO_EQUIPPED) {
+ prof += defaultprof[clss];
+ }
+ } else {
+ //it is not clear what is the penalty for non player classes
+ prof += 4;
}
- THAC0Bonus += wspecial[stars][0];
- DamageBonus += wspecial[stars][1];
- speed += wspecial[stars][2];
- // add non-proficiency penalty, which is missing from the table
- if (stars == 0) THAC0Bonus -= 4;
}
- if (IsDualWielding() && wsdualwield) {
+ if (dualwielding && wsdualwield) {
//add dual wielding penalty
stars = GetStat(IE_PROFICIENCY2WEAPON)&PROFS_MASK;
if (stars > STYLE_MAX) stars = STYLE_MAX;
style = 1000*stars + IE_PROFICIENCY2WEAPON;
- THAC0Bonus += wsdualwield[stars][leftorright?1:0];
- } else if (wi.itemflags&(IE_INV_ITEM_TWOHANDED) && (Flags&WEAPON_MELEE) && wstwohanded) {
+ prof += wsdualwield[stars][leftorright?1:0];
+ } else if (wi.itemflags&(IE_INV_ITEM_TWOHANDED) && (wi.wflags&WEAPON_MELEE) && wstwohanded) {
//add two handed profs bonus
stars = GetStat(IE_PROFICIENCY2HANDED)&PROFS_MASK;
if (stars > STYLE_MAX) stars = STYLE_MAX;
@@ -4376,7 +5960,7 @@ bool Actor::GetCombatDetails(int &tohit, bool leftorright, WeaponInfo& wi, ITMEx
DamageBonus += wstwohanded[stars][0];
CriticalBonus = wstwohanded[stars][1];
speed += wstwohanded[stars][2];
- } else if (Flags&WEAPON_MELEE) {
+ } else if (wi.wflags&WEAPON_MELEE) {
int slot;
CREItem *weapon = inventory.GetUsedWeapon(true, slot);
if(wssingle && weapon == NULL) {
@@ -4398,14 +5982,44 @@ bool Actor::GetCombatDetails(int &tohit, bool leftorright, WeaponInfo& wi, ITMEx
// ranged - no bonus
}
+ // racial enemies suffer 4hp more in all games
+ if (GetRangerLevel() && GetRacialEnemyBonus(target)) {
+ DamageBonus += 4;
+ }
+
// TODO: Elves get a racial THAC0 bonus with all swords and bows in BG2 (but not daggers)
- //second parameter is left or right hand flag
- tohit = GetToHit(THAC0Bonus, Flags, target);
+ if (third) {
+ // iwd2 gives a dualwielding bonus when using a simple weapon in the offhand
+ // it is limited to shortswords and daggers, which also have this flag set
+ // the bonus is applied to both hands
+ if (dualwielding) {
+ if (leftorright) {
+ if (wi.wflags&WEAPON_FINESSE) {
+ prof += 2;
+ }
+ } else {
+ // lookup the offhand
+ ITMExtHeader *header2;
+ WeaponInfo wi2;
+ header2 = GetWeapon(wi2, true);
+ if (header2->RechargeFlags&IE_ITEM_USEDEXTERITY) { // identical to the WEAPON_FINESSE check
+ prof += 2;
+ }
+ }
+ }
+ } else {
+ prof = -prof;
+ }
+ ToHit.SetProficiencyBonus(prof);
+
+ // get the remaining boni
+ // FIXME: merge
+ tohit = GetToHit(wi.wflags, target);
//pst increased critical hits
if (pstflags && (Modified[IE_STATE_ID]&STATE_CRIT_ENH)) {
- CriticalBonus++;
+ CriticalBonus--;
}
return true;
}
@@ -4417,71 +6031,145 @@ int Actor::MeleePenalty() const
return 0;
}
-int Actor::GetToHit(int bonus, ieDword Flags, Actor *target) const
+//FIXME: can get called on its own and ToHit could erroneusly give weapon and some prof boni in that case
+int Actor::GetToHit(ieDword Flags, Actor *target)
{
- int tohit = bonus;
+ int generic = 0;
+ int prof = 0;
+ int attacknum = attackcount;
//get our dual wielding modifier
if (IsDualWielding()) {
if (Flags&WEAPON_LEFTHAND) {
- tohit += GetStat(IE_HITBONUSLEFT);
+ generic = GetStat(IE_HITBONUSLEFT);
+ attacknum = 1; // shouldn't be needed, but let's play safe
} else {
- tohit += GetStat(IE_HITBONUSRIGHT);
+ generic = GetStat(IE_HITBONUSRIGHT);
+ attacknum--; // remove 1, since it is for the other hand (otherwise we would never use the max tohit for this hand)
+ }
+ if (third) {
+ // FIXME: externalise
+ // penalites and boni for both hands:
+ // -6 main, -10 off with no adjustments
+ // 0 main, +4 off with ambidexterity
+ // +2 main, +2 off with two weapon fighting
+ // +2 main, +2 off with a simple weapons in the off hand (handled in GetCombatDetails)
+ if (HasFeat(FEAT_TWO_WEAPON_FIGHTING)) {
+ prof += 2;
+ }
+ if (Flags&WEAPON_LEFTHAND) {
+ prof -= 6;
+ } else {
+ prof -= 10;
+ if (HasFeat(FEAT_AMBIDEXTERITY)) {
+ prof += 4;
+ }
+ }
}
}
+ ToHit.SetProficiencyBonus(ToHit.GetProficiencyBonus()+prof);
+
+ // set up strength/dexterity boni
+ GetTHAbilityBonus(Flags);
+
+ // check if there is any armor unproficiency penalty
+ int am = 0, sm = 0;
+ GetArmorSkillPenalty(1, am, sm);
+ ToHit.SetArmorBonus(-am);
+ ToHit.SetShieldBonus(-sm);
//get attack style (melee or ranged)
switch(Flags&WEAPON_STYLEMASK) {
case WEAPON_MELEE:
- tohit += GetStat(IE_MELEETOHIT);
+ generic += GetStat(IE_MELEETOHIT);
break;
case WEAPON_FIST:
- tohit += GetStat(IE_FISTHIT);
+ generic += GetStat(IE_FISTHIT);
break;
case WEAPON_RANGED:
- tohit += GetStat(IE_MISSILEHITBONUS);
- //add dexterity bonus
- tohit += core->GetDexterityBonus(STAT_DEX_MISSILE, GetStat(IE_DEX));
+ generic += GetStat(IE_MISSILEHITBONUS);
break;
}
- //add strength bonus if we need
- if (Flags&WEAPON_USESTRENGTH) {
- tohit += core->GetStrengthBonus(0,GetStat(IE_STR), GetStat(IE_STREXTRA) );
- }
-
if (target) {
// if the target is using a ranged weapon while we're meleeing, we get a +4 bonus
if ((Flags&WEAPON_STYLEMASK) != WEAPON_RANGED) {
if (target->GetAttackStyle() == WEAPON_RANGED) {
- tohit += 4;
+ generic += 4;
}
}
// melee vs. unarmed
- tohit += target->MeleePenalty() - MeleePenalty();
+ generic += target->MeleePenalty() - MeleePenalty();
// add +4 attack bonus vs racial enemies
if (GetRangerLevel()) {
- if (IsRacialEnemy(target)) {
- tohit += 4;
+ generic += GetRacialEnemyBonus(target);
+ }
+ generic += fxqueue.BonusAgainstCreature(fx_tohit_vs_creature_ref, target);
+ }
+
+ // finally involve the Modified stat and add to it the rest of the generic bonus
+ if (ReverseToHit) {
+ ToHit.SetGenericBonus(ToHit.GetGenericBonus()-generic);
+ return ToHit.GetTotal();
+ } else {
+ ToHit.SetGenericBonus(ToHit.GetGenericBonus()+generic); // flat out cummulative
+ return ToHit.GetTotalForAttackNum(attacknum);
+ }
+}
+
+void Actor::GetTHAbilityBonus(ieDword Flags)
+{
+ int dexbonus = 0, strbonus = 0;
+ //add strength bonus if we need
+ if (Flags&WEAPON_USESTRENGTH) {
+ if (third) {
+ strbonus = GetAbilityBonus(IE_STR );
+ } else {
+ strbonus = core->GetStrengthBonus(0,GetStat(IE_STR), GetStat(IE_STREXTRA) );
+ }
+ }
+
+ //get attack style (melee or ranged)
+ switch(Flags&WEAPON_STYLEMASK) {
+ case WEAPON_MELEE:
+ if ((Flags&WEAPON_FINESSE) && HasFeat(FEAT_WEAPON_FINESSE) ) {
+ if (third) {
+ dexbonus = GetAbilityBonus(IE_DEX );
+ } else {
+ dexbonus = core->GetDexterityBonus(STAT_DEX_MISSILE, GetStat(IE_DEX));
+ }
+ // weapon finesse is not cummulative
+ if (dexbonus > strbonus) {
+ strbonus = 0;
+ } else {
+ dexbonus = 0;
+ }
+ }
+ break;
+ case WEAPON_RANGED:
+ //add dexterity bonus
+ if (third) {
+ dexbonus = GetAbilityBonus(IE_DEX);
+ } else {
+ dexbonus = core->GetDexterityBonus(STAT_DEX_MISSILE, GetStat(IE_DEX));
}
- }
+ //TODO: check what to do with weapons with WEAPON_USESTRENGTH (there's a sling in bg2 with it)
+ // do these stack or are handled like finesse or are really only damage boni or there is no game with both?
+ break;
+ // no ability tohit bonus for WEAPON_FIST
}
- if (ReverseToHit) {
- tohit = (signed)GetStat(IE_TOHIT)-tohit;
+ // both strength and dex bonus are stored positive only in iwd2
+ if (third) {
+ ToHit.SetAbilityBonus(dexbonus + strbonus);
} else {
- tohit += GetStat(IE_TOHIT);
+ ToHit.SetAbilityBonus(-(dexbonus + strbonus));
}
- return tohit;
}
-static const int weapon_damagetype[] = {DAMAGE_CRUSHING, DAMAGE_PIERCING,
- DAMAGE_CRUSHING, DAMAGE_SLASHING, DAMAGE_MISSILE, DAMAGE_STUNNING};
-static EffectRef fx_ac_vs_creature_type_ref = { "ACVsCreatureType", -1 };
-
-int Actor::GetDefense(int DamageType, Actor *attacker) const
+int Actor::GetDefense(int DamageType, ieDword wflags, Actor *attacker)
{
//specific damage type bonus.
int defense = 0;
@@ -4505,6 +6193,7 @@ int Actor::GetDefense(int DamageType, Actor *attacker) const
break;
}
+
//check for s/s and single weapon ac bonuses
if (!IsDualWielding() && wssingle && wsswordshield) {
WeaponInfo wi;
@@ -4528,26 +6217,37 @@ int Actor::GetDefense(int DamageType, Actor *attacker) const
}
}
- if (ReverseToHit) {
- defense = GetStat(IE_ARMORCLASS)-defense;
+ if (wflags&WEAPON_BYPASS) {
+ if (ReverseToHit) {
+ // deflection is used to store the armor value in adnd
+ defense = AC.GetTotal() - AC.GetDeflectionBonus() - defense;
+ } else {
+ defense += AC.GetTotal() - AC.GetArmorBonus() - AC.GetShieldBonus();
+ }
} else {
- defense += GetStat(IE_ARMORCLASS);
+ if (ReverseToHit) {
+ defense = AC.GetTotal()-defense;
+ } else {
+ defense += AC.GetTotal();
+ }
}
- //Dexterity bonus is stored negative in 2da files.
- defense += core->GetDexterityBonus(STAT_DEX_AC, GetStat(IE_DEX) );
+
if (attacker) {
defense -= fxqueue.BonusAgainstCreature(fx_ac_vs_creature_type_ref,attacker);
}
return defense;
}
-
void Actor::PerformAttack(ieDword gameTime)
{
- // start a new round if we really don't have one yet
- if (!roundTime) {
- printMessage("Actor", "Unregistered attack. We shouldn't be here?\n", RED);
- secondround = 0;
+ if (InParty) {
+ // TODO: this is temporary hack
+ Game *game = core->GetGame();
+ game->PartyAttack = true;
+ }
+
+ if (!roundTime || (gameTime-roundTime > core->Time.attack_round_size)) { // the original didn't use a normal round
+ // TODO: do we need cleverness for secondround here?
InitRound(gameTime);
}
@@ -4561,7 +6261,7 @@ void Actor::PerformAttack(ieDword gameTime)
// this check shouldn't be necessary, but it causes a divide-by-zero below,
// so i would like it to be clear if it ever happens
if (attacksperround==0) {
- printMessage("Actor", "APR was 0 in PerformAttack!\n", RED);
+ Log(ERROR, "Actor", "APR was 0 in PerformAttack!");
return;
}
@@ -4573,47 +6273,66 @@ void Actor::PerformAttack(ieDword gameTime)
return;
}
- if (InternalFlags&IF_STOPATTACK) {
+ if (IsDead()) {
// this should be avoided by the AF_ALIVE check by all the calling actions
- printMessage("Actor", "Attack by dead actor!\n", LIGHT_RED);
+ Log(ERROR, "Actor", "Attack by dead actor!");
return;
}
if (!LastTarget) {
- printMessage("Actor", "Attack without valid target ID!\n", LIGHT_RED);
+ Log(ERROR, "Actor", "Attack without valid target ID!");
return;
}
//get target
Actor *target = area->GetActorByGlobalID(LastTarget);
-
- if (target && (target->GetStat(IE_STATE_ID)&(STATE_DEAD|state_invisible))) {
- target = NULL;
- }
-
if (!target) {
- printMessage("Actor", "Attack without valid target!\n", LIGHT_RED);
+ Log(WARNING, "Actor", "Attack without valid target!");
return;
}
- printf("Performattack for %s, target is: %s\n", ShortName, target->ShortName);
+ assert(!(target->IsInvisibleTo((Scriptable *) this) || (target->GetSafeStat(IE_STATE_ID) & STATE_DEAD)));
+ target->AttackedBy(this);
+ ieDword state = GetStat(IE_STATE_ID);
+ if (state&STATE_BERSERK) {
+ BaseStats[IE_CHECKFORBERSERK]=3;
+ }
+
+ print("Performattack for %s, target is: %s", ShortName, target->ShortName);
//which hand is used
//we do apr - attacksleft so we always use the main hand first
- bool leftorright = (bool) ((attacksperround-attackcount)&1);
+ // however, in 3ed, only one attack can be made by the offhand
+ bool leftorright;
+ if (third) {
+ leftorright = false;
+ // make only the last attack with the offhand (iwd2)
+ if (attackcount == 1 && IsDualWielding()) {
+ leftorright = true;
+ }
+ } else {
+ leftorright = (bool) ((attacksperround-attackcount)&1);
+ }
WeaponInfo wi;
ITMExtHeader *header = NULL;
ITMExtHeader *hittingheader = NULL;
int tohit;
- ieDword Flags;
int DamageBonus, CriticalBonus;
int speed, style;
//will return false on any errors (eg, unusable weapon)
- if (!GetCombatDetails(tohit, leftorright, wi, header, hittingheader, Flags, DamageBonus, speed, CriticalBonus, style, target)) {
+ if (!GetCombatDetails(tohit, leftorright, wi, header, hittingheader, DamageBonus, speed, CriticalBonus, style, target)) {
return;
}
+ if (PCStats) {
+ // make a copy of wi.slot, since GetUsedWeapon can modify it
+ int wislot = wi.slot;
+ CREItem *slot = inventory.GetUsedWeapon(leftorright && IsDualWielding(), wislot);
+ //if slot was null, then GetCombatDetails returned false
+ PCStats->RegisterFavourite(slot->ItemResRef, FAV_WEAPON);
+ }
+
//if this is the first call of the round, we need to update next attack
if (nextattack == 0) {
// initiative calculation (lucky 1d6-1 + item speed + speed stat + constant):
@@ -4634,10 +6353,10 @@ void Actor::PerformAttack(ieDword gameTime)
}
}
- // FIXME: use proper weapon range
- if((PersonalDistance(this, target) > wi.range*10) || (GetCurrentArea()!=target->GetCurrentArea() ) ) {
+ unsigned int weaponrange = GetWeaponRange(wi);
+ if ((PersonalDistance(this, target) > weaponrange) || (GetCurrentArea() != target->GetCurrentArea())) {
// this is a temporary double-check, remove when bugfixed
- printMessage("Actor", "Attack action didn't bring us close enough!", LIGHT_RED);
+ Log(ERROR, "Actor", "Attack action didn't bring us close enough!");
return;
}
@@ -4649,27 +6368,50 @@ void Actor::PerformAttack(ieDword gameTime)
nextattack += (core->Time.round_size/attacksperround);
lastattack = gameTime;
+ StringBuffer buffer;
//debug messages
if (leftorright && IsDualWielding()) {
- printMessage("Attack","(Off) ", YELLOW);
+ buffer.append("(Off) ");
} else {
- printMessage("Attack","(Main) ", GREEN);
+ buffer.append("(Main) ");
}
if (attacksperround) {
- printf("Left: %d | ", attackcount);
- printf("Next: %d ", nextattack);
+ buffer.appendFormatted("Left: %d | ", attackcount);
+ buffer.appendFormatted("Next: %d ", nextattack);
+ }
+ if (fxqueue.HasEffectWithParam(fx_puppetmarker_ref, 1) || fxqueue.HasEffectWithParam(fx_puppetmarker_ref, 2)) { // illusions can't hit
+ ResetState();
+ buffer.append("[Missed]");
+ Log(COMBAT, "Attack", buffer);
+ return;
}
- int roll = LuckyRoll(1, ATTACKROLL, 0);
+ // iwd2 rerolls to check for criticals (cf. manual page 45) - the second roll just needs to hit; on miss, it degrades to a normal hit
+ // CriticalBonus is negative, it is added to the minimum roll needed for a critical hit
+ // IE_CRITICALHITBONUS is positive, it is subtracted
+ int roll = LuckyRoll(1, ATTACKROLL, 0, LR_CRITICAL);
+ int criticalroll = roll + (int) GetStat(IE_CRITICALHITBONUS) - CriticalBonus;
+ if (third) {
+ int ThreatRangeMin = wi.critrange;
+ ThreatRangeMin -= ((int) GetStat(IE_CRITICALHITBONUS) - CriticalBonus); // TODO: move to GetCombatDetails
+ criticalroll = LuckyRoll(1, ATTACKROLL, 0, LR_CRITICAL);
+ if (criticalroll < ThreatRangeMin) {
+ // make it an ordinary hit
+ criticalroll = 1;
+ } else {
+ // make sure it will be a critical hit
+ criticalroll = ATTACKROLL;
+ }
+ }
if (roll==1) {
//critical failure
- printBracket("Critical Miss", RED);
- printf("\n");
- displaymsg->DisplayConstantStringName(STR_CRITICAL_MISS, 0xffffff, this);
- DisplayStringCore(this, VB_CRITMISS, DS_CONSOLE|DS_CONST );
- if (Flags&WEAPON_RANGED) {//no need for this with melee weapon!
+ buffer.append("[Critical Miss]");
+ Log(COMBAT, "Attack", buffer);
+ displaymsg->DisplayConstantStringName(STR_CRITICAL_MISS, DMC_WHITE, this);
+ VerbalConstant(VB_CRITMISS, 1);
+ if (wi.wflags&WEAPON_RANGED) {//no need for this with melee weapon!
UseItem(wi.slot, (ieDword)-2, target, UI_MISS);
- } else if (core->HasFeature(GF_BREAKABLE_WEAPONS)) {
+ } else if (core->HasFeature(GF_BREAKABLE_WEAPONS) && InParty) {
//break sword
// a random roll on-hit (perhaps critical failure too)
// in 0,5% (1d20*1d10==1) cases
@@ -4684,71 +6426,141 @@ void Actor::PerformAttack(ieDword gameTime)
//modify defense with damage type
ieDword damagetype = hittingheader->DamageType;
int damage = 0;
- int resisted = 0;
if (hittingheader->DiceThrown<256) {
- damage += LuckyRoll(hittingheader->DiceThrown, hittingheader->DiceSides, 0, LR_CRITICAL);
- damage += DamageBonus;
- printf("| Damage %dd%d%+d = %d ",hittingheader->DiceThrown, hittingheader->DiceSides, DamageBonus, damage);
+ damage += LuckyRoll(hittingheader->DiceThrown, hittingheader->DiceSides, DamageBonus, LR_DAMAGELUCK);
} else {
- printf("| No Damage");
damage = 0;
}
- if (roll >= (ATTACKROLL - (int) GetStat(IE_CRITICALHITBONUS) - CriticalBonus)) {
- //critical success
- printBracket("Critical Hit", GREEN);
- printf("\n");
- displaymsg->DisplayConstantStringName(STR_CRITICAL_HIT, 0xffffff, this);
- DisplayStringCore(this, VB_CRITHIT, DS_CONSOLE|DS_CONST );
- ModifyDamage (target, this, damage, resisted, weapon_damagetype[damagetype], &wi, true);
- UseItem(wi.slot, Flags&WEAPON_RANGED?-2:-1, target, 0, damage);
- ResetState();
-
- return;
- }
-
+ bool critical = criticalroll>=ATTACKROLL;
+ bool success = critical;
- //get target's defense against attack
- int defense = target->GetDefense(damagetype, this);
+ if (!critical) {
+ //get target's defense against attack
+ int defense = target->GetDefense(damagetype, wi.wflags, this);
- bool success;
- if(ReverseToHit) {
- success = roll + defense > tohit;
- } else {
- success = tohit + roll > defense;
+ if(ReverseToHit) {
+ success = roll + defense > tohit;
+ } else {
+ success = tohit + roll > defense;
+ }
+ // autohit immobile enemies (true for atleast stun, sleep, timestop)
+ if (target->Immobile() || (target->GetStat(IE_STATE_ID) & STATE_SLEEP)) {
+ success = true;
+ }
}
if (!success) {
//hit failed
- if (Flags&WEAPON_RANGED) {//Launch the projectile anyway
+ if (wi.wflags&WEAPON_RANGED) {//Launch the projectile anyway
UseItem(wi.slot, (ieDword)-2, target, UI_MISS);
}
ResetState();
- printBracket("Missed", LIGHT_RED);
- printf("\n");
+ buffer.append("[Missed]");
+ Log(COMBAT, "Attack", buffer);
return;
}
- printBracket("Hit", GREEN);
- printf("\n");
- ModifyDamage (target, this, damage, resisted, weapon_damagetype[damagetype], &wi, false);
- UseItem(wi.slot, Flags&WEAPON_RANGED?-2:-1, target, 0, damage);
+
+ ModifyWeaponDamage(wi, target, damage, critical);
+
+ if (critical) {
+ //critical success
+ buffer.append("[Critical Hit]");
+ Log(COMBAT, "Attack", buffer);
+ displaymsg->DisplayConstantStringName(STR_CRITICAL_HIT, DMC_WHITE, this);
+ VerbalConstant(VB_CRITHIT, 1);
+ } else {
+ //normal success
+ buffer.append("[Hit]");
+ Log(COMBAT, "Attack", buffer);
+ }
+ UseItem(wi.slot, wi.wflags&WEAPON_RANGED?-2:-1, target, critical?UI_CRITICAL:0, damage);
ResetState();
}
-static EffectRef fx_stoneskin_ref = { "StoneSkinModifier", -1 };
-static EffectRef fx_stoneskin2_ref = { "StoneSkin2Modifier", -1 };
-static EffectRef fx_mirrorimage_ref = { "MirrorImageModifier", -1 };
-static EffectRef fx_aegis_ref = { "Aegis", -1 };
+// FIXME: figure out and use proper weapon ranges
+// long bows and xbows have a range of 100, shortbows 75, while melee weapons around 0
+// 400 units is about the normal sight range
+int Actor::GetWeaponRange(const WeaponInfo &wi) const
+{
+ if (!wi.range) {
+ // hitting header lookup failed
+ return 0;
+ }
+
+ int rangemultiplier = 10;
+ if (wi.wflags&WEAPON_RANGED) {
+ rangemultiplier = 4; // ranged weapons are almost fine
+ }
+ return rangemultiplier * wi.range;
+}
+
+int Actor::WeaponDamageBonus(const WeaponInfo &wi) const
+{
+ if (wi.wflags&WEAPON_USESTRENGTH) {
+ if (third) {
+ int bonus = GetAbilityBonus(IE_STR);
+ // 150% bonus for twohanders
+ if (wi.itemflags&IE_INV_ITEM_TWOHANDED) bonus+=bonus/2;
+ // only 50% for the offhand
+ if (wi.wflags&WEAPON_LEFTHAND) bonus=bonus/2;
+ return bonus;
+ }
+ return core->GetStrengthBonus(1, GetStat(IE_STR), GetStat(IE_STREXTRA) );
+ }
+
+ return 0;
+}
+
+// filter out any damage reduction that is cancelled by high weapon enchantment
+// damage reduction (the effect and other uses) is implemented as normal resistance for physical damage, just with extra checks
+int Actor::GetDamageReduction(int resist_stat, ieDword weaponEnchantment) const
+{
+ // this is the total, but some of it may have to be discarded
+ int resisted = (signed)GetSafeStat(resist_stat);
+ if (!resisted) {
+ return 0;
+ }
+ int remaining = 0;
+ int total = 0;
+ if (resist_stat == IE_RESISTMISSILE) {
+ remaining = fxqueue.SumDamageReduction(fx_missile_damage_reduction_ref, weaponEnchantment, total);
+ } else {
+ // the usual 3 physical types
+ remaining = fxqueue.SumDamageReduction(fx_damage_reduction_ref, weaponEnchantment, total);
+ }
+
+ if (remaining == -1) {
+ // no relevant effects were found, so the whole resistance value ignores enchantment checks
+ return resisted;
+ }
+ if (remaining == resisted) {
+ Log(COMBAT, "DamageReduction", "Damage resistance (%d) is completely from damage reduction.", resisted);
+ return resisted;
+ }
+ if (remaining == total) {
+ Log(COMBAT, "DamageReduction", "No weapon enchantment breach — full damage reduction and resistance used.");
+ return resisted;
+ } else {
+ Log(COMBAT, "DamageReduction", "Ignoring %d of %d damage reduction due to weapon enchantment breach.", total-remaining, total);
+ return resisted - (total-remaining);
+ }
+}
-void Actor::ModifyDamage(Actor *target, Scriptable *hitter, int &damage, int &resisted, int damagetype, WeaponInfo *wi, bool critical)
+/*Always call this on the suffering actor */
+void Actor::ModifyDamage(Scriptable *hitter, int &damage, int &resisted, int damagetype)
{
+ Actor *attacker = NULL;
+
+ if (hitter && hitter->Type==ST_ACTOR) {
+ attacker = (Actor *) hitter;
+ }
- int mirrorimages = target->Modified[IE_MIRRORIMAGES];
- if (mirrorimages) {
- if (LuckyRoll(1,mirrorimages+1,0) != 1) {
- target->fxqueue.DecreaseParam1OfEffect(fx_mirrorimage_ref, 1);
- target->Modified[IE_MIRRORIMAGES]--;
+ //guardian mantle for PST
+ if (attacker && (Modified[IE_IMMUNITY]&IMM_GUARDIAN) ) {
+ //if the hitter doesn't make the spell save, the mantle works and the damage is 0
+ if (!attacker->GetSavingThrow(0,-4) ) {
damage = 0;
return;
}
@@ -4757,122 +6569,147 @@ void Actor::ModifyDamage(Actor *target, Scriptable *hitter, int &damage, int &re
// only check stone skins if damage type is physical or magical
// DAMAGE_CRUSHING is 0, so we can't AND with it to check for its presence
if (!(damagetype & ~(DAMAGE_PIERCING|DAMAGE_SLASHING|DAMAGE_MISSILE|DAMAGE_MAGIC))) {
- int stoneskins = target->Modified[IE_STONESKINS];
+ int stoneskins = Modified[IE_STONESKINS];
if (stoneskins) {
- target->fxqueue.DecreaseParam1OfEffect(fx_stoneskin_ref, 1);
- target->fxqueue.DecreaseParam1OfEffect(fx_aegis_ref, 1);
- target->Modified[IE_STONESKINS]--;
+ //pst style damage soaking from cloak of warding
+ damage = fxqueue.DecreaseParam3OfEffect(fx_cloak_ref, damage, 0);
+ if (!damage) {
+ return;
+ }
+
+ fxqueue.DecreaseParam1OfEffect(fx_stoneskin_ref, 1);
+ fxqueue.DecreaseParam1OfEffect(fx_aegis_ref, 1);
+
+ Modified[IE_STONESKINS]--;
damage = 0;
return;
}
- stoneskins = target->Modified[IE_STONESKINSGOLEM];
+ stoneskins = GetSafeStat(IE_STONESKINSGOLEM);
if (stoneskins) {
- target->fxqueue.DecreaseParam1OfEffect(fx_stoneskin2_ref, 1);
- target->Modified[IE_STONESKINSGOLEM]--;
+ fxqueue.DecreaseParam1OfEffect(fx_stoneskin2_ref, 1);
+ Modified[IE_STONESKINSGOLEM]--;
damage = 0;
return;
}
}
- if (wi) {
- if (BaseStats[IE_BACKSTABDAMAGEMULTIPLIER] > 1) {
- if (Modified[IE_STATE_ID] & state_invisible || Modified[IE_ALWAYSBACKSTAB]) {
- if ( !(core->HasFeature(GF_PROPER_BACKSTAB) && !IsBehind(target)) ) {
- if (target->Modified[IE_DISABLEBACKSTAB]) {
- // The backstab seems to have failed
- displaymsg->DisplayConstantString (STR_BACKSTAB_FAIL, 0xffffff);
- } else {
- if (wi->backstabbing) {
- damage *= Modified[IE_BACKSTABDAMAGEMULTIPLIER];
- // display a simple message instead of hardcoding multiplier names
- displaymsg->DisplayConstantStringValue (STR_BACKSTAB, 0xffffff, Modified[IE_BACKSTABDAMAGEMULTIPLIER]);
- } else {
- // weapon is unsuitable for backstab
- displaymsg->DisplayConstantString (STR_BACKSTAB_BAD, 0xffffff);
- }
- }
- }
- }
- }
-
- // add strength bonus; backstab does not affect it
- // TODO: should actually check WEAPON_USESTRENGTH, since a sling in bg2 has it
- if (GetAttackStyle() != WEAPON_RANGED) {
- if (core->HasFeature(GF_3ED_RULES) && wi->itemflags&IE_INV_ITEM_TWOHANDED) {
- // 150% bonus for twohandlers
- damage += 150 * core->GetStrengthBonus(1, GetStat(IE_STR), GetStat(IE_STREXTRA)) / 100;
- } else {
- damage += core->GetStrengthBonus(1, GetStat(IE_STR), GetStat(IE_STREXTRA) );
- }
- }
- }
-
- if (wi && target->fxqueue.WeaponImmunity(wi->enchantment, wi->itemflags)) {
- damage = 0;
- resisted = DR_IMMUNE; // mark immunity for GetCombatDetails
- } else {
+ if (damage>0) {
// check damage type immunity / resistance / susceptibility
std::multimap<ieDword, DamageInfoStruct>::iterator it;
it = core->DamageInfoMap.find(damagetype);
if (it == core->DamageInfoMap.end()) {
- printf("Unhandled damagetype:%d\n", damagetype);
- } else if (it->second.resist_stat == 0) {
- // damage type without a resistance stat
- } else {
- damage += (signed)target->GetStat(IE_DAMAGEBONUS);
- resisted = (int) (damage * (signed)target->GetSafeStat(it->second.resist_stat)/100.0);
+ Log(ERROR, "ModifyDamage", "Unhandled damagetype:%d", damagetype);
+ } else if (it->second.resist_stat) {
// check for bonuses for specific damage types
- if (core->HasFeature(GF_SPECIFIC_DMG_BONUS) && hitter && hitter->Type == ST_ACTOR) {
- int bonus = ((Actor *)hitter)->fxqueue.SpecificDamageBonus(it->second.iwd_mod_type);
+ if (core->HasFeature(GF_SPECIFIC_DMG_BONUS) && attacker) {
+ int bonus = attacker->fxqueue.BonusForParam2(fx_damage_bonus_modifier_ref, it->second.iwd_mod_type);
if (bonus) {
resisted -= int (damage * bonus / 100.0);
- printf("Bonus damage of %d (%+d%%), neto: %d\n", int (damage * bonus / 100.0), bonus, -resisted);
+ Log(COMBAT, "ModifyDamage", "Bonus damage of %d(%+d%%), neto: %d", int(damage * bonus / 100.0), bonus, -resisted);
+ }
+ }
+ // damage type with a resistance stat
+ if (third) {
+ // flat resistance, eg. 10/- or eg. 5/+2 for physical types
+ // for actors we need special care for damage reduction - traps (...) don't have enchanted weapons
+ if (attacker && it->second.reduction) {
+ WeaponInfo wi;
+ attacker->GetWeapon(wi, 0); // FIXME: use a cheaper way to share the weaponEnchantment + this might have been the left hand
+ ieDword weaponEnchantment = wi.enchantment;
+ // disregard other resistance boni when checking whether to skip reduction
+ resisted = GetDamageReduction(it->second.resist_stat, weaponEnchantment);
+ } else {
+ resisted = (signed)GetSafeStat(it->second.resist_stat);
+ }
+ damage -= resisted;
+ } else {
+ int resistance = (signed)GetSafeStat(it->second.resist_stat);
+ // avoid buggy data
+ if (abs(resistance) > maximum_values[it->second.resist_stat]) {
+ resistance = 0;
+ Log(DEBUG, "ModifyDamage", "Ignoring bad damage resistance value (%d).", resistance);
+ }
+ resisted = (int) (damage * resistance/100.0);
+ damage -= resisted;
+ }
+ Log(COMBAT, "ModifyDamage", "Resisted %d of %d at %d%% resistance to %d", resisted, damage+resisted, GetSafeStat(it->second.resist_stat), damagetype);
+ // PST and BG1 may actually heal on negative damage
+ if (!core->HasFeature(GF_HEAL_ON_100PLUS)) {
+ if (damage <= 0) {
+ resisted = DR_IMMUNE;
+ damage = 0;
}
}
- damage -= resisted;
- printf("Resisted %d of %d at %d%% resistance to %d\n", resisted, damage+resisted, target->GetSafeStat(it->second.resist_stat), damagetype);
- if (damage <= 0) resisted = DR_IMMUNE;
}
}
- //check casting failure
- if (damage<0) damage = 0;
- if (!damage) {
- DisplayStringCore(this, VB_TIMMUNE, DS_CONSOLE|DS_CONST );
- return;
- }
-
- //critical protection a la PST
- if (pstflags && (Modified[IE_STATE_ID] & (ieDword) STATE_CRIT_PROT )) {
- critical = 0;
- }
-
- if (critical) {
- if (target->inventory.ProvidesCriticalAversion()) {
- //critical hit is averted by helmet
- displaymsg->DisplayConstantStringName(STR_NO_CRITICAL, 0xffffff, target);
- } else {
- //a critical surely raises the morale?
- //only if it is successful
- NewBase(IE_MORALE, 1, MOD_ADDITIVE);
- damage <<=1; //critical damage is always double?
- core->timer->SetScreenShake(16,16,8);
+ if (damage<=0) {
+ if (attacker && attacker->InParty) {
+ DisplayStringOrVerbalConstant(STR_WEAPONINEFFECTIVE, VB_TIMMUNE, 1);
+ core->Autopause(AP_UNUSABLE, this);
}
}
- return;
}
void Actor::UpdateActorState(ieDword gameTime) {
+ char Tmp[40];
+
if (modalTime==gameTime) {
return;
}
- //IWD2 has no autodetect, you actually should 'search'
- if (InParty && core->HasFeature(GF_AUTOSEARCH_HIDDEN) ) {
+ int roundFraction = (gameTime-roundTime) % core->Time.round_size;
+
+ //actually, iwd2 has autosearch, also, this is useful for dayblindness
+ //apply the modal effect about every second (pst and iwds have round sizes that are not multiples of 15)
+ // FIXME: split dayblindness out of detect.spl and only run that each tick + simplify this check
+ if (InParty && core->HasFeature(GF_AUTOSEARCH_HIDDEN) && (third || ((roundFraction%AI_UPDATE_TIME) == 0))) {
core->ApplySpell("detect", this, this, 0);
}
+ ieDword state = Modified[IE_STATE_ID];
+
+ // each round also re-confuse the actor
+ if (!roundFraction) {
+ if (BaseStats[IE_CHECKFORBERSERK]) {
+ BaseStats[IE_CHECKFORBERSERK]--;
+ }
+ if ((state&STATE_CONFUSED)) {
+
+ int tmp = core->Roll(1,3,0);
+ switch(tmp) {
+ case 2:
+ strlcpy(Tmp, "RandomWalk()", sizeof(Tmp));
+ break;
+ case 1:
+ strlcpy(Tmp, "Attack([0])", sizeof(Tmp));
+ break;
+ default:
+ strlcpy(Tmp, "NoAction()", sizeof(Tmp));
+ break;
+ }
+ Action *action = GenerateAction( Tmp );
+ if (action) {
+ ReleaseCurrentAction();
+ AddActionInFront(action);
+ print("Confusion: added %s", Tmp);
+ }
+ return;
+ }
+
+ if (Modified[IE_CHECKFORBERSERK] && !LastTarget && SeeAnyOne(false, false) ) {
+ strlcpy(Tmp, "Berserk()", sizeof(Tmp));
+ Action *action = GenerateAction( Tmp );
+ if (action) {
+ ReleaseCurrentAction();
+ AddActionInFront(action);
+ print("Berserk: added %s", Tmp);
+ }
+ return;
+ }
+ }
+
// this is a HACK, fuzzie can't work out where else to do this for now
// but we shouldn't be resetting rounds/attacks just because the actor
// wandered away, the action code should probably be responsible somehow
@@ -4882,11 +6719,9 @@ void Actor::UpdateActorState(ieDword gameTime) {
if (!target || target->GetStat(IE_STATE_ID)&STATE_DEAD) {
StopAttack();
} else {
- printMessage("Attack","(Leaving attack)", GREEN);
- core->GetGame()->OutAttack(GetGlobalID());
+ Log(COMBAT, "Attack", "(Leaving attack)");
}
- roundTime = 0;
lastattack = 0;
}
@@ -4895,10 +6730,7 @@ void Actor::UpdateActorState(ieDword gameTime) {
}
//apply the modal effect on the beginning of each round
- if ((((gameTime-roundTime)%core->Time.round_size)==0)) {
- //we can set this to 0
- modalTime = gameTime;
-
+ if (roundFraction == 0) {
// handle lingering modal spells like bardsong in iwd2
if (modalSpellLingering && LingeringModalSpell[0]) {
modalSpellLingering--;
@@ -4912,8 +6744,17 @@ void Actor::UpdateActorState(ieDword gameTime) {
return;
}
+ // some states and timestop disable modal actions
+ // interestingly the original doesn't include STATE_DISABLED, STATE_FROZEN/STATE_PETRIFIED
+ if (Immobile() || (state & (STATE_CONFUSED | STATE_DEAD | STATE_HELPLESS | STATE_PANIC | STATE_BERSERK | STATE_SLEEP))) {
+ return;
+ }
+
+ //we can set this to 0
+ modalTime = gameTime;
+
if (!ModalSpell[0]) {
- printMessage("Actor","Modal Spell Effect was not set!\n", YELLOW);
+ Log(WARNING, "Actor", "Modal Spell Effect was not set!");
ModalSpell[0]='*';
} else if(ModalSpell[0]!='*') {
if (ModalSpellSkillCheck()) {
@@ -4923,16 +6764,18 @@ void Actor::UpdateActorState(ieDword gameTime) {
core->ApplySpell(ModalSpell, this, this, 0);
}
if (InParty) {
- displaymsg->DisplayStringName(core->ModalStates[ModalState].entering_str, 0xffffff, this, IE_STR_SOUND|IE_STR_SPEECH);
+ displaymsg->DisplayStringName(core->ModalStates[ModalState].entering_str, DMC_WHITE, this, IE_STR_SOUND|IE_STR_SPEECH);
}
} else {
if (InParty) {
- displaymsg->DisplayStringName(core->ModalStates[ModalState].failed_str, 0xffffff, this, IE_STR_SOUND|IE_STR_SPEECH);
+ displaymsg->DisplayStringName(core->ModalStates[ModalState].failed_str, DMC_WHITE, this, IE_STR_SOUND|IE_STR_SPEECH);
}
ModalState = MS_NONE;
- // TODO: wait for a round until allowing new states?
}
}
+
+ // shut everyone up, so they don't whine if the actor is on a long hiding-in-shadows recon mission
+ core->GetGame()->ResetPartyCommentTimes();
}
}
@@ -4951,6 +6794,12 @@ void Actor::SetColor( ieDword idx, ieDword grd)
if (index>6) {
return;
}
+
+ //Don't modify the modified stats if the colors were locked (for this ai cycle)
+ if (anims && anims->lockPalette) {
+ return;
+ }
+
if (shift == 15) {
// put gradient in all four bytes of value
value = gradient;
@@ -4997,8 +6846,8 @@ void Actor::SetColorMod( ieDword location, RGBModifier::Type type, int speed,
}
//00xx0yyy-->000xxyyy
if (location&0xffffffc8) return; //invalid location
- if (phase && ca->ColorMods[location].locked) return;
location = (location &7) | ((location>>1)&0x18);
+ if (phase && ca->ColorMods[location].locked) return;
ca->ColorMods[location].type = type;
ca->ColorMods[location].speed = speed;
ca->ColorMods[location].rgb.r = r;
@@ -5020,21 +6869,26 @@ void Actor::SetLeader(Actor *actor, int xoffset, int yoffset)
FollowOffset.y = yoffset;
}
-//if days == 0, it means full healing
-void Actor::Heal(int days)
+//if hp <= 0, it means full healing
+void Actor::Heal(int hp)
{
- if (days) {
- SetBase(IE_HITPOINTS, BaseStats[IE_HITPOINTS]+days*2);
+ if (hp > 0) {
+ SetBase(IE_HITPOINTS, BaseStats[IE_HITPOINTS] + hp);
} else {
SetBase(IE_HITPOINTS, Modified[IE_MAXHITPOINTS]);
}
}
-void Actor::AddExperience(int exp)
+void Actor::AddExperience(int exp, int combat)
{
if (core->HasFeature(GF_WISDOM_BONUS)) {
exp = (exp * (100 + core->GetWisdomBonus(0, Modified[IE_WIS]))) / 100;
}
+ int adjustmentPercent = dmgadjustments[GameDifficulty];
+ // the "Suppress Extra Difficulty Damage" also switches off the XP bonus
+ if (combat && (!NoExtraDifficultyDmg || adjustmentPercent < 0)) {
+ exp += exp * adjustmentPercent/100;
+ }
SetBase(IE_XP,BaseStats[IE_XP]+exp);
}
@@ -5051,7 +6905,7 @@ int Actor::CalculateExperience(int type, int level)
return xpbonus[type*xpbonuslevels+l];
}
-bool Actor::Schedule(ieDword gametime, bool checkhide)
+bool Actor::Schedule(ieDword gametime, bool checkhide) const
{
if (checkhide) {
if (!(InternalFlags&IF_VISIBLE) ) {
@@ -5101,6 +6955,7 @@ void Actor::WalkTo(const Point &Des, ieDword flags, int MinDistance)
return;
}
SetRunFlags(flags);
+ ResetCommentTime();
// is this true???
if (Des.x==-2 && Des.y==-2) {
Point p((ieWord) Modified[IE_SAVEDXPOS], (ieWord) Modified[IE_SAVEDYPOS] );
@@ -5110,6 +6965,12 @@ void Actor::WalkTo(const Point &Des, ieDword flags, int MinDistance)
}
}
+int Actor::WantDither() const
+{
+ if (always_dither) return 2;
+ return Selectable::WantDither();
+}
+
//there is a similar function in Map for stationary vvcs
void Actor::DrawVideocells(const Region &screen, vvcVector &vvcCells, const Color &tint)
{
@@ -5117,18 +6978,17 @@ void Actor::DrawVideocells(const Region &screen, vvcVector &vvcCells, const Colo
for (unsigned int i = 0; i < vvcCells.size(); i++) {
ScriptedAnimation* vvc = vvcCells[i];
-/* we don't allow holes anymore
- if (!vvc)
- continue;
-*/
// actually this is better be drawn by the vvc
- bool endReached = vvc->Draw(screen, Pos, tint, area, WantDither(), GetOrientation());
+ bool endReached = vvc->Draw(screen, Pos, tint, area, WantDither(), GetOrientation(), BBox.h);
if (endReached) {
delete vvc;
vvcCells.erase(vvcCells.begin()+i);
continue;
}
+ if (!vvc->active) {
+ vvc->SetPhase(P_RELEASE);
+ }
}
}
@@ -5140,6 +7000,13 @@ void Actor::DrawActorSprite(const Region &screen, int cx, int cy, const Region&
int PartCount = ca->GetTotalPartCount();
Video* video = core->GetVideoDriver();
Region vp = video->GetViewport();
+ unsigned int flags = TranslucentShadows ? BLIT_TRANSSHADOW : 0;
+ if (!ca->lockPalette) flags |= BLIT_TINTED;
+ Game* game = core->GetGame();
+ // when time stops, almost everything turns dull grey, the caster and immune actors being the most notable exceptions
+ if (game->TimeStoppedFor(this)) {
+ flags |= BLIT_GREY;
+ }
// display current frames in the right order
const int* zOrder = ca->GetZOrder(Face);
@@ -5162,10 +7029,6 @@ void Actor::DrawActorSprite(const Region &screen, int cx, int cy, const Region&
}
assert(newsc->Covers(cx, cy, nextFrame->XPos, nextFrame->YPos, nextFrame->Width, nextFrame->Height));
- unsigned int flags = TranslucentShadows ? BLIT_TRANSSHADOW : 0;
-
- if (!ca->lockPalette) flags|=BLIT_TINTED;
-
video->BlitGameSprite( nextFrame, cx + screen.x, cy + screen.y,
flags, tint, newsc, ca->GetPartPalette(partnum), &screen);
}
@@ -5184,7 +7047,7 @@ bool Actor::ShouldHibernate() {
return false;
if (LastTarget) //currently attacking someone
return false;
- if (!lastRunTime) // haven't had a chance to run a script
+ if (InternalFlags&IF_JUSTDIED) // didn't have a chance to run a script
return false;
if (CurrentAction)
return false;
@@ -5206,7 +7069,7 @@ void Actor::UpdateAnimations()
//make actor unselectable and unselected when it is not moving
//dead, petrified, frozen, paralysed or unavailable to player
- if (Immobile() || !ShouldDrawCircle()) {
+ if (!ValidTarget(GA_SELECT|GA_NO_ENEMY|GA_NO_NEUTRAL)) {
core->GetGame()->SelectActor(this, false, SELECT_NORMAL);
}
@@ -5254,10 +7117,11 @@ void Actor::UpdateAnimations()
anims[0]->SetPos(0);
}
} else {
+ //check if walk sounds need to be played
//dialog, pause game
if (!(core->GetGameControl()->GetDialogueFlags()&(DF_IN_DIALOG|DF_FREEZE_SCRIPTS) ) ) {
- //stance
- if (GetStance() == IE_ANI_WALK) {
+ //footsteps option set, stance
+ if (footsteps && (GetStance() == IE_ANI_WALK)) {
//frame reached 0
if (!anims[0]->GetCurrentFrame()) {
PlayWalkSound();
@@ -5267,7 +7131,12 @@ void Actor::UpdateAnimations()
}
}
-bool Actor::ShouldDrawCircle()
+bool Actor::IsDead() const
+{
+ return InternalFlags & IF_STOPATTACK;
+}
+
+bool Actor::ShouldDrawCircle() const
{
if (Modified[IE_NOCIRCLE]) {
return false;
@@ -5279,7 +7148,7 @@ bool Actor::ShouldDrawCircle()
int State = Modified[IE_STATE_ID];
- if (State&STATE_DEAD || InternalFlags&IF_JUSTDIED) {
+ if ((State&STATE_DEAD) || (InternalFlags&IF_REALLYDIED)) {
return false;
}
@@ -5293,9 +7162,17 @@ bool Actor::ShouldDrawCircle()
return true;
}
+bool Actor::HasBodyHeat() const
+{
+ if (Modified[IE_STATE_ID]&(STATE_DEAD|STATE_FROZEN|STATE_PETRIFIED) ) return false;
+ if (GetAnims()->GetFlags()&AV_NO_BODY_HEAT) return false;
+ return true;
+}
+
void Actor::Draw(const Region &screen)
{
Map* area = GetCurrentArea();
+ if (!area) return;
int cx = Pos.x;
int cy = Pos.y;
@@ -5384,15 +7261,15 @@ void Actor::Draw(const Region &screen)
if (gc->dialoghandler->targetID == GetGlobalID() && (gc->GetDialogueFlags()&DF_IN_DIALOG)) {
drawcircle = true;
}
- bool drawtarget = drawcircle;
+ bool drawtarget = false;
// we always show circle/target on pause
if (drawcircle && !(gc->GetDialogueFlags() & DF_FREEZE_SCRIPTS)) {
// check marker feedback level
ieDword markerfeedback = 4;
core->GetDictionary()->Lookup("GUI Feedback Level", markerfeedback);
if (Over) {
- // picked creature
- drawcircle = markerfeedback >= 1;
+ // picked creature, should always be true
+ drawcircle = true;
} else if (Selected) {
// selected creature
drawcircle = markerfeedback >= 2;
@@ -5401,18 +7278,18 @@ void Actor::Draw(const Region &screen)
drawcircle = markerfeedback >= 3;
} else if (Modified[IE_EA] >= EA_EVILCUTOFF) {
// hostile
- drawcircle = markerfeedback >= 5;
+ drawcircle = markerfeedback >= 4;
} else {
// all
- drawcircle = markerfeedback >= 6;
+ drawcircle = markerfeedback >= 5;
}
- drawtarget = Selected && markerfeedback >= 4;
}
if (drawcircle) {
DrawCircle(vp);
+ drawtarget = ((Selected || Over) && !(InternalFlags&IF_NORETICLE) && Modified[IE_EA] <= EA_CONTROLLABLE && GetPathLength());
}
if (drawtarget) {
- DrawTargetPoint(vp);
+ gc->DrawTargetReticle(Destination, (size - 1) * 4, true, Over, Selected); //we could set this to !paused if we wanted to only animate when not paused
}
unsigned char StanceID = GetStance();
@@ -5528,7 +7405,7 @@ void Actor::Draw(const Region &screen)
}
//infravision tint
- if (!(State&(STATE_DEAD|STATE_FROZEN|STATE_PETRIFIED) ) &&
+ if ( HasBodyHeat() &&
(area->GetLightLevel(Pos)<128) &&
core->GetGame()->PartyHasInfravision()) {
tint.r=255;
@@ -5586,6 +7463,14 @@ void Actor::Draw(const Region &screen)
//draw videocells over the actor
DrawVideocells(screen, vvcOverlays, tint);
+
+ // display pc hitpoints if requested
+ // limit the invocation count to save resources (the text is drawn repeatedly anyway)
+ ieDword tmp = 0;
+ core->GetDictionary()->Lookup("HP Over Head", tmp);
+ if (tmp && Persistent() && (core->GetGame()->GameTime % (core->Time.round_size/2) == 0)) { // smaller delta to skip fading
+ DisplayHeadHPRatio();
+ }
}
/* Handling automatic stance changes */
@@ -5640,22 +7525,24 @@ void Actor::GetSoundFrom2DA(ieResRef Sound, unsigned int index) const
index = 10;
break;
//TODO: one day we should implement verbal constant groups
+ case VB_DIALOG:
case VB_SELECT:
case VB_SELECT+1:
case VB_SELECT+2:
index = 36;
break;
default:
- printMessage("Actor","TODO:", YELLOW);
- printf("Cannot determine 2DA rowcount for index: %d\n", index);
+ Log(WARNING, "Actor", "TODO:Cannot determine 2DA rowcount for index: %d", index);
return;
}
- printMessage("Actor"," ", WHITE);
- printf("Getting sound 2da %.8s entry: %s\n", anims->ResRef, tab->GetRowName(index) );
+ Log(MESSAGE, "Actor", "Getting sound 2da %.8s entry: %s",
+ anims->ResRef, tab->GetRowName(index) );
int col = core->Roll(1,tab->GetColumnCount(index),-1);
strnlwrcpy(Sound, tab->QueryField (index, col), 8);
}
+//Get the monster sound from a global .ini file.
+//It is ResData.ini in PST and Sounds.ini in IWD/HoW
void Actor::GetSoundFromINI(ieResRef Sound, unsigned int index) const
{
const char *resource = "";
@@ -5668,15 +7555,19 @@ void Actor::GetSoundFromINI(ieResRef Sound, unsigned int index) const
switch(index) {
case VB_ATTACK:
- resource = core->GetResDataINI()->GetKeyAsString(section, "at1sound","");
+ resource = core->GetResDataINI()->GetKeyAsString(section, IWDSound?"att1":"at1sound","");
break;
case VB_DAMAGE:
- resource = core->GetResDataINI()->GetKeyAsString(section, "hitsound","");
+ resource = core->GetResDataINI()->GetKeyAsString(section, IWDSound?"damage":"hitsound","");
break;
case VB_DIE:
- resource = core->GetResDataINI()->GetKeyAsString(section, "dfbsound","");
+ resource = core->GetResDataINI()->GetKeyAsString(section, IWDSound?"death":"dfbsound","");
break;
case VB_SELECT:
+ //this isn't in PST, apparently
+ if (IWDSound) {
+ resource = core->GetResDataINI()->GetKeyAsString(section, "selected","");
+ }
break;
}
int count = CountElements(resource,',');
@@ -5686,7 +7577,7 @@ void Actor::GetSoundFromINI(ieResRef Sound, unsigned int index) const
while(*resource && *resource!=',') resource++;
if (*resource==',') resource++;
}
- strncpy(Sound, resource, 8);
+ CopyResRef(Sound, resource);
for(count=0;count<8 && Sound[count]!=',';count++) {};
Sound[count]=0;
}
@@ -5700,7 +7591,7 @@ void Actor::ResolveStringConstant(ieResRef Sound, unsigned int index) const
return;
}
//icewind style
- snprintf(Sound, sizeof(ieResRef), "%s%02d", PCStats->SoundSet, index);
+ snprintf(Sound, sizeof(ieResRef), "%s%02d", PCStats->SoundSet, VCMap[index]);
return;
}
@@ -5721,8 +7612,20 @@ void Actor::SetActionButtonRow(ActionButtonRow &ar)
{
for(int i=0;i<GUIBT_COUNT;i++) {
ieByte tmp = ar[i];
- if (QslotTranslation) {
- tmp=gemrb2iwd[tmp];
+ if (QslotTranslation && i>2) {
+ if (tmp>ACT_IWDQSONG) {//quick songs
+ tmp = 110+tmp%10;
+ } else if (tmp>ACT_IWDQSPEC) {//quick abilities
+ tmp = 90+tmp%10;
+ } else if (tmp>ACT_IWDQITEM) {//quick items
+ tmp = 80+tmp%10;
+ } else if (tmp>ACT_IWDQSPELL) {//quick spells
+ tmp = 70+tmp%10;
+ } else if (tmp>ACT_BARD) {//spellbooks
+ tmp = 50+tmp%10;
+ } else {
+ tmp=gemrb2iwd[tmp];
+ }
}
PCStats->QSlots[i]=tmp;
}
@@ -5735,20 +7638,31 @@ void Actor::GetActionButtonRow(ActionButtonRow &ar)
CreateStats();
InitButtons(GetStat(IE_CLASS), false);
for(int i=0;i<GUIBT_COUNT;i++) {
- ieByte tmp=PCStats->QSlots[i];
- if (QslotTranslation) {
- if (tmp>=90) { //quick weapons
- tmp=16+tmp%10;
- } else if (tmp>=80) { //quick items
- tmp=9+tmp%10;
- } else if (tmp>=70) { //quick spells
- tmp=3+tmp%10;
- } else {
- tmp=iwd2gemrb[tmp];
- }
+ ar[i] = IWD2GemrbQslot(i);
+ }
+}
+
+int Actor::IWD2GemrbQslot (int slotindex)
+{
+ ieByte tmp = PCStats->QSlots[slotindex];
+ //the first three buttons are hardcoded in gemrb
+ //don't mess with them
+ if (QslotTranslation && slotindex>2) {
+ if (tmp>=110) { //quick songs
+ tmp = ACT_IWDQSONG + tmp%10;
+ } else if (tmp>=90) { //quick abilities
+ tmp = ACT_IWDQSPEC + tmp%10;
+ } else if (tmp>=80) { //quick items
+ tmp = ACT_IWDQITEM + tmp%10;
+ } else if (tmp>=70) { //quick spells
+ tmp = ACT_IWDQSPELL + tmp%10;
+ } else if (tmp>=50) { //spellbooks
+ tmp = ACT_BARD + tmp%10;
+ } else {
+ tmp = iwd2gemrb[tmp];
}
- ar[i]=tmp;
}
+ return tmp;
}
void Actor::SetPortrait(const char* ResRef, int Which)
@@ -5763,12 +7677,10 @@ void Actor::SetPortrait(const char* ResRef, int Which)
}
if(Which!=1) {
- memset( SmallPortrait, 0, 8 );
- strncpy( SmallPortrait, ResRef, 8 );
+ CopyResRef( SmallPortrait, ResRef );
}
if(Which!=2) {
- memset( LargePortrait, 0, 8 );
- strncpy( LargePortrait, ResRef, 8 );
+ CopyResRef( LargePortrait, ResRef );
}
if(!Which) {
for (i = 0; i < 8 && ResRef[i]; i++) {};
@@ -5787,9 +7699,13 @@ void Actor::SetSoundFolder(const char *soundset)
char filepath[_MAX_PATH];
strnlwrcpy(PCStats->SoundFolder, soundset, 32);
- PathJoin(filepath,core->GamePath,"sounds",PCStats->SoundFolder,0);
+ PathJoin(filepath, core->GamePath, "sounds", PCStats->SoundFolder, NULL);
char file[_MAX_PATH];
- if (FileGlob(file, filepath, "?????01")) {
+
+ //TODO: this could be simpler with *
+ if (FileGlob(file, filepath, "??????01")) {
+ file[6] = '\0';
+ } else if (FileGlob(file, filepath, "?????01")) {
file[5] = '\0';
} else if (FileGlob(file, filepath, "????01")) {
file[4] = '\0';
@@ -5822,11 +7738,8 @@ bool Actor::HasVVCCell(const ieResRef resource) const
return GetVVCCell(resource) != NULL;
}
-ScriptedAnimation *Actor::GetVVCCell(const ieResRef resource) const
+ScriptedAnimation *Actor::GetVVCCell(const vvcVector *vvcCells, const ieResRef resource) const
{
- int j = true;
- const vvcVector *vvcCells=&vvcShields;
-retry:
size_t i=vvcCells->size();
while (i--) {
ScriptedAnimation *vvc = (*vvcCells)[i];
@@ -5837,11 +7750,16 @@ retry:
return vvc;
}
}
- vvcCells=&vvcOverlays;
- if (j) { j = false; goto retry; }
return NULL;
}
+ScriptedAnimation *Actor::GetVVCCell(const ieResRef resource) const
+{
+ ScriptedAnimation *vvc = GetVVCCell(&vvcShields, resource);
+ if (vvc) return vvc;
+ return GetVVCCell(&vvcOverlays, resource);
+}
+
void Actor::RemoveVVCell(const ieResRef resource, bool graceful)
{
bool j = true;
@@ -5941,33 +7859,35 @@ int Actor::RestoreSpellLevel(ieDword maxlevel, ieDword type)
}
return 0;
}
-
//replenishes spells, cures fatigue
void Actor::Rest(int hours)
{
- if (hours) {
+ if (hours < 8) {
+ // partial (interrupted) rest does not affect fatigue
//do remove effects
int remaining = hours*10;
- //removes hours*10 fatigue points
- NewStat (IE_FATIGUE, -remaining, MOD_ADDITIVE);
NewStat (IE_INTOXICATION, -remaining, MOD_ADDITIVE);
//restore hours*10 spell levels
//rememorization starts with the lower spell levels?
inventory.ChargeAllItems (remaining);
- for (int level = 1; level<16; level++) {
- if (level<remaining) {
- break;
- }
- while (remaining>0) {
- remaining -= RestoreSpellLevel(level,0);
+ int level = 1;
+ int memorizedSpell = 0;
+ while (remaining > 0 && level < 16)
+ {
+ memorizedSpell = RestoreSpellLevel(level, -1);
+ remaining -= memorizedSpell;
+ if (memorizedSpell == 0)
+ {
+ level += 1;
}
}
} else {
- SetBase (IE_FATIGUE, 0);
+ TicksLastRested = core->GetGame()->GameTime;
SetBase (IE_INTOXICATION, 0);
inventory.ChargeAllItems (0);
spellbook.ChargeAllSpells ();
}
+ ResetCommentTime();
}
//returns the actual slot from the quickslot
@@ -6004,7 +7924,11 @@ int Actor::SetEquippedQuickSlot(int slot, int header)
break;
}
}
+ //if it is the fist slot and not currently used, then set it up
if (i==MAX_QUICKWEAPONSLOT) {
+ Equipped = IW_NO_EQUIPPED;
+ EquippedHeader = 0;
+ inventory.SetEquippedSlot(Equipped, EquippedHeader);
return 0;
}
}
@@ -6016,7 +7940,7 @@ int Actor::SetEquippedQuickSlot(int slot, int header)
else {
PCStats->QuickWeaponHeaders[slot]=header;
}
- slot = PCStats->QuickWeaponSlots[slot]-inventory.GetWeaponSlot();
+ slot = inventory.GetWeaponQuickSlot(PCStats->QuickWeaponSlots[slot]);
Equipped = (ieWordSigned) slot;
EquippedHeader = (ieWord) header;
if (inventory.SetEquippedSlot(slot, header)) {
@@ -6033,12 +7957,19 @@ bool Actor::UseItemPoint(ieDword slot, ieDword header, const Point &target, ieDw
CREItem *item = inventory.GetSlotItem(slot);
if (!item)
return false;
+ // HACK: disable use when stunned (remove if stunned/petrified/etc actors stop running scripts)
+ if (Immobile()) {
+ return false;
+ }
ieResRef tmpresref;
strnuprcpy(tmpresref, item->ItemResRef, sizeof(ieResRef)-1);
- Item *itm = gamedata->GetItem(tmpresref);
- if (!itm) return false; //quick item slot contains invalid item resref
+ Item *itm = gamedata->GetItem(tmpresref, true);
+ if (!itm) {
+ Log(WARNING, "Actor", "Invalid quick slot item: %s!", tmpresref);
+ return false; //quick item slot contains invalid item resref
+ }
//item is depleted for today
if(itm->UseCharge(item->Usages, header, false)==CHG_DAY) {
return false;
@@ -6047,6 +7978,7 @@ bool Actor::UseItemPoint(ieDword slot, ieDword header, const Point &target, ieDw
Projectile *pro = itm->GetProjectile(this, header, target, slot, flags&UI_MISS);
ChargeItem(slot, header, item, itm, flags&UI_SILENT);
gamedata->FreeItem(itm,tmpresref, false);
+ ResetCommentTime();
if (pro) {
pro->SetCaster(GetGlobalID(), ITEM_CASTERLEVEL);
GetCurrentArea()->AddProjectile(pro, Pos, target);
@@ -6055,15 +7987,100 @@ bool Actor::UseItemPoint(ieDword slot, ieDword header, const Point &target, ieDw
return false;
}
-static EffectRef fx_damage_ref = { "Damage", -1 };
-static EffectRef fx_melee_ref = { "SetMeleeEffect", -1 };
-static EffectRef fx_ranged_ref = { "SetRangedEffect", -1 };
+void Actor::ModifyWeaponDamage(WeaponInfo &wi, Actor *target, int &damage, bool &critical)
+{
+ //Calculate weapon based damage bonuses (strength bonus, dexterity bonus, backstab)
+ //ToBEx compatibility in the ALWAYSBACKSTAB field:
+ //0 Normal conditions (attacker must be invisible, attacker must be in 90-degree arc behind victim)
+ //1 Ignore invisible requirement and positioning requirement
+ //2 Ignore invisible requirement only
+ //4 Ignore positioning requirement only
+ int multiplier=BaseStats[IE_BACKSTABDAMAGEMULTIPLIER];
+ if (multiplier>1) {
+ ieDword always = Modified[IE_ALWAYSBACKSTAB];
+ if ((Modified[IE_STATE_ID] & state_invisible) || (always&0x3) ) {
+ if ( !(core->HasFeature(GF_PROPER_BACKSTAB) && !IsBehind(target)) || (always&0x5) ) {
+ if (target->Modified[IE_DISABLEBACKSTAB]) {
+ // The backstab seems to have failed
+ displaymsg->DisplayConstantString (STR_BACKSTAB_FAIL, DMC_WHITE);
+ wi.backstabbing = false;
+ } else {
+ if (wi.backstabbing) {
+ damage *= multiplier;
+ // display a simple message instead of hardcoding multiplier names
+ displaymsg->DisplayConstantStringValue (STR_BACKSTAB, DMC_WHITE, multiplier);
+ } else {
+ // weapon is unsuitable for backstab
+ displaymsg->DisplayConstantString (STR_BACKSTAB_BAD, DMC_WHITE);
+ wi.backstabbing = false;
+ }
+ }
+ }
+ }
+ }
+ damage += WeaponDamageBonus(wi);
+
+ if (target->fxqueue.WeaponImmunity(wi.enchantment, wi.itemflags) ) {
+ //'my weapon has no effect'
+ damage = 0;
+ critical = false;
+ if (InParty) {
+ DisplayStringOrVerbalConstant(STR_WEAPONINEFFECTIVE, VB_TIMMUNE, 1);
+ core->Autopause(AP_UNUSABLE, this);
+ }
+ return;
+ }
+
+ //special effects on hit for arterial strike and hamstring
+ if (damage>0 && wi.backstabbing && BackstabResRef[0]!='*') {
+ core->ApplySpell(BackstabResRef, target, this, multiplier);
+ //do we need this?
+ BackstabResRef[0]='*';
+ if (HasFeat(FEAT_CRIPPLING_STRIKE) ) {
+ core->ApplySpell(resref_cripstr, target, this, multiplier);
+ }
+ }
+
+ //critical protection a la PST
+ if (pstflags && (target->Modified[IE_STATE_ID] & (ieDword) STATE_CRIT_PROT )) {
+ critical = false;
+ }
+
+ if (critical) {
+ if (target->inventory.ProvidesCriticalAversion()) {
+ //critical hit is averted by helmet
+ displaymsg->DisplayConstantStringName(STR_NO_CRITICAL, DMC_WHITE, target);
+ critical = false;
+ } else {
+ //a critical surely raises the morale?
+ //only if it is successful it raises the morale of the attacker
+ VerbalConstant(VB_CRITHIT, 1);
+ NewBase(IE_MORALE, 1, MOD_ADDITIVE);
+ //multiply the damage with the critical multiplier
+ damage *= wi.critmulti;
+
+ // check if critical hit needs a screenshake
+ if (crit_hit_scr_shake && (InParty || target->InParty) && core->GetVideoDriver()->GetViewport().PointInside(Pos) ) {
+ core->timer->SetScreenShake(10,-10,AI_UPDATE_TIME);
+ }
+
+ //apply the dirty fighting spell
+ if (HasFeat(FEAT_DIRTY_FIGHTING) ) {
+ core->ApplySpell(resref_dirty, target, this, multiplier);
+ }
+ }
+ }
+}
bool Actor::UseItem(ieDword slot, ieDword header, Scriptable* target, ieDword flags, int damage)
{
if (target->Type!=ST_ACTOR) {
return UseItemPoint(slot, header, target->Pos, flags);
}
+ // HACK: disable use when stunned (remove if stunned/petrified/etc actors stop running scripts)
+ if (Immobile()) {
+ return false;
+ }
Actor *tar = (Actor *) target;
CREItem *item = inventory.GetSlotItem(slot);
@@ -6074,7 +8091,10 @@ bool Actor::UseItem(ieDword slot, ieDword header, Scriptable* target, ieDword fl
strnuprcpy(tmpresref, item->ItemResRef, sizeof(ieResRef)-1);
Item *itm = gamedata->GetItem(tmpresref);
- if (!itm) return false; //quick item slot contains invalid item resref
+ if (!itm) {
+ Log(WARNING, "Actor", "Invalid quick slot item: %s!", tmpresref);
+ return false; //quick item slot contains invalid item resref
+ }
//item is depleted for today
if (itm->UseCharge(item->Usages, header, false)==CHG_DAY) {
return false;
@@ -6083,6 +8103,7 @@ bool Actor::UseItem(ieDword slot, ieDword header, Scriptable* target, ieDword fl
Projectile *pro = itm->GetProjectile(this, header, target->Pos, slot, flags&UI_MISS);
ChargeItem(slot, header, item, itm, flags&UI_SILENT);
gamedata->FreeItem(itm,tmpresref, false);
+ ResetCommentTime();
if (pro) {
//ieDword is unsigned!!
pro->SetCaster(GetGlobalID(), ITEM_CASTERLEVEL);
@@ -6092,6 +8113,12 @@ bool Actor::UseItem(ieDword slot, ieDword header, Scriptable* target, ieDword fl
Effect* AttackEffect = EffectQueue::CreateEffect(fx_damage_ref, damage, (weapon_damagetype[which->DamageType])<<16, FX_DURATION_INSTANT_LIMITED);
AttackEffect->Projectile = which->ProjectileAnimation;
AttackEffect->Target = FX_TARGET_PRESET;
+ AttackEffect->Parameter3 = 1;
+ if (pstflags) {
+ AttackEffect->IsVariable = GetCriticalType();
+ } else {
+ AttackEffect->IsVariable = flags&UI_CRITICAL;
+ }
pro->GetEffects()->AddEffect(AttackEffect, true);
if (ranged)
fxqueue.AddWeaponEffects(pro->GetEffects(), fx_ranged_ref);
@@ -6113,9 +8140,12 @@ void Actor::ChargeItem(ieDword slot, ieDword header, CREItem *item, Item *itm, b
item = inventory.GetSlotItem(slot);
if (!item)
return;
- itm = gamedata->GetItem(item->ItemResRef);
+ itm = gamedata->GetItem(item->ItemResRef, true);
+ }
+ if (!itm) {
+ Log(WARNING, "Actor", "Invalid quick slot item: %s!", item->ItemResRef);
+ return; //quick item slot contains invalid item resref
}
- if (!itm) return; //quick item slot contains invalid item resref
if (IsSelected()) {
core->SetEventFlag( EF_ACTION );
@@ -6171,7 +8201,7 @@ void Actor::InitButtons(ieDword cls, bool forced)
}
ActionButtonRow myrow;
- if ((int) cls >= classcount) {
+ if (cls >= (ieDword) classcount) {
memcpy(&myrow, &DefaultButtons, sizeof(ActionButtonRow));
for (int i=0;i<extraslots;i++) {
if (cls==OtherGUIButtons[i].clss) {
@@ -6205,6 +8235,26 @@ void Actor::SetFeat(unsigned int feat, int mode)
}
}
+void Actor::SetFeatValue(unsigned int feat, int value)
+{
+ if (feat>=MAX_FEATS) {
+ return;
+ }
+
+ //handle maximum and minimum values
+ if (value<0) value = 0;
+ else if (value>featmax[feat]) value = featmax[feat];
+
+ if (value) {
+ SetFeat(feat, BM_OR);
+ if (featstats[feat]) SetBase(featstats[feat], value);
+ } else {
+ SetFeat(feat, BM_NAND);
+ if (featstats[feat]) SetBase(featstats[feat], 0);
+ }
+ ApplyFeats();
+}
+
void Actor::SetUsedWeapon(const char* AnimationType, ieWord* MeleeAnimation, int wt)
{
memcpy(WeaponRef, AnimationType, sizeof(WeaponRef) );
@@ -6234,7 +8284,7 @@ void Actor::SetUsedWeapon(const char* AnimationType, ieWord* MeleeAnimation, int
AttackStance = IE_ANI_ATTACK_SLASH; //That's it!!
return;
}
- AttackStance = IE_ANI_ATTACK;
+ AttackStance = IE_ANI_ATTACK;
}
void Actor::SetUsedShield(const char* AnimationType, int wt)
@@ -6342,14 +8392,20 @@ int Actor::CheckUsability(Item *item) const
ieDword itemvalue = itembits[itemuse[i].which];
ieDword stat = GetStat(itemuse[i].stat);
ieDword mcol = itemuse[i].mcol;
- //if we have a kit, we just we use it's index for the lookup
+ //if we have a kit, we just use its index for the lookup
if (itemuse[i].stat==IE_KIT) {
- stat = GetKitIndex(stat, itemuse[i].table);
- mcol = 0xff;
+ if (!iwd2class) {
+ stat = GetKitIndex(stat, itemuse[i].table);
+ mcol = 0xff;
+ } else {
+ //iwd2 doesn't need translation from kit to usability, the kit value IS usability
+ goto no_resolve;
+ }
}
stat = ResolveTableValue(itemuse[i].table, stat, mcol, itemuse[i].vcol);
+no_resolve:
if (stat&itemvalue) {
- //printf("failed usability: itemvalue %d, stat %d, stat value %d\n", itemvalue, itemuse[i].stat, stat);
+ //print("failed usability: itemvalue %d, stat %d, stat value %d", itemvalue, itemuse[i].stat, stat);
return STR_CANNOT_USE_ITEM;
}
}
@@ -6357,9 +8413,6 @@ int Actor::CheckUsability(Item *item) const
return 0;
}
-static EffectRef fx_cant_use_item_ref = { "CantUseItem", -1 };
-static EffectRef fx_cant_use_item_type_ref = { "CantUseItemType", -1 };
-
//this one is the same, but returns strrefs based on effects
ieStrRef Actor::Disabled(ieResRef name, ieDword type) const
{
@@ -6465,10 +8518,27 @@ bool Actor::HasSpellState(unsigned int spellstate) const
return false;
}
+int Actor::GetMaxEncumbrance() const
+{
+ int max = core->GetStrengthBonus(3, GetStat(IE_STR), GetStat(IE_STREXTRA));
+ if (HasFeat(FEAT_STRONG_BACK)) max += max/2;
+ return max;
+}
+
//this is a very specific rule that might need an external table later
-int Actor::GetAbilityBonus(unsigned int ability) const
+int Actor::GetAbilityBonus(unsigned int ability, int value) const
+{
+ if (value == -1) { // invalid (default), use the current value
+ return GetStat(ability)/2-5;
+ } else {
+ return value/2-5;
+ }
+}
+
+int Actor::GetSkillStat(unsigned int skill) const
{
- return GetStat(ability)/2-5;
+ if (skill>=(unsigned int) skillcount) return -1;
+ return skillstats[skill];
}
int Actor::GetSkill(unsigned int skill) const
@@ -6534,26 +8604,30 @@ void Actor::CreateDerivedStatsBG()
//recalculate all level based changes
pcf_level(this,0,0);
- //even though the original didn't allow a cleric/paladin dual or multiclass
- //we shouldn't restrict the possibility by using "else if" here
- if (isclass[ISCLERIC]&(1<<classid)) {
- turnundeadlevel += GetClericLevel()+1-turnlevels[classid];
- if (turnundeadlevel<0) turnundeadlevel=0;
- }
- if (isclass[ISPALADIN]&(1<<classid)) {
- turnundeadlevel += GetPaladinLevel()+1-turnlevels[classid];
- if (turnundeadlevel<0) turnundeadlevel=0;
- }
-
// barbarian immunity to backstab was hardcoded
if (GetBarbarianLevel()) {
BaseStats[IE_DISABLEBACKSTAB] = 1;
}
+ for (int i=0;i<ISCLASSES;i++) {
+ int tmp;
+
+ if (classesiwd2[i]>=(ieDword) classcount) continue;
+ int tl = turnlevels[classesiwd2[i]];
+ if (tl) {
+ tmp = GetClassLevel(i)+1-tl;
+ //adding up turn undead levels, but this is probably moot
+ //anyway, you will be able to create custom priest/paladin classes
+ if (tmp>0) {
+ turnundeadlevel+=tmp;
+ }
+ }
+ }
+
ieDword backstabdamagemultiplier=GetThiefLevel();
if (backstabdamagemultiplier) {
// HACK: swashbucklers can't backstab
- if ((BaseStats[IE_KIT]&0xfff) == 12) {
+ if (GetKitUsability(BaseStats[IE_KIT])==KIT_SWASHBUCKLER) {
backstabdamagemultiplier = 1;
} else {
AutoTable tm("backstab");
@@ -6569,8 +8643,7 @@ void Actor::CreateDerivedStatsBG()
} else {
backstabdamagemultiplier = (backstabdamagemultiplier+7)/4;
}
- printf("\n");
- if (backstabdamagemultiplier>7) backstabdamagemultiplier=7;
+ if (backstabdamagemultiplier>5) backstabdamagemultiplier=5;
}
}
@@ -6579,7 +8652,7 @@ void Actor::CreateDerivedStatsBG()
if (isclass[ISMONK]&(1<<classid)) {
unsigned int level = GetMonkLevel()-1;
if (level < monkbon_cols) {
- BaseStats[IE_ARMORCLASS] = DEFAULTAC - monkbon[1][level];
+ AC.SetNatural(DEFAULTAC - monkbon[1][level]);
BaseStats[IE_ACMISSILEMOD] = - monkbon[2][level];
}
}
@@ -6595,33 +8668,51 @@ void Actor::CreateDerivedStatsIWD2()
int i;
int turnundeadlevel = 0;
+ // barbarian immunity to backstab was hardcoded
+ if (GetBarbarianLevel()) {
+ BaseStats[IE_DISABLEBACKSTAB] = 1;
+ }
+
+ //this is a bit too much hardcoded, backstab ability should be a class ability (like turn undead)
ieDword backstabdamagemultiplier=GetThiefLevel();
if (backstabdamagemultiplier) {
+ backstabdamagemultiplier += GetMonkLevel();
+ backstabdamagemultiplier += GetBardLevel();
AutoTable tm("backstab");
if (tm) {
ieDword cols = tm->GetColumnCount();
- if (backstabdamagemultiplier >= cols) backstabdamagemultiplier = cols;
+ if (backstabdamagemultiplier >= cols) backstabdamagemultiplier = cols-1;
backstabdamagemultiplier = atoi(tm->QueryField(0, backstabdamagemultiplier));
} else {
- backstabdamagemultiplier = (BaseStats[IE_LEVELTHIEF]+1)/2;
+ backstabdamagemultiplier = (backstabdamagemultiplier+7)/4;
}
- printf("\n");
- if (backstabdamagemultiplier>7) backstabdamagemultiplier=7;
+ if (backstabdamagemultiplier>5) backstabdamagemultiplier=5;
}
- int layonhandsamount = (int) BaseStats[IE_LEVELPALADIN];
- if (layonhandsamount) {
- layonhandsamount *= BaseStats[IE_CHR]/2-5;
- if (layonhandsamount<1) layonhandsamount = 1;
+ int layonhandsamount = 0;
+ int level = GetPaladinLevel();
+ if (level) {
+ // when this is called for the first time, Modified is not set yet
+ // FIXME: move to RefreshEffects, since it relies on a volatile stat
+ int mod = GetAbilityBonus(IE_CHR, BaseStats[IE_CHR]);
+ if (mod < 1) {
+ layonhandsamount = level;
+ } else {
+ layonhandsamount = level * mod;
+ }
}
- for (i=0;i<11;i++) {
+ for (i=0;i<ISCLASSES;i++) {
int tmp;
- if (turnlevels[i+1]) {
- tmp = BaseStats[IE_LEVELBARBARIAN+i]+1-turnlevels[i+1];
- if (tmp<0) tmp=0;
- if (tmp>turnundeadlevel) turnundeadlevel=tmp;
+ if (classesiwd2[i]>=(ieDword) classcount) continue;
+ int tl = turnlevels[classesiwd2[i]];
+ if (tl) {
+ tmp = GetClassLevel(i)+1-tl;
+ if (tmp>0) {
+ //the levels add up (checked)
+ turnundeadlevel+=tmp;
+ }
}
}
BaseStats[IE_TURNUNDEADLEVEL]=turnundeadlevel;
@@ -6633,20 +8724,18 @@ void Actor::CreateDerivedStatsIWD2()
//and similar derived stats that change with level
void Actor::CreateDerivedStats()
{
- //we have to calculate multiclass for further code
- AutoTable tm("classes");
- if (tm) {
- // currently we need only the MULTI value
- char tmpmulti[8];
- long tmp;
- strcpy(tmpmulti, tm->QueryField(tm->FindTableValue(5, BaseStats[IE_CLASS]), 4));
- if (!valid_number(tmpmulti, tmp))
+ if (iwd2class) {
+ multiclass = 0;
+ } else {
+ ieDword cls = BaseStats[IE_CLASS]-1;
+ if (cls>=(ieDword) classcount) {
multiclass = 0;
- else
- multiclass = (ieDword)tmp;
+ } else {
+ multiclass = multi[cls];
+ }
}
- if (core->HasFeature(GF_3ED_RULES)) {
+ if (third) {
CreateDerivedStatsIWD2();
} else {
CreateDerivedStatsBG();
@@ -6682,9 +8771,6 @@ Actor *Actor::CopySelf(bool mislead) const
//the creature importer does this too
memcpy(newActor->Modified,newActor->BaseStats, sizeof(Modified) );
- // temporary hack, so we don't get into a loop with CreateDerivedStats
- newActor->multiclass = 0;
-
//copy the inventory, but only if it is not the Mislead illusion
if (mislead) {
//these need to be called too to have a valid inventory
@@ -6709,9 +8795,9 @@ Actor *Actor::CopySelf(bool mislead) const
//copy the running effects
EffectQueue *newFXQueue = fxqueue.CopySelf();
- area->AddActor(newActor);
+ area->AddActor(newActor, true);
newActor->SetPosition( Pos, CC_CHECK_IMPASSABLE, 0 );
- newActor->SetOrientation(GetOrientation(),0);
+ newActor->SetOrientation(GetOrientation(), false);
newActor->SetStance( IE_ANI_READY );
//and apply them
@@ -6719,16 +8805,37 @@ Actor *Actor::CopySelf(bool mislead) const
return newActor;
}
-ieDword Actor::GetClassLevel(const ieDword id) const
+//high level function, used by scripting
+ieDword Actor::GetLevelInClass(ieDword classid) const
+{
+ if (version==22) {
+ //iwd2
+ for (int i=0;i<ISCLASSES;i++) {
+ if (classid==classesiwd2[i]) {
+ return GetClassLevel(i);
+ }
+ }
+ return 0;
+ }
+
+ if (classid>BGCLASSCNT) {
+ classid=0;
+ }
+ //other, levelslotsbg starts at 0 classid
+ return GetClassLevel(levelslotsbg[classid]);
+}
+
+//lowlevel internal function, isclass is NOT the class id, but an internal index
+ieDword Actor::GetClassLevel(const ieDword isclass) const
{
- if (id>=ISCLASSES)
+ if (isclass>=ISCLASSES)
return 0;
//return iwd2 value if appropriate
if (version==22)
- return BaseStats[levelslotsiwd2[id]];
+ return BaseStats[levelslotsiwd2[isclass]];
- //houston, we gots a problem!
+ //houston, we got a problem!
if (!levelslots || !dualswap)
return 0;
@@ -6738,12 +8845,12 @@ ieDword Actor::GetClassLevel(const ieDword id) const
return 0;
//handle barbarians specially, since they're kits and not in levelslots
- if (id == ISBARBARIAN && levelslots[classid][ISFIGHTER] && GetKitIndex(BaseStats[IE_KIT]) == 31) {
+ if ( (isclass == ISBARBARIAN) && levelslots[classid][ISFIGHTER] && (GetKitUsability(BaseStats[IE_KIT]) == KIT_BARBARIAN) ) {
return BaseStats[IE_LEVEL];
}
//get the levelid (IE_LEVEL,*2,*3)
- ieDword levelid = levelslots[classid][id];
+ ieDword levelid = levelslots[classid][isclass];
if (!levelid)
return 0;
@@ -6751,7 +8858,7 @@ ieDword Actor::GetClassLevel(const ieDword id) const
if (IsDualClassed()) {
//if the old class is inactive, and it is the class
//being searched for, return 0
- if (IsDualInactive() && ((Modified[IE_MC_FLAGS]&MC_WAS_ANY)==(ieDword)mcwasflags[id]))
+ if (IsDualInactive() && ((Modified[IE_MC_FLAGS]&MC_WAS_ANY)==(ieDword)mcwasflags[isclass]))
return 0;
}
return BaseStats[levelid];
@@ -6823,6 +8930,8 @@ void Actor::UseExit(ieDword exitID) {
InternalFlags|=IF_USEEXIT;
} else {
InternalFlags&=~IF_USEEXIT;
+ UsedExit = LastExit;
+ memcpy(LastArea, Area, 8);
}
LastExit = exitID;
}
@@ -6831,22 +8940,27 @@ void Actor::UseExit(ieDword exitID) {
// luck does not affect critical hit chances:
// if critical is set, it will return 1/sides on a critical, otherwise it can never
// return a critical miss when luck is positive and can return a false critical hit
+// Callees with LR_CRITICAL should check if the result matches 1 or size*dice.
int Actor::LuckyRoll(int dice, int size, int add, ieDword flags, Actor* opponent) const
{
assert(this != opponent);
- ieDword stat;
+ int luck;
+
+ luck = (signed) GetSafeStat(IE_LUCK);
+
+ //damageluck is additive with regular luck (used for maximized damage, righteous magic)
if (flags&LR_DAMAGELUCK) {
- stat = IE_DAMAGELUCK;
- } else {
- stat = IE_LUCK;
+ luck += (signed) GetSafeStat(IE_DAMAGELUCK);
}
- int luck = (signed) GetSafeStat(stat);
+ //it is always the opponent's luck that decrease damage (or anything)
+ if (opponent) luck -= opponent->GetSafeStat(IE_LUCK);
+
if (flags&LR_NEGATIVE) {
luck = -luck;
}
- if (opponent) luck -= (signed) opponent->GetStat(stat);
+
if (dice < 1 || size < 1) {
return add + luck;
}
@@ -6887,13 +9001,17 @@ int Actor::LuckyRoll(int dice, int size, int add, ieDword flags, Actor* opponent
// ensure we can still return a critical failure/success
if (critical && dice == misses) return 1;
- if (critical && dice == hits) return size;
+ if (critical && dice == hits) return size*dice;
- return result + add;
+ // hack for critical mode, so overbearing luck does not cause a critical hit
+ // FIXME: decouple the result from the critical info
+ if (critical && result+add >= size*dice) {
+ return size*dice - 1;
+ } else {
+ return result + add;
+ }
}
-static EffectRef fx_remove_invisible_state_ref = { "ForceVisible", -1 };
-
// removes the (normal) invisibility state
void Actor::CureInvisibility()
{
@@ -6907,13 +9025,11 @@ void Actor::CureInvisibility()
//not sure, but better than nothing
if (! (Modified[IE_STATE_ID]&state_invisible)) {
- InternalFlags|=IF_BECAMEVISIBLE;
+ AddTrigger(TriggerEntry(trigger_becamevisible));
}
}
}
-static EffectRef fx_remove_sanctuary_ref = { "Cure:Sanctuary", -1 };
-
// removes the sanctuary effect
void Actor::CureSanctuary()
{
@@ -6930,6 +9046,7 @@ void Actor::ResetState()
CureInvisibility();
CureSanctuary();
SetModal(MS_NONE);
+ ResetCommentTime();
}
// doesn't check the range, but only that the azimuth and the target
@@ -6951,67 +9068,151 @@ bool Actor::IsBehind(Actor* target) const
}
// checks all the actor's stats to see if the target is her racial enemy
-bool Actor::IsRacialEnemy(Actor* target) const
+int Actor::GetRacialEnemyBonus(Actor* target) const
{
- if (Modified[IE_HATEDRACE] == target->Modified[IE_RACE]) {
- return true;
- } else if (core->HasFeature(GF_3ED_RULES)) {
+ if (!target) {
+ return 0;
+ }
+
+ if (third) {
+ int level = GetRangerLevel();
+ if (Modified[IE_HATEDRACE] == target->Modified[IE_RACE]) {
+ return (level+4)/5;
+ }
// iwd2 supports multiple racial enemies gained through level progression
for (unsigned int i=0; i<7; i++) {
if (Modified[IE_HATEDRACE2+i] == target->Modified[IE_RACE]) {
- return true;
+ return (level+4)/5-i-1;
}
}
+ return 0;
}
- return false;
+ if (Modified[IE_HATEDRACE] == target->Modified[IE_RACE]) {
+ return 4;
+ }
+ return 0;
}
-bool Actor::ModalSpellSkillCheck() {
+bool Actor::ModalSpellSkillCheck()
+{
switch(ModalState) {
- case MS_BATTLESONG:
- case MS_DETECTTRAPS:
- case MS_TURNUNDEAD:
+ case MS_BATTLESONG:
+ if (isclass[ISBARD]&(1<<Modified[IE_CLASS])) {
return true;
- case MS_STEALTH:
+ }
+ /* do we need this */
+ if (Modified[IE_STATE_ID]& STATE_SILENCED) {
+ return true;
+ }
+ return false;
+ case MS_DETECTTRAPS:
+ if (Modified[IE_TRAPS]<=0) return false;
+ return true;
+ case MS_TURNUNDEAD:
+ if (Modified[IE_TURNUNDEADLEVEL]<=0) return false;
+ return true;
+ case MS_STEALTH:
return TryToHide();
- case MS_NONE:
+ case MS_NONE:
default:
return false;
}
}
-static EffectRef fx_disable_button_ref = { "DisableButton", -1 };
-
-inline void HideFailed(Actor* actor)
+inline void HideFailed(Actor* actor, int reason = -1, int skill = 0, int roll = 0, int targetDC = 0)
{
Effect *newfx;
newfx = EffectQueue::CreateEffect(fx_disable_button_ref, 0, ACT_STEALTH, FX_DURATION_INSTANT_LIMITED);
newfx->Duration = core->Time.round_sec; // 90 ticks, 1 round
core->ApplyEffect(newfx, actor, actor);
delete newfx;
+
+ if (!third) {
+ return;
+ }
+
+ int bonus = actor->GetAbilityBonus(IE_DEX);
+ switch (reason) {
+ case 0:
+ // ~Failed hide in shadows check! Hide in shadows check %d vs. D20 roll %d (%d Dexterity ability modifier)~
+ displaymsg->DisplayRollStringName(39300, DMC_LIGHTGREY, actor, skill-bonus, roll, bonus);
+ break;
+ case 1:
+ // ~Failed hide in shadows because you were seen by creature! Hide in Shadows check %d vs. creature's Level+Wisdom+Race modifier %d + %d D20 Roll.~
+ displaymsg->DisplayRollStringName(39298, DMC_LIGHTGREY, actor, skill, targetDC, roll);
+ break;
+ case 2:
+ // ~Failed hide in shadows because you were heard by creature! Hide in Shadows check %d vs. creature's Level+Wisdom+Race modifier %d + %d D20 Roll.~
+ displaymsg->DisplayRollStringName(39297, DMC_LIGHTGREY, actor, skill, targetDC, roll);
+ default:
+ // no message
+ break;
+ }
}
-bool Actor::TryToHide() {
- ieDword roll = LuckyRoll(1, 100, 0);
- if (roll == 1) {
- HideFailed(this);
- return false;
+//checks if we are seen, or seeing anyone
+bool Actor::SeeAnyOne(bool enemy, bool seenby)
+{
+ Map *area = GetCurrentArea();
+ if (!area) return false;
+
+ int flag = seenby?GA_NO_DEAD:GA_NO_DEAD|GA_NO_HIDDEN;
+ if (enemy) {
+ ieDword ea = GetSafeStat(IE_EA);
+ if (ea>=EA_EVILCUTOFF) {
+ flag|=GA_NO_ENEMY|GA_NO_NEUTRAL;
+ } else if (ea<=EA_GOODCUTOFF) {
+ flag|=GA_NO_ALLY|GA_NO_NEUTRAL;
+ } else return false; //neutrals got no enemy
}
+ Actor** visActors = area->GetAllActorsInRadius(Pos, flag, seenby?15*10:GetSafeStat(IE_VISUALRANGE)*10, this);
- // check for disabled dualclassed thieves (not sure if we need it)
+ Actor** poi = visActors;
+ bool seeEnemy = false;
+
+ //we need to look harder if we look for seenby anyone
+ while (*poi && !seeEnemy) {
+ Actor *toCheck = *poi++;
+ if (toCheck==this) continue;
+ if (seenby) {
+ if(ValidTarget(GA_NO_HIDDEN, toCheck) && (toCheck->Modified[IE_VISUALRANGE]*10<PersonalDistance(toCheck, this) ) ) seeEnemy=true;
+ }
+ else seeEnemy = true;
+ }
+ free(visActors);
+ return seeEnemy;
+}
+bool Actor::TryToHide()
+{
if (Modified[IE_DISABLEDBUTTON] & (1<<ACT_STEALTH)) {
HideFailed(this);
return false;
}
- // check if the pc is in combat (seen / heard)
- Game *game = core->GetGame();
- if (game->PCInCombat(this)) {
- HideFailed(this);
- return false;
+ // iwd2 is like the others only when trying to hide for the first time
+ // TODO: once understood, the visual checks need syncing (not just lightness)
+ bool continuation = third && (Modified[IE_STATE_ID]&state_invisible);
+ if (third && continuation) {
+ return TryToHideIWD2();
+ }
+
+ ieDword roll = 0;
+ if (third) {
+ roll = LuckyRoll(1, 20, GetArmorSkillPenalty(0));
+ } else {
+ roll = LuckyRoll(1, 100, GetArmorSkillPenalty(0));
+ // critical failure
+ if (roll == 1) {
+ HideFailed(this);
+ return false;
+ }
}
+ // check for disabled dualclassed thieves (not sure if we need it)
+
+ bool seen = SeeAnyOne(true, true);
+
ieDword skill;
if (core->HasFeature(GF_HAS_HIDE_IN_SHADOWS)) {
skill = (GetStat(IE_HIDEINSHADOWS) + GetStat(IE_STEALTH))/2;
@@ -7019,6 +9220,15 @@ bool Actor::TryToHide() {
skill = GetStat(IE_STEALTH);
}
+ if (seen) {
+ HideFailed(this, 1);
+ }
+
+ if (third) {
+ skill *= 7; // FIXME: temporary increase for the lightness percentage calculation
+ }
+ // TODO: figure out how iwd2 uses the area lightness and crelight.2da
+ Game *game = core->GetGame();
// check how bright our spot is
ieDword lightness = game->GetCurrentArea()->GetLightLevel(Pos);
// seems to be the color overlay at midnight; lightness of a point with rgb (200, 100, 100)
@@ -7027,15 +9237,96 @@ bool Actor::TryToHide() {
ieDword chance = (100 - light_diff) * skill/100;
if (roll > chance) {
- HideFailed(this);
+ HideFailed(this, 0, skill/7, roll);
return false;
}
+ if (!third) return true;
+ // ~Successful hide in shadows check! Hide in shadows check %d vs. D20 roll %d (%d Dexterity ability modifier)~
+ displaymsg->DisplayRollStringName(39299, DMC_LIGHTGREY, this, skill/7, roll, GetAbilityBonus(IE_DEX));
+ return true;
+}
+
+// skill check when trying to maintain invisibility: separate move silently and visibility check
+bool Actor::TryToHideIWD2()
+{
+ Actor **neighbours = area->GetAllActorsInRadius(Pos, GA_NO_DEAD|GA_NO_LOS|GA_NO_ALLY|GA_NO_NEUTRAL|GA_NO_SELF, 60);
+ Actor **poi = neighbours;
+ ieDword roll = LuckyRoll(1, 20, GetArmorSkillPenalty(0));
+ int targetDC = 0;
+ bool checked = false;
+
+ // visibility check, you can try hiding while enemies are nearby
+ // TODO: add lightness check as in TryToHide
+ // TODO: use crehidemd.2da as a skill bonus/malus (after refreshing effects, not here)
+ ieDword skill = GetStat(IE_HIDEINSHADOWS);
+ bool seen = false;
+ while (*poi) {
+ Actor *toCheck = *poi++;
+ if (toCheck->GetStat(IE_STATE_ID)&STATE_BLIND) {
+ continue;
+ }
+ // we need to do a visual range check here, since we ignored it above, so hearing is not affected
+ if (toCheck->GetStat(IE_VISUALRANGE)*10 < PersonalDistance(toCheck, this)) {
+ continue;
+ }
+ // IE_XPVALUE is the CR value in iwd2
+ // the third summand should be a racial bonus, but since skillrac has other values, we use their search skill directly
+ targetDC = toCheck->GetStat(IE_XPVALUE) + toCheck->GetAbilityBonus(IE_WIS) + toCheck->GetStat(IE_SEARCH);
+ seen = skill < (roll + targetDC);
+ if (seen) {
+ HideFailed(this, 1, skill, roll, targetDC);
+ free(neighbours);
+ return false;
+ } else {
+ // ~You were not seen by creature! Hide check %d vs. creature's Level+Wisdom+Race modifier %d + %d D20 Roll.~
+ displaymsg->DisplayRollStringName(28379, DMC_LIGHTGREY, this, skill, targetDC, roll);
+ }
+ }
+
+ // we're stationary, so no need to check if we're making movement sounds
+ if (!InMove() && !checked) {
+ free(neighbours);
+ return true;
+ }
+
+ // separate move silently check
+ skill = GetStat(IE_STEALTH);
+ poi = neighbours;
+ bool heard = false;
+ while (*poi) {
+ Actor *toCheck = *poi++;
+ if (toCheck->HasSpellState(SS_DEAF)) {
+ continue;
+ }
+ // NOTE: pretending there is no hearing range
+ // IE_XPVALUE is the CR value in iwd2
+ // the third summand should be a racial bonus, but since skillrac has other values, we use their search skill directly
+ targetDC = toCheck->GetStat(IE_XPVALUE) + toCheck->GetAbilityBonus(IE_WIS) + toCheck->GetStat(IE_SEARCH);
+ heard = skill < (roll + targetDC);
+ if (heard) {
+ HideFailed(this, 2, skill, roll, targetDC);
+ free(neighbours);
+ return false;
+ } else {
+ // ~You were not heard by creature! Move silently check %d vs. creature's Level+Wisdom+Race modifier %d + %d D20 Roll.~
+ displaymsg->DisplayRollStringName(112, DMC_LIGHTGREY, this, skill, targetDC, roll);
+ }
+ }
+
+ free(neighbours);
return true;
}
+//cannot target actor (used by GUI)
+bool Actor::Untargetable()
+{
+ return (GetSafeStat(IE_STATE_ID)&state_invisible) || HasSpellState(SS_SANCTUARY);
+}
+
+//it is futile to try to harm target (used by AI scripts)
bool Actor::InvalidSpellTarget() const
{
- if (GetStat(IE_STATE_ID) & (STATE_DEAD)) return true;
+ if (GetSafeStat(IE_STATE_ID) & STATE_DEAD) return true;
if (HasSpellState(SS_SANCTUARY)) return true;
return false;
}
@@ -7044,13 +9335,18 @@ bool Actor::InvalidSpellTarget(int spellnum, Actor *caster, int range) const
{
ieResRef spellres;
- //TODO: spell specific state checks
- if (!range) return false;
-
ResolveSpellName(spellres, spellnum);
- Spell *spl = gamedata->GetSpell(spellres);
- int srange = spl->GetCastingDistance(caster);
+ //cheap substitute of the original hardcoded feature, returns true if already affected by the exact spell
+ //no (spell)state checks based on every effect in the spell
+ //FIXME: create a more compatible version if needed
+ if (fxqueue.HasSource(spellres)) return true;
+ //return true if caster cannot cast
+ if (!caster->CanCast(spellres, false)) return true;
+
+ if (!range) return false;
+
+ int srange = GetSpellDistance(spellres, caster);
return srange<range;
}
@@ -7076,3 +9372,254 @@ int Actor::GetClassMask() const
return classmask;
}
+int Actor::GetBookMask() const
+{
+ int bookmask = 0;
+ for (int i=0; i < ISCLASSES; i++) {
+ if (Modified[levelslotsiwd2[i]] > 0) {
+ bookmask |= 1<<((1<<booksiwd2[i])-1);
+ }
+ }
+
+ return bookmask;
+}
+
+// returns the combined dexterity and racial bonus to specified thieving skill
+// column indices are 1-based, since 0 holds the rowname against which we do the lookup
+int Actor::GetSkillBonus(unsigned int col) const
+{
+ if (skilldex.empty()) return 0;
+
+ // race
+ int lookup = Modified[IE_RACE];
+ int bonus = 0;
+ std::vector<std::vector<int> >::iterator it = skillrac.begin();
+ // make sure we have a column, since the games have different amounts of thieving skills
+ if (col < (*it).size()) {
+ for ( ; it != skillrac.end(); it++) {
+ if ((*it)[0] == lookup) {
+ bonus = (*it)[col];
+ break;
+ }
+ }
+ }
+
+ // dexterity
+ lookup = Modified[IE_DEX];
+ it = skilldex.begin();
+ // make sure we have a column, since the games have different amounts of thieving skills
+ if (col < (*it).size()) {
+ for ( ; it != skilldex.end(); it++) {
+ if ((*it)[0] == lookup) {
+ bonus += (*it)[col];
+ break;
+ }
+ }
+ }
+ return bonus;
+}
+
+bool Actor::IsPartyMember() const
+{
+ if (Modified[IE_EA]<=EA_FAMILIAR) return true;
+ return InParty>0;
+}
+
+void Actor::ResetCommentTime()
+{
+ Game *game = core->GetGame();
+ if (bored_time) {
+ nextBored = game->GameTime + core->Roll(1, 30, bored_time);
+ } else {
+ nextBored = 0;
+ }
+ nextComment = game->GameTime + core->Roll(5, 1000, bored_time/2);
+}
+
+// this one is just a hack, so we can keep a bunch of other functions const
+int Actor::GetArmorSkillPenalty(int profcheck) const
+{
+ int tmp1, tmp2;
+ return GetArmorSkillPenalty(profcheck, tmp1, tmp2);
+}
+
+// Returns the armor check penalty.
+// used for mapping the iwd2 armor feat to the equipped armor's weight class
+// the armor weight class is perfectly deduced from the penalty as following:
+// 0, none: none, robes
+// 1-3, light: leather, studded
+// 4-6, medium: hide, chain, scale
+// 7-, heavy: splint, plate, full plate
+// the values are taken from our dehardcoded itemdata.2da
+// magical shields and armors get a +1 bonus
+int Actor::GetArmorSkillPenalty(int profcheck, int &armor, int &shield) const
+{
+ if (!third) return 0;
+
+ ieWord armorType = inventory.GetArmorItemType();
+ int penalty = core->GetArmorPenalty(armorType);
+ int weightClass = 0;
+
+ if (penalty >= 1 && penalty < 4) {
+ weightClass = 1;
+ } else if (penalty >= 4 && penalty < 7) {
+ weightClass = 2;
+ } else if (penalty >= 7) {
+ weightClass = 3;
+ }
+
+ // ignore the penalty if we are proficient
+ if (profcheck && GetFeat(FEAT_ARMOUR_PROFICIENCY) >= weightClass) {
+ penalty = 0;
+ }
+ bool magical = false;
+ int armorSlot = inventory.GetArmorSlot();
+ CREItem *armorItem = inventory.GetSlotItem(armorSlot);
+ if (armorItem) {
+ magical = armorItem->Flags&IE_INV_ITEM_MAGICAL;
+ }
+ if (magical) {
+ penalty -= 1;
+ if (penalty < 0) {
+ penalty = 0;
+ }
+ }
+ armor = penalty;
+
+ // check also the shield penalty
+ armorType = inventory.GetShieldItemType();
+ int shieldPenalty = core->GetShieldPenalty(armorType);
+ magical = false;
+ armorSlot = inventory.GetShieldSlot();
+ if (armorSlot != -1) { // there is a shield
+ armorItem = inventory.GetSlotItem(armorSlot);
+ if (armorItem) {
+ magical = armorItem->Flags&IE_INV_ITEM_MAGICAL;
+ }
+ }
+ if (magical) {
+ shieldPenalty -= 1;
+ if (shieldPenalty < 0) {
+ shieldPenalty = 0;
+ }
+ }
+ if (profcheck) {
+ if (HasFeat(FEAT_SHIELD_PROF)) {
+ shieldPenalty = 0;
+ } else {
+ penalty += shieldPenalty;
+ }
+ } else {
+ penalty += shieldPenalty;
+ }
+ shield = shieldPenalty;
+
+ return -penalty;
+}
+
+int Actor::GetTotalArmorFailure() const
+{
+ int armorfailure, shieldfailure;
+ GetArmorFailure(armorfailure, shieldfailure);
+ return armorfailure+shieldfailure;
+}
+
+int Actor::GetArmorFailure(int &armor, int &shield) const
+{
+ armor = shield = 0;
+ if (!third) return 0;
+
+ ieWord armorType = inventory.GetArmorItemType();
+ int penalty = core->GetArmorFailure(armorType);
+ armor = penalty;
+
+ // check also the shield penalty
+ armorType = inventory.GetShieldItemType();
+ int shieldPenalty = core->GetShieldPenalty(armorType);
+ penalty += shieldPenalty;
+ shield = shieldPenalty;
+
+ return -penalty;
+}
+
+// checks whether the actor is visible to another scriptable
+// if flags is 1, it skips the EA check for STATE_INVISIBLE
+bool Actor::IsInvisibleTo(Scriptable *checker) const
+{
+ if (Modified[IE_AVATARREMOVAL]) return true;
+
+ bool canSeeInvisibles = false;
+ if (checker && checker->Type == ST_ACTOR) {
+ canSeeInvisibles = ((Actor *) checker)->GetSafeStat(IE_SEEINVISIBLE);
+ }
+ if (!canSeeInvisibles && (Modified[IE_STATE_ID] & state_invisible)) {
+ return true;
+ }
+
+ return false;
+}
+
+int Actor::UpdateAnimationID(bool derived)
+{
+ if (avCount<0) return 1;
+ // the base animation id
+ int AnimID = avBase;
+ int StatID = derived?GetSafeStat(IE_ANIMATION_ID):avBase;
+ if (AnimID<0 || StatID<AnimID || StatID>AnimID+0x1000) return 1; //no change
+ if (!InParty) return 1; //too many bugs caused by buggy game data, we change only PCs
+
+ // tables for additive modifiers of the animation id (race, gender, class)
+ for (int i = 0; i < avCount; i++) {
+ const TableMgr *tm = avPrefix[i].avtable.ptr();
+ if (!tm) {
+ return -3;
+ }
+ StatID = avPrefix[i].stat;
+ StatID = derived?GetSafeStat(StatID):GetBase( StatID );
+
+ const char *poi = tm->QueryField( StatID );
+ AnimID += strtoul( poi, NULL, 0 );
+ }
+ if (BaseStats[IE_ANIMATION_ID]!=(unsigned int) AnimID) {
+ SetBase(IE_ANIMATION_ID, (unsigned int) AnimID);
+ }
+ if (!derived) {
+ SetAnimationID(AnimID);
+ //setting PST's starting stance to 18
+ if (avStance !=-1) {
+ SetStance( avStance );
+ }
+ }
+ return 0;
+}
+
+void Actor::MovementCommand(char *command)
+{
+ UseExit(0);
+ ClearPath();
+ ClearActions();
+ AddAction( GenerateAction( command ) );
+ ProcessActions();
+}
+
+// shows hp/maxhp as overhead text
+void Actor::DisplayHeadHPRatio()
+{
+ //sucks but this is set in different places
+ if (GetStat(IE_MC_FLAGS) & MC_HIDE_HP) return;
+ if (GetStat(IE_EXTSTATE_ID) & EXTSTATE_NO_HP) return;
+
+ char tmpstr[10];
+ memset(tmpstr, 0, 10);
+ snprintf(tmpstr, 10, "%d/%d", Modified[IE_HITPOINTS], Modified[IE_MAXHITPOINTS]);
+ DisplayHeadText(tmpstr);
+}
+
+void Actor::ReleaseCurrentAction()
+{
+ disarmTrap = -1;
+ Scriptable::ReleaseCurrentAction();
+}
+
+}
+
diff --git a/gemrb/core/Scriptable/Actor.h b/gemrb/core/Scriptable/Actor.h
index 5b54b5b..7e05232 100644
--- a/gemrb/core/Scriptable/Actor.h
+++ b/gemrb/core/Scriptable/Actor.h
@@ -28,25 +28,36 @@
#include "exports.h"
#include "ie_types.h"
-#include "Animation.h"
#include "Audio.h"
-#include "CharAnimations.h"
+#include "CombatInfo.h"
#include "EffectQueue.h"
-#include "ScriptedAnimation.h"
+#include "Palette.h"
#include <cstring>
#include <vector>
+namespace GemRB {
+
+class Animation;
+class ArmorClass;
+class CharAnimations;
+class DataFileMgr;
class Map;
class ScriptedAnimation;
+class StringBuffer;
+class ToHitStats;
struct PolymorphCache;
+}
+
/** USING DEFINITIONS AS DESCRIBED IN STATS.IDS */
#include "ie_stats.h"
#include "Inventory.h"
#include "Spellbook.h"
+namespace GemRB {
+
#define MAX_STATS 256
#define MAX_LEVEL 128
#define MAX_FEATS 96 //3*sizeof(ieDword)
@@ -89,6 +100,14 @@ struct PolymorphCache;
#define PANIC_RUNAWAY 2
#define PANIC_RANDOMWALK 3
+//Game Difficulty
+#define DIFF_DEFAULT 0
+#define DIFF_EASY 1
+#define DIFF_NORMAL 2
+#define DIFF_CORE 3
+#define DIFF_HARD 4
+#define DIFF_NIGHTMARE 5
+
/** flags for GetActor */
//default action
#define GA_DEFAULT 0
@@ -134,9 +153,13 @@ struct PolymorphCache;
#define VCONST_COUNT 100
//interact types
+#define I_NONE 0
#define I_INSULT 1
#define I_COMPLIMENT 2
#define I_SPECIAL 3
+#define I_INSULT_RESP 4
+#define I_COMPL_RESP 5
+#define I_DIALOG 6
// 3 for blur, 8 for mirror images
#define EXTRA_ACTORCOVERS 11
@@ -144,6 +167,7 @@ struct PolymorphCache;
//flags for UseItem
#define UI_SILENT 1 //no sound when used up
#define UI_MISS 2 //ranged miss (projectile has no effects)
+#define UI_CRITICAL 4 //a critical hit happened
//used to mask off current profs
#define PROFS_MASK 0x07
@@ -160,14 +184,17 @@ struct PolymorphCache;
#define ISPALADIN 8
#define ISRANGER 9
#define ISSORCERER 10
-#define ISCLASSES 11
+#define ISCLASS12 11
+#define ISCLASS13 12
+
+#define ISCLASSES 13
//appearance flags
#define APP_HALFTRANS 2 //half transparent
#define APP_DEATHVAR 16 //set death variable
#define APP_DEATHTYPE 32 //count creature type deaths
-//64
+#define APP_ADDKILL 64 //prepend KILL_ to the creature type
#define APP_FACTION 128 //count killed faction
#define APP_TEAM 0x100 //count killed team
#define APP_INVULNERABLE 0x200 //invulnerable
@@ -208,18 +235,30 @@ struct ActionButtonRow2 {
};
typedef std::vector< ScriptedAnimation*> vvcVector;
-typedef std::list<ieResRef*> resourceList;
struct WeaponInfo {
int slot;
- int enchantment;
+ ieDword enchantment;
unsigned int range;
ieDword itemflags;
ieDword prof;
bool backstabbing;
+ ieDword wflags;
+ int critmulti; //critical hit multiplier (usually 2)
+ int critrange; // the lower value of the critical range (eg. 19 in 19-20/x3)
+ int profdmgbon;
+ int launcherdmgbon;
+ WeaponInfo(): slot(0), enchantment(0), range(0), itemflags(0), prof(0), backstabbing(false), wflags(0), critmulti(0), critrange(0), profdmgbon(0), launcherdmgbon(0) {};
+};
+
+struct BABTable {
+ ieDword level;
+ int bab; // basic attack bonus
+ int apr; // attacks per round
};
extern void ReleaseMemoryActor();
+GEM_EXPORT void UpdateActorConfig(); //call this from guiscripts when some variable has changed
class GEM_EXPORT Actor : public Movable {
public:
@@ -242,6 +281,7 @@ public:
ieResRef ModalSpell; //apply this spell once per round
ieResRef LingeringModalSpell; //apply this spell once per round if the effects are lingering
ieResRef BardSong; //custom bard song (updated by fx)
+ ieResRef BackstabResRef; //apply on successful backstab
PCStatsStruct* PCStats;
ieResRef SmallPortrait;
@@ -274,27 +314,12 @@ public:
ieDword appearance;
ieDword ModalState;
int PathTries; //the # of previous tries to pick up a new walkpath
+ ArmorClass AC;
+ ToHitStats ToHit;
public:
- #define LastTarget LastDisarmFailed
- //ieDword LastTarget; use lastdisarmfailed
- #define LastAttacker LastDisarmed
- //ieDword LastAttacker; use lastdisarmed
- #define LastHitter LastEntered
- //ieDword LastHitter; use lastentered
- #define LastSummoner LastTrigger
- //ieDword LastSummoner; use lasttrigger
- #define LastTalkedTo LastUnlocked
- //ieDword LastTalkedTo; use lastunlocked
- ieDword LastProtected;
- ieDword LastFollowed;
- ieDword LastCommander;
- ieDword LastHelp;
- ieDword LastSeen;
- ieDword LastMarked; //no idea if non-actors could mark objects
- int LastMarkedSpell; //a spell number to cast
- ieDword LastHeard;
- ieDword HotKey;
ieDword LastExit; //the global ID of the exit to be used
+ ieDword UsedExit;
+ ieResRef LastArea;
char ShieldRef[2];
char HelmetRef[2];
char WeaponRef[2];
@@ -303,11 +328,8 @@ public:
bool GotLUFeedback;
int WMLevelMod;
- int LastCommand; //lastcommander
- int LastShout; //lastheard
- int LastDamage; //lasthitter
- int LastDamageType;//lasthitter
- ieDword LastTurner;
+ int LastDamageType;
+ int LastDamage;
Point FollowOffset;//follow lastfollowed at this offset
Point HomeLocation;//spawnpoint, return here after rest
@@ -322,9 +344,13 @@ public:
ieDword modalTime; //last time the modal effect used
char modalSpellLingering; //the count of rounds for which the modal spell will be reapplied after the state ends
ieDword panicMode; //runaway, berserk or randomwalk
+ ieDword nextComment; //do something random (area comment, interaction)
+ ieDword nextBored; //do something when bored
ieDword lastInit;
bool no_more_steps;
int speed;
+ //how many attacks left in this round, must be public for cleave opcode
+ int attackcount;
PolymorphCache *polymorphCache; // fx_polymorph etc
WildSurgeSpellMods wildSurgeMods;
@@ -333,8 +359,8 @@ private:
CharAnimations* anims;
SpriteCover* extraCovers[EXTRA_ACTORCOVERS];
ieByte SavingThrow[5];
- //how many attacks in this round
- int attackcount;
+ // true when command has been played after select
+ bool playedCommandSound;
//true every second round of attack
bool secondround;
int attacksperround;
@@ -342,21 +368,22 @@ private:
ieDword nextattack;
ieDword nextWalk;
ieDword lastattack;
+ //trap we're trying to disarm
+ ieDword disarmTrap;
ieDword InTrap;
char AttackStance;
/*The projectile bringing the current attack*/
Projectile* attackProjectile ;
+ int TicksLastRested;
/** paint the actor itself. Called internally by Draw() */
void DrawActorSprite(const Region &screen, int cx, int cy, const Region& bbox,
- SpriteCover*& sc, Animation** anims,
- unsigned char Face, const Color& tint);
+ SpriteCover*& sc, Animation** anims,
+ unsigned char Face, const Color& tint);
/** fixes the palette */
void SetupColors();
/** debugging function, gets the scripting name of an actor referenced by a global ID */
const char* GetActorNameByID(ieDword ID) const;
- /* if Lasttarget is gone, call this */
- void StopAttack();
/* checks a weapon quick slot and resets it to fist if it is empty */
void CheckWeaponQuickSlot(unsigned int which);
/* helper for usability checks */
@@ -366,15 +393,20 @@ private:
/* Set up all the missing stats on load time, or after level up */
void CreateDerivedStatsIWD2();
/* Gets the given ISCLASS level */
- ieDword GetClassLevel (const ieDword id) const;
+ ieDword GetClassLevel (const ieDword isclass) const;
/* Returns true if the dual class is backwards */
bool IsDualSwap() const;
+ /* returns the weapon proficiency stat of the actor */
+ int GetProficiency(int proftype) const;
/** Re/Inits the Modified vector for PCs/NPCs */
void RefreshPCStats();
+ void RefreshHP();
bool ShouldHibernate();
void ApplyClassClab(int cls, bool remove);
- bool ShouldDrawCircle();
+ bool ShouldDrawCircle() const;
+ bool HasBodyHeat() const;
void SetupFistData();
+ void UpdateFatigue();
public:
Actor(void);
~Actor(void);
@@ -385,18 +417,23 @@ public:
/** sets game specific default data about action buttons */
static void SetDefaultActions(int qslot, ieByte slot1, ieByte slot2, ieByte slot3);
/** prints useful information on console */
- void DumpMaxValues();
- void DebugDump();
+ void dump() const;
+ /** prints useful information to given buffer */
+ void dump(StringBuffer&) const;
/** fixes the feet circle */
void SetCircleSize();
/** places the actor on the map */
void SetMap(Map *map);
/** sets the actor's position, calculating with the nojump flag*/
- void SetPosition(const Point &position, int jump, int radius=0);
+ void SetPosition(const Point &position, int jump, int radiusx=0, int radiusy=0);
/** you better use SetStat, this stuff is only for special cases*/
void SetAnimationID(unsigned int AnimID);
/** returns the animations */
CharAnimations* GetAnims() const;
+ /** returns the gender of actor for cg sound - illusions are tricky */
+ ieDword GetCGGender();
+ /** some hardcoded effects in puppetmaster based on puppet type */
+ void CheckPuppet(Actor *puppet, ieDword type);
/** Re/Inits the Modified vector */
void RefreshEffects(EffectQueue *eqfx);
/** gets saving throws */
@@ -404,7 +441,9 @@ public:
/** returns a saving throw */
bool GetSavingThrow(ieDword type, int modifier);
/** Returns true if the actor is targetable */
- bool ValidTarget(int ga_flags) const;
+ bool ValidTarget(int ga_flags, Scriptable *checker = NULL) const;
+ /** Clamps a stat value to the valid range for the respective stat */
+ ieDword ClampStat(unsigned int StatIndex, ieDword Value) const;
/** Returns a Stat value */
ieDword GetStat(unsigned int StatIndex) const;
/** Returns a safe Stat value, one, that is not partially computed */
@@ -450,7 +489,8 @@ public:
ieDword GetXPLevel(int modified) const;
/** Guesses the (base) casting level */
ieDword GetCasterLevel(int spelltype);
- ieDword GetBaseCasterLevel(int spelltype) const;
+ ieDword GetBaseCasterLevel(int spelltype, int flags=0) const;
+ ieDword GetAnyActiveCasterLevel() const;
/** Returns the wild mage casting level modifier */
int GetWildMod(int level);
/** Returns any casting level modifier */
@@ -471,14 +511,20 @@ public:
}
void SetName(const char* ptr, unsigned char type);
void SetName(int strref, unsigned char type);
- /* returns carried weight atm, could calculate with strength*/
- int GetEncumbrance();
+ /* calculates speed, encumbrance etc */
+ int CalculateSpeed(bool feedback);
/* checks on death of actor, returns true if it should be removed*/
bool CheckOnDeath();
/* receives undead turning message */
void Turn(Scriptable *cleric, ieDword turnlevel);
/* call this on gui selects */
- void SelectActor();
+ void PlaySelectionSound();
+ /* call this when adding actions via gui */
+ void CommandActor();
+ /** handle panic and other involuntary actions that mess with scripting */
+ bool OverrideActions();
+ /** handle idle actions, that shouldn't mess with scripting */
+ void IdleActions(bool nonidle);
/* sets the actor in panic (turn/morale break) */
void Panic(Scriptable *attacker, int panicmode);
/* sets a multi class flag (actually this is a lot of else too) */
@@ -488,19 +534,31 @@ public:
/* returns a remapped verbal constant strref */
ieStrRef GetVerbalConstant(int index) const;
/* displaying a random verbal constant */
- void VerbalConstant(int start, int count);
+ void VerbalConstant(int start, int count) const;
+ /* display string or verbal constant depending on what is available */
+ void DisplayStringOrVerbalConstant(int str, int vcstat, int vccount) const;
/* inlined dialogue response */
- void Response(int type);
+ void Response(int type) const;
/* called when someone died in the party */
void ReactToDeath(const char *deadname);
+ /* sends trigger_died to everyone in visual range */
+ void SendDiedTrigger();
/* called when someone talks to Actor */
void DialogInterrupt();
/* called when actor was hit */
- void GetHit();
+ void GetHit(int damage=0, int spellLevel=0);
+ /* checks whether concentration cancels damage taken disrupting casting */
+ bool CheckCastingInterrupt(int damage, int spellLevel);
/* called when actor starts to cast a spell*/
- bool HandleCastingStance(const ieResRef SpellResRef, bool deplete);
+ bool HandleCastingStance(const ieResRef SpellResRef, bool deplete, bool instant);
+ /* check if the actor should be just knocked out by a lethal hit */
+ bool AttackIsStunning(int damagetype) const;
+ /* check if the actor is silenced - for casting purposes */
+ bool CheckSilenced();
+ /* check and perform a cleave movement */
+ void CheckCleave();
/* deals damage to this actor */
- int Damage(int damage, int damagetype, Scriptable *hitter, int modtype=MOD_ADDITIVE);
+ int Damage(int damage, int damagetype, Scriptable *hitter, int modtype=MOD_ADDITIVE, int critical=0, int saveflags=0);
/* displays the damage taken and other details (depends on the game type) */
void DisplayCombatFeedback (unsigned int damage, int resisted, int damagetype, Scriptable *hitter);
/* play a random footstep sound */
@@ -547,14 +605,14 @@ public:
/* returns the ranged weapon header associated with the currently equipped projectile */
ITMExtHeader *GetRangedWeapon(WeaponInfo &wi) const;
/* Returns current weapon range and extended header
- if range is nonzero, then which is valid */
+ if range is nonzero, then which is valid */
ITMExtHeader* GetWeapon(WeaponInfo &wi, bool leftorright=false) const;
/* Creates player statistics */
void CreateStats();
- /* Heals actor by days */
- void Heal(int days);
+ /* Heals actor */
+ void Heal(int hp);
/* Receive experience (handle dual/multi class) */
- void AddExperience(int exp);
+ void AddExperience(int exp, int combat);
/* Calculate experience bonus */
int CalculateExperience(int type, int level);
/* Sets the modal state after checks */
@@ -565,27 +623,40 @@ public:
int GetAttackStyle() const;
/* adds the combatants to the attackers list */
void AttackedBy(Actor *actor);
- /* sets target for immediate attack */
- void SetTarget( Scriptable *actor);
+ /* reorients to face target (for immediate attack) */
+ void FaceTarget(Scriptable *actor);
+ /* returns the number of attacks (handles monk barehanded bonus) */
+ ieDword GetNumberOfAttacks();
/* starts combat round*/
void InitRound(ieDword gameTime);
/* returns melee penalty */
int MeleePenalty() const;
/* gets the to hit value */
- int GetToHit(int bonus, ieDword Flags, Actor *target) const;
+ int GetToHit(ieDword Flags, Actor* target);
+ void GetTHAbilityBonus(ieDword Flags);
/* gets the defense against an attack */
- int GetDefense(int DamageType, Actor *attacker) const;
+ int GetDefense(int DamageType, ieDword wflags, Actor *attacker);
+ /* checks if something is wrong with the weapon we are using for the attack */
+ bool WeaponIsUsable(bool leftorright, ITMExtHeader *header=NULL) const;
/* get the current hit bonus */
bool GetCombatDetails(int &tohit, bool leftorright, WeaponInfo &wi, ITMExtHeader *&header, ITMExtHeader *&hittingheader,\
- ieDword &Flags, int &DamageBonus, int &speed, int &CriticalBonus, int &style, Actor *target) const;
+ int &DamageBonus, int &speed, int &CriticalBonus, int &style, Actor *target);
/* performs attack against target */
void PerformAttack(ieDword gameTime);
- /* ensures we can deal damage to a target */
- void ModifyDamage(Actor *target, Scriptable *hitter, int &damage, int &resisted, int damagetype, WeaponInfo *wi, bool critical);
+ /* returns the adjusted weapon range, since items have odd values stored */
+ int GetWeaponRange(const WeaponInfo &wi) const;
+ /* filter out any damage reduction that is cancelled by high weapon enchantment and return the resulting resistance */
+ int GetDamageReduction(int resist_stat, ieDword weaponEnchantment) const;
+ /* calculates strength (dexterity) based damage adjustment */
+ int WeaponDamageBonus(const WeaponInfo &wi) const;
+ /* handles critical, backstab, etc. damage modifications */
+ void ModifyWeaponDamage(WeaponInfo &wi, Actor *target, int &damage, bool &critical);
+ /* adjusts damage dealt to this actor, handles mirror images */
+ void ModifyDamage(Scriptable *hitter, int &damage, int &resisted, int damagetype);
/* applies modal spell etc, if needed */
void UpdateActorState(ieDword gameTime);
/* returns the hp adjustment based on constitution */
- int GetHpAdjustment(int multiplier);
+ int GetHpAdjustment(int multiplier) const;
/* does all the housekeeping after loading the actor from file */
void InitStatsOnLoad();
/* sets a colour gradient stat, handles location */
@@ -594,7 +665,7 @@ public:
void SetColorMod( ieDword location, RGBModifier::Type type, int speed,
unsigned char r, unsigned char g, unsigned char b,
int phase=-1 );
- bool Schedule(ieDword gametime, bool checkhide);
+ bool Schedule(ieDword gametime, bool checkhide) const;
/* call this when path needs to be changed */
void NewPath();
/* overridden method, won't walk if dead */
@@ -603,10 +674,18 @@ public:
void ResolveStringConstant(ieResRef sound, unsigned int index) const;
void GetSoundFromINI(ieResRef Sound, unsigned int index) const;
void GetSoundFrom2DA(ieResRef Sound, unsigned int index) const;
+ /* generate area specific oneliner */
+ void GetAreaComment(int areaflag) const;
+ /* handle oneliner interaction, -1: unsuccessful (may comment area), 0: dialog banter, 1: oneliner */
+ int HandleInteract(Actor *target);
+ /* generate party banter, return true if successful */
+ bool GetPartyComment();
/* sets the quick slots */
void SetActionButtonRow(ActionButtonRow &ar);
/* updates the quick slots */
void GetActionButtonRow(ActionButtonRow &qs);
+ /* converts the iwd2 qslot index to our internal representation */
+ int IWD2GemrbQslot (int slotindex);
/* Handling automatic stance changes */
bool HandleActorStance();
@@ -622,11 +701,14 @@ public:
void RemoveVVCell(const ieResRef vvcname, bool graceful);
/* returns true if actor already has the overlay (slow) */
bool HasVVCCell(const ieResRef resource) const;
+ /* returns overlay (or underlay) if actor already has it, faster */
+ ScriptedAnimation *GetVVCCell(const vvcVector *vvcCells, const ieResRef resource) const;
/* returns overlay if actor already has it (slow) */
ScriptedAnimation *GetVVCCell(const ieResRef resource) const;
/* returns the vvc pointer to a hardcoded overlay */
/* if it exists (faster than hasvvccell) */
ScriptedAnimation *FindOverlay(int index) const;
+ int WantDither() const;
/* draw videocells */
void DrawVideocells(const Region &screen, vvcVector &vvcCells, const Color &tint);
@@ -635,6 +717,15 @@ public:
void AddAnimation(const ieResRef resource, int gradient, int height, int flags);
/* plays damage animation, if hit is not set, then plays only the splash part */
void PlayDamageAnimation(int x, bool hit=true);
+ void PlayCritDamageAnimation(int x);
+ /* returns mage or cleric spell casting failure, iwd2 compatible */
+ ieDword GetSpellFailure(bool arcana) const;
+ /* returns the dexterity AC adjusted by armor, iwd2 compatible */
+ int GetDexterityAC() const;
+ /* returns the monk wisdom AC adjusted by armor (iwd2) */
+ int GetWisdomAC() const;
+ /* PST specific criticals */
+ int GetCriticalType() const;
/* restores a spell of maximum maxlevel level, type is a mask of disabled spells */
int RestoreSpellLevel(ieDword maxlevel, ieDword typemask);
/* rememorizes spells, cures fatigue, etc */
@@ -659,10 +750,13 @@ public:
/* initialize the action buttons based on class. If forced, it will override
previously customized or set buttons. */
void InitButtons(ieDword cls, bool forced);
- int GetAbilityBonus(unsigned int ability) const;
+ int GetMaxEncumbrance() const;
+ int GetAbilityBonus(unsigned int ability, int value = -1) const;
+ int GetSkillStat(unsigned int skill) const;
int GetSkill(unsigned int skill) const;
int GetFeat(unsigned int feat) const;
void SetFeat(unsigned int feat, int mode);
+ void SetFeatValue(unsigned int feat, int value);
void SetUsedWeapon(const char *AnimationType, ieWord *MeleeAnimation,
int WeaponType=-1);
void SetUsedShield(const char *AnimationType, int WeaponType=-1);
@@ -688,6 +782,10 @@ public:
ieDword ImmuneToProjectile(ieDword projectile) const;
/* Sets projectile immunity */
void AddProjectileImmunity(ieDword projectile);
+ /* Apply feats */
+ void ApplyFeats();
+ /* reapply modal feat spells */
+ void ApplyExtraSettings();
/* Set up all the missing stats on load time, chargen, or after level up */
void CreateDerivedStats();
/* Checks if the actor is multiclassed (excluding dualclassed actors)) */
@@ -720,7 +818,7 @@ public:
void UseExit(ieDword exitID);
//int GetReaction() const;
/* Similar to Roll, but takes luck into account */
- int LuckyRoll(int dice, int size, int add, ieDword flags=1, Actor* opponent=NULL) const;
+ int LuckyRoll(int dice, int size, int add, ieDword flags=LR_CRITICAL, Actor* opponent=NULL) const;
/* removes normal invisibility (type 0) */
void CureInvisibility();
/* removes sanctuary */
@@ -730,21 +828,57 @@ public:
/* checks whether the actor is behind the target */
bool IsBehind(Actor* target) const;
/* checks whether the target is the actor's racial enemy */
- bool IsRacialEnemy(Actor* target) const;
+ int GetRacialEnemyBonus(Actor* target) const;
/* checks whether the actor can stay in the current modal state */
bool ModalSpellSkillCheck();
+ /* check if this actor is seen by or seeing anyone */
+ bool SeeAnyOne(bool enemy, bool seen);
/* does all the game logic checks to see if the actor can hide */
bool TryToHide();
+ bool TryToHideIWD2();
/* checks if the alignment matches one of the masking constants */
//bool MatchesAlignmentMask(ieDword mask);
- /* returns true if this actor is untargetable */
+ /** untargetable by spells/attack due to invisibility or sanctuary */
+ bool Untargetable();
+ /* returns true if this it is futile to try to harm actor (dead/sanctuaried) */
bool InvalidSpellTarget() const;
/* returns true if the spell is useless to cast on target
or the spell's range is smaller than range */
bool InvalidSpellTarget(int spellnum, Actor *caster, int range) const;
/* returns true if the lightmap under the actor is dark */
bool PCInDark() const;
+ /* function to get a class level used by scripting */
+ ieDword GetLevelInClass (const ieDword classid) const;
/* computes the actor's classmask (iwd2) */
int GetClassMask() const;
+ /* computes the actor's usable books (iwd2) */
+ int GetBookMask() const;
+ /* computes the thieving skill bonus from race and dexterity */
+ int GetSkillBonus(unsigned int col) const;
+ /* returns true for party members (and familiars) */
+ bool IsPartyMember() const;
+ /* resets the bored and area comment timers */
+ void ResetCommentTime();
+ /* returns the armor check penalty */
+ int GetArmorSkillPenalty(int profcheck=1) const;
+ int GetArmorSkillPenalty(int profcheck, int &armor, int &shield) const;
+ int GetTotalArmorFailure() const;
+ int GetArmorFailure(int &armor, int &shield) const;
+ bool IsDead() const;
+ bool IsInvisibleTo(Scriptable *checker) const;
+ int UpdateAnimationID(bool derived);
+ void MovementCommand(char *command);
+ /* shows hp/maxhp as overhead text */
+ void DisplayHeadHPRatio();
+ /* if Lasttarget is gone, call this */
+ void StopAttack();
+ int SetBaseAPRandAB(bool CheckRapidShot);
+ int BAB2APR(int pBAB, int pBABDecrement, int CheckRapidShot) const;
+ /* set to trap id if current action is disarm; unset after */
+ void SetDisarmingTrap(ieDword trapId) { disarmTrap = trapId; }
+ ieDword GetDisarmingTrap() const { return disarmTrap; }
+ void ReleaseCurrentAction();
};
+}
+
#endif
diff --git a/gemrb/core/Scriptable/CombatInfo.cpp b/gemrb/core/Scriptable/CombatInfo.cpp
new file mode 100644
index 0000000..5e9b518
--- /dev/null
+++ b/gemrb/core/Scriptable/CombatInfo.cpp
@@ -0,0 +1,332 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2012 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "CombatInfo.h"
+
+#include "Interface.h"
+#include "System/StringBuffer.h"
+#include "Scriptable/Actor.h"
+
+namespace GemRB {
+
+static bool third = false;
+
+/*
+ * Shared code between the classes
+ */
+static void SetBonusInternal(int& current, int bonus, int mod)
+{
+ int newBonus = current;
+
+ switch (mod) {
+ case 0: // cummulative modifier
+ if (third) {
+ // 3ed boni don't stack
+ // but, use some extra logic so any negative boni first try to cancel out
+ int tmp = bonus;
+ if ((current < 0) ^ (bonus < 0)) {
+ tmp = current + bonus;
+ }
+ if (tmp != bonus) {
+ // we just summed the boni, so we need to be careful about the resulting sign, since (-2+3)>(-2), but abs(-2+3)<abs(-2)
+ if (tmp > current) {
+ newBonus = tmp;
+ } // else leave it be at the current value
+ } else {
+ if (abs(tmp) > abs(current)) {
+ newBonus = tmp;
+ } // else leave it be at the current value
+ }
+ } else {
+ newBonus += bonus;
+ }
+ break;
+ // like with other effects, the following options have chicked-and-egg problems and the result depends on the order of application
+ case 1: // flat modifier
+ newBonus = bonus;
+ break;
+ case 2: // percent modifier
+ newBonus = current * bonus / 100;
+ break;
+ default:
+ error("CombatInfo", "Bad bonus mod type: %d", mod);
+ break;
+ }
+
+ current = newBonus;
+}
+
+
+/*
+ * Class holding the main armor class stat and general boni
+ */
+ArmorClass::ArmorClass()
+{
+ natural = 0;
+ Owner = NULL;
+ ResetAll();
+
+ third = !!core->HasFeature(GF_3ED_RULES);
+}
+
+void ArmorClass::SetOwner( Actor* owner)
+{
+ Owner = owner;
+ // rerun this, so both the stats get set correctly
+ SetNatural(natural);
+}
+
+int ArmorClass::GetTotal() const
+{
+ return total;
+}
+
+void ArmorClass::RefreshTotal()
+{
+ total = natural + deflectionBonus + armorBonus + shieldBonus + dexterityBonus + wisdomBonus + genericBonus;
+ // add a maximum_values[IE_ARMORCLASS] check here if needed
+ if (Owner) { // not true for a short while during init, but we make amends immediately
+ Owner->Modified[IE_ARMORCLASS] = total;
+ }
+}
+
+// resets all the boni (natural is skipped, since it holds the base value)
+void ArmorClass::ResetAll() {
+ deflectionBonus = 0;
+ armorBonus = 0;
+ shieldBonus = 0;
+ dexterityBonus = 0;
+ wisdomBonus = 0;
+ genericBonus = 0;
+ RefreshTotal();
+}
+
+void ArmorClass::SetNatural(int AC, int /*mod*/)
+{
+ natural = AC;
+ if (Owner) { // not true for a short while during init, but we make amends immediately
+ Owner->BaseStats[IE_ARMORCLASS] = AC;
+ }
+ RefreshTotal();
+}
+
+void ArmorClass::SetDeflectionBonus(int bonus, int mod)
+{
+ SetBonus(deflectionBonus, bonus, mod);
+}
+
+void ArmorClass::SetArmorBonus(int bonus, int mod)
+{
+ SetBonus(armorBonus, bonus, mod);
+}
+
+void ArmorClass::SetShieldBonus(int bonus, int mod)
+{
+ SetBonus(shieldBonus, bonus, mod);
+}
+
+void ArmorClass::SetDexterityBonus(int bonus, int mod)
+{
+ SetBonus(dexterityBonus, bonus, mod);
+}
+
+void ArmorClass::SetWisdomBonus(int bonus, int mod)
+{
+ SetBonus(wisdomBonus, bonus, mod);
+}
+
+void ArmorClass::SetGenericBonus(int bonus, int mod)
+{
+ SetBonus(genericBonus, bonus, mod);
+}
+
+void ArmorClass::SetBonus(int& current, int bonus, int mod)
+{
+ SetBonusInternal(current, bonus, mod);
+ RefreshTotal();
+}
+
+void ArmorClass::HandleFxBonus(int mod, bool permanent)
+{
+ if (permanent) {
+ if (Owner->IsReverseToHit()) {
+ SetNatural(natural-mod);
+ } else {
+ SetNatural(natural+mod);
+ }
+ return;
+ }
+ // this was actually aditively modifying Modified directly before
+ if (Owner->IsReverseToHit()) {
+ SetGenericBonus(-mod, 0);
+ } else {
+ SetGenericBonus(mod, 0);
+ }
+}
+
+void ArmorClass::dump() const
+{
+ StringBuffer buffer;
+ buffer.appendFormatted("Debugdump of ArmorClass of %s:\n", Owner->GetName(1));
+ buffer.appendFormatted("TOTAL: %d\n", total);
+ buffer.appendFormatted("Natural: %d\tGeneric: %d\tDeflection: %d\n", natural, genericBonus, deflectionBonus);
+ buffer.appendFormatted("Armor: %d\tShield: %d\n", armorBonus, shieldBonus);
+ buffer.appendFormatted("Dexterity: %d\tWisdom: %d\n\n", dexterityBonus, wisdomBonus);
+ Log(DEBUG, "ArmorClass", buffer);
+}
+
+/*
+ * Class holding the main to-hit/thac0 stat and general boni
+ * NOTE: Always use it through GetCombatDetails to get the full state
+ */
+ToHitStats::ToHitStats()
+{
+ base = 0;
+ babDecrement = 0;
+ Owner = NULL;
+ ResetAll();
+
+ third = !!core->HasFeature(GF_3ED_RULES);
+}
+
+void ToHitStats::SetOwner(Actor* owner)
+{
+ Owner = owner;
+ // rerun this, so both the stats get set correctly
+ SetBase(base);
+}
+
+int ToHitStats::GetTotal() const
+{
+ return total;
+}
+
+void ToHitStats::RefreshTotal()
+{
+ total = base + proficiencyBonus + armorBonus + shieldBonus + abilityBonus + weaponBonus + genericBonus;
+ if (Owner) { // not true for a short while during init, but we make amends immediately
+ Owner->Modified[IE_TOHIT] = total;
+ }
+}
+
+// resets all the boni
+void ToHitStats::ResetAll() {
+ weaponBonus = 0;
+ armorBonus = 0;
+ shieldBonus = 0;
+ abilityBonus = 0;
+ proficiencyBonus = 0;
+ genericBonus = 0;
+ RefreshTotal();
+}
+
+void ToHitStats::SetBase(int tohit, int /*mod*/)
+{
+ base = tohit;
+ if (Owner) { // not true for a short while during init, but we make amends immediately
+ Owner->BaseStats[IE_TOHIT] = tohit;
+ }
+ RefreshTotal();
+}
+
+void ToHitStats::SetProficiencyBonus(int bonus, int mod)
+{
+ SetBonus(proficiencyBonus, bonus, mod);
+}
+
+void ToHitStats::SetArmorBonus(int bonus, int mod)
+{
+ SetBonus(armorBonus, bonus, mod);
+}
+
+void ToHitStats::SetShieldBonus(int bonus, int mod)
+{
+ SetBonus(shieldBonus, bonus, mod);
+}
+
+void ToHitStats::SetAbilityBonus(int bonus, int mod)
+{
+ SetBonus(abilityBonus, bonus, mod);
+}
+
+void ToHitStats::SetWeaponBonus(int bonus, int mod)
+{
+ SetBonus(weaponBonus, bonus, mod);
+}
+
+void ToHitStats::SetGenericBonus(int bonus, int mod)
+{
+ SetBonus(genericBonus, bonus, mod);
+}
+
+void ToHitStats::SetBonus(int& current, int bonus, int mod)
+{
+ SetBonusInternal(current, bonus, mod);
+ RefreshTotal();
+}
+
+void ToHitStats::HandleFxBonus(int mod, bool permanent)
+{
+ if (permanent) {
+ if (Owner->IsReverseToHit()) {
+ SetBase(base-mod);
+ } else {
+ SetBase(base+mod);
+ }
+ return;
+ }
+ // this was actually aditively modifying Modified directly before
+ if (Owner->IsReverseToHit()) {
+ SetGenericBonus(-mod, 0);
+ } else {
+ SetGenericBonus(mod, 0);
+ }
+}
+
+void ToHitStats::SetBABDecrement(int decrement) {
+ babDecrement = decrement;
+}
+
+int ToHitStats::GetTotalForAttackNum(unsigned int number) const
+{
+ if (number <= 1) { // out of combat, we'd get 0 and that's fine
+ return total;
+ }
+ number--;
+ // compute the cascaded values
+ // only base tohit affects the number of attacks (Actor::GetBaseAPRandAB),
+ // so make sure the other boni don't grant new ones if called with a too high number
+ assert((base-(signed)number*babDecrement) >= 0);
+ return total-number*babDecrement;
+}
+
+void ToHitStats::dump() const
+{
+ StringBuffer buffer;
+ buffer.appendFormatted("Debugdump of ToHit of %s:\n", Owner->GetName(1));
+ buffer.appendFormatted("TOTAL: %d\n", total);
+ buffer.appendFormatted("Base: %2d\tGeneric: %d\tAbility: %d\n", base, genericBonus, abilityBonus);
+ buffer.appendFormatted("Armor: %d\tShield: %d\n", armorBonus, shieldBonus);
+ buffer.appendFormatted("Weapon: %d\tProficiency: %d\n\n", weaponBonus, proficiencyBonus);
+ Log(DEBUG, "ToHit", buffer);
+}
+
+
+}
diff --git a/gemrb/core/Scriptable/CombatInfo.h b/gemrb/core/Scriptable/CombatInfo.h
new file mode 100644
index 0000000..b0686f8
--- /dev/null
+++ b/gemrb/core/Scriptable/CombatInfo.h
@@ -0,0 +1,131 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2012 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+// convenience classes for storing the complex armor class, to-hit and other combat state
+
+#ifndef COMBATINFO_H
+#define COMBATINFO_H
+
+#include "exports.h"
+
+namespace GemRB {
+
+class Actor;
+
+class GEM_EXPORT ArmorClass {
+public:
+ ArmorClass();
+
+ int GetTotal() const;
+ int GetNatural() const { return natural; };
+ int GetDeflectionBonus() const { return deflectionBonus; };
+ int GetArmorBonus() const { return armorBonus; };
+ int GetShieldBonus() const { return shieldBonus; };
+ int GetDexterityBonus() const { return dexterityBonus; };
+ int GetWisdomBonus() const { return wisdomBonus; };
+ int GetGenericBonus() const { return genericBonus; };
+
+ void ResetAll();
+ void SetOwner(Actor *owner);
+ // no total, it is always kept up to date with RefreshTotal
+ void SetNatural(int AC, int mod=1);
+ void SetDeflectionBonus(int bonus, int mod=1);
+ void SetArmorBonus(int bonus, int mod=1);
+ void SetShieldBonus(int bonus, int mod=1);
+ void SetDexterityBonus(int bonus, int mod=1);
+ void SetWisdomBonus(int bonus, int mod=1);
+ void SetGenericBonus(int bonus, int mod=1);
+
+ void HandleFxBonus(int mod, bool permanent);
+ void dump() const;
+
+private:
+ Actor *Owner;
+ int total; // modified stat
+ int natural; // base stat
+
+ int deflectionBonus;
+ int armorBonus;
+ int shieldBonus;
+ int dexterityBonus;
+ int wisdomBonus;
+ int genericBonus; // the iwd2 dodge bonus was also just applied here and is not a separate value
+ // NOTE: some are currently left out, like BonusAgainstCreature and all the real separate AC-mod stats
+ // (in case of change) recheck all the introduced GetTotal()s with this in mind - before they were Modified[IE_ARMORCLASS] only
+
+ void SetBonus(int ¤t, int bonus, int mod);
+ void RefreshTotal();
+};
+
+
+class GEM_EXPORT ToHitStats {
+public:
+ ToHitStats();
+
+ int GetTotal() const;
+ int GetBase() const { return base; };
+ int GetWeaponBonus() const { return weaponBonus; };
+ int GetArmorBonus() const { return armorBonus; };
+ int GetShieldBonus() const { return shieldBonus; };
+ int GetAbilityBonus() const { return abilityBonus; };
+ int GetProficiencyBonus() const { return proficiencyBonus; };
+ int GetGenericBonus() const { return genericBonus; };
+
+ // returns the value of the cascade for the specified attack
+ // eg. one of +11/+6/+1 for 1,2,3
+ int GetTotalForAttackNum(unsigned int number) const;
+
+ void ResetAll();
+ void SetOwner(Actor *owner);
+ // no total, it is always kept up to date with RefreshTotal
+ void SetBase(int tohit, int mod=1);
+ void SetProficiencyBonus(int bonus, int mod=1);
+ void SetArmorBonus(int bonus, int mod=1);
+ void SetShieldBonus(int bonus, int mod=1);
+ void SetAbilityBonus(int bonus, int mod=1);
+ void SetWeaponBonus(int bonus, int mod=1);
+ void SetGenericBonus(int bonus, int mod=1);
+
+ void SetBABDecrement(int decrement);
+ void HandleFxBonus(int mod, bool permanent);
+ void dump() const;
+
+private:
+ Actor *Owner;
+ int total; // modified stat, now really containing all the boni
+ int base; // base stat
+ int babDecrement; // 3ed, used for calculating the tohit value of succeeding attacks
+
+ // to-hit boni
+ int weaponBonus;
+ int armorBonus; // this is a malus
+ int shieldBonus; // this is a malus
+ int abilityBonus;
+ int proficiencyBonus;
+ int genericBonus; // "other"
+
+ void SetBonus(int ¤t, int bonus, int mod);
+ void RefreshTotal();
+};
+
+
+}
+
+#endif
diff --git a/gemrb/core/Scriptable/Container.cpp b/gemrb/core/Scriptable/Container.cpp
index e2f6757..287078c 100644
--- a/gemrb/core/Scriptable/Container.cpp
+++ b/gemrb/core/Scriptable/Container.cpp
@@ -31,15 +31,19 @@
#include "Map.h"
#include "Projectile.h"
#include "Spell.h"
+#include "Sprite2D.h"
#include "SpriteCover.h"
#include "TileMap.h"
#include "Video.h"
#include "GameScript/GSUtils.h"
#include "GUI/GameControl.h"
+#include "System/StringBuffer.h"
#include <cassert>
#include <cmath>
+namespace GemRB {
+
#define YESNO(x) ( (x)?"Yes":"No")
Container::Container(void)
@@ -168,8 +172,8 @@ void Container::DestroyContainer()
CREItem *Container::RemoveItem(unsigned int idx, unsigned int count)
{
CREItem *ret = inventory.RemoveItem(idx, count);
- //we just took the 3. or less item, groundpile changed
- if ((Type == IE_CONTAINER_PILE) && (inventory.GetSlotCount()<3)) {
+ //if we just took one of the first few items, groundpile changed
+ if ((Type == IE_CONTAINER_PILE) && (idx<MAX_GROUND_ICON_DRAWN)) {
RefreshGroundIcons();
}
return ret;
@@ -181,7 +185,7 @@ int Container::AddItem(CREItem *item)
{
inventory.AddItem(item);
//we just added a 3. or less item, groundpile changed
- if ((Type == IE_CONTAINER_PILE) && (inventory.GetSlotCount()<4)) {
+ if ((Type == IE_CONTAINER_PILE) && (inventory.GetSlotCount()<=MAX_GROUND_ICON_DRAWN)) {
RefreshGroundIcons();
}
return 2;
@@ -196,6 +200,7 @@ void Container::RefreshGroundIcons()
while (i--) {
CREItem *slot = inventory.GetSlotItem(i); //borrowed reference
Item *itm = gamedata->GetItem( slot->ItemResRef ); //cached reference
+ if (!itm) continue;
//well, this is required in PST, needs more work if some other
//game is broken by not using -1,0
groundicons[i] = gamedata->GetBAMSprite( itm->GroundIcon, 0, 0 );
@@ -226,20 +231,30 @@ void Container::TryPickLock(Actor *actor)
{
if (LockDifficulty == 100) {
if (OpenFail != (ieDword)-1) {
- displaymsg->DisplayStringName(OpenFail, 0xbcefbc, actor, IE_STR_SOUND|IE_STR_SPEECH);
+ displaymsg->DisplayStringName(OpenFail, DMC_BG2XPGREEN, actor, IE_STR_SOUND|IE_STR_SPEECH);
} else {
- displaymsg->DisplayConstantStringName(STR_CONT_NOPICK, 0xbcefbc, actor);
+ displaymsg->DisplayConstantStringName(STR_CONT_NOPICK, DMC_BG2XPGREEN, actor);
}
return;
}
- if (actor->GetStat(IE_LOCKPICKING)<LockDifficulty) {
- displaymsg->DisplayConstantStringName(STR_LOCKPICK_FAILED, 0xbcefbc, actor);
- LastPickLockFailed = actor->GetGlobalID();
+ int stat = actor->GetStat(IE_LOCKPICKING);
+ if (core->HasFeature(GF_3ED_RULES)) {
+ stat *= 7; // convert to percent (magic 7 is from RE)
+ int dexmod = actor->GetAbilityBonus(IE_DEX);
+ stat += dexmod; // the original didn't use it, so let's not multiply it
+ displaymsg->DisplayRollStringName(39301, DMC_LIGHTGREY, actor, stat-dexmod, LockDifficulty, dexmod);
+ }
+ if (stat < LockDifficulty) {
+ displaymsg->DisplayConstantStringName(STR_LOCKPICK_FAILED, DMC_BG2XPGREEN, actor);
+ AddTrigger(TriggerEntry(trigger_picklockfailed, actor->GetGlobalID()));
+ core->PlaySound(DS_PICKFAIL); //AMB_D21
return;
}
SetContainerLocked(false);
- displaymsg->DisplayConstantStringName(STR_LOCKPICK_DONE, 0xd7d7be, actor);
- LastUnlocked = actor->GetGlobalID();
+ core->GetGameControl()->ResetTargetMode();
+ displaymsg->DisplayConstantStringName(STR_LOCKPICK_DONE, DMC_LIGHTGREY, actor);
+ AddTrigger(TriggerEntry(trigger_unlocked, actor->GetGlobalID()));
+ core->PlaySound(DS_PICKLOCK); //AMB_D21D
ImmediateEvent();
int xp = actor->CalculateExperience(XP_LOCKPICK, actor->GetXPLevel(1));
Game *game = core->GetGame();
@@ -249,39 +264,55 @@ void Container::TryPickLock(Actor *actor)
void Container::TryBashLock(Actor *actor)
{
//Get the strength bonus agains lock difficulty
- int str = actor->GetStat(IE_STR);
- int strEx = actor->GetStat(IE_STREXTRA);
- unsigned int bonus = core->GetStrengthBonus(2, str, strEx); //BEND_BARS_LIFT_GATES
+ int bonus;
+
+ if (core->HasFeature(GF_3ED_RULES)) {
+ bonus = actor->GetAbilityBonus(IE_STR);
+ } else {
+ int str = actor->GetStat(IE_STR);
+ int strEx = actor->GetStat(IE_STREXTRA);
+ bonus = core->GetStrengthBonus(2, str, strEx); //BEND_BARS_LIFT_GATES
+ }
unsigned int roll = actor->LuckyRoll(1, 10, bonus, 0);
+ if (core->HasFeature(GF_3ED_RULES)) {
+ // ~Bash door check. Roll %d + %d Str mod > %d door DC.~
+ // there is no separate string for non-doors
+ displaymsg->DisplayRollStringName(20460, DMC_LIGHTGREY, actor, roll, bonus, LockDifficulty);
+ }
+
+ actor->FaceTarget(this);
if(roll < LockDifficulty || LockDifficulty == 100) {
- displaymsg->DisplayConstantStringName(STR_CONTBASH_FAIL, 0xbcefbc, actor);
+ displaymsg->DisplayConstantStringName(STR_CONTBASH_FAIL, DMC_BG2XPGREEN, actor);
return;
}
- displaymsg->DisplayConstantStringName(STR_CONTBASH_DONE, 0xd7d7be, actor);
+ displaymsg->DisplayConstantStringName(STR_CONTBASH_DONE, DMC_LIGHTGREY, actor);
SetContainerLocked(false);
+ core->GetGameControl()->ResetTargetMode();
//Is this really useful ?
- LastUnlocked = actor->GetGlobalID();
+ AddTrigger(TriggerEntry(trigger_unlocked, actor->GetGlobalID()));
ImmediateEvent();
}
-void Container::DebugDump() const
+void Container::dump() const
{
- printf( "Debugdump of Container %s\n", GetScriptName() );
- printf( "Container Global ID: %d\n", GetGlobalID());
- printf( "Position: %d.%d\n", Pos.x, Pos.y);
- printf( "Type: %d, Locked: %s, LockDifficulty: %d\n", Type, YESNO(Flags&CONT_LOCKED), LockDifficulty );
- printf( "Flags: %d, Trapped: %s, Detected: %d\n", Flags, YESNO(Trapped), TrapDetected );
- printf( "Trap detection: %d%%, Trap removal: %d%%\n", TrapDetectionDiff,
+ StringBuffer buffer;
+ buffer.appendFormatted( "Debugdump of Container %s\n", GetScriptName() );
+ buffer.appendFormatted( "Container Global ID: %d\n", GetGlobalID());
+ buffer.appendFormatted( "Position: %d.%d\n", Pos.x, Pos.y);
+ buffer.appendFormatted( "Type: %d, Locked: %s, LockDifficulty: %d\n", Type, YESNO(Flags&CONT_LOCKED), LockDifficulty );
+ buffer.appendFormatted( "Flags: %d, Trapped: %s, Detected: %d\n", Flags, YESNO(Trapped), TrapDetected );
+ buffer.appendFormatted( "Trap detection: %d%%, Trap removal: %d%%\n", TrapDetectionDiff,
TrapRemovalDiff );
const char *name = "NONE";
if (Scripts[0]) {
name = Scripts[0]->GetName();
}
- printf( "Script: %s, Key: %s\n", name, KeyResRef );
+ buffer.appendFormatted( "Script: %s, Key: %s\n", name, KeyResRef );
// FIXME: const_cast
- const_cast<Inventory&>(inventory).dump();
+ inventory.dump(buffer);
+ Log(DEBUG, "Container", buffer);
}
bool Container::TryUnlock(Actor *actor) {
@@ -290,3 +321,5 @@ bool Container::TryUnlock(Actor *actor) {
return Highlightable::TryUnlock(actor, false);
}
+
+}
diff --git a/gemrb/core/Scriptable/Container.h b/gemrb/core/Scriptable/Container.h
index 39fd7bb..4f7c6f0 100644
--- a/gemrb/core/Scriptable/Container.h
+++ b/gemrb/core/Scriptable/Container.h
@@ -21,12 +21,15 @@
#ifndef CONTAINER_H
#define CONTAINER_H
-#include "Scriptable.h"
+#include "Inventory.h"
+#include "Scriptable/Scriptable.h"
+
+namespace GemRB {
//container flags
#define CONT_LOCKED 1
#define CONT_RESET 8
-#define CONT_DISABLED 32
+#define CONT_DISABLED (32|128) //bg2 and pst uses different bits, luckily they are not overlapping
class GEM_EXPORT Container : public Highlightable {
public:
@@ -47,7 +50,7 @@ public:
void TryPickLock(Actor *actor);
void TryBashLock(Actor* actor) ;
bool TryUnlock(Actor *actor);
- void DebugDump() const;
+ void dump() const;
int TrapResets() const { return Flags & CONT_RESET; }
private:
//updates the ground icons for a pile
@@ -67,4 +70,6 @@ public:
//keyresref is stored in Highlightable
};
+}
+
#endif
diff --git a/gemrb/core/Scriptable/Door.cpp b/gemrb/core/Scriptable/Door.cpp
index 33df7bd..1189d0b 100644
--- a/gemrb/core/Scriptable/Door.cpp
+++ b/gemrb/core/Scriptable/Door.cpp
@@ -37,10 +37,13 @@
#include "GameScript/GSUtils.h"
#include "GUI/GameControl.h"
#include "Scriptable/InfoPoint.h"
+#include "System/StringBuffer.h"
#include <cassert>
#include <cmath>
+namespace GemRB {
+
#define YESNO(x) ( (x)?"Yes":"No")
Door::Door(TileOverlay* Overlay)
@@ -105,23 +108,22 @@ void Door::UpdateDoor()
Pos.x = outline->BBox.x + outline->BBox.w/2;
Pos.y = outline->BBox.y + outline->BBox.h/2;
- unsigned char oval, cval;
- oval = PATH_MAP_IMPASSABLE;
+ unsigned char pmdflags;
+
if (Flags & DOOR_TRANSPARENT) {
- cval = PATH_MAP_DOOR_IMPASSABLE;
- }
- else {
+ pmdflags = PATH_MAP_DOOR_IMPASSABLE;
+ } else {
//both door flags are needed here, one for transparency the other
//is for passability
- cval = PATH_MAP_DOOR_OPAQUE|PATH_MAP_DOOR_IMPASSABLE;
+ pmdflags = PATH_MAP_DOOR_OPAQUE|PATH_MAP_DOOR_IMPASSABLE;
}
if (Flags &DOOR_OPEN) {
ImpedeBlocks(cibcount, closed_ib, 0);
- ImpedeBlocks(oibcount, open_ib, cval);
+ ImpedeBlocks(oibcount, open_ib, pmdflags);
}
else {
ImpedeBlocks(oibcount, open_ib, 0);
- ImpedeBlocks(cibcount, closed_ib, cval);
+ ImpedeBlocks(cibcount, closed_ib, pmdflags);
}
InfoPoint *ip = area->TMap->GetInfoPoint(LinkedInfo);
@@ -252,14 +254,22 @@ void Door::SetDoorOpen(int Open, int playsound, ieDword ID)
area->JumpActors(true);
}
if (Open) {
- LastEntered = ID; //used as lastOpener
+ if (Trapped) {
+ AddTrigger(TriggerEntry(trigger_opened, ID));
+ } else {
+ AddTrigger(TriggerEntry(trigger_harmlessopened, ID));
+ }
// in PS:T, opening a door does not unlock it
if (!core->HasFeature(GF_REVERSE_DOOR)) {
SetDoorLocked(false,playsound);
}
} else {
- LastTriggerObject = LastTrigger = ID; //used as lastCloser
+ if (Trapped) {
+ AddTrigger(TriggerEntry(trigger_closed, ID));
+ } else {
+ AddTrigger(TriggerEntry(trigger_harmlessclosed, ID));
+ }
}
ToggleTiles(Open, playsound);
//synchronising other data with the door state
@@ -277,13 +287,14 @@ bool Door::TryUnlock(Actor *actor) {
return Highlightable::TryUnlock(actor, removekey);
}
-void Door::TryDetectSecret(int skill)
+void Door::TryDetectSecret(int skill, ieDword actorID)
{
if (Type != ST_DOOR) return;
if (Visible()) return;
if (skill > (signed)DiscoveryDiff) {
Flags |= DOOR_FOUND;
core->PlaySound(DS_FOUNDSECRET);
+ AddTrigger(TriggerEntry(trigger_detected, actorID));
}
}
@@ -317,7 +328,7 @@ void Highlightable::SetTrapDetected(int x)
return;
TrapDetected = x;
if(TrapDetected) {
- core->Autopause(AP_TRAP);
+ core->Autopause(AP_TRAP, this);
}
}
@@ -325,20 +336,41 @@ void Highlightable::TryDisarm(Actor *actor)
{
if (!Trapped || !TrapDetected) return;
- LastTriggerObject = LastTrigger = actor->GetGlobalID();
int skill = actor->GetStat(IE_TRAPS);
+ int roll = 0;
+ int bonus = 0;
+ int trapDC = TrapRemovalDiff;
+
+ if (core->HasFeature(GF_3ED_RULES)) {
+ roll = core->Roll(1, 20, 0);
+ bonus = actor->GetAbilityBonus(IE_INT);
+ trapDC = TrapRemovalDiff/7 + 10; // oddity from the original
+ } else {
+ roll = core->Roll(1, skill/2, 0);
+ skill /= 2;
+ }
- if (skill/2+core->Roll(1,skill/2,0)>TrapRemovalDiff) {
- LastDisarmed = actor->GetGlobalID();
+ int check = skill + roll + bonus;
+ if (check > trapDC) {
+ AddTrigger(TriggerEntry(trigger_disarmed, actor->GetGlobalID()));
//trap removed
Trapped = 0;
- displaymsg->DisplayConstantStringName(STR_DISARM_DONE, 0xd7d7be, actor);
+ if (core->HasFeature(GF_3ED_RULES)) {
+ // ~Successful Disarm Device - d20 roll %d + Disarm Device skill %d + INT mod %d >= Trap DC %d~
+ displaymsg->DisplayRollStringName(39266, DMC_LIGHTGREY, actor, roll, skill-bonus, bonus, trapDC);
+ }
+ displaymsg->DisplayConstantStringName(STR_DISARM_DONE, DMC_LIGHTGREY, actor);
int xp = actor->CalculateExperience(XP_DISARM, actor->GetXPLevel(1));
Game *game = core->GetGame();
game->ShareXP(xp, SX_DIVIDE);
+ core->GetGameControl()->ResetTargetMode();
} else {
- displaymsg->DisplayConstantStringName(STR_DISARM_FAIL, 0xd7d7be, actor);
- TriggerTrap(skill, LastTrigger);
+ if (core->HasFeature(GF_3ED_RULES)) {
+ // ~Failed Disarm Device - d20 roll %d + Disarm Device skill %d + INT mod %d >= Trap DC %d~
+ displaymsg->DisplayRollStringName(39266, DMC_LIGHTGREY, actor, roll, skill-bonus, bonus, trapDC);
+ }
+ displaymsg->DisplayConstantStringName(STR_DISARM_FAIL, DMC_LIGHTGREY, actor);
+ TriggerTrap(skill, actor->GetGlobalID());
}
ImmediateEvent();
}
@@ -347,20 +379,30 @@ void Door::TryPickLock(Actor *actor)
{
if (LockDifficulty == 100) {
if (OpenStrRef != (ieDword)-1) {
- displaymsg->DisplayStringName(OpenStrRef, 0xbcefbc, actor, IE_STR_SOUND|IE_STR_SPEECH);
+ displaymsg->DisplayStringName(OpenStrRef, DMC_BG2XPGREEN, actor, IE_STR_SOUND|IE_STR_SPEECH);
} else {
- displaymsg->DisplayConstantStringName(STR_DOOR_NOPICK, 0xbcefbc, actor);
+ displaymsg->DisplayConstantStringName(STR_DOOR_NOPICK, DMC_BG2XPGREEN, actor);
}
return;
}
- if (actor->GetStat(IE_LOCKPICKING)<LockDifficulty) {
- displaymsg->DisplayConstantStringName(STR_LOCKPICK_FAILED, 0xbcefbc, actor);
- LastPickLockFailed = actor->GetGlobalID();
+ int stat = actor->GetStat(IE_LOCKPICKING);
+ if (core->HasFeature(GF_3ED_RULES)) {
+ stat *= 7; // convert to percent (magic 7 is from RE)
+ int dexmod = actor->GetAbilityBonus(IE_DEX);
+ stat += dexmod; // the original didn't use it, so let's not multiply it
+ displaymsg->DisplayRollStringName(39301, DMC_LIGHTGREY, actor, stat-dexmod, LockDifficulty, dexmod);
+ }
+ if (stat < (signed)LockDifficulty) {
+ displaymsg->DisplayConstantStringName(STR_LOCKPICK_FAILED, DMC_BG2XPGREEN, actor);
+ AddTrigger(TriggerEntry(trigger_picklockfailed, actor->GetGlobalID()));
+ core->PlaySound(DS_PICKFAIL);
return;
}
SetDoorLocked( false, true);
- displaymsg->DisplayConstantStringName(STR_LOCKPICK_DONE, 0xd7d7be, actor);
- LastUnlocked = actor->GetGlobalID();
+ core->GetGameControl()->ResetTargetMode();
+ displaymsg->DisplayConstantStringName(STR_LOCKPICK_DONE, DMC_LIGHTGREY, actor);
+ AddTrigger(TriggerEntry(trigger_unlocked, actor->GetGlobalID()));
+ core->PlaySound(DS_PICKLOCK);
ImmediateEvent();
int xp = actor->CalculateExperience(XP_LOCKPICK, actor->GetXPLevel(1));
Game *game = core->GetGame();
@@ -369,41 +411,61 @@ void Door::TryPickLock(Actor *actor)
void Door::TryBashLock(Actor *actor)
{
- //Get the strength bonus agains lock difficulty
- int str = actor->GetStat(IE_STR);
- int strEx = actor->GetStat(IE_STREXTRA);
- unsigned int bonus = core->GetStrengthBonus(2, str, strEx); //BEND_BARS_LIFT_GATES
+ //Get the strength bonus against lock difficulty
+ int bonus;
+
+ if (core->HasFeature(GF_3ED_RULES)) {
+ bonus = actor->GetAbilityBonus(IE_STR);
+ } else {
+ int str = actor->GetStat(IE_STR);
+ int strEx = actor->GetStat(IE_STREXTRA);
+ bonus = core->GetStrengthBonus(2, str, strEx); //BEND_BARS_LIFT_GATES
+ }
unsigned int roll = actor->LuckyRoll(1, 10, bonus, 0);
+ actor->FaceTarget(this);
+ if (core->HasFeature(GF_3ED_RULES)) {
+ // ~Bash door check. Roll %d + %d Str mod > %d door DC.~
+ displaymsg->DisplayRollStringName(20460, DMC_LIGHTGREY, actor, roll, bonus, LockDifficulty);
+ }
+
if(roll < LockDifficulty || LockDifficulty == 100) {
- displaymsg->DisplayConstantStringName(STR_DOORBASH_FAIL, 0xbcefbc, actor);
+ displaymsg->DisplayConstantStringName(STR_DOORBASH_FAIL, DMC_BG2XPGREEN, actor);
return;
}
- displaymsg->DisplayConstantStringName(STR_DOORBASH_DONE, 0xd7d7be, actor);
+ displaymsg->DisplayConstantStringName(STR_DOORBASH_DONE, DMC_LIGHTGREY, actor);
SetDoorLocked(false, true);
- //Is this really useful ?
- LastUnlocked = actor->GetGlobalID();
+ core->GetGameControl()->ResetTargetMode();
+ Flags|=DOOR_BROKEN;
+
+ //This is ok, bashdoor also sends the unlocked trigger
+ AddTrigger(TriggerEntry(trigger_unlocked, actor->GetGlobalID()));
ImmediateEvent();
}
-void Door::DebugDump() const
+void Door::dump() const
{
- printf( "Debugdump of Door %s:\n", GetScriptName() );
- printf( "Door Global ID: %d\n", GetGlobalID());
- printf( "Position: %d.%d\n", Pos.x, Pos.y);
- printf( "Door Open: %s\n", YESNO(IsOpen()));
- printf( "Door Locked: %s\n", YESNO(Flags&DOOR_LOCKED));
- printf( "Door Trapped: %s\n", YESNO(Trapped));
+ StringBuffer buffer;
+ buffer.appendFormatted( "Debugdump of Door %s:\n", GetScriptName() );
+ buffer.appendFormatted( "Door Global ID: %d\n", GetGlobalID());
+ buffer.appendFormatted( "Position: %d.%d\n", Pos.x, Pos.y);
+ buffer.appendFormatted( "Door Open: %s\n", YESNO(IsOpen()));
+ buffer.appendFormatted( "Door Locked: %s Difficulty: %d\n", YESNO(Flags&DOOR_LOCKED), LockDifficulty);
+ buffer.appendFormatted( "Door Trapped: %s Difficulty: %d\n", YESNO(Trapped), TrapRemovalDiff);
if (Trapped) {
- printf( "Trap Permanent: %s Detectable: %s\n", YESNO(Flags&DOOR_RESET), YESNO(Flags&DOOR_DETECTABLE) );
+ buffer.appendFormatted( "Trap Permanent: %s Detectable: %s\n", YESNO(Flags&DOOR_RESET), YESNO(Flags&DOOR_DETECTABLE) );
}
- printf( "Secret door: %s (Found: %s)\n", YESNO(Flags&DOOR_SECRET),YESNO(Flags&DOOR_FOUND));
+ buffer.appendFormatted( "Secret door: %s (Found: %s)\n", YESNO(Flags&DOOR_SECRET),YESNO(Flags&DOOR_FOUND));
const char *Key = GetKey();
const char *name = "NONE";
if (Scripts[0]) {
name = Scripts[0]->GetName();
}
- printf( "Script: %s, Key (%s) removed: %s, Dialog: %s\n", name, Key?Key:"NONE", YESNO(Flags&DOOR_KEY), Dialog );
+ buffer.appendFormatted( "Script: %s, Key (%s) removed: %s, Dialog: %s\n", name, Key?Key:"NONE", YESNO(Flags&DOOR_KEY), Dialog );
+
+ Log(DEBUG, "Door", buffer);
}
+
+}
diff --git a/gemrb/core/Scriptable/Door.h b/gemrb/core/Scriptable/Door.h
index 5d6e4db..70690b0 100644
--- a/gemrb/core/Scriptable/Door.h
+++ b/gemrb/core/Scriptable/Door.h
@@ -21,21 +21,30 @@
#ifndef DOOR_H
#define DOOR_H
-#include "Scriptable.h"
+#include "Scriptable/Scriptable.h"
+
+namespace GemRB {
+
+class TileOverlay;
//door flags
#define DOOR_OPEN 1
#define DOOR_LOCKED 2
#define DOOR_RESET 4 //reset trap
#define DOOR_DETECTABLE 8 //trap detectable
-#define DOOR_16 16 //unknown
-#define DOOR_32 32 //unknown
+#define DOOR_BROKEN 16 //door is broken (force opened)
+#define DOOR_CANTCLOSE 32 //from IE dev source
#define DOOR_LINKED 64 //info trigger linked to this door
#define DOOR_SECRET 128 //door is secret
#define DOOR_FOUND 256 //secret door found
-#define DOOR_TRANSPARENT 512 //obscures vision
-#define DOOR_KEY 1024 //key removed when used
-#define DOOR_SLIDE 2048 //impeded blocks ignored
+#define DOOR_TRANSPARENT 512 //obscures vision (LOCKEDINFOTEXT in iwd2)
+#define DOOR_KEY 1024 //key removed when used (SEETHROUGH in iwd2)
+#define DOOR_SLIDE 2048 //impeded blocks ignored (WARNINGINFOTEXT in iwd2)
+#define DOOR_WARNINGTEXTDISPLAYED 0x1000 // iwd2
+#define DOOR_HIDDEN 8192 // iwd2, ignore the door
+#define DOOR_USEUPKEY 0x4000 // treating as identical to DOOR_KEY
+#define DOOR_LOCKEDINFOTEXT 0x8000
+#define DOOR_WARNINGINFOTEXT 0x10000
class GEM_EXPORT Door : public Highlightable {
public:
@@ -71,7 +80,7 @@ public:
ieDword LockDifficulty; //this is a dword?
ieStrRef OpenStrRef;
ieStrRef NameStrRef;
- ieDword Unknown54; //unused in tob
+ ieWord hp, ac; //unused???, but learned from IE DEV info
private:
void SetWallgroups(int count, int value);
void ImpedeBlocks(int count, Point *points, unsigned char value);
@@ -88,11 +97,13 @@ public:
void TryPickLock(Actor *actor);
void TryBashLock(Actor* actor) ;
bool TryUnlock(Actor *actor);
- void TryDetectSecret(int skill);
+ void TryDetectSecret(int skill, ieDword actorID);
bool Visible();
- void DebugDump() const;
+ void dump() const;
int TrapResets() const { return Flags & DOOR_RESET; }
void SetNewOverlay(TileOverlay *Overlay);
};
+}
+
#endif
diff --git a/gemrb/core/Scriptable/InfoPoint.cpp b/gemrb/core/Scriptable/InfoPoint.cpp
index 0199bc7..8b3ca35 100644
--- a/gemrb/core/Scriptable/InfoPoint.cpp
+++ b/gemrb/core/Scriptable/InfoPoint.cpp
@@ -19,8 +19,9 @@
#include "Scriptable/InfoPoint.h"
-#include "strrefs.h"
#include "win32def.h"
+#include "strrefs.h"
+#include "ie_cursors.h"
#include "Audio.h"
#include "DisplayMessage.h"
@@ -36,12 +37,19 @@
#include "Video.h"
#include "GameScript/GSUtils.h"
#include "GUI/GameControl.h"
+#include "System/StringBuffer.h"
#include <cassert>
#include <cmath>
+namespace GemRB {
+
#define YESNO(x) ( (x)?"Yes":"No")
+//crazy programmers couldn't decide which bit marks the alternative point
+static ieDword TRAP_USEPOINT = _TRAP_USEPOINT;
+static bool inited = false;
+
InfoPoint::InfoPoint(void)
: Highlightable( ST_TRIGGER )
{
@@ -52,7 +60,19 @@ InfoPoint::InfoPoint(void)
TrapRemovalDiff = 0;
TrapDetected = 0;
TrapLaunch.empty();
- EnterWav[0] = 0;
+ if (!inited) {
+ inited = true;
+ //TRAP_USEPOINT may have three values
+ //0 - PST - no such flag
+ //0x200 - IWD2 - it has no TRAP_NONPC flag, the usepoint flag takes it over
+ //0x400 - all other engines (some don't use it)
+ if (core->HasFeature(GF_USEPOINT_400)) TRAP_USEPOINT = _TRAP_USEPOINT;
+ else if (core->HasFeature(GF_USEPOINT_200)) TRAP_USEPOINT = _TRAVEL_NONPC;
+ else TRAP_USEPOINT = 0;
+ }
+ StrRef = 0;
+ UsePoint.empty();
+ TalkPos.empty();
}
InfoPoint::~InfoPoint(void)
@@ -66,21 +86,31 @@ void InfoPoint::SetEnter(const char *resref)
}
}
+ieDword InfoPoint::GetUsePoint() const {
+ return Flags&TRAP_USEPOINT;
+}
+
//checks if the actor may use this travel trigger
//bit 1 : can use
//bit 2 : whole team
int InfoPoint::CheckTravel(Actor *actor)
{
if (Flags&TRAP_DEACTIVATED) return CT_CANTMOVE;
- if (!actor->InParty && (Flags&TRAVEL_NONPC) ) return CT_CANTMOVE;
- if (actor->InParty && (Flags&TRAVEL_PARTY) ) {
+ bool pm = actor->IsPartyMember();
+
+ //this flag does not exist in IWD2, we cannot use it if the infopoint flag took it over
+ if (TRAP_USEPOINT!=_TRAVEL_NONPC) {
+ if (!pm && (Flags&_TRAVEL_NONPC) ) return CT_CANTMOVE;
+ }
+
+ if (pm && (Flags&TRAVEL_PARTY) ) {
if (core->HasFeature(GF_TEAM_MOVEMENT) || core->GetGame()->EveryoneNearPoint(actor->GetCurrentArea(), actor->Pos, ENP_CANMOVE) ) {
return CT_WHOLE;
}
return CT_GO_CLOSER;
}
- if(actor->IsSelected() ) {
- if(core->GetGame()->EveryoneNearPoint(actor->GetCurrentArea(), actor->Pos, ENP_CANMOVE|ENP_ONLYSELECT) ) {
+ if (actor->IsSelected() ) {
+ if (core->GetGame()->EveryoneNearPoint(actor->GetCurrentArea(), actor->Pos, ENP_CANMOVE|ENP_ONLYSELECT) ) {
return CT_MOVE_SELECTED;
}
return CT_SELECTED;
@@ -88,23 +118,6 @@ int InfoPoint::CheckTravel(Actor *actor)
return CT_ACTIVE;
}
-//detect this trap, using a skill, skill could be set to 256 for 'sure'
-//skill is the all around modified trap detection skill
-//a trapdetectiondifficulty of 100 means impossible detection short of a spell
-void Highlightable::DetectTrap(int skill)
-{
- if (!CanDetectTrap()) return;
- if (!Scripts[0]) return;
- if ((skill>=100) && (skill!=256) ) skill = 100;
- if (skill/2+core->Roll(1,skill/2,0)>TrapDetectionDiff) {
- SetTrapDetected(1); //probably could be set to the player #?
- }
-}
-
-bool Highlightable::PossibleToSeeTrap() const
-{
- return CanDetectTrap();
-}
bool InfoPoint::PossibleToSeeTrap() const
{
@@ -142,24 +155,6 @@ bool Highlightable::VisibleTrap(int see_all) const
}
//trap that will fire now
-bool Highlightable::TriggerTrap(int /*skill*/, ieDword ID)
-{
- if (!Trapped) {
- return false;
- }
- //actually this could be script name[0]
- if (!Scripts[0] && !EnterWav[0]) {
- return false;
- }
- LastTriggerObject = LastTrigger = LastEntered = ID;
- ImmediateEvent();
- if (!TrapResets()) {
- Trapped = false;
- }
- return true;
-}
-
-//trap that will fire now
bool InfoPoint::TriggerTrap(int skill, ieDword ID)
{
if (Type!=ST_PROXIMITY) {
@@ -170,15 +165,10 @@ bool InfoPoint::TriggerTrap(int skill, ieDword ID)
}
if (!Trapped) {
// we have to set Entered somewhere, here seems best..
- LastEntered = ID;
+ // FIXME: likely not best :)
+ AddTrigger(TriggerEntry(trigger_harmlessentered, ID));
return true;
} else if (Highlightable::TriggerTrap(skill, ID)) {
- if (!Trapped) {
- Flags|=TRAP_DEACTIVATED;
- }
- // ok, so this is a pain. Entered() trigger checks Trapped,
- // so it needs to be kept set. how to do this right?
- Trapped = true;
return true;
}
return false;
@@ -189,6 +179,10 @@ bool InfoPoint::Entered(Actor *actor)
if (outline->PointIn( actor->Pos ) ) {
goto check;
}
+ // be more lenient for travel regions, fixed iwd2 ar1100 to1101 region
+ if (Type == ST_TRAVEL && outline->BBox.PointInside(actor->Pos)) {
+ goto check;
+ }
// why is this here? actors which aren't *in* a trap get IF_INTRAP
// repeatedly unset, so this triggers again and again and again.
// i disabled it for ST_PROXIMITY for now..
@@ -219,6 +213,11 @@ check:
return false;
}
+ // allow entering trap when trying to disarm
+ if (Type == ST_PROXIMITY && actor->GetDisarmingTrap() == GetGlobalID()) {
+ return false;
+ }
+
if (actor->InParty || (Flags&TRAP_NPC) ) {
//no need to avoid a travel trigger
@@ -230,35 +229,36 @@ check:
return false;
}
-void InfoPoint::DebugDump() const
+void InfoPoint::dump() const
{
+ StringBuffer buffer;
switch (Type) {
case ST_TRIGGER:
- printf( "Debugdump of InfoPoint Region %s:\n", GetScriptName() );
+ buffer.appendFormatted( "Debugdump of InfoPoint Region %s:\n", GetScriptName() );
break;
case ST_PROXIMITY:
- printf( "Debugdump of Trap Region %s:\n", GetScriptName() );
+ buffer.appendFormatted( "Debugdump of Trap Region %s:\n", GetScriptName() );
break;
case ST_TRAVEL:
- printf( "Debugdump of Travel Region %s:\n", GetScriptName() );
+ buffer.appendFormatted( "Debugdump of Travel Region %s:\n", GetScriptName() );
break;
default:
- printf( "Debugdump of Unsupported Region %s:\n", GetScriptName() );
+ buffer.appendFormatted( "Debugdump of Unsupported Region %s:\n", GetScriptName() );
break;
}
- printf( "Region Global ID: %d\n", GetGlobalID());
- printf( "Position: %d.%d\n", Pos.x, Pos.y);
+ buffer.appendFormatted( "Region Global ID: %d\n", GetGlobalID());
+ buffer.appendFormatted( "Position: %d.%d\n", Pos.x, Pos.y);
switch(Type) {
case ST_TRAVEL:
- printf( "Destination Area: %s Entrance: %s\n", Destination, EntranceName);
+ buffer.appendFormatted( "Destination Area: %s Entrance: %s\n", Destination, EntranceName);
break;
case ST_PROXIMITY:
- printf( "TrapDetected: %d, Trapped: %s\n", TrapDetected, YESNO(Trapped));
- printf( "Trap detection: %d%%, Trap removal: %d%%\n", TrapDetectionDiff,
+ buffer.appendFormatted( "TrapDetected: %d, Trapped: %s\n", TrapDetected, YESNO(Trapped));
+ buffer.appendFormatted( "Trap detection: %d%%, Trap removal: %d%%\n", TrapDetectionDiff,
TrapRemovalDiff );
break;
case ST_TRIGGER:
- printf ( "InfoString: %s\n", overHeadText );
+ buffer.appendFormatted ( "InfoString: %s\n", overHeadText );
break;
default:;
}
@@ -266,7 +266,11 @@ void InfoPoint::DebugDump() const
if (Scripts[0]) {
name = Scripts[0]->GetName();
}
- printf( "Script: %s, Key: %s, Dialog: %s\n", name, KeyResRef, Dialog );
- printf( "Active: %s\n", YESNO(InternalFlags&IF_ACTIVE));
+ buffer.appendFormatted( "Script: %s, Key: %s, Dialog: %s\n", name, KeyResRef, Dialog );
+ buffer.appendFormatted( "Deactivated: %s\n", YESNO(Flags&TRAP_DEACTIVATED));
+ buffer.appendFormatted( "Active: %s\n", YESNO(InternalFlags&IF_ACTIVE));
+ Log(DEBUG, "InfoPoint", buffer);
}
+
+}
diff --git a/gemrb/core/Scriptable/InfoPoint.h b/gemrb/core/Scriptable/InfoPoint.h
index 0eb6282..c53b845 100644
--- a/gemrb/core/Scriptable/InfoPoint.h
+++ b/gemrb/core/Scriptable/InfoPoint.h
@@ -21,21 +21,9 @@
#ifndef INFOPOINT_H
#define INFOPOINT_H
-#include "Scriptable.h"
+#include "Scriptable/Scriptable.h"
-//trigger flags
-#define TRAP_INVISIBLE 1
-#define TRAP_RESET 2
-#define TRAVEL_PARTY 4
-#define TRAP_DETECTABLE 8
-//#define TRAP_16 16
-#define TRAP_LOWMEM 32 //special treatment when low on memory ?
-#define TRAP_NPC 64
-//#define TRAP_128 128
-#define TRAP_DEACTIVATED 256
-#define TRAVEL_NONPC 512
-#define TRAP_USEPOINT 1024 //override usage point of travel regions (used for sound in PST traps)
-#define INFO_DOOR 2048 //info trigger blocked by door
+namespace GemRB {
class GEM_EXPORT InfoPoint : public Highlightable {
public:
@@ -46,9 +34,11 @@ public:
bool TriggerTrap(int skill, ieDword ID);
//call this to check if an actor entered the trigger zone
bool Entered(Actor *actor);
+ //returns true if
+ ieDword GetUsePoint() const;
//checks if the actor may use this travel trigger
int CheckTravel(Actor *actor);
- void DebugDump() const;
+ void dump() const;
int TrapResets() const { return Flags & TRAP_RESET; }
bool CanDetectTrap() const;
bool PossibleToSeeTrap() const;
@@ -62,7 +52,8 @@ public:
ieStrRef StrRef;
Point UsePoint;
Point TalkPos;
-
};
+}
+
#endif
diff --git a/gemrb/core/Scriptable/PCStatStruct.cpp b/gemrb/core/Scriptable/PCStatStruct.cpp
index 32338e5..b636a29 100644
--- a/gemrb/core/Scriptable/PCStatStruct.cpp
+++ b/gemrb/core/Scriptable/PCStatStruct.cpp
@@ -20,11 +20,12 @@
#include "Scriptable/PCStatStruct.h"
-#include "globals.h" //for abort()
#include "win32def.h"
#include <cstring>
+namespace GemRB {
+
PCStatsStruct::PCStatsStruct()
{
BestKilledName = 0xffffffff;
@@ -124,6 +125,16 @@ void PCStatsStruct::InitQuickSlot(unsigned int which, int slot, int headerindex)
case ACT_QSLOT3: SetQuickItemSlot(2,slot,headerindex); break;
case ACT_QSLOT4: SetQuickItemSlot(3,slot,headerindex); break;
case ACT_QSLOT5: SetQuickItemSlot(4,slot,headerindex); break;
+ case ACT_IWDQITEM:
+ case ACT_IWDQITEM+1:
+ case ACT_IWDQITEM+2:
+ case ACT_IWDQITEM+3:
+ case ACT_IWDQITEM+4:
+ case ACT_IWDQITEM+5: // crashy from here on until we do do/use 9 quickslots
+ case ACT_IWDQITEM+6:
+ case ACT_IWDQITEM+7:
+ case ACT_IWDQITEM+8:
+ case ACT_IWDQITEM+9: SetQuickItemSlot(which - ACT_IWDQITEM, slot, headerindex); break;
case ACT_WEAPON1:
QuickWeaponSlots[0]=slot;
QuickWeaponHeaders[0]=header;
@@ -148,6 +159,8 @@ void PCStatsStruct::InitQuickSlot(unsigned int which, int slot, int headerindex)
QuickWeaponSlots[7]=slot2;
QuickWeaponHeaders[7]=header;
break;
+ default:
+ Log(DEBUG, "PCSS", "InitQuickSlot: unknown which/slot %d/%d", which, slot);
}
}
@@ -162,7 +175,17 @@ void PCStatsStruct::GetSlotAndIndex(unsigned int which, ieWord &slot, ieWord &he
case ACT_QSLOT3: idx = 2; break;
case ACT_QSLOT4: idx = 3; break;
case ACT_QSLOT5: idx = 4; break;
- default: abort();
+ case ACT_IWDQITEM:
+ case ACT_IWDQITEM+1:
+ case ACT_IWDQITEM+2:
+ case ACT_IWDQITEM+3:
+ case ACT_IWDQITEM+4:
+ case ACT_IWDQITEM+5: // crashy from here on until we do do/use 9 quickslots
+ case ACT_IWDQITEM+6:
+ case ACT_IWDQITEM+7:
+ case ACT_IWDQITEM+8:
+ case ACT_IWDQITEM+9: idx = which - ACT_IWDQITEM; break;
+ default: error("Core", "Unknown Quickslot accessed '%d'.\n", which);
}
slot=QuickItemSlots[idx];
headerindex=QuickItemHeaders[idx];
@@ -183,3 +206,77 @@ int PCStatsStruct::GetHeaderForSlot(int slot)
}
return -1;
}
+
+//register favourite weapon or spell
+//method:
+//there are MAX_FAVOURITES slots, each with a resref and an usage count
+//the currently registered resref will always be stored somewhere, the question is just where
+//if it was an old favourite, just increase the usage count
+//if it is the new favourite candidate (last slot) then just increase the usage count
+//but also swap it with a previous slot if its usage count is now better, so the last slot is always the weakest
+//finally if it was not found anywhere, register it as the new candidate with 1 usage
+
+void PCStatsStruct::RegisterFavourite(ieResRef fav, int what)
+{
+ ieResRef *respoi;
+ ieWord *cntpoi;
+
+ switch (what) {
+ case FAV_SPELL:
+ respoi = FavouriteSpells;
+ cntpoi = FavouriteSpellsCount;
+ break;
+ case FAV_WEAPON:
+ respoi = FavouriteWeapons;
+ cntpoi = FavouriteWeaponsCount;
+ break;
+ default:
+ print("Illegal RegisterFavourite call...");
+ abort();
+ return;
+ }
+ //least favourite candidate position and count
+ int minpos = 0;
+ int mincnt = cntpoi[0];
+ int pos = 0;
+ for (pos = 0; pos<MAX_FAVOURITES-1; pos++) {
+ if (!strnicmp(fav, respoi[pos], 8) ) {
+ //found an old favourite, just increase its usage count and done
+ if (cntpoi[pos]<0xffff) {
+ cntpoi[pos]++;
+ }
+ return;
+ }
+ if (pos) {
+ //collect least favourite for possible swapping
+ if (cntpoi[pos]<mincnt) {
+ minpos = pos;
+ mincnt = cntpoi[pos];
+ }
+ }
+ }
+
+ //pos is always MAX_FAVOURITES-1 here
+ if (strnicmp(fav, respoi[pos], 8) ) {
+ //new favourite candidate, scrapping the old one
+ cntpoi[pos] = 1;
+ strnuprcpy(respoi[pos], fav, 8);
+ return;
+ }
+ //increase the favourite candidate
+ cntpoi[pos]++;
+ if (cntpoi[pos]>mincnt) {
+ //if it is now exceeding an old favourite, swap them
+
+ //move the old resref to the last position
+ memcpy(respoi[pos], respoi[minpos], sizeof(ieResRef) );
+ //store the new resref into the new position
+ strnuprcpy(respoi[minpos], fav, 8);
+ //store the new count to the new position
+ cntpoi[minpos] = cntpoi[pos];
+ //store the old count to the last position
+ cntpoi[pos] = mincnt;
+ }
+}
+
+}
diff --git a/gemrb/core/Scriptable/PCStatStruct.h b/gemrb/core/Scriptable/PCStatStruct.h
index f081f58..1b0984b 100644
--- a/gemrb/core/Scriptable/PCStatStruct.h
+++ b/gemrb/core/Scriptable/PCStatStruct.h
@@ -24,6 +24,8 @@
#include "exports.h"
#include "ie_types.h"
+namespace GemRB {
+
#define MAX_QUICKITEMSLOT 5 //pst has 5
#define MAX_QUICKWEAPONSLOT 8 //iwd2 has 4x2
#define MAX_QSLOTS 9 //iwd2 has 9
@@ -66,11 +68,30 @@
//gui navigation (scrolling button rows left or right)
#define ACT_LEFT 32
#define ACT_RIGHT 33
+#define ACT_BARD 40
+#define ACT_CLERIC 41
+#define ACT_DRUID 42
+#define ACT_PALADIN 43
+#define ACT_RANGER 44
+#define ACT_SORCERER 45
+#define ACT_WIZARD 46
+#define ACT_DOMAIN 47
+#define ACT_WILDSHAPE 48
+
+#define ACT_IWDQSPELL 50
+#define ACT_IWDQITEM 60
+#define ACT_IWDQSPEC 70
+#define ACT_IWDQSONG 80
+
+#define MAX_ACT_COUNT 100
-#define MAX_ACT_COUNT 34 //update this
+#define ES_COUNT 16 //number of iwd2 persistent feat preset values (original iwd2 had only 5)
#define GUIBT_COUNT (MAX_QSLOTS + 3)
+#define FAV_SPELL 0
+#define FAV_WEAPON 1
+
class GEM_EXPORT PCStatsStruct {
public:
ieStrRef BestKilledName;
@@ -88,7 +109,7 @@ public:
ieWord FavouriteWeaponsCount[MAX_FAVOURITES];
ieResRef SoundSet;
char SoundFolder[SOUNDFOLDERSIZE];
- ieDword ExtraSettings[16]; //iwd2 - expertise, hamstring, arterial strike, etc
+ ieDword ExtraSettings[ES_COUNT]; //iwd2 - expertise, hamstring, arterial strike, etc
ieResRef QuickSpells[MAX_QSLOTS]; //iwd2 uses 9, others use only 3
ieWord QuickWeaponSlots[MAX_QUICKWEAPONSLOT]; //iwd2 uses 8, others use only 4
ieWord QuickWeaponHeaders[MAX_QUICKWEAPONSLOT];
@@ -113,5 +134,8 @@ public:
void SetSlotIndex(unsigned int which, ieWord headerindex);
void GetSlotAndIndex(unsigned int which, ieWord &slot, ieWord &headerindex);
int GetHeaderForSlot(int slot);
+ void RegisterFavourite(ieResRef fav, int what);
};
+}
+
#endif
diff --git a/gemrb/core/Scriptable/Scriptable.cpp b/gemrb/core/Scriptable/Scriptable.cpp
index 9efced6..b922e6a 100644
--- a/gemrb/core/Scriptable/Scriptable.cpp
+++ b/gemrb/core/Scriptable/Scriptable.cpp
@@ -19,8 +19,9 @@
#include "Scriptable/Scriptable.h"
-#include "strrefs.h"
#include "win32def.h"
+#include "strrefs.h"
+#include "ie_cursors.h"
#include "Audio.h"
#include "DisplayMessage.h"
@@ -28,6 +29,7 @@
#include "GameData.h"
#include "Interface.h"
#include "Item.h"
+#include "Font.h"
#include "Map.h"
#include "Projectile.h"
#include "Spell.h"
@@ -35,16 +37,22 @@
#include "TileMap.h"
#include "Video.h"
#include "GameScript/GSUtils.h"
+#include "GameScript/Matching.h" // MatchActor
#include "GUI/GameControl.h"
+//#include "GUI/Window.h"
#include "Scriptable/InfoPoint.h"
#include <cassert>
#include <cmath>
+namespace GemRB {
+
#define YESNO(x) ( (x)?"Yes":"No")
// we start this at a non-zero value to make debugging easier
static ieDword globalActorCounter = 10000;
+static bool startActive = false;
+static bool third = false;
/***********************
* Scriptable Class *
@@ -60,51 +68,68 @@ Scriptable::Scriptable(ScriptableType type)
textDisplaying = 0;
timeStartDisplaying = 0;
scriptName[0] = 0;
- TriggerID = 0; //used by SendTrigger
- LastTriggerObject = LastTrigger = 0;
- LastEntered = 0;
- LastDisarmed = 0;
- LastDisarmFailed = 0;
- LastUnlocked = 0;
- LastOpenFailed = 0;
- LastPickLockFailed = 0;
+
+ LastAttacker = 0;
+ LastCommander = 0;
+ LastProtector = 0;
+ LastProtectee = 0;
+ LastTargetedBy = 0;
+ LastHitter = 0;
+ LastHelp = 0;
+ LastTrigger = 0;
+ LastSeen = 0;
+ LastTalker = 0;
+ LastHeard = 0;
+ LastSummoner = 0;
+ LastFollowed = 0;
+ LastMarked = 0;
+ LastMarkedSpell = 0;
+
DialogName = 0;
CurrentAction = NULL;
CurrentActionState = 0;
CurrentActionTarget = 0;
CurrentActionInterruptable = true;
+ CurrentActionTicks = 0;
UnselectableTimer = 0;
- startTime = 0; //executing scripts
- lastRunTime = 0; //evaluating scripts
- lastDelay = 0;
+ Ticks = 0;
+ AdjustedTicks = 0;
+ ScriptTicks = 0;
+ IdleTicks = 0;
+ AuraTicks = 100;
+ TriggerCountdown = 0;
Dialog[0] = 0;
globalID = ++globalActorCounter;
+ if (globalActorCounter == 0) {
+ error("Scriptable", "GlobalID overflowed, quitting due to too many actors.");
+ }
- interval = ( 1000 / AI_UPDATE_TIME );
WaitCounter = 0;
if (Type == ST_ACTOR) {
- InternalFlags = IF_VISIBLE | IF_ONCREATION | IF_USEDSAVE;
+ InternalFlags = IF_VISIBLE | IF_USEDSAVE;
+ if (startActive) {
+ InternalFlags |= IF_ACTIVE;
+ }
} else {
- InternalFlags = IF_ACTIVE | IF_VISIBLE | IF_ONCREATION | IF_NOINT;
+ InternalFlags = IF_ACTIVE | IF_VISIBLE | IF_NOINT;
}
area = 0;
Pos.x = 0;
Pos.y = 0;
- LastCasterOnMe = 0;
LastSpellOnMe = 0xffffffff;
- LastCasterSeen = 0;
- LastSpellSeen = 0xffffffff;
- SpellHeader = -1;
- SpellResRef[0] = 0;
- LastTargetPos.empty();
+ ResetCastingState(NULL);
+ InterruptCasting = false;
locals = new Variables();
locals->SetType( GEM_VARIABLES_INT );
locals->ParseKey( 1 );
InitTriggers();
+ AddTrigger(TriggerEntry(trigger_oncreation));
memset( script_timers,0, sizeof(script_timers));
+ startActive = core->HasFeature(GF_START_ACTIVE);
+ third = core->HasFeature(GF_3ED_RULES);
}
Scriptable::~Scriptable(void)
@@ -157,8 +182,7 @@ void Scriptable::SetMap(Map *map)
{
if (map && (map->GetCurrentArea()!=map)) {
//a map always points to itself (if it is a real map)
- printMessage("Scriptable","Invalid map set!\n",LIGHT_RED);
- abort();
+ error("Scriptable", "Invalid map set!\n");
}
area = map;
}
@@ -169,8 +193,7 @@ void Scriptable::SetMap(Map *map)
void Scriptable::SetScript(const ieResRef aScript, int idx, bool ai)
{
if (idx >= MAX_SCRIPTS) {
- printMessage("Scriptable","Invalid script index!\n",LIGHT_RED);
- abort();
+ error("Scriptable", "Invalid script index!\n");
}
if (Scripts[idx]) {
delete Scripts[idx];
@@ -187,7 +210,7 @@ void Scriptable::SetScript(const ieResRef aScript, int idx, bool ai)
void Scriptable::SetScript(int index, GameScript* script)
{
if (index >= MAX_SCRIPTS) {
- printMessage("Scriptable","Invalid script index!\n",LIGHT_RED);
+ Log(ERROR, "Scriptable", "Invalid script index!");
return;
}
if (Scripts[index] ) {
@@ -205,9 +228,9 @@ void Scriptable::DisplayHeadText(const char* text)
if (overHeadText) {
core->FreeString( overHeadText );
}
- overHeadText = (char *) text;
overHeadTextPos.empty();
if (text) {
+ overHeadText = strdup(text);
timeStartDisplaying = core->GetGame()->Ticks;
textDisplaying = 1;
}
@@ -243,7 +266,8 @@ void Scriptable::DrawOverheadText(const Region &screen)
} else {
time = (MAX_DELAY-time)/10;
if (time<256) {
- const Color overHeadColor = {time,time,time,time};
+ ieByte time2 = time; // shut up narrowing warnings
+ const Color overHeadColor = {time2,time2,time2,time2};
palette = core->CreatePalette(overHeadColor, black);
}
}
@@ -268,14 +292,9 @@ void Scriptable::DrawOverheadText(const Region &screen)
gamedata->FreePalette(palette);
}
-void Scriptable::DelayedEvent()
-{
- lastRunTime = core->GetGame()->Ticks;
-}
-
void Scriptable::ImmediateEvent()
{
- lastRunTime = 0;
+ InternalFlags |= IF_FORCEUPDATE;
}
bool Scriptable::IsPC() const
@@ -288,6 +307,79 @@ bool Scriptable::IsPC() const
return false;
}
+void Scriptable::Update()
+{
+ Ticks++;
+ AdjustedTicks++;
+ AuraTicks++;
+
+ Actor *act = NULL;
+ if (Type == ST_ACTOR) {
+ act = (Actor *) this;
+ }
+
+ if (UnselectableTimer) {
+ UnselectableTimer--;
+ if (!UnselectableTimer) {
+ if (act) {
+ act->SetCircleSize();
+ }
+ }
+ }
+
+ TickScripting();
+
+ ProcessActions();
+
+ InterruptCasting = false;
+}
+
+void Scriptable::TickScripting()
+{
+ // Stagger script updates.
+ if (Ticks % 16 != globalID % 16)
+ return;
+
+ ieDword actorState = 0;
+ if (Type == ST_ACTOR)
+ actorState = ((Actor *)this)->Modified[IE_STATE_ID];
+
+ // Dead actors only get one chance to run a new script.
+ if ( (InternalFlags& (IF_REALLYDIED|IF_JUSTDIED))==IF_REALLYDIED)
+ return;
+
+ ScriptTicks++;
+
+ // If no action is running, we've had triggers set recently or we haven't checked recently, do a script update.
+ bool needsUpdate = (!CurrentAction) || (TriggerCountdown > 0) || (IdleTicks > 15);
+
+ // Also do a script update if one was forced..
+ if (InternalFlags & IF_FORCEUPDATE) {
+ needsUpdate = true;
+ InternalFlags &= ~IF_FORCEUPDATE;
+ }
+ // TODO: force for all on-screen actors
+
+ // Charmed actors don't get frequent updates.
+ if ((actorState & STATE_CHARMED) && (IdleTicks < 5))
+ needsUpdate = false;
+
+ if (!needsUpdate) {
+ IdleTicks++;
+ return;
+ }
+
+ if (triggers.size())
+ TriggerCountdown = 5;
+ IdleTicks = 0;
+ InternalFlags &= ~IF_JUSTDIED;
+ if (TriggerCountdown > 0)
+ TriggerCountdown--;
+ // TODO: set TriggerCountdown once we have real triggers
+
+ ExecuteScript(MAX_SCRIPTS);
+}
+
void Scriptable::ExecuteScript(int scriptCount)
{
// area scripts still run for at least the current area, in bg1 (see ar2631, confirmed by testing)
@@ -298,72 +390,68 @@ void Scriptable::ExecuteScript(int scriptCount)
}
}
+ // Don't abort if there is a running non-interruptable action.
if ((InternalFlags & IF_NOINT) && (CurrentAction || GetNextAction())) {
return;
}
-
if (!CurrentActionInterruptable) {
- if (!CurrentAction && !GetNextAction()) abort();
+ // sanity check
+ if (!CurrentAction && !GetNextAction())
+ error("Scriptable", "No current action and no next action.\n");
return;
}
- // only allow death scripts to run once, hopefully?
- // this is probably terrible logic which needs moving elsewhere
- if ((lastRunTime != 0) && (InternalFlags & IF_JUSTDIED)) {
- return;
- }
+ bool changed = false;
- ieDword thisTime = core->GetGame()->Ticks;
- if (( thisTime - lastRunTime ) < 1000) {
- return;
+ // if party AI is disabled, don't run non-override scripts
+ if (Type == ST_ACTOR && ((Actor *) this)->InParty && (core->GetGame()->ControlStatus & CS_PARTY_AI))
+ scriptCount = 1;
+ // TODO: hardcoded action hacks
+ if (Type == ST_ACTOR) {
+ //TODO: add stuff here that overrides actions (like Panic, etc)
+ changed |= ((Actor *) this)->OverrideActions();
}
- lastDelay = lastRunTime;
- lastRunTime = thisTime;
-
- bool alive = false;
-
bool continuing = false, done = false;
- for (int i = 0;i<scriptCount;i++) {
- //disable AI script level for actors in party when the player disabled them
- if ((i == AI_SCRIPT_LEVEL) && Type == ST_ACTOR && ((Actor *) this)->InParty) {
- if (core->GetGame()->ControlStatus&CS_PARTY_AI) {
- continue;
- }
- }
-
- GameScript *Script = Scripts[i];
+ for (scriptlevel = 0;scriptlevel<scriptCount;scriptlevel++) {
+ GameScript *Script = Scripts[scriptlevel];
if (Script) {
- alive |= Script->Update(&continuing, &done);
+ changed |= Script->Update(&continuing, &done);
}
/* scripts are not concurrent, see WAITPC override script for example */
if (done) break;
}
- if (alive && UnselectableTimer) {
- UnselectableTimer--;
- if (!UnselectableTimer) {
- if (Type == ST_ACTOR) {
- ((Actor *) this)->SetCircleSize();
- }
- }
+
+ if (changed)
+ InitTriggers();
+
+ if (Type == ST_ACTOR) {
+ //TODO: add stuff here about idle actions
+ ((Actor *) this)->IdleActions(CurrentAction!=NULL);
}
- InternalFlags &= ~IF_ONCREATION;
}
void Scriptable::AddAction(Action* aC)
{
if (!aC) {
- printf( "[GameScript]: NULL action encountered for %s!\n",scriptName );
+ print("[GameScript]: NULL action encountered for %s!", scriptName);
return;
}
InternalFlags|=IF_ACTIVE;
+ if (startActive) {
+ InternalFlags &= ~IF_IDLE;
+ }
aC->IncRef();
+ if (actionflags[aC->actionID] & AF_SCRIPTLEVEL) {
+ aC->int0Parameter = scriptlevel;
+ }
// attempt to handle 'instant' actions, from instant.ids, which run immediately
// when added if the action queue is empty, even on actors which are Held/etc
- if (!CurrentAction && !GetNextAction()) {
+ // FIXME: area check hack until fuzzie fixes scripts here
+ if (!CurrentAction && !GetNextAction() && area) {
if (actionflags[aC->actionID] & AF_INSTANT) {
CurrentAction = aC;
GameScript::ExecuteAction( this, CurrentAction );
@@ -377,7 +465,7 @@ void Scriptable::AddAction(Action* aC)
void Scriptable::AddActionInFront(Action* aC)
{
if (!aC) {
- printf( "[GameScript]: NULL action encountered for %s!\n",scriptName );
+ print("[GameScript]: NULL action encountered for %s!", scriptName);
return;
}
InternalFlags|=IF_ACTIVE;
@@ -414,8 +502,6 @@ void Scriptable::ClearActions()
actionQueue.clear();
WaitCounter = 0;
LastTarget = 0;
- //clear the triggers as fast as possible when queue ended?
- ClearTriggers();
if (Type == ST_ACTOR) {
Interrupt();
@@ -434,38 +520,38 @@ void Scriptable::ReleaseCurrentAction()
CurrentActionState = 0;
CurrentActionTarget = 0;
CurrentActionInterruptable = true;
+ CurrentActionTicks = 0;
}
-void Scriptable::ProcessActions(bool force)
+void Scriptable::ProcessActions()
{
- unsigned long thisTime = core->GetGame()->Ticks;
-
- if (!force && (( thisTime - startTime ) < interval)) {
- return;
- }
- startTime = thisTime;
if (WaitCounter) {
WaitCounter--;
if (WaitCounter) return;
}
+ int lastAction = -1;
+
while (true) {
CurrentActionInterruptable = true;
if (!CurrentAction) {
+ if (! (CurrentActionTicks == 0 && CurrentActionState == 0)) {
+ print("Last action: %d", lastAction);
+ }
+ assert(CurrentActionTicks == 0 && CurrentActionState == 0);
CurrentAction = PopNextAction();
+ } else {
+ CurrentActionTicks++;
}
if (!CurrentAction) {
ClearActions();
- //removing the triggers at the end of the
- //block
- //ClearTriggers();
+ lastAction = -1;
break;
}
+ lastAction = CurrentAction->actionID;
GameScript::ExecuteAction( this, CurrentAction );
//break execution in case of a Wait flag
if (WaitCounter) {
- //clear triggers while waiting
- //ClearTriggers();
break;
}
//break execution in case of blocking action
@@ -478,12 +564,10 @@ void Scriptable::ProcessActions(bool force)
break;
}
}
- //most likely the best place to clear triggers is here
- //queue is empty, or there is a looong action subject to break
- ClearTriggers();
- if (InternalFlags&IF_IDLE) {
+ // FIXME
+ /*if (InternalFlags&IF_IDLE) {
Deactivate();
- }
+ }*/
}
bool Scriptable::InMove() const
@@ -507,7 +591,7 @@ unsigned long Scriptable::GetWait() const
void Scriptable::LeaveDialog()
{
- InternalFlags |=IF_WASINDIALOG;
+ AddTrigger(TriggerEntry(trigger_wasindialog));
}
void Scriptable::Hide()
@@ -547,101 +631,113 @@ void Scriptable::Activate()
void Scriptable::PartyRested()
{
- InternalFlags |=IF_PARTYRESTED;
+ //InternalFlags |=IF_PARTYRESTED;
+ AddTrigger(TriggerEntry(trigger_partyrested));
}
-ieDword Scriptable::GetInternalFlag()
+ieDword Scriptable::GetInternalFlag() const
{
return InternalFlags;
}
void Scriptable::InitTriggers()
{
- tolist.clear();
- bittriggers = 0;
+ triggers.clear();
}
-void Scriptable::ClearTriggers()
+void Scriptable::AddTrigger(TriggerEntry trigger)
{
- for (TriggerObjects::iterator m = tolist.begin(); m != tolist.end (); m++) {
- *(*m) = 0;
- }
- if (!bittriggers) {
- return;
- }
- if (bittriggers & BT_DIE) {
- InternalFlags &= ~IF_JUSTDIED;
- }
- if (bittriggers & BT_ONCREATION) {
- InternalFlags &= ~IF_ONCREATION;
- }
- if (bittriggers & BT_BECAMEVISIBLE) {
- InternalFlags &= ~IF_BECAMEVISIBLE;
- }
- if (bittriggers & BT_PARTYRESTED) {
- InternalFlags &= ~IF_PARTYRESTED;
- }
- if (bittriggers & BT_WASINDIALOG) {
- InternalFlags &= ~IF_WASINDIALOG;
- }
- if (bittriggers & BT_PARTYRESTED) {
- InternalFlags &= ~IF_PARTYRESTED;
+ triggers.push_back(trigger);
+ ImmediateEvent();
+
+ assert(trigger.triggerID < MAX_TRIGGERS);
+ if (triggerflags[trigger.triggerID] & TF_SAVED) {
+ //TODO: if LastTrigger is still overwritten by script action blocks, store this in a separate field and copy it back when the block ends
+ //Log(WARNING, "Scriptable", "%s: Added LastTrigger: %d for trigger %d\n", scriptName, trigger.param1, trigger.triggerID);
+ LastTrigger = trigger.param1;
}
- InitTriggers();
}
-void Scriptable::SetBitTrigger(ieDword bittrigger)
-{
- bittriggers |= bittrigger;
+bool Scriptable::MatchTrigger(unsigned short id, ieDword param) {
+ for (std::list<TriggerEntry>::iterator m = triggers.begin(); m != triggers.end (); m++) {
+ TriggerEntry &trigger = *m;
+ if (trigger.triggerID != id)
+ continue;
+ if (param && trigger.param1 != param)
+ continue;
+ return true;
+ }
+
+ return false;
}
-void Scriptable::AddTrigger(ieDword *actorref)
-{
- tolist.push_back(actorref);
+bool Scriptable::MatchTriggerWithObject(unsigned short id, class Object *obj, ieDword param) {
+ for (std::list<TriggerEntry>::iterator m = triggers.begin(); m != triggers.end (); m++) {
+ TriggerEntry &trigger = *m;
+ if (trigger.triggerID != id)
+ continue;
+ if (param && trigger.param2 != param)
+ continue;
+ if (!MatchActor(this, trigger.param1, obj))
+ continue;
+ return true;
+ }
+
+ return false;
}
-static EffectRef fx_set_invisible_state_ref = { "State:Invisible", -1 };
+const TriggerEntry *Scriptable::GetMatchingTrigger(unsigned short id, unsigned int notflags) {
+ for (std::list<TriggerEntry>::iterator m = triggers.begin(); m != triggers.end (); m++) {
+ TriggerEntry &trigger = *m;
+ if (trigger.triggerID != id)
+ continue;
+ if (notflags & trigger.flags)
+ continue;
+ return &*m;
+ }
+
+ return NULL;
+}
void Scriptable::CreateProjectile(const ieResRef SpellResRef, ieDword tgt, int level, bool fake)
{
Spell* spl = gamedata->GetSpell( SpellResRef );
- Spell* spltmp= NULL;
Actor *caster = NULL;
//PST has a weird effect, called Enoll Eva's duplication
//it creates every projectile of the affected actor twice
- int duplicate = 1;
+ int projectileCount = 1;
if (Type == ST_ACTOR) {
caster = (Actor *) this;
- //FIXME: 1 duplicate is no duplicate, right?
- duplicate = caster->wildSurgeMods.num_castings;
- if (!duplicate) {
- duplicate = 1;
+ if (spl->Flags&SF_HOSTILE) {
+ caster->CureSanctuary();
+ }
+
+ // check if a wild surge ordered us to replicate the projectile
+ projectileCount = caster->wildSurgeMods.num_castings;
+ if (!projectileCount) {
+ projectileCount = 1;
}
}
+
if (core->HasFeature(GF_PST_STATE_FLAGS) && (Type == ST_ACTOR)) {
if (caster->GetStat(IE_STATE_ID)&STATE_EE_DUPL) {
//seriously, wild surges and EE in the same game?
//anyway, it would be too many duplications
- duplicate = 2;
+ projectileCount = 2;
}
}
- // when doing wild magic mods, use a copy of the spell to avoid mod propagation into the cache
- if (caster && (caster->wildSurgeMods.target_change_type || caster->wildSurgeMods.saving_throw_mod || caster->wildSurgeMods.projectile_id)) {
- spltmp = gamedata->GetUncachedSpell( SpellResRef );
- }
-
- while(duplicate --) {
+ while(projectileCount --) {
Projectile *pro = NULL;
- // jump through hoops to skip applying selftargetting spells to the caster
+ // jump through hoops to skip applying selftargeting spells to the caster
// if we'll be changing the target
int tct = 0;
if (caster) {
tct = caster->wildSurgeMods.target_change_type;
}
if (!caster || !tct || tct == WSTC_ADDTYPE || !caster->wildSurgeMods.projectile_id) {
- pro = spl->GetProjectile(this, SpellHeader, LastTargetPos);
+ pro = spl->GetProjectile(this, SpellHeader, level, LastTargetPos);
if (!pro) {
return;
}
@@ -664,19 +760,19 @@ void Scriptable::CreateProjectile(const ieResRef SpellResRef, ieDword tgt, int l
Effect *fx = NULL;
switch (caster->wildSurgeMods.target_change_type) {
case WSTC_SETTYPE:
- seh = &spltmp->ext_headers[SpellHeader];
+ seh = &spl->ext_headers[SpellHeader];
for (i=0; i < seh->FeatureCount; i++) {
seh->features[i].Target = caster->wildSurgeMods.target_type;
}
// we need to fetch the projectile, so the effect queue is created
// (skipped above)
- pro = spltmp->GetProjectile(this, SpellHeader, LastTargetPos);
+ pro = spl->GetProjectile(this, SpellHeader, level, LastTargetPos);
pro->SetCaster(GetGlobalID(), level);
break;
case WSTC_ADDTYPE:
// TODO: unhardcode to allow for mixing all the target types
- // caster gets selftargetting fx when the projectile is fetched above
- seh = &spltmp->ext_headers[SpellHeader];
+ // caster gets selftargeting fx when the projectile is fetched above
+ seh = &spl->ext_headers[SpellHeader];
for (i=0; i < seh->FeatureCount; i++) {
if (seh->features[i].Target == FX_TARGET_SELF) {
seh->features[i].Target = caster->wildSurgeMods.target_type;
@@ -687,7 +783,7 @@ void Scriptable::CreateProjectile(const ieResRef SpellResRef, ieDword tgt, int l
}
}
// we need to refetch the projectile, so the effect queue is created
- pro = spltmp->GetProjectile(this, SpellHeader, LastTargetPos);
+ pro = spl->GetProjectile(this, SpellHeader, level, LastTargetPos);
pro->SetCaster(GetGlobalID(), level);
break;
case WSTC_RANDOMIZE:
@@ -706,9 +802,9 @@ void Scriptable::CreateProjectile(const ieResRef SpellResRef, ieDword tgt, int l
LastTargetPos = newact->Pos;
}
- // make it also work for self-targetting spells:
+ // make it also work for self-targeting spells:
// change the payload or this was all in vain
- seh = &spltmp->ext_headers[SpellHeader];
+ seh = &spl->ext_headers[SpellHeader];
for (i=0; i < seh->FeatureCount; i++) {
if (seh->features[i].Target == FX_TARGET_SELF) {
seh->features[i].Target = FX_TARGET_PRESET;
@@ -716,7 +812,7 @@ void Scriptable::CreateProjectile(const ieResRef SpellResRef, ieDword tgt, int l
}
// we need to fetch the projectile, so the effect queue is created
// (skipped above)
- pro = spltmp->GetProjectile(this, SpellHeader, LastTargetPos);
+ pro = spl->GetProjectile(this, SpellHeader, level, LastTargetPos);
pro->SetCaster(GetGlobalID(), level);
break;
default: //0 - do nothing
@@ -725,7 +821,7 @@ void Scriptable::CreateProjectile(const ieResRef SpellResRef, ieDword tgt, int l
// apply the saving throw mod
if (caster->wildSurgeMods.saving_throw_mod) {
- seh = &spltmp->ext_headers[SpellHeader];
+ seh = &spl->ext_headers[SpellHeader];
for (i=0; i < seh->FeatureCount; i++) {
seh->features[i].SavingThrowBonus += caster->wildSurgeMods.saving_throw_mod;
}
@@ -733,17 +829,17 @@ void Scriptable::CreateProjectile(const ieResRef SpellResRef, ieDword tgt, int l
// change the projectile
if (caster->wildSurgeMods.projectile_id) {
- spltmp->ext_headers[SpellHeader].ProjectileAnimation = caster->wildSurgeMods.projectile_id;
- // make it also work for self-targetting spells:
+ spl->ext_headers[SpellHeader].ProjectileAnimation = caster->wildSurgeMods.projectile_id;
+ // make it also work for self-targeting spells:
// change the payload or this was all in vain
- seh = &spltmp->ext_headers[SpellHeader];
+ seh = &spl->ext_headers[SpellHeader];
for (i=0; i < seh->FeatureCount; i++) {
if (seh->features[i].Target == FX_TARGET_SELF) {
seh->features[i].Target = FX_TARGET_PRESET;
}
}
// we need to refetch the projectile, so the new one is used
- pro = spltmp->GetProjectile(this, SpellHeader, LastTargetPos);
+ pro = spl->GetProjectile(this, SpellHeader, level, LastTargetPos);
pro->SetCaster(GetGlobalID(), level);
}
@@ -757,7 +853,7 @@ void Scriptable::CreateProjectile(const ieResRef SpellResRef, ieDword tgt, int l
}
if (tgt) {
- area->AddProjectile(pro, origin, LastTarget, fake);
+ area->AddProjectile(pro, origin, tgt, fake);
} else {
area->AddProjectile(pro, origin, LastTargetPos);
}
@@ -767,78 +863,100 @@ void Scriptable::CreateProjectile(const ieResRef SpellResRef, ieDword tgt, int l
if (spellnum!=0xffffffff) {
area->SeeSpellCast(this, spellnum);
- // caster - Casts spellname : target OR
- // caster - spellname : target (repeating spells)
- Scriptable *target = NULL;
- char tmp[100];
- const char* msg = core->GetString(displaymsg->GetStringReference(STR_ACTION_CAST), 0);
- const char* spell = core->GetString(spl->SpellName);
- if (LastTarget) {
- target = area->GetActorByGlobalID(LastTarget);
- if (!target) {
- target=core->GetGame()->GetActorByGlobalID(LastTarget);
- }
- }
- if (stricmp(spell, "")) {
- if (target) {
- snprintf(tmp, sizeof(tmp), "%s %s : %s", msg, spell, target->GetName(-1));
- } else {
- snprintf(tmp, sizeof(tmp), "%s : %s", spell, GetName(-1));
- }
- displaymsg->DisplayStringName(tmp, 0xffffff, this);
- }
-
- if(LastTarget) {
- if (target && (Type==ST_ACTOR) ) {
- target->LastSpellOnMe = spellnum;
- target->LastCasterOnMe = caster->GetGlobalID();
- // don't cure invisibility if this is a self targetting invisibility spell
- // like shadow door
- //can't check GetEffectBlock, since it doesn't construct the queue for selftargetting spells
- bool invis = false;
- unsigned int opcode = EffectQueue::ResolveEffect(fx_set_invisible_state_ref);
- for (unsigned int i=0; i < spl->ext_headers[SpellHeader].FeatureCount; i++) {
- if (spl->GetExtHeader(SpellHeader)->features[i].Opcode == opcode) {
- invis = true;
- break;
- }
- }
- if (invis && spl->GetExtHeader(SpellHeader)->Target == TARGET_SELF) {
- //pass
- } else {
- caster->CureInvisibility();
- }
- // sanctuary ends with all hostile actions or when the caster targets someone else
- if (target != this || spl->Flags & SF_HOSTILE) {
- caster->CureSanctuary();
+ // spellcasting feedback
+ if (third) {
+ // only display it for party friendly creatures - enemies require a successful spellcraft check
+ if (Type == ST_ACTOR) {
+ Actor *caster = ((Actor *) this);
+ if (caster->GetStat(IE_EA) <= EA_CONTROLLABLE) {
+ DisplaySpellCastMessage(tgt, spl);
}
}
+ } else {
+ DisplaySpellCastMessage(tgt, spl);
}
}
-
- core->Autopause(AP_SPELLCAST);
+ // only trigger the autopause when in combat or buffing gets very annoying
+ if (core->GetGame()->CombatCounter) {
+ core->Autopause(AP_SPELLCAST, this);
+ }
gamedata->FreeSpell(spl, SpellResRef, false);
- if (spltmp) {
- delete spltmp;
+}
+
+void Scriptable::DisplaySpellCastMessage(ieDword tgt, Spell *spl)
+{
+ // caster - Casts spellname : target OR
+ // caster - spellname : target (repeating spells)
+ Scriptable *target = NULL;
+ if (tgt) {
+ target = area->GetActorByGlobalID(tgt);
+ if (!target) {
+ target=core->GetGame()->GetActorByGlobalID(tgt);
+ }
+ }
+ char* spell = core->GetString(spl->SpellName);
+ if (stricmp(spell, "") && Type == ST_ACTOR) {
+ char* msg = core->GetString(displaymsg->GetStringReference(STR_ACTION_CAST), 0);
+ char *tmp;
+ if (target) {
+ tmp = (char *) malloc(strlen(msg)+strlen(spell)+strlen(target->GetName(-1))+5);
+ sprintf(tmp, "%s %s : %s", msg, spell, target->GetName(-1));
+ } else {
+ tmp = (char *) malloc(strlen(spell)+strlen(GetName(-1))+4);
+ sprintf(tmp, "%s : %s", spell, GetName(-1));
+ }
+ displaymsg->DisplayStringName(tmp, DMC_WHITE, this);
+ core->FreeString(msg);
+ free(tmp);
}
+ core->FreeString(spell);
+}
+void Scriptable::SendTriggerToAll(TriggerEntry entry)
+{
+ Actor** nearActors = area->GetAllActorsInRadius(Pos, GA_NO_DEAD, 15*10);
+ int i=0;
+ while(nearActors[i]!=NULL) {
+ nearActors[i]->AddTrigger(entry);
+ ++i;
+ }
+ free(nearActors);
+}
+
+inline void Scriptable::ResetCastingState(Actor *caster) {
+ SpellHeader = -1;
+ SpellResRef[0] = 0;
+ LastTarget = 0;
+ LastTargetPos.empty();
+ if (caster) {
+ memset(&(caster->wildSurgeMods), 0, sizeof(caster->wildSurgeMods));
+ }
}
-void Scriptable::CastSpellPointEnd(int level)
+void Scriptable::CastSpellPointEnd(int level, int no_stance)
{
Actor *caster = NULL;
+ Spell* spl = gamedata->GetSpell(SpellResRef); // this was checked before we got here
+ if (!spl) {
+ return;
+ }
+ int nSpellType = spl->SpellType;
+ gamedata->FreeSpell(spl, SpellResRef, false);
+
if (Type == ST_ACTOR) {
caster = ((Actor *) this);
- caster->SetStance(IE_ANI_CONJURE);
- if (level == 0) {
- Spell* spl = gamedata->GetSpell(SpellResRef); // this was checked before we got here
- Actor *actor = NULL;
- if (Type == ST_ACTOR) {
- actor = (Actor *) this;
- level = actor->GetCasterLevel(spl->SpellType);
- }
- gamedata->FreeSpell(spl, SpellResRef, false);
+ if (!no_stance) {
+ caster->SetStance(IE_ANI_CONJURE);
+ caster->CureInvisibility();
+ }
+ }
+ if (level == 0) {
+ if (caster) {
+ level = caster->GetCasterLevel(nSpellType);
+ } else {
+ //default caster level is 1
+ level = 1;
}
}
@@ -855,32 +973,57 @@ void Scriptable::CastSpellPointEnd(int level)
if (!SpellResRef[0]) {
return;
}
+ if (!area) {
+ Log(ERROR, "Scriptable", "CastSpellPointEnd: lost area, skipping %s!", SpellResRef);
+ ResetCastingState(caster);
+ return;
+ }
- CreateProjectile(SpellResRef, 0, level, false);
+ if (caster && caster->PCStats) {
+ caster->PCStats->RegisterFavourite(SpellResRef, FAV_SPELL);
+ }
- SpellHeader = -1;
- SpellResRef[0] = 0;
- LastTarget = 0;
- LastTargetPos.empty();
- if (caster) {
- memset(&(caster->wildSurgeMods), 0, sizeof(caster->wildSurgeMods));
+ CreateProjectile(SpellResRef, 0, level, false);
+ //FIXME: this trigger affects actors whom the caster sees, not just the caster itself
+ // the original engine saves lasttrigger only in case of SpellCast, so we have to differentiate
+ ieDword spellID = ResolveSpellNumber(SpellResRef);
+ switch (nSpellType) {
+ case 1:
+ SendTriggerToAll(TriggerEntry(trigger_spellcast, GetGlobalID(), spellID));
+ break;
+ case 2:
+ SendTriggerToAll(TriggerEntry(trigger_spellcastpriest, GetGlobalID(), spellID));
+ break;
+ default:
+ SendTriggerToAll(TriggerEntry(trigger_spellcastinnate, GetGlobalID(), spellID));
+ break;
}
+
+ ResetCastingState(caster);
}
-void Scriptable::CastSpellEnd(int level)
+void Scriptable::CastSpellEnd(int level, int no_stance)
{
Actor *caster = NULL;
+ Spell* spl = gamedata->GetSpell(SpellResRef); // this was checked before we got here
+ if (!spl) {
+ return;
+ }
+ int nSpellType = spl->SpellType;
+ gamedata->FreeSpell(spl, SpellResRef, false);
if (Type == ST_ACTOR) {
caster = ((Actor *) this);
- caster->SetStance(IE_ANI_CONJURE);
- if (level == 0) {
- Spell* spl = gamedata->GetSpell(SpellResRef); // this was checked before we got here
- Actor *actor = NULL;
- if (Type == ST_ACTOR) {
- actor = (Actor *) this;
- level = actor->GetCasterLevel(spl->SpellType);
- }
- gamedata->FreeSpell(spl, SpellResRef, false);
+ if (!no_stance) {
+ caster->SetStance(IE_ANI_CONJURE);
+ caster->CureInvisibility();
+ }
+ }
+ if (level == 0) {
+ if (caster) {
+ level = caster->GetCasterLevel(nSpellType);
+ } else {
+ //default caster level is 1
+ level = 1;
}
}
@@ -895,24 +1038,49 @@ void Scriptable::CastSpellEnd(int level)
if (!SpellResRef[0]) {
return;
}
+ if (!area) {
+ Log(ERROR, "Scriptable", "CastSpellEnd: lost area, skipping %s!", SpellResRef);
+ ResetCastingState(caster);
+ return;
+ }
+
+ if (caster && caster->PCStats) {
+ caster->PCStats->RegisterFavourite(SpellResRef, FAV_SPELL);
+ }
//if the projectile doesn't need to follow the target, then use the target position
CreateProjectile(SpellResRef, LastTarget, level, GetSpellDistance(SpellResRef, this)==0xffffffff);
- SpellHeader = -1;
- SpellResRef[0] = 0;
- LastTarget = 0;
- LastTargetPos.empty();
- if (caster) {
- memset(&(caster->wildSurgeMods), 0, sizeof(caster->wildSurgeMods));
+ //FIXME: this trigger affects actors whom the caster sees, not just the caster itself
+ // the original engine saves lasttrigger only in case of SpellCast, so we have to differentiate
+ ieDword spellID = ResolveSpellNumber(SpellResRef);
+ switch (nSpellType) {
+ case 1:
+ SendTriggerToAll(TriggerEntry(trigger_spellcast, GetGlobalID(), spellID));
+ break;
+ case 2:
+ SendTriggerToAll(TriggerEntry(trigger_spellcastpriest, GetGlobalID(), spellID));
+ break;
+ default:
+ SendTriggerToAll(TriggerEntry(trigger_spellcastinnate, GetGlobalID(), spellID));
+ break;
}
+
+ // TODO: maybe it should be set on effect application, since the data uses it with dispel magic and true sight a lot
+ Actor *target = area->GetActorByGlobalID(LastTarget);
+ if (target) {
+ target->AddTrigger(TriggerEntry(trigger_spellcastonme, GetGlobalID(), spellID));
+ target->LastSpellOnMe = spellID;
+ }
+
+ ResetCastingState(caster);
}
// check for input sanity and good casting conditions
-int Scriptable::CanCast(const ieResRef SpellResRef) {
+int Scriptable::CanCast(const ieResRef SpellResRef, bool verbose) {
Spell* spl = gamedata->GetSpell(SpellResRef);
if (!spl) {
SpellHeader = -1;
- printMessage("Scriptable", "Spell not found, aborting cast!\n", LIGHT_RED);
+ Log(ERROR, "Scriptable", "Spell not found, aborting cast!");
return 0;
}
@@ -920,7 +1088,12 @@ int Scriptable::CanCast(const ieResRef SpellResRef) {
// tob AR3004 is a dead magic area, but using a script with personal dead magic
if (area->GetInternalFlag()&AF_DEADMAGIC) {
// TODO: display fizzling animation
- displaymsg->DisplayConstantStringName(STR_DEADMAGIC_FAIL, 0xffffff, this);
+ displaymsg->DisplayConstantStringName(STR_DEADMAGIC_FAIL, DMC_WHITE, this);
+ return 0;
+ }
+
+ if (spl->Flags&SF_NOT_INDOORS && !(area->AreaType&AT_OUTDOOR)) {
+ displaymsg->DisplayConstantStringName(STR_INDOOR_FAIL, DMC_WHITE, this);
return 0;
}
@@ -932,9 +1105,9 @@ int Scriptable::CanCast(const ieResRef SpellResRef) {
// only a handful of spells don't have a verbal component -
// the original hardcoded vocalize and a few more
// we (also) ignore nonmagic spells
- if (actor->Modified[IE_STATE_ID] & STATE_SILENCED) {
+ if (actor->CheckSilenced()) {
if (!(core->GetSpecialSpell(spl->Name)&SP_SILENCE) && !(spl->Flags&SF_HLA)) {
- printMessage("Scriptable", "Tried to cast while silenced!\n", YELLOW);
+ Log(WARNING, "Scriptable", "Tried to cast while silenced!");
return 0;
}
}
@@ -942,34 +1115,42 @@ int Scriptable::CanCast(const ieResRef SpellResRef) {
// check for personal dead magic
if (actor->Modified[IE_DEADMAGIC]) {
// TODO: display fizzling animation
- displaymsg->DisplayConstantStringName(STR_DEADMAGIC_FAIL, 0xffffff, this);
+ displaymsg->DisplayConstantStringName(STR_DEADMAGIC_FAIL, DMC_WHITE, this);
return 0;
}
// check for miscast magic and similar
ieDword roll = actor->LuckyRoll(1, 100, 0, 0);
bool failed = false;
+ ieDword chance = 0;
switch(spl->SpellType)
{
case IE_SPL_PRIEST:
- if (actor->Modified[IE_SPELLFAILUREPRIEST] >= roll) {
+ chance = actor->GetSpellFailure(false);
+ if (chance >= roll) {
failed = true;
}
break;
case IE_SPL_WIZARD:
- if (actor->Modified[IE_SPELLFAILUREMAGE] >= roll) {
+ chance = actor->GetSpellFailure(true);
+ if (chance >= roll) {
failed = true;
}
break;
case IE_SPL_INNATE:
- if (actor->Modified[IE_SPELLFAILUREINNATE] >= roll) {
+ chance = actor->Modified[IE_SPELLFAILUREINNATE];
+ if (chance >= roll) {
failed = true;
}
break;
}
+ if (verbose && chance && third) {
+ // ~Spell Failure check: Roll d100 %d vs. Spell failure chance %d~
+ displaymsg->DisplayRollStringName(40955, DMC_LIGHTGREY, actor, roll, chance);
+ }
if (failed) {
// TODO: display fizzling animation
- displaymsg->DisplayConstantStringName(STR_MISCASTMAGIC, 0xffffff, this);
+ displaymsg->DisplayConstantStringName(STR_MISCASTMAGIC, DMC_WHITE, this);
return 0;
}
}
@@ -977,72 +1158,110 @@ int Scriptable::CanCast(const ieResRef SpellResRef) {
return 1;
}
+// checks if a party-friendly actor is nearby and if so, if it reckognizes the spell
+// this enemy just started casting
+void Scriptable::SpellcraftCheck(const Actor *caster, const ieResRef SpellResRef)
+{
+ if (!third || !caster || caster->GetStat(IE_EA) <= EA_CONTROLLABLE || !area) {
+ return;
+ }
+
+ Spell* spl = gamedata->GetSpell(SpellResRef);
+ assert(spl); // only a bad surge could make this fail and we want to catch it
+ int AdjustedSpellLevel = spl->SpellLevel + 15;
+ Actor **neighbours = area->GetAllActorsInRadius(caster->Pos, GA_NO_DEAD|GA_NO_ENEMY|GA_NO_SELF, 10*caster->GetBase(IE_VISUALRANGE));
+ Actor **poi = neighbours;
+ while (*poi) {
+ Actor *detective = *poi;
+ // disallow neutrals from helping the party
+ if (detective->GetStat(IE_EA) > EA_CONTROLLABLE) {
+ poi++;
+ continue;
+ }
+ if ((signed)detective->GetStat(IE_SPELLCRAFT) <= 0) {
+ poi++;
+ continue;
+ }
+
+ // ~Spellcraft check (d20 roll + Spellcraft level + int mod) %d vs. (spell level + 15) = %d. (Int mod = %d)~
+ int Spellcraft = core->Roll(1, 20, 0) + detective->GetStat(IE_SPELLCRAFT);
+ int IntMod = detective->GetAbilityBonus(IE_INT);
+
+ if ((Spellcraft + IntMod) > AdjustedSpellLevel) {
+ char tmpstr[100];
+ memset(tmpstr, 0, sizeof(tmpstr));
+ // eg. .:Casts Word of Recall:.
+ snprintf(tmpstr, sizeof(tmpstr), ".:%s %s:.", core->GetString(displaymsg->GetStringReference(STR_CASTS)), core->GetString(spl->SpellName));
+ DisplayHeadText(tmpstr);
+ displaymsg->DisplayRollStringName(39306, DMC_LIGHTGREY, detective, Spellcraft+IntMod, AdjustedSpellLevel, IntMod);
+ break;
+ }
+ poi++;
+ }
+ gamedata->FreeSpell(spl, SpellResRef, false);
+ free(neighbours);
+}
+
//set target as point
//if spell needs to be depleted, do it
//if spell is illegal stop casting
-int Scriptable::CastSpellPoint( ieResRef &SpellRef, const Point &target, bool deplete, bool instant )
+int Scriptable::CastSpellPoint( const Point &target, bool deplete, bool instant, bool nointerrupt )
{
LastTarget = 0;
LastTargetPos.empty();
+ Actor *actor = NULL;
if (Type == ST_ACTOR) {
- Actor *actor = (Actor *) this;
- if (actor->HandleCastingStance(SpellRef,deplete) ) {
- printMessage("Scriptable", "Spell not known or memorized, aborting cast!\n", LIGHT_RED);
+ actor = (Actor *) this;
+ if (actor->HandleCastingStance(SpellResRef, deplete, instant) ) {
+ Log(ERROR, "Scriptable", "Spell not known or memorized, aborting cast!");
return -1;
}
}
- if(deplete && !CanCast(SpellRef)) {
+ if(!nointerrupt && !CanCast(SpellResRef)) {
SpellResRef[0] = 0;
- if (Type == ST_ACTOR) {
- Actor *actor = (Actor *) this;
+ if (actor) {
actor->SetStance(IE_ANI_READY);
}
return -1;
}
- if (!SpellResRef[0]) {
- SetSpellResRef(SpellRef);
- }
-
LastTargetPos = target;
if(!CheckWildSurge()) {
return -1;
}
+ if (!instant) {
+ SpellcraftCheck(actor, SpellResRef);
+ }
return SpellCast(instant);
}
//set target as actor (if target isn't actor, use its position)
//if spell needs to be depleted, do it
//if spell is illegal stop casting
-int Scriptable::CastSpell( ieResRef &SpellRef, Scriptable* target, bool deplete, bool instant )
+int Scriptable::CastSpell( Scriptable* target, bool deplete, bool instant, bool nointerrupt )
{
LastTarget = 0;
LastTargetPos.empty();
+ Actor *actor = NULL;
if (Type == ST_ACTOR) {
- Actor *actor = (Actor *) this;
- if (actor->HandleCastingStance(SpellRef,deplete) ) {
- printMessage("Scriptable", "Spell not known or memorized, aborting cast!\n", LIGHT_RED);
+ actor = (Actor *) this;
+ if (actor->HandleCastingStance(SpellResRef, deplete, instant) ) {
+ Log(ERROR, "Scriptable", "Spell not known or memorized, aborting cast!");
return -1;
}
}
- // FIXME: fishy
- if (!target) target = this;
+ assert(target);
- if(deplete && !CanCast(SpellRef)) {
+ if(!nointerrupt && !CanCast(SpellResRef)) {
SpellResRef[0] = 0;
- if (Type == ST_ACTOR) {
- Actor *actor = (Actor *) this;
+ if (actor) {
actor->SetStance(IE_ANI_READY);
}
return -1;
}
- if (!SpellResRef[0]) {
- SetSpellResRef(SpellRef);
- }
-
LastTargetPos = target->Pos;
if (target->Type==ST_ACTOR) {
LastTarget = target->GetGlobalID();
@@ -1052,6 +1271,9 @@ int Scriptable::CastSpell( ieResRef &SpellRef, Scriptable* target, bool deplete,
return -1;
}
+ if (!instant) {
+ SpellcraftCheck(actor, SpellResRef);
+ }
return SpellCast(instant);
}
@@ -1079,9 +1301,14 @@ int Scriptable::SpellCast(bool instant)
if (actor) {
// The mental speed effect can shorten or lengthen the casting time.
casting_time -= (int)actor->Modified[IE_MENTALSPEED];
- if (casting_time < 0) casting_time = 0;
+ // maybe also add a random lucky roll as for weapon speed / initiative
+ if (casting_time < 0) {
+ casting_time = 0;
+ } else if (casting_time > 10) {
+ casting_time = 10;
+ }
}
- // this is a guess which seems approximately right so far
+ // this is a guess which seems approximately right so far (same as in the bg2 manual, except that it may be a combat round instead)
int duration = (casting_time*core->Time.round_size) / 10;
if (instant) {
duration = 0;
@@ -1090,8 +1317,9 @@ int Scriptable::SpellCast(bool instant)
//cfb
EffectQueue *fxqueue = spl->GetEffectBlock(this, this->Pos, -1, level);
fxqueue->SetOwner(actor);
- if (!actor->Modified[IE_AVATARREMOVAL]) {
- spl->AddCastingGlow(fxqueue, duration, actor->Modified[IE_SEX]);
+ if (!(actor->Modified[IE_AVATARREMOVAL] || instant)) {
+ ieDword gender = actor->GetCGGender();
+ spl->AddCastingGlow(fxqueue, duration, gender);
}
fxqueue->AddAllEffects(actor, actor->Pos);
delete fxqueue;
@@ -1101,6 +1329,7 @@ int Scriptable::SpellCast(bool instant)
// we have to remove it manually
actor->fxqueue.RemoveAllEffectsWithParam(fx_force_surge_modifier_ref, 1);
}
+ actor->ResetCommentTime();
}
gamedata->FreeSpell(spl, SpellResRef, false);
@@ -1113,11 +1342,18 @@ int Scriptable::SpellCast(bool instant)
// 1. the spell is cast normally (score of 100 or more)
// 2. one or more wild surges happen and something else is cast
// 2.1. this can loop, since some surges cause rerolls
+static EffectRef fx_chaosshield_ref = { "ChaosShieldModifier", -1 };
+
int Scriptable::CheckWildSurge()
{
- if (Type != ST_ACTOR || core->HasFeature(GF_3ED_RULES)) {
+ //no need to check for 3rd ed rules, because surgemod or forcesurge need to be nonzero to get a surge
+ if (Type != ST_ACTOR) {
return 1;
}
+ if (core->InCutSceneMode()) {
+ return 1;
+ }
+
Actor *caster = (Actor *) this;
int roll = core->Roll(1, 100, 0);
@@ -1126,19 +1362,30 @@ int Scriptable::CheckWildSurge()
memcpy(OldSpellResRef, SpellResRef, sizeof(OldSpellResRef));
Spell *spl = gamedata->GetSpell( OldSpellResRef ); // this was checked before we got here
// ignore non-magic "spells"
- if (!(spl->Flags&SF_HLA)) {
+ if (!(spl->Flags&(SF_HLA|SF_TRIGGER) )) {
int check = roll + caster->GetCasterLevel(spl->SpellType) + caster->Modified[IE_SURGEMOD];
- // hundred or more means a normal cast
- if (check < 100) {
+ if (caster->Modified[IE_CHAOSSHIELD]) {
+ //avert the surge and decrease the chaos shield counter
+ check = 0;
+ caster->fxqueue.DecreaseParam1OfEffect(fx_chaosshield_ref,1);
+ displaymsg->DisplayConstantStringName(STR_CHAOSSHIELD,DMC_LIGHTGREY,caster);
+ }
+
+ // hundred or more means a normal cast; same for negative values (for absurd antisurge modifiers)
+ if ((check > 0) && (check < 100) ) {
// display feedback: Wild Surge: bla bla
- char text[200];
- snprintf(text, 200, "%s %s", core->GetString(displaymsg->GetStringReference(STR_WILDSURGE), 0), core->GetString(core->SurgeSpells[check-1].message, 0));
- displaymsg->DisplayStringName(text, 0xffffff, this);
+ char *s1 = core->GetString(displaymsg->GetStringReference(STR_WILDSURGE), 0);
+ char *s2 = core->GetString(core->SurgeSpells[check-1].message, 0);
+ char *s3 = (char *) malloc(strlen(s1)+strlen(s2)+2);
+ sprintf(s3, "%s %s", s1, s2);
+ core->FreeString(s1);
+ core->FreeString(s2);
+ displaymsg->DisplayStringName(s3, DMC_WHITE, this);
+ free(s3);
// lookup the spell in the "check" row of wildmag.2da
ieResRef surgeSpellRef;
- memset(surgeSpellRef, 0, sizeof(surgeSpellRef));
- strncpy(surgeSpellRef, core->SurgeSpells[check-1].spell, 8);
+ CopyResRef(surgeSpellRef, core->SurgeSpells[check-1].spell);
if (!gamedata->Exists(surgeSpellRef, IE_SPL_CLASS_ID)) {
// handle the hardcoded cases - they'll also fail here
@@ -1150,7 +1397,7 @@ int Scriptable::CheckWildSurge()
} else {
// finally change the spell
// the hardcoded bunch does it on its own when needed
- strncpy(SpellResRef, surgeSpellRef, 8);
+ CopyResRef(SpellResRef, surgeSpellRef);
}
}
}
@@ -1214,20 +1461,22 @@ bool Scriptable::HandleHardcodedSurge(ieResRef surgeSpellRef, Spell *spl, Actor
} else if (target) {
targetpos = target->Pos;
}
+ // SpellResRef still contains the original spell and we need to keep it that way
+ // as any of the rerolls could result in a "spell cast normally" (non-surge)
for (i=0; i<count; i++) {
if (target) {
- caster->CastSpell(SpellResRef, target, false, true);
- strncpy(newspl, SpellResRef, 8);
+ caster->CastSpell(target, false, true);
+ CopyResRef(newspl, SpellResRef);
caster->WMLevelMod = tmp3;
- caster->CastSpellEnd(level);
+ caster->CastSpellEnd(level, 1);
} else {
- caster->CastSpellPoint(SpellResRef, targetpos, false, true);
- strncpy(newspl, SpellResRef, 8);
+ caster->CastSpellPoint(targetpos, false, true);
+ CopyResRef(newspl, SpellResRef);
caster->WMLevelMod = tmp3;
- caster->CastSpellPointEnd(level);
+ caster->CastSpellPointEnd(level, 1);
}
// reset the ref, since CastSpell*End destroyed it
- strncpy(SpellResRef, newspl, 8);
+ CopyResRef(SpellResRef, newspl);
}
caster->Modified[IE_FORCESURGE] = tmp;
caster->Modified[IE_SURGEMOD] = tmp2;
@@ -1254,7 +1503,7 @@ bool Scriptable::HandleHardcodedSurge(ieResRef surgeSpellRef, Spell *spl, Actor
int id = core->Roll(1, spellCount, -1);
CREKnownSpell *ck = caster->spellbook.GetKnownSpell(i, lvl, id);
if (ck) {
- strncpy(SpellResRef, ck->SpellResRef, 8);
+ CopyResRef(SpellResRef, ck->SpellResRef);
break;
}
}
@@ -1267,13 +1516,40 @@ bool Scriptable::HandleHardcodedSurge(ieResRef surgeSpellRef, Spell *spl, Actor
default:
SpellHeader = -1;
SpellResRef[0] = 0;
- printMessage("Scriptable", "New spell not found, aborting cast mid-surge!\n", LIGHT_RED);
+ Log(ERROR, "Scriptable", "New spell not found, aborting cast mid-surge!");
caster->SetStance(IE_ANI_READY);
return false;
}
return true;
}
+bool Scriptable::AuraPolluted()
+{
+ if (Type != ST_ACTOR) {
+ return false;
+ }
+
+ // aura pollution happens automatically
+ // aura cleansing the usual and magical way
+ if (AuraTicks >= core->Time.attack_round_size) {
+ AuraTicks = -1;
+ return false;
+ } else if (CurrentActionTicks == 0 && AuraTicks != 1 && Type == ST_ACTOR) {
+ Actor *act = (Actor *) this;
+ if (act->GetStat(IE_AURACLEANSING)) {
+ AuraTicks = -1;
+ displaymsg->DisplayConstantStringName(STR_AURACLEANSED, DMC_WHITE, this);
+ return false;
+ }
+ }
+
+ if (AuraTicks > 0) {
+ // sorry, you'll have to recover first
+ return true;
+ }
+ return false;
+}
+
bool Scriptable::TimerActive(ieDword ID)
{
if (ID>=MAX_TIMER) {
@@ -1301,8 +1577,8 @@ bool Scriptable::TimerExpired(ieDword ID)
void Scriptable::StartTimer(ieDword ID, ieDword expiration)
{
if (ID>=MAX_TIMER) {
- printMessage("Scriptable", " ", RED);
- printf("Timer id %d exceeded MAX_TIMER %d\n", ID, MAX_TIMER);
+ Log(ERROR, "Scriptable", "Timer id %d exceeded MAX_TIMER %d",
+ ID, MAX_TIMER);
return;
}
script_timers[ID]= core->GetGame()->GameTime + expiration*AI_UPDATE_TIME;
@@ -1339,8 +1615,6 @@ void Selectable::SetBBox(const Region &newBBox)
BBox = newBBox;
}
-static const unsigned long tp_steps[8]={3,2,1,0,1,2,3,4};
-
void Selectable::DrawCircle(const Region &vp)
{
/* BG2 colours ground circles as follows:
@@ -1366,8 +1640,8 @@ void Selectable::DrawCircle(const Region &vp)
//doing a time dependent flashing of colors
//if it is too fast, increase the 6 to 7
unsigned long step;
- GetTime( step );
- step = tp_steps [(step >> 6) & 7];
+ step = GetTickCount();
+ step = tp_steps [(step >> 7) & 7]*2;
mix.a = overColor.a;
mix.r = (overColor.r*step+selectedColor.r*(8-step))/8;
mix.g = (overColor.g*step+selectedColor.g*(8-step))/8;
@@ -1442,7 +1716,7 @@ void Selectable::SetCircle(int circlesize, const Color &color, Sprite2D* normal_
}
//used for creatures
-int Selectable::WantDither()
+int Selectable::WantDither() const
{
//if dithering is disabled globally, don't do it
if (core->FogOfWar&FOG_DITHERSPRITES) {
@@ -1470,6 +1744,7 @@ Highlightable::Highlightable(ScriptableType type)
Highlight = false;
Cursor = IE_CURSOR_NORMAL;
KeyResRef[0] = 0;
+ EnterWav[0] = 0;
}
Highlightable::~Highlightable(void)
@@ -1500,6 +1775,23 @@ void Highlightable::SetCursor(unsigned char CursorIndex)
Cursor = CursorIndex;
}
+//trap that will fire now
+bool Highlightable::TriggerTrap(int /*skill*/, ieDword ID)
+{
+ if (!Trapped) {
+ return false;
+ }
+ //actually this could be script name[0]
+ if (!Scripts[0] && !EnterWav[0]) {
+ return false;
+ }
+ AddTrigger(TriggerEntry(trigger_entered, ID));
+ if (!TrapResets()) {
+ Trapped = false;
+ }
+ return true;
+}
+
bool Highlightable::TryUnlock(Actor *actor, bool removekey) {
const char *Key = GetKey();
Actor *haskey = NULL;
@@ -1539,6 +1831,37 @@ bool Highlightable::TryUnlock(Actor *actor, bool removekey) {
return true;
}
+//detect this trap, using a skill, skill could be set to 256 for 'sure'
+//skill is the all around modified trap detection skill
+//a trapdetectiondifficulty of 100 means impossible detection short of a spell
+void Highlightable::DetectTrap(int skill, ieDword actorID)
+{
+ if (!CanDetectTrap()) return;
+ if (!Scripts[0]) return;
+ if ((skill>=100) && (skill!=256) ) skill = 100;
+ int check = 0;
+ if (third) {
+ //~Search (detect traps) check. Search skill %d vs. trap's difficulty %d (searcher's %d INT bonus).~
+ Actor *detective = core->GetGame()->GetActorByGlobalID(actorID);
+ int bonus = 0;
+ if (detective) {
+ bonus = detective->GetAbilityBonus(IE_INT);
+ displaymsg->DisplayRollStringName(39303, DMC_LIGHTGREY, detective, skill-bonus, TrapDetectionDiff, bonus);
+ }
+ check = (skill + bonus)*7;
+ } else {
+ check = skill/2 + core->Roll(1, skill/2, 0);
+ }
+ if (check > TrapDetectionDiff) {
+ SetTrapDetected(1); //probably could be set to the player #?
+ AddTrigger(TriggerEntry(trigger_detected, actorID));
+ }
+}
+
+bool Highlightable::PossibleToSeeTrap() const
+{
+ return CanDetectTrap();
+}
/*****************
* Movable Class *
@@ -1571,6 +1894,8 @@ Movable::~Movable(void)
int Movable::GetPathLength()
{
PathNode *node = GetNextStep(0);
+ if (!node) return 0;
+
int i = 0;
while (node->Next) {
i++;
@@ -1612,7 +1937,7 @@ void Movable::SetStance(unsigned int arg)
//don't modify stance from dead back to anything if the actor is dead
if ((StanceID==IE_ANI_TWITCH || StanceID==IE_ANI_DIE) && (arg!=IE_ANI_TWITCH) ) {
if (GetInternalFlag()&IF_REALLYDIED) {
- printMessage("Movable","Stance overridden by death\n", YELLOW);
+ Log(WARNING, "Movable", "Stance overridden by death");
return;
}
}
@@ -1643,7 +1968,7 @@ void Movable::SetStance(unsigned int arg)
} else {
StanceID=IE_ANI_AWAKE; //
- printf("Tried to set invalid stance id (%u)\n", arg);
+ print("Tried to set invalid stance id(%u)", arg);
}
}
@@ -1654,18 +1979,15 @@ void Movable::SetAttackMoveChances(ieWord *amc)
AttackMovements[2]=amc[2];
}
-
-
//this could be used for WingBuffet as well
void Movable::MoveLine(int steps, int Pass, ieDword orient)
{
- //remove previous path
- ClearPath();
- if (!steps)
+ if (path || !steps) {
return;
+ }
Point p = Pos;
p.x/=16;
- p.y/=14;
+ p.y/=12;
path = area->GetLine( p, steps, orient, Pass );
}
@@ -1684,6 +2006,24 @@ void AdjustPositionTowards(Point &Pos, ieDword time_diff, unsigned int walk_spee
( ( ( Pos.y - ( ( desty * 12 ) + 6 ) ) * ( time_diff ) ) / walk_speed );
}
+unsigned char Movable::GetNextFace()
+{
+ //slow turning
+ if (timeStartStep==core->GetGame()->Ticks) {
+ return Orientation;
+ }
+ if (Orientation != NewOrientation) {
+ if ( ( (NewOrientation-Orientation) & (MAX_ORIENT-1) ) <= MAX_ORIENT/2) {
+ Orientation++;
+ } else {
+ Orientation--;
+ }
+ Orientation = Orientation&(MAX_ORIENT-1);
+ }
+
+ return Orientation;
+}
+
// returns whether we made all pending steps (so, false if we must be called again this tick)
// we can't just do them all here because the caller might have to update searchmap etc
bool Movable::DoStep(unsigned int walk_speed, ieDword time)
@@ -1702,11 +2042,11 @@ bool Movable::DoStep(unsigned int walk_speed, ieDword time)
step = path;
timeStartStep = time;
} else if (step->Next && (( time - timeStartStep ) >= walk_speed)) {
- //printf("[New Step] : Orientation = %d\n", step->orient);
+ //print("[New Step] : Orientation = %d", step->orient);
step = step->Next;
timeStartStep = timeStartStep + walk_speed;
}
- SetOrientation (step->orient, false);
+ SetOrientation (step->orient, true);
StanceID = IE_ANI_WALK;
if ((Type == ST_ACTOR) && (InternalFlags & IF_RUNNING)) {
StanceID = IE_ANI_RUN;
@@ -1869,9 +2209,9 @@ void Movable::RandomWalk(bool can_stop, bool run)
//p.x+=x;
//p.y+=(int) sqrt(100-x*x);
- //selecting points in a square around actor
- p.x+=core->Roll(1,50,-25);
- p.y+=core->Roll(1,50,-25);
+ //selecting points in a square around actor (-24 to +24)
+ p.x+=core->Roll(1,49,-25);
+ p.y+=core->Roll(1,49,-25);
//the 5th parameter is controlling the orientation of the actor
//0 - back away, 1 - face direction
path = area->RunAway( Pos, p, size, 50, 1 );
@@ -1896,7 +2236,7 @@ void Movable::ClearPath()
if (StanceID==IE_ANI_WALK || StanceID==IE_ANI_RUN) {
StanceID = IE_ANI_AWAKE;
}
- InternalFlags&=~IF_NORECTICLE;
+ InternalFlags&=~IF_NORETICLE;
PathNode* thisNode = path;
while (thisNode) {
PathNode* nextNode = thisNode->Next;
@@ -1908,46 +2248,6 @@ void Movable::ClearPath()
//don't call ReleaseCurrentAction
}
-void Movable::DrawTargetPoint(const Region &vp)
-{
- if (!path || !Selected || (InternalFlags&IF_NORECTICLE) )
- return;
-
- // recticles are never drawn in cutscenes
- if ((core->GetGameControl()->GetScreenFlags()&SF_CUTSCENE))
- return;
-
- // generates "step" from sequence 3 2 1 0 1 2 3 4
- // updated each 1/15 sec
- unsigned long step;
- GetTime( step );
- step = tp_steps [(step >> 6) & 7];
-
- step = step + 1;
- int csize = (size - 1) * 4;
- if (csize < 4) csize = 3;
-
- /* segments should not go outside selection radius */
- unsigned short xradius = (csize * 4) - 5;
- unsigned short yradius = (csize * 3) - 5;
- ieWord xcentre = (ieWord) (Destination.x - vp.x);
- ieWord ycentre = (ieWord) (Destination.y - vp.y);
-
- // TODO: 0.5 and 0.7 are pretty much random values
- // right segment
- core->GetVideoDriver()->DrawEllipseSegment( xcentre + step, ycentre, xradius,
- yradius, selectedColor, -0.5, 0.5 );
- // top segment
- core->GetVideoDriver()->DrawEllipseSegment( xcentre, ycentre - step, xradius,
- yradius, selectedColor, -0.7 - M_PI_2, 0.7 - M_PI_2 );
- // left segment
- core->GetVideoDriver()->DrawEllipseSegment( xcentre - step, ycentre, xradius,
- yradius, selectedColor, -0.5 - M_PI, 0.5 - M_PI );
- // bottom segment
- core->GetVideoDriver()->DrawEllipseSegment( xcentre, ycentre + step, xradius,
- yradius, selectedColor, -0.7 - M_PI - M_PI_2, 0.7 - M_PI - M_PI_2 );
-}
-
/**********************
* Tiled Object Class *
**********************/
@@ -1989,3 +2289,5 @@ void TileObject::SetClosedTiles(unsigned short* Tiles, int cnt)
closedcount = cnt;
}
+
+}
diff --git a/gemrb/core/Scriptable/Scriptable.h b/gemrb/core/Scriptable/Scriptable.h
index d35a9bb..4108053 100644
--- a/gemrb/core/Scriptable/Scriptable.h
+++ b/gemrb/core/Scriptable/Scriptable.h
@@ -23,15 +23,12 @@
#include "exports.h"
-#include "CharAnimations.h"
-#include "Inventory.h"
-#include "PathFinder.h"
-#include "Sprite2D.h"
-#include "TileOverlay.h"
#include "Variables.h"
#include <list>
+namespace GemRB {
+
class Action;
class Actor;
class Container;
@@ -40,10 +37,13 @@ class GameScript;
class Gem_Polygon;
class Highlightable;
class InfoPoint;
+class Map;
class Movable;
+struct PathNode;
class Scriptable;
class Selectable;
class Spell;
+class Sprite2D;
class SpriteCover;
#define MAX_SCRIPTS 8
@@ -74,12 +74,12 @@ class SpriteCover;
#define TRAVEL_PARTY 4
#define TRAP_DETECTABLE 8
//#define TRAP_16 16
-#define TRAP_LOWMEM 32 //special treatment when low on memory ?
+#define TRAP_TUTORIAL 32 //active only when in tutorial mode
#define TRAP_NPC 64
//#define TRAP_128 128
#define TRAP_DEACTIVATED 256
-#define TRAVEL_NONPC 512
-#define TRAP_USEPOINT 1024 //override usage point of travel regions (used for sound in PST traps)
+#define _TRAVEL_NONPC 512
+#define _TRAP_USEPOINT 1024 //override usage point of travel regions (used for sound in PST traps)
#define INFO_DOOR 2048 //info trigger blocked by door
//internal actor flags
@@ -87,26 +87,27 @@ class SpriteCover;
#define IF_JUSTDIED 2 //Died() will return true
#define IF_FROMGAME 4 //this is an NPC or PC
#define IF_REALLYDIED 8 //real death happened, actor will be set to dead
-#define IF_NORECTICLE 16 //draw recticle (target mark)
+#define IF_NORETICLE 16 //draw reticle (target mark)
#define IF_NOINT 32 //cannot interrupt the actions of this actor (save is not possible!)
#define IF_CLEANUP 64 //actor died chunky death, or other total destruction
#define IF_RUNNING 128 //actor is running
//these bits could be set by a WalkTo
-#define IF_RUNFLAGS (IF_RUNNING|IF_NORECTICLE|IF_NOINT)
-#define IF_BECAMEVISIBLE 0x100//actor just became visible (trigger event)
+#define IF_RUNFLAGS (IF_RUNNING|IF_NORETICLE|IF_NOINT)
+//#define IF_BECAMEVISIBLE 0x100//actor just became visible (trigger event)
#define IF_INITIALIZED 0x200
#define IF_USEDSAVE 0x400 //actor needed saving throws
-#define IF_TARGETGONE 0x800 //actor's target is gone (trigger event)
+#define IF_GOTAREA 0x800 //actor already moved to an area
#define IF_USEEXIT 0x1000 //
#define IF_INTRAP 0x2000 //actor is currently in a trap (intrap trigger event)
-#define IF_WASINDIALOG 0x4000 //actor just left dialog
+//#define IF_WASINDIALOG 0x4000 //actor just left dialog
//scriptable flags
#define IF_ACTIVE 0x10000
#define IF_VISIBLE 0x40000
-#define IF_ONCREATION 0x80000
+//#define IF_ONCREATION 0x80000
#define IF_IDLE 0x100000
-#define IF_PARTYRESTED 0x200000 //party rested trigger event
+//#define IF_PARTYRESTED 0x200000 //party rested trigger event
+#define IF_FORCEUPDATE 0x400000
//the actor should stop attacking
#define IF_STOPATTACK (IF_JUSTDIED|IF_REALLYDIED|IF_CLEANUP|IF_IDLE)
@@ -119,14 +120,6 @@ class SpriteCover;
#define CT_SELECTED 4 //not all selected actors are there
#define CT_MOVE_SELECTED 5 //all selected can move
-//bits for binary trigger bitfield
-#define BT_DIE 1
-#define BT_ONCREATION 2
-#define BT_BECAMEVISIBLE 4
-#define BT_WASINDIALOG 8
-#define BT_PARTYRESTED 16
-#define BT_VACANT 32
-
//xp bonus types (for xpbonus.2da)
#define XP_LOCKPICK 0
#define XP_DISARM 1
@@ -135,7 +128,80 @@ class SpriteCover;
typedef enum ScriptableType { ST_ACTOR = 0, ST_PROXIMITY = 1, ST_TRIGGER = 2,
ST_TRAVEL = 3, ST_DOOR = 4, ST_CONTAINER = 5, ST_AREA = 6, ST_GLOBAL = 7 } ScriptableType;
-typedef std::list<ieDword *> TriggerObjects;
+enum {
+ trigger_acquired = 0x1,
+ trigger_attackedby = 0x2,
+ trigger_help = 0x3,
+ trigger_joins = 0x4,
+ trigger_leaves = 0x5,
+ trigger_receivedorder = 0x6,
+ trigger_said = 0x7,
+ trigger_turnedby = 0x8,
+ trigger_unusable = 0x9,
+ trigger_hitby = 0x20,
+ trigger_hotkey = 0x21,
+ trigger_timerexpired = 0x22,
+ trigger_trigger = 0x24,
+ trigger_die = 0x25,
+ trigger_targetunreachable = 0x26,
+ trigger_heard = 0x2f,
+ trigger_becamevisible = 0x33,
+ trigger_oncreation = 0x36,
+ trigger_died = 0x4a,
+ trigger_killed = 0x4b,
+ trigger_entered = 0x4c,
+ trigger_opened = 0x52,
+ trigger_closed = 0x53,
+ trigger_detected = 0x54,
+ trigger_reset = 0x55,
+ trigger_disarmed = 0x56,
+ trigger_unlocked = 0x57,
+ trigger_breakingpoint = 0x5c,
+ trigger_pickpocketfailed = 0x5d,
+ trigger_stealfailed = 0x5e,
+ trigger_disarmfailed = 0x5f,
+ trigger_picklockfailed = 0x60,
+ trigger_clicked = 0x70,
+ trigger_triggerclick = 0x79, // pst
+ trigger_traptriggered = 0x87, // bg2
+ trigger_partymemberdied = 0x88, // bg2
+ trigger_spellcast = 0x91, // bg2
+ trigger_partyrested = 0x93, // bg2
+ trigger_vacant = 0x94, // pst
+ trigger_summoned = 0x97, // bg2
+ trigger_harmlessopened = 0x9d, // pst
+ trigger_harmlessclosed = 0x9e, // pst
+ trigger_harmlessentered = 0x9f, // pst
+ trigger_spellcastonme = 0xa1, // bg2
+ trigger_nulldialog = 0xa4, // pst
+ trigger_wasindialog = 0xa5, // pst
+ trigger_spellcastpriest = 0xa6, // bg2
+ trigger_spellcastinnate = 0xa7, // bg2
+ trigger_namelessbitthedust = 0xab, // pst
+ trigger_failedtoopen = 0xaf, // pst
+ trigger_tookdamage = 0xcc, // bg2
+ trigger_walkedtotrigger = 0xd6 // bg2
+};
+
+// flags for TriggerEntry
+enum {
+ // has the effect queue (if any) been processed since this trigger
+ // was added? (for fx_cast_spell_on_condition)
+ TEF_PROCESSED_EFFECTS = 1
+};
+
+struct TriggerEntry {
+ TriggerEntry(unsigned short id) : triggerID(id), param1(0), param2(0), flags(0) { }
+ TriggerEntry(unsigned short id, ieDword p1) : triggerID(id), param1(p1), param2(0), flags(0) { }
+ TriggerEntry(unsigned short id, ieDword p1, ieDword p2) : triggerID(id), param1(p1), param2(p2), flags(0) { }
+
+ unsigned short triggerID;
+ ieDword param1;
+ ieDword param2;
+ unsigned int flags;
+};
+
+//typedef std::list<ieDword *> TriggerObjects;
//#define SEA_RESET 0x00000002
//#define SEA_PARTY_REQUIRED 0x00000004
@@ -145,16 +211,13 @@ public:
Scriptable(ScriptableType type);
virtual ~Scriptable(void);
private:
- TriggerObjects tolist;
- ieDword bittriggers;
- unsigned long startTime;
- unsigned long interval;
unsigned long WaitCounter;
// script_timers should probably be a std::map to
// conserve memory (usually at most 2 ids are used)
ieDword script_timers[MAX_TIMER];
ieDword globalID;
protected: //let Actor access this
+ std::list<TriggerEntry> triggers;
Map *area;
ieVariable scriptName;
ieDword InternalFlags; //for triggers
@@ -162,40 +225,68 @@ protected: //let Actor access this
std::list< Action*> actionQueue;
Action* CurrentAction;
public:
+ // State relating to the currently-running action.
int CurrentActionState;
ieDword CurrentActionTarget;
bool CurrentActionInterruptable;
- ieDword lastDelay;
- ieDword lastRunTime;
+ ieDword CurrentActionTicks;
+
+ // The number of times this was updated.
+ ieDword Ticks;
+ // The same, after adjustment for being slowed/hasted.
+ ieDword AdjustedTicks;
+ // The number of times UpdateActions() was run.
+ ieDword ScriptTicks;
+ // The number of times since UpdateActions() tried to do anything.
+ ieDword IdleTicks;
+ // The number of ticks since the last spellcast
+ ieDword AuraTicks;
+ // The countdown for forced activation by triggers.
+ ieDword TriggerCountdown;
+
Variables* locals;
ScriptableType Type;
Point Pos;
+
ieStrRef DialogName;
- ieResRef EnterWav; //play this wav file when stepping on the trap
+
GameScript* Scripts[MAX_SCRIPTS];
+ int scriptlevel;
+
+ // Variables for overhead text.
char* overHeadText;
Point overHeadTextPos;
unsigned char textDisplaying;
unsigned long timeStartDisplaying;
+
ieDword UnselectableTimer;
- ieDword TriggerID; //for sendtrigger
- ieDword LastTrigger; // also LastClosed
- ieDword LastTriggerObject; // hack until someone fixes triggers
- ieDword LastEntered; // also LastOpened
- ieDword LastDisarmed; // also LastAttacker
- ieDword LastDisarmFailed; //also LastTarget
- ieDword LastUnlocked;
- ieDword LastOpenFailed; // also LastPickpocketFailed
- ieDword LastPickLockFailed;
- int LastOrder;
- ieDword LastOrderer;
+
+ // Stored objects.
+ ieDword LastAttacker;
+ ieDword LastCommander;
+ ieDword LastProtector;
+ ieDword LastProtectee;
+ ieDword LastTargetedBy;
+ ieDword LastHitter;
+ ieDword LastHelp;
+ ieDword LastTrigger;
+ ieDword LastSeen;
+ ieDword LastTalker;
+ ieDword LastHeard;
+ ieDword LastSummoner;
+ ieDword LastFollowed; // gemrb extension (LeaderOf)
+ ieDword LastMarked; // iwd2
+
+ int LastMarkedSpell; // iwd2
+
+ // this is used by GUIScript :(
ieDword LastSpellOnMe; //Last spell cast on this scriptable
- ieDword LastCasterOnMe; //Last spellcaster on this scriptable
- ieDword LastSpellSeen; //Last spell seen to be cast
- ieDword LastCasterSeen; //Last spellcaster seen
+
+ ieDword LastTarget;
Point LastTargetPos;
int SpellHeader;
ieResRef SpellResRef;
+ bool InterruptCasting;
public:
/** Gets the Dialog ResRef */
const char* GetDialog(void) const
@@ -215,7 +306,7 @@ public:
void Activate();
void Deactivate();
void PartyRested();
- ieDword GetInternalFlag();
+ ieDword GetInternalFlag() const;
const char* GetScriptName() const;
Map* GetCurrentArea() const;
void SetMap(Map *map);
@@ -223,45 +314,49 @@ public:
void DisplayHeadText(const char* text);
void FixHeadTextPos();
void SetScriptName(const char* text);
- //call this to deny script running in the next AI cycle
- void DelayedEvent();
//call this to enable script running as soon as possible
void ImmediateEvent();
bool IsPC() const;
- void ExecuteScript(int scriptCount);
+ virtual void Update();
+ void TickScripting();
+ virtual void ExecuteScript(int scriptCount);
void AddAction(Action* aC);
void AddActionInFront(Action* aC);
Action* GetCurrentAction() const { return CurrentAction; }
Action* GetNextAction() const;
Action* PopNextAction();
void ClearActions();
- void ReleaseCurrentAction();
+ virtual void ReleaseCurrentAction();
bool InMove() const;
- void ProcessActions(bool force);
+ void ProcessActions();
//these functions handle clearing of triggers that resulted a
//true condition (whole triggerblock returned true)
void InitTriggers();
- void ClearTriggers();
- void SetBitTrigger(ieDword bittrigger);
- void AddTrigger(ieDword *actorref);
+ void AddTrigger(TriggerEntry trigger);
+ bool MatchTrigger(unsigned short id, ieDword param = 0);
+ bool MatchTriggerWithObject(unsigned short id, class Object *obj, ieDword param = 0);
+ const TriggerEntry *GetMatchingTrigger(unsigned short id, unsigned int notflags = 0);
+ void SendTriggerToAll(TriggerEntry entry);
/* re/draws overhead text on the map screen */
void DrawOverheadText(const Region &screen);
/* check if casting is allowed at all */
- int CanCast(const ieResRef SpellResRef);
+ int CanCast(const ieResRef SpellResRef, bool verbose=true);
/* check for and trigger a wild surge */
int CheckWildSurge();
+ void SpellcraftCheck(const Actor *caster, const ieResRef SpellResRef);
/* actor/scriptable casts spell */
- int CastSpellPoint( ieResRef &SpellRef, const Point &Target, bool deplete, bool instant = false );
- int CastSpell( ieResRef &SpellRef, Scriptable* Target, bool deplete, bool instant = false );
+ int CastSpellPoint( const Point &Target, bool deplete, bool instant = false, bool nointerrupt = false );
+ int CastSpell( Scriptable* Target, bool deplete, bool instant = false, bool nointerrupt = false );
/* spellcasting finished */
- void CastSpellPointEnd(int level);
- void CastSpellEnd(int level);
+ void CastSpellPointEnd(int level, int no_stance);
+ void CastSpellEnd(int level, int no_stance);
ieDword GetGlobalID() const { return globalID; }
/** timer functions (numeric ID, not saved) */
bool TimerActive(ieDword ID);
bool TimerExpired(ieDword ID);
void StartTimer(ieDword ID, ieDword expiration);
virtual char* GetName(int /*which*/) const { return NULL; }
+ bool AuraPolluted();
private:
/* used internally to handle start of spellcasting */
int SpellCast(bool instant);
@@ -269,6 +364,8 @@ private:
void CreateProjectile(const ieResRef SpellResRef, ieDword tgt, int level, bool fake);
/* do some magic for the wierd/awesome wild surges */
bool HandleHardcodedSurge(ieResRef surgeSpellRef, Spell *spl, Actor *caster);
+ void ResetCastingState(Actor* caster);
+ void DisplaySpellCastMessage(ieDword tgt, Spell *spl);
};
class GEM_EXPORT Selectable : public Scriptable {
@@ -300,7 +397,7 @@ public:
/* get stored SpriteCover */
SpriteCover* GetSpriteCover() const { return cover; }
/* want dithered SpriteCover */
- int WantDither();
+ int WantDither() const;
};
class GEM_EXPORT Highlightable : public Scriptable {
@@ -321,6 +418,8 @@ public:
ieWord Trapped;
ieWord TrapDetected;
ieResRef KeyResRef;
+ //play this wav file when stepping on the trap (on PST)
+ ieResRef EnterWav;
public:
bool IsOver(const Point &Pos) const;
void DrawOutline() const;
@@ -333,7 +432,7 @@ public:
void SetTrapDetected(int x);
void TryDisarm(Actor *actor);
//detect trap, set skill to 256 if you want sure fire
- void DetectTrap(int skill);
+ void DetectTrap(int skill, ieDword actorID);
//returns true if trap is visible, only_detected must be true
//if you want to see discovered traps, false is for cheats
bool VisibleTrap(int only_detected) const;
@@ -368,23 +467,12 @@ public:
return step;
}
+ unsigned char GetNextFace();
+
inline unsigned char GetOrientation() const {
return Orientation;
}
- inline unsigned char GetNextFace() {
- //slow turning
- if (Orientation != NewOrientation) {
- if ( ( (NewOrientation-Orientation) & (MAX_ORIENT-1) ) <= MAX_ORIENT/2) {
- Orientation++;
- } else {
- Orientation--;
- }
- Orientation = Orientation&(MAX_ORIENT-1);
- }
-
- return Orientation;
- }
inline unsigned char GetStance() const {
return StanceID;
}
@@ -408,7 +496,6 @@ public:
void WalkTo(const Point &Des, int MinDistance = 0);
void MoveTo(const Point &Des);
void ClearPath();
- void DrawTargetPoint(const Region &vp);
/* returns the most likely position of this actor */
Point GetMostLikelyPosition();
virtual bool BlocksSearchMap() const = 0;
@@ -435,4 +522,6 @@ public:
ieDword closedcount;
};
+}
+
#endif
diff --git a/gemrb/core/ScriptedAnimation.cpp b/gemrb/core/ScriptedAnimation.cpp
index f1c9d9e..d618102 100644
--- a/gemrb/core/ScriptedAnimation.cpp
+++ b/gemrb/core/ScriptedAnimation.cpp
@@ -25,12 +25,18 @@
#include "win32def.h"
+#include "Animation.h"
+#include "AnimationFactory.h"
#include "Audio.h"
#include "Game.h"
#include "GameData.h"
#include "Interface.h"
+#include "Map.h"
+#include "Sprite2D.h"
#include "Video.h"
+namespace GemRB {
+
#define ILLEGAL 0 //
#define ONE 1 //hold
#define TWO 2 //onset + hold
@@ -177,6 +183,8 @@ void ScriptedAnimation::LoadAnimationFactory(AnimationFactory *af, int gettwin)
if (type&DOUBLE) {
c<<=1;
if (gettwin) c++;
+ //this is needed for PST twin animations that contain 2 or 3 phases
+ p*=MAX_ORIENT;
} else if (type&FIVE) {
c=SixteenToFive[c];
if ((i&15)>=5) mirror = true;
@@ -226,7 +234,7 @@ void ScriptedAnimation::LoadAnimationFactory(AnimationFactory *af, int gettwin)
}
/* Creating animation from VVC */
-ScriptedAnimation::ScriptedAnimation(DataStream* stream, bool autoFree)
+ScriptedAnimation::ScriptedAnimation(DataStream* stream)
{
Init();
if (!stream) {
@@ -237,9 +245,8 @@ ScriptedAnimation::ScriptedAnimation(DataStream* stream, bool autoFree)
stream->Read( Signature, 8);
if (strncmp( Signature, "VVC V1.0", 8 ) != 0) {
- printf( "Not a valid VVC File\n" );
- if (autoFree)
- delete( stream );
+ print("Not a valid VVC File");
+ delete stream;
return;
}
ieResRef Anim1ResRef;
@@ -383,9 +390,7 @@ ScriptedAnimation::ScriptedAnimation(DataStream* stream, bool autoFree)
SetPhase(P_ONSET);
- if (autoFree) {
- delete( stream );
- }
+ delete stream;
}
ScriptedAnimation::~ScriptedAnimation(void)
@@ -426,7 +431,7 @@ void ScriptedAnimation::SetPhase(int arg)
void ScriptedAnimation::SetSound(int arg, const ieResRef sound)
{
if (arg>=P_ONSET && arg<=P_RELEASE) {
- memcpy(sounds[arg],sound,sizeof(sound));
+ memcpy(sounds[arg],sound,sizeof(ieResRef));
}
//no need to call the twin
}
@@ -545,13 +550,13 @@ bool ScriptedAnimation::HandlePhase(Sprite2D *&frame)
if (justCreated) {
if (Phase == P_NOTINITED) {
- printMessage("ScriptedAnimation", "Not fully initialised VVC!\n", LIGHT_RED);
+ Log(ERROR, "ScriptedAnimation", "Not fully initialised VVC!");
return true;
}
unsigned long time;
time = core->GetGame()->Ticks;
if (starttime == 0) {
- starttime = time;
+ starttime = time;
}
if (( time - starttime ) >= ( unsigned long ) ( 1000 / FrameRate )) {
inc = (time-starttime)*FrameRate/1000;
@@ -627,7 +632,7 @@ retry:
}
//it is not sure if we need tint at all
-bool ScriptedAnimation::Draw(const Region &screen, const Point &Pos, const Color &p_tint, Map *area, int dither, int orientation)
+bool ScriptedAnimation::Draw(const Region &screen, const Point &Pos, const Color &p_tint, Map *area, int dither, int orientation, int height)
{
if (FaceTarget) {
SetOrientation(orientation);
@@ -635,7 +640,7 @@ bool ScriptedAnimation::Draw(const Region &screen, const Point &Pos, const Color
// not sure
if (twin) {
- twin->Draw(screen, Pos, p_tint, area, dither, -1);
+ twin->Draw(screen, Pos, p_tint, area, dither, -1, height);
}
Video *video = core->GetVideoDriver();
@@ -670,7 +675,7 @@ bool ScriptedAnimation::Draw(const Region &screen, const Point &Pos, const Color
}
if (Transparency & IE_VVC_SEPIA) {
- flag |= BLIT_RED;
+ flag |= BLIT_SEPIA;
}
if (Transparency & BLIT_TINTED) {
@@ -683,6 +688,7 @@ bool ScriptedAnimation::Draw(const Region &screen, const Point &Pos, const Color
int cx = Pos.x + XPos;
int cy = Pos.y - ZPos + YPos;
+ if (SequenceFlags&IE_VVC_HEIGHT) cy-=height;
if( SequenceFlags&IE_VVC_NOCOVER) {
if (cover) SetSpriteCover(NULL);
@@ -715,6 +721,14 @@ void ScriptedAnimation::PreparePalette()
}
}
+void ScriptedAnimation::SetEffectOwned(bool flag)
+{
+ effect_owned=flag;
+ if (twin) {
+ twin->effect_owned=flag;
+ }
+}
+
void ScriptedAnimation::SetBlend()
{
Transparency |= IE_VVC_BLENDED;
@@ -775,3 +789,5 @@ ScriptedAnimation *ScriptedAnimation::DetachTwin()
twin=NULL;
return ret;
}
+
+}
diff --git a/gemrb/core/ScriptedAnimation.h b/gemrb/core/ScriptedAnimation.h
index 088a8bf..6f9dbc4 100644
--- a/gemrb/core/ScriptedAnimation.h
+++ b/gemrb/core/ScriptedAnimation.h
@@ -22,12 +22,17 @@
#include "exports.h"
-#include "AnimationFactory.h"
#include "Audio.h"
-#include "Map.h"
#include "Palette.h"
#include "SpriteCover.h"
-#include "System/DataStream.h"
+
+namespace GemRB {
+
+class Animation;
+class AnimationFactory;
+class DataStream;
+class Map;
+class Sprite2D;
//scripted animation flags
#define S_ANI_PLAYONCE 8 //(same as area animation)
@@ -72,7 +77,7 @@ class GEM_EXPORT ScriptedAnimation {
public:
ScriptedAnimation();
~ScriptedAnimation(void);
- ScriptedAnimation(DataStream* stream, bool autoFree = true);
+ ScriptedAnimation(DataStream* stream);
void Init();
void LoadAnimationFactory(AnimationFactory *af, int gettwin = 0);
void Override(ScriptedAnimation *templ);
@@ -110,7 +115,7 @@ public:
unsigned long starttime;
public:
//draws the next frame of the videocell
- bool Draw(const Region &screen, const Point &Pos, const Color &tint, Map *area, int dither, int orientation);
+ bool Draw(const Region &screen, const Point &Pos, const Color &tint, Map *area, int dither, int orientation, int height);
//sets phase (0-2)
void SetPhase(int arg);
//sets sound for phase (p_onset, p_hold, p_release)
@@ -132,11 +137,13 @@ public:
/* sets up a delay in the beginning of the vvc */
void SetDelay(ieDword delay);
/* sets default duration if it wasn't set yet */
- void SetDefaultDuration(unsigned int duration);
+ void SetDefaultDuration(ieDword duration);
/* sets up the direction of the vvc */
void SetOrientation(int orientation);
/* transforms vvc to blended */
void SetBlend();
+ /* sets the effect owned flag */
+ void SetEffectOwned(bool flag);
/* sets fade effect at end of animation (pst feature) */
void SetFade(ieByte initial, int speed);
/* alters palette with rgb factor */
@@ -150,4 +157,6 @@ private:
void GetPaletteCopy();
};
+}
+
#endif
diff --git a/gemrb/core/SoundMgr.cpp b/gemrb/core/SoundMgr.cpp
index 2172155..3dbfc80 100644
--- a/gemrb/core/SoundMgr.cpp
+++ b/gemrb/core/SoundMgr.cpp
@@ -20,6 +20,8 @@
#include "SoundMgr.h"
+namespace GemRB {
+
const TypeID SoundMgr::ID = { "SoundMgr" };
SoundMgr::SoundMgr(void)
@@ -30,3 +32,5 @@ SoundMgr::SoundMgr(void)
SoundMgr::~SoundMgr(void)
{
}
+
+}
diff --git a/gemrb/core/SoundMgr.h b/gemrb/core/SoundMgr.h
index 3b01a95..c048c31 100644
--- a/gemrb/core/SoundMgr.h
+++ b/gemrb/core/SoundMgr.h
@@ -26,6 +26,8 @@
#include "Resource.h"
#include "System/DataStream.h"
+namespace GemRB {
+
/**
* Base Class for sound plugins
*/
@@ -61,4 +63,6 @@ protected:
int samplerate;
};
+}
+
#endif
diff --git a/gemrb/core/Spell.cpp b/gemrb/core/Spell.cpp
index 06512eb..69232f1 100644
--- a/gemrb/core/Spell.cpp
+++ b/gemrb/core/Spell.cpp
@@ -31,6 +31,45 @@
#include "ProjectileServer.h"
#include "Scriptable/Actor.h"
+namespace GemRB {
+
+struct SpellFocus {
+ ieDword stat;
+ ieDword val1;
+ ieDword val2;
+};
+
+static int pstflags = false;
+static int inited = false;
+SpellFocus *spellfocus = NULL;
+int schoolcount = 0;
+
+static void InitSpellTables()
+{
+ pstflags = !!core->HasFeature(GF_PST_STATE_FLAGS);
+ AutoTable tm("splfocus", true);
+ if (tm) {
+ schoolcount = tm->GetRowCount();
+
+ spellfocus = new SpellFocus [schoolcount];
+ for(int i = 0; i<schoolcount; i++) {
+ ieDword stat = core->TranslateStat(tm->QueryField(i, 0));
+ ieDword val1 = atoi(tm->QueryField(i, 1));
+ ieDword val2 = atoi(tm->QueryField(i, 2));
+ spellfocus[i].stat = stat;
+ spellfocus[i].val1 = val1;
+ spellfocus[i].val2 = val2;
+ }
+ }
+}
+
+
+void ReleaseMemorySpell()
+{
+ inited = false;
+ delete [] spellfocus;
+}
+
SPLExtHeader::SPLExtHeader(void)
{
features = NULL;
@@ -45,6 +84,10 @@ Spell::Spell(void)
{
ext_headers = NULL;
casting_features = NULL;
+ if (!inited) {
+ inited = true;
+ InitSpellTables();
+ }
}
Spell::~Spell(void)
@@ -80,23 +123,30 @@ void Spell::AddCastingGlow(EffectQueue *fxqueue, ieDword duration, int gender)
char g, t;
Effect *fx;
ieResRef Resource;
-
+
int cgsound = CastingSound;
if (cgsound>=0 && duration > 1) {
//bg2 style
- if(cgsound&0x100) {
- switch(gender) {
- default: g = 'm'; break;
- case SEX_FEMALE: g = 'f'; break;
- case SEX_OTHER: case SEX_NEITHER: g = 's'; break;
+ if(cgsound&0x100) {
+ //if duration is less than 3, use only the background sound
+ g = 's';
+ if (duration>3) {
+ switch(gender) {
+ //selection of these sounds is almost purely on whim
+ //though the sounds of devas/demons are probably better this way
+ //all other cases (mostly elementals/animals) don't have sound
+ //externalise if you don't mind another 2da
+ case SEX_MALE: case SEX_SUMMON_DEMON: g = 'm'; break;
+ case SEX_FEMALE: case SEX_BOTH: g = 'f'; break;
+ }
}
} else {
- //how style
-
+ //how style, no pure background sound
+
switch(gender) {
default: g = 'm'; break;
case SEX_FEMALE: g = 'f'; break;
- }
+ }
}
if (SpellType==IE_SPL_PRIEST) {
t = 'p';
@@ -120,6 +170,7 @@ void Spell::AddCastingGlow(EffectQueue *fxqueue, ieDword duration, int gender)
EffectQueue *Spell::GetEffectBlock(Scriptable *self, const Point &pos, int block_index, int level, ieDword pro) const
{
+ bool pst_hostile = false;
Effect *features;
int count;
@@ -131,6 +182,9 @@ EffectQueue *Spell::GetEffectBlock(Scriptable *self, const Point &pos, int block
} else {
features = ext_headers[block_index].features;
count = ext_headers[block_index].FeatureCount;
+ if (pstflags && !(ext_headers[block_index].Hostile&4)) {
+ pst_hostile = true;
+ }
}
} else {
features = casting_features;
@@ -156,6 +210,10 @@ EffectQueue *Spell::GetEffectBlock(Scriptable *self, const Point &pos, int block
fx->InventorySlot = 0xffff;
//the hostile flag is used to determine if this was an attack
fx->SourceFlags = Flags;
+ //pst spells contain a friendly flag in the spell header
+ if (pst_hostile) {
+ fx->SourceFlags|=SF_HOSTILE;
+ }
fx->CasterLevel = level;
// apply the stat-based spell duration modifier
@@ -166,6 +224,19 @@ EffectQueue *Spell::GetEffectBlock(Scriptable *self, const Point &pos, int block
} else if (caster->Modified[IE_SPELLDURATIONMODPRIEST] && SpellType == IE_SPL_PRIEST) {
fx->Duration = (fx->Duration * caster->Modified[IE_SPELLDURATIONMODPRIEST]) / 100;
}
+
+ //evaluate spell focus feats
+ //TODO: the usual problem: which saving throw is better? Easy fix in the data file.
+ if (fx->PrimaryType<(ieDword) schoolcount) {
+ ieDword stat = spellfocus[fx->PrimaryType].stat;
+ if (stat>0) {
+ switch (caster->Modified[stat]) {
+ case 0: break;
+ case 1: fx->SavingThrowBonus += spellfocus[fx->PrimaryType].val1; break;
+ default: fx->SavingThrowBonus += spellfocus[fx->PrimaryType].val2; break;
+ }
+ }
+ }
}
if (fx->Target != FX_TARGET_SELF) {
@@ -192,17 +263,17 @@ EffectQueue *Spell::GetEffectBlock(Scriptable *self, const Point &pos, int block
return fxqueue;
}
-Projectile *Spell::GetProjectile(Scriptable *self, int header, const Point &target) const
+Projectile *Spell::GetProjectile(Scriptable *self, int header, int level, const Point &target) const
{
SPLExtHeader *seh = GetExtHeader(header);
if (!seh) {
- printMessage("Spell", "Cannot retrieve spell header!!! ",RED);
- printf("required header: %d, maximum: %d\n", header, (int) ExtHeaderCount);
+ Log(ERROR, "Spell", "Cannot retrieve spell header!!! required header: %d, maximum: %d",
+ header, (int) ExtHeaderCount);
return NULL;
}
Projectile *pro = core->GetProjectileServer()->GetProjectileByIndex(seh->ProjectileAnimation);
if (seh->FeatureCount) {
- pro->SetEffects(GetEffectBlock(self, target, header, seh->ProjectileAnimation));
+ pro->SetEffects(GetEffectBlock(self, target, header, level, seh->ProjectileAnimation));
}
return pro;
}
@@ -225,8 +296,8 @@ unsigned int Spell::GetCastingDistance(Scriptable *Sender) const
int idx = GetHeaderIndexFromLevel(level);
SPLExtHeader *seh = GetExtHeader(idx);
if (!seh) {
- printMessage("Spell", "Cannot retrieve spell header!!! ",RED);
- printf("required header: %d, maximum: %d\n", idx, (int) ExtHeaderCount);
+ Log(ERROR, "Spell", "Cannot retrieve spell header!!! required header: %d, maximum: %d",
+ idx, (int) ExtHeaderCount);
return 0;
}
@@ -235,3 +306,24 @@ unsigned int Spell::GetCastingDistance(Scriptable *Sender) const
}
return (unsigned int) seh->Range;
}
+
+static EffectRef fx_damage_ref = { "Damage", -1 };
+// checks if any of the extended headers contains fx_damage
+bool Spell::ContainsDamageOpcode() const
+{
+ ieDword damage_opcode = EffectQueue::ResolveEffect(fx_damage_ref);
+ for (int h=0; h< ExtHeaderCount; h++) {
+ for (int i=0; i< ext_headers[h].FeatureCount; i++) {
+ Effect *fx = ext_headers[h].features+i;
+ if (fx->Opcode == damage_opcode) {
+ return true;
+ }
+ }
+ if (Flags & SF_SIMPLIFIED_DURATION) { // iwd2 has only one header
+ break;
+ }
+ }
+ return false;
+}
+
+}
diff --git a/gemrb/core/Spell.h b/gemrb/core/Spell.h
index 810cb41..7dad23e 100644
--- a/gemrb/core/Spell.h
+++ b/gemrb/core/Spell.h
@@ -33,6 +33,8 @@
#include "EffectQueue.h"
+namespace GemRB {
+
class Projectile;
//values for Spell usability Flags
@@ -60,6 +62,9 @@ class Projectile;
#define SPEC_IDENTIFY 1 //spells that don't appear in the casting bar
#define SPEC_SILENCE 2 //spells that can be cast when silenced
#define SPEC_DEAD 4 //spells that can target dead actors despite their target type is 1 (pst hack)
+
+extern void ReleaseMemorySpell();
+
/**
* @class SPLExtHeader
* Header for Spell special effects
@@ -71,7 +76,7 @@ public:
~SPLExtHeader();
ieByte SpellForm;
- ieByte unknown1;
+ ieByte Hostile;
ieByte Location;
ieByte unknown2;
ieResRef MemorisedIcon;
@@ -167,8 +172,11 @@ public:
// add appropriate casting glow effect
void AddCastingGlow(EffectQueue *fxqueue, ieDword duration, int gender);
//returns a projectile created from an extended header
- Projectile *GetProjectile(Scriptable *self, int headerindex, const Point &pos) const;
+ Projectile *GetProjectile(Scriptable *self, int headerindex, int level, const Point &pos) const;
unsigned int GetCastingDistance(Scriptable *Sender) const;
+ bool ContainsDamageOpcode() const;
};
+}
+
#endif // ! SPELL_H
diff --git a/gemrb/core/SpellMgr.cpp b/gemrb/core/SpellMgr.cpp
index 661588f..2e45cfe 100644
--- a/gemrb/core/SpellMgr.cpp
+++ b/gemrb/core/SpellMgr.cpp
@@ -20,6 +20,8 @@
#include "SpellMgr.h"
+namespace GemRB {
+
SpellMgr::SpellMgr(void)
{
}
@@ -27,3 +29,5 @@ SpellMgr::SpellMgr(void)
SpellMgr::~SpellMgr(void)
{
}
+
+}
diff --git a/gemrb/core/SpellMgr.h b/gemrb/core/SpellMgr.h
index 44c1032..6ac6b18 100644
--- a/gemrb/core/SpellMgr.h
+++ b/gemrb/core/SpellMgr.h
@@ -31,6 +31,8 @@
#include "Spell.h"
#include "System/DataStream.h"
+namespace GemRB {
+
/**
* @class SpellMgr
* Abstract loader for Spell objects
@@ -40,8 +42,10 @@ class GEM_EXPORT SpellMgr : public Plugin {
public:
SpellMgr(void);
virtual ~SpellMgr(void);
- virtual bool Open(DataStream* stream, bool autoFree = true) = 0;
+ virtual bool Open(DataStream* stream) = 0;
virtual Spell* GetSpell(Spell *spl, bool silent=false) = 0;
};
+}
+
#endif
diff --git a/gemrb/core/Spellbook.cpp b/gemrb/core/Spellbook.cpp
index b910faf..e722ee8 100644
--- a/gemrb/core/Spellbook.cpp
+++ b/gemrb/core/Spellbook.cpp
@@ -20,15 +20,20 @@
#include "Spellbook.h"
+#include "ActorMgr.h"
#include "GameData.h"
#include "Interface.h"
+#include "PluginMgr.h"
#include "Projectile.h"
#include "Spell.h"
#include "TableMgr.h"
#include "Scriptable/Actor.h"
+#include "System/StringBuffer.h"
#include <cstdio>
+namespace GemRB {
+
static bool SBInitialized = false;
static int NUM_BOOK_TYPES = 3;
static bool IWD2Style = false;
@@ -45,6 +50,12 @@ Spellbook::Spellbook()
InitializeSpellbook();
}
spells = new std::vector<CRESpellMemorization*> [NUM_BOOK_TYPES];
+ sorcerer = 0;
+ if (IWD2Style) {
+ innate = 1<<IE_IWD2_SPELL_INNATE;
+ } else {
+ innate = 1<<IE_SPELL_TYPE_INNATE;
+ }
}
void Spellbook::InitializeSpellbook()
@@ -53,8 +64,10 @@ void Spellbook::InitializeSpellbook()
SBInitialized=true;
if (core->HasFeature(GF_HAS_SPELLLIST)) {
NUM_BOOK_TYPES=NUM_IWD2_SPELLTYPES; //iwd2 spell types
+ IWD2Style = true;
} else {
NUM_BOOK_TYPES=NUM_SPELLTYPES; //bg/pst/iwd1 spell types
+ IWD2Style = false;
}
}
return;
@@ -120,8 +133,8 @@ void Spellbook::CopyFrom(const Actor *source)
CRESpellMemorization *sm = new CRESpellMemorization();
spells[t].push_back(sm);
sm->Level = wm->Level;
- sm->Number = wm->Number;
- sm->Number2 = wm->Number2;
+ sm->SlotCount = wm->SlotCount;
+ sm->SlotCountWithBonus = wm->SlotCountWithBonus;
sm->Type = wm->Type;
for (k = 0; k < wm->known_spells.size(); k++) {
CREKnownSpell *tmp_known = new CREKnownSpell();
@@ -141,21 +154,65 @@ void Spellbook::CopyFrom(const Actor *source)
//ITEM, SPPR, SPWI, SPIN, SPCL
int sections[]={3,0,1,2,2};
+// domain spells are of all types, so look them up in all cases
+// ignore songs and shapes altogether
+int arcanetypes[] = {IE_IWD2_SPELL_BARD, IE_IWD2_SPELL_SORCERER, IE_IWD2_SPELL_WIZARD, IE_IWD2_SPELL_DOMAIN};
+int divinetypes[] = {IE_IWD2_SPELL_CLERIC, IE_IWD2_SPELL_DRUID, IE_IWD2_SPELL_PALADIN, IE_IWD2_SPELL_RANGER, IE_IWD2_SPELL_DOMAIN};
+int *alltypes[2] = {divinetypes, arcanetypes};
-//flags bits
-// 1 - unmemorize it
-bool Spellbook::HaveSpell(int spellid, ieDword flags)
+int inline GetType(int spellid, unsigned int &bookcount, int &idx)
{
int type = spellid/1000;
if (type>4) {
- return false;
+ return -1;
+ }
+ if (IWD2Style) {
+ if (type == 1) {
+ // check divine
+ idx = 0;
+ bookcount = sizeof(divinetypes)/sizeof(int);
+ } else if (type == 2) {
+ // check arcane
+ idx = 1;
+ bookcount = sizeof(arcanetypes)/sizeof(int);
+ } else if (type == 3) {
+ type = IE_IWD2_SPELL_INNATE;
+ }
+ } else {
+ type = sections[type];
+ if (type >= NUM_BOOK_TYPES) {
+ return -1;
+ }
}
- type = sections[type];
- if (type >= NUM_BOOK_TYPES) {
+ return type;
+}
+
+//flags bits
+// 1 - unmemorize it
+bool Spellbook::HaveSpell(int spellid, ieDword flags)
+{
+ int idx = -1;
+ unsigned int bookcount;
+ int type = GetType(spellid, bookcount, idx);
+ if (type == -1) {
return false;
}
+
spellid = spellid % 1000;
+ if (idx == -1) {
+ return HaveSpell(spellid, type, flags);
+ } else {
+ for (unsigned int book = 0; book < bookcount; book++) {
+ if (HaveSpell(spellid, alltypes[idx][book], flags)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+bool Spellbook::HaveSpell(int spellid, int type, ieDword flags)
+{
for (unsigned int j = 0; j < GetSpellLevelCount(type); j++) {
CRESpellMemorization* sm = spells[type][j];
for (unsigned int k = 0; k < sm->memorized_spells.size(); k++) {
@@ -164,7 +221,7 @@ bool Spellbook::HaveSpell(int spellid, ieDword flags)
if (atoi(ms->SpellResRef+4)==spellid) {
if (flags&HS_DEPLETE) {
if (DepleteSpell(ms) && (sorcerer & (1<<type) ) ) {
- DepleteLevel (sm);
+ DepleteLevel (sm, ms->SpellResRef);
}
}
return true;
@@ -175,21 +232,64 @@ bool Spellbook::HaveSpell(int spellid, ieDword flags)
return false;
}
-bool Spellbook::KnowSpell(int spellid)
+//returns count of memorized spells of a given name/type
+int Spellbook::CountSpells(const char *resref, unsigned int type, int flag) const
{
- int type = spellid/1000;
- if (type>4) {
- return false;
+ int i, max;
+ int count = 0;
+
+ if (type==0xffffffff) {
+ i=0;
+ max = NUM_BOOK_TYPES;
+ } else {
+ i = type;
+ max = i+1;
}
- type = sections[type];
- if (type >= NUM_BOOK_TYPES) {
+
+ while(i < max) {
+ for (unsigned int j = 0; j < spells[i].size(); j++) {
+ CRESpellMemorization* sm = spells[i][j];
+ for (unsigned int k = 0; k < sm->memorized_spells.size(); k++) {
+ CREMemorizedSpell* ms = sm->memorized_spells[k];
+ if (resref[0] && !stricmp(ms->SpellResRef, resref) ) {
+ if (flag || ms->Flags) {
+ count++;
+ }
+ }
+ }
+ }
+ i++;
+ }
+ return count;
+}
+
+bool Spellbook::KnowSpell(int spellid) const
+{
+ int idx = -1;
+ unsigned int bookcount;
+ int type = GetType(spellid, bookcount, idx);
+ if (type == -1) {
return false;
}
spellid = spellid % 1000;
+ if (idx == -1) {
+ return KnowSpell(spellid, type);
+ } else {
+ for (unsigned int book = 0; book < bookcount; book++) {
+ if (KnowSpell(spellid, alltypes[idx][book])) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool Spellbook::KnowSpell(int spellid, int type) const
+{
for (unsigned int j = 0; j < GetSpellLevelCount(type); j++) {
CRESpellMemorization* sm = spells[type][j];
- for (unsigned int k = 0; k < sm->memorized_spells.size(); k++) {
+ for (unsigned int k = 0; k < sm->known_spells.size(); k++) {
CREKnownSpell* ks = sm->known_spells[k];
if (atoi(ks->SpellResRef+4)==spellid) {
return true;
@@ -200,12 +300,12 @@ bool Spellbook::KnowSpell(int spellid)
}
//if resref=="" then it is a knownanyspell
-bool Spellbook::KnowSpell(const char *resref)
+bool Spellbook::KnowSpell(const char *resref) const
{
for (int i = 0; i < NUM_BOOK_TYPES; i++) {
for (unsigned int j = 0; j < spells[i].size(); j++) {
CRESpellMemorization* sm = spells[i][j];
- for (unsigned int k = 0; k < sm->memorized_spells.size(); k++) {
+ for (unsigned int k = 0; k < sm->known_spells.size(); k++) {
CREKnownSpell* ks = sm->known_spells[k];
if (resref[0] && stricmp(ks->SpellResRef, resref) ) {
continue;
@@ -231,7 +331,7 @@ bool Spellbook::HaveSpell(const char *resref, ieDword flags)
}
if (flags&HS_DEPLETE) {
if (DepleteSpell(ms) && (sorcerer & (1<<i) ) ) {
- DepleteLevel (sm);
+ DepleteLevel (sm, ms->SpellResRef);
}
}
return true;
@@ -285,7 +385,7 @@ unsigned int Spellbook::GetTotalMemorizedSpellsCount() const
for (int type = 0; type < NUM_BOOK_TYPES; type++) {
unsigned int level = GetSpellLevelCount(type);
while(level--) {
- total += GetMemorizedSpellsCount(type, level);
+ total += GetMemorizedSpellsCount(type, level, false);
}
}
return total;
@@ -343,15 +443,26 @@ bool Spellbook::RemoveSpell(CREKnownSpell* spell)
//IWD2 clab files use it
void Spellbook::RemoveSpell(int spellid)
{
- int type = spellid/1000;
- if (type>4) {
- return;
- }
- type = sections[type];
- if (type >= NUM_BOOK_TYPES) {
+ int idx = -1;
+ unsigned int bookcount;
+ int type = GetType(spellid, bookcount, idx);
+ if (type == -1) {
return;
}
spellid = spellid % 1000;
+
+ if (idx == -1) {
+ RemoveSpell(spellid, type);
+ } else {
+ for (unsigned int book = 0; book < bookcount; book++) {
+ RemoveSpell(spellid, alltypes[idx][book]);
+ }
+ }
+
+}
+
+void Spellbook::RemoveSpell(int spellid, int type)
+{
std::vector< CRESpellMemorization* >::iterator sm;
for (sm = spells[type].begin(); sm != spells[type].end(); sm++) {
std::vector< CREKnownSpell* >::iterator ks;
@@ -405,30 +516,30 @@ void Spellbook::SetBookType(int bt)
//wildshapes are marked as innate, they need some hack to get stored
//in the right group
//the rest are stored as innate
-int Spellbook::GetSpellType(int spelltype)
-{
- if (IWD2Style) return spelltype;
-
- if (spelltype<6) {
- return spelltypes[spelltype];
- }
- return IE_SPELL_TYPE_INNATE;
-}
-int Spellbook::LearnSpell(Spell *spell, int memo)
+int Spellbook::LearnSpell(Spell *spell, int memo, unsigned int clsmsk, unsigned int kit)
{
CREKnownSpell *spl = new CREKnownSpell();
- strncpy(spl->SpellResRef, spell->Name, 8);
- spl->Type = (ieWord) GetSpellType(spell->SpellType);
- if ( spl->Type == IE_SPELL_TYPE_INNATE) {
- spl->Level = 0;
- }
- else {
- spl->Level = (ieWord) (spell->SpellLevel-1);
+ CopyResRef(spl->SpellResRef, spell->Name);
+ spl->Level = 0;
+ if (IWD2Style) {
+ PluginHolder<ActorMgr> gm(IE_CRE_CLASS_ID);
+ spl->Type = gm->FindSpellType(spell->Name, spl->Level, clsmsk, kit);
+ return spell->SpellLevel;
+ }
+
+ //not IWD2
+ if (spell->SpellType<6) {
+ spl->Type = spelltypes[spell->SpellType];
+ spl->Level = spell->SpellLevel-1;
+ } else {
+ spl->Type = IE_SPELL_TYPE_INNATE;
}
+
bool ret=AddKnownSpell(spl, memo);
if (!ret) {
delete spl;
+ return 0;
}
return spell->SpellLevel; // return only the spell level (xp is based on xpbonus)
}
@@ -445,7 +556,7 @@ bool Spellbook::AddKnownSpell(CREKnownSpell *spl, int flg)
CRESpellMemorization *sm = new CRESpellMemorization();
sm->Type = (ieWord) type;
sm->Level = (ieWord) level;
- sm->Number = sm->Number2 = 0;
+ sm->SlotCount = sm->SlotCountWithBonus = 0;
if ( !AddSpellMemorization(sm) ) {
delete sm;
return false;
@@ -454,8 +565,8 @@ bool Spellbook::AddKnownSpell(CREKnownSpell *spl, int flg)
spells[type][level]->known_spells.push_back(spl);
if (type==IE_SPELL_TYPE_INNATE) {
- spells[type][level]->Number++;
- spells[type][level]->Number2++;
+ spells[type][level]->SlotCount++;
+ spells[type][level]->SlotCountWithBonus++;
}
if (flg) {
MemorizeSpell(spl, true);
@@ -470,25 +581,69 @@ CREKnownSpell* Spellbook::GetKnownSpell(int type, unsigned int level, unsigned i
return spells[type][level]->known_spells[index];
}
-unsigned int Spellbook::GetMemorizedSpellsCount(int type) const
+unsigned int Spellbook::GetMemorizedSpellsCount(int type, bool real) const
{
unsigned int count = 0;
size_t i=GetSpellLevelCount(type);
while(i--) {
- count += (unsigned int) spells[type][i]->memorized_spells.size();
+ if (real) {
+ int j = spells[type][i]->memorized_spells.size();
+ while(j--) {
+ if (spells[type][i]->memorized_spells[j]->Flags) count++;
+ }
+ } else {
+ count += (unsigned int) spells[type][i]->memorized_spells.size();
+ }
}
return count;
}
-unsigned int Spellbook::GetMemorizedSpellsCount(int type, unsigned int level) const
+unsigned int Spellbook::GetMemorizedSpellsCount(int type, unsigned int level, bool real) const
{
if (type >= NUM_BOOK_TYPES)
return 0;
if (level >= GetSpellLevelCount(type))
return 0;
+ if (real) {
+ unsigned int count = 0;
+ int j = spells[type][level]->memorized_spells.size();
+ while(j--) {
+ if (spells[type][level]->memorized_spells[j]->Flags) count++;
+ }
+ return count;
+ }
return (unsigned int) spells[type][level]->memorized_spells.size();
}
+unsigned int Spellbook::GetMemorizedSpellsCount(const ieResRef name, int type, bool real) const
+{
+ if (type >= NUM_BOOK_TYPES)
+ return 0;
+ int t;
+ if (type<0) {
+ t = NUM_BOOK_TYPES-1;
+ } else {
+ t = type;
+ }
+
+ int j = 0;
+ while(t>=0) {
+ unsigned int level = GetSpellLevelCount(t);
+ while(level--) {
+ int i = spells[t][level]->memorized_spells.size();
+ while(i--) {
+ CREMemorizedSpell *cms = spells[t][level]->memorized_spells[i];
+
+ if (strnicmp(cms->SpellResRef, name, sizeof(ieResRef) ) ) continue;
+ if (!real || cms->Flags) j++;
+ }
+ }
+ if (type>=0) break;
+ t--;
+ }
+ return j;
+}
+
CREMemorizedSpell* Spellbook::GetMemorizedSpell(int type, unsigned int level, unsigned int index) const
{
if (type >= NUM_BOOK_TYPES || level >= GetSpellLevelCount(type) || index >= spells[type][level]->memorized_spells.size())
@@ -515,7 +670,7 @@ bool Spellbook::AddSpellMemorization(CRESpellMemorization* sm)
CRESpellMemorization *newsm = new CRESpellMemorization();
newsm->Type = sm->Type;
newsm->Level = (ieWord) s->size();
- newsm->Number = newsm->Number2 = 0;
+ newsm->SlotCount = newsm->SlotCountWithBonus = 0;
s->push_back( newsm );
}
@@ -533,7 +688,10 @@ void Spellbook::BonusSpells(int type, int count, int *bonuses)
if (level>count) level=count;
for (int i = 0; i < level; i++) {
CRESpellMemorization* sm = GetSpellMemorization(type, i);
- sm->Number2+=bonuses[i];
+ // don't give access to new spell levels through these boni
+ if (sm->SlotCountWithBonus) {
+ sm->SlotCountWithBonus+=bonuses[i];
+ }
}
}
@@ -547,7 +705,7 @@ void Spellbook::ClearBonus()
int level = GetSpellLevelCount(type);
for (int i = 0; i < level; i++) {
CRESpellMemorization* sm = GetSpellMemorization(type, i);
- sm->Number2=sm->Number;
+ sm->SlotCountWithBonus=sm->SlotCount;
}
}
}
@@ -562,7 +720,7 @@ CRESpellMemorization *Spellbook::GetSpellMemorization(unsigned int type, unsigne
sm = new CRESpellMemorization();
sm->Type = (ieWord) type;
sm->Level = (ieWord) level;
- sm->Number = sm->Number2 = 0;
+ sm->SlotCount = sm->SlotCountWithBonus = 0;
if ( !AddSpellMemorization(sm) ) {
delete sm;
return NULL;
@@ -588,14 +746,14 @@ void Spellbook::SetMemorizableSpellsCount(int Value, int type, unsigned int leve
CRESpellMemorization* sm = GetSpellMemorization(type, level);
if (bonus) {
if (!Value) {
- Value=sm->Number;
+ Value=sm->SlotCount;
}
- sm->Number2=(ieWord) (sm->Number2+Value);
+ sm->SlotCountWithBonus=(ieWord) (sm->SlotCountWithBonus+Value);
}
else {
- diff=sm->Number2-sm->Number;
- sm->Number=(ieWord) Value;
- sm->Number2=(ieWord) (Value+diff);
+ diff=sm->SlotCountWithBonus-sm->SlotCount;
+ sm->SlotCount=(ieWord) Value;
+ sm->SlotCountWithBonus=(ieWord) (Value+diff);
}
}
@@ -605,21 +763,22 @@ int Spellbook::GetMemorizableSpellsCount(int type, unsigned int level, bool bonu
return 0;
CRESpellMemorization* sm = spells[type][level];
if (bonus)
- return sm->Number2;
- return sm->Number;
+ return sm->SlotCountWithBonus;
+ return sm->SlotCount;
}
bool Spellbook::MemorizeSpell(CREKnownSpell* spell, bool usable)
{
- CRESpellMemorization* sm = spells[spell->Type][spell->Level];
- if (sm->Number2 <= sm->memorized_spells.size()) {
+ ieWord spellType = spell->Type;
+ CRESpellMemorization* sm = spells[spellType][spell->Level];
+ if (sm->SlotCountWithBonus <= sm->memorized_spells.size() && !(innate & (1<<spellType))) {
//it is possible to have sorcerer type spellbooks for any spellbook type
- if (! (sorcerer & (1<<spell->Type) ) )
+ if (! (sorcerer & (1<<spellType) ) )
return false;
}
CREMemorizedSpell* mem_spl = new CREMemorizedSpell();
- strncpy( mem_spl->SpellResRef, spell->SpellResRef, 8 );
+ CopyResRef( mem_spl->SpellResRef, spell->SpellResRef );
mem_spl->Flags = usable ? 1 : 0; // FIXME: is it all it's used for?
sm->memorized_spells.push_back( mem_spl );
@@ -647,7 +806,7 @@ bool Spellbook::UnmemorizeSpell(CREMemorizedSpell* spell)
return false;
}
-bool Spellbook::UnmemorizeSpell(const ieResRef ResRef, bool deplete)
+bool Spellbook::UnmemorizeSpell(const ieResRef ResRef, bool deplete, bool onlydepleted)
{
for (int type = 0; type<NUM_BOOK_TYPES; type++) {
std::vector< CRESpellMemorization* >::iterator sm;
@@ -657,6 +816,9 @@ bool Spellbook::UnmemorizeSpell(const ieResRef ResRef, bool deplete)
if (strnicmp(ResRef, (*s)->SpellResRef, sizeof(ieResRef) ) ) {
continue;
}
+ if (onlydepleted && (*s)->Flags != 0) {
+ continue;
+ }
if (deplete) {
(*s)->Flags = 0;
} else {
@@ -674,7 +836,7 @@ bool Spellbook::UnmemorizeSpell(const ieResRef ResRef, bool deplete)
//bitfield disabling type: 1 - mage, 2 - cleric etc
//level: if set, then finds that level only
-CREMemorizedSpell* Spellbook::FindUnchargedSpell(int type, int level)
+CREMemorizedSpell* Spellbook::FindUnchargedSpell(int type, int level) const
{
int mask=1;
@@ -714,7 +876,7 @@ void Spellbook::CreateSorcererMemory(int type)
sm->memorized_spells.clear();
for (unsigned int k = 0; k < sm->known_spells.size(); k++) {
CREKnownSpell *ck = sm->known_spells[k];
- cnt = sm->Number2;
+ cnt = sm->SlotCountWithBonus;
while(cnt--) {
MemorizeSpell(ck, true);
}
@@ -755,7 +917,7 @@ bool Spellbook::DepleteSpell(int type)
for (unsigned int k = 0; k < sm->memorized_spells.size(); k++) {
if (DepleteSpell( sm->memorized_spells[k] )) {
if (sorcerer & (1<<type) ) {
- DepleteLevel (sm);
+ DepleteLevel (sm, sm->memorized_spells[k]->SpellResRef);
}
return true;
}
@@ -764,19 +926,23 @@ bool Spellbook::DepleteSpell(int type)
return false;
}
-void Spellbook::DepleteLevel(CRESpellMemorization* sm)
+void Spellbook::DepleteLevel(CRESpellMemorization* sm, const ieResRef except)
{
size_t cnt = sm->memorized_spells.size();
ieResRef last={""};
+
for (size_t i = 0; i < cnt && cnt>0; i++) {
CREMemorizedSpell *cms = sm->memorized_spells[i];
//sorcerer spells are created in orderly manner
- if (strncmp(last,cms->SpellResRef,8) ) {
+ if (cms->Flags && strncmp(last,cms->SpellResRef,8) && strncmp(except,cms->SpellResRef,8)) {
memcpy(last, cms->SpellResRef, sizeof(ieResRef) );
+ cms->Flags=0;
+/*
delete cms;
sm->memorized_spells.erase(sm->memorized_spells.begin()+i);
i--;
cnt--;
+*/
}
}
}
@@ -799,7 +965,7 @@ bool Spellbook::DepleteSpell(int type, unsigned int page, unsigned int slot)
CREMemorizedSpell* cms = sm->memorized_spells[slot];
ret = DepleteSpell(cms);
if (ret && (sorcerer & (1<<type) ) ) {
- DepleteLevel (sm);
+ DepleteLevel (sm, cms->SpellResRef);
}
return ret;
@@ -878,6 +1044,27 @@ unsigned int Spellbook::GetSpellInfoSize(int type)
return count;
}
+//type = 0 means any type
+int Spellbook::FindSpellInfo(SpellExtHeader *array, const ieResRef spellname, unsigned int type)
+{
+ memset(array, 0, sizeof(SpellExtHeader) );
+ if (spellinfo.size() == 0) {
+ GenerateSpellInfo();
+ }
+ int offset = 0;
+ for (unsigned int i = 0; i<spellinfo.size(); i++) {
+ // take the offset into account, since we need per-type indices
+ if (type && !(1<<(spellinfo[i]->type) & type)) {
+ offset++;
+ continue;
+ }
+ if (strnicmp(spellinfo[i]->spellname, spellname, sizeof(ieResRef) ) ) continue;
+ memcpy(array, spellinfo[i], sizeof(SpellExtHeader));
+ return i-offset+1;
+ }
+ return 0;
+}
+
SpellExtHeader *Spellbook::FindSpellInfo(unsigned int level, unsigned int type, const ieResRef spellname)
{
size_t i = spellinfo.size();
@@ -893,7 +1080,7 @@ SpellExtHeader *Spellbook::FindSpellInfo(unsigned int level, unsigned int type,
void Spellbook::AddSpellInfo(unsigned int sm_level, unsigned int sm_type, const ieResRef spellname, unsigned int idx)
{
- Spell *spl = gamedata->GetSpell(spellname);
+ Spell *spl = gamedata->GetSpell(spellname, true);
if (!spl)
return;
if (spl->ExtHeaderCount<1)
@@ -908,16 +1095,16 @@ void Spellbook::AddSpellInfo(unsigned int sm_level, unsigned int sm_type, const
seh = new SpellExtHeader;
spellinfo.push_back( seh );
-
+
memcpy(seh->spellname, spellname, sizeof(ieResRef) );
int ehc;
-
+
for (ehc = 0; ehc < spl->ExtHeaderCount-1; ehc++) {
if (level<spl->ext_headers[ehc+1].RequiredLevel) {
break;
}
}
-
+
SPLExtHeader *ext_header = spl->ext_headers+ehc;
seh->headerindex = ehc;
seh->level = sm_level;
@@ -956,7 +1143,7 @@ void Spellbook::SetCustomSpellInfo(ieResRef *data, ieResRef spell, int type)
if (!slot)
continue;
//skip the spell itself
- if (!strnicmp(slot->SpellResRef, spell, sizeof(ieResRef)))
+ if (spell && !strnicmp(slot->SpellResRef, spell, sizeof(ieResRef)))
continue;
AddSpellInfo(sm->Level, sm->Type, slot->SpellResRef, -1);
}
@@ -985,32 +1172,41 @@ void Spellbook::GenerateSpellInfo()
}
}
-void Spellbook::dump()
+void Spellbook::dump() const
+{
+ StringBuffer buffer;
+ dump(buffer);
+ Log(DEBUG, "Spellbook", buffer);
+}
+
+void Spellbook::dump(StringBuffer& buffer) const
{
unsigned int k;
- printf( "SPELLBOOK:\n" );
+ buffer.append( "SPELLBOOK:\n" );
for (int i = 0; i < NUM_BOOK_TYPES; i++) {
for (unsigned int j = 0; j < spells[i].size(); j++) {
CRESpellMemorization* sm = spells[i][j];
if (sm->known_spells.size())
- printf( " Known spells:\n" );
+ buffer.append( " Known spells:\n" );
for (k = 0; k < sm->known_spells.size(); k++) {
CREKnownSpell* spl = sm->known_spells[k];
if (!spl) continue;
- printf ( " %2d: %8s L: %d T: %d\n", k, spl->SpellResRef, spl->Level, spl->Type );
+ buffer.appendFormatted ( " %2d: %8s L: %d T: %d\n", k, spl->SpellResRef, spl->Level, spl->Type );
}
if (sm->memorized_spells.size())
- printf( " Memorized spells:\n" );
+ buffer.append( " Memorized spells:\n" );
for (k = 0; k < sm->memorized_spells.size (); k++) {
CREMemorizedSpell* spl = sm->memorized_spells[k];
if (!spl) continue;
- printf ( " %2u: %8s %x\n", k, spl->SpellResRef, spl->Flags );
+ buffer.appendFormatted ( " %2u: %8s %x\n", k, spl->SpellResRef, spl->Flags );
}
}
}
}
+
+}
diff --git a/gemrb/core/Spellbook.h b/gemrb/core/Spellbook.h
index 97c962e..43a1f4a 100644
--- a/gemrb/core/Spellbook.h
+++ b/gemrb/core/Spellbook.h
@@ -8,7 +8,7 @@
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
@@ -34,8 +34,11 @@
#include <vector>
+namespace GemRB {
+
class Actor;
class Spell;
+class StringBuffer;
#define MAX_SPELL_LEVEL 16
@@ -74,7 +77,7 @@ typedef enum ieIWD2SpellType {
IE_IWD2_SPELL_DRUID = 2,
IE_IWD2_SPELL_PALADIN = 3,
IE_IWD2_SPELL_RANGER = 4,
- IE_IWD2_SPELL_SORCEROR = 5,
+ IE_IWD2_SPELL_SORCERER = 5,
IE_IWD2_SPELL_WIZARD = 6,
IE_IWD2_SPELL_DOMAIN = 7,
IE_IWD2_SPELL_INNATE = 8,
@@ -96,10 +99,10 @@ struct CREMemorizedSpell {
};
struct CRESpellMemorization {
- ieWord Level;
- ieWord Number;
- ieWord Number2;
- ieWord Type;
+ ieWord Level;
+ ieWord SlotCount;
+ ieWord SlotCountWithBonus;
+ ieWord Type;
std::vector<CREKnownSpell*> known_spells;
std::vector<CREMemorizedSpell*> memorized_spells;
@@ -108,7 +111,7 @@ struct CRESpellMemorization {
struct SpellExtHeader {
ieDword level;
ieDword count;
- ieDword type; //spelltype
+ ieDword type; //spelltype
ieDword headerindex;
ieDword slot;
//these come from the header
@@ -121,7 +124,7 @@ struct SpellExtHeader {
ieWord CastingTime;
//other data
ieResRef spellname;
- ieDword strref; //the spell's name
+ ieDword strref; //the spell's name
};
/**
@@ -134,11 +137,12 @@ private:
std::vector<CRESpellMemorization*> *spells;
std::vector<SpellExtHeader*> spellinfo;
int sorcerer;
+ int innate;
/** Sets spell from memorized as 'already-cast' */
bool DepleteSpell(CREMemorizedSpell* spl);
/** Depletes a sorcerer type spellpage by one */
- void DepleteLevel(CRESpellMemorization* sm);
+ void DepleteLevel(CRESpellMemorization* sm, const ieResRef except);
/** Adds a single spell to the spell info list */
void AddSpellInfo(unsigned int level, unsigned int type, const ieResRef name, unsigned int idx);
/** regenerates the spellinfo list */
@@ -152,6 +156,9 @@ private:
/** Adds a new CRESpellMemorization, to the *end* only */
bool AddSpellMemorization(CRESpellMemorization* sm);
+ bool HaveSpell(int spellid, int type, ieDword flags);
+ bool KnowSpell(int spellid, int type) const;
+ void RemoveSpell(int spellid, int type);
public:
Spellbook();
~Spellbook();
@@ -164,9 +171,11 @@ public:
/** Check if the spell is memorised, optionally deplete it (casting) */
bool HaveSpell(const char *resref, ieDword flags);
bool HaveSpell(int spellid, ieDword flags);
- /** Check if the spell is in the book */
- bool KnowSpell(const char *resref);
- bool KnowSpell(int spellid);
+
+ int CountSpells(const char *resref, unsigned int type, int flag) const;
+ /** Check if the spell is in the book */
+ bool KnowSpell(const char *resref) const;
+ bool KnowSpell(int spellid) const;
/** returns a CRESpellMemorization pointer */
CRESpellMemorization *GetSpellMemorization(unsigned int type, unsigned int level);
@@ -190,13 +199,12 @@ public:
/** sets the book type */
void SetBookType(int clss);
- /** returns the page number for the spelltype */
- static int GetSpellType(int spelltype);
/** adds a spell to the book, returns experience if learned */
- int LearnSpell(Spell *spell, int memo);
+ int LearnSpell(Spell *spell, int memo, unsigned int clsmsk, unsigned int kit);
CREKnownSpell* GetKnownSpell(int type, unsigned int level, unsigned int index) const;
- unsigned int GetMemorizedSpellsCount(int type) const;
- unsigned int GetMemorizedSpellsCount(int type, unsigned int level) const;
+ unsigned int GetMemorizedSpellsCount(int type, bool real) const;
+ unsigned int GetMemorizedSpellsCount(int type, unsigned int level, bool real) const;
+ unsigned int GetMemorizedSpellsCount(const ieResRef name, int type, bool real) const;
CREMemorizedSpell* GetMemorizedSpell(int type, unsigned int level, unsigned int index) const;
int GetMemorizableSpellsCount(int type, unsigned int level, bool bonus) const;
@@ -209,10 +217,10 @@ public:
bool UnmemorizeSpell(CREMemorizedSpell* spl);
/** Removes (or just depletes) memorized spell by ResRef */
- bool UnmemorizeSpell(const char *resref, bool deplete);
+ bool UnmemorizeSpell(const char *resref, bool deplete, bool onlydepleted=false);
/** finds the first spell needing to rememorize */
- CREMemorizedSpell* FindUnchargedSpell(int type, int level=0);
+ CREMemorizedSpell* FindUnchargedSpell(int type, int level=0) const;
/** Sets spell from memorized as 'not-yet-cast' */
bool ChargeSpell(CREMemorizedSpell* spl);
@@ -241,8 +249,16 @@ public:
/** lists spells of a type */
bool GetSpellInfo(SpellExtHeader *array, int type, int startindex, int count);
+
+ /** find the first spell matching resref (returns index+1) */
+ int FindSpellInfo(SpellExtHeader *array, const ieResRef spellname, unsigned int type);
+
/** Dumps spellbook to stdout for debugging */
- void dump();
+ void dump() const;
+ /// Dumps spellbook to given buffer
+ void dump(StringBuffer&) const;
};
+}
+
#endif
diff --git a/gemrb/core/Sprite2D.cpp b/gemrb/core/Sprite2D.cpp
index 0e1ac3a..89663cd 100644
--- a/gemrb/core/Sprite2D.cpp
+++ b/gemrb/core/Sprite2D.cpp
@@ -25,19 +25,20 @@
#include "Interface.h"
#include "Video.h"
+namespace GemRB {
+
const TypeID Sprite2D::ID = { "Sprite2D" };
-Sprite2D::Sprite2D()
+Sprite2D::Sprite2D(int Width, int Height, int Bpp, void* vptr, const void* pixels)
+ : Width(Width), Height(Height), Bpp(Bpp), vptr(vptr), pixels(pixels)
{
BAM = false;
- vptr = NULL;
- pixels = NULL;
XPos = 0;
YPos = 0;
RefCount = 1;
}
-Sprite2D::~Sprite2D(void)
+Sprite2D::~Sprite2D()
{
}
@@ -149,3 +150,5 @@ void Sprite2D::release()
Sprite2D *that = this;
core->GetVideoDriver()->FreeSprite(that);
}
+
+}
diff --git a/gemrb/core/Sprite2D.h b/gemrb/core/Sprite2D.h
index 2e1ceaf..640926c 100644
--- a/gemrb/core/Sprite2D.h
+++ b/gemrb/core/Sprite2D.h
@@ -33,6 +33,8 @@
#include "Palette.h"
#include "TypeID.h"
+namespace GemRB {
+
class AnimationFactory;
/**
@@ -61,13 +63,13 @@ class GEM_EXPORT Sprite2D {
public:
static const TypeID ID;
public:
+ int XPos, YPos, Width, Height, Bpp;
/** Pointer to the Driver Video Structure */
void* vptr;
bool BAM;
const void* pixels;
- int XPos, YPos, Width, Height, Bpp;
- Sprite2D(void);
- ~Sprite2D(void);
+ Sprite2D(int Width, int Height, int Bpp, void* vptr, const void* pixels);
+ ~Sprite2D();
bool IsPixelTransparent(unsigned short x, unsigned short y) const;
Palette *GetPalette() const;
void SetPalette(Palette *pal);
@@ -79,4 +81,6 @@ public:
void release();
};
+}
+
#endif // ! SPRITE2D_H
diff --git a/gemrb/core/SpriteCover.cpp b/gemrb/core/SpriteCover.cpp
index 943de09..6391988 100644
--- a/gemrb/core/SpriteCover.cpp
+++ b/gemrb/core/SpriteCover.cpp
@@ -23,6 +23,8 @@
#include "Interface.h"
#include "Video.h"
+namespace GemRB {
+
SpriteCover::SpriteCover()
{
pixels = 0;
@@ -47,3 +49,5 @@ bool SpriteCover::Covers(int x, int y, int xpos, int ypos,
return true;
}
+
+}
diff --git a/gemrb/core/SpriteCover.h b/gemrb/core/SpriteCover.h
index 9e14847..3ddb242 100644
--- a/gemrb/core/SpriteCover.h
+++ b/gemrb/core/SpriteCover.h
@@ -23,6 +23,8 @@
#include "exports.h"
+namespace GemRB {
+
class GEM_EXPORT SpriteCover {
public:
unsigned char* pixels;
@@ -36,4 +38,6 @@ public:
};
+}
+
#endif
diff --git a/gemrb/core/Store.cpp b/gemrb/core/Store.cpp
index 5d60994..5bd5684 100644
--- a/gemrb/core/Store.cpp
+++ b/gemrb/core/Store.cpp
@@ -31,6 +31,8 @@
#include "Item.h"
#include "GameScript/GameScript.h"
+namespace GemRB {
+
Store::Store(void)
{
HasTriggers = false;
@@ -102,6 +104,13 @@ int Store::AcceptableItemType(ieDword type, ieDword invflags, bool pc) const
if (!(invflags&IE_INV_ITEM_IDENTIFIED) ) {
ret |= IE_STORE_ID;
}
+
+ // can't buy/sell if store doesn't allow it at all
+ if (!(Flags&IE_STORE_SELL))
+ ret &= ~IE_STORE_SELL;
+ if (!(Flags&IE_STORE_BUY))
+ ret &= ~IE_STORE_BUY;
+
if (pc && (Type<STT_BG2CONT) ) {
//can't sell critical items
if (!(invflags&IE_INV_ITEM_DESTRUCTIBLE )) {
@@ -114,7 +123,7 @@ int Store::AcceptableItemType(ieDword type, ieDword invflags, bool pc) const
}
//check if store buys stolen items
- if ((invflags&IE_INV_ITEM_STOLEN) && !(Type&IE_STORE_FENCE) ) {
+ if ((invflags&IE_INV_ITEM_STOLEN) && !(Flags&IE_STORE_FENCE) ) {
ret &= ~IE_STORE_SELL;
}
}
@@ -150,9 +159,9 @@ STODrink *Store::GetDrink(unsigned int idx) const
}
//We need this weirdness for PST item lookup
-STOItem *Store::GetItem(unsigned int idx)
+STOItem *Store::GetItem(unsigned int idx, bool usetrigger)
{
- if (!HasTriggers) {
+ if (!HasTriggers || !usetrigger) {
if (idx>=items.size()) {
return NULL;
}
@@ -197,12 +206,13 @@ STOItem *Store::FindItem(CREItem *item, bool exact)
if (strnicmp(item->ItemResRef, temp->ItemResRef, 8) ) {
continue;
}
- if(exact) {
+ if (exact) {
+ // Infinite supply means we don't have to worry about keeping track of amounts.
if (temp->InfiniteSupply==-1) {
return temp;
}
- //check if we could simply merge the item into the stock or need a new entry
- if ((temp->StackAmount>=99) || memcmp(temp->Usages, item->Usages, sizeof(item->Usages))) {
+ // Check if we have a non-stackable item with a different number of charges.
+ if (!item->MaxStackAmount && memcmp(temp->Usages, item->Usages, sizeof(item->Usages))) {
continue;
}
}
@@ -211,19 +221,21 @@ STOItem *Store::FindItem(CREItem *item, bool exact)
return NULL;
}
-//some stores can recharge items
+//some stores can recharge items - in original engine apparently all stores
+//did this. In gemrb there is a flag.
void Store::RechargeItem(CREItem *item)
{
-//is there any flag which store can recharge?
Item *itm = gamedata->GetItem(item->ItemResRef);
if (!itm) {
return;
}
- if (!itm->LoreToID) {
- item->Flags |= IE_INV_ITEM_IDENTIFIED;
- }
//gemrb extension, some shops won't recharge items
- if (!(Flags&IE_STORE_RECHARGE)) {
+ //containers' behaviour is inverted
+ //bag 0 1 0 1
+ //flag 0 0 1 1
+ //recharge 1 0 0 1
+ bool bag = (Type==STT_BG2CONT || Type==STT_IWD2CONT);
+ if (bag != !(Flags&IE_STORE_RECHARGE)) {
for (int i=0;i<CHARGE_COUNTERS;i++) {
ITMExtHeader *h = itm->GetExtHeader(i);
if (!h) {
@@ -238,14 +250,46 @@ void Store::RechargeItem(CREItem *item)
gamedata->FreeItem(itm, item->ItemResRef, 0);
}
+void Store::IdentifyItem(CREItem *item) const
+{
+ if (item->Flags & IE_INV_ITEM_IDENTIFIED) {
+ return;
+ }
+
+ Item *itm = gamedata->GetItem(item->ItemResRef);
+ if (!itm) {
+ return;
+ }
+
+ if (itm->LoreToID <= Lore) {
+ item->Flags |= IE_INV_ITEM_IDENTIFIED;
+ }
+}
+
void Store::AddItem(CREItem *item)
{
+ IdentifyItem(item);
RechargeItem(item);
STOItem *temp = FindItem(item, true);
if (temp) {
if (temp->InfiniteSupply!=-1) {
- temp->StackAmount++;
+ if (item->MaxStackAmount) {
+ // Stacked, so increase usages.
+ ieDword newAmount = 1;
+ if (!temp->Usages[0]) temp->Usages[0] = 1;
+ if (item->Usages[0] != temp->Usages[0] && item->Usages[0] > 0) {
+ // Stack sizes differ!
+ // For now, we do what bg2 does and just round up.
+ newAmount = item->Usages[0] / temp->Usages[0];
+ if (item->Usages[0] % temp->Usages[0])
+ newAmount++;
+ }
+ temp->AmountInStock += newAmount;
+ } else {
+ // Not stacked, so just increase the amount.
+ temp->AmountInStock++;
+ }
}
return;
}
@@ -255,6 +299,12 @@ void Store::AddItem(CREItem *item)
//a real class from struct, make sure the fields are cleared
memset( temp, 0, sizeof (STOItem ) );
memcpy( temp, item, sizeof( CREItem ) );
+ temp->AmountInStock = 1;
+ if (temp->MaxStackAmount && temp->Usages[0] > 1) {
+ // For now, we do what bg2 does and add new items in stacks of 1.
+ temp->AmountInStock = item->Usages[0];
+ temp->Usages[0] = 1;
+ }
items.push_back (temp );
ItemsCount++;
}
@@ -262,8 +312,7 @@ void Store::AddItem(CREItem *item)
void Store::RemoveItem( unsigned int idx )
{
if (items.size()!=ItemsCount) {
- printMessage("Store","Inconsistent store", LIGHT_RED);
- abort();
+ error("Store", "Inconsistent store");
}
if (ItemsCount<=idx) {
return;
@@ -272,6 +321,18 @@ void Store::RemoveItem( unsigned int idx )
ItemsCount--;
}
+void Store::RemoveItem( STOItem *itm )
+{
+ size_t i = items.size();
+ while(i--) {
+ if (items[i]==itm) {
+ items.erase(items.begin()+i);
+ ItemsCount--;
+ break;
+ }
+ }
+}
+
ieDword Store::GetOwnerID() const
{
return StoreOwnerID;
@@ -281,3 +342,5 @@ void Store::SetOwnerID(ieDword owner)
{
StoreOwnerID = owner;
}
+
+}
diff --git a/gemrb/core/Store.h b/gemrb/core/Store.h
index aaabd35..56234f2 100644
--- a/gemrb/core/Store.h
+++ b/gemrb/core/Store.h
@@ -34,6 +34,8 @@
#include <vector>
+namespace GemRB {
+
//bah!
class CREItem;
class Trigger;
@@ -54,7 +56,7 @@ STA_CURE=3, STA_DONATE=4, STA_DRINK=5, STA_ROOMRENT=6, STA_OPTIONAL=0x80} StoreA
#define IE_STORE_SELECT 0x40 //valid when these flags used as store action
#define IE_STORE_RENT 128 //gemrb extension
#define IE_STORE_QUALITY 0x600 //2 bits
-#define IE_STORE_FENCE 0x2000 //
+#define IE_STORE_FENCE 0x1000 //
#define IE_STORE_RECHARGE 0x4000 //gemrb extension, if set, store won't recharge
@@ -69,7 +71,7 @@ struct STOItem {
ieDword Flags;
// 2 cached values from associated item. LEAVE IT SIGNED!
int Weight;
- int StackAmount;
+ int MaxStackAmount;
ieDword AmountInStock;
ieDwordSigned InfiniteSupply;
// V1.1
@@ -156,7 +158,7 @@ public: //queries
int AcceptableItemType(ieDword type, ieDword invflags, bool pc) const;
STOCure *GetCure(unsigned int idx) const;
STODrink *GetDrink(unsigned int idx) const;
- STOItem *GetItem(unsigned int idx);
+ STOItem *GetItem(unsigned int idx, bool usetrigger);
/** Evaluates item availability triggers */
int GetRealStockSize();
/** Recharges item */
@@ -164,15 +166,20 @@ public: //queries
/** Adds a new item to the store (selling) */
void AddItem(CREItem* item);
void RemoveItem(unsigned int idx);
+ void RemoveItem( STOItem *itm);
/** Returns index of item */
unsigned int FindItem(const ieResRef item, bool usetrigger) const;
const char *GetOwner() const;
ieDword GetOwnerID() const;
void SetOwnerID(ieDword owner);
private:
+ /** Identifies item according to store lore */
+ void IdentifyItem(CREItem *item) const;
/** Finds a mergeable item in the stock, if exact is set, it checks for usage counts too */
STOItem *FindItem(CREItem *item, bool exact);
bool IsItemAvailable(unsigned int slot) const;
};
+}
+
#endif // ! STORE_H
diff --git a/gemrb/core/StoreMgr.cpp b/gemrb/core/StoreMgr.cpp
index b2d6bd0..e870c21 100644
--- a/gemrb/core/StoreMgr.cpp
+++ b/gemrb/core/StoreMgr.cpp
@@ -20,6 +20,8 @@
#include "StoreMgr.h"
+namespace GemRB {
+
StoreMgr::StoreMgr(void)
{
}
@@ -27,3 +29,5 @@ StoreMgr::StoreMgr(void)
StoreMgr::~StoreMgr(void)
{
}
+
+}
diff --git a/gemrb/core/StoreMgr.h b/gemrb/core/StoreMgr.h
index 16a7070..5fa662f 100644
--- a/gemrb/core/StoreMgr.h
+++ b/gemrb/core/StoreMgr.h
@@ -32,6 +32,8 @@
#include "Store.h"
#include "System/DataStream.h"
+namespace GemRB {
+
/**
* @class StoreMgr
* Abstract loader for Store objects
@@ -41,11 +43,12 @@ class GEM_EXPORT StoreMgr : public Plugin {
public:
StoreMgr(void);
virtual ~StoreMgr(void);
- virtual bool Open(DataStream* stream, bool autoFree = true) = 0;
+ virtual bool Open(DataStream* stream) = 0;
virtual Store* GetStore(Store *s) = 0;
- virtual int GetStoredFileSize(Store *s) = 0;
- virtual int PutStore(DataStream* stream, Store *s) = 0;
+ virtual bool PutStore(DataStream* stream, Store *s) = 0;
};
+}
+
#endif
diff --git a/gemrb/core/StringMgr.cpp b/gemrb/core/StringMgr.cpp
index 202f4f3..8b19755 100644
--- a/gemrb/core/StringMgr.cpp
+++ b/gemrb/core/StringMgr.cpp
@@ -20,6 +20,8 @@
#include "StringMgr.h"
+namespace GemRB {
+
StringMgr::StringMgr(void)
{
}
@@ -27,3 +29,5 @@ StringMgr::StringMgr(void)
StringMgr::~StringMgr(void)
{
}
+
+}
diff --git a/gemrb/core/StringMgr.h b/gemrb/core/StringMgr.h
index be18bd1..52c1b43 100644
--- a/gemrb/core/StringMgr.h
+++ b/gemrb/core/StringMgr.h
@@ -31,6 +31,8 @@
#include "Plugin.h"
#include "System/DataStream.h"
+namespace GemRB {
+
/**
* @struct StringBlock
* Text and its associated sound.
@@ -52,11 +54,13 @@ public:
virtual ~StringMgr(void);
virtual void OpenAux() = 0;
virtual void CloseAux() = 0;
- virtual bool Open(DataStream* stream, bool autoFree = true) = 0;
+ virtual bool Open(DataStream* stream) = 0;
virtual char* GetString(ieStrRef strref, unsigned int flags = 0) = 0;
virtual StringBlock GetStringBlock(ieStrRef strref, unsigned int flags = 0) = 0;
virtual void FreeString(char *str) = 0;
virtual ieStrRef UpdateString(ieStrRef strref, const char *text) = 0;
};
+}
+
#endif // ! STRINGMGR_H
diff --git a/gemrb/core/SymbolMgr.cpp b/gemrb/core/SymbolMgr.cpp
index dcd030a..389be69 100644
--- a/gemrb/core/SymbolMgr.cpp
+++ b/gemrb/core/SymbolMgr.cpp
@@ -20,6 +20,8 @@
#include "SymbolMgr.h"
+namespace GemRB {
+
SymbolMgr::SymbolMgr(void)
{
}
@@ -27,3 +29,5 @@ SymbolMgr::SymbolMgr(void)
SymbolMgr::~SymbolMgr(void)
{
}
+
+}
diff --git a/gemrb/core/SymbolMgr.h b/gemrb/core/SymbolMgr.h
index ebf3399..7cb045c 100644
--- a/gemrb/core/SymbolMgr.h
+++ b/gemrb/core/SymbolMgr.h
@@ -14,8 +14,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- *
*/
/**
@@ -24,16 +22,14 @@
* @author The GemRB Project
*/
-
#ifndef SYMBOLMGR_H
#define SYMBOLMGR_H
-/** GetValue returns this if text is not found in arrays */
-#define SYMBOL_VALUE_NOT_LOCATED -65535
-
#include "Plugin.h"
#include "System/DataStream.h"
+namespace GemRB {
+
/**
* @class SymbolMgr
* Abstract loader for symbol tables (.IDS files)
@@ -43,7 +39,8 @@ class GEM_EXPORT SymbolMgr : public Plugin {
public:
SymbolMgr(void);
virtual ~SymbolMgr(void);
- virtual bool Open(DataStream* stream, bool autoFree = true) = 0;
+ virtual bool Open(DataStream* stream) = 0;
+ /// Returns -1 if string isn't found.
virtual int GetValue(const char* text) const = 0;
virtual char* GetValue(int val) const = 0;
virtual char* GetStringIndex(unsigned int Index) const = 0;
@@ -53,4 +50,6 @@ public:
virtual int GetSize() const = 0;
};
+}
+
#endif // ! SYMBOLMGR_H
diff --git a/gemrb/core/System/CachedFileStream.cpp b/gemrb/core/System/CachedFileStream.cpp
deleted file mode 100644
index f9ae248..0000000
--- a/gemrb/core/System/CachedFileStream.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-/* GemRB - Infinity Engine Emulator
- * Copyright (C) 2003 The GemRB Project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- *
- */
-
-#include "System/CachedFileStream.h"
-
-#include "win32def.h"
-
-#include "Interface.h"
-
-CachedFileStream::CachedFileStream(const char* stream, bool autoFree)
-{
- ExtractFileFromPath( filename, stream );
- PathJoin( originalfile, core->CachePath, filename, NULL );
-
- str = _fopen( originalfile, "rb" );
- if (str == NULL) { // File was not found in cache
- if (core->GameOnCD) {
- _FILE* src = _fopen( stream, "rb" );
-#ifdef _DEBUG
- core->CachedFileStreamPtrCount++;
-#endif
- _FILE* dest = _fopen( originalfile, "wb" );
-#ifdef _DEBUG
- core->CachedFileStreamPtrCount++;
-#endif
- void* buff = malloc( 1024 * 1000 );
- do {
- size_t len = _fread( buff, 1, 1024 * 1000, src );
- size_t c = _fwrite( buff, 1, len, dest );
- if (c != len) {
- printf("CachedFileStream failed to write to cached file '%s' (from '%s')\n", originalfile, stream);
- abort();
- }
- } while (!_feof( src ));
- free( buff );
- _fclose( src );
-#ifdef _DEBUG
- core->CachedFileStreamPtrCount--;
-#endif
- _fclose( dest );
-#ifdef _DEBUG
- core->CachedFileStreamPtrCount--;
-#endif
- } else { // Don't cache files already on hdd
- strncpy(originalfile, stream, _MAX_PATH);
- }
- str = _fopen( originalfile, "rb" );
- }
-#ifdef _DEBUG
- core->CachedFileStreamPtrCount++;
-#endif
- startpos = 0;
- _fseek( str, 0, SEEK_END );
- size = _ftell( str );
- _fseek( str, 0, SEEK_SET );
- Pos = 0;
- this->autoFree = autoFree;
-}
-
-CachedFileStream::CachedFileStream(CachedFileStream* cfs, int startpos,
- int size, bool autoFree)
-{
- this->size = size;
- this->startpos = startpos;
- this->autoFree = autoFree;
- char cpath[_MAX_PATH];
- PathJoin( cpath, core->CachePath, cfs->filename, NULL );
- str = _fopen( cpath, "rb" );
- if (str == NULL) {
- str = _fopen( cfs->originalfile, "rb" );
- if (str == NULL) {
- printf( "Can't open stream (maybe leaking?)\n" );
- return;
- }
- strncpy( originalfile, cfs->originalfile, sizeof(originalfile) );
- strncpy( filename, cfs->filename, sizeof(filename) );
- } else {
- strncpy( originalfile, cpath, sizeof(originalfile) );
- strncpy( filename, cfs->filename, sizeof(filename) );
- }
-#ifdef _DEBUG
- core->CachedFileStreamPtrCount++;
-#endif
- _fseek( str, startpos, SEEK_SET );
-
-
- Pos = 0;
-}
-
-CachedFileStream::~CachedFileStream(void)
-{
- if (autoFree && str) {
-#ifdef _DEBUG
- core->CachedFileStreamPtrCount--;
-#endif
- _fclose( str );
- }
- str = NULL;
- //autoFree = false; //File stream destructor hack
-}
-
-int CachedFileStream::Read(void* dest, unsigned int length)
-{
- //we don't allow partial reads anyway, so it isn't a problem that
- //i don't adjust length here (partial reads are evil)
- if (Pos+length>size ) {
- return GEM_ERROR;
- }
-
- unsigned int c = (unsigned int) _fread( dest, 1, length, str );
- if (c != length) {
- return GEM_ERROR;
- }
- if (Encrypted) {
- ReadDecrypted( dest, c );
- }
- Pos += c;
- return c;
-}
-
-int CachedFileStream::Write(const void* src, unsigned int length)
-{
- // do encryption here if needed
-
- unsigned int c = (unsigned int) _fwrite( src, 1, length, str );
- if (c != length) {
- return GEM_ERROR;
- }
- Pos += c;
- //this is needed only if you want to Seek in a written file
- if (Pos>size) {
- size = Pos;
- }
- return c;
-}
-
-int CachedFileStream::Seek(int newpos, int type)
-{
- switch (type) {
- case GEM_CURRENT_POS:
- _fseek( str, newpos, SEEK_CUR );
- Pos += newpos;
- break;
-
- case GEM_STREAM_START:
- _fseek( str, startpos + newpos, SEEK_SET );
- Pos = newpos;
- break;
-
- default:
- return GEM_ERROR;
- }
- //we went past the buffer
- if (Pos>size) {
- printf("[Streams]: Invalid seek position: %ld (limit: %ld)\n",Pos, size);
- return GEM_ERROR;
- }
- return GEM_OK;
-}
-
-/** No descriptions */
-int CachedFileStream::ReadLine(void* buf, unsigned int maxlen)
-{
- if (!maxlen) {
- return 0;
- }
- unsigned char * p = ( unsigned char * ) buf;
- if (_feof( str )) {
- p[0]=0;
- return -1;
- }
- if (Pos >= size) {
- p[0]=0;
- return -1;
- }
- unsigned int i = 0;
- while (i < ( maxlen - 1 )) {
- int ch = _fgetc( str );
- if (Pos == size)
- break;
- if (Encrypted)
- ch ^= GEM_ENCRYPTION_KEY[Pos & 63];
- Pos++;
- if (( ( char ) ch ) == '\n')
- break;
- if (( ( char ) ch ) == '\t')
- ch = ' ';
- if (( ( char ) ch ) != '\r')
- p[i++] = ch;
- //Warning:this feof implementation reads forward one byte
- if (_feof( str ))
- break;
- }
- p[i] = 0;
- return i;
-}
diff --git a/gemrb/core/System/CachedFileStream.h b/gemrb/core/System/CachedFileStream.h
deleted file mode 100644
index 40042eb..0000000
--- a/gemrb/core/System/CachedFileStream.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* GemRB - Infinity Engine Emulator
- * Copyright (C) 2003 The GemRB Project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- *
- */
-
-#ifndef CACHEDFILESTREAM_H
-#define CACHEDFILESTREAM_H
-
-#include "System/DataStream.h"
-
-#include "exports.h"
-
-class GEM_EXPORT CachedFileStream : public DataStream// : public FileStream
-{
-private:
- bool autoFree;
- unsigned long startpos;
- _FILE* str;
-public:
- CachedFileStream(const char* stream, bool autoFree = true);
- CachedFileStream(CachedFileStream* cfs, int startpos, int size,
- bool autoFree = true);
- ~CachedFileStream(void);
- int Read(void* dest, unsigned int length);
- int Write(const void* src, unsigned int length);
- int Seek(int pos, int startpos);
- /** No descriptions */
- int ReadLine(void* buf, unsigned int maxlen);
-};
-#endif
diff --git a/gemrb/core/System/DataStream.cpp b/gemrb/core/System/DataStream.cpp
index 71c0f19..d3a2b2f 100644
--- a/gemrb/core/System/DataStream.cpp
+++ b/gemrb/core/System/DataStream.cpp
@@ -24,6 +24,10 @@
#include <ctype.h>
+namespace GemRB {
+
+static const char* GEM_ENCRYPTION_KEY = "\x88\xa8\x8f\xba\x8a\xd3\xb9\xf5\xed\xb1\xcf\xea\xaa\xe4\xb5\xfb\xeb\x82\xf9\x90\xca\xc9\xb5\xe7\xdc\x8e\xb7\xac\xee\xf7\xe0\xca\x8e\xea\xca\x80\xce\xc5\xad\xb7\xc4\xd0\x84\x93\xd5\xf0\xeb\xc8\xb4\x9d\xcc\xaf\xa5\x95\xba\x99\x87\xd2\x9d\xe3\x91\xba\x90\xca";
+
static bool EndianSwitch = false;
DataStream::DataStream(void)
@@ -49,7 +53,7 @@ bool DataStream::IsEndianSwitch()
/** Returns true if the stream is encrypted */
bool DataStream::CheckEncrypted()
{
- ieWord two;
+ ieWord two = 0x0000; // if size < 2, two won't be initialized
Seek( 0, GEM_STREAM_START );
Read( &two, 2 );
if (two == 0xFFFF) {
@@ -183,3 +187,42 @@ int DataStream::WriteResRef(const ieResRef src)
{
return Write( src, 8);
}
+
+int DataStream::ReadLine(void* buf, unsigned int maxlen)
+{
+ // FIXME: eof?
+ if (!maxlen) {
+ return 0;
+ }
+ unsigned char * p = ( unsigned char * ) buf;
+ if (Pos >= size) {
+ p[0]=0;
+ return -1;
+ }
+ unsigned int i = 0;
+ //TODO: fix this to handle any combination of \r and \n
+ //Windows: \r\n
+ //Old Mac: \r
+ //otherOS: \n
+ while (i < ( maxlen - 1 )) {
+ char ch;
+ Read(&ch, 1);
+ if (( ( char ) ch ) == '\n')
+ break;
+ if (( ( char ) ch ) == '\t')
+ ch = ' ';
+ if (( ( char ) ch ) != '\r')
+ p[i++] = ch;
+ if (Pos == size)
+ break;
+ }
+ p[i] = 0;
+ return i;
+}
+
+DataStream* DataStream::Clone()
+{
+ return NULL;
+}
+
+}
diff --git a/gemrb/core/System/DataStream.h b/gemrb/core/System/DataStream.h
index e20c118..1260772 100644
--- a/gemrb/core/System/DataStream.h
+++ b/gemrb/core/System/DataStream.h
@@ -31,6 +31,8 @@
#include "exports.h"
#include "globals.h"
+namespace GemRB {
+
#define GEM_CURRENT_POS 0
#define GEM_STREAM_START 1
#define GEM_STREAM_END 2
@@ -68,10 +70,19 @@ public:
/** Returns true if the stream is encrypted */
bool CheckEncrypted();
void ReadDecrypted(void* buf, unsigned int size);
- virtual int ReadLine(void* buf, unsigned int maxlen) = 0;
+ int ReadLine(void* buf, unsigned int maxlen);
/** Endian Switch setup */
static void SetEndianSwitch(int par);
static bool IsEndianSwitch();
+ /** Create a copy of this stream.
+ *
+ * Returns NULL on failure.
+ **/
+ virtual DataStream* Clone();
+private:
+ DataStream(const DataStream&);
};
+}
+
#endif // ! DATASTREAM_H
diff --git a/gemrb/core/System/FileStream.cpp b/gemrb/core/System/FileStream.cpp
index eeeabc1..3c4cce9 100644
--- a/gemrb/core/System/FileStream.cpp
+++ b/gemrb/core/System/FileStream.cpp
@@ -24,147 +24,232 @@
#include "Interface.h"
+namespace GemRB {
+
+#ifdef _DEBUG
+int FileStream::FileStreamPtrCount = 0;
+#endif
+
+#ifdef WIN32
+struct FileStream::File {
+private:
+ HANDLE file;
+public:
+ File() : file() {}
+ void Close() { CloseHandle(file); }
+ size_t Length() {
+ LARGE_INTEGER size;
+ DWORD high;
+ DWORD low = GetFileSize(file, &high);
+ if (low != 0xFFFFFFFF || GetLastError() == NO_ERROR) {
+ size.LowPart = low;
+ size.HighPart = high;
+ return size.QuadPart;
+ }
+ return 0;
+ }
+ bool OpenRO(const char *name) {
+ file = CreateFile(name,
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ return (file != INVALID_HANDLE_VALUE);
+ }
+ bool OpenRW(const char *name) {
+ file = CreateFile(name,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ return (file != INVALID_HANDLE_VALUE);
+ }
+ bool OpenNew(const char *name) {
+ file = CreateFile(name,
+ GENERIC_WRITE,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ return (file != INVALID_HANDLE_VALUE);
+ }
+ size_t Read(void* ptr, size_t length) {
+ unsigned long read;
+ if (!ReadFile(file, ptr, length, &read, NULL))
+ return 0;
+ return read;
+ }
+ size_t Write(const void* ptr, size_t length) {
+ unsigned long wrote;
+ if (!WriteFile(file, ptr, length, &wrote, NULL))
+ return 0;
+ return wrote;
+ }
+ bool SeekStart(int offset)
+ {
+ return SetFilePointer(file, offset, NULL, FILE_BEGIN) != 0xffffffff;
+ }
+ bool SeekCurrent(int offset)
+ {
+ return SetFilePointer(file, offset, NULL, FILE_CURRENT) != 0xffffffff;
+ }
+ bool SeekEnd(int offset)
+ {
+ return SetFilePointer(file, offset, NULL, FILE_END) != 0xffffffff;
+ }
+};
+#else
+struct FileStream::File {
+private:
+ FILE* file;
+public:
+ File() : file(NULL) {}
+ void Close() { fclose(file); }
+ size_t Length() {
+ fseek(file, 0, SEEK_END);
+ size_t size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+ return size;
+ }
+ bool OpenRO(const char *name) {
+ return (file = fopen(name, "rb"));
+ }
+ bool OpenRW(const char *name) {
+ return (file = fopen(name, "r+b"));
+ }
+ bool OpenNew(const char *name) {
+ return (file = fopen(name, "wb"));
+ }
+ size_t Read(void* ptr, size_t length) {
+ return fread(ptr, 1, length, file);
+ }
+ size_t Write(const void* ptr, size_t length) {
+ return fwrite(ptr, 1, length, file);
+ }
+ bool SeekStart(int offset)
+ {
+ return !fseek(file, offset, SEEK_SET);
+ }
+ bool SeekCurrent(int offset)
+ {
+ return !fseek(file, offset, SEEK_CUR);
+ }
+ bool SeekEnd(int offset)
+ {
+ return !fseek(file, offset, SEEK_END);
+ }
+};
+#endif
+
FileStream::FileStream(void)
{
opened = false;
created = false;
- str = NULL;
- autoFree = false;
+ str = new File();
+}
+
+DataStream* FileStream::Clone()
+{
+ return OpenFile(originalfile);
}
FileStream::~FileStream(void)
{
- if (autoFree && str) {
-#ifdef _DEBUG
- core->FileStreamPtrCount--;
-#endif
- _fclose( str );
- }
- str = NULL;
+ Close();
+ delete str;
}
-bool FileStream::Open(const char* fname, bool aF)
+void FileStream::Close()
{
- if (str && autoFree) {
+ if (opened) {
#ifdef _DEBUG
- core->FileStreamPtrCount--;
+ FileStreamPtrCount--;
#endif
- _fclose( str );
- str = NULL;
+ str->Close();
}
+ opened = false;
+ created = false;
+}
+
+void FileStream::FindLength()
+{
+ size = str->Length();
+ Pos = 0;
+}
+
+bool FileStream::Open(const char* fname)
+{
+ Close();
if (!file_exists(fname)) {
return false;
}
- autoFree = aF;
- str = _fopen( fname, "rb" );
- if (str == NULL) {
+ if (!str->OpenRO(fname)) {
return false;
}
#ifdef _DEBUG
- core->FileStreamPtrCount++;
+ FileStreamPtrCount++;
#endif
- startpos = 0;
opened = true;
created = false;
- //FIXME: this is a very lame way to tell the file length
- _fseek( str, 0, SEEK_END );
- size = _ftell( str );
- _fseek( str, 0, SEEK_SET );
+ FindLength();
ExtractFileFromPath( filename, fname );
- strncpy( originalfile, fname, _MAX_PATH);
- Pos = 0;
+ strlcpy( originalfile, fname, _MAX_PATH);
return true;
}
-bool FileStream::Modify(const char* fname, bool aF)
+bool FileStream::Modify(const char* fname)
{
- if (str && autoFree) {
-#ifdef _DEBUG
- core->FileStreamPtrCount--;
-#endif
- _fclose( str );
- }
- autoFree = aF;
- str = _fopen( fname, "r+b" );
- if (str == NULL) {
+ Close();
+
+ if (!str->OpenRW(fname)) {
return false;
}
#ifdef _DEBUG
- core->FileStreamPtrCount++;
+ FileStreamPtrCount++;
#endif
- startpos = 0;
opened = true;
created = true;
- //FIXME: this is a very lame way to tell the file length
- _fseek( str, 0, SEEK_END );
- size = _ftell( str );
- _fseek( str, 0, SEEK_SET );
+ FindLength();
ExtractFileFromPath( filename, fname );
- strncpy( originalfile, fname, _MAX_PATH);
- Pos = 0;
- return true;
-}
-
-bool FileStream::Open(_FILE* stream, int spos, int maxsize, bool aF)
-{
- if (str && autoFree) {
-#ifdef _DEBUG
- core->FileStreamPtrCount--;
-#endif
- _fclose( str );
- }
- autoFree = aF;
- str = stream;
- if (str == NULL) {
- return false;
- }
-#ifdef _DEBUG
- core->FileStreamPtrCount++;
-#endif
- startpos = spos;
- opened = true;
- created = false;
- size = maxsize;
- filename[0]=0;
- originalfile[0]=0;
- _fseek( str, spos, SEEK_SET );
+ strlcpy( originalfile, fname, _MAX_PATH);
Pos = 0;
return true;
}
//Creating file in the cache
-//Create is ALWAYS autofree
bool FileStream::Create(const char* fname, SClass_ID ClassID)
{
return Create(core->CachePath, fname, ClassID);
}
-//Creating file outside of the cache
bool FileStream::Create(const char *folder, const char* fname, SClass_ID ClassID)
{
- if (str && autoFree) {
-#ifdef _DEBUG
- core->FileStreamPtrCount--;
-#endif
- _fclose( str );
- }
- autoFree = true;
+ char path[_MAX_PATH];
+ char filename[_MAX_PATH];
ExtractFileFromPath( filename, fname );
- strcpy( originalfile, folder );
- strcat( originalfile, SPathDelimiter);
- strcat( originalfile, filename );
- strcat( originalfile, core->TypeExt( ClassID ) );
- str = _fopen( originalfile, "wb" );
- if (str == NULL) {
+ PathJoinExt(path, folder, filename, core->TypeExt(ClassID));
+ return Create(path);
+}
+
+//Creating file outside of the cache
+bool FileStream::Create(const char *path)
+{
+ Close();
+
+ ExtractFileFromPath( filename, path );
+ strlcpy(originalfile, path, _MAX_PATH);
+
+ if (!str->OpenNew(originalfile)) {
return false;
}
opened = true;
created = true;
Pos = 0;
size = 0;
- startpos = 0;
return true;
}
@@ -178,7 +263,7 @@ int FileStream::Read(void* dest, unsigned int length)
if (Pos+length>size ) {
return GEM_ERROR;
}
- size_t c = _fread( dest, 1, length, str );
+ size_t c = str->Read(dest, length);
if (c != length) {
return GEM_ERROR;
}
@@ -196,7 +281,7 @@ int FileStream::Write(const void* src, unsigned int length)
}
// do encryption here if needed
- size_t c = _fwrite( src, 1, length, str );
+ size_t c = str->Write(src, length);
if (c != length) {
return GEM_ERROR;
}
@@ -214,16 +299,16 @@ int FileStream::Seek(int newpos, int type)
}
switch (type) {
case GEM_STREAM_END:
- _fseek( str, startpos + size - newpos, SEEK_SET);
+ str->SeekStart(size - newpos);
Pos = size - newpos;
break;
case GEM_CURRENT_POS:
- _fseek( str, newpos, SEEK_CUR );
+ str->SeekCurrent(newpos);
Pos += newpos;
break;
case GEM_STREAM_START:
- _fseek( str, startpos + newpos, SEEK_SET );
+ str->SeekStart(newpos);
Pos = newpos;
break;
@@ -231,51 +316,20 @@ int FileStream::Seek(int newpos, int type)
return GEM_ERROR;
}
if (Pos>size) {
- printf("[Streams]: Invalid seek position %ld in file %s (limit: %ld)\n",Pos, filename, size);
+ print("[Streams]: Invalid seek position %ld in file %s(limit: %ld)", Pos, filename, size);
return GEM_ERROR;
}
return GEM_OK;
}
-/** No descriptions */
-int FileStream::ReadLine(void* buf, unsigned int maxlen)
+FileStream* FileStream::OpenFile(const char* filename)
{
- if(!maxlen) {
- return 0;
- }
- unsigned char * p = ( unsigned char * ) buf;
- if (_feof( str )) {
- p[0]=0;
- return -1;
- }
- if (Pos >= size) {
- p[0]=0;
- return -1;
- }
- unsigned int i = 0;
- while (i < ( maxlen - 1 )) {
- int ch = _fgetc( str );
- if (Pos == size)
- break;
- if (Encrypted) {
- ch ^= GEM_ENCRYPTION_KEY[Pos & 63];
- }
- Pos++;
- if (( ( char ) ch ) == '\n')
- break;
- if (( ( char ) ch ) == '\t')
- ch = ' ';
- if (( ( char ) ch ) != '\r')
- p[i++] = ch;
- //Warning:this feof implementation reads forward one byte
- if (_feof( str ))
- break;
- }
- p[i] = 0;
- return i;
+ FileStream *fs = new FileStream();
+ if (fs->Open(filename))
+ return fs;
+
+ delete fs;
+ return NULL;
}
-unsigned long FileStream::GetStartPos() const
-{
- return startpos;
}
diff --git a/gemrb/core/System/FileStream.h b/gemrb/core/System/FileStream.h
index 8c8a28a..3bec689 100644
--- a/gemrb/core/System/FileStream.h
+++ b/gemrb/core/System/FileStream.h
@@ -33,6 +33,8 @@
#include "exports.h"
#include "globals.h"
+namespace GemRB {
+
/**
* @class FileStream
* Reads and writes data from/to files on a filesystem
@@ -40,24 +42,37 @@
class GEM_EXPORT FileStream : public DataStream {
private:
- bool autoFree;
- unsigned long startpos;
- _FILE* str;
+#ifdef _DEBUG
+ static int FileStreamPtrCount;
+#endif
+ struct File;
+ File* str;
bool opened, created;
public:
FileStream(void);
~FileStream(void);
+ DataStream* Clone();
- bool Open(const char* filename, bool autoFree = true);
- bool Open(_FILE* stream, int startpos, int size, bool autoFree = false);
- bool Modify(const char* filename, bool autoFree = true);
+ bool Open(const char* filename);
+ bool Modify(const char* filename);
bool Create(const char* folder, const char* filename, SClass_ID ClassID);
bool Create(const char* filename, SClass_ID ClassID);
+ bool Create(const char* filename);
int Read(void* dest, unsigned int length);
int Write(const void* src, unsigned int length);
int Seek(int pos, int startpos);
- unsigned long GetStartPos() const;
- int ReadLine(void* buf, unsigned int maxlen);
+
+ void Close();
+public:
+ /** Opens the specifed file.
+ *
+ * Returns NULL, if the file can't be opened.
+ */
+ static FileStream* OpenFile(const char* filename);
+private:
+ void FindLength();
};
+}
+
#endif // ! FILESTREAM_H
diff --git a/gemrb/core/System/Logger.cpp b/gemrb/core/System/Logger.cpp
new file mode 100644
index 0000000..1e73494
--- /dev/null
+++ b/gemrb/core/System/Logger.cpp
@@ -0,0 +1,96 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "System/Logger.h"
+
+#include "System/Logging.h"
+
+#include <cstdio>
+
+namespace GemRB {
+
+Logger::Logger(log_level level)
+{
+ // set level directly instead of calling SetLogLevel() to avoid pure virtual call
+ myLevel = level;
+}
+
+Logger::~Logger()
+{}
+
+void Logger::destroy()
+{
+ delete this;
+}
+
+bool Logger::SetLogLevel(log_level level)
+{
+ if (level > INTERNAL) {
+ myLevel = level;
+ static const char* fmt = "Log Level set to %d";
+ char msg[25];
+ snprintf(msg, 25, fmt, level);
+ // careful to use our log function and not the global one to prevent this message form
+ // propagating to other loggers.
+ LogInternal(INTERNAL, "Logger", msg, DEFAULT);
+ return true;
+ } else {
+ // careful to use our log function and not the global one to prevent this message form
+ // propagating to other loggers.
+ LogInternal(INTERNAL, "Logger", "Log Level cannot be set below CRITICAL.", RED);
+ }
+ return false;
+}
+
+void Logger::log(log_level level, const char* owner, const char* message, log_color color)
+{
+ if (level <= myLevel) {
+ LogInternal(level, owner, message, color);
+ }
+}
+
+const char* log_level_text[] = {
+ "FATAL",
+ "ERROR",
+ "WARNING",
+ "", // MESSAGE
+ "COMBAT",
+ "DEBUG"
+};
+
+}
+
+using namespace GemRB;
+
+#ifdef ANDROID
+
+#include "System/Logger/Android.h"
+Logger* (*GemRB::createDefaultLogger)() = createAndroidLogger;
+
+#elif defined(WIN32) && !defined(WIN32_USE_STDIO)
+
+#include "System/Logger/Win32Console.h"
+Logger* (*GemRB::createDefaultLogger)() = createWin32ConsoleLogger;
+
+#else
+
+#include "System/Logger/Stdio.h"
+Logger* (*GemRB::createDefaultLogger)() = createStdioLogger;
+
+#endif
+
diff --git a/gemrb/core/System/Logger.h b/gemrb/core/System/Logger.h
new file mode 100644
index 0000000..1030f66
--- /dev/null
+++ b/gemrb/core/System/Logger.h
@@ -0,0 +1,73 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file Logger.h
+ * Logging targets
+ * @author The GemRB Project
+ */
+
+#ifndef LOGGER_H
+#define LOGGER_H
+
+#include "exports.h"
+
+#include "System/Logging.h"
+
+namespace GemRB {
+
+enum log_color {
+ DEFAULT,
+ BLACK,
+ RED,
+ GREEN,
+ BROWN,
+ BLUE,
+ MAGENTA,
+ CYAN,
+ WHITE,
+ LIGHT_RED,
+ LIGHT_GREEN,
+ YELLOW,
+ LIGHT_BLUE,
+ LIGHT_MAGENTA,
+ LIGHT_CYAN,
+ LIGHT_WHITE
+};
+
+class GEM_EXPORT Logger {
+private:
+ log_level myLevel;
+public:
+ Logger(log_level = DEBUG);
+ virtual ~Logger();
+ virtual void destroy();
+
+ bool SetLogLevel(log_level);
+ void log(log_level, const char* owner, const char* message, log_color color);
+protected:
+ virtual void LogInternal(log_level, const char*, const char*, log_color)=0;
+};
+
+extern const char* log_level_text[];
+
+extern Logger* (*createDefaultLogger)();
+
+}
+
+#endif
diff --git a/gemrb/core/System/Logger/Android.cpp b/gemrb/core/System/Logger/Android.cpp
new file mode 100644
index 0000000..ea502a2
--- /dev/null
+++ b/gemrb/core/System/Logger/Android.cpp
@@ -0,0 +1,56 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "System/Logger/Android.h"
+
+#include <android/log.h>
+
+namespace GemRB {
+
+AndroidLogger::AndroidLogger()
+{}
+
+AndroidLogger::~AndroidLogger()
+{}
+
+void AndroidLogger::LogInternal(log_level level, const char* owner, const char* message, log_color /*color*/)
+{
+ android_LogPriority priority = ANDROID_LOG_INFO;
+ switch (level) {
+ case FATAL:
+ priority = ANDROID_LOG_FATAL;
+ break;
+ case ERROR:
+ priority = ANDROID_LOG_ERROR;
+ break;
+ case WARNING:
+ priority = ANDROID_LOG_WARN;
+ break;
+ case DEBUG:
+ priority = ANDROID_LOG_DEBUG;
+ break;
+ }
+ __android_log_print(priority, "GemRB", "[%s/%s]: %s", owner, log_level_text[level], message);
+}
+
+Logger* createAndroidLogger()
+{
+ return new AndroidLogger();
+}
+
+}
diff --git a/gemrb/core/System/Logger/Android.h b/gemrb/core/System/Logger/Android.h
new file mode 100644
index 0000000..4a8eea6
--- /dev/null
+++ b/gemrb/core/System/Logger/Android.h
@@ -0,0 +1,39 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef LOGGER_ANDROID_H
+#define LOGGER_ANDROID_H
+
+#include "System/Logger.h"
+
+namespace GemRB {
+
+class GEM_EXPORT AndroidLogger : public Logger {
+public:
+ AndroidLogger();
+ virtual ~AndroidLogger();
+
+protected:
+ void LogInternal(log_level, const char*, const char*, log_color);
+};
+
+Logger* createAndroidLogger();
+
+}
+
+#endif
diff --git a/gemrb/core/System/Logger/File.cpp b/gemrb/core/System/Logger/File.cpp
new file mode 100644
index 0000000..70971f9
--- /dev/null
+++ b/gemrb/core/System/Logger/File.cpp
@@ -0,0 +1,77 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "System/Logger/File.h"
+
+#include "System/DataStream.h"
+#include "System/FileStream.h"
+#include "System/Logging.h"
+
+#ifndef STATIC_LINK
+# define STATIC_LINK
+#endif
+#include "plugindef.h"
+#include "Interface.h"
+
+#include <cstdio>
+
+namespace GemRB {
+
+FileLogger::FileLogger(DataStream* log_file)
+ : StdioLogger(false), log_file(log_file)
+{}
+
+FileLogger::~FileLogger()
+{
+ delete log_file;
+}
+
+void FileLogger::print(const char *message)
+{
+ log_file->Write(message, strlen(message));
+}
+
+Logger* createFileLogger(DataStream* log_file)
+{
+ return new FileLogger(log_file);
+}
+
+static void addLogger()
+{
+ char log_path[_MAX_PATH];
+ FileStream* log_file = new FileStream();
+ PathJoin(log_path, core->GamePath, "GemRB.log", NULL);
+ if (log_file->Create(log_path)) {
+ AddLogger(createFileLogger(log_file));
+ } else {
+ PathJoin(log_path, core->CachePath, "GemRB.log", NULL);
+ if (log_file->Create(log_path)) {
+ AddLogger(createFileLogger(log_file));
+ } else if (log_file->Create("/tmp/GemRB.log")) {
+ AddLogger(createFileLogger(log_file));
+ } else {
+ Log (WARNING, "Logger", "Could not create a log file, skipping!");
+ }
+ }
+}
+
+}
+
+GEMRB_PLUGIN(unused, "tmp/file logger")
+PLUGIN_INITIALIZER(addLogger)
+END_PLUGIN()
diff --git a/gemrb/core/System/Logger/File.h b/gemrb/core/System/Logger/File.h
new file mode 100644
index 0000000..48e0b10
--- /dev/null
+++ b/gemrb/core/System/Logger/File.h
@@ -0,0 +1,43 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef LOGGER_FILE_H
+#define LOGGER_FILE_H
+
+#include "System/Logger/Stdio.h"
+
+namespace GemRB {
+
+class DataStream;
+
+class GEM_EXPORT FileLogger : public StdioLogger {
+public:
+ FileLogger(DataStream*);
+ virtual ~FileLogger();
+
+ void print(const char* message);
+
+private:
+ DataStream* log_file;
+};
+
+Logger* createFileLogger(DataStream*);
+
+}
+
+#endif
diff --git a/gemrb/core/System/Logger/MessageWindowLogger.cpp b/gemrb/core/System/Logger/MessageWindowLogger.cpp
new file mode 100644
index 0000000..aaa1806
--- /dev/null
+++ b/gemrb/core/System/Logger/MessageWindowLogger.cpp
@@ -0,0 +1,107 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2012 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "MessageWindowLogger.h"
+
+#include "DisplayMessage.h"
+#include "GUI/GameControl.h"
+#include "Interface.h"
+
+namespace GemRB {
+
+MessageWindowLogger* mwl = NULL;
+
+MessageWindowLogger::MessageWindowLogger( log_level level)
+ : Logger(level)
+{
+ PrintStatus(true);
+}
+
+MessageWindowLogger::~MessageWindowLogger()
+{
+ PrintStatus(false);
+ assert(mwl == this);
+ mwl = NULL;
+}
+
+void MessageWindowLogger::LogInternal(log_level level, const char* owner, const char* message, log_color color)
+{
+ GameControl* gc = core->GetGameControl();
+ if (displaymsg && gc && !(gc->GetDialogueFlags()&DF_IN_DIALOG)) {
+ // FIXME: we check DF_IN_DIALOG here to avoid recurssion in the MessageWindowLogger, but what happens when an error happens during dialog?
+ // I'm not super sure about how to avoid that. for now the logger will not log anything in dialog mode.
+ static const char* colors[] = {
+ "[color=FFFFFF]", // DEFAULT
+ "[color=000000]", // BLACK
+ "[color=FF0000]", // RED
+ "[color=00FF00]", // GREEN
+ "[color=603311]", // BROWN
+ "[color=0000FF]", // BLUE
+ "[color=8B008B]", // MAGENTA
+ "[color=00CDCD]", // CYAN
+ "[color=FFFFFF]", // WHITE
+ "[color=CD5555]", // LIGHT_RED
+ "[color=90EE90]", // LIGHT_GREEN
+ "[color=FFFF00]", // YELLOW
+ "[color=BFEFFF]", // LIGHT_BLUE
+ "[color=FF00FF]", // LIGHT_MAGENTA
+ "[color=B4CDCD]", // LIGHT_CYAN
+ "[color=CDCDCD]" // LIGHT_WHITE
+ };
+ static const log_color log_level_color[] = {
+ RED,
+ RED,
+ YELLOW,
+ LIGHT_WHITE,
+ GREEN,
+ BLUE
+ };
+
+ if (level < 0) {
+ // re-assign our internal message level to the real one
+ level = MESSAGE;
+ }
+ const char* fmt = "%s%s: [/color]%s%s[/color]";
+ char* msg = (char*)malloc(strlen(message) + strlen(owner) + strlen(fmt) + 28); // 28 is for sizeof(colors[x]) * 2
+ sprintf(msg, fmt, colors[color], owner, colors[log_level_color[level]], message);
+ displaymsg->DisplayString(msg);
+ free(msg);
+ }
+}
+
+void MessageWindowLogger::PrintStatus(bool toggle)
+{
+ if (toggle) {
+ LogInternal( INTERNAL, "Logger", "MessageWindow logging active.", LIGHT_GREEN);
+ } else {
+ LogInternal( INTERNAL, "Logger", "MessageWindow logging disabled.", LIGHT_RED);
+ }
+}
+
+// this MUST be a singleton. we only have one message window and multiple messages to that window are useless
+// additionally GUIScript doesnt check its existance and simply calls this function whenever the command is given
+Logger* getMessageWindowLogger( bool create )
+{
+ if (create && !mwl) {
+ mwl = new MessageWindowLogger();
+ AddLogger(mwl);
+ }
+ return mwl;
+}
+
+}
diff --git a/gemrb/core/System/Logger/MessageWindowLogger.h b/gemrb/core/System/Logger/MessageWindowLogger.h
new file mode 100644
index 0000000..c45ca62
--- /dev/null
+++ b/gemrb/core/System/Logger/MessageWindowLogger.h
@@ -0,0 +1,40 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2012 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#ifndef __GemRB__MessageWindowLogger__
+#define __GemRB__MessageWindowLogger__
+
+#include "System/Logger.h" // for log_color
+
+namespace GemRB {
+
+class GEM_EXPORT MessageWindowLogger : public Logger {
+public:
+ MessageWindowLogger( log_level = WARNING ); // this logger has a diffrent default level than its base class.
+ virtual ~MessageWindowLogger();
+protected:
+ void LogInternal(log_level level, const char* owner, const char* message, log_color color);
+private:
+ void PrintStatus(bool);
+};
+
+// if create is true then getMessageWindowLogger will create and attach the message window logger
+// if it doesnt exist; otherwise simply returns a pointer to the logger.
+GEM_EXPORT Logger* getMessageWindowLogger( bool create = false);
+}
+
+#endif /* defined(__GemRB__MessageWindowLogger__) */
diff --git a/gemrb/core/System/Logger/Stdio.cpp b/gemrb/core/System/Logger/Stdio.cpp
new file mode 100644
index 0000000..2a66199
--- /dev/null
+++ b/gemrb/core/System/Logger/Stdio.cpp
@@ -0,0 +1,127 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "System/Logger/Stdio.h"
+
+#include "System/Logging.h"
+
+#include <cstdio>
+
+namespace GemRB {
+
+StdioLogger::StdioLogger(bool useColor)
+ : useColor(useColor)
+{}
+
+StdioLogger::~StdioLogger()
+{}
+
+void StdioLogger::print(const char* message)
+{
+ fprintf(stdout, "%s", message);
+}
+
+static const char* colors[] = {
+ "\033[0m",
+ "\033[0m\033[30;40m",
+ "\033[0m\033[31;40m",
+ "\033[0m\033[32;40m",
+ "\033[0m\033[33;40m",
+ "\033[0m\033[34;40m",
+ "\033[0m\033[35;40m",
+ "\033[0m\033[36;40m",
+ "\033[0m\033[37;40m",
+ "\033[1m\033[31;40m",
+ "\033[1m\033[32;40m",
+ "\033[1m\033[33;40m",
+ "\033[1m\033[34;40m",
+ "\033[1m\033[35;40m",
+ "\033[1m\033[36;40m",
+ "\033[1m\033[37;40m"
+};
+
+
+void StdioLogger::textcolor(log_color c)
+{
+ // Shold this be in an ansi-term subclass?
+ // Probably not worth the bother
+ if (useColor)
+ print(colors[c]);
+}
+
+void StdioLogger::printBracket(const char* status, log_color color)
+{
+ textcolor(WHITE);
+ print("[");
+ textcolor(color);
+ print(status);
+ textcolor(WHITE);
+ print("]");
+}
+
+void StdioLogger::printStatus(const char* status, log_color color)
+{
+ printBracket(status, color);
+ print("\n");
+}
+
+static log_color log_level_color[] = {
+ LIGHT_RED,
+ LIGHT_RED,
+ YELLOW,
+ LIGHT_WHITE,
+ GREEN,
+ BLUE
+};
+
+void StdioLogger::LogInternal(log_level level, const char* owner, const char* message, log_color color)
+{
+ if (level < FATAL) {
+ level = FATAL;
+ }
+ textcolor(LIGHT_WHITE);
+ print("[");
+ print(owner);
+ if (log_level_text[level][0]) {
+ print("/");
+ textcolor(log_level_color[level]);
+ print(log_level_text[level]);
+ }
+ textcolor(LIGHT_WHITE);
+ print("]: ");
+
+ textcolor(color);
+ print(message);
+ print("\n");
+}
+
+void StdioLogger::destroy()
+{
+ textcolor(DEFAULT);
+}
+
+Logger* createStdioLogger()
+{
+#ifndef NOCOLOR
+ return new StdioLogger(true);
+#else
+ return new StdioLogger(false);
+#endif
+}
+
+}
diff --git a/gemrb/core/System/Logger/Stdio.h b/gemrb/core/System/Logger/Stdio.h
new file mode 100644
index 0000000..e77830f
--- /dev/null
+++ b/gemrb/core/System/Logger/Stdio.h
@@ -0,0 +1,46 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef LOGGER_STDIO_H
+#define LOGGER_STDIO_H
+
+#include "System/Logger.h" // for log_color
+
+namespace GemRB {
+
+class GEM_EXPORT StdioLogger : public Logger {
+public:
+ StdioLogger(bool useColor);
+ virtual ~StdioLogger();
+ virtual void destroy();
+protected:
+ virtual void LogInternal(log_level, const char* owner, const char* message, log_color color);
+ virtual void print(const char*);
+ virtual void textcolor(log_color);
+ bool useColor;
+private:
+ void printBracket(const char *status, log_color color);
+ void printStatus(const char* status, log_color color);
+
+};
+
+Logger* createStdioLogger();
+
+}
+
+#endif
diff --git a/gemrb/core/System/Logger/Win32Console.cpp b/gemrb/core/System/Logger/Win32Console.cpp
new file mode 100644
index 0000000..6bd9295
--- /dev/null
+++ b/gemrb/core/System/Logger/Win32Console.cpp
@@ -0,0 +1,79 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "System/Logger/Win32Console.h"
+
+#include "System/Logging.h"
+
+#include <cstdio>
+
+#define ADV_TEXT
+#include <conio.h>
+
+namespace GemRB {
+
+#ifdef __MINGW32__
+# define cprintf _cprintf
+#endif
+
+Win32ConsoleLogger::Win32ConsoleLogger(bool useColor)
+ : StdioLogger(useColor)
+{
+ hConsole = GetStdHandle( STD_OUTPUT_HANDLE );
+}
+
+Win32ConsoleLogger::~Win32ConsoleLogger()
+{}
+
+void Win32ConsoleLogger::print(const char *message)
+{
+ cprintf("%s", message);
+}
+
+static int colors[] = {
+ 0,
+ 0,
+ FOREGROUND_RED,
+ FOREGROUND_GREEN,
+ FOREGROUND_GREEN | FOREGROUND_RED,
+ FOREGROUND_BLUE,
+ FOREGROUND_RED | FOREGROUND_BLUE,
+ FOREGROUND_BLUE | FOREGROUND_GREEN,
+ FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED,
+ FOREGROUND_RED | FOREGROUND_INTENSITY,
+ FOREGROUND_GREEN | FOREGROUND_INTENSITY,
+ FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY,
+ FOREGROUND_BLUE | FOREGROUND_INTENSITY,
+ FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
+ FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
+ FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY,
+ FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED,
+};
+
+void Win32ConsoleLogger::textcolor(log_color c)
+{
+ if (useColor)
+ SetConsoleTextAttribute(hConsole, colors[c]);
+}
+
+Logger* createWin32ConsoleLogger()
+{
+ return new Win32ConsoleLogger(true);
+}
+
+}
diff --git a/gemrb/core/System/Logger/Win32Console.h b/gemrb/core/System/Logger/Win32Console.h
new file mode 100644
index 0000000..e28c685
--- /dev/null
+++ b/gemrb/core/System/Logger/Win32Console.h
@@ -0,0 +1,43 @@
+
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef LOGGER_WIN32_H
+#define LOGGER_WIN32_H
+
+#include "System/Logger/Stdio.h"
+
+namespace GemRB {
+
+class GEM_EXPORT Win32ConsoleLogger : public StdioLogger {
+public:
+ Win32ConsoleLogger(bool useColor);
+ virtual ~Win32ConsoleLogger();
+
+ void print(const char* message);
+ void textcolor(log_color);
+
+private:
+ HANDLE hConsole;
+};
+
+Logger* createWin32ConsoleLogger();
+
+}
+
+#endif
diff --git a/gemrb/core/System/Logging.cpp b/gemrb/core/System/Logging.cpp
new file mode 100644
index 0000000..bdaf08b
--- /dev/null
+++ b/gemrb/core/System/Logging.cpp
@@ -0,0 +1,129 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "System/Logging.h"
+
+#include "System/Logger.h"
+#include "System/StringBuffer.h"
+
+#include <cstdarg>
+#include <vector>
+
+namespace GemRB {
+
+static std::vector<Logger*> theLogger;
+
+void ShutdownLogging()
+{
+ for (size_t i = 0; i < theLogger.size(); ++i) {
+ theLogger[i]->destroy();
+ }
+ theLogger.clear();
+}
+
+void InitializeLogging()
+{
+ AddLogger(createDefaultLogger());
+}
+
+void AddLogger(Logger* logger)
+{
+ if (logger)
+ theLogger.push_back(logger);
+}
+
+void RemoveLogger(Logger* logger)
+{
+ if (logger) {
+ std::vector<Logger*>::iterator itr = theLogger.begin();
+ while (itr != theLogger.end()) {
+ if (*itr == logger) {
+ itr = theLogger.erase(itr);
+ } else {
+ itr++;
+ }
+ }
+ logger->destroy();
+ logger = NULL;
+ }
+}
+
+static void vLog(log_level level, const char* owner, const char* message, log_color color, va_list ap)
+{
+ if (theLogger.empty())
+ return;
+
+ // Copied from System/StringBuffer.cpp
+#if defined(_MSC_VER)
+ // Don't try to be smart.
+ // Assume this is long enough. If not, message will be truncated.
+ // MSVC6 has old vsnprintf that doesn't give length
+ const size_t len = 4095;
+#else
+ va_list ap_copy;
+ va_copy(ap_copy, ap);
+ const size_t len = vsnprintf(NULL, 0, message, ap_copy);
+ va_end(ap_copy);
+#endif
+
+#if defined(__GNUC__)
+ __extension__ // Variable-length arrays
+#endif
+ char buf[len+1];
+ vsnprintf(buf, len + 1, message, ap);
+ for (size_t i = 0; i < theLogger.size(); ++i) {
+ theLogger[i]->log(level, owner, buf, color);
+ }
+}
+
+void print(const char *message, ...)
+{
+ va_list ap;
+ va_start(ap, message);
+ vLog(MESSAGE, "Unknown", message, WHITE, ap);
+ va_end(ap);
+}
+
+void error(const char* owner, const char* message, ...)
+{
+ va_list ap;
+ va_start(ap, message);
+ vLog(FATAL, owner, message, LIGHT_RED, ap);
+ va_end(ap);
+
+ ShutdownLogging();
+
+ exit(1);
+}
+
+void Log(log_level level, const char* owner, const char* message, ...)
+{
+ va_list ap;
+ va_start(ap, message);
+ vLog(level, owner, message, WHITE, ap);
+ va_end(ap);
+}
+
+void Log(log_level level, const char* owner, StringBuffer const& buffer)
+{
+ for (size_t i = 0; i < theLogger.size(); ++i) {
+ theLogger[i]->log(level, owner, buffer.get().c_str(), WHITE);
+ }
+}
+
+}
diff --git a/gemrb/core/System/Logging.h b/gemrb/core/System/Logging.h
new file mode 100644
index 0000000..6a6a44d
--- /dev/null
+++ b/gemrb/core/System/Logging.h
@@ -0,0 +1,96 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file logging.h
+ * Logging definitions.
+ * @author The GemRB Project
+ */
+
+
+#ifndef LOGGING_H
+#define LOGGING_H
+
+#include "exports.h"
+#include "win32def.h"
+
+namespace GemRB {
+
+#ifdef WIN32
+# undef ERROR
+#endif
+// !!! Keep this synchronized with GUIDefines !!!
+enum log_level {
+ INTERNAL = -1, // special value that can only be used by the logger itself. these messages cannot be supressed
+ FATAL = 0,
+ ERROR = 1,
+ WARNING = 2,
+ MESSAGE = 3,
+ COMBAT = 4,
+ DEBUG = 5
+};
+
+class Logger;
+class StringBuffer;
+
+GEM_EXPORT void InitializeLogging();
+GEM_EXPORT void AddLogger(Logger*);
+GEM_EXPORT void RemoveLogger(Logger*);
+GEM_EXPORT void ShutdownLogging();
+
+#if defined(__GNUC__)
+# define PRINTF_FORMAT(x, y) \
+ __attribute__ ((format(printf, x, y)))
+#else
+# define PRINTF_FORMAT(x, y)
+#endif
+
+#if defined(__GNUC__)
+# define NORETURN __attribute__ ((noreturn))
+#elif defined(_MSC_VER)
+# define NORETURN __declspec(noreturn)
+#else
+# define NORETURN
+#endif
+
+GEM_EXPORT void print(const char* message, ...)
+ PRINTF_FORMAT(1, 2);
+
+/// Log an error, and exit.
+NORETURN
+GEM_EXPORT void error(const char* owner, const char* message, ...)
+ PRINTF_FORMAT(2, 3);
+
+GEM_EXPORT void Log(log_level, const char* owner, const char* message, ...)
+ PRINTF_FORMAT(3, 4);
+
+GEM_EXPORT void Log(log_level, const char* owner, StringBuffer const&);
+
+#undef PRINTF_FORMAT
+#undef NORETURN
+
+}
+
+// poison printf
+#if (__GNUC__ >= 4 && (__GNUC_MINOR__ >= 5 || __GNUC__ > 4))
+extern "C" int printf(const char* message, ...) __attribute__ ((deprecated("GemRB doesn't use printf; use Log instead.")));
+#elif __GNUC__ >= 4
+extern "C" int printf(const char* message, ...) __attribute__ ((deprecated));
+#endif
+
+#endif
diff --git a/gemrb/core/System/MemoryStream.cpp b/gemrb/core/System/MemoryStream.cpp
index 1ce9656..7fcbe91 100644
--- a/gemrb/core/System/MemoryStream.cpp
+++ b/gemrb/core/System/MemoryStream.cpp
@@ -21,90 +21,82 @@
#include "System/MemoryStream.h"
#include "win32def.h"
+#include "errors.h"
-#include <cstring>
+#include "Interface.h"
-MemoryStream::MemoryStream(void* buffer, int length, bool autoFree)
+namespace GemRB {
+
+MemoryStream::MemoryStream(char *name, void* data, unsigned long size)
+ : data((char*)data)
{
- ptr = buffer;
- size = length;
- Pos = 0;
- strcpy( filename, "" );
- this->autoFree = autoFree;
+ this->size = size;
+ ExtractFileFromPath(filename, name);
+ strlcpy(originalfile, name, _MAX_PATH);
}
-MemoryStream::~MemoryStream(void)
+MemoryStream::~MemoryStream()
{
- if (autoFree) {
- free( ptr );
- }
+ free(data);
+}
+
+DataStream* MemoryStream::Clone()
+{
+ void *copy = malloc(size);
+ memcpy(copy, data, size);
+ return new MemoryStream(originalfile, copy, size);
}
int MemoryStream::Read(void* dest, unsigned int length)
{
- if (length + Pos > size) {
+ //we don't allow partial reads anyway, so it isn't a problem that
+ //i don't adjust length here (partial reads are evil)
+ if (Pos+length>size ) {
return GEM_ERROR;
}
- ieByte* p = ( ieByte* ) ptr + Pos;
- memcpy( dest, p, length );
+
+ memcpy(dest, data + Pos + (Encrypted ? 2 : 0), length);
if (Encrypted) {
ReadDecrypted( dest, length );
}
Pos += length;
- return GEM_OK;
+ return length;
+}
+
+int MemoryStream::Write(const void* src, unsigned int length)
+{
+ if (Pos+length>size ) {
+ //error("MemoryStream", "We don't support appending to memory streams yet.");
+ return GEM_ERROR;
+ }
+ memcpy(data+Pos, src, length);
+ Pos += length;
+ return length;
}
int MemoryStream::Seek(int newpos, int type)
{
switch (type) {
case GEM_CURRENT_POS:
- if (( Pos + newpos ) > size) {
- printf("[Streams]: Invalid seek\n");
- return GEM_ERROR;
- }
Pos += newpos;
break;
case GEM_STREAM_START:
- if ((unsigned long) newpos > size) {
- printf("[Streams]: Invalid seek\n");
- return GEM_ERROR;
- }
Pos = newpos;
break;
+ case GEM_STREAM_END:
+ Pos = size - newpos;
+
default:
return GEM_ERROR;
}
+ //we went past the buffer
+ if (Pos>size) {
+ print("[Streams]: Invalid seek position: %ld(limit: %ld)", Pos, size);
+ return GEM_ERROR;
+ }
return GEM_OK;
}
-/** No descriptions */
-int MemoryStream::ReadLine(void* buf, unsigned int maxlen)
-{
- if(!maxlen) {
- return 0;
- }
- unsigned char * p = ( unsigned char * ) buf;
- if (Pos >= size) {
- p[0]=0;
- return -1;
- }
- unsigned int i = 0;
- while (i < ( maxlen - 1 )) {
- ieByte ch = *( ( ieByte* ) ptr + Pos );
- if (Pos == size)
- break;
- if (Encrypted)
- p[i] ^= GEM_ENCRYPTION_KEY[Pos & 63];
- Pos++;
- if (( ( char ) ch ) == '\n')
- break;
- if (( ( char ) ch ) == '\t')
- ch = ' ';
- if (( ( char ) ch ) != '\r')
- p[i++] = ch;
- }
- p[i] = 0;
- return i;
}
diff --git a/gemrb/core/System/MemoryStream.h b/gemrb/core/System/MemoryStream.h
index adda37f..19a1659 100644
--- a/gemrb/core/System/MemoryStream.h
+++ b/gemrb/core/System/MemoryStream.h
@@ -18,41 +18,29 @@
*
*/
-/**
- * @file MemoryStream.h
- * Declares MemoryStream class, stream reading/writing data from/to a buffer in memory.
- * @author The GemRB Project
- */
-
-
#ifndef MEMORYSTREAM_H
#define MEMORYSTREAM_H
#include "System/DataStream.h"
#include "exports.h"
-#include "globals.h"
-/**
- * @class MemoryStream
- * Reads and writes data from/to a buffer in memory.
- */
+namespace GemRB {
-class GEM_EXPORT MemoryStream : public DataStream {
+class GEM_EXPORT MemoryStream : public DataStream
+{
private:
- void* ptr;
- //unsigned long length;
- bool autoFree;
+ char *data;
public:
- MemoryStream(void* buffer, int length, bool autoFree = true);
- ~MemoryStream(void);
+ MemoryStream(char *name, void* data, unsigned long size);
+ ~MemoryStream();
+ DataStream* Clone();
+
int Read(void* dest, unsigned int length);
- int Write(const void * /*src*/, unsigned int /*length*/)
- {
- return GEM_ERROR;
- }
+ int Write(const void* src, unsigned int length);
int Seek(int pos, int startpos);
- int ReadLine(void* buf, unsigned int maxlen);
};
-#endif // ! MEMORYSTREAM_H
+}
+
+#endif
diff --git a/gemrb/core/System/SlicedStream.cpp b/gemrb/core/System/SlicedStream.cpp
new file mode 100644
index 0000000..6fb2e51
--- /dev/null
+++ b/gemrb/core/System/SlicedStream.cpp
@@ -0,0 +1,130 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "System/SlicedStream.h"
+
+#include "System/MemoryStream.h"
+
+#include "win32def.h"
+#include "errors.h"
+
+#include "Interface.h"
+
+namespace GemRB {
+
+SlicedStream::SlicedStream(DataStream* str, int startpos, int size)
+{
+ this->str = str->Clone();
+ assert(this->str);
+ this->size = size;
+ this->startpos = startpos;
+ strlcpy(originalfile, str->originalfile, _MAX_PATH);
+ strlcpy(filename, str->filename, sizeof(filename));
+ this->str->Seek(this->startpos, GEM_STREAM_START);
+}
+
+SlicedStream::~SlicedStream()
+{
+ delete str;
+}
+
+DataStream* SlicedStream::Clone()
+{
+ return new SlicedStream(str, startpos, size);
+}
+
+int SlicedStream::Read(void* dest, unsigned int length)
+{
+ //we don't allow partial reads anyway, so it isn't a problem that
+ //i don't adjust length here (partial reads are evil)
+ if (Pos+length>size ) {
+ return GEM_ERROR;
+ }
+
+ //str->Seek(startpos + Pos + (Encrypted ? 2 : 0), GEM_STREAM_START);
+ unsigned int c = (unsigned int) str->Read(dest, length);
+ if (c != length) {
+ return GEM_ERROR;
+ }
+ if (Encrypted) {
+ ReadDecrypted( dest, c );
+ }
+ Pos += c;
+ return c;
+}
+
+int SlicedStream::Write(const void* src, unsigned int length)
+{
+ //str->Seek(startpos + Pos, GEM_STREAM_START);
+ unsigned int c = (unsigned int) Write(src, length);
+ if (c != length) {
+ return GEM_ERROR;
+ }
+ Pos += c;
+ //this is needed only if you want to Seek in a written file
+ if (Pos>size) {
+ size = Pos;
+ }
+ return c;
+}
+
+int SlicedStream::Seek(int newpos, int type)
+{
+ switch (type) {
+ case GEM_CURRENT_POS:
+ Pos += newpos;
+ break;
+
+ case GEM_STREAM_START:
+ Pos = newpos;
+ break;
+
+ default:
+ return GEM_ERROR;
+ }
+ str->Seek(startpos + Pos /*+ (Encrypted ? 2 : 0)*/, GEM_STREAM_START);
+ //we went past the buffer
+ if (Pos>size) {
+ print("[Streams]: Invalid seek position: %ld(limit: %ld)", Pos, size);
+ return GEM_ERROR;
+ }
+ return GEM_OK;
+}
+
+DataStream* SliceStream(DataStream* str, unsigned long startpos, unsigned long size, bool preservepos)
+{
+ if (size <= 16384) {
+ // small (or empty) substream, just read it into a buffer instead of expensive file I/O
+ unsigned long oldpos;
+ if (preservepos)
+ oldpos = str->GetPos();
+ str->Seek(startpos, GEM_STREAM_START);
+ char *data = (char*)malloc(size);
+ str->Read(data, size);
+ if (preservepos)
+ str->Seek(oldpos, GEM_STREAM_START);
+
+ DataStream *mem = new MemoryStream(str->originalfile, data, size);
+ return mem;
+ } else
+ return new SlicedStream(str, startpos, size);
+}
+
+}
diff --git a/gemrb/core/System/SlicedStream.h b/gemrb/core/System/SlicedStream.h
new file mode 100644
index 0000000..b341770
--- /dev/null
+++ b/gemrb/core/System/SlicedStream.h
@@ -0,0 +1,50 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef SLICEDSTREAM_H
+#define SLICEDSTREAM_H
+
+#include "System/DataStream.h"
+
+#include "exports.h"
+
+namespace GemRB {
+
+class GEM_EXPORT SlicedStream : public DataStream
+{
+private:
+// bool autoFree;
+ unsigned long startpos;
+ DataStream* str;
+public:
+ SlicedStream(DataStream* cfs, int startpos, int size);
+ ~SlicedStream();
+ DataStream* Clone();
+
+ int Read(void* dest, unsigned int length);
+ int Write(const void* src, unsigned int length);
+ int Seek(int pos, int startpos);
+};
+
+GEM_EXPORT DataStream* SliceStream(DataStream* str, unsigned long startpos, unsigned long size, bool preservepos = false);
+
+}
+
+#endif
diff --git a/gemrb/core/System/String.cpp b/gemrb/core/System/String.cpp
new file mode 100644
index 0000000..77b08ab
--- /dev/null
+++ b/gemrb/core/System/String.cpp
@@ -0,0 +1,191 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "System/String.h"
+
+#include "exports.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#ifdef WIN32
+#include "win32def.h"
+#ifdef _DEBUG
+#include <crtdbg.h>
+#endif
+#endif
+
+namespace GemRB {
+
+unsigned char pl_uppercase[256];
+unsigned char pl_lowercase[256];
+
+// these 3 functions will copy a string to a zero terminated string with a maximum length
+void strnlwrcpy(char *dest, const char *source, int count, bool pad)
+{
+ while(count--) {
+ *dest++ = pl_lowercase[(unsigned char) *source];
+ if(!*source++) {
+ if (!pad)
+ return;
+ while(count--) *dest++=0;
+ break;
+ }
+ }
+ *dest=0;
+}
+
+void strnuprcpy(char* dest, const char *source, int count)
+{
+ while(count--) {
+ *dest++ = pl_uppercase[(unsigned char) *source];
+ if(!*source++) {
+ while(count--) *dest++=0;
+ break;
+ }
+ }
+ *dest=0;
+}
+
+// this one also filters spaces, used to copy resrefs and variables
+void strnspccpy(char* dest, const char *source, int count, bool upper)
+{
+ memset(dest,0,count);
+ while(count--) {
+ char c;
+ if (upper)
+ c = pl_uppercase[(unsigned char) *source];
+ else
+ c = pl_lowercase[(unsigned char) *source];
+ if (c!=' ') {
+ *dest++=c;
+ }
+ if(!*source++) {
+ return;
+ }
+ }
+}
+
+/** Convert string to uppercase in-place using selected IE encoding */
+char* strtoupper(char* string)
+{
+ char* s;
+ if (string) {
+ for (s = string; *s; ++s)
+ *s = pl_uppercase[(unsigned char)*s];
+ }
+ return string;
+}
+
+/** Convert string to lowercase in-place using selected IE encoding */
+char* strtolower(char* string)
+{
+ char* s;
+ if (string) {
+ for (s = string; *s; ++s)
+ *s = pl_lowercase[(unsigned char)*s];
+ }
+ return string;
+}
+
+/** Returns the length of string (up to a delimiter) */
+GEM_EXPORT int strlench(const char* string, char ch)
+{
+ int i;
+ for (i = 0; string[i] && string[i] != ch; i++)
+ ;
+ return i;
+}
+
+} // namespace GemRB
+
+#ifndef HAVE_STRNLEN
+int strnlen(const char* string, int maxlen)
+{
+ if (!string) {
+ return -1;
+ }
+ int i = 0;
+ while (maxlen-- > 0) {
+ if (!string[i])
+ break;
+ i++;
+ }
+ return i;
+}
+#endif // ! HAVE_STRNLEN
+
+//// Compatibility functions
+#ifndef HAVE_STRNDUP
+GEM_EXPORT char* strndup(const char* s, size_t l)
+{
+ size_t len = strlen( s );
+ if (len < l) {
+ l = len;
+ }
+ char* string = ( char* ) malloc( l + 1 );
+ strlcpy( string, s, l + 1 );
+ return string;
+}
+#endif
+
+#ifndef HAVE_STRLCPY
+GEM_EXPORT size_t strlcpy(char *d, const char *s, size_t l)
+{
+ char *dst = d;
+ const char *src = s;
+
+ if (l != 0) {
+ while (--l != 0) {
+ if ((*dst++ = *src++) == '\0')
+ break;
+ }
+ if (l == 0)
+ *dst = '\0';
+ }
+
+ if (l == 0)
+ while (*src++) ;
+ return src - s - 1; /* length of source, excluding NULL */
+}
+#endif
+
+#ifdef WIN32
+
+#else
+
+char* strupr(char* string)
+{
+ char* s;
+ if (string) {
+ for (s = string; *s; ++s)
+ *s = toupper( *s );
+ }
+ return string;
+}
+
+char* strlwr(char* string)
+{
+ char* s;
+ if (string) {
+ for (s = string; *s; ++s)
+ *s = tolower( *s );
+ }
+ return string;
+}
+
+#endif // ! WIN32
diff --git a/gemrb/core/System/String.h b/gemrb/core/System/String.h
new file mode 100644
index 0000000..31aa1f0
--- /dev/null
+++ b/gemrb/core/System/String.h
@@ -0,0 +1,67 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef STRING_H
+#define STRING_H
+
+#include "exports.h"
+
+#include <cstring>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef WIN32
+# define stricmp strcasecmp
+# define strnicmp strncasecmp
+#endif
+
+namespace GemRB {
+/* this function will work with pl/cz special characters */
+
+extern unsigned char pl_uppercase[256];
+extern unsigned char pl_lowercase[256];
+
+GEM_EXPORT void strnlwrcpy(char* d, const char *s, int l, bool pad = true);
+GEM_EXPORT void strnuprcpy(char* d, const char *s, int l);
+GEM_EXPORT void strnspccpy(char* d, const char *s, int l, bool upper = false);
+/** Convert string to uppercase in-place using selected IE encoding */
+GEM_EXPORT char* strtoupper(char* string);
+/** Convert string to uppercase in-place using selected IE encoding */
+GEM_EXPORT char* strtolower(char* string);
+GEM_EXPORT int strlench(const char* string, char ch);
+
+}
+
+#ifndef HAVE_STRNLEN
+GEM_EXPORT int strnlen(const char* string, int maxlen);
+#endif
+#ifndef HAVE_STRNDUP
+GEM_EXPORT char* strndup(const char* s, size_t l);
+#endif
+#ifndef HAVE_STRLCPY
+GEM_EXPORT size_t strlcpy(char *d, const char *s, size_t l);
+#endif
+
+#ifndef WIN32
+GEM_EXPORT char* strupr(char* string);
+GEM_EXPORT char* strlwr(char* string);
+#endif
+
+#endif
diff --git a/gemrb/core/System/StringBuffer.cpp b/gemrb/core/System/StringBuffer.cpp
new file mode 100644
index 0000000..221f9df
--- /dev/null
+++ b/gemrb/core/System/StringBuffer.cpp
@@ -0,0 +1,76 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "System/StringBuffer.h"
+
+#include "win32def.h"
+
+#include <cstdio>
+#include <cstdarg>
+
+namespace GemRB {
+
+StringBuffer::StringBuffer()
+{}
+
+StringBuffer::~StringBuffer()
+{}
+
+void StringBuffer::appendFormatted(const char* message, ...)
+{
+ va_list ap;
+
+#if defined(_MSC_VER)
+ // Don't try to be smart.
+ // Assume this is long enough. If not, message will be truncated.
+ // MSVC6 has old vsnprintf that doesn't give length
+ const size_t len = 4095;
+#else
+ va_start(ap, message);
+ const size_t len = vsnprintf(NULL, 0, message, ap);
+ va_end(ap);
+#endif
+
+#if defined(__GNUC__)
+ __extension__ // Variable-length arrays
+#endif
+ char buf[len+1];
+ va_start(ap, message);
+ vsnprintf(buf, len + 1, message, ap);
+ va_end(ap);
+
+ // TODO: If we manage the string ourselves, we can avoid this extra copy.
+ buffer += buf;
+}
+
+void StringBuffer::append(const char* message)
+{
+ buffer += message;
+}
+
+void StringBuffer::append(std::string const& message)
+{
+ buffer += message;
+}
+
+std::string const& StringBuffer::get() const
+{
+ return buffer;
+}
+
+}
diff --git a/gemrb/core/System/StringBuffer.h b/gemrb/core/System/StringBuffer.h
new file mode 100644
index 0000000..f6f41b9
--- /dev/null
+++ b/gemrb/core/System/StringBuffer.h
@@ -0,0 +1,66 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file StringBuffer.h
+ * Code for formating debug dumps
+ * @author The GemRB Project
+ */
+
+#ifndef STRINGBUFFER_H
+#define STRINGBUFFER_H
+
+#include "exports.h"
+
+#include <string>
+
+namespace GemRB {
+
+#if defined(__GNUC__)
+# define PRINTF_FORMAT(x, y) \
+ __attribute__ ((format(printf, x, y)))
+#else
+# define PRINTF_FORMAT(x, y)
+#endif
+
+class GEM_EXPORT StringBuffer {
+public:
+ StringBuffer();
+ virtual ~StringBuffer();
+
+ /// Append formatted string to buffer
+ void appendFormatted(const char* message, ...)
+ PRINTF_FORMAT(2, 3);
+ /// Append a string to buffer
+ void append(const char* message);
+ /// Append a std::string to buffer
+ void append(std::string const& message);
+
+ /// Return buffer
+ std::string const& get() const;
+
+private:
+ // TODO: Should we manage the string ourselves, and use the small string optimization?
+ std::string buffer;
+};
+
+#undef PRINTF_FORMAT
+
+}
+
+#endif
diff --git a/gemrb/core/System/VFS.cpp b/gemrb/core/System/VFS.cpp
index 4e6d348..3e68995 100644
--- a/gemrb/core/System/VFS.cpp
+++ b/gemrb/core/System/VFS.cpp
@@ -27,17 +27,23 @@
#include "Interface.h"
-#if defined(__HAIKU__)
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <cstdarg>
#include <cstring>
+#include <cerrno>
#ifndef WIN32
#include <dirent.h>
#endif
+#ifdef __APPLE__
+// for getting resources inside the bundle
+#include <CoreFoundation/CFBundle.h>
+#endif
+
#ifndef S_ISDIR
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#endif
@@ -48,6 +54,8 @@
#ifdef WIN32
+using namespace GemRB;
+
struct DIR {
char path[_MAX_PATH];
bool is_first;
@@ -62,7 +70,7 @@ struct dirent {
// buffer which readdir returns
static dirent de;
-DIR* opendir(const char* filename)
+static DIR* opendir(const char* filename)
{
DIR* dirp = ( DIR* ) malloc( sizeof( DIR ) );
dirp->is_first = 1;
@@ -73,7 +81,7 @@ DIR* opendir(const char* filename)
return dirp;
}
-dirent* readdir(DIR* dirp)
+static dirent* readdir(DIR* dirp)
{
struct _finddata_t c_file;
@@ -93,156 +101,45 @@ dirent* readdir(DIR* dirp)
return &de;
}
-void closedir(DIR* dirp)
+static void closedir(DIR* dirp)
{
_findclose( dirp->hFile );
free( dirp );
}
+#endif // WIN32
-_FILE* _fopen(const char* filename, const char* mode)
-{
- DWORD OpenFlags = 0;
- DWORD AccessFlags = 0;
- DWORD ShareFlags = 0;
-
- while (*mode) {
- if (( *mode == 'w' ) || ( *mode == 'W' )) {
- OpenFlags |= OPEN_ALWAYS;
- AccessFlags |= GENERIC_WRITE;
- ShareFlags |= FILE_SHARE_READ;
- } else if (( *mode == 'r' ) || ( *mode == 'R' )) {
- OpenFlags |= OPEN_EXISTING;
- AccessFlags |= GENERIC_READ;
- ShareFlags |= FILE_SHARE_READ|FILE_SHARE_WRITE;
- } else if (( *mode == 'a' ) || ( *mode == 'A' )) {
- OpenFlags |= OPEN_ALWAYS;
- AccessFlags |= GENERIC_READ|GENERIC_WRITE;
- ShareFlags |= FILE_SHARE_READ|FILE_SHARE_WRITE;
- } else if (*mode == '+') {
- AccessFlags |= GENERIC_READ|GENERIC_WRITE;
- ShareFlags |= FILE_SHARE_READ|FILE_SHARE_WRITE;
- }
- mode++;
- }
- HANDLE hFile = CreateFile( filename, AccessFlags, ShareFlags, NULL,
- OpenFlags, FILE_ATTRIBUTE_NORMAL, NULL );
- if (hFile == INVALID_HANDLE_VALUE) {
- return NULL;
- }
- _FILE* ret = ( _FILE* ) malloc( sizeof( _FILE ) );
- ret->hFile = hFile;
- return ret;
-}
-
-size_t _fread(void* ptr, size_t size, size_t n, _FILE* stream)
-{
- if (!stream) {
- return ( size_t ) 0;
- }
- unsigned long read;
- if (!ReadFile( stream->hFile, ptr, ( unsigned long ) ( size * n ), &read,
- NULL )) {
- return ( size_t ) 0;
- }
- return ( size_t ) read;
-}
-
-size_t _fwrite(const void* ptr, size_t size, size_t n, _FILE* stream)
-{
- if (!stream) {
- return ( size_t ) 0;
- }
- unsigned long wrote;
- if (!WriteFile( stream->hFile, ptr, ( unsigned long ) ( size * n ),
- &wrote, NULL )) {
- return ( size_t ) 0;
- }
- return ( size_t ) wrote;
-}
-
-size_t _fseek(_FILE* stream, long offset, int whence)
+namespace GemRB {
+#if __APPLE__
+//bundle path functions
+void CopyBundlePath(char* outPath, ieWord maxLen, BundleDirectory dir)
{
- if (!stream) {
- return ( size_t ) 1;
- }
- unsigned long method;
- switch (whence) {
- case SEEK_SET:
- method = FILE_BEGIN;
- break;
- case SEEK_CUR:
- method = FILE_CURRENT;
+ CFBundleRef mainBundle = CFBundleGetMainBundle();
+ CFURLRef bundleDirURL = NULL;
+ switch (dir) {
+ case RESOURCES:
+ bundleDirURL = CFBundleCopyResourcesDirectoryURL(mainBundle);
break;
- case SEEK_END:
- method = FILE_END;
+ case PLUGINS:
+ // undeined on iOS!
+ bundleDirURL = CFBundleCopyBuiltInPlugInsURL(mainBundle);
break;
+ case BUNDLE:
default:
- return ( size_t ) 1;
- }
- if (SetFilePointer( stream->hFile, offset, NULL, method ) == 0xffffffff) {
- return ( size_t ) 1;
- }
- return ( size_t ) 0;
-}
-
-int _fgetc(_FILE* stream)
-{
- if (!stream) {
- return 0;
- }
- unsigned char tmp;
- unsigned long read;
- BOOL bResult = ReadFile( stream->hFile, &tmp, ( unsigned long ) 1, &read,
- NULL );
- if (bResult && read) {
- return ( int ) tmp;
- }
- return EOF;
-}
-
-long int _ftell(_FILE* stream)
-{
- if (!stream) {
- return EOF;
- }
- unsigned long pos = SetFilePointer( stream->hFile, 0, NULL, FILE_CURRENT );
- if (pos == 0xffffffff) {
- return -1L;
- }
- return ( long int ) pos;
-}
-
-int _feof(_FILE* stream)
-{
- if (!stream) {
- return 0;
- }
- unsigned char tmp;
- unsigned long read;
- BOOL bResult = ReadFile( stream->hFile, &tmp, ( unsigned long ) 1, &read,
- NULL );
- if (bResult && ( read == 0 )) {
- return 1;
- } //EOF
- bResult = SetFilePointer( stream->hFile, -1, NULL, FILE_CURRENT );
- return 0;
-}
-
-int _fclose(_FILE* stream)
-{
- if (!stream) {
- return EOF;
+ // get the bundle directory istelf by default
+ bundleDirURL = CFBundleCopyBundleURL(mainBundle);
+ break;
}
- if (!CloseHandle( stream->hFile )) {
- return EOF;
+ if (bundleDirURL) {
+ CFURLRef absoluteURL = CFURLCopyAbsoluteURL(bundleDirURL);
+ CFRelease(bundleDirURL);
+ CFStringRef bundleDirPath = CFURLCopyFileSystemPath( absoluteURL, kCFURLPOSIXPathStyle );
+ CFRelease(absoluteURL);
+ CFStringGetCString( bundleDirPath, outPath, maxLen, kCFStringEncodingASCII );
+ CFRelease(bundleDirPath);
}
- free( stream );
- return 0;
}
-
-#endif // WIN32
-
+#endif
/** Returns true if path is an existing directory */
bool dir_exists(const char* path)
@@ -260,7 +157,7 @@ bool dir_exists(const char* path)
return true;
}
-/** Returns true if path is an existing directory */
+/** Returns true if path is an existing file */
bool file_exists(const char* path)
{
struct stat buf;
@@ -289,13 +186,19 @@ char* PathAppend (char* target, const char* name)
target[len++] = PathDelimiter;
target[len] = 0;
}
+ // strip possible leading backslash, since it is not ignored on all platforms
+ // totl has '\data\zcMHar.bif' in the key file, and also the CaseSensitive
+ // code breaks with that extra slash, so simple fix: remove it
+ if (name[0] == '\\') {
+ name = name+1;
+ }
strncat( target+len, name, _MAX_PATH - len - 1 );
return target;
}
-bool FindInDir(const char* Dir, char *Filename)
+static bool FindInDir(const char* Dir, char *Filename)
{
// First test if there's a Filename with exactly same name
// and if yes, return it and do not search in the Dir
@@ -330,15 +233,16 @@ bool FindInDir(const char* Dir, char *Filename)
bool PathJoin (char *target, const char *base, ...)
{
- va_list ap;
- va_start(ap, base);
-
if (base == NULL) {
target[0] = '\0';
return false;
}
+ if (base != target) {
+ strcpy(target, base);
+ }
- strcpy(target, base);
+ va_list ap;
+ va_start(ap, base);
while (char *source = va_arg(ap, char*)) {
char *slash;
@@ -361,8 +265,10 @@ bool PathJoin (char *target, const char *base, ...)
source = slash + 1;
} while (slash);
}
+
va_end( ap );
return true;
+
finish:
while (char *source = va_arg(ap, char*)) {
PathAppend(target, source);
@@ -402,7 +308,7 @@ void FixPath (char *path, bool needslash)
path[i] = 0;
}
-int strmatch(const char *string, const char *mask)
+static int strmatch(const char *string, const char *mask)
{
while(*mask) {
if (*mask!='?') {
@@ -441,10 +347,9 @@ void ResolveFilePath(char* FilePath)
char TempFilePath[_MAX_PATH];
if (FilePath[0]=='~') {
- const char *home = getenv("HOME");
- if (home) {
- strcpy(TempFilePath, FilePath+1);
- PathJoin(FilePath, home, TempFilePath, NULL);
+ if (CopyHomePath(TempFilePath, _MAX_PATH)) {
+ PathAppend(TempFilePath, FilePath+1);
+ strcpy(FilePath, TempFilePath);
return;
}
}
@@ -461,9 +366,8 @@ void ResolveFilePath(std::string& FilePath)
char TempFilePath[_MAX_PATH];
if (FilePath[0]=='~') {
- const char *home = getenv("HOME");
- if (home) {
- PathJoin(TempFilePath, home, FilePath.c_str()+1, NULL);
+ if (CopyHomePath(TempFilePath, _MAX_PATH)) {
+ PathAppend(TempFilePath, FilePath.c_str()+1);
FilePath = TempFilePath;
return;
}
@@ -489,6 +393,107 @@ void ExtractFileFromPath(char *file, const char *full_path)
strcpy(file, full_path);
}
+bool MakeDirectories(const char* path)
+{
+ char TempFilePath[_MAX_PATH] = "";
+ char Tokenized[_MAX_PATH];
+ strcpy(Tokenized, path);
+
+ char* Token = strtok(Tokenized, &PathDelimiter);
+ while(Token != NULL) {
+ if(TempFilePath[0] == 0) {
+ if(path[0] == PathDelimiter) {
+ TempFilePath[0] = PathDelimiter;
+ TempFilePath[1] = 0;
+ }
+ strcat(TempFilePath, Token);
+ } else
+ PathJoin(TempFilePath, TempFilePath, Token, NULL);
+
+ if(!MakeDirectory(TempFilePath))
+ return false;
+
+ Token = strtok(NULL, &PathDelimiter);
+ }
+ return true;
+}
+
+bool MakeDirectory(const char* path)
+{
+#ifdef WIN32
+#define mkdir(path, mode) _mkdir(path)
+#endif
+ if (mkdir(path, S_IREAD|S_IWRITE|S_IEXEC) < 0) {
+ if (errno != EEXIST) {
+ return false;
+ }
+ }
+ // Ignore errors from chmod
+ chmod(path, S_IREAD|S_IWRITE|S_IEXEC);
+ return true;
+#ifdef WIN32
+#undef mkdir
+#endif
+}
+
+GEM_EXPORT char* CopyHomePath(char* outPath, ieWord maxLen)
+{
+ char* home = getenv( "HOME" );
+ if (home) {
+ strlcpy(outPath, home, maxLen);
+ return outPath;
+ }
+#ifdef WIN32
+ else {
+ // if home is null check HOMEDRIVE + HOMEPATH
+ char* homedrive = getenv("HOMEDRIVE");
+ home = getenv("HOMEPATH");
+
+ if (home) {
+ outPath[0] = '\0'; //ensure start string length is 0
+ if (homedrive) {
+ strlcpy(outPath, homedrive, maxLen);
+ }
+ PathAppend(outPath, home);
+ return outPath;
+ }
+ }
+#endif
+ return NULL;
+}
+
+GEM_EXPORT char* CopyGemDataPath(char* outPath, ieWord maxLen)
+{
+// build time supplied directory first
+#ifdef DATADIR
+ strlcpy(outPath, DATADIR, maxLen);
+#else
+#ifdef __APPLE__
+ CopyBundlePath(outPath, maxLen, RESOURCES);
+#else
+ // check $GEM_DATA env. note that Android wrapper sets this.
+ char* dataDir = getenv("GEM_DATA");
+ if (dataDir) {
+ strlcpy(outPath, dataDir, maxLen);
+ } else {
+ if (!CopyHomePath(outPath, maxLen)) {
+#ifdef WIN32
+ strlcpy(outPath, ".\\", maxLen);
+ } else {
+ PathAppend(outPath, PACKAGE);
+#else
+ strlcpy(outPath, "./", maxLen);
+ } else {
+ PathAppend(outPath, "."PACKAGE);
+#endif
+ }
+ }
+#endif
+#endif
+ return outPath;
+}
+
+
DirectoryIterator::DirectoryIterator(const char *path)
: Directory(NULL), Entry(NULL), Path(path)
{
@@ -504,10 +509,10 @@ DirectoryIterator::~DirectoryIterator()
bool DirectoryIterator::IsDirectory()
{
char dtmp[_MAX_PATH];
- struct stat fst;
GetFullPath(dtmp);
- stat( dtmp, &fst );
- return S_ISDIR( fst.st_mode );
+ //this is needed on windows!!!
+ FixPath(dtmp, false);
+ return dir_exists(dtmp);
}
char* DirectoryIterator::GetName()
@@ -536,3 +541,6 @@ void DirectoryIterator::Rewind()
else
Entry = readdir(static_cast<DIR*>(Directory));
}
+
+
+}
diff --git a/gemrb/core/System/VFS.h b/gemrb/core/System/VFS.h
index d78cb28..6c8f1aa 100644
--- a/gemrb/core/System/VFS.h
+++ b/gemrb/core/System/VFS.h
@@ -51,35 +51,23 @@
#define R_OK 04
#endif
+namespace GemRB {
+
#ifdef WIN32
-typedef struct _FILE {
- HANDLE hFile;
-} _FILE;
-
-GEM_EXPORT _FILE* _fopen(const char* filename, const char* mode);
-GEM_EXPORT size_t _fread(void* ptr, size_t size, size_t n, _FILE* stream);
-GEM_EXPORT size_t _fwrite(const void* ptr, size_t size, size_t n,
- _FILE* stream);
-GEM_EXPORT size_t _fseek(_FILE* stream, long offset, int whence);
-GEM_EXPORT int _fgetc(_FILE* stream);
-GEM_EXPORT long int _ftell(_FILE* stream);
-GEM_EXPORT int _feof(_FILE* stream);
-GEM_EXPORT int _fclose(_FILE* stream);
-#define mkdir(path, rights) _mkdir(path)
#define ResolveFilePath(p)
#else // ! WIN32
-#define _FILE FILE
-#define _fopen fopen
-#define _fread fread
-#define _fwrite fwrite
-#define _fseek fseek
-#define _fgetc fgetc
-#define _ftell ftell
-#define _feof feof
-#define _fclose fclose
+#ifdef __APPLE__
+// bundle path functions
+enum BundleDirectory {
+ BUNDLE,
+ RESOURCES,
+ PLUGINS
+};
+GEM_EXPORT void CopyBundlePath(char* outPath, ieWord maxLen, BundleDirectory dir = BUNDLE);
+#endif
/** Handle ~ -> $HOME mapping and do initial case-sensitity check */
GEM_EXPORT void ResolveFilePath(char* FilePath);
@@ -125,12 +113,22 @@ GEM_EXPORT bool file_exists(const char* path);
* char filepath[_MAX_PATH];
* PathJoin( filepath, core->GUIScriptsPath, core->GameType, 'GUIDefines.py', NULL );
*/
-GEM_EXPORT bool PathJoin (char* target, const char* base, ...);
+GEM_EXPORT bool PathJoin (char* target, const char* base, ...) SENTINEL;
GEM_EXPORT bool PathJoinExt (char* target, const char* dir, const char* file, const char* ext = NULL);
GEM_EXPORT void FixPath (char *path, bool needslash);
GEM_EXPORT void ExtractFileFromPath(char *file, const char *full_path);
+GEM_EXPORT char* PathAppend (char* target, const char* name);
+
+GEM_EXPORT bool MakeDirectories(const char* path) WARN_UNUSED;
+GEM_EXPORT bool MakeDirectory(const char* path) WARN_UNUSED;
+
+GEM_EXPORT char* CopyHomePath(char* outPath, ieWord maxLen);
+
+// default directory housing GUIScripts/Override/Unhardcoded
+GEM_EXPORT char* CopyGemDataPath(char* outPath, ieWord maxLen);
+
class GEM_EXPORT DirectoryIterator {
public:
/**
@@ -161,4 +159,6 @@ private:
const char *Path;
};
+}
+
#endif // !VFS_H
diff --git a/gemrb/core/System/android_log_printf.cpp b/gemrb/core/System/android_log_printf.cpp
deleted file mode 100644
index 73bf15c..0000000
--- a/gemrb/core/System/android_log_printf.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/* GemRB - Infinity Engine Emulator
- * Copyright (C) 2011 The GemRB Project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <android/log.h>
-
-int android_log_printf(const char * fmt, ...) {
- int return_value;
- va_list ap;
- va_start(ap, fmt);
- int characters = vfprintf(stdout, fmt, ap); // determine buffer size
- if(characters<0) return characters;
- char* buff = new char[characters+1];
- return_value = vsprintf(buff, fmt, ap);
- va_end(ap);
- __android_log_print(ANDROID_LOG_INFO, "printf:", buff);
- delete buff;
- return return_value;
-}
diff --git a/gemrb/core/System/android_log_printf.h b/gemrb/core/System/android_log_printf.h
deleted file mode 100644
index 1cc17be..0000000
--- a/gemrb/core/System/android_log_printf.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* GemRB - Infinity Engine Emulator
- * Copyright (C) 2011 The GemRB Project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#ifndef IE_ANDROID_LOG_PRINTF_H
-#define IE_ANDROID_LOG_PRINTF_H
-
-int android_log_printf(const char * fmt, ...);
-
-#endif
diff --git a/gemrb/core/System/snprintf.cpp b/gemrb/core/System/snprintf.cpp
deleted file mode 100644
index acd785d..0000000
--- a/gemrb/core/System/snprintf.cpp
+++ /dev/null
@@ -1,980 +0,0 @@
-/*
- * Copyright Patrick Powell 1995
- * This code is based on code written by Patrick Powell (papowell at astart.com)
- * It may be used for any purpose as long as this notice remains intact
- * on all source code distributions
- */
-
-/**************************************************************
- * Original:
- * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
- * A bombproof version of doprnt (dopr) included.
- * Sigh. This sort of thing is always nasty do deal with. Note that
- * the version here does not include floating point...
- *
- * snprintf() is used instead of sprintf() as it does limit checks
- * for string length. This covers a nasty loophole.
- *
- * The other functions are there to prevent NULL pointers from
- * causing nast effects.
- *
- * More Recently:
- * Brandon Long <blong at fiction.net> 9/15/96 for mutt 0.43
- * This was ugly. It is still ugly. I opted out of floating point
- * numbers, but the formatter understands just about everything
- * from the normal C string format, at least as far as I can tell from
- * the Solaris 2.5 printf(3S) man page.
- *
- * Brandon Long <blong at fiction.net> 10/22/97 for mutt 0.87.1
- * Ok, added some minimal floating point support, which means this
- * probably requires libm on most operating systems. Don't yet
- * support the exponent (e,E) and sigfig (g,G). Also, fmtint()
- * was pretty badly broken, it just wasn't being exercised in ways
- * which showed it, so that's been fixed. Also, formated the code
- * to mutt conventions, and removed dead code left over from the
- * original. Also, there is now a builtin-test, just compile with:
- * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
- * and run snprintf for results.
- *
- * Thomas Roessler <roessler at guug.de> 01/27/98 for mutt 0.89i
- * The PGP code was using unsigned hexadecimal formats.
- * Unfortunately, unsigned formats simply didn't work.
- *
- * Michael Elkins <me at cs.hmc.edu> 03/05/98 for mutt 0.90.8
- * The original code assumed that both snprintf() and vsnprintf() were
- * missing. Some systems only have snprintf() but not vsnprintf(), so
- * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
- *
- * Andrew Tridgell (tridge at samba.org) Oct 1998
- * fixed handling of %.0f
- * added test for HAVE_LONG_DOUBLE
- *
- * tridge at samba.org, idra at samba.org, April 2001
- * got rid of fcvt code (twas buggy and made testing harder)
- * added C99 semantics
- *
- * HT authors
- * * ht_snprintf/ht_vsnprintf return number of characters actually
- * written instead of the number of characters that would
- * have been written.
- * * added '%y' to allow object output using Object's toString() method.
- * * added '%q[dioux]' for formatting qwords.
- * * added '%b' for formatting in binary notation.
- **************************************************************/
-#include "win32def.h"
-#ifndef HAVE_SNPRINTF
-
-#include <cctype>
-#include <cstring>
-#include <cstdlib>
-#include <cstdio>
-#include <cstdarg>
-#include <sys/types.h>
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "system/types.h"
-#include "data.h"
-
-#ifndef MIN
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-#endif
-#ifndef MAX
-#define MAX(a, b) ((a) > (b) ? (a) : (b))
-#endif
-
-#ifdef HAVE_LONG_DOUBLE
-#define LDOUBLE long double
-#else
-#define LDOUBLE double
-#endif
-
-#ifdef HAVE_LONG_LONG
-#define LLONG long long
-#else
-#define LLONG long
-#endif
-
-static size_t dopr(char *buffer, size_t maxlen, const char *format,
- va_list args);
-static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
- char *value, int flags, int min, int max);
-static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
- long value, int base, int min, int max, int flags);
-static void fmtqword(char *buffer, size_t *currlen, size_t maxlen,
- sint64 value, int base, int min, int max, int flags);
-static void fmtfp(char *buffer, size_t *currlen, size_t maxlen,
- LDOUBLE fvalue, int min, int max, int flags);
-static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c);
-
-/*
- * dopr(): poor man's version of doprintf
- */
-
-/* format read states */
-#define DP_S_DEFAULT 0
-#define DP_S_FLAGS 1
-#define DP_S_MIN 2
-#define DP_S_DOT 3
-#define DP_S_MAX 4
-#define DP_S_MOD 5
-#define DP_S_CONV 6
-#define DP_S_DONE 7
-
-/* format flags - Bits */
-#define DP_F_MINUS (1 << 0)
-#define DP_F_PLUS (1 << 1)
-#define DP_F_SPACE (1 << 2)
-#define DP_F_NUM (1 << 3)
-#define DP_F_ZERO (1 << 4)
-#define DP_F_UP (1 << 5)
-#define DP_F_UNSIGNED (1 << 6)
-
-/* Conversion Flags */
-#define DP_C_SHORT 1
-#define DP_C_LONG 2
-#define DP_C_LDOUBLE 3
-#define DP_C_LLONG 4
-#define DP_C_QWORD 5
-
-#define char_to_int(p) ((p)- '0')
-#ifndef MAX
-#define MAX(p,q) (((p) >= (q)) ? (p) : (q))
-#endif
-
-static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args)
-{
- char ch;
- LLONG value;
- LDOUBLE fvalue;
- char *strvalue;
- int min;
- int max;
- int state;
- int flags;
- int cflags;
- size_t currlen;
-
- state = DP_S_DEFAULT;
- currlen = flags = cflags = min = 0;
- max = -1;
- ch = *format++;
-
- while (state != DP_S_DONE) {
- if (ch == '\0') state = DP_S_DONE;
-
- switch(state) {
- case DP_S_DEFAULT:
- if (ch == '%') {
- state = DP_S_FLAGS;
- } else {
- dopr_outch(buffer, &currlen, maxlen, ch);
- }
- ch = *format++;
- break;
- case DP_S_FLAGS:
- switch (ch) {
- case '-':
- flags |= DP_F_MINUS;
- ch = *format++;
- break;
- case '+':
- flags |= DP_F_PLUS;
- ch = *format++;
- break;
- case ' ':
- flags |= DP_F_SPACE;
- ch = *format++;
- break;
- case '#':
- flags |= DP_F_NUM;
- ch = *format++;
- break;
- case '0':
- flags |= DP_F_ZERO;
- ch = *format++;
- break;
- default:
- state = DP_S_MIN;
- break;
- }
- break;
- case DP_S_MIN:
- if (isdigit((unsigned char)ch)) {
- min = 10*min + char_to_int (ch);
- ch = *format++;
- } else if (ch == '*') {
- min = va_arg (args, int);
- ch = *format++;
- state = DP_S_DOT;
- } else {
- state = DP_S_DOT;
- }
- break;
- case DP_S_DOT:
- if (ch == '.') {
- state = DP_S_MAX;
- ch = *format++;
- } else {
- state = DP_S_MOD;
- }
- break;
- case DP_S_MAX:
- if (isdigit((unsigned char)ch)) {
- if (max < 0) max = 0;
- max = 10*max + char_to_int (ch);
- ch = *format++;
- } else if (ch == '*') {
- max = va_arg (args, int);
- ch = *format++;
- state = DP_S_MOD;
- } else {
- state = DP_S_MOD;
- }
- break;
- case DP_S_MOD:
- switch (ch) {
- case 'h':
- cflags = DP_C_SHORT;
- ch = *format++;
- break;
- case 'l':
- cflags = DP_C_LONG;
- ch = *format++;
- if (ch == 'l') { /* It's a long long */
- cflags = DP_C_LLONG;
- ch = *format++;
- }
- break;
- case 'L':
- cflags = DP_C_LDOUBLE;
- ch = *format++;
- break;
- case 'q':
- cflags = DP_C_QWORD;
- ch = *format++;
- break;
- default:
- break;
- }
- state = DP_S_CONV;
- break;
- case DP_S_CONV:
- switch (ch) {
- case 'b':
- flags |= DP_F_UNSIGNED;
- if (cflags == DP_C_SHORT) {
- value = va_arg (args, unsigned int);
- } else if (cflags == DP_C_LONG) {
- value = (long)va_arg (args, unsigned long int);
- } else if (cflags == DP_C_LLONG) {
- value = (LLONG)va_arg (args, unsigned LLONG);
- } else if (cflags == DP_C_QWORD) {
- sint64 *q = va_arg (args, sint64 *);
- fmtqword(buffer, &currlen, maxlen, *q, 2, min, max, flags);
- break;
- } else {
- value = (long)va_arg (args, unsigned int);
- }
- fmtint (buffer, &currlen, maxlen, value, 2, min, max, flags);
- break;
- case 'd':
- case 'i':
- if (cflags == DP_C_SHORT) {
- value = va_arg (args, int);
- } else if (cflags == DP_C_LONG) {
- value = va_arg (args, long int);
- } else if (cflags == DP_C_LLONG) {
- value = va_arg (args, LLONG);
- } else if (cflags == DP_C_QWORD) {
- sint64 *q = va_arg (args, sint64 *);
- fmtqword(buffer, &currlen, maxlen, *q, 10, min, max, flags);
- break;
- } else {
- value = va_arg (args, int);
- }
- fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
- break;
- case 'o':
- flags |= DP_F_UNSIGNED;
- if (cflags == DP_C_SHORT) {
- value = va_arg (args, unsigned int);
- } else if (cflags == DP_C_LONG) {
- value = (long)va_arg (args, unsigned long int);
- } else if (cflags == DP_C_LLONG) {
- value = (long)va_arg (args, unsigned LLONG);
- } else if (cflags == DP_C_QWORD) {
- sint64 *q = va_arg (args, sint64 *);
- fmtqword(buffer, &currlen, maxlen, *q, 8, min, max, flags);
- break;
- } else {
- value = (long)va_arg (args, unsigned int);
- }
- fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
- break;
- case 'u':
- flags |= DP_F_UNSIGNED;
- if (cflags == DP_C_SHORT) {
- value = va_arg (args, unsigned int);
- } else if (cflags == DP_C_LONG) {
- value = (long)va_arg (args, unsigned long int);
- } else if (cflags == DP_C_LLONG) {
- value = (LLONG)va_arg (args, unsigned LLONG);
- } else if (cflags == DP_C_QWORD) {
- sint64 *q = va_arg (args, sint64 *);
- fmtqword(buffer, &currlen, maxlen, *q, 10, min, max, flags);
- break;
- } else {
- value = (long)va_arg (args, unsigned int);
- }
- fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
- break;
- case 'X':
- flags |= DP_F_UP;
- case 'x':
- flags |= DP_F_UNSIGNED;
- if (cflags == DP_C_SHORT) {
- value = va_arg (args, unsigned int);
- } else if (cflags == DP_C_LONG) {
- value = (long)va_arg (args, unsigned long int);
- } else if (cflags == DP_C_LLONG) {
- value = (LLONG)va_arg (args, unsigned LLONG);
- } else if (cflags == DP_C_QWORD) {
- sint64 *q = va_arg (args, sint64 *);
- fmtqword(buffer, &currlen, maxlen, *q, 16, min, max, flags);
- break;
- } else {
- value = (long)va_arg (args, unsigned int);
- }
- fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
- break;
- case 'f':
- if (cflags == DP_C_LDOUBLE)
- fvalue = va_arg (args, LDOUBLE);
- else
- fvalue = va_arg (args, double);
- /* um, floating point? */
- fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
- break;
- case 'E':
- flags |= DP_F_UP;
- case 'e':
- if (cflags == DP_C_LDOUBLE)
- fvalue = va_arg (args, LDOUBLE);
- else
- fvalue = va_arg (args, double);
- break;
- case 'G':
- flags |= DP_F_UP;
- case 'g':
- if (cflags == DP_C_LDOUBLE)
- fvalue = va_arg (args, LDOUBLE);
- else
- fvalue = va_arg (args, double);
- break;
- case 'c':
- dopr_outch(buffer, &currlen, maxlen, va_arg (args, int));
- break;
- case 's':
- strvalue = va_arg (args, char *);
- if (!strvalue) strvalue = "(null)";
- if (max == -1) {
- max = strlen(strvalue);
- }
- if (min > 0 && max >= 0 && min > max) max = min;
- fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
- break;
- case 'p':
- strvalue = va_arg (args, char *);
- fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
- break;
- case 'n':
- if (cflags == DP_C_SHORT) {
- short int *num;
- num = va_arg (args, short int *);
- *num = currlen;
- } else if (cflags == DP_C_LONG) {
- long int *num;
- num = va_arg (args, long int *);
- *num = (long int)currlen;
- } else if (cflags == DP_C_LLONG) {
- LLONG *num;
- num = va_arg (args, LLONG *);
- *num = (LLONG)currlen;
- } else {
- int *num;
- num = va_arg (args, int *);
- *num = currlen;
- }
- break;
- case '%':
- dopr_outch(buffer, &currlen, maxlen, ch);
- break;
- case 'w':
- /* not supported yet, treat as next char */
- ch = *format++;
- break;
- case 'y': {
- /* object */
- Object *obj = va_arg (args, Object *);
- if (obj) {
- currlen += obj->toString(buffer+currlen, maxlen - currlen);
- } else {
- strvalue = "(null)";
- if (max == -1) {
- max = strlen(strvalue);
- }
- if (min > 0 && max >= 0 && min > max) max = min;
- fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
- }
- break;
- }
- default:
- /* Unknown, skip */
- break;
- }
- ch = *format++;
- state = DP_S_DEFAULT;
- flags = cflags = min = 0;
- max = -1;
- break;
- case DP_S_DONE:
- break;
- default:
- /* hmm? */
- break; /* some picky compilers need this */
- }
- }
- if (maxlen != 0) {
- if (currlen < maxlen - 1)
- buffer[currlen] = '\0';
- else if (maxlen > 0)
- buffer[maxlen - 1] = '\0';
- }
-
- return currlen;
-}
-
-static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
- char *value, int flags, int min, int max)
-{
- int padlen, strln; /* amount to pad */
- int cnt = 0;
-
-#ifdef DEBUG_SNPRINTF
- printf("fmtstr min=%d max=%d s=[%s]\n", min, max, value);
-#endif
-
- for (strln = 0; value[strln]; ++strln); /* strlen */
- padlen = min - strln;
- if (padlen < 0)
- padlen = 0;
- if (flags & DP_F_MINUS)
- padlen = -padlen; /* Left Justify */
-
- while ((padlen > 0) && (cnt < max)) {
- dopr_outch(buffer, currlen, maxlen, ' ');
- --padlen;
- ++cnt;
- }
- while (*value && (cnt < max)) {
- dopr_outch(buffer, currlen, maxlen, *value++);
- ++cnt;
- }
- while ((padlen < 0) && (cnt < max)) {
- dopr_outch(buffer, currlen, maxlen, ' ');
- ++padlen;
- ++cnt;
- }
-}
-
-/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
-
-static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
- long value, int base, int min, int max, int flags)
-{
-#define MAX_CONVERT_PLACES 40
- int signvalue = 0;
- unsigned long uvalue;
- char convert[MAX_CONVERT_PLACES];
- int place = 0;
- int spadlen = 0; /* amount to space pad */
- int zpadlen = 0; /* amount to zero pad */
- int caps = 0;
-
- if (max < 0)
- max = 0;
-
- uvalue = value;
-
- if (!(flags & DP_F_UNSIGNED)) {
- if (value < 0) {
- signvalue = '-';
- uvalue = -value;
- } else {
- if (flags & DP_F_PLUS) /* Do a sign (+/i) */
- signvalue = '+';
- else if (flags & DP_F_SPACE)
- signvalue = ' ';
- }
- }
-
- if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
-
- do {
- convert[place++] =
- (caps? "0123456789ABCDEF":"0123456789abcdef")[uvalue % (unsigned)base];
- uvalue = (uvalue / (unsigned)base );
- } while (uvalue && (place < MAX_CONVERT_PLACES));
- if (place == MAX_CONVERT_PLACES) place--;
- convert[place] = 0;
-
- zpadlen = max - place;
- spadlen = min - MAX (max, place) - (signvalue ? 1 : 0);
- if (zpadlen < 0) zpadlen = 0;
- if (spadlen < 0) spadlen = 0;
- if (flags & DP_F_ZERO) {
- zpadlen = MAX(zpadlen, spadlen);
- spadlen = 0;
- }
- if (flags & DP_F_MINUS)
- spadlen = -spadlen; /* Left Justifty */
-
-#ifdef DEBUG_SNPRINTF
- printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
- zpadlen, spadlen, min, max, place);
-#endif
-
- /* Spaces */
- while (spadlen > 0) {
- dopr_outch(buffer, currlen, maxlen, ' ');
- --spadlen;
- }
-
- /* Sign */
- if (signvalue) dopr_outch(buffer, currlen, maxlen, signvalue);
-
- /* Zeros */
- if (zpadlen > 0) {
- while (zpadlen > 0) {
- dopr_outch(buffer, currlen, maxlen, '0');
- --zpadlen;
- }
- }
-
- /* Digits */
- while (place > 0) dopr_outch(buffer, currlen, maxlen, convert[--place]);
-
- /* Left Justified spaces */
- while (spadlen < 0) {
- dopr_outch(buffer, currlen, maxlen, ' ');
- ++spadlen;
- }
-}
-
-static void fmtqword(char *buffer, size_t *currlen, size_t maxlen,
- sint64 value, int base, int min, int max, int flags)
-{
-#undef MAX_CONVERT_PLACES
-#define MAX_CONVERT_PLACES 80
- int signvalue = 0;
- uint64 uvalue;
- char convert[MAX_CONVERT_PLACES];
- int place = 0;
- int spadlen = 0; /* amount to space pad */
- int zpadlen = 0; /* amount to zero pad */
- int caps = 0;
-
- if (max < 0) max = 0;
-
- uvalue = value;
-
- if (!(flags & DP_F_UNSIGNED)) {
- if (value < 0) {
- signvalue = '-';
- uvalue = -uvalue;
- } else {
- if (flags & DP_F_PLUS) /* Do a sign (+/i) */
- signvalue = '+';
- else if (flags & DP_F_SPACE)
- signvalue = ' ';
- }
- }
-
- if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
-
- do {
- uint64 uv = uvalue % (uint64)base;
- convert[place++] =
- (caps? "0123456789ABCDEF":"0123456789abcdef")[uv];
- uvalue = (uvalue / (uint64)base);
- } while ((uvalue != 0) && (place < MAX_CONVERT_PLACES));
- if (place == MAX_CONVERT_PLACES) place--;
- convert[place] = 0;
-
- zpadlen = max - place;
- spadlen = min - MAX (max, place) - (signvalue ? 1 : 0);
- if (zpadlen < 0) zpadlen = 0;
- if (spadlen < 0) spadlen = 0;
- if (flags & DP_F_ZERO) {
- zpadlen = MAX(zpadlen, spadlen);
- spadlen = 0;
- }
- if (flags & DP_F_MINUS) spadlen = -spadlen; /* Left Justifty */
-
-#ifdef DEBUG_SNPRINTF
- printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
- zpadlen, spadlen, min, max, place);
-#endif
-
- /* Spaces */
- while (spadlen > 0) {
- dopr_outch(buffer, currlen, maxlen, ' ');
- --spadlen;
- }
-
- /* Sign */
- if (signvalue) dopr_outch(buffer, currlen, maxlen, signvalue);
-
- /* Zeros */
- if (zpadlen > 0) {
- while (zpadlen > 0) {
- dopr_outch(buffer, currlen, maxlen, '0');
- --zpadlen;
- }
- }
-
- /* Digits */
- while (place > 0) dopr_outch(buffer, currlen, maxlen, convert[--place]);
-
- /* Left Justified spaces */
- while (spadlen < 0) {
- dopr_outch(buffer, currlen, maxlen, ' ');
- ++spadlen;
- }
-}
-
-static LDOUBLE abs_val(LDOUBLE value)
-{
- return (value < 0) ? -value : value;
-}
-
-static LDOUBLE POW10(int exp)
-{
- LDOUBLE result = 1;
-
- while (exp) {
- result *= 10;
- exp--;
- }
-
- return result;
-}
-
-static LLONG ROUND(LDOUBLE value)
-{
- LLONG intpart;
-
- intpart = (LLONG)value;
- value = value - intpart;
- if (value >= 0.5) intpart++;
-
- return intpart;
-}
-
-/* a replacement for modf that doesn't need the math library. Should
- be portable, but slow */
-static double my_modf(double x0, double *iptr)
-{
- int i;
- long l;
- double x = x0;
- double f = 1.0;
-
- for (i=0;i<100;i++) {
- l = (long)x;
- if (l <= (x+1) && l >= (x-1)) break;
- x *= 0.1;
- f *= 10.0;
- }
-
- if (i == 100) {
- /* yikes! the number is beyond what we can handle. What do we do? */
- (*iptr) = 0;
- return 0;
- }
-
- if (i != 0) {
- double i2;
- double ret;
-
- ret = my_modf(x0-l*f, &i2);
- (*iptr) = l*f + i2;
- return ret;
- }
-
- (*iptr) = l;
- return x - (*iptr);
-}
-
-
-static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
- LDOUBLE fvalue, int min, int max, int flags)
-{
- int signvalue = 0;
- double ufvalue;
- char iconvert[311];
- char fconvert[311];
- int iplace = 0;
- int fplace = 0;
- int padlen = 0; /* amount to pad */
- int zpadlen = 0;
- int caps = 0;
- int index;
- double intpart;
- double fracpart;
- double temp;
-
- /*
- * AIX manpage says the default is 0, but Solaris says the default
- * is 6, and sprintf on AIX defaults to 6
- */
- if (max < 0)
- max = 6;
-
- ufvalue = abs_val (fvalue);
-
- if (fvalue < 0) {
- signvalue = '-';
- } else {
- if (flags & DP_F_PLUS) { /* Do a sign (+/i) */
- signvalue = '+';
- } else {
- if (flags & DP_F_SPACE)
- signvalue = ' ';
- }
- }
-
-#if 0
- if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
-#endif
-
-#if 0
- if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */
-#endif
-
- /*
- * Sorry, we only support 16 digits past the decimal because of our
- * conversion method
- */
- if (max > 16)
- max = 16;
-
- /* We "cheat" by converting the fractional part to integer by
- * multiplying by a factor of 10
- */
-
- temp = ufvalue;
- my_modf(temp, &intpart);
-
- fracpart = ROUND((POW10(max)) * (ufvalue - intpart));
-
- if (fracpart >= POW10(max)) {
- intpart++;
- fracpart -= POW10(max);
- }
-
-
- /* Convert integer part */
- do {
- temp = intpart;
- my_modf(intpart*0.1, &intpart);
- temp = temp*0.1;
- index = (int) ((temp -intpart +0.05)* 10.0);
- /* index = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */
- /* printf ("%llf, %f, %x\n", temp, intpart, index); */
- iconvert[iplace++] =
- (caps? "0123456789ABCDEF":"0123456789abcdef")[index];
- } while (intpart && (iplace < 311));
- if (iplace == 311) iplace--;
- iconvert[iplace] = 0;
-
- /* Convert fractional part */
- if (fracpart)
- {
- do {
- temp = fracpart;
- my_modf(fracpart*0.1, &fracpart);
- temp = temp*0.1;
- index = (int) ((temp -fracpart +0.05)* 10.0);
- /* index = (int) ((((temp/10) -fracpart) +0.05) *10); */
- /* printf ("%lf, %lf, %ld\n", temp, fracpart, index); */
- fconvert[fplace++] =
- (caps? "0123456789ABCDEF":"0123456789abcdef")[index];
- } while(fracpart && (fplace < 311));
- if (fplace == 311) fplace--;
- }
- fconvert[fplace] = 0;
-
- /* -1 for decimal point, another -1 if we are printing a sign */
- padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
- zpadlen = max - fplace;
- if (zpadlen < 0) zpadlen = 0;
- if (padlen < 0)
- padlen = 0;
- if (flags & DP_F_MINUS)
- padlen = -padlen; /* Left Justifty */
-
- if ((flags & DP_F_ZERO) && (padlen > 0)) {
- if (signvalue) {
- dopr_outch(buffer, currlen, maxlen, signvalue);
- --padlen;
- signvalue = 0;
- }
- while (padlen > 0) {
- dopr_outch(buffer, currlen, maxlen, '0');
- --padlen;
- }
- }
- while (padlen > 0) {
- dopr_outch(buffer, currlen, maxlen, ' ');
- --padlen;
- }
- if (signvalue)
- dopr_outch(buffer, currlen, maxlen, signvalue);
-
- while (iplace > 0)
- dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]);
-
-#ifdef DEBUG_SNPRINTF
- printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen);
-#endif
-
- /*
- * Decimal point. This should probably use locale to find the correct
- * char to print out.
- */
- if (max > 0) {
- dopr_outch(buffer, currlen, maxlen, '.');
-
- while (fplace > 0)
- dopr_outch(buffer, currlen, maxlen, fconvert[--fplace]);
- }
-
- while (zpadlen > 0) {
- dopr_outch(buffer, currlen, maxlen, '0');
- --zpadlen;
- }
-
- while (padlen < 0) {
- dopr_outch(buffer, currlen, maxlen, ' ');
- ++padlen;
- }
-}
-
-static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
-{
- if (*currlen < maxlen) {
- buffer[(*currlen)] = c;
- }
- (*currlen)++;
-}
-
-int ht_vsnprintf (char *str, size_t count, const char *fmt, va_list args)
-{
- if ((int)count < 0) count = 0;
- int res = dopr(str, count, fmt, args);
- if (count) count--;
- return str ? MIN(res, (int)count) : count;
-}
-
-int ht_snprintf(char *str, size_t count, const char *fmt,...)
-{
- size_t ret;
- va_list ap;
-
- va_start(ap, fmt);
- ret = ht_vsnprintf(str, count, fmt, ap);
- va_end(ap);
- return ret;
-}
-
-int ht_vasprintf(char **ptr, const char *format, va_list ap)
-{
- int ret;
-
- ret = dopr(NULL, 0, format, ap);
- if (ret <= 0) {
- *ptr = NULL;
- return 0;
- }
-
- (*ptr) = (char *)malloc(ret+1);
- if (!*ptr) return 0;
- ret = ht_vsnprintf(*ptr, ret+1, format, ap);
-
- return ret;
-}
-
-
-int ht_asprintf(char **ptr, const char *format, ...)
-{
- va_list ap;
- int ret;
-
- va_start(ap, format);
- ret = ht_vasprintf(ptr, format, ap);
- va_end(ap);
-
- return ret;
-}
-
-int ht_vfprintf(FILE *file, const char *fmt, va_list args)
-{
-#if 0
- char *buf;
- int ret = ht_vasprintf(&buf, fmt, args);
- fputs(buf, file);
- free(buf);
-#else
- char buf[1024];
- int ret = ht_vsnprintf(buf, sizeof buf, fmt, args);
- fputs(buf, file);
-#endif
- return ret;
-}
-
-int ht_fprintf(FILE *file, const char *fmt, ...)
-{
- va_list ap;
- int ret;
-
- va_start(ap, fmt);
- ret = ht_vfprintf(file, fmt, ap);
- va_end(ap);
-
- return ret;
-}
-
-
-int ht_vprintf(const char *fmt, va_list args)
-{
- return ht_vfprintf(stdout, fmt, args);
-}
-
-int ht_printf(const char *fmt, ...)
-{
- va_list ap;
- int ret;
-
- va_start(ap, fmt);
- ret = ht_vprintf(fmt, ap);
- va_end(ap);
-
- return ret;
-}
-
-
-#endif //HAVE_SNPRINTF
diff --git a/gemrb/core/System/snprintf.h b/gemrb/core/System/snprintf.h
deleted file mode 100644
index 262a4e2..0000000
--- a/gemrb/core/System/snprintf.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * HT Editor
- * snprintf.h
- *
- * Copyright (C) 1999-2003 Sebastian Biallas (sb at biallas.net)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __SNPRINTF_H__
-#define __SNPRINTF_H__
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-int ht_asprintf(char **ptr, const char *format, ...);
-int ht_vasprintf(char **ptr, const char *format, va_list ap);
-
-int ht_snprintf(char *str, size_t count, const char *fmt, ...);
-int ht_vsnprintf(char *str, size_t count, const char *fmt, va_list args);
-
-int ht_fprintf(FILE *file, const char *fmt, ...);
-int ht_vfprintf(FILE *file, const char *fmt, va_list args);
-
-int ht_printf(const char *fmt, ...);
-int ht_vprintf(const char *fmt, va_list args);
-
-#define snprintf ht_snprintf
-#endif
diff --git a/gemrb/core/TableMgr.cpp b/gemrb/core/TableMgr.cpp
index fb47c68..308f0fd 100644
--- a/gemrb/core/TableMgr.cpp
+++ b/gemrb/core/TableMgr.cpp
@@ -23,6 +23,8 @@
#include "GameData.h"
#include "Interface.h"
+namespace GemRB {
+
TableMgr::TableMgr()
{
}
@@ -35,9 +37,9 @@ AutoTable::AutoTable()
{
}
-AutoTable::AutoTable(const char* ResRef)
+AutoTable::AutoTable(const char* ResRef, bool silent)
{
- load(ResRef);
+ load(ResRef, silent);
}
AutoTable::AutoTable(const AutoTable& other)
@@ -56,11 +58,11 @@ AutoTable& AutoTable::operator=(const AutoTable& other)
return *this;
}
-bool AutoTable::load(const char* ResRef)
+bool AutoTable::load(const char* ResRef, bool silent)
{
release();
- int ref = gamedata->LoadTable(ResRef);
+ int ref = gamedata->LoadTable(ResRef, silent);
if (ref == -1)
return false;
@@ -82,3 +84,5 @@ void AutoTable::release()
}
}
+
+}
diff --git a/gemrb/core/TableMgr.h b/gemrb/core/TableMgr.h
index 5e38557..30efaf1 100644
--- a/gemrb/core/TableMgr.h
+++ b/gemrb/core/TableMgr.h
@@ -32,6 +32,8 @@
#include "Plugin.h"
+namespace GemRB {
+
/**
* @class TableMgr
* Abstract loader for Table objects (.2DA files)
@@ -63,9 +65,11 @@ public:
virtual const char* GetRowName(unsigned int index) const = 0;
virtual int FindTableValue(unsigned int column, long value, int start = 0) const = 0;
virtual int FindTableValue(unsigned int column, const char* value, int start = 0) const = 0;
+ virtual int FindTableValue(const char* column, long value, int start = 0) const = 0;
+ virtual int FindTableValue(const char* column, const char* value, int start = 0) const = 0;
/** Opens a Table File */
- virtual bool Open(DataStream* stream, bool autoFree = true) = 0;
+ virtual bool Open(DataStream* stream) = 0;
};
/**
@@ -76,12 +80,12 @@ class GEM_EXPORT AutoTable
{
public:
AutoTable();
- AutoTable(const char* ResRef);
+ AutoTable(const char* ResRef, bool silent=false);
~AutoTable();
AutoTable(const AutoTable &);
AutoTable& operator=(const AutoTable&);
- bool load(const char* ResRef);
+ bool load(const char* ResRef, bool silent=false);
void release();
bool ok() const { return table; }
operator bool() const { return table; }
@@ -96,4 +100,6 @@ private:
};
+}
+
#endif // ! TABLEMGR_H
diff --git a/gemrb/core/Tile.cpp b/gemrb/core/Tile.cpp
index 405a297..c8946c4 100644
--- a/gemrb/core/Tile.cpp
+++ b/gemrb/core/Tile.cpp
@@ -20,23 +20,19 @@
#include "Tile.h"
+namespace GemRB {
+
Tile::Tile(Animation* anim, Animation* sec)
{
- tileIndex = 0;
+ tileIndex = om = 0;
this->anim[0] = anim;
- if (sec) {
- this->anim[1] = sec;
- } else {
- this->anim[1] = NULL;
- }
+ this->anim[1] = sec;
}
Tile::~Tile(void)
{
- if (anim[0]) {
- delete( anim[0] );
- }
- if (anim[1]) {
- delete( anim[1] );
- }
+ delete( anim[0] );
+ delete( anim[1] );
+}
+
}
diff --git a/gemrb/core/Tile.h b/gemrb/core/Tile.h
index 88c1ffb..dd7a06d 100644
--- a/gemrb/core/Tile.h
+++ b/gemrb/core/Tile.h
@@ -26,6 +26,8 @@
#include "Animation.h"
+namespace GemRB {
+
class GEM_EXPORT Tile {
public:
Tile(Animation* anim, Animation* sec = NULL);
@@ -39,4 +41,6 @@ public:
Animation* anim[2];
};
+}
+
#endif
diff --git a/gemrb/core/TileMap.cpp b/gemrb/core/TileMap.cpp
index ae2fc7a..f0ce697 100644
--- a/gemrb/core/TileMap.cpp
+++ b/gemrb/core/TileMap.cpp
@@ -27,6 +27,8 @@
#include "Scriptable/Door.h"
#include "Scriptable/InfoPoint.h"
+namespace GemRB {
+
TileMap::TileMap(void)
{
XCellCount = 0;
@@ -205,12 +207,12 @@ void TileMap::AddRainOverlay(TileOverlay* overlay)
rain_overlays.push_back( overlay );
}
-void TileMap::DrawOverlays(Region screen, int rain)
+void TileMap::DrawOverlays(Region screen, int rain, int flags)
{
if (rain) {
- overlays[0]->Draw( screen, rain_overlays );
+ overlays[0]->Draw( screen, rain_overlays, flags );
} else {
- overlays[0]->Draw( screen, overlays );
+ overlays[0]->Draw( screen, overlays, flags );
}
}
@@ -513,8 +515,8 @@ int TileMap::CleanupContainer(Container *container)
return 1;
}
}
- printMessage("TileMap", " ", LIGHT_RED);
- printf("Invalid container cleanup: %s\n", container->GetScriptName());
+ Log(ERROR, "TileMap", "Invalid container cleanup: %s",
+ container->GetScriptName());
return 1;
}
@@ -647,3 +649,5 @@ Point TileMap::GetMapSize()
{
return Point((short) (XCellCount*64), (short) (YCellCount*64));
}
+
+}
diff --git a/gemrb/core/TileMap.h b/gemrb/core/TileMap.h
index ad97d10..cf359cd 100644
--- a/gemrb/core/TileMap.h
+++ b/gemrb/core/TileMap.h
@@ -26,6 +26,8 @@
#include "Polygon.h"
#include "TileOverlay.h"
+namespace GemRB {
+
//special container types
#define IE_CONTAINER_PILE 4
@@ -90,11 +92,13 @@ public:
void ClearOverlays();
void AddOverlay(TileOverlay* overlay);
void AddRainOverlay(TileOverlay* overlay);
- void DrawOverlays(Region screen, int rain);
+ void DrawOverlays(Region screen, int rain, int flags);
void DrawFogOfWar(ieByte* explored_mask, ieByte* visible_mask, Region viewport);
Point GetMapSize();
public:
int XCellCount, YCellCount;
};
+}
+
#endif
diff --git a/gemrb/core/TileMapMgr.cpp b/gemrb/core/TileMapMgr.cpp
index 634aa1f..e756bb2 100644
--- a/gemrb/core/TileMapMgr.cpp
+++ b/gemrb/core/TileMapMgr.cpp
@@ -20,6 +20,8 @@
#include "TileMapMgr.h"
+namespace GemRB {
+
TileMapMgr::TileMapMgr(void)
{
}
@@ -27,3 +29,5 @@ TileMapMgr::TileMapMgr(void)
TileMapMgr::~TileMapMgr(void)
{
}
+
+}
diff --git a/gemrb/core/TileMapMgr.h b/gemrb/core/TileMapMgr.h
index 4333775..e40d8ba 100644
--- a/gemrb/core/TileMapMgr.h
+++ b/gemrb/core/TileMapMgr.h
@@ -25,11 +25,13 @@
#include "TileMap.h"
#include "System/DataStream.h"
+namespace GemRB {
+
class GEM_EXPORT TileMapMgr : public Plugin {
public:
TileMapMgr(void);
virtual ~TileMapMgr(void);
- virtual bool Open(DataStream* stream, bool autoFree = true) = 0;
+ virtual bool Open(DataStream* stream) = 0;
virtual TileMap* GetTileMap(TileMap *tm) = 0;
virtual ieWord* GetDoorIndices(char* ResRef, int* count,
bool& BaseClosed) = 0;
@@ -43,4 +45,6 @@ public:
virtual ieDword GetPolygonsCount() = 0;
};
+}
+
#endif
diff --git a/gemrb/core/TileOverlay.cpp b/gemrb/core/TileOverlay.cpp
index 475192e..cb05332 100644
--- a/gemrb/core/TileOverlay.cpp
+++ b/gemrb/core/TileOverlay.cpp
@@ -20,9 +20,13 @@
#include "TileOverlay.h"
+//#include "Game.h" // needed only for TILE_GREY below
+#include "GlobalTimer.h"
#include "Interface.h"
#include "Video.h"
+namespace GemRB {
+
bool RedrawTile = false;
TileOverlay::TileOverlay(int Width, int Height)
@@ -72,7 +76,7 @@ void TileOverlay::BumpViewport(const Region &viewport, Region &vp)
}
}
-void TileOverlay::Draw(Region viewport, std::vector< TileOverlay*> &overlays)
+void TileOverlay::Draw(Region viewport, std::vector< TileOverlay*> &overlays, int flags)
{
Video* vid = core->GetVideoDriver();
Region vp = vid->GetViewport();
@@ -95,7 +99,7 @@ void TileOverlay::Draw(Region viewport, std::vector< TileOverlay*> &overlays)
anim = tile->anim[0];
}
vid->BlitTile( anim->NextFrame(), 0, viewport.x + ( x * 64 ),
- viewport.y + ( y * 64 ), &viewport, false );
+ viewport.y + ( y * 64 ), &viewport, flags );
if (!tile->om || tile->tileIndex) {
continue;
}
@@ -112,7 +116,7 @@ void TileOverlay::Draw(Region viewport, std::vector< TileOverlay*> &overlays)
tile->anim[0]->NextFrame(),
viewport.x + ( x * 64 ),
viewport.y + ( y * 64 ),
- &viewport, false );
+ &viewport, flags );
} else {
Sprite2D* mask = 0;
if (tile->anim[1])
@@ -121,7 +125,7 @@ void TileOverlay::Draw(Region viewport, std::vector< TileOverlay*> &overlays)
mask,
viewport.x + ( x * 64 ),
viewport.y + ( y * 64 ),
- &viewport, true );
+ &viewport, TILE_HALFTRANS | flags );
}
}
}
@@ -130,3 +134,5 @@ void TileOverlay::Draw(Region viewport, std::vector< TileOverlay*> &overlays)
}
}
}
+
+}
diff --git a/gemrb/core/TileOverlay.h b/gemrb/core/TileOverlay.h
index 642f1d3..5713b6d 100644
--- a/gemrb/core/TileOverlay.h
+++ b/gemrb/core/TileOverlay.h
@@ -27,6 +27,8 @@
#include <vector>
+namespace GemRB {
+
extern bool RedrawTile;
class GEM_EXPORT TileOverlay {
@@ -39,8 +41,10 @@ public:
TileOverlay(int Width, int Height);
~TileOverlay(void);
void AddTile(Tile* tile);
- void Draw(Region viewport, std::vector< TileOverlay*> &overlays);
+ void Draw(Region viewport, std::vector< TileOverlay*> &overlays, int flags);
void BumpViewport(const Region &viewport, Region &vp);
};
+}
+
#endif
diff --git a/gemrb/core/TileSetMgr.cpp b/gemrb/core/TileSetMgr.cpp
index 87a0dc7..13983af 100644
--- a/gemrb/core/TileSetMgr.cpp
+++ b/gemrb/core/TileSetMgr.cpp
@@ -20,6 +20,8 @@
#include "TileSetMgr.h"
+namespace GemRB {
+
TileSetMgr::TileSetMgr(void)
{
}
@@ -27,3 +29,5 @@ TileSetMgr::TileSetMgr(void)
TileSetMgr::~TileSetMgr(void)
{
}
+
+}
diff --git a/gemrb/core/TileSetMgr.h b/gemrb/core/TileSetMgr.h
index 0cc21dc..2646e22 100644
--- a/gemrb/core/TileSetMgr.h
+++ b/gemrb/core/TileSetMgr.h
@@ -25,13 +25,17 @@
#include "Tile.h"
#include "System/DataStream.h"
+namespace GemRB {
+
class GEM_EXPORT TileSetMgr : public Plugin {
public:
TileSetMgr(void);
virtual ~TileSetMgr(void);
- virtual bool Open(DataStream* stream, bool autoFree = true) = 0;
+ virtual bool Open(DataStream* stream) = 0;
virtual Tile* GetTile(unsigned short* indexes, int count,
unsigned short* secondary = NULL) = 0;
};
+}
+
#endif
diff --git a/gemrb/core/TypeID.h b/gemrb/core/TypeID.h
index 65acc4c..9950118 100644
--- a/gemrb/core/TypeID.h
+++ b/gemrb/core/TypeID.h
@@ -21,9 +21,13 @@
#ifndef TYPE_ID_H
#define TYPE_ID_H
+namespace GemRB {
+
class TypeID {
public:
const char *description;
};
+}
+
#endif
diff --git a/gemrb/core/Variables.cpp b/gemrb/core/Variables.cpp
index 9be058f..2f0e93e 100644
--- a/gemrb/core/Variables.cpp
+++ b/gemrb/core/Variables.cpp
@@ -23,6 +23,8 @@
#include "Interface.h" // for LoadInitialValues
#include "System/FileStream.h" // for LoadInitialValues
+namespace GemRB {
+
/////////////////////////////////////////////////////////////////////////////
// private inlines
inline bool Variables::MyCopyKey(char*& dest, const char* key) const
@@ -293,7 +295,7 @@ bool Variables::Lookup(const char* key, char* dest, int MaxLength) const
return false; // not in map
}
- strncpy( dest, pAssoc->Value.sValue, MaxLength );
+ strlcpy( dest, pAssoc->Value.sValue, MaxLength + 1 );
return true;
}
@@ -426,8 +428,7 @@ void Variables::SetAt(const char* key, ieDword value, bool nocreate)
assert( m_type == GEM_VARIABLES_INT );
if (( pAssoc = GetAssocAt( key, nHash ) ) == NULL) {
if (nocreate) {
- printMessage("Variables", " ", YELLOW);
- printf("Cannot create new variable: %s\n", key);
+ Log(WARNING, "Variables", "Cannot create new variable: %s", key);
return;
}
@@ -480,7 +481,7 @@ void Variables::LoadInitialValues(const char* name)
// we only support PST's var.var for now
PathJoin( nPath, core->GamePath, "var.var", NULL );
FileStream fs;
- if (!fs.Open( nPath, true )) {
+ if (!fs.Open(nPath)) {
return;
}
@@ -500,7 +501,45 @@ void Variables::LoadInitialValues(const char* name)
// is it the type we want? if not, skip
if (strnicmp(buffer, name, 6)) continue;
// copy variable (types got 2 extra spaces, and the name is padded too)
- strnspccpy(varname,buffer+8,32);
+ // (true = uppercase, needed for original engine save compat, see 315b8f2e)
+ strnspccpy(varname,buffer+8,32, true);
SetAt(varname, value);
}
}
+
+void Variables::DebugDump()
+{
+ const char *poi;
+
+ switch(m_type) {
+ case GEM_VARIABLES_STRING:
+ poi = "string";
+ break;
+ case GEM_VARIABLES_INT:
+ poi = "int";
+ break;
+ case GEM_VARIABLES_POINTER:
+ poi = "other";
+ break;
+ default:
+ poi = "invalid";
+ }
+ Log (DEBUG, "Variables", "Item type: %s", poi);
+ Log (DEBUG, "Variables", "Item count: %d", m_nCount);
+ Log (DEBUG, "Variables", "HashTableSize: %d\n", m_nHashTableSize);
+ for (unsigned int nHash = 0; nHash < m_nHashTableSize; nHash++) {
+ Variables::MyAssoc* pAssoc;
+ for (pAssoc = m_pHashTable[nHash]; pAssoc != NULL; pAssoc = pAssoc->pNext) {
+ switch(m_type) {
+ case GEM_VARIABLES_STRING:
+ Log (DEBUG, "Variables", "%s = %s", pAssoc->key, pAssoc->Value.sValue);
+ break;
+ default:
+ Log (DEBUG, "Variables", "%s = %d", pAssoc->key, pAssoc->Value.nValue);
+ break;
+ }
+ }
+ }
+}
+
+}
diff --git a/gemrb/core/Variables.h b/gemrb/core/Variables.h
index db392a8..5c6d9fe 100644
--- a/gemrb/core/Variables.h
+++ b/gemrb/core/Variables.h
@@ -27,6 +27,10 @@
#include "globals.h"
#include "win32def.h"
+#include <cassert>
+
+namespace GemRB {
+
#ifndef ReleaseFun
typedef void (*ReleaseFun)(void *);
#endif
@@ -102,6 +106,9 @@ public:
iterator GetNextAssoc(iterator rNextPosition, const char*& rKey,
ieDword& rValue) const;
+
+ // Debugging
+ void DebugDump();
// Implementation
protected:
Variables::MyAssoc** m_pHashTable;
@@ -124,4 +131,6 @@ public:
~Variables();
};
+}
+
#endif
diff --git a/gemrb/core/Video.cpp b/gemrb/core/Video.cpp
index 22eeb17..941ac16 100644
--- a/gemrb/core/Video.cpp
+++ b/gemrb/core/Video.cpp
@@ -22,17 +22,28 @@
#include "win32def.h"
-#include "Audio.h"
#include "Interface.h"
#include "Palette.h"
+#include "Sprite2D.h"
#include <cmath>
+namespace GemRB {
+
const TypeID Video::ID = { "Video" };
Video::Video(void)
+ : Viewport(), CursorPos(), fadeColor()
{
- Evnt = NULL;
+ CursorIndex = VID_CUR_UP;
+ Cursor[VID_CUR_UP] = NULL;
+ Cursor[VID_CUR_DOWN] = NULL;
+ Cursor[VID_CUR_DRAG] = NULL;
+
+ EvntManager = NULL;
+ // MOUSE_GRAYED and MOUSE_DISABLED are the first 2 bits so shift the config value away from those.
+ // we care only about 2 bits at the moment so mask out the remainder
+ MouseFlags = ((core->MouseFeedback & 0x3) << 2);
// Initialize gamma correction tables
for (int i = 0; i < 256; i++) {
@@ -45,26 +56,54 @@ Video::~Video(void)
{
}
+bool Video::ToggleFullscreenMode()
+{
+ return SetFullscreenMode(!fullscreen);
+}
+
/** Set Event Manager */
void Video::SetEventMgr(EventMgr* evnt)
{
//if 'evnt' is NULL then no Event Manager will be used
- Evnt = evnt;
+ EvntManager = evnt;
+}
+
+void Video::SetCursor(Sprite2D* cur, enum CursorType curIdx)
+{
+ if (cur) {
+ //cur will be assigned in the end, increase refcount
+ cur->acquire();
+ //setting a dragged sprite cursor, it will 'stick' until cleared
+ if (curIdx == VID_CUR_DRAG)
+ CursorIndex = VID_CUR_DRAG;
+ } else {
+ //clearing the dragged sprite cursor, replace it with the normal cursor
+ if (curIdx == VID_CUR_DRAG)
+ CursorIndex = VID_CUR_UP;
+ }
+ //decrease refcount of the previous cursor
+ if (Cursor[curIdx])
+ FreeSprite(Cursor[curIdx]);
+ Cursor[curIdx] = cur;
}
/** Mouse is invisible and cannot interact */
void Video::SetMouseEnabled(int enabled)
{
- DisableMouse = enabled^MOUSE_DISABLED;
+ if (enabled) {
+ MouseFlags &= ~MOUSE_DISABLED;
+ } else {
+ MouseFlags |= MOUSE_DISABLED;
+ }
}
/** Mouse cursor is grayed and doesn't click (but visible and movable) */
void Video::SetMouseGrayed(bool grayed)
{
if (grayed) {
- DisableMouse |= MOUSE_GRAYED;
+ MouseFlags |= MOUSE_GRAYED;
} else {
- DisableMouse &= ~MOUSE_GRAYED;
+ MouseFlags &= ~MOUSE_GRAYED;
}
}
@@ -202,6 +241,12 @@ Region Video::GetViewport() const
return Viewport;
}
+void Video::SetMovieFont(Font *stfont, Palette *pal)
+{
+ subtitlefont = stfont;
+ subtitlepal = pal;
+}
+
void Video::SetViewport(int x, int y, unsigned int w, unsigned int h)
{
if (x>width)
@@ -228,3 +273,4 @@ void Video::MoveViewportTo(int x, int y)
}
}
+}
diff --git a/gemrb/core/Video.h b/gemrb/core/Video.h
index 1560e5e..bd8b958 100644
--- a/gemrb/core/Video.h
+++ b/gemrb/core/Video.h
@@ -29,18 +29,21 @@
#include "globals.h"
-#include "Animation.h"
#include "Plugin.h"
-#include "Polygon.h"
#include "ScriptedAnimation.h"
-#include "GUI/EventMgr.h"
+
+namespace GemRB {
class AnimationFactory;
+class EventMgr;
+class Font;
+class Gem_Polygon;
class Palette;
class SpriteCover;
+class Wall_Polygon;
// Note: not all these flags make sense together. Specifically:
-// NOSHADOW overrides TRANSSHADOW
+// NOSHADOW overrides TRANSSHADOW, and BLIT_GREY overrides BLIT_SEPIA
enum SpriteBlitFlags {
BLIT_HALFTRANS = IE_VVC_TRANSPARENT, // 2
BLIT_BLENDED = IE_VVC_BLENDED, // 8; not implemented in SDLVideo yet
@@ -50,15 +53,31 @@ enum SpriteBlitFlags {
BLIT_TRANSSHADOW = 0x2000,
BLIT_TINTED = 0x00010000, // IE_VVC_TINT = 0x00030000
BLIT_GREY = IE_VVC_GREYSCALE, // 0x80000; timestop palette
- BLIT_RED = IE_VVC_SEPIA, // 0x02000000; dream scene palette
+ BLIT_SEPIA = IE_VVC_SEPIA, // 0x02000000; dream scene palette
BLIT_DARK = IE_VVC_DARKEN, // 0x00100000; not implemented in SDLVideo yet
BLIT_GLOW = IE_VVC_GLOWING // 0x00200000; not implemented in SDLVideo yet
// Note: bits 29,30,31 are used by SDLVideo internally
};
+// TILE_GREY overrides TILE_SEPIA
+enum TileBlitFlags {
+ TILE_HALFTRANS = 1,
+ TILE_GREY = 2,
+ TILE_SEPIA = 4
+};
+
+enum CursorType {
+ VID_CUR_UP = 0,
+ VID_CUR_DOWN = 1,
+ VID_CUR_DRAG = 2
+};
+
//disable mouse flags
-#define MOUSE_DISABLED 1
-#define MOUSE_GRAYED 2
+const int MOUSE_GRAYED = 1;
+const int MOUSE_DISABLED = 2;
+//used (primarily with touchscreens) to control graphical feedback related to the mouse
+const int MOUSE_HIDDEN = 4; // show cursor
+const int MOUSE_NO_TOOLTIPS = 8; // show tooltips
// !!! Keep this synchronized with GUIDefines.py !!!
// used for calculating the tooltip delay limit and the real tooltip delay
@@ -72,23 +91,42 @@ enum SpriteBlitFlags {
class GEM_EXPORT Video : public Plugin {
public:
static const TypeID ID;
+protected:
+ int MouseFlags;
+ short xCorr, yCorr;
+ EventMgr* EvntManager;
+ Region Viewport;
+ int width,height,bpp;
+ bool fullscreen;
+ Sprite2D* Cursor[3];// 0=up, 1=down, 2=drag
+ CursorType CursorIndex;
+ Region CursorPos;
+
+ unsigned char Gamma10toGamma22[256];
+ unsigned char Gamma22toGamma10[256];
+ //subtitle specific variables
+ Font *subtitlefont;
+ Palette *subtitlepal;
+ Region subtitleregion;
+ Color fadeColor;
public:
Video(void);
virtual ~Video(void);
virtual int Init(void) = 0;
- virtual int CreateDisplay(int width, int height, int bpp, bool fullscreen) = 0;
- /** Sets window title of GemRB window */
- virtual void SetDisplayTitle(char* title, char* icon) = 0;
- /** Toggles GemRB between fullscreen and windowed mode.
- * 0 = windowed, 1 = fullscreen, -1 (default) = toggle */
- virtual bool ToggleFullscreenMode(int set_reset=-1) = 0;
+ virtual int CreateDisplay(int width, int height, int bpp, bool fullscreen, const char* title) = 0;
+ /** Toggles GemRB between fullscreen and windowed mode. */
+ bool ToggleFullscreenMode();
+ virtual bool SetFullscreenMode(bool set) = 0;
/** Swaps displayed and back buffers */
virtual int SwapBuffers(void) = 0;
/** Grabs and releases mouse cursor within GemRB window */
virtual bool ToggleGrabInput() = 0;
virtual short GetWidth() = 0;
virtual short GetHeight() = 0;
-
+ /** Displays or hides a virtual (software) keyboard*/
+ virtual void ShowSoftKeyboard() = 0;
+ virtual void HideSoftKeyboard() = 0;
+
virtual void InitSpriteCover(SpriteCover* sc, int flags) = 0;
virtual void AddPolygonToSpriteCover(SpriteCover* sc, Wall_Polygon* poly) = 0;
virtual void DestroySpriteCover(SpriteCover* sc) = 0;
@@ -106,25 +144,16 @@ public:
virtual bool SupportsBAMSprites() { return false; }
virtual void FreeSprite(Sprite2D* &spr) = 0;
virtual Sprite2D* DuplicateSprite(const Sprite2D* spr) = 0;
- virtual void BlitTile(const Sprite2D* spr, const Sprite2D* mask, int x, int y, const Region* clip, bool trans) = 0;
+ virtual void BlitTile(const Sprite2D* spr, const Sprite2D* mask, int x, int y, const Region* clip, unsigned int flags) = 0;
virtual void BlitSprite(const Sprite2D* spr, int x, int y, bool anchor = false,
- const Region* clip = NULL) = 0;
+ const Region* clip = NULL, Palette* palette = NULL) = 0;
- // Note: BlitSpriteRegion's clip region is shifted by Viewport.x/y if
- // anchor is false. This is different from the other BlitSprite functions.
- virtual void BlitSpriteRegion(const Sprite2D* spr, const Region& size, int x, int y,
- bool anchor = true, const Region* clip = NULL) = 0;
// Note: Tint cannot be constified, because it is modified locally
// not a pretty interface :)
virtual void BlitGameSprite(const Sprite2D* spr, int x, int y,
unsigned int flags, Color tint,
SpriteCover* cover, Palette *palette = NULL,
const Region* clip = NULL, bool anchor = false) = 0;
- virtual void SetCursor(Sprite2D* up, Sprite2D* down) = 0;
- /** Sets a temporary cursor when dragging an Item from Inventory.
- * VideoDriver will call FreeSprite on it.
- */
- virtual void SetDragCursor(Sprite2D* drag) = 0;
/** Return GemRB window screenshot.
* It's generated from the momentary back buffer */
virtual Sprite2D* GetScreenshot( Region r ) = 0;
@@ -157,8 +186,6 @@ public:
void BlitTiled(Region rgn, const Sprite2D* img, bool anchor = false);
/** Sets Event Manager */
void SetEventMgr(EventMgr* evnt);
- /** Sends a Quit Signal to the Event Queue */
- virtual bool Quit(void) = 0;
/** Gets the Palette of a surface */
virtual Palette* GetPalette(void* surface) = 0;
/** Flips sprite vertically, returns new sprite */
@@ -188,8 +215,10 @@ public:
virtual void MoveMouse(unsigned int x, unsigned int y) = 0;
/** initializes the screen for movie */
virtual void InitMovieScreen(int &w, int &h, bool yuv=false) = 0;
+ /** called when a video player is done. clean up any video specific resources. */
+ virtual void DestroyMovieScreen() = 0;
/** sets the font and color of the movie subtitles */
- virtual void SetMovieFont(Font *stfont, Palette *pal) = 0;
+ void SetMovieFont(Font *stfont, Palette *pal);
/** draws a movie frame */
virtual void showFrame(unsigned char* buf, unsigned int bufw,
unsigned int bufh, unsigned int sx, unsigned int sy,
@@ -205,12 +234,12 @@ public:
/** handles events during movie */
virtual int PollMovieEvents() = 0;
virtual void SetGamma(int brightness, int contrast) = 0;
-public:
- /** Event Manager Pointer */
void SetMouseEnabled(int enabled);
void SetMouseGrayed(bool grayed);
bool GetFullscreenMode() const;
+ /** Sets the mouse cursor sprite to be used for mouseUp, mouseDown, and mouseDrag. See VID_CUR_* defines. */
+ void SetCursor(Sprite2D* cur, enum CursorType curIdx);
/** Scales down a sprite by a ratio */
Sprite2D* SpriteScaleDown( const Sprite2D* sprite, unsigned int ratio );
@@ -222,16 +251,8 @@ public:
Region GetViewport(void) const;
void SetViewport(int x, int y, unsigned int w, unsigned int h);
void MoveViewportTo(int x, int y);
-protected:
- int DisableMouse;
- short xCorr, yCorr;
- EventMgr* Evnt;
- Region Viewport;
- int width,height,bpp;
- bool fullscreen;
-
- unsigned char Gamma10toGamma22[256];
- unsigned char Gamma22toGamma10[256];
};
+}
+
#endif
diff --git a/gemrb/core/VideoMode.h b/gemrb/core/VideoMode.h
index ee71f74..56da198 100644
--- a/gemrb/core/VideoMode.h
+++ b/gemrb/core/VideoMode.h
@@ -23,6 +23,8 @@
#include "exports.h"
+namespace GemRB {
+
class GEM_EXPORT VideoMode {
public:
VideoMode(void);
@@ -48,4 +50,6 @@ public:
VideoMode& operator=(const VideoMode& vm);
};
+}
+
#endif
diff --git a/gemrb/core/WindowMgr.cpp b/gemrb/core/WindowMgr.cpp
index bdde5a5..fdf4a81 100644
--- a/gemrb/core/WindowMgr.cpp
+++ b/gemrb/core/WindowMgr.cpp
@@ -20,9 +20,13 @@
#include "WindowMgr.h"
+namespace GemRB {
+
WindowMgr::WindowMgr()
{
}
WindowMgr::~WindowMgr()
{
}
+
+}
diff --git a/gemrb/core/WindowMgr.h b/gemrb/core/WindowMgr.h
index 61a3a37..7e0d507 100644
--- a/gemrb/core/WindowMgr.h
+++ b/gemrb/core/WindowMgr.h
@@ -28,8 +28,11 @@
#define WINDOWMGR_H
#include "Plugin.h"
-#include "GUI/Window.h"
-#include "System/DataStream.h"
+
+namespace GemRB {
+
+class DataStream;
+class Window;
/**
* @class WindowMgr
@@ -42,11 +45,13 @@ public:
WindowMgr();
virtual ~WindowMgr();
/** This function loads all available windows from the 'stream' parameter. */
- virtual bool Open(DataStream* stream, bool autoFree = true) = 0;
+ virtual bool Open(DataStream* stream) = 0;
/** Returns the i-th window in the Previously Loaded Stream */
virtual Window* GetWindow(unsigned int i) = 0;
/** Returns the number of available windows */
virtual unsigned int GetWindowsCount() = 0;
};
+}
+
#endif
diff --git a/gemrb/core/WorldMap.cpp b/gemrb/core/WorldMap.cpp
index c2face0..08f01c7 100644
--- a/gemrb/core/WorldMap.cpp
+++ b/gemrb/core/WorldMap.cpp
@@ -24,10 +24,13 @@
#include "Game.h"
#include "Interface.h"
+#include "TableMgr.h"
#include "Video.h"
#include <list>
+namespace GemRB {
+
WMPAreaEntry::WMPAreaEntry()
{
MapIcon = NULL;
@@ -86,7 +89,7 @@ void WMPAreaEntry::SetPalette(int gradient, Sprite2D* MapIcon)
Sprite2D *WMPAreaEntry::GetMapIcon(AnimationFactory *bam)
{
- if (!bam) {
+ if (!bam || IconSeq == (ieDword) -1) {
return NULL;
}
if (!MapIcon) {
@@ -105,7 +108,7 @@ Sprite2D *WMPAreaEntry::GetMapIcon(AnimationFactory *bam)
}
MapIcon = bam->GetFrame((ieWord) frame, (ieByte) IconSeq);
if (!MapIcon) {
- printf("WMPAreaEntry::GetMapIcon failed for frame %d, seq %d\n", frame, IconSeq);
+ print("WMPAreaEntry::GetMapIcon failed for frame %d, seq %d", frame, IconSeq);
return NULL;
}
if (color>=0) {
@@ -134,6 +137,7 @@ WorldMap::WorldMap(void)
Distances = NULL;
GotHereFrom = NULL;
bam = NULL;
+ encounterArea = -1;
}
//Allocate AE and AL only in Core, otherwise Win32 will
@@ -157,7 +161,7 @@ void WorldMap::SetAreaEntry(unsigned int x, WMPAreaEntry *ae)
{
//if index is too large, we break
if (x>area_entries.size()) {
- abort();
+ error("WorldMap", "Trying to set invalid entry (%d/%d)\n", x, (int)area_entries.size());
}
//altering an existing entry
if (x<area_entries.size()) {
@@ -194,8 +198,6 @@ void WorldMap::InsertAreaLink(unsigned int areaidx, unsigned int dir, WMPAreaLin
}
}
}
- //update the link count, just in case
- AreaLinksCount++;
}
void WorldMap::SetAreaLink(unsigned int x, WMPAreaLink *arealink)
@@ -207,7 +209,7 @@ void WorldMap::SetAreaLink(unsigned int x, WMPAreaLink *arealink)
//if index is too large, we break
if (x>area_links.size()) {
- abort();
+ error("WorldMap", "Trying to set invalid link (%d/%d)", x, (int)area_links.size());
}
//altering an existing link
if (x<area_links.size()) {
@@ -302,15 +304,13 @@ int WorldMap::CalculateDistances(const ieResRef AreaName, int direction)
}
if (direction<0 || direction>3) {
- printMessage("WorldMap","", LIGHT_RED);
- printf("CalculateDistances for invalid direction: %s\n", AreaName);
+ Log(ERROR, "WorldMap", "CalculateDistances for invalid direction: %s", AreaName);
return -1;
}
unsigned int i;
if (!GetArea(AreaName, i)) {
- printMessage("WorldMap","", LIGHT_RED);
- printf("CalculateDistances for invalid Area: %s\n", AreaName);
+ Log(ERROR, "WorldMap", "CalculateDistances for invalid Area: %s", AreaName);
return -1;
}
if (Distances) {
@@ -320,8 +320,7 @@ int WorldMap::CalculateDistances(const ieResRef AreaName, int direction)
free(GotHereFrom);
}
- printMessage("WorldMap","", GREEN);
- printf("CalculateDistances for Area: %s\n", AreaName);
+ Log(MESSAGE, "WorldMap", "CalculateDistances for Area: %s", AreaName);
size_t memsize =sizeof(int) * area_entries.size();
Distances = (int *) malloc( memsize );
@@ -345,8 +344,8 @@ int WorldMap::CalculateDistances(const ieResRef AreaName, int direction)
int j=ae->AreaLinksIndex[d];
int k=j+ae->AreaLinksCount[d];
if ((size_t) k>area_links.size()) {
- printMessage("WorldMap","The worldmap file is corrupted... and it would crash right now!\n",RED);
- printf("Entry #: %d Direction: %d\n",i,d);
+ Log(ERROR, "WorldMap", "The worldmap file is corrupted... and it would crash right now! Entry #: %d Direction: %d",
+ i, d);
break;
}
for(;j<k;j++) {
@@ -382,7 +381,8 @@ int WorldMap::CalculateDistances(const ieResRef AreaName, int direction)
//returns the index of the area owning this link
unsigned int WorldMap::WhoseLinkAmI(int link_index) const
{
- for (unsigned int i=0;i<AreaEntriesCount;i++) {
+ unsigned int cnt = GetEntryCount();
+ for (unsigned int i = 0; i < cnt; i++) {
WMPAreaEntry *ae=area_entries[i];
for (int direction=0;direction<4;direction++)
{
@@ -433,27 +433,25 @@ WMPAreaLink *WorldMap::GetEncounterLink(const ieResRef AreaName, bool &encounter
unsigned int i;
WMPAreaEntry *ae=GetArea( AreaName, i ); //target area
if (!ae) {
- printMessage("WorldMap","",LIGHT_RED);
- printf("No such area: %s\n", AreaName);
+ Log(ERROR, "WorldMap", "No such area: %s", AreaName);
return NULL;
}
std::list<WMPAreaLink*> walkpath;
- printf("Gathering path information for: %s\n", AreaName);
+ print("Gathering path information for: %s", AreaName);
while (GotHereFrom[i]!=-1) {
- printf("Adding path to %d\n", i);
+ print("Adding path to %d", i);
walkpath.push_back(area_links[GotHereFrom[i]]);
i = WhoseLinkAmI(GotHereFrom[i]);
if (i==(ieDword) -1) {
- printf("Something has been screwed up here (incorrect path)!\n");
- abort();
+ error("WorldMap", "Something has been screwed up here (incorrect path)!\n");
}
}
- printf("Walkpath size is: %d\n",(int) walkpath.size());
+ print("Walkpath size is: %d",(int) walkpath.size());
if (!walkpath.size()) {
return NULL;
}
- std::list<WMPAreaLink*>::iterator p=walkpath.begin();
+ std::list<WMPAreaLink*>::reverse_iterator p=walkpath.rbegin();
WMPAreaLink *lastpath;
encounter=false;
do {
@@ -464,10 +462,104 @@ WMPAreaLink *WorldMap::GetEncounterLink(const ieResRef AreaName, bool &encounter
}
p++;
}
- while(p!=walkpath.end() );
+ while(p!=walkpath.rend() );
return lastpath;
}
+//adds a temporary AreaEntry to the world map
+//this entry has two links for each direction, leading to the two areas
+//we were travelling between when using the supplied link
+void WorldMap::SetEncounterArea(const ieResRef area, WMPAreaLink *link) {
+ unsigned int i;
+ if (GetArea(area, i)) {
+ return;
+ }
+
+ //determine the area the link came from
+ unsigned int j, cnt = GetLinkCount();
+ for (j = 0; j < cnt; ++j) {
+ if (link == area_links[j]) {
+ break;
+ }
+ }
+
+ i = WhoseLinkAmI(j);
+ if (i == (unsigned int) -1) {
+ Log(ERROR, "WorldMap", "Could not add encounter area");
+ return;
+ }
+
+ WMPAreaEntry *ae = GetNewAreaEntry();
+ ae->SetAreaStatus(WMP_ENTRY_VISIBLE|WMP_ENTRY_ACCESSIBLE|WMP_ENTRY_VISITED, BM_SET);
+ CopyResRef(ae->AreaName, area);
+ CopyResRef(ae->AreaResRef, area);
+ ae->LocCaptionName = -1;
+ ae->LocTooltipName = -1;
+ ae->IconSeq = -1;
+ CopyResRef(ae->LoadScreenResRef, "");
+
+ WMPAreaEntry *src = area_entries[i];
+ WMPAreaEntry *dest = area_entries[link->AreaIndex];
+ ae->X = src->X + (int) (dest->X - src->X) / 2;
+ ae->Y = src->Y + (int) (dest->Y - src->Y) / 2;
+
+ //setup the area links
+ WMPAreaLink *ldest = new WMPAreaLink();
+ memcpy(ldest, link, sizeof(WMPAreaLink));
+ ldest->DistanceScale /= 2;
+ ldest->EncounterChance = 0;
+
+ link = GetLink(dest->AreaName, src->AreaName);
+ if (!link) {
+ Log(ERROR, "WorldMap", "Could not find link from %s to %s",
+ dest->AreaName, src->AreaName);
+ delete ae;
+ delete ldest;
+ return;
+ }
+
+ WMPAreaLink *lsrc = new WMPAreaLink();
+ memcpy(lsrc, link, sizeof(WMPAreaLink));
+ lsrc->DistanceScale /= 2;
+ lsrc->EncounterChance = 0;
+
+ unsigned int idx = area_links.size();
+ AddAreaLink(ldest);
+ AddAreaLink(lsrc);
+
+ for (i = 0; i < 4; ++i) {
+ ae->AreaLinksCount[i] = 2;
+ ae->AreaLinksIndex[i] = idx;
+ }
+
+ encounterArea = area_entries.size();
+ AddAreaEntry(ae);
+}
+
+void WorldMap::ClearEncounterArea()
+{
+ if (encounterArea == -1) {
+ return;
+ }
+
+ WMPAreaEntry *ea = area_entries[encounterArea];
+ area_entries.erase(area_entries.begin() + encounterArea);
+
+ WMPAreaLink *l = area_links[ea->AreaLinksIndex[0]];
+ delete l;
+ l = area_links[ea->AreaLinksIndex[0] + 1];
+ delete l;
+
+ //NOTE: if anything else added links after us we'd have to globally
+ //update all link indices, but since ambush areas do not allow
+ //saving/loading we should be okay with this
+ area_links.erase(area_links.begin() + ea->AreaLinksIndex[0],
+ area_links.begin() + ea->AreaLinksIndex[0] + ea->AreaLinksCount[0]);
+
+ delete ea;
+ encounterArea = -1;
+}
+
int WorldMap::GetDistance(const ieResRef AreaName) const
{
if (!Distances) {
@@ -488,9 +580,9 @@ void WorldMap::UpdateAreaVisibility(const ieResRef AreaName, int direction)
if (!ae)
return;
//we are here, so we visited and it is visible too (i guess)
- printf("Updated Area visibility: %s (visited, and visible)\n", AreaName);
+ print("Updated Area visibility: %s(visited, accessible and visible)", AreaName);
- ae->SetAreaStatus(WMP_ENTRY_VISITED|WMP_ENTRY_VISIBLE, BM_OR);
+ ae->SetAreaStatus(WMP_ENTRY_VISITED|WMP_ENTRY_VISIBLE|WMP_ENTRY_ACCESSIBLE, BM_OR);
if (direction<0 || direction>3)
return;
i=ae->AreaLinksCount[direction];
@@ -498,7 +590,7 @@ void WorldMap::UpdateAreaVisibility(const ieResRef AreaName, int direction)
WMPAreaLink* al = area_links[ae->AreaLinksIndex[direction]+i];
WMPAreaEntry* ae2 = area_entries[al->AreaIndex];
if (ae2->GetAreaStatus()&WMP_ENTRY_ADJACENT) {
- printf("Updated Area visibility: %s (accessible, and visible)\n", ae2->AreaName);
+ print("Updated Area visibility: %s(accessible, and visible)", ae2->AreaName);
ae2->SetAreaStatus(WMP_ENTRY_VISIBLE|WMP_ENTRY_ACCESSIBLE, BM_OR);
}
}
@@ -515,7 +607,7 @@ void WorldMap::SetAreaStatus(const ieResRef AreaName, int Bits, int Op)
void WorldMap::UpdateReachableAreas()
{
- AutoTable tab("worlde");
+ AutoTable tab("worlde", true);
if (!tab) {
return;
}
@@ -591,3 +683,5 @@ WorldMap *WorldMapArray::NewWorldMap(unsigned int index)
all_maps[index] = new WorldMap();
return all_maps[index];
}
+
+}
diff --git a/gemrb/core/WorldMap.h b/gemrb/core/WorldMap.h
index f8cce25..13801b9 100644
--- a/gemrb/core/WorldMap.h
+++ b/gemrb/core/WorldMap.h
@@ -36,6 +36,8 @@
#include <vector>
+namespace GemRB {
+
/** Area is visible on WorldMap */
#define WMP_ENTRY_VISIBLE 0x1
/** Area is visible on WorldMap only when party is in adjacent area */
@@ -83,7 +85,7 @@ private:
public:
ieResRef AreaName;
ieResRef AreaResRef;
- char AreaLongName[32];
+ ieVariable AreaLongName;
ieDword IconSeq;
ieDword X;
ieDword Y;
@@ -101,7 +103,7 @@ public:
struct WMPAreaLink {
ieDword AreaIndex;
- char DestEntryPoint[32];
+ ieVariable DestEntryPoint;
ieDword DistanceScale;
ieDword DirectionFlags; //where will the player appear on dest. area
ieResRef EncounterAreaResRef[5];
@@ -126,10 +128,6 @@ public: //struct members
ieStrRef AreaName;
ieDword unknown1;
ieDword unknown2;
- ieDword AreaEntriesCount;
- ieDword AreaEntriesOffset;
- ieDword AreaLinksOffset;
- ieDword AreaLinksCount;
ieResRef MapIconResRef;
AnimationFactory *bam;
@@ -139,6 +137,7 @@ private: //non-struct members
std::vector< WMPAreaLink*> area_links;
int *Distances;
int *GotHereFrom;
+ int encounterArea;
public:
void SetMapIcons(AnimationFactory *bam);
Sprite2D* GetMapMOS() const { return MapMOS; }
@@ -169,6 +168,8 @@ public:
WMPAreaEntry* GetArea(const ieResRef AreaName, unsigned int &i) const;
/** Finds an area name closest to the given area */
WMPAreaEntry* FindNearestEntry(const ieResRef AreaName, unsigned int &i) const;
+ void SetEncounterArea(const ieResRef area, WMPAreaLink *link);
+ void ClearEncounterArea();
private:
/** updates visibility of adjacent areas, called from CalculateDistances */
void UpdateAreaVisibility(const ieResRef AreaName, int direction);
@@ -202,4 +203,6 @@ public:
unsigned int FindAndSetCurrentMap(const ieResRef area);
};
+}
+
#endif // ! WORLDMAP_H
diff --git a/gemrb/core/WorldMapMgr.cpp b/gemrb/core/WorldMapMgr.cpp
index 425c2b0..752af1f 100644
--- a/gemrb/core/WorldMapMgr.cpp
+++ b/gemrb/core/WorldMapMgr.cpp
@@ -20,6 +20,8 @@
#include "WorldMapMgr.h"
+namespace GemRB {
+
WorldMapMgr::WorldMapMgr(void)
{
}
@@ -27,3 +29,5 @@ WorldMapMgr::WorldMapMgr(void)
WorldMapMgr::~WorldMapMgr(void)
{
}
+
+}
diff --git a/gemrb/core/WorldMapMgr.h b/gemrb/core/WorldMapMgr.h
index 80eed4c..a7ab9ff 100644
--- a/gemrb/core/WorldMapMgr.h
+++ b/gemrb/core/WorldMapMgr.h
@@ -31,6 +31,8 @@
#include "WorldMap.h"
#include "System/DataStream.h"
+namespace GemRB {
+
/**
* @class WorldMapMgr
* Abstract loader for WorldMap objects
@@ -40,11 +42,13 @@ class GEM_EXPORT WorldMapMgr : public Plugin {
public:
WorldMapMgr(void);
virtual ~WorldMapMgr(void);
- virtual bool Open(DataStream* stream1, DataStream* stream2, bool autoFree = true) = 0;
+ virtual bool Open(DataStream* stream1, DataStream* stream2) = 0;
virtual WorldMapArray* GetWorldMapArray() = 0;
virtual int GetStoredFileSize(WorldMapArray *wmap, unsigned int index) = 0;
virtual int PutWorldMap(DataStream* stream1, DataStream* stream2, WorldMapArray *wmap) = 0;
};
+}
+
#endif
diff --git a/gemrb/core/damages.h b/gemrb/core/damages.h
index adb20cc..c195ed5 100644
--- a/gemrb/core/damages.h
+++ b/gemrb/core/damages.h
@@ -21,6 +21,8 @@
#ifndef DAMAGE_H
#define DAMAGE_H
+namespace GemRB {
+
//damage types
#define DAMAGE_CRUSHING 0
#define DAMAGE_ACID 1
@@ -33,11 +35,12 @@
#define DAMAGE_MISSILE 0x80
#define DAMAGE_SLASHING 0x100
#define DAMAGE_MAGICFIRE 0x200
-#define DAMAGE_PIERCINGMISSILE 0x400 //iwd2
+#define DAMAGE_PIERCINGMISSILE 0x200 //iwd2
#define DAMAGE_MAGICCOLD 0x400
#define DAMAGE_CRUSHINGMISSILE 0x400 //iwd2
#define DAMAGE_STUNNING 0x800
#define DAMAGE_SOULEATER 0x1000 //iwd2
+#define DAMAGE_BLEEDING 0x2000 //iwd2
#define DAMAGE_DISEASE 0x4000 //iwd2
#define DAMAGE_CHUNKING 0x8000
@@ -50,4 +53,6 @@
#define DL_ACID 14
#define DL_DISINTEGRATE 17
+}
+
#endif
diff --git a/gemrb/docs/en/CheatKeys.txt b/gemrb/docs/en/CheatKeys.txt
index 0706a55..ad025e8 100644
--- a/gemrb/docs/en/CheatKeys.txt
+++ b/gemrb/docs/en/CheatKeys.txt
@@ -9,9 +9,10 @@ This list can be incomplete and obsolete - for current status, look into
gemrb/plugins/Core/GameControl.cpp, functions GameControl::OnKeyRelease()
and GameControl::Draw().
-Cheat keys are disabled by default. To activate them, either type command
-GemRB.EnableCheatKeys(1) on console (pops-up with CTRL+SPACE key combination)
-or put it into some GUIScript - e.g. for PS:T in Start.py.
+Cheat keys are enabled by default. To activate them, either type command
+GemRB.EnableCheatKeys(1) on console (pops-up with CTRL+SPACE key combination),
+put EnableCheatKeys=1 in the GemRB config or Cheats=1 under game options in
+baldur.ini/icewind.ini/torment.ini found in the top game directory.
GameControl control must be focused for the keys to be recognized, so it
might be needed to 'click' the GameControl (i.e. map) first.
diff --git a/gemrb/docs/en/GUIScript/AddNewArea.txt b/gemrb/docs/en/GUIScript/AddNewArea.txt
new file mode 100644
index 0000000..905f78a
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/AddNewArea.txt
@@ -0,0 +1,14 @@
+
+Prototype: GemRB.AddNewArea(_2daresref)
+
+Metaclass Prototype:
+
+Description: Adds the extension areas to the game.
+
+Parameters:
+_2daresref -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/ApplySpell.txt b/gemrb/docs/en/GUIScript/ApplySpell.txt
index 7bfc008..edcd308 100644
--- a/gemrb/docs/en/GUIScript/ApplySpell.txt
+++ b/gemrb/docs/en/GUIScript/ApplySpell.txt
@@ -1,5 +1,5 @@
-Prototype: GemRB.ApplySpell(PartyID, resref)
+Prototype: GemRB.ApplySpell(PartyID, resref[, casterID])
Description: Applies a spell on the actor marked by PartyID.
This function can be used to add abilities that are stored as spells (eg. innates)
@@ -7,6 +7,7 @@ This function can be used to add abilities that are stored as spells (eg. innate
Parameters:
PartyID - the player character's index in the party
resref - spell resource reference
+casterID - global id of the desired caster
Return value: N/A
diff --git a/gemrb/docs/en/GUIScript/Button_CreateLabelOnButton.txt b/gemrb/docs/en/GUIScript/Button_CreateLabelOnButton.txt
new file mode 100644
index 0000000..904a2f6
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Button_CreateLabelOnButton.txt
@@ -0,0 +1,18 @@
+
+Prototype: GemRB.CreateLabelOnButton(WindowIndex, ControlIndex, NewControlID, font, align)
+
+Metaclass Prototype:
+
+Description: Creates a label on top of a button, copying the button's size and position.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+NewControlID -
+font -
+align -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Button_EnableBorder.txt b/gemrb/docs/en/GUIScript/Button_EnableBorder.txt
new file mode 100644
index 0000000..6037a9d
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Button_EnableBorder.txt
@@ -0,0 +1,17 @@
+
+Prototype: GemRB.EnableButtonBorder(WindowIndex, ControlIndex, BorderIndex, enabled)
+
+Metaclass Prototype:
+
+Description: Enable or disable specified border/frame.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+BorderIndex -
+enabled -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Button_SetActionIcon.txt b/gemrb/docs/en/GUIScript/Button_SetActionIcon.txt
new file mode 100644
index 0000000..6d95289
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Button_SetActionIcon.txt
@@ -0,0 +1,18 @@
+
+Prototype: GemRB.SetActionIcon(Window, Button, Dict, ActionIndex[, Function])
+
+Metaclass Prototype:
+
+Description: Sets up an action button. The ActionIndex should be less than 34.
+
+Parameters:
+Window -
+Button -
+Dict -
+ActionIndex -
+Function - (optional)
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Button_SetAnchor.txt b/gemrb/docs/en/GUIScript/Button_SetAnchor.txt
new file mode 100644
index 0000000..c527531
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Button_SetAnchor.txt
@@ -0,0 +1,18 @@
+
+Prototype: GemRB.SetButtonAnchor(WindowIndex, ControlIndex, x, y)
+
+Metaclass Prototype:
+
+Description: Sets explicit anchor point used for drawing button label.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+x -
+y -
+
+Return value:
+
+See also:
+ Button_SetPushOffset
+
diff --git a/gemrb/docs/en/GUIScript/Button_SetBAM.txt b/gemrb/docs/en/GUIScript/Button_SetBAM.txt
new file mode 100644
index 0000000..6d02336
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Button_SetBAM.txt
@@ -0,0 +1,19 @@
+
+Prototype: GemRB.SetButtonBAM(WindowIndex, ControlIndex, BAMResRef, CycleIndex, FrameIndex, col1)
+
+Metaclass Prototype:
+
+Description: Sets the Picture of a Button Control from a BAM file. If col1 is >= 0, changes palette picture's palette to one specified by col1. Since it uses 12 colors palette, it has issues in PST.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+BAMResRef -
+CycleIndex -
+FrameIndex -
+col1 -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Button_SetBorder.txt b/gemrb/docs/en/GUIScript/Button_SetBorder.txt
new file mode 100644
index 0000000..260d158
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Button_SetBorder.txt
@@ -0,0 +1,26 @@
+
+Prototype: GemRB.SetButtonBorder(WindowIndex, ControlIndex, BorderIndex, dx1, dy1, dx2, dy2, R, G, B, A, [enabled, filled])
+
+Metaclass Prototype:
+
+Description: Sets border/frame parameters for a button.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+BorderIndex -
+dx1 -
+dy1 -
+dx2 -
+dy2 -
+R -
+G -
+B -
+A -
+enabled -
+filled - (optional)
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Button_SetFlags.txt b/gemrb/docs/en/GUIScript/Button_SetFlags.txt
new file mode 100644
index 0000000..eec0904
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Button_SetFlags.txt
@@ -0,0 +1,17 @@
+
+Prototype: GemRB.SetButtonFlags(WindowIndex, ControlIndex, Flags, Operation)
+
+Metaclass Prototype:
+
+Description: Sets the Display Flags of a Button.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+Flags -
+Operation -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Button_SetFont.txt b/gemrb/docs/en/GUIScript/Button_SetFont.txt
new file mode 100644
index 0000000..1fe5989
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Button_SetFont.txt
@@ -0,0 +1,16 @@
+
+Prototype: GemRB.SetButtonFont(WindowIndex, ControlIndex, FontResRef)
+
+Metaclass Prototype:
+
+Description: Sets font used for drawing button label.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+FontResRef -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Button_SetItemIcon.txt b/gemrb/docs/en/GUIScript/Button_SetItemIcon.txt
new file mode 100644
index 0000000..f84541e
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Button_SetItemIcon.txt
@@ -0,0 +1,20 @@
+
+Prototype: GemRB.SetItemIcon(WindowIndex, ControlIndex, ITMResRef[, type, tooltip, Function, ITM2ResRef])nnSets Item icon image on a button. 0/1 - Inventory Icons, 2 - Description Icon, 3 - No icon,n
+
+Metaclass Prototype:
+
+Description: 4/5 - Weapon icons, 6 and above - Extended header icons.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+ITMResRef -
+type -
+tooltip -
+Function -
+ITM2ResRef - (optional)
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Button_SetMOS.txt b/gemrb/docs/en/GUIScript/Button_SetMOS.txt
new file mode 100644
index 0000000..e72abb7
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Button_SetMOS.txt
@@ -0,0 +1,16 @@
+
+Prototype: GemRB.SetButtonMOS(WindowIndex, ControlIndex, MOSResRef)
+
+Metaclass Prototype:
+
+Description: Sets the Picture of a Button Control from a MOS file.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+MOSResRef -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Button_SetOverlay.txt b/gemrb/docs/en/GUIScript/Button_SetOverlay.txt
new file mode 100644
index 0000000..7c0dc46
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Button_SetOverlay.txt
@@ -0,0 +1,19 @@
+
+Prototype: GemRB.SetButtonOverlay(WindowIndex, ControlIndex, Current, Max, r,g,b,a, r,g,b,a)
+
+Metaclass Prototype:
+
+Description: Sets up a portrait button for hitpoint overlay
+
+Parameters:
+WindowIndex -
+ControlIndex -
+Current -
+Max -
+rgba -
+rgba -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Button_SetPLT.txt b/gemrb/docs/en/GUIScript/Button_SetPLT.txt
new file mode 100644
index 0000000..7763625
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Button_SetPLT.txt
@@ -0,0 +1,25 @@
+
+Prototype: GemRB.SetButtonPLT(WindowIndex, ControlIndex, PLTResRef, col1, col2, col3, col4, col5, col6, col7, col8, type)
+
+Metaclass Prototype:
+
+Description: Sets the Picture of a Button Control from a PLT file.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+PLTResRef -
+col1 -
+col2 -
+col3 -
+col4 -
+col5 -
+col6 -
+col7 -
+col8 -
+type -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Button_SetPicture.txt b/gemrb/docs/en/GUIScript/Button_SetPicture.txt
new file mode 100644
index 0000000..271f827
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Button_SetPicture.txt
@@ -0,0 +1,17 @@
+
+Prototype: GemRB.SetButtonPicture(WindowIndex, ControlIndex, PictureResRef, DefaultResRef)
+
+Metaclass Prototype:
+
+Description: Sets the Picture of a Button Control from a BMP file. You can also supply a default picture.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+PictureResRef -
+DefaultResRef -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Button_SetPictureClipping.txt b/gemrb/docs/en/GUIScript/Button_SetPictureClipping.txt
new file mode 100644
index 0000000..307c36b
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Button_SetPictureClipping.txt
@@ -0,0 +1,16 @@
+
+Prototype: GemRB.SetButtonPictureClipping(Window, Button, ClippingPercent)
+
+Metaclass Prototype:
+
+Description: Sets percent (0-1.0) of width to which button picture will be clipped.
+
+Parameters:
+Window -
+Button -
+ClippingPercent -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Button_SetPushOffset.txt b/gemrb/docs/en/GUIScript/Button_SetPushOffset.txt
new file mode 100644
index 0000000..d1452af
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Button_SetPushOffset.txt
@@ -0,0 +1,18 @@
+
+Prototype: GemRB.SetButtonPushOffset(WindowIndex, ControlIndex, x, y)
+
+Metaclass Prototype:
+
+Description: Sets offset pictures and label move when the button is pressed.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+x -
+y -
+
+Return value:
+
+See also:
+ Button_SetAnchor
+
diff --git a/gemrb/docs/en/GUIScript/Button_SetSpellIcon.txt b/gemrb/docs/en/GUIScript/Button_SetSpellIcon.txt
new file mode 100644
index 0000000..91c6356
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Button_SetSpellIcon.txt
@@ -0,0 +1,19 @@
+
+Prototype: GemRB.SetSpellIcon(WindowIndex, ControlIndex, SPLResRef[, type, tooltip, function])
+
+Metaclass Prototype:
+
+Description: Sets Spell icon image on a button. Type is the icon's type.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+SPLResRef -
+type -
+tooltip -
+function - (optional)
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Button_SetSprite2D.txt b/gemrb/docs/en/GUIScript/Button_SetSprite2D.txt
new file mode 100644
index 0000000..317d0af
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Button_SetSprite2D.txt
@@ -0,0 +1,16 @@
+
+Prototype: GemRB.Button.SetSprite2D(WindowIndex, ControlIndex, Sprite2D)
+
+Metaclass Prototype:
+
+Description: Sets a Sprite2D onto a button as picture.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+Sprite2D -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Button_SetSprites.txt b/gemrb/docs/en/GUIScript/Button_SetSprites.txt
new file mode 100644
index 0000000..c2f9c7c
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Button_SetSprites.txt
@@ -0,0 +1,21 @@
+
+Prototype: GemRB.SetButtonSprites(WindowIndex, ControlIndex, ResRef, Cycle, UnpressedFrame, PressedFrame, SelectedFrame, DisabledFrame)
+
+Metaclass Prototype:
+
+Description: Sets a Button Sprites Images.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+ResRef -
+Cycle -
+UnpressedFrame -
+PressedFrame -
+SelectedFrame -
+DisabledFrame -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Button_SetState.txt b/gemrb/docs/en/GUIScript/Button_SetState.txt
new file mode 100644
index 0000000..0b386a9
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Button_SetState.txt
@@ -0,0 +1,16 @@
+
+Prototype: GemRB.SetButtonState(WindowIndex, ControlIndex, State)
+
+Metaclass Prototype:
+
+Description: Sets the state of a Button Control.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+State -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Button_SetTextColor.txt b/gemrb/docs/en/GUIScript/Button_SetTextColor.txt
new file mode 100644
index 0000000..4472938
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Button_SetTextColor.txt
@@ -0,0 +1,19 @@
+
+Prototype: GemRB.SetButtonTextColor(WindowIndex, ControlIndex, red, green, blue[, invert=false])
+
+Metaclass Prototype:
+
+Description: Sets the Text Color of a Button Control. Invert is used for fonts with swapped background and text colors.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+red -
+green -
+blue -
+invert=false - (optional)
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Control_AttachScrollBar.txt b/gemrb/docs/en/GUIScript/Control_AttachScrollBar.txt
new file mode 100644
index 0000000..f14051f
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Control_AttachScrollBar.txt
@@ -0,0 +1,16 @@
+
+Prototype: GemRB.AttachScrollBar(WindowIndex, ControlIndex, ScrollBarControlIndex)
+
+Metaclass Prototype:
+
+Description: Attaches a ScrollBar to another control.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+ScrollBarControlIndex -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Control_QueryText.txt b/gemrb/docs/en/GUIScript/Control_QueryText.txt
new file mode 100644
index 0000000..b89b32f
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Control_QueryText.txt
@@ -0,0 +1,15 @@
+
+Prototype: GemRB.QueryText(WindowIndex, ControlIndex)
+
+Metaclass Prototype:
+
+Description: Returns the Text of a TextEdit control.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+
+Return value: string
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Control_SetAnimation.txt b/gemrb/docs/en/GUIScript/Control_SetAnimation.txt
new file mode 100644
index 0000000..e7c00e3
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Control_SetAnimation.txt
@@ -0,0 +1,18 @@
+
+Prototype: GemRB.SetAnimation(WindowIndex, ControlIndex, BAMResRef[, Cycle, Blend])
+
+Metaclass Prototype:
+
+Description: Sets the animation of a Control (usually a Button) from a BAM file. Optionally an animation cycle could be set too.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+BAMResRef -
+Cycle -
+Blend - (optional)
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Control_SetAnimationPalette.txt b/gemrb/docs/en/GUIScript/Control_SetAnimationPalette.txt
new file mode 100644
index 0000000..01925f5
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Control_SetAnimationPalette.txt
@@ -0,0 +1,23 @@
+
+Prototype: GemRB.SetAnimationPalette(WindowIndex, ControlIndex, col1, col2, col3, col4, col5, col6, col7, col8)
+
+Metaclass Prototype:
+
+Description: Sets the palette of an animation already assigned to the button.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+col1 -
+col2 -
+col3 -
+col4 -
+col5 -
+col6 -
+col7 -
+col8 -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Control_SetEvent.txt b/gemrb/docs/en/GUIScript/Control_SetEvent.txt
new file mode 100644
index 0000000..83803b1
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Control_SetEvent.txt
@@ -0,0 +1,15 @@
+
+Prototype: GemRB.Control.SetEvent(EventMask, Function)
+
+Metaclass Prototype:
+
+Description: Sets an event of a control on a window to a script defined function.
+
+Parameters:
+EventMask -
+Function -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Control_SetPos.txt b/gemrb/docs/en/GUIScript/Control_SetPos.txt
new file mode 100644
index 0000000..89c5568
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Control_SetPos.txt
@@ -0,0 +1,17 @@
+
+Prototype: GemRB.SetControlPos(WindowIndex, ControlIndex, X, Y)
+
+Metaclass Prototype:
+
+Description: Moves a Control.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+X -
+Y -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Control_SetSize.txt b/gemrb/docs/en/GUIScript/Control_SetSize.txt
new file mode 100644
index 0000000..3a6f8c7
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Control_SetSize.txt
@@ -0,0 +1,17 @@
+
+Prototype: GemRB.SetControlSize(WindowIndex, ControlIndex, Width, Height)
+
+Metaclass Prototype:
+
+Description: Resizes a Control.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+Width -
+Height -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Control_SetStatus.txt b/gemrb/docs/en/GUIScript/Control_SetStatus.txt
new file mode 100644
index 0000000..6e7879e
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Control_SetStatus.txt
@@ -0,0 +1,16 @@
+
+Prototype: GemRB.SetControlStatus(WindowIndex, ControlIndex, Status)
+
+Metaclass Prototype:
+
+Description: Sets the status of a Control.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+Status -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Control_SetText.txt b/gemrb/docs/en/GUIScript/Control_SetText.txt
new file mode 100644
index 0000000..8bfe872
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Control_SetText.txt
@@ -0,0 +1,16 @@
+
+Prototype: GemRB.SetText(WindowIndex, ControlIndex, String|Strref)
+
+Metaclass Prototype:
+
+Description: Sets the Text of a control in a Window.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+String|Strref -
+
+Return value: int
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Control_SetTooltip.txt b/gemrb/docs/en/GUIScript/Control_SetTooltip.txt
new file mode 100644
index 0000000..aea203e
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Control_SetTooltip.txt
@@ -0,0 +1,17 @@
+
+Prototype: GemRB.SetTooltip(WindowIndex, ControlIndex, String|Strref[, Function])
+
+Metaclass Prototype:
+
+Description: Sets control's tooltip. The optional function number will set the function key linkage as well.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+String|Strref -
+Function - (optional)
+
+Return value: int
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Control_SetVarAssoc.txt b/gemrb/docs/en/GUIScript/Control_SetVarAssoc.txt
new file mode 100644
index 0000000..444c4f8
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Control_SetVarAssoc.txt
@@ -0,0 +1,17 @@
+
+Prototype: GemRB.SetVarAssoc(WindowIndex, ControlIndex, VariableName, LongValue)
+
+Metaclass Prototype:
+
+Description: Sets the name of the Variable associated with a control.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+VariableName -
+LongValue -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Control_TextArea_SetFlags.txt b/gemrb/docs/en/GUIScript/Control_TextArea_SetFlags.txt
new file mode 100644
index 0000000..8e616df
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Control_TextArea_SetFlags.txt
@@ -0,0 +1,17 @@
+
+Prototype: GemRB.SetTextAreaFlags(WindowIndex, ControlIndex, Flags, Operation)
+
+Metaclass Prototype:
+
+Description: Sets the Display Flags of a TextArea. Flags are: IE_GUI_TA_SELECTABLE, IE_GUI_TA_AUTOSCROLL, IE_GUI_TA_SMOOTHSCROLL. Operation defaults to OP_SET.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+Flags -
+Operation -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/CreateString.txt b/gemrb/docs/en/GUIScript/CreateString.txt
new file mode 100644
index 0000000..ed3869d
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/CreateString.txt
@@ -0,0 +1,14 @@
+
+Prototype: GemRB.CreateString( Text )->StrRef
+
+Metaclass Prototype:
+
+Description: Creates a custom string.
+
+Parameters:
+Text -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/DispelEffect.txt b/gemrb/docs/en/GUIScript/DispelEffect.txt
new file mode 100644
index 0000000..0876e8c
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/DispelEffect.txt
@@ -0,0 +1,16 @@
+
+Prototype: GemRB.DispelEffect(PartyID, EffectName, Parameter2)
+
+Metaclass Prototype:
+
+Description: Removes all effects from target whose opcode and second parameter matches the arguments.
+
+Parameters:
+PartyID -
+EffectName -
+Parameter2 -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/FindStoreItem.txt b/gemrb/docs/en/GUIScript/FindStoreItem.txt
new file mode 100644
index 0000000..e3216f5
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/FindStoreItem.txt
@@ -0,0 +1,14 @@
+
+Prototype: GemRB.FindStoreItem(resref)nnReturns the amount of the specified items in the open store.
+
+Metaclass Prototype:
+
+Description: 0 is also returned for an infinite ammount.
+
+Parameters:
+resref -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/GameGetExpansion.txt b/gemrb/docs/en/GUIScript/GameGetExpansion.txt
new file mode 100644
index 0000000..3cb8f4a
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/GameGetExpansion.txt
@@ -0,0 +1,13 @@
+
+Prototype: GemRB.GameGetExpansion()
+
+Metaclass Prototype:
+
+Description: Gets the expansion mode.
+
+Parameters:
+
+Return value: int
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/GameGetFirstSelectedActor.txt b/gemrb/docs/en/GUIScript/GameGetFirstSelectedActor.txt
new file mode 100644
index 0000000..c4b0da5
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/GameGetFirstSelectedActor.txt
@@ -0,0 +1,13 @@
+
+Prototype: GemRB.GameGetFirstSelectedActor()
+
+Metaclass Prototype:
+
+Description: Returns the global ID of the first selected actor or 0 if none.
+
+Parameters:
+
+Return value: int
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/GamePause.txt b/gemrb/docs/en/GUIScript/GamePause.txt
index abb5017..1cdd4e8 100644
--- a/gemrb/docs/en/GUIScript/GamePause.txt
+++ b/gemrb/docs/en/GUIScript/GamePause.txt
@@ -1,12 +1,19 @@
-Prototype: GemRB.GamePause(pause, quiet)
+Prototype: bool GemRB.GamePause(pause, quiet)
Description: Pauses or unpauses the current game. This affects all ingame events, including: scripts, animations, movement. It doesn't affect the GUI.
-Parameters: pause - int, 1 = pause, 0 = continue, 2 = toggle pause
- quiet - bool, true = no message, false = game paused/unpaused message
+Parameters:
+pause - int,
+ 0 = continue
+ 1 = pause
+ 2 = toggle pause
+ 3 = query state
+quiet - int bitfield,
+ 1 - no feedback
+ 2 - forced pause
-Return value: N/A
+Return value: the resulting paused state
See also:
diff --git a/gemrb/docs/en/GUIScript/GetCombatDetails.txt b/gemrb/docs/en/GUIScript/GetCombatDetails.txt
index fa148da..e17fd3d 100644
--- a/gemrb/docs/en/GUIScript/GetCombatDetails.txt
+++ b/gemrb/docs/en/GUIScript/GetCombatDetails.txt
@@ -7,7 +7,8 @@ Parameters:
pc - position in the party
leftorright - left or right hand weapon (main or offhand)
-Return value: dict: "ToHit", "Flags", "DamageBonus", "Speed", "CriticalBonus", "Style"
+Return value: dict: "ToHit", "Flags", "DamageBonus", "Speed", "CriticalBonus",
+ "Style", "Proficiency", "Range", "Enchantment", "Slot"
See also: IsDualWielding
diff --git a/gemrb/docs/en/GUIScript/GetDestinationArea.txt b/gemrb/docs/en/GUIScript/GetDestinationArea.txt
index 2dc9e84..276a9fa 100644
--- a/gemrb/docs/en/GUIScript/GetDestinationArea.txt
+++ b/gemrb/docs/en/GUIScript/GetDestinationArea.txt
@@ -17,5 +17,3 @@ Destination - The area resource reference where the player arrives (if there was
Entrance - The area entrance in the Destination area, it could be empty, in this casethe player should appear in middle of the area
See also: CreateWorldMapControl, CreateMovement, accessing_gui_controls
-
-MD5: b19700ed972c915b0910b40a746a87ee
diff --git a/gemrb/docs/en/GUIScript/GetGamePortraitPreview.txt b/gemrb/docs/en/GUIScript/GetGamePortraitPreview.txt
new file mode 100644
index 0000000..54c049e
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/GetGamePortraitPreview.txt
@@ -0,0 +1,14 @@
+
+Prototype: GemRB.GetGamePortraitPreview(PCSlotCount)
+
+Metaclass Prototype:
+
+Description: Gets a current game PC portrait.
+
+Parameters:
+PCSlotCount -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/GetGamePreview.txt b/gemrb/docs/en/GUIScript/GetGamePreview.txt
new file mode 100644
index 0000000..b0d264e
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/GetGamePreview.txt
@@ -0,0 +1,13 @@
+
+Prototype: GemRB.GetGamePreview()
+
+Metaclass Prototype:
+
+Description: Gets current game area preview.
+
+Parameters:
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/GetGameString.txt b/gemrb/docs/en/GUIScript/GetGameString.txt
index dd1eb40..e93b951 100644
--- a/gemrb/docs/en/GUIScript/GetGameString.txt
+++ b/gemrb/docs/en/GUIScript/GetGameString.txt
@@ -6,6 +6,7 @@ Description: Returns a system variable of string type referenced by Index.
Parameters: Index
0 - returns the loading picture's name (MOS resref)
1 - returns the current area's name (ARE resref)
+2 - returns the table name for the text screen (2DA resref)
Return value: string - the referenced system variable
diff --git a/gemrb/docs/en/GUIScript/GetItem.txt b/gemrb/docs/en/GUIScript/GetItem.txt
index 3b157d1..1451cd2 100644
--- a/gemrb/docs/en/GUIScript/GetItem.txt
+++ b/gemrb/docs/en/GUIScript/GetItem.txt
@@ -12,7 +12,7 @@ The fields of the dictionary are the following:
"ItemDesc" - strref of unidentified description.
"ItemDescIdentified" - strref of identified description.
"ItemIcon" - the item's icon (.bam resref)
-"StackAmount" - maximum stackable amount
+"MaxStackAmount" - maximum stackable amount
"Dialog" - item dialog (.dlg resref)
"DialogName" - the item dialog name
"Function" - returns special function
diff --git a/gemrb/docs/en/GUIScript/GetMazeEntry.txt b/gemrb/docs/en/GUIScript/GetMazeEntry.txt
new file mode 100644
index 0000000..15562fa
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/GetMazeEntry.txt
@@ -0,0 +1,14 @@
+
+Prototype: GemRB.GetMazeEntry(entry)
+
+Metaclass Prototype:
+
+Description: Returns a Maze entry from Planescape Torment savegames. Entry must be 0-63.
+
+Parameters:
+entry -
+
+Return value: dict
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/GetMazeHeader.txt b/gemrb/docs/en/GUIScript/GetMazeHeader.txt
new file mode 100644
index 0000000..0e9b5eb
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/GetMazeHeader.txt
@@ -0,0 +1,13 @@
+
+Prototype: GemRB.GetMazeHeader()
+
+Metaclass Prototype:
+
+Description: Returns the Maze header of Planescape Torment savegames.
+
+Parameters:
+
+Return value: dict
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/GetPlayerSound.txt b/gemrb/docs/en/GUIScript/GetPlayerSound.txt
new file mode 100644
index 0000000..004f2de
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/GetPlayerSound.txt
@@ -0,0 +1,14 @@
+
+Prototype: GemRB.SetPlayerSound(Slot)
+
+Metaclass Prototype:
+
+Description: Gets the player character's sound set.
+
+Parameters:
+Slot -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/GetPlayerStat.txt b/gemrb/docs/en/GUIScript/GetPlayerStat.txt
index b08d172..9d1dac9 100644
--- a/gemrb/docs/en/GUIScript/GetPlayerStat.txt
+++ b/gemrb/docs/en/GUIScript/GetPlayerStat.txt
@@ -6,6 +6,7 @@ Description: Queries a stat of the player character. The stats are listed in ie_
Parameters: Slot - actor index in game structure
ID - Stat index
Base - if set to 1, the function will return the base instead of the modified (current) value
+ global - if set, use Slot as globalID of global actor
Return value: numeric
diff --git a/gemrb/docs/en/GUIScript/GetSaveGames.txt b/gemrb/docs/en/GUIScript/GetSaveGames.txt
new file mode 100644
index 0000000..8bb1c79
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/GetSaveGames.txt
@@ -0,0 +1,13 @@
+
+Prototype: GemRB.GetSaveGameCount()
+
+Metaclass Prototype:
+
+Description: Returns the list of saved games.
+
+Parameters:
+
+Return value: int
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/GetSelectedActors.txt b/gemrb/docs/en/GUIScript/GetSelectedActors.txt
new file mode 100644
index 0000000..52fec49
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/GetSelectedActors.txt
@@ -0,0 +1,13 @@
+
+Prototype: GemRB.GetSelectedActors()
+
+Metaclass Prototype:
+
+Description: Returns the global ids of selected actors in a tuple.
+
+Parameters:
+
+Return value: int
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/GetSpell.txt b/gemrb/docs/en/GUIScript/GetSpell.txt
index 3834640..b205eb9 100644
--- a/gemrb/docs/en/GUIScript/GetSpell.txt
+++ b/gemrb/docs/en/GUIScript/GetSpell.txt
@@ -16,6 +16,8 @@ The fields of the dictionary are the following:
"SpellSchool" - the spell's school (primary type)
"SpellType" - the type of text that appears on spell dispelling
"SpellLevel" - the spell's level
+"Completion" - the spell's completion sound
+"SpellTargetType" - the spell's target type
See also: GetItem, SetSpellIcon, spell_structure(IESDP)
diff --git a/gemrb/docs/en/GUIScript/GetSpellCastOn.txt b/gemrb/docs/en/GUIScript/GetSpellCastOn.txt
new file mode 100644
index 0000000..1b7bb74
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/GetSpellCastOn.txt
@@ -0,0 +1,14 @@
+
+Prototype: GemRB.GetSpellCastOn(pc)
+
+Metaclass Prototype:
+
+Description: Returns the last spell cast on a partymember.
+
+Parameters:
+pc -
+
+Return value: resref
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/GetStoreItem.txt b/gemrb/docs/en/GUIScript/GetStoreItem.txt
index 9dfb076..9c041aa 100644
--- a/gemrb/docs/en/GUIScript/GetStoreItem.txt
+++ b/gemrb/docs/en/GUIScript/GetStoreItem.txt
@@ -15,6 +15,7 @@ Return value: dictionary
"Usages1" - The secondary charges of the item.
"Usages2" - The tertiary charges of the item.
"Flags" - Item flags.
+"Purchased" - The count of purchased items of this type.
See also: EnterStore, GetStoreDrink, GetStoreCure, GetStore, GetSlotItem
diff --git a/gemrb/docs/en/GUIScript/HasFeat.txt b/gemrb/docs/en/GUIScript/HasFeat.txt
new file mode 100644
index 0000000..122ec0c
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/HasFeat.txt
@@ -0,0 +1,14 @@
+Prototype: GemRB.HasFeat(Slot, feat)
+
+Metaclass Prototype:
+
+Description: Returns 1 if the player in Slot has the passed feat id (from ie_feats.py).
+
+Parameters:
+Slot - player party index
+feat - feat index from ie_feats.py
+
+Return value: 1 if the pc has it, 0 otherwise
+
+See also:
+CheckFeatCondition
diff --git a/gemrb/docs/en/GUIScript/Label_SetTextColor.txt b/gemrb/docs/en/GUIScript/Label_SetTextColor.txt
new file mode 100644
index 0000000..2bd9707
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Label_SetTextColor.txt
@@ -0,0 +1,18 @@
+
+Prototype: GemRB.SetLabelTextColor(WindowIndex, ControlIndex, red, green, blue)
+
+Metaclass Prototype:
+
+Description: Sets the Text Color of a Label Control.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+red -
+green -
+blue -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Label_SetUseRGB.txt b/gemrb/docs/en/GUIScript/Label_SetUseRGB.txt
new file mode 100644
index 0000000..7d02a91
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Label_SetUseRGB.txt
@@ -0,0 +1,16 @@
+
+Prototype: GemRB.SetLabelUseRGB(WindowIndex, ControlIndex, status)
+
+Metaclass Prototype:
+
+Description: Tells a Label to use the RGB colors with the text.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+status -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/MemorizeSpell.txt b/gemrb/docs/en/GUIScript/MemorizeSpell.txt
index c257d56..88b5516 100644
--- a/gemrb/docs/en/GUIScript/MemorizeSpell.txt
+++ b/gemrb/docs/en/GUIScript/MemorizeSpell.txt
@@ -1,5 +1,5 @@
-Prototype: GemRB.MemorizeSpell(PartyID, SpellType, Level, Index)
+Prototype: GemRB.MemorizeSpell(PartyID, SpellType, Level, Index[, Enabled])
Description: Sets spell to be memorized on rest.
@@ -8,6 +8,7 @@ PartyID - the PC's position in the party
SpellType - 0 - priest, 1 - wizard, 2 - innate
Level - the known spell's level
Index - the known spell's index
+Enabled - defaults to 0, which means the spell is depleted
Return value: boolean, 1 on success.
diff --git a/gemrb/docs/en/GUIScript/MessageWindowDebug.txt b/gemrb/docs/en/GUIScript/MessageWindowDebug.txt
new file mode 100644
index 0000000..06c41c3
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/MessageWindowDebug.txt
@@ -0,0 +1,22 @@
+
+Prototype: GemRB.MessageWindowDebug(log_level)
+
+Alias: debug(log_level)
+
+Description: Enable/Disable logging messages of "log_level" to the message window.
+
+Parameters: log_level - can be a string representing levels or the level itself as a number.
+Possibles values (see GUIDefines.py):
+LOG_NONE = -1,
+LOG_FATAL = 0,
+LOG_ERROR = 1,
+LOG_WARNING = 2
+LOG_MESSAGE = 3
+LOG_COMBAT = 4
+LOG_DEBUG = 5
+
+Values of LOG_NONE or -1 will remove the logger.
+
+Return value: None
+
+See also:
diff --git a/gemrb/docs/en/GUIScript/SaveGame_GetDate.txt b/gemrb/docs/en/GUIScript/SaveGame_GetDate.txt
new file mode 100644
index 0000000..abfc88e
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/SaveGame_GetDate.txt
@@ -0,0 +1,13 @@
+
+Prototype: GemRB.SaveGame.GetDate()
+
+Metaclass Prototype:
+
+Description: Returns date of the saved game.
+
+Parameters:
+
+Return value: string/int
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/SaveGame_GetGameDate.txt b/gemrb/docs/en/GUIScript/SaveGame_GetGameDate.txt
new file mode 100644
index 0000000..7008bb9
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/SaveGame_GetGameDate.txt
@@ -0,0 +1,13 @@
+
+Prototype: GemRB.SaveGame.GetGameDate()
+
+Metaclass Prototype:
+
+Description: Returns game date of the saved game.
+
+Parameters:
+
+Return value: string/int
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/SaveGame_GetName.txt b/gemrb/docs/en/GUIScript/SaveGame_GetName.txt
new file mode 100644
index 0000000..ada563b
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/SaveGame_GetName.txt
@@ -0,0 +1,13 @@
+
+Prototype: GemRB.SaveGame.GetName()
+
+Metaclass Prototype:
+
+Description: Returns name of the saved game.
+
+Parameters:
+
+Return value: string/int
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/SaveGame_GetPortrait.txt b/gemrb/docs/en/GUIScript/SaveGame_GetPortrait.txt
new file mode 100644
index 0000000..194b43e
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/SaveGame_GetPortrait.txt
@@ -0,0 +1,15 @@
+
+Prototype: GemRB.SaveGame.GetPortrait(int index)
+
+Metaclass Prototype:
+
+Description: Returns portrait of the saved game.
+
+Parameters:
+int -
+index -
+
+Return value: string/int
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/SaveGame_GetPreview.txt b/gemrb/docs/en/GUIScript/SaveGame_GetPreview.txt
new file mode 100644
index 0000000..2e34553
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/SaveGame_GetPreview.txt
@@ -0,0 +1,13 @@
+
+Prototype: GemRB.SaveGame.GetPreview()
+
+Metaclass Prototype:
+
+Description: Returns preview of the saved game.
+
+Parameters:
+
+Return value: string/int
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/SaveGame_GetSaveID.txt b/gemrb/docs/en/GUIScript/SaveGame_GetSaveID.txt
new file mode 100644
index 0000000..89c0c78
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/SaveGame_GetSaveID.txt
@@ -0,0 +1,13 @@
+
+Prototype: GemRB.SaveGame.GetSaveID()
+
+Metaclass Prototype:
+
+Description: Returns ID of the saved game.
+
+Parameters:
+
+Return value: string/int
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/ScrollBar_SetDefaultScrollBar.txt b/gemrb/docs/en/GUIScript/ScrollBar_SetDefaultScrollBar.txt
new file mode 100644
index 0000000..b3d7330
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/ScrollBar_SetDefaultScrollBar.txt
@@ -0,0 +1,15 @@
+
+Prototype: GemRB.SetDefaultScrollBar(WindowIndex, ControlIndex)
+
+Metaclass Prototype:
+
+Description: Sets the ScrollBar control as default.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/ScrollBar_SetSprites.txt b/gemrb/docs/en/GUIScript/ScrollBar_SetSprites.txt
new file mode 100644
index 0000000..12da3ee
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/ScrollBar_SetSprites.txt
@@ -0,0 +1,23 @@
+
+Prototype: GemRB.SetScrollBarSprites(WindowIndex, ControlIndex, ResRef, Cycle, UpUnpressedFrame, UpPressedFrame, DownUnpressedFrame, DownPressedFrame, TroughFrame, SliderFrame)
+
+Metaclass Prototype:
+
+Description: Sets a ScrollBar Sprites Images.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+ResRef -
+Cycle -
+UpUnpressedFrame -
+UpPressedFrame -
+DownUnpressedFrame -
+DownPressedFrame -
+TroughFrame -
+SliderFrame -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/SetButtonFlags.txt b/gemrb/docs/en/GUIScript/SetButtonFlags.txt
index 480d574..470a8b1 100644
--- a/gemrb/docs/en/GUIScript/SetButtonFlags.txt
+++ b/gemrb/docs/en/GUIScript/SetButtonFlags.txt
@@ -11,7 +11,7 @@ Flags - various bits altering the behaviour of the control
IE_GUI_BUTTON_NO_IMAGE = 0x00000001, no button image set by SetButtonSprites
IE_GUI_BUTTON_PICTURE = 0x00000002, has picture set by other SetButton* commands
IE_GUI_BUTTON_SOUND = 0x00000004, clicking the button has a sound
-IE_GUI_BUTTON_ALT_SOUND = 0x00000008, clicking the button has a different sound
+IE_GUI_BUTTON_CAPS = 0x00000008, uppercase the button label
IE_GUI_BUTTON_CHECKBOX = 0x00000010, it is a checkbox
IE_GUI_BUTTON_RADIOBUTTON= 0x00000020, it is a radio button
IE_GUI_BUTTON_DEFAULT = 0x00000040, it is the default button
diff --git a/gemrb/docs/en/GUIScript/SetButtonState.txt b/gemrb/docs/en/GUIScript/SetButtonState.txt
index b439d82..8615ac4 100644
--- a/gemrb/docs/en/GUIScript/SetButtonState.txt
+++ b/gemrb/docs/en/GUIScript/SetButtonState.txt
@@ -14,8 +14,8 @@ IE_GUI_BUTTON_PRESSED = 0x00000001, the button is pressed
IE_GUI_BUTTON_SELECTED = 0x00000002, the button stuck in pressed state
IE_GUI_BUTTON_DISABLED = 0x00000003, the button is disabled
IE_GUI_BUTTON_LOCKED = 0x00000004, the button is inactive (like DISABLED, but processes MouseOver events and draws UNPRESSED bitmap)
-IE_GUI_BUTTON_THIRD = 0x00000005, draws DISABLED bitmap, but it isn't disabled
-IE_GUI_BUTTON_SECOND = 0x00000006, draws PRESSED bitmap, but it isn't shifted
+IE_GUI_BUTTON_FAKEDISABLED = 0x00000005, draws DISABLED bitmap, but it isn't disabled
+IE_GUI_BUTTON_FAKEPRESSED = 0x00000006, draws PRESSED bitmap, but it isn't shifted
Return value: N/A
diff --git a/gemrb/docs/en/GUIScript/SetEvent.txt b/gemrb/docs/en/GUIScript/SetEvent.txt
index 98ff994..4e7c2c2 100644
--- a/gemrb/docs/en/GUIScript/SetEvent.txt
+++ b/gemrb/docs/en/GUIScript/SetEvent.txt
@@ -19,7 +19,6 @@ IE_GUI_PROGRESS_END_REACHED = 0x01000000, the progressbar received a 100 percent
IE_GUI_SLIDER_ON_CHANGE = 0x02000000, the slider's knob position has changed.
IE_GUI_EDIT_ON_CHANGE = 0x03000000, the text in the editbox has changed.
IE_GUI_TEXTAREA_ON_CHANGE = 0x05000000, the text in the textarea has changed.
-IE_GUI_TEXTAREA_OUT_OF_TEXT = 0x05000001, the smooth scrolling textarea is out of text.
IE_GUI_LABEL_ON_PRESS = 0x06000000, the label was pressed.
IE_GUI_SCROLLBAR_ON_CHANGE= 0x07000000, the scrollbar's knob position has changed.
.... (See GUIDefines.py for more event types)
diff --git a/gemrb/docs/en/GUIScript/SetMapAnimation.txt b/gemrb/docs/en/GUIScript/SetMapAnimation.txt
new file mode 100644
index 0000000..6080382
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/SetMapAnimation.txt
@@ -0,0 +1,19 @@
+
+Prototype: GemRB.SetMapAnimation(X, Y, BAMresref[, flags, cycle, height])
+
+Metaclass Prototype:
+
+Description: Creates an area animation.
+
+Parameters:
+X -
+Y -
+BAMresref -
+flags -
+cycle -
+height - (optional)
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/SetMapDoor.txt b/gemrb/docs/en/GUIScript/SetMapDoor.txt
new file mode 100644
index 0000000..686c976
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/SetMapDoor.txt
@@ -0,0 +1,15 @@
+
+Prototype: GemRB.SetMapDoor(DoorName, State)
+
+Metaclass Prototype:
+
+Description: Modifies a door's open state in the current area.
+
+Parameters:
+DoorName -
+State -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/SetMapExit.txt b/gemrb/docs/en/GUIScript/SetMapExit.txt
new file mode 100644
index 0000000..c429292
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/SetMapExit.txt
@@ -0,0 +1,16 @@
+
+Prototype: GemRB.SetMapExit(ExitName[, NewArea, NewEntrance])nnModifies the target of an exit in the current area. If no destination is given,
+
+Metaclass Prototype:
+
+Description: then the exit will be disabled.
+
+Parameters:
+ExitName -
+NewArea -
+NewEntrance - (optional)
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/SetMapRegion.txt b/gemrb/docs/en/GUIScript/SetMapRegion.txt
new file mode 100644
index 0000000..f7186c4
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/SetMapRegion.txt
@@ -0,0 +1,15 @@
+
+Prototype: GemRB.SetMapRegion(TrapName[, trapscript])
+
+Metaclass Prototype:
+
+Description: Enables or disables an infopoint in the current area.
+
+Parameters:
+TrapName -
+trapscript - (optional)
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/SetMazeData.txt b/gemrb/docs/en/GUIScript/SetMazeData.txt
new file mode 100644
index 0000000..e035103
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/SetMazeData.txt
@@ -0,0 +1,15 @@
+
+Prototype: GemRB.SetMazeData(type, value)nnSets a field in the maze header.
+
+Metaclass Prototype:
+
+Description: The type could be: ME_0, ME_WALLS, ME_TRAP or ME_16.
+
+Parameters:
+type -
+value -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/SetMazeEntry.txt b/gemrb/docs/en/GUIScript/SetMazeEntry.txt
new file mode 100644
index 0000000..e94cabc
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/SetMazeEntry.txt
@@ -0,0 +1,16 @@
+
+Prototype: GemRB.SetMazeEntry(entry, type, value)nnSets a field in a maze entry. The entry index shouldn't exceed the maximum possible maze size (64).
+
+Metaclass Prototype:
+
+Description: The type could be: ME_ACCESSED, ME_WALLS, ME_TRAP or ME_SPECIAL.
+
+Parameters:
+entry -
+type -
+value -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/SetPlayerStat.txt b/gemrb/docs/en/GUIScript/SetPlayerStat.txt
index d6eb59e..9f42ecf 100644
--- a/gemrb/docs/en/GUIScript/SetPlayerStat.txt
+++ b/gemrb/docs/en/GUIScript/SetPlayerStat.txt
@@ -7,6 +7,7 @@ Parameters: Slot - actor index in game structure
ID - Stat index
Value - New stat value
PCF - Set to 0 if you don't want the stat's post-change function to be ran
+ global - if set, use Slot as globalID of global actor
Return value: N/A
diff --git a/gemrb/docs/en/GUIScript/SetTickHook.txt b/gemrb/docs/en/GUIScript/SetTickHook.txt
new file mode 100644
index 0000000..9f58d8b
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/SetTickHook.txt
@@ -0,0 +1,13 @@
+
+Prototype: GemRB.Set callback to be called every main loop iteration.
+
+Metaclass Prototype:
+
+Description: This is useful for things like running a twisted reactor.
+
+Parameters:
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/SetupControls.txt b/gemrb/docs/en/GUIScript/SetupControls.txt
index 61bfd09..5746995 100644
--- a/gemrb/docs/en/GUIScript/SetupControls.txt
+++ b/gemrb/docs/en/GUIScript/SetupControls.txt
@@ -11,4 +11,4 @@ Slot - the player character's index in the party
Return value: N/A
-See also: SetActionIcon, SetDefaultActions, SetupEquipmentIcons, SetupSpellIcons
+See also: SetActionIcon, SetDefaultActions, SetupEquipmentIcons
diff --git a/gemrb/docs/en/GUIScript/SetupEquipmentIcons.txt b/gemrb/docs/en/GUIScript/SetupEquipmentIcons.txt
index 81c58a9..c11ef21 100644
--- a/gemrb/docs/en/GUIScript/SetupEquipmentIcons.txt
+++ b/gemrb/docs/en/GUIScript/SetupEquipmentIcons.txt
@@ -14,4 +14,4 @@ Start - start the equipment list from this value
Return value: N/A
-See also: SetupSpellIcons, SetupControls, UseItem
+See also: SetupControls, UseItem
diff --git a/gemrb/docs/en/GUIScript/SetupMaze.txt b/gemrb/docs/en/GUIScript/SetupMaze.txt
new file mode 100644
index 0000000..6721405
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/SetupMaze.txt
@@ -0,0 +1,14 @@
+
+Prototype: GemRB.SetupMaze(x,y)nnInitializes a maze of XxY size.
+
+Metaclass Prototype:
+
+Description: The dimensions shouldn't exceed the maximum possible maze size (8x8).
+
+Parameters:
+xy -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/SetupQuickSpell.txt b/gemrb/docs/en/GUIScript/SetupQuickSpell.txt
new file mode 100644
index 0000000..9a7697b
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/SetupQuickSpell.txt
@@ -0,0 +1,17 @@
+
+Prototype: GemRB.SetupQuickSpell(PartyID, spellslot, spellindex, type)
+
+Metaclass Prototype:
+
+Description: Set up a quick spell slot. It also returns the target type of the selected spell.
+
+Parameters:
+PartyID -
+spellslot -
+spellindex -
+type -
+
+Return value: int
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/SetupSpellIcons.txt b/gemrb/docs/en/GUIScript/SetupSpellIcons.txt
deleted file mode 100644
index 343a4dd..0000000
--- a/gemrb/docs/en/GUIScript/SetupSpellIcons.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-
-Prototype: GemRB.SetupSpellIcons(WindowIndex, Slot, Type[, Start])
-
-Metaclass Prototype: SetupSpellIcons(Slot, Type[, Start])
-
-Description: Sets up all 12 action buttons for a player character with spell or innate icons.
-It also sets up the scroll buttons left and right if needed.
-If Start is supplied, it will skip the first few items.
-
-Parameters:
-WindowIndex - the buttons' window index
-Slot - the player character's index in the party
-Type - the spell type bitfield (1-mage, 2-priest, 4-innate)
-Start - start the spell list from this value
-
-Return value: N/A
-
-See also: SetupEquipmentIcons, SetupControls, SpellCast
diff --git a/gemrb/docs/en/GUIScript/SpellCast.txt b/gemrb/docs/en/GUIScript/SpellCast.txt
index cdf39a6..cd609bd 100644
--- a/gemrb/docs/en/GUIScript/SpellCast.txt
+++ b/gemrb/docs/en/GUIScript/SpellCast.txt
@@ -10,4 +10,4 @@ Spell - the spell's index in the list
Return value: N/A
-See also: SetupSpellIcons
+See also: UseItem
diff --git a/gemrb/docs/en/GUIScript/Symbol_GetValue.txt b/gemrb/docs/en/GUIScript/Symbol_GetValue.txt
new file mode 100644
index 0000000..818ae18
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Symbol_GetValue.txt
@@ -0,0 +1,15 @@
+
+Prototype: GemRB.GetSymbolValue(SymbolIndex, StringVal)
+
+Metaclass Prototype:
+
+Description: Returns a field of an IDS Symbol Table.
+
+Parameters:
+SymbolIndex -
+StringVal -
+
+Return value: intnGetSymbolValue(SymbolIndex, IntVal)
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Symbol_Unload.txt b/gemrb/docs/en/GUIScript/Symbol_Unload.txt
new file mode 100644
index 0000000..ed91fd5
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Symbol_Unload.txt
@@ -0,0 +1,14 @@
+
+Prototype: GemRB.UnloadSymbol(SymbolIndex)
+
+Metaclass Prototype:
+
+Description: Unloads an IDS Symbol Table.
+
+Parameters:
+SymbolIndex -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Table_FindValue.txt b/gemrb/docs/en/GUIScript/Table_FindValue.txt
new file mode 100644
index 0000000..7c6def1
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Table_FindValue.txt
@@ -0,0 +1,17 @@
+
+Prototype: GemRB.FindTableValue(TableIndex, ColumnIndex, Value[, StartRow])
+
+Metaclass Prototype:
+
+Description: Returns the first rowcount of a field of a 2DA Table.
+
+Parameters:
+TableIndex -
+ColumnIndex -
+Value -
+StartRow - (optional)
+
+Return value: Row
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Table_GetColumnCount.txt b/gemrb/docs/en/GUIScript/Table_GetColumnCount.txt
new file mode 100644
index 0000000..b354ba8
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Table_GetColumnCount.txt
@@ -0,0 +1,15 @@
+
+Prototype: GemRB.GetTableColumnCount(TableIndex[, Row])
+
+Metaclass Prototype:
+
+Description: Returns the number of columns in the given row of a 2DA Table. Row may be omitted.
+
+Parameters:
+TableIndex -
+Row - (optional)
+
+Return value: ColumnCount
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Table_GetColumnIndex.txt b/gemrb/docs/en/GUIScript/Table_GetColumnIndex.txt
new file mode 100644
index 0000000..3725736
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Table_GetColumnIndex.txt
@@ -0,0 +1,15 @@
+
+Prototype: GemRB.GetTableColumnIndex(TableIndex, ColumnName)
+
+Metaclass Prototype:
+
+Description: Returns the Index of a Column in a 2DA Table.
+
+Parameters:
+TableIndex -
+ColumnName -
+
+Return value: Column
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Table_GetColumnName.txt b/gemrb/docs/en/GUIScript/Table_GetColumnName.txt
new file mode 100644
index 0000000..e35be6c
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Table_GetColumnName.txt
@@ -0,0 +1,15 @@
+
+Prototype: GemRB.GetTableColumnName(TableIndex, ColumnIndex)
+
+Metaclass Prototype:
+
+Description: Returns the Name of a Column in a 2DA Table.
+
+Parameters:
+TableIndex -
+ColumnIndex -
+
+Return value: string
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Table_GetRowCount.txt b/gemrb/docs/en/GUIScript/Table_GetRowCount.txt
new file mode 100644
index 0000000..45f4e30
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Table_GetRowCount.txt
@@ -0,0 +1,14 @@
+
+Prototype: GemRB.GetTableRowCount(TableIndex)
+
+Metaclass Prototype:
+
+Description: Returns the number of rows in a 2DA Table.
+
+Parameters:
+TableIndex -
+
+Return value: RowCount
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Table_GetRowIndex.txt b/gemrb/docs/en/GUIScript/Table_GetRowIndex.txt
new file mode 100644
index 0000000..8ac65c7
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Table_GetRowIndex.txt
@@ -0,0 +1,15 @@
+
+Prototype: GemRB.GetTableRowIndex(TableIndex, RowName)
+
+Metaclass Prototype:
+
+Description: Returns the Index of a Row in a 2DA Table.
+
+Parameters:
+TableIndex -
+RowName -
+
+Return value: Row
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Table_GetRowName.txt b/gemrb/docs/en/GUIScript/Table_GetRowName.txt
new file mode 100644
index 0000000..8f2de34
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Table_GetRowName.txt
@@ -0,0 +1,15 @@
+
+Prototype: GemRB.GetTableRowName(TableIndex, RowIndex)
+
+Metaclass Prototype:
+
+Description: Returns the Name of a Row in a 2DA Table.
+
+Parameters:
+TableIndex -
+RowIndex -
+
+Return value: string
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Table_GetValue.txt b/gemrb/docs/en/GUIScript/Table_GetValue.txt
new file mode 100644
index 0000000..f79e751
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Table_GetValue.txt
@@ -0,0 +1,17 @@
+
+Prototype: GemRB.GetTableValue(TableIndex, RowIndex/RowString, ColIndex/ColString, type)
+
+Metaclass Prototype:
+
+Description: otherwise 0 means string, 1 means integer, 2 means stat symbol translation.
+
+Parameters:
+TableIndex -
+RowIndex/RowString -
+ColIndex/ColString -
+type -
+
+Return value: valuennReturns a field of a 2DA Table. If Type is omitted the return type is the autodetected,
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Table_Unload.txt b/gemrb/docs/en/GUIScript/Table_Unload.txt
new file mode 100644
index 0000000..98496b3
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Table_Unload.txt
@@ -0,0 +1,14 @@
+
+Prototype: GemRB.UnloadTable(TableIndex)
+
+Metaclass Prototype:
+
+Description: Unloads a 2DA Table.
+
+Parameters:
+TableIndex -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/TextArea_Append.txt b/gemrb/docs/en/GUIScript/TextArea_Append.txt
new file mode 100644
index 0000000..26cbf97
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/TextArea_Append.txt
@@ -0,0 +1,19 @@
+
+Prototype: GemRB.TextAreaAppend(WindowIndex, ControlIndex, String|Strref [, Row[, Flag]])
+
+Metaclass Prototype:
+
+Description: If Flag is given, then it will use that value as a GetString flag.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+String|Strref -
+ -
+Row -
+Flag - (optional)
+
+Return value: intnnAppends the Text to the TextArea Control in the Window. If Row is given then it will insert the text after that row.
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/TextArea_Clear.txt b/gemrb/docs/en/GUIScript/TextArea_Clear.txt
new file mode 100644
index 0000000..dc63d81
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/TextArea_Clear.txt
@@ -0,0 +1,15 @@
+
+Prototype: GemRB.TextAreaClear(WindowIndex, ControlIndex)
+
+Metaclass Prototype:
+
+Description: Clears the Text from the TextArea Control in the Window.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/TextArea_GetCharSounds.txt b/gemrb/docs/en/GUIScript/TextArea_GetCharSounds.txt
new file mode 100644
index 0000000..69b850d
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/TextArea_GetCharSounds.txt
@@ -0,0 +1,15 @@
+
+Prototype: GemRB.GetCharSounds(WindowIndex, ControlIndex)
+
+Metaclass Prototype:
+
+Description: Reads in the contents of the sounds subfolder.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+
+Return value: int
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/TextArea_GetCharacters.txt b/gemrb/docs/en/GUIScript/TextArea_GetCharacters.txt
new file mode 100644
index 0000000..1a6f0de
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/TextArea_GetCharacters.txt
@@ -0,0 +1,15 @@
+
+Prototype: GemRB.GetCharacters(WindowIndex, ControlIndex)
+
+Metaclass Prototype:
+
+Description: Reads in the contents of the characters subfolder.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+
+Return value: int
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/TextArea_GetPortraits.txt b/gemrb/docs/en/GUIScript/TextArea_GetPortraits.txt
new file mode 100644
index 0000000..1d029f9
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/TextArea_GetPortraits.txt
@@ -0,0 +1,16 @@
+
+Prototype: GemRB.GetPortraits(WindowIndex, ControlIndex, SmallOrLarge)
+
+Metaclass Prototype:
+
+Description: Reads in the contents of the portraits subfolder.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+SmallOrLarge -
+
+Return value: int
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/TextArea_MoveText.txt b/gemrb/docs/en/GUIScript/TextArea_MoveText.txt
new file mode 100644
index 0000000..ab9ca20
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/TextArea_MoveText.txt
@@ -0,0 +1,17 @@
+
+Prototype: GemRB.MoveTAText(srcWin, srcCtrl, dstWin, dstCtrl)
+
+Metaclass Prototype:
+
+Description: Copies a TextArea content to another.
+
+Parameters:
+srcWin -
+srcCtrl -
+dstWin -
+dstCtrl -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/TextArea_Rewind.txt b/gemrb/docs/en/GUIScript/TextArea_Rewind.txt
new file mode 100644
index 0000000..362a342
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/TextArea_Rewind.txt
@@ -0,0 +1,16 @@
+
+Prototype: GemRB.RewindTA(Win, Ctrl)
+
+Metaclass Prototype:
+
+Description: Sets up a TextArea for scrolling.
+
+Parameters:
+Win -
+Ctrl -
+Ticks -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/TextArea_Scroll.txt b/gemrb/docs/en/GUIScript/TextArea_Scroll.txt
new file mode 100644
index 0000000..0ca15e9
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/TextArea_Scroll.txt
@@ -0,0 +1,16 @@
+
+Prototype: GemRB.TextAreaScroll(WindowIndex, ControlIndex, offset)
+
+Metaclass Prototype:
+
+Description: Scrolls the textarea up or down by offset.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+offset -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/TextArea_SelectText.txt b/gemrb/docs/en/GUIScript/TextArea_SelectText.txt
new file mode 100644
index 0000000..327af72
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/TextArea_SelectText.txt
@@ -0,0 +1,16 @@
+
+Prototype: GemRB.SelectText(WindowIndex, ControlIndex, String|Strref)
+
+Metaclass Prototype:
+
+Description: Tries to set the Variable of the TextArea control to the linenumber of the referenced string.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+String|Strref -
+
+Return value: void
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/TextArea_SetHistory.txt b/gemrb/docs/en/GUIScript/TextArea_SetHistory.txt
new file mode 100644
index 0000000..c834a82
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/TextArea_SetHistory.txt
@@ -0,0 +1,16 @@
+
+Prototype: GemRB.SetTAHistory(Win, Ctrl, KeepLines)
+
+Metaclass Prototype:
+
+Description: Sets up a TextArea to expire scrolled out lines.
+
+Parameters:
+Win -
+Ctrl -
+KeepLines -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/TextEdit_ConvertEdit.txt b/gemrb/docs/en/GUIScript/TextEdit_ConvertEdit.txt
new file mode 100644
index 0000000..97cebcc
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/TextEdit_ConvertEdit.txt
@@ -0,0 +1,16 @@
+
+Prototype: GemRB.ConvertEdit(WindowIndex, ControlIndex, ScrollBarID)
+
+Metaclass Prototype:
+
+Description: Converts a simple Edit Control to a TextArea, keeping its ControlID.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+ScrollBarID -
+
+Return value: ControlIndex
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/TextEdit_SetBufferLength.txt b/gemrb/docs/en/GUIScript/TextEdit_SetBufferLength.txt
new file mode 100644
index 0000000..8f21b36
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/TextEdit_SetBufferLength.txt
@@ -0,0 +1,16 @@
+
+Prototype: GemRB.SetBufferLength(WindowIndex, ControlIndex, Length)
+
+Metaclass Prototype:
+
+Description: Sets the maximum text length of a TextEdit Control. It cannot be more than 65535.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+Length -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/UnmemorizeSpell.txt b/gemrb/docs/en/GUIScript/UnmemorizeSpell.txt
index 8cb391c..adde6c8 100644
--- a/gemrb/docs/en/GUIScript/UnmemorizeSpell.txt
+++ b/gemrb/docs/en/GUIScript/UnmemorizeSpell.txt
@@ -4,10 +4,11 @@ Prototype: GemRB.UnmemorizeSpell(PartyID, SpellType, Level, Index)
Description: Unmemorizes specified memorized spell.
Parameters:
-PartyID - the PC's position in the party
-SpellType - 0 - priest, 1 - wizard, 2 - innate
-Level - the memorized spell's level
-Index - the memorized spell's index
+PartyID - the PC's position in the party
+SpellType - 0 - priest, 1 - wizard, 2 - innate
+Level - the memorized spell's level
+Index - the memorized spell's index
+onlydepleted - remove only an already depleted spell with the same resref as the specified spell
Return value: boolean, 1 on success
diff --git a/gemrb/docs/en/GUIScript/VerbalConstant.txt b/gemrb/docs/en/GUIScript/VerbalConstant.txt
new file mode 100644
index 0000000..13ba7d6
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/VerbalConstant.txt
@@ -0,0 +1,15 @@
+
+Prototype: GemRB.VerbalConstant(PartyID, str)
+
+Metaclass Prototype:
+
+Description: Plays a Character's SoundSet entry.
+
+Parameters:
+PartyID -
+str -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Window_CreateButton.txt b/gemrb/docs/en/GUIScript/Window_CreateButton.txt
new file mode 100644
index 0000000..9cabf41
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Window_CreateButton.txt
@@ -0,0 +1,19 @@
+
+Prototype: GemRB.CreateButton(WindowIndex, ControlID, x, y, w, h)
+
+Metaclass Prototype:
+
+Description: Creates and adds a new Button to a Window.
+
+Parameters:
+WindowIndex -
+ControlID -
+x -
+y -
+w -
+h -
+
+Return value: ControlIndex
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Window_CreateLabel.txt b/gemrb/docs/en/GUIScript/Window_CreateLabel.txt
new file mode 100644
index 0000000..095097f
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Window_CreateLabel.txt
@@ -0,0 +1,22 @@
+
+Prototype: GemRB.CreateLabel(WindowIndex, ControlID, x, y, w, h, font, text, align)
+
+Metaclass Prototype:
+
+Description: Creates and adds a new Label to a Window.
+
+Parameters:
+WindowIndex -
+ControlID -
+x -
+y -
+w -
+h -
+font -
+text -
+align -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Window_CreateMapControl.txt b/gemrb/docs/en/GUIScript/Window_CreateMapControl.txt
new file mode 100644
index 0000000..d726df3
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Window_CreateMapControl.txt
@@ -0,0 +1,22 @@
+
+Prototype: GemRB.CreateMapControl(WindowIndex, ControlID, x, y, w, h, [LabelID, FlagResRef[, Flag2ResRef]])nnCreates and adds a new Area Map Control to a Window.nNote
+
+Metaclass Prototype:
+
+Description: LabelID is an ID, not an index. : If there are two flags given, they will be considered a BMP.
+
+Parameters:
+WindowIndex -
+ControlID -
+x -
+y -
+w -
+h -
+LabelID -
+FlagResRef -
+Flag2ResRef - (optional)
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Window_CreateScrollBar.txt b/gemrb/docs/en/GUIScript/Window_CreateScrollBar.txt
new file mode 100644
index 0000000..3f8123b
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Window_CreateScrollBar.txt
@@ -0,0 +1,19 @@
+
+Prototype: GemRB.CreateScrollBar(WindowIndex, ControlID, x, y, w, h)
+
+Metaclass Prototype:
+
+Description: Creates and adds a new ScrollBar to a Window.
+
+Parameters:
+WindowIndex -
+ControlID -
+x -
+y -
+w -
+h -
+
+Return value: ControlIndex
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Window_CreateTextEdit.txt b/gemrb/docs/en/GUIScript/Window_CreateTextEdit.txt
new file mode 100644
index 0000000..825d19d
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Window_CreateTextEdit.txt
@@ -0,0 +1,21 @@
+
+Prototype: GemRB.CreateTextEdit(WindowIndex, ControlID, x, y, w, h, font, text)
+
+Metaclass Prototype:
+
+Description: Creates and adds a new TextEdit to a Window.
+
+Parameters:
+WindowIndex -
+ControlID -
+x -
+y -
+w -
+h -
+font -
+text -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Window_CreateWorldMapControl.txt b/gemrb/docs/en/GUIScript/Window_CreateWorldMapControl.txt
new file mode 100644
index 0000000..7dd3516
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Window_CreateWorldMapControl.txt
@@ -0,0 +1,21 @@
+
+Prototype: GemRB.CreateWorldMapControl(WindowIndex, ControlID, x, y, w, h, direction[, font])
+
+Metaclass Prototype:
+
+Description: Creates and adds a new WorldMap control to a Window.
+
+Parameters:
+WindowIndex -
+ControlID -
+x -
+y -
+w -
+h -
+direction -
+font - (optional)
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Window_DeleteControl.txt b/gemrb/docs/en/GUIScript/Window_DeleteControl.txt
new file mode 100644
index 0000000..8feaf5e
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Window_DeleteControl.txt
@@ -0,0 +1,15 @@
+
+Prototype: GemRB.DeleteControl(WindowIndex, ControlID)
+
+Metaclass Prototype:
+
+Description: Deletes a control from a Window.
+
+Parameters:
+WindowIndex -
+ControlID -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Window_GetControl.txt b/gemrb/docs/en/GUIScript/Window_GetControl.txt
new file mode 100644
index 0000000..74e2423
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Window_GetControl.txt
@@ -0,0 +1,15 @@
+
+Prototype: GemRB.GetControlObject(WindowID, ControlID)
+
+Metaclass Prototype:
+
+Description: Returns a control as an object.
+
+Parameters:
+WindowID -
+ControlID -
+
+Return value: GControl, ornWindow.GetControl(ControlID)
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Window_HasControl.txt b/gemrb/docs/en/GUIScript/Window_HasControl.txt
new file mode 100644
index 0000000..d74a3dc
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Window_HasControl.txt
@@ -0,0 +1,16 @@
+
+Prototype: GemRB.HasControl(WindowIndex, ControlID[, ControlType])
+
+Metaclass Prototype:
+
+Description: Returns true if the control exists.
+
+Parameters:
+WindowIndex -
+ControlID -
+ControlType - (optional)
+
+Return value: bool
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Window_Invalidate.txt b/gemrb/docs/en/GUIScript/Window_Invalidate.txt
new file mode 100644
index 0000000..5de49a9
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Window_Invalidate.txt
@@ -0,0 +1,14 @@
+
+Prototype: GemRB.InvalidateWindow(WindowIndex)
+
+Metaclass Prototype:
+
+Description: Invalidates the given Window.
+
+Parameters:
+WindowIndex -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Window_SetFrame.txt b/gemrb/docs/en/GUIScript/Window_SetFrame.txt
new file mode 100644
index 0000000..a42e664
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Window_SetFrame.txt
@@ -0,0 +1,14 @@
+
+Prototype: GemRB.SetWindowFrame(WindowIndex)
+
+Metaclass Prototype:
+
+Description: Sets Window frame used to fill screen on higher resolutions.
+
+Parameters:
+WindowIndex -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Window_SetPicture.txt b/gemrb/docs/en/GUIScript/Window_SetPicture.txt
new file mode 100644
index 0000000..4720dfd
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Window_SetPicture.txt
@@ -0,0 +1,15 @@
+
+Prototype: GemRB.SetWindowPicture(WindowIndex, MosResRef)
+
+Metaclass Prototype:
+
+Description: Changes the background of a Window.
+
+Parameters:
+WindowIndex -
+MosResRef -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Window_SetPos.txt b/gemrb/docs/en/GUIScript/Window_SetPos.txt
new file mode 100644
index 0000000..183c798
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Window_SetPos.txt
@@ -0,0 +1,17 @@
+
+Prototype: GemRB.SetWindowPos(WindowIndex, X, Y, [Flags=WINDOW_TOPLEFT])nnMoves a Window to pos. (X, Y).nFlags is a bitmask of WINDOW_(TOPLEFT|CENTER|ABSCENTER|RELATIVE|SCALE|BOUNDED) and they are used to modify the meaning of X and Y.nTOPLEFT
+
+Metaclass Prototype:
+
+Description: X, Y are coordinates of upper-left corner.nCENTER: X, Y are coordinates of window's center.nABSCENTER: window is placed at screen center, moved by X, Y.nRELATIVE: window is moved by X, Y.nSCALE: window is moved by diff of screen size and X, Y, divided by 2.n : BOUNDED: the window is kept within screen boundaries.
+
+Parameters:
+WindowIndex -
+X -
+Y -
+[Flags=WINDOW_TOPLEFT - (optional)
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Window_SetSize.txt b/gemrb/docs/en/GUIScript/Window_SetSize.txt
new file mode 100644
index 0000000..73df153
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Window_SetSize.txt
@@ -0,0 +1,16 @@
+
+Prototype: GemRB.SetWindowSize(WindowIndex, Width, Height)
+
+Metaclass Prototype:
+
+Description: Resizes a Window.
+
+Parameters:
+WindowIndex -
+Width -
+Height -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Window_SetVisible.txt b/gemrb/docs/en/GUIScript/Window_SetVisible.txt
new file mode 100644
index 0000000..1a1adb2
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Window_SetVisible.txt
@@ -0,0 +1,15 @@
+
+Prototype: GemRB.SetVisible(WindowIndex, Visible)
+
+Metaclass Prototype:
+
+Description: Sets the Visibility Flag of a Window.
+
+Parameters:
+WindowIndex -
+Visible -
+
+Return value: bool
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Window_SetupControls.txt b/gemrb/docs/en/GUIScript/Window_SetupControls.txt
new file mode 100644
index 0000000..c2644e5
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Window_SetupControls.txt
@@ -0,0 +1,17 @@
+
+Prototype: GemRB.SetupControls(WindowIndex, dict, slot[, Start])nnAutomagically sets up the controls of the action window for a PC indexed by slot.n
+
+Metaclass Prototype:
+
+Description: If global is set, the actor will be looked up by its global ID instead of party slot.
+
+Parameters:
+WindowIndex -
+dict -
+slot -
+Start -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Window_SetupEquipmentIcons.txt b/gemrb/docs/en/GUIScript/Window_SetupEquipmentIcons.txt
new file mode 100644
index 0000000..6fdbea9
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Window_SetupEquipmentIcons.txt
@@ -0,0 +1,18 @@
+
+Prototype: GemRB.SetupEquipmentIcons(WindowIndex, dict, slot[, Start, Offset])nnAutomagically sets up the controls of the equipment list window for a PC indexed by globalID.nStart is the beginning of the visible part of the item list.nOffset is the ID of the first usable button.n
+
+Metaclass Prototype:
+
+Description: If global is set, the actor will be looked up by its global ID instead of party slot.
+
+Parameters:
+WindowIndex -
+dict -
+slot -
+Start -
+Offset -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Window_ShowModal.txt b/gemrb/docs/en/GUIScript/Window_ShowModal.txt
new file mode 100644
index 0000000..1fe325e
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Window_ShowModal.txt
@@ -0,0 +1,15 @@
+
+Prototype: GemRB.ShowModal(WindowIndex, [Shadow=MODAL_SHADOW_NONE])nnShow a Window on Screen setting the Modal Status. If Shadow is MODAL_SHADOW_GRAY, other windows are grayed.
+
+Metaclass Prototype:
+
+Description: If Shadow is MODAL_SHADOW_BLACK, they are blacked out.
+
+Parameters:
+WindowIndex -
+[Shadow=MODAL_SHADOW_NONE - (optional)
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/Window_Unload.txt b/gemrb/docs/en/GUIScript/Window_Unload.txt
new file mode 100644
index 0000000..4489ce5
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/Window_Unload.txt
@@ -0,0 +1,14 @@
+
+Prototype: GemRB.UnloadWindow(WindowIndex)
+
+Metaclass Prototype:
+
+Description: Unloads a previously Loaded Window.
+
+Parameters:
+WindowIndex -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/WorldMap_AdjustScrolling.txt b/gemrb/docs/en/GUIScript/WorldMap_AdjustScrolling.txt
new file mode 100644
index 0000000..2f9f5c5
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/WorldMap_AdjustScrolling.txt
@@ -0,0 +1,17 @@
+
+Prototype: GemRB.AdjustScrolling(WindowIndex, ControlIndex, x, y)
+
+Metaclass Prototype:
+
+Description: Sets the scrolling offset of a WorldMapControl.
+
+Parameters:
+WindowIndex -
+ControlIndex -
+x -
+y -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/WorldMap_GetDestinationArea.txt b/gemrb/docs/en/GUIScript/WorldMap_GetDestinationArea.txt
new file mode 100644
index 0000000..eb002b5
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/WorldMap_GetDestinationArea.txt
@@ -0,0 +1,16 @@
+
+Prototype: GemRB.GetDestinationArea(WindowIndex, ControlID[, RndEncounter])
+
+Metaclass Prototype:
+
+Description: If the random encounter flag is set, the random encounters will be evaluated too.
+
+Parameters:
+WindowIndex -
+ControlID -
+RndEncounter - (optional)
+
+Return value: WorldMap entrynnReturns the last area pointed on the worldmap.n
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/WorldMap_SetTextColor.txt b/gemrb/docs/en/GUIScript/WorldMap_SetTextColor.txt
new file mode 100644
index 0000000..fdaf0c6
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/WorldMap_SetTextColor.txt
@@ -0,0 +1,19 @@
+
+Prototype: GemRB.SetWorldMapTextColor(WindowIndex, ControlIndex, which, red, green, blue)nnSets the label colors of a WorldMap Control. WHICH selects color affected
+
+Metaclass Prototype:
+
+Description: and is one of IE_GUI_WMAP_COLOR_(BACKGROUND|NORMAL|SELECTED|NOTVISITED).
+
+Parameters:
+WindowIndex -
+ControlIndex -
+which -
+red -
+green -
+blue -
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/GUIScript/internal.txt b/gemrb/docs/en/GUIScript/internal.txt
new file mode 100644
index 0000000..bce8623
--- /dev/null
+++ b/gemrb/docs/en/GUIScript/internal.txt
@@ -0,0 +1,15 @@
+
+Prototype: GemRB.Internal module for GemRB metaclasses.
+
+This module is only for implementing GUIClass.py.
+
+Metaclass Prototype:
+
+Description: It's implemented in gemrb/plugins/GUIScript/GUIScript.cpp
+
+Parameters:
+
+Return value:
+
+See also:
+
diff --git a/gemrb/docs/en/Release.txt b/gemrb/docs/en/Release.txt
index 5f698bb..b0caab8 100644
--- a/gemrb/docs/en/Release.txt
+++ b/gemrb/docs/en/Release.txt
@@ -18,10 +18,11 @@ Preparing and testing GIT
* Tag current GIT to version number e.g. v0.9.0
i.e. in the gemrb root directory do
- git tag -a -m "GemRB 0.9.0" v0.9.0
- git push origin v0.9.0
+ ver=0.9.0
+ git tag -a -m "GemRB $ver" v$ver
+ git push origin v$ver
* Update from GIT to the tagged version
- git checkout v0.9.0
+ git checkout v$ver
* After you're done, update the version with a -git suffix, so it will be
easier to tell if people are running release builds or not
@@ -29,7 +30,7 @@ Preparing and testing GIT
Source release
==============
-* on Unix/Linux:
+* via cmake/autotools:
make dist
@@ -50,8 +51,14 @@ Linux binary release
Windows binary release
======================
-* FIXME: To be defined....
+If gembot is around on IRC, ask it to make a build for the tagged revision:
+ gembot: force build --revision=701453842c7cb5783 nmake-msvc++10 release build
+ gembot: watch nmake-msvc++10
+It will tell you where to see the report and on the last (upload) step,
+there will also be a link for the binary download. Rename it, upload
+it to the main sourceforge windows directory and mark it as default for
+the platform.
Release and Announcements
=========================
@@ -61,16 +68,15 @@ create them if there are structural or build related changes. New config
options should also be mentioned here if they're not part of the changelog.
* Put the tarballs/binaries into Releases on SF
- - create a new directory in the appropriate section by rightclicking
- - mark it for upload
- - upload the release notes
- - upload the file
- - mark the release notes as release notes (popup on leftclick)
- - mark the file to have the release notes and default platforms (popup on leftclick)
+ - go to the Files section
+ - click on the sources subdir
+ - add a new similarly-named folder
+ - use "add file" to upload the sources and release notes
+ - change the file properties to set the default platforms (under "view details")
* Test the downloads from sourceforge.net
-* Announce on homepage, SF, #GemRB in channel and title, Happypenguin and
+* Announce on homepage, SF, #GemRB in channel and title, Happypenguin, LGDB and
Gibberlings3:
- our forum
- modding news (Avenger, Theacefes, Grim Squeaker, DavidW and cmorgan have access)
diff --git a/gemrb/docs/en/Tables/avatars.txt b/gemrb/docs/en/Tables/avatars.txt
index de8e2af..ee4ed35 100644
--- a/gemrb/docs/en/Tables/avatars.txt
+++ b/gemrb/docs/en/Tables/avatars.txt
@@ -20,11 +20,11 @@ Columns: AT_1 - first armour level animation prefix
1 - The whole animation is in one file. Scheme is: [NAME][G1]. There are 16 orientations.
2 - The whole animation is in four files. Scheme is: [NAME][G1-2][/E].
3 - The whole animation is in two files. Scheme is: [NAME][G1][/E].
-4 - Many files (simular to 0), but all with G. Scheme is: [NAME][G][1-2][1-6].
-5 - ?
+4 - Many files (similar to 0), but all with G. Scheme is: [NAME][G][1-2][1-6].
+5 - Six files contain the whole animation. Scheme is:[NAME][G1-3][/E] (example: MOGR)
6 - BG2 style animation. Scheme is:[NAME][ACTIONCODE][/E]. The G1 code contains many sequences. (5 orientations).
7 - Bird animations, one file, only movement with orientations.
-8 - Six files contain the whole animation. Scheme is:[NAME][G1-3][/E]
+8 - Six files contain the whole animation. Scheme is:[NAME][G1-3][/E]. The sequences are different from 5. (example: MCAR)
9 - IWD style animation. Scheme is:[NAME][ACTIONTYPE][/E]. The main difference from 6 is that instead of G1, it has separate bams for many actions. (9 orientations).
10 - The whole animation is in two files [NAME][G1][/E]. Used for some low res static BG1 animations like the horse and cow. It lacks the walking animations of type 3.
11 - large 2x2 animations (wyvern and balor)
diff --git a/gemrb/docs/en/Tables/comment.txt b/gemrb/docs/en/Tables/comment.txt
new file mode 100644
index 0000000..bc271aa
--- /dev/null
+++ b/gemrb/docs/en/Tables/comment.txt
@@ -0,0 +1,7 @@
+Description: This table lists the association of verbal constants with area type flags.
+The order is important.
+
+
+AREAFLAG - the area flag bit (PST has special flags, otherwise the games are pretty much the same)
+VC - the verbal constant associated with the area flag
+SWITCH - marks the day/night bit, if it is set to 1, then there are different messages for day and night
diff --git a/gemrb/docs/en/Tables/fonts.txt b/gemrb/docs/en/Tables/fonts.txt
index 4e2b730..fa05d32 100644
--- a/gemrb/docs/en/Tables/fonts.txt
+++ b/gemrb/docs/en/Tables/fonts.txt
@@ -1,13 +1,23 @@
Description: This table lists fonts. Only fonts listed here could be used as a font resource.
+Note: the font system is described in depth on the wiki: http://gemrb.sourceforge.net/wiki/doku.php?id=plugins:ttf
+
Columns: RESREF - the .bam ResRef of the font
NEED_PALETTE - if the font has no own palette, set this to 1
- FIRST_CHAR - usually 0, it contains the first printable character of the font.
+ FIRST_CHAR - usually 33 (33 = ! in ASCII), it contains the first printable character of the font as an ASCII value.
+ LAST_CHAR - the last printable character of the font as an (extended) ASCII value.
+
+Note: the following columns are used primarily for non-BAM fonts.
+
+ FONT_NAME - used to map a non-BAM font to a BAM ResRef.
+ PT_SIZE - the pt size of the font.
+ STYLE - a numeric value representing: normal, bold, italic, underline.
+ COLOR - RGBA hexadecimal representation to use for coloring the font.
Rows: <rowcount> - make sure the 9. font is a 'normal' font. Used for floating texts. (this is a hacked legacy feature, it may go away).
Example (BG2):
- RESREF NEED_PALETTE FIRST_CHAR
-0 NORMAL 1 0
-1 NUMBER 0 47
-2 INITIALS 0 0
+ RESREF NEED_PALETTE FIRST_CHAR LAST_CHAR FONT_NAME PT_SIZE STYLE COLOR
+0 NORMAL 1 33 255 NORMAL 14 0 0xffffffff
+1 NUMBER 0 48 57 NUMBER 14 0 0xffffffff
+2 INITIALS 0 33 255 myFont 18 1 0x999999ff
diff --git a/gemrb/docs/en/Tables/item_use.txt b/gemrb/docs/en/Tables/item_use.txt
index 5a96e86..0ef22ac 100644
--- a/gemrb/docs/en/Tables/item_use.txt
+++ b/gemrb/docs/en/Tables/item_use.txt
@@ -3,5 +3,9 @@ Description: This table lists special items that won't be dropped by certain act
Columns:
USER - the scripting name of the playable character
STRREF - the displayed string
-
+FLAGS - usability bitfield
+ 1 - named actor cannot remove it
+ 2 - anyone else cannot equip it
+ 4 - can only swap it for something else
+
Rows: Item resrefs
diff --git a/gemrb/docs/en/Tables/proftype.txt b/gemrb/docs/en/Tables/proftype.txt
new file mode 100644
index 0000000..69b75cc
--- /dev/null
+++ b/gemrb/docs/en/Tables/proftype.txt
@@ -0,0 +1,6 @@
+Description: This table contains itemtype->weapon proficiency mapping.
+
+Columns -
+PROFICIENCY - the weapon proficiency index (not a stat number).
+
+Rows - item types, make sure it is continuous from zero.
diff --git a/gemrb/docs/en/Tables/stances.txt b/gemrb/docs/en/Tables/stances.txt
new file mode 100644
index 0000000..fbf24c6
--- /dev/null
+++ b/gemrb/docs/en/Tables/stances.txt
@@ -0,0 +1,12 @@
+Description: Using this table you can override the animations for certain stances for specific avatars.
+
+Columns:
+STANCE - the stance ID to override
+OVERRIDE - the stance ID to use instead
+
+Rows:
+Each row can be used to override one stance for one animation. If you need to override multiple stances for the same animations, add one row for each override.
+
+Example:
+(Kobold from BG1 - don't use ATTACK_JAB because that animation is for SHOOT)
+0x8200 13 12
diff --git a/gemrb/docs/en/Tables/storespl.txt b/gemrb/docs/en/Tables/storespl.txt
new file mode 100644
index 0000000..dd1f1c3
--- /dev/null
+++ b/gemrb/docs/en/Tables/storespl.txt
@@ -0,0 +1,6 @@
+Description: This table contains the spell casting sound of temple spells (different from their completion sound).
+
+Columns -
+SOUND - the spell casting sound
+
+Rows - one for each spell
diff --git a/gemrb/docs/en/Tables/textscrn.txt b/gemrb/docs/en/Tables/textscrn.txt
new file mode 100644
index 0000000..5c9b90b
--- /dev/null
+++ b/gemrb/docs/en/Tables/textscrn.txt
@@ -0,0 +1,12 @@
+Description: This table defines various attributes of text screens used in the games.
+
+Columns:
+WINDOW - window ID from the GUICHAP pack
+MUSIC - music to play
+STRING - string to display on the console
+
+Rows:
+Each row describes one textscreen 2da file.
+
+Example (BG1):
+CHPTXT1 1 CHAPTER 17556
diff --git a/gemrb/docs/en/default_ini.txt b/gemrb/docs/en/default_ini.txt
new file mode 100644
index 0000000..2ce27d0
--- /dev/null
+++ b/gemrb/docs/en/default_ini.txt
@@ -0,0 +1,50 @@
+ENCODING SPECIFICATION - DEFAULT.INI, POLISH.INI, CZECH.INI, ...
+****************************************************************
+
+GemRB needs information about encoding used in game data (specifically, in
+DIALOG.TLK and DIALOGF.TLK) to properly lowercase and uppercase strings,
+which is used in button labels. Encoding files define pairs of
+uppercase code, lowercase code.
+
+Naming
+------
+
+default.ini is standard encoding for all western language-games.
+polish.ini is encoding used for polish version of BG1.
+czec.ini is effectively the same as default.ini.
+
+To use e.g. polish.ini encoding, specify "Encoding=polish" in GemRB.cfg.
+Default is default.ini.
+
+Format
+------
+
+File format is INI file. All information is now in [charset] section.
+Each uppercase-lowercase pair is specified as
+
+ LetterX = UUU,LLL
+
+where X is counter starting from 1, UUU is decimal code of the uppercase
+and LLL is decimal code for the lowercase. For example,
+
+ Letter9 = 195,227 # A~
+
+specifies A-with-tilde.
+
+Number of letter pairs is given by CharCount, e.g,
+
+ CharCount = 35
+
+
+Example
+-------
+
+[charset]
+CharCount = 35
+
+Letter1 = 138,154 # Sv
+Letter2 = 140,156 # OE
+...
+Letter35 = 222,254 # Thorn
+
+
diff --git a/gemrb/docs/en/gemrb_ini.txt b/gemrb/docs/en/gemrb_ini.txt
index a1a1a9d..387b2c4 100644
--- a/gemrb/docs/en/gemrb_ini.txt
+++ b/gemrb/docs/en/gemrb_ini.txt
@@ -18,6 +18,13 @@ specific to GemRB and which are not intended to be usually changed by
a user. More complicated configuration data (tables, etc.) are kept in
their own files. User specific configuration is in other file (GemRB.cfg).
+Options that do not deal strictly with data availability and diversity
+may be freely changed. Some that may be interesting to users include:
+AutoSearchHidden, BreakableWeapons, DeathOnZeroStat,
+HasSpecificDamageBonus (mod required), HasWisdomBonusTable (mod required),
+HealOn100Plus, KnowWorld, ProperBackstab, SelectiveMagicRes, StealIsAttack
+ and TeamMovement.
+
[FIXME: eventually, this file could be searched for in user's config directory too]
This file's path can be
@@ -129,11 +136,10 @@ Each pixel line in these files is for one base color. Pixels in the
row then define the gradient of that color.
-IgnoreButtonFrames = <bool>
-- - - - - - - - - - - - - -
-If set to 1, buttons will ignore frame numbers as set in button CHU
-resource, and always use frames 0, 1, 2, 3 from their associated
-BAM. (PST, ...)
+3EdRules = <bool>
+- - - - - - - - -
+Toggles whether the game (data) is using the 3rd edition rules. Blindly
+toggling it will do no good!
AllStringsTagged = <bool>
@@ -142,22 +148,138 @@ If set to 1, .tlk tokens are always resolved regardless of the token
flag in dialog.tlk. Normally only BG2 has token flags (0), all other
games have this option set to 1.
-HasDPLAYER = <bool>
-- - - - - - - - - -
-If set to 1, then NPCs will get a default player script (DPLAYER2) set
-when they join the party. PST has no such feature.
-HasPickSound = <bool>
+AreaVisitedVar = <bool>
+- - - - - - - - - - - -
+Toggles whether also AREANAME_visited variables are set when an actor
+enters an area. Used in the IWD scripts and worldmaps.
+
+
+AreaOverride = <bool>
- - - - - - - - - - -
-If set to 1, items have a pick up sound resource reference instead of a
-description icon. PST has this option. (Mutually exclusive with the
-HasDescIcon option).
+Toggles use of area customisation scripts. Used to implement the PST
+random modron mazes.
+
+
+AutomapINI = <bool>
+- - - - - - - - - -
+If set to 1, automap entries will be done PST style.
+
+
+AutoSearchHidden = <bool>
+- - - - - - - - - - - - -
+Toggles whether character automatically search for hidden doors.
+
+
+BiographyIsRes = <bool>
+- - - - - - - - - - - -
+Toggles whether to expect the biography extension as "res" or "bio".
+
+
+BreakableWeapons = <bool>
+- - - - - - - - - - - -
+Determines if weapons can randomly break when used (1% chance in bg1).
+
+
+CastingSounds = <bool>
+- - - - - - - - - - - -
+Toggles whether the game supports casting sounds.
+
+
+ChallengeRating = <bool>
+- - - - - - - - - - - - -
+Toggles whether the game supports challenge ratings. Affects experience
+gains.
+
+
+CharNameIsGabber = <bool>
+- - - - - - - - - - - - -
+Toggles whether Player1 is treated as a protagonist, talker, gabber in
+dialogs and interactions.
+
+
+CheckAbilities = <bool>
+- - - - - - - - - - -
+Determines if character abilities should matter in item usability checks.
+
+
+ClearUnusedArea = <bool>
+- - - - - - - - - - -
+Determines whether some fields in ARE files that are not used in all of
+the games should be cleared on load. If you don't do this in BG1, for
+example, those unitialized values in the data files will cause errors.
+
+
+CutsceneAreascripts = <bool>
+- - - - - - - - - -
+Determines whether area scripts should run during cutscenes or not.
+
+
+DeathOnZeroStat = <bool>
+- - - - - - - - - - -
+Determines whether characters should die if any of their primary stats
+reaches zero.
+
+
+DialogueScrolls = <bool>
+- - - - - - - - - - - - -
+If set to 1, dialogue window behaves as in PS:T - i.e. talk between
+Nameless One and others is appended into the window as it comes. If set to
+0 (default) each new pair of NPC's talk and Nameless One's replies is
+written from the start of the page, like in BG2.
+
+
+EnhancedCastingSounds = <bool>
+- - - - - - - - - - - - - - - -
+Toggles whether the game supports enhanced casting sounds (bg2).
+
+
+EnhancedEffects = <bool>
+- - - - - - - - - - - - -
+Toggles whether the game supports enhanced effects (iwd2). This has to
+do with the data (EFF version), so do not change it on a whim.
+
+
+FistStat = <number>
+- - - - - - - - -
+Which stat determines the fist weapon (defaults to IE_CLASS).
+
+
+ForceAreaScript = <bool>
+- - - - - - - - - - - - -
+Toggle always running area scripts, even in dialog.
+
+
+ForceStereo = <bool>
+- - - - - - - - - - -
+If set to 1, all acm files will be player as if they are stereo.
+Some early .ACM files (PST, IWD1) were encoded with a faulty channel
+number, this option overrides the channel number.
+
+
+FlexibleWorldmap = <bool>
+- - - - - - - - - - - - -
+Toggles whether the game supports worldmap extensions.
+
+
+HasBeastsINI = <bool>
+- - - - - - - - - - -
+Whether original game data contains beasts.ini and quests.ini files
+with descriptions of monsters and quests (PST only).
+
HasDescIcon = <bool>
- - - - - - - - - - -
If set to 1, items have a description icon, instead of a pick up sound.
BG2 has this option. (Mutually exclusive with the HasPickSound option).
+
+HasDPLAYER = <bool>
+- - - - - - - - - -
+If set to 1, then NPCs will get a default player script (DPLAYER2) set
+when they join the party. PST has no such feature.
+
+
HasEXPTABLE = <bool>
- - - - - - - - - - -
If set to 1, then an exptable.2da file is responsible of storing quest
@@ -166,10 +288,48 @@ will use xplist.2da table for a similar feature. AddXP2da and AddXPVar
scripting actions use this option to determine which .2da file to use.
XPList is bg2 specific, while exptable is an iwd2 feature.
-SoundFolders = <bool>
+
+HasFloatMenu = <bool>
- - - - - - - - - - -
-If set to 1, then there are separate directories for each player
-character soundset. IWD2 specific.
+Used for the PST float menu implementation. Not portable without extra
+guiscript work.
+
+
+HasHideInShadows = <bool>
+- - - - - - - - - - - -
+Enable this if the characters also have the IE_HIDEINSHADOWS stat besides
+IE_STEALTH.
+
+
+HasKaputz = <bool>
+- - - - - - - - - -
+If set to 1, then death variables will be in a separate context.
+This is PST specific.
+
+
+HasNoNPCFlag = <bool>
+- - - - - - - - - - -
+Detail about how infopoints react when used (all except iwd2).
+
+
+HasPartyINI = <bool>
+- - - - - - - - - - -
+If set to 1, then there is a party.ini file describing pre-generated
+parties. Normally only IWD2 has this option set.
+
+
+HasPickSound = <bool>
+- - - - - - - - - - -
+If set to 1, items have a pick up sound resource reference instead of a
+description icon. PST has this option. (Mutually exclusive with the
+HasDescIcon option).
+
+
+HasResDataIni = <bool>
+- - - - - - - - - - - -
+Determines whether the game stores some sounds in separate resource
+INI files and where they are ("resdata").
+
HasSongList = <bool>
- - - - - - - - - - -
@@ -178,35 +338,115 @@ Otherwise the music files are listed in a music.2da file. Original
BG1 and PST doesn't have either of these files (the list is hardcoded
into the engine), GemRB supplies a music.2da file for them.
-UpperButtonText = <bool>
+
+HasSoundsIni = <bool>
+- - - - - - - - - - -
+Determines whether the game stores some sounds in separate resource
+INI files and where they are ("sounds").
+
+
+HasSpecificDamageBonus = <bool>
+- - - - - - - - - - - - - - -
+Determines if the game supports specific damage bonus like for example +10%
+extra cold damage.
+
+
+HasSpellList = <bool>
+- - - - - - - - - - -
+Toggles whether the game has separate spell lists. Used in iwd2 for the
+wider selection of spell books/types.
+
+
+HasUsePointFlag = <bool>
- - - - - - - - - - - - -
-Set to 1 if button labels should be converted to upper-case (e.g. BG2)
+Detail about how infopoints react when used (iwd2).
+
+
+HasWisdomBonusTable = <bool>
+- - - - - - - - - - - - - - -
+Toggles whether the game has a wisxpbon.2da that dictates a bonus or malus
+to gained experience according to the actor's wisdom (pst).
+
+
+IgnoreButtonFrames = <bool>
+- - - - - - - - - - - - - -
+If set to 1, buttons will ignore frame numbers as set in button CHU
+resource, and always use frames 0, 1, 2, 3 from their associated
+BAM. (PST, ...)
+
+
+ImplicitAreaAnimBackground = <bool>
+- - - - - - - - - - - - - -
+If set to 1, area animations will have a different renderering order.
+This is used to fix some animations in the IWD line of games
+
+
+InPartyAllowsDead = <bool>
+- - - - - - - - - - - - - -
+If set to 0, the InParty() trigger will always return 0 for dead
+PCs.
+
+
+IWD2DeathVarFormat = <bool>
+- - - - - - - - - - - - - -
+Toggles whether the game uses the IWD2 death var format ("_DEAD%s").
+
+
+IWDMapDimensions = <bool>
+- - - - - - - - - - - - -
+If set to 1, then the minimap dimensions are using the IWD specific ratio.
+
+
+IWD2ScriptName = <bool>
+- - - - - - - - - - - -
+If set to 1, then areas always override the scripting name of the creature.
+Normally there is an area flag for this.
+
+
+JournalHasSections = <bool>
+- - - - - - - - - - - - - -
+Toggles whether the journal is split in multiple sections ala BG2.
+
+
+KnowWorld = <bool>
+- - - - - - - - - -
+Determines whether the worldmap is already fully explored at the start.
+All areas are marked as visited.
+
+
+LevelslotPerClass = <bool>
+- - - - - - - - - - - - - -
+Toggles whether the game expects separate stats for class levels. All but
+IWD2 have to share only 3.
LowerLabelText = <bool>
- - - - - - - - - - - -
Set to 1 if label text should be converted to lower-case.
-HasPartyINI = <bool>
-- - - - - - - - - - -
-If set to 1, then there is a party.ini file describing pre-generated
-parties. Normally only IWD2 has this option set.
-HasBeastsINI = <bool>
-- - - - - - - - - - -
-Whether original game data contains beasts.ini and quests.ini files
-with descriptions of monsters and quests (PST only).
+MagicBit = <bool>
+- - - - - - - - -
+Toggles whether the magic item bit is used for marking items as
+undroppable (iwd2 - yes).
-ForceStereo = <bool>
-- - - - - - - - - - -
-If set to 1, all acm files will be player as if they are stereo.
-Some early .ACM files (PST, IWD1) were encoded with a faulty channel
-number, this option overrides the channel number.
-TeamMovement = <bool>
-- - - - - - - - - - -
-If set to 1, the team always moves to the protagonist (first player).
-This option is 1 for original PST.
+MaximumAbility = 25|40
+- - - - - - - - - - - -
+Determines the maximum value of character abilities. Setting it to absurd
+values might cause problems. Its value should be 40 for IWD2, 25 for all
+other games.
+
+
+NoDropCanMove = <bool>
+- - - - - - - - - - - -
+Toggles whether undroppable items can be moved around.
+
+
+NoNewVariables = <bool>
+- - - - - - - - - - - -
+Toggles whether the engine can create new variables in the Game structure.
+
OneByteAnimationID = <bool>
- - - - - - - - - - - - - -
@@ -218,105 +458,112 @@ are also controlled by this flag. One such example is the avatar icon
size in the saved games. If set to 1, then the avatar portrait won't be
shrunk further. Otherwise the saved portrait bmp's will be shrunk 2:1.
-AutomapINI = <bool>
-- - - - - - - - - -
-If set to 1, automap entries will be done PST style.
-SmallFog = <bool>
+OnScreenText = <bool>
- - - - - - - - - - -
-Whether fog-of-war maintained in Map::ExploredBitmap is aligned with
-map boundary (SmallFog=1, like in PST) or the fog is half a tile
-larger in each of four cardinal directions (SmallFog=0, e.g. in BG2)
+Toggles whether the game displays text on the game area instead of the
+message window (pst).
-ReverseDoor = <bool>
+
+ProperBackstab = <bool>
- - - - - - - - - - -
-If set to 1, doors will have a reversed open/closed state. PST quirk.
+Determines how many checks the backstabbing code does before treating an
+attack as a backstab.
+
ProtagonistTalks = <bool>
- - - - - - - - - - - - -
If set to 1, only protagonist speaks with stranger for the whole party (PST).
-HasKaputz = <bool>
-- - - - - - - - - -
-If set to 1, then death variables will be in a separate context.
-This is PST specific.
-
-IWDMapDimensions = <bool>
-- - - - - - - - - - - - -
-If set to 1, then the minimap dimensions are using the IWD specific ratio.
-IWD2ScriptName = <bool>
+PSTStateFlags = <bool>
- - - - - - - - - - - -
-If set to 1, then areas always override the scripting name of the creature.
-Normally there is an area flag for this.
+Toggles whether to interpret state flags like PST. For example, the
+invisibility state flag is different there.
-DialogueScrolls = <bool>
+
+RedrawTile = <bool>
+- - - - - - - - -
+Force redraw of some overlay tiles??
+
+
+RareActionSounds = <bool>
- - - - - - - - - - - - -
-If set to 1, dialogue window behaves as in PS:T - i.e. talk between
-Nameless One and others is appended into the window as it comes. If set to
-0 (default) each new pair of NPC's talk and Nameless One's replies is
-written from the start of the page, like in BG2.
+Toggles whether to use all the available verbal constants or not.
-MaximumAbility = 25|40
-- - - - - - - - - - - -
-Determines the maximum value of character abilities. Setting it to absurd
-values might cause problems. Its value should be 40 for IWD2, 25 for all
-other games.
-StrrefSaveGame = 0|1
+ReverseDoor = <bool>
- - - - - - - - - - -
-Determines whether the GameScript action SaveGame uses the int0 paramater
-to lookup a strref, or to look in savegame.2da for the save game name.
+If set to 1, doors will have a reversed open/closed state. PST quirk.
+
-ReverseToHit = 0|1
+ReverseToHit = <bool>
- - - - - - - - - -
Determines whether higher armor class is better (iwd2) or worse (the rest).
-RedrawTile = 0|1
-- - - - - - - - -
-Force redraw of some overlay tiles??
-CheckAbilities = 0|1
-- - - - - - - - - - -
-Determines if character abilities should matter in item usability checks.
+SaveForHalfDamage = <bool>
+- - - - - - - - - - - - -
+Toggles whether actors can save for half damage even when spells are not
+set up that way traditionally. Used in PST via the resource effect field.
+
-SpellBookIconHack = 0|1
+SelectiveMagicRes = <bool>
- - - - - - - - - - - -
-Enables the spell book icon name hack needed for ToB.
+Determines whether the magic resistance applies to all effects, even the
+beneficial ones.
-DeathOnZeroStat = 0|1
-- - - - - - - - - - -
-Determines whether characters should die if any of their primary stats
-reaches zero.
-BreakableWeapons = 0|1
+SkipUpdateHack = <bool>
- - - - - - - - - - - -
-Determines if weapons can randomly break when used (1% chance in bg1).
+Determines how the engine treats a very specific script continuation nuance.
-SelectiveMagicRes = 0|1
-- - - - - - - - - - - -
-Determines whether the magic resistance applies to all effects, even the
-beneficial ones.
-HasHideInShadows = 0|1
+SmallFog = <bool>
+- - - - - - - - - - -
+Whether fog-of-war maintained in Map::ExploredBitmap is aligned with
+map boundary (SmallFog=1, like in PST) or the fog is half a tile
+larger in each of four cardinal directions (SmallFog=0, e.g. in BG2)
+
+
+SoundFolders = <bool>
+- - - - - - - - - - -
+If set to 1, then there are separate directories for each player
+character soundset. IWD2 specific.
+
+
+SpawnIni = <bool>
+- - - - - - - - -
+Determines whether the game stores spawns in external INI files.
+
+
+SpellBookIconHack = <bool>
- - - - - - - - - - - -
-Enable this if the characters also have the IE_HIDEINSHADOWS stat besides
-IE_STEALTH.
+Enables the spell book icon name hack needed for ToB.
+
-ProperBackstab = 0|1
+StartActive = <bool>
- - - - - - - - - - -
-Determines how many checks the backstabbing code does before treating an
-attack as a backstab.
+Toggles whether actors start active (script activated) or not.
-HasSpecificDamageBonus = 0|1
-- - - - - - - - - - - - - - -
-Determines if the game supports specific damage bonus like for example +10%
-extra cold damage.
-StealIsAttack = 0|1
+StealIsAttack = <bool>
- - - - - - - - - -
Determines whether a detected stealing attempt causes the shopkeep to turn hostile.
-CutsceneAreascripts = 0|1
-- - - - - - - - - -
-Determines whether area scripts should run during cutscenes or not.
+
+StrrefSaveGame = <bool>
+- - - - - - - - - - -
+Determines whether the GameScript action SaveGame uses the int0 paramater
+to lookup a strref, or to look in savegame.2da for the save game name.
+
+
+TeamMovement = <bool>
+- - - - - - - - - - -
+If set to 1, the team always moves to the protagonist (first player).
+This option is 1 for original PST.
+
+
+UpperButtonText = <bool>
+- - - - - - - - - - - - -
+Set to 1 if button labels should be converted to upper-case (e.g. BG2)
diff --git a/gemrb/includes/CocoaWrapper.h b/gemrb/includes/CocoaWrapper.h
new file mode 100644
index 0000000..5a3c6a3
--- /dev/null
+++ b/gemrb/includes/CocoaWrapper.h
@@ -0,0 +1,65 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifdef GCC_VERSION
+#if GCC_VERSION < 40200
+#warning You may need to disable wanings as errors or unused warnings to compile on this system.
+#undef __unused
+#define __unused
+#endif
+#endif
+
+/*
+ !!!:
+ Because this file is shared between the CocoaWrapper object and plugins extending it we need to keep it
+ in the gemrb/includes directory.
+*/
+#if __cplusplus
+extern "C" {
+#define COCOA_EXPORT extern "C" __attribute__ ((visibility("default")))
+#else
+#define COCOA_EXPORT __attribute__ ((visibility("default")))
+#endif
+
+#import <Cocoa/Cocoa.h>
+
+COCOA_EXPORT
+ at interface CocoaWrapper : NSObject
+#ifdef __AVAILABILITY_INTERNAL__MAC_10_0_DEP__MAC_10_6
+<NSApplicationDelegate>
+#endif
+{
+ NSWindow* _configWindow;
+
+ BOOL _showConfigWindow;
+}
+ at property(nonatomic, retain) IBOutlet NSWindow* configWindow;
+
+// Override these application delegate methods in plugin categories
+- (void)applicationWillTerminate:(NSNotification *)aNotification;
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
+
+- (IBAction)openGame:(id)sender;
+- (IBAction)launchGame:(id)sender;
+ at end
+
+#if __cplusplus
+} // Extern C
+#endif
diff --git a/gemrb/includes/HashMap.h b/gemrb/includes/HashMap.h
new file mode 100644
index 0000000..f8d0e45
--- /dev/null
+++ b/gemrb/includes/HashMap.h
@@ -0,0 +1,459 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef HASHMAP_H
+#define HASHMAP_H
+
+#include <cassert>
+#include <cstring>
+#include <deque>
+
+#include "System/Logging.h"
+
+namespace GemRB {
+
+// dumps stats upon destruction
+//#define HASHMAP_DEBUG
+
+template<typename T>
+struct HashKey {
+ static inline unsigned int hash(const T &key);
+ static inline bool equals(const T &a, const T &b);
+ static inline void copy(T &a, const T &b);
+};
+
+#define HASHMAP_DEFINE_TRIVIAL_HASHKEY(T) \
+ template<> \
+ inline unsigned int HashKey<T>::hash(const T &key) \
+ { \
+ return static_cast<unsigned int>(key); \
+ } \
+ template<> \
+ inline bool HashKey<T>::equals(const T &a, const T &b) \
+ { \
+ return a == b; \
+ } \
+ template<> \
+ inline void HashKey<T>::copy(T &a, const T &b) \
+ { \
+ a = b; \
+ }
+
+// MSVC6 is convinced that this the same as char[1] from StringMap.h
+//HASHMAP_DEFINE_TRIVIAL_HASHKEY(char);
+//HASHMAP_DEFINE_TRIVIAL_HASHKEY(signed char);
+//HASHMAP_DEFINE_TRIVIAL_HASHKEY(unsigned char);
+
+HASHMAP_DEFINE_TRIVIAL_HASHKEY(short)
+HASHMAP_DEFINE_TRIVIAL_HASHKEY(unsigned short)
+HASHMAP_DEFINE_TRIVIAL_HASHKEY(int)
+HASHMAP_DEFINE_TRIVIAL_HASHKEY(unsigned int)
+HASHMAP_DEFINE_TRIVIAL_HASHKEY(long)
+HASHMAP_DEFINE_TRIVIAL_HASHKEY(unsigned long)
+
+#undef HASHMAP_DEFINE_TRIVIAL_HASHKEY
+
+template<typename Key, typename Value, typename Hash = HashKey<Key> >
+class HashMap {
+public:
+ HashMap();
+ ~HashMap();
+
+ void init(unsigned int tableSize, unsigned int blockSize);
+
+ // sets a value and returns true if an existing entry has been replaced
+ bool set(const Key &key, const Value &value);
+ const Value *get(const Key &key) const;
+ bool has(const Key &key) const;
+
+ bool remove(const Key &key);
+ void clear();
+
+protected:
+ struct Entry {
+ Key key;
+ Value value;
+ Entry *next;
+ };
+
+ inline bool isInitialized() const;
+
+ inline Entry *popAvailable();
+ inline void pushAvailable(Entry *e);
+ inline unsigned int getMapPosByHash(unsigned int hash) const;
+ inline unsigned int getMapPosByKey(const Key &key) const;
+ inline Entry *getBucketByHash(unsigned int hash) const;
+ inline Entry *getBucketByKey(const Key &key) const;
+
+ // walks from e and looks for key. if a match is found, its in
+ // result->next, else result is the end of the list.
+ inline Entry *findPredecessor(const Key &key, Entry *e) const;
+ // just for stats, usable by derived classes
+ inline void incAccesses() const;
+
+private:
+ unsigned int _tableSize;
+ unsigned int _blockSize;
+ std::deque<Entry *> _blocks;
+ Entry **_buckets;
+ Entry *_available;
+
+ void allocBlock();
+
+#ifdef HASHMAP_DEBUG
+ struct Debug {
+ unsigned int allocs;
+ unsigned int accesses;
+ };
+
+ mutable Debug _debug;
+public:
+ void dumpStats(const char* description);
+#endif
+};
+
+template<typename Key, typename Value, typename HashKey>
+HashMap<Key, Value, HashKey>::HashMap() :
+ _tableSize(0),
+ _blockSize(0),
+ _blocks(),
+ _buckets(NULL),
+ _available(NULL)
+{
+#ifdef HASHMAP_DEBUG
+ memset(&_debug, 0, sizeof(_debug));
+#endif
+}
+
+template<typename Key, typename Value, typename HashKey>
+HashMap<Key, Value, HashKey>::~HashMap()
+{
+ clear();
+}
+
+template<typename Key, typename Value, typename HashKey>
+void HashMap<Key, Value, HashKey>::init(unsigned int tableSize, unsigned int blockSize)
+{
+ clear();
+
+ if (tableSize < 1)
+ return;
+
+ _tableSize = tableSize;
+ if (_tableSize < 16)
+ _tableSize = 16;
+
+ // even sucks for distribution
+ _tableSize |= 1u;
+
+ _blockSize = blockSize;
+ if (_blockSize < 4)
+ _blockSize = 4;
+
+ _buckets = new Entry *[_tableSize];
+
+ memset(_buckets, 0, sizeof(Entry *) * _tableSize);
+
+#ifdef HASHMAP_DEBUG
+ memset(&_debug, 0, sizeof(_debug));
+#endif
+}
+
+template<typename Key, typename Value, typename Hash>
+bool HashMap<Key, Value, Hash>::set(const Key &key, const Value &value)
+{
+ if (!isInitialized())
+ error("HashMap", "Not initialized\n");
+
+ unsigned int p = getMapPosByKey(key);
+ Entry *e;
+
+ // set as root if empty
+ if (!_buckets[p]) {
+ e = popAvailable();
+ Hash::copy(e->key, key);
+ e->value = value;
+
+ _buckets[p] = e;
+
+ return false;
+ }
+
+ e = _buckets[p];
+
+ // check root
+ if (Hash::equals(e->key, key)) {
+ e->value = value;
+ return true;
+ }
+
+ // walk list
+ e = findPredecessor(key, e);
+ Entry *hit = e->next;
+
+ // replace match
+ if (hit) {
+ hit->value = value;
+ return true;
+ }
+
+ // append new
+ hit = popAvailable();
+ Hash::copy(hit->key, key);
+ hit->value = value;
+ e->next = hit;
+
+ return false;
+}
+
+template<typename Key, typename Value, typename Hash>
+const Value *HashMap<Key, Value, Hash>::get(const Key &key) const
+{
+ if (!isInitialized())
+ return NULL;
+
+ incAccesses();
+
+ for (Entry *e = getBucketByKey(key); e; e = e->next)
+ if (Hash::equals(e->key, key))
+ return &e->value;
+
+ return NULL;
+}
+
+template<typename Key, typename Value, typename Hash>
+bool HashMap<Key, Value, Hash>::has(const Key &key) const
+{
+ return get(key) != NULL;
+}
+
+template<typename Key, typename Value, typename Hash>
+inline bool HashMap<Key, Value, Hash>::remove(const Key &key)
+{
+ if (!isInitialized())
+ return false;
+
+ unsigned int p = getMapPosByKey(key);
+ Entry *e = _buckets[p];
+
+ if (!e)
+ return false;
+
+ // check root
+ if (Hash::equals(e->key, key)) {
+ _buckets[p] = e->next;
+ pushAvailable(e);
+
+ return true;
+ }
+
+ // walk the list
+ e = findPredecessor(key, e);
+ Entry *hit = e->next;
+
+ if (!hit)
+ return false;
+
+ e->next = hit->next;
+ pushAvailable(hit);
+
+ return true;
+}
+
+template<typename Key, typename Value, typename Hash>
+void HashMap<Key, Value, Hash>::clear()
+{
+ if (!isInitialized())
+ return;
+
+#ifdef HASHMAP_DEBUG
+ dumpStats();
+#endif
+
+ _available = NULL;
+
+ delete[] _buckets;
+ _buckets = NULL;
+
+ while (!_blocks.empty()) {
+ delete[] _blocks.front();
+ _blocks.pop_front();
+ }
+}
+
+template<typename Key, typename Value, typename Hash>
+bool inline HashMap<Key, Value, Hash>::isInitialized() const
+{
+ return _buckets != NULL;
+}
+
+template<typename Key, typename Value, typename Hash>
+inline typename HashMap<Key, Value, Hash>::Entry *HashMap<Key, Value, Hash>::popAvailable()
+{
+ if (!_available)
+ allocBlock();
+
+ Entry *e = _available;
+ _available = e->next;
+
+ e->next = NULL;
+
+ return e;
+}
+
+template<typename Key, typename Value, typename Hash>
+inline void HashMap<Key, Value, Hash>::pushAvailable(Entry *e) {
+ e->next = _available;
+ _available = e;
+}
+
+template<typename Key, typename Value, typename Hash>
+inline unsigned int HashMap<Key, Value, Hash>::getMapPosByHash(unsigned int hash) const
+{
+ return hash % _tableSize;
+}
+
+template<typename Key, typename Value, typename Hash>
+inline unsigned int HashMap<Key, Value, Hash>::getMapPosByKey(const Key &key) const
+{
+ return getMapPosByHash(Hash::hash(key));
+}
+
+template<typename Key, typename Value, typename Hash>
+inline typename HashMap<Key, Value, Hash>::Entry *HashMap<Key, Value, Hash>::getBucketByHash(unsigned int hash) const
+{
+ return _buckets[getMapPosByHash(hash)];
+}
+
+template<typename Key, typename Value, typename Hash>
+inline typename HashMap<Key, Value, Hash>::Entry *HashMap<Key, Value, Hash>::getBucketByKey(const Key &key) const
+{
+ return _buckets[getMapPosByKey(key)];
+}
+
+template<typename Key, typename Value, typename Hash>
+inline typename HashMap<Key, Value, Hash>::Entry *HashMap<Key, Value, Hash>::findPredecessor(const Key &key, Entry *e) const
+{
+ for (; e->next; e = e->next)
+ if (Hash::equals(e->next->key, key))
+ break;
+
+ return e;
+}
+
+template<typename Key, typename Value, typename Hash>
+inline void HashMap<Key, Value, Hash>::incAccesses() const
+{
+#ifdef HASHMAP_DEBUG
+ _debug.accesses++;
+#endif
+}
+
+template<typename Key, typename Value, typename Hash>
+void HashMap<Key, Value, Hash>::allocBlock()
+{
+ Entry *block = new Entry[_blockSize];
+
+ _blocks.push_back(block);
+
+ for (unsigned int i = 0; i < _blockSize; ++i)
+ pushAvailable(block++);
+
+#ifdef HASHMAP_DEBUG
+ _debug.allocs++;
+#endif
+}
+
+#ifdef HASHMAP_DEBUG
+template<typename Key, typename Value, typename Hash>
+void HashMap<Key, Value, Hash>::dumpStats(const char* description)
+{
+ if (!isInitialized())
+ return;
+
+ unsigned int entries = 0;
+ unsigned int collisions = 0;
+ unsigned int empty = 0;
+ unsigned int eq1 = 0;
+ unsigned int eq2 = 0;
+ unsigned int gt2 = 0;
+ unsigned int gt4 = 0;
+ unsigned int gt8 = 0;
+ unsigned int largest = 0;
+
+ Entry **b = _buckets;
+ for (unsigned int i = 0; i < _tableSize; ++i, ++b) {
+ if (!(*b)) {
+ empty++;
+ continue;
+ }
+
+ unsigned int c = 0;
+ for (Entry *e = *b; e; c++, entries++, e = e->next)
+ ;
+
+ if (c > 8)
+ gt8++;
+ else if (c > 4)
+ gt4++;
+ else if (c > 2)
+ gt2++;
+ else if (c > 1)
+ eq2++;
+ else
+ eq1++;
+
+ if (c > 1)
+ collisions += c;
+
+ if (c > largest)
+ largest++;
+ }
+
+ unsigned int bytes = sizeof(*this) +
+ _tableSize * sizeof(Entry *) +
+ _blocks.size() * sizeof(Entry) * _blockSize;
+
+ Log(DEBUG, "HashMap", "stats for %s:\n"
+ "size\t\t%u\n"
+ "allocs\t\t%u\n"
+ "accesses\t%u\n"
+ "entries\t\t%u\n"
+ "collisions\t%u\n"
+ "empty buckets\t%u\n"
+ "=1 buckets\t%u\n"
+ "=2 buckets\t%u\n"
+ ">2 buckets\t%u\n"
+ ">4 buckets\t%u\n"
+ ">8 buckets\t%u\n"
+ "largest bucket\t%u\n"
+ "memsize\t\t%ukb\n",
+ description,
+ _tableSize, _debug.allocs, _debug.accesses,
+ entries, collisions, empty, eq1, eq2, gt2,
+ gt4, gt8, largest, bytes / 1024);
+
+ memset(&_debug, 0, sizeof(_debug));
+}
+#endif
+
+}
+
+#endif
diff --git a/gemrb/includes/RGBAColor.h b/gemrb/includes/RGBAColor.h
index 1f520d0..87e7707 100644
--- a/gemrb/includes/RGBAColor.h
+++ b/gemrb/includes/RGBAColor.h
@@ -20,12 +20,20 @@
#ifndef RGBACOLOR_H
#define RGBACOLOR_H
+namespace GemRB {
+
struct RevColor {
unsigned char b,g,r,a;
};
struct Color {
unsigned char r,g,b,a;
-};
+}
+#ifdef __GNUC__
+ __attribute__((aligned(4)))
+#endif
+ ;
+
+}
#endif
diff --git a/gemrb/includes/SClassID.h b/gemrb/includes/SClassID.h
index b82d71c..03681d8 100644
--- a/gemrb/includes/SClassID.h
+++ b/gemrb/includes/SClassID.h
@@ -28,6 +28,8 @@
#ifndef SCLASS_ID_H
#define SCLASS_ID_H
+namespace GemRB {
+
/** Type of plugin ID numbers */
typedef unsigned long SClass_ID;
@@ -75,15 +77,22 @@ typedef unsigned long SClass_ID;
#define IE_SCRIPT_CLASS_ID 0x000D0000
#define IE_GUI_SCRIPT_CLASS_ID 0x000E0000
+// !!! Update the PLUGIN_BASE_VERSION, if the list below is reordered !!!
+// !!! or entries inserted in the middle. !!!
+const unsigned long PLUGIN_BASE_VERSION = 0x1000 * 0xABCE;
typedef unsigned long PluginID;
enum {
- PLUGIN_OPCODES_CORE = 0xABCD0001,
+ PLUGIN_OPCODES_CORE = PLUGIN_BASE_VERSION+1,
PLUGIN_OPCODES_ICEWIND,
PLUGIN_OPCODES_TORMENT,
PLUGIN_RESOURCE_KEY,
PLUGIN_RESOURCE_DIRECTORY,
+ PLUGIN_RESOURCE_CACHEDDIRECTORY,
+ PLUGIN_RESOURCE_NULL,
PLUGIN_IMAGE_WRITER_BMP,
- PLUGIN_COMPRESSION_ZLIB
+ PLUGIN_COMPRESSION_ZLIB
};
+}
+
#endif
diff --git a/gemrb/includes/StringMap.h b/gemrb/includes/StringMap.h
new file mode 100644
index 0000000..044d8fa
--- /dev/null
+++ b/gemrb/includes/StringMap.h
@@ -0,0 +1,131 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef STRINGMAP_H
+#define STRINGMAP_H
+
+#include <string>
+
+#include "ie_types.h"
+
+#include "System/String.h"
+#include "HashMap.h"
+
+namespace GemRB {
+
+// Use "StringMap" for mapping std::strings to std::strings.
+// This does not limit the length of either the keys nor values, but at the
+// cost of (re)allocs for each string.
+//
+// Use HashMap<char[size], ...> to use fixed-sized char arrays as keys.
+// This has the advantage that HashMap will alloc the char array as part of
+// its blocks.
+
+template<>
+struct HashKey<std::string> {
+ // hash without std::string construction
+ static inline unsigned int hash(const char *key)
+ {
+ unsigned int h = 0;
+
+ while (*key)
+ h = (h << 5) + h + tolower(*key++);
+
+ return h;
+ }
+
+ static inline unsigned int hash(const std::string &key)
+ {
+ return hash(key.c_str());
+ }
+
+ // equal check without std::string construction
+ static inline bool equals(const std::string &a, const char *b)
+ {
+ return stricmp(a.c_str(), b) == 0;
+ }
+
+ static inline bool equals(const std::string &a, const std::string &b)
+ {
+ return equals(a, b.c_str());
+ }
+
+ static inline void copy(std::string &a, const std::string &b)
+ {
+ a = b;
+ }
+};
+
+class StringMap : public HashMap<std::string, std::string> {
+public:
+ // lookup without std::string construction
+ const std::string *get(const char *key) const
+ {
+ if (!isInitialized())
+ return NULL;
+
+ incAccesses();
+
+ for (Entry *e = getBucketByHash(HashKey<std::string>::hash(key)); e; e = e->next)
+ if (HashKey<std::string>::equals(e->key, key))
+ return &e->value;
+
+ return NULL;
+ }
+
+ // lookup without std::string construction
+ bool has(const char *key) const
+ {
+ return get(key) != NULL;
+ }
+};
+
+// disabled, msvc6 hates it
+#if 0
+template<unsigned int size>
+struct HashKey<char[size]> {
+ typedef char array[size];
+
+ static inline unsigned int hash(const array &key)
+ {
+ unsigned int h = 0;
+ const char *c = key;
+
+ for (unsigned int i = 0; *c && i < size; ++i)
+ h = (h << 5) + h + tolower(*c++);
+
+ return h;
+ }
+
+ static inline bool equals(const array &a, const array &b)
+ {
+ return strnicmp(a, b, size) == 0;
+ }
+
+ static inline void copy(array &a, const array &b)
+ {
+ strncpy(a, b, size);
+ }
+};
+#endif
+
+}
+
+#endif
diff --git a/gemrb/includes/defsounds.h b/gemrb/includes/defsounds.h
index 7ce8dc0..5abc6c6 100644
--- a/gemrb/includes/defsounds.h
+++ b/gemrb/includes/defsounds.h
@@ -28,6 +28,8 @@
#ifndef IE_SOUNDS_H
#define IE_SOUNDS_H
+namespace GemRB {
+
#define DS_OPEN 0
#define DS_CLOSE 1
#define DS_HOPEN 2
@@ -39,11 +41,23 @@
#define DS_CLOSE_FAIL 8
#define DS_ITEM_GONE 9
#define DS_FOUNDSECRET 10
+#define DS_PICKLOCK 11
+#define DS_PICKFAIL 12
#define DS_RAIN 20
#define DS_SNOW 21
#define DS_LIGHTNING1 22
#define DS_LIGHTNING2 23
#define DS_LIGHTNING3 24
+#define DS_SOLD 25
+#define DS_STOLEN 26
+#define DS_DRUNK 27
+#define DS_DONATE1 28
+#define DS_DONATE2 29
+#define DS_IDENTIFY 30
+#define DS_GOTXP 31
+#define DS_TOOLTIP 32
+
+}
#endif //! IE_SOUNDS_H
diff --git a/gemrb/includes/errors.h b/gemrb/includes/errors.h
index 92e8f3e..723744a 100644
--- a/gemrb/includes/errors.h
+++ b/gemrb/includes/errors.h
@@ -20,8 +20,12 @@
#ifndef ERRORS_H
#define ERRORS_H
+namespace GemRB {
+
#define GEM_OK 0
#define GEM_ERROR -1
#define GEM_EOF -2
+}
+
#endif
diff --git a/gemrb/includes/exports.h b/gemrb/includes/exports.h
index 0faa7f1..932d6ab 100644
--- a/gemrb/includes/exports.h
+++ b/gemrb/includes/exports.h
@@ -21,6 +21,15 @@
#ifndef EXPORTS_H
#define EXPORTS_H
+/**
+ * @file exports.h
+ * This file contains global compiler configuration.
+ *
+ * It should not contain any declarations or includes,
+ * only compiler dependent macros and pragmas.
+ */
+
+/// Symbol visibility macros
#ifdef WIN32
# ifdef GEM_BUILD_DLL
# define GEM_EXPORT __declspec(dllexport)
@@ -38,11 +47,39 @@
#endif
#ifndef GEM_EXPORT
-#define GEM_EXPORT
+# define GEM_EXPORT
#endif
#ifndef GEM_EXPORT_DLL
-#define GEM_EXPORT_DLL extern "C"
+# define GEM_EXPORT_DLL extern "C"
+#endif
+
+/// Semantic Warning Macros
+#ifdef __GNUC__
+# define WARN_UNUSED __attribute__ ((warn_unused_result))
+# define SENTINEL __attribute__ ((sentinel))
+#else
+# define WARN_UNUSED
+# define SENTINEL
+#endif
+
+/// Disable silly MSVC warnings
+#if _MSC_VER >= 1000
+// 4251 disables the annoying warning about missing dll interface in templates
+# pragma warning( disable: 4251 521 )
+# pragma warning( disable: 4275 )
+// disables annoying warning caused by STL:Map in msvc 6.0
+# if _MSC_VER < 7000
+# pragma warning(disable:4786)
+# endif
+// disables warnings about posix functions
+# define _CRT_NONSTDC_NO_DEPRECATE 1
+#endif
+
+/// Make sure we don't like to static libraries
+/// This causes hard to debug errors due to multiple heaps.
+#if defined(_MSC_VER) && !defined(_DLL)
+# error GemRB must be dynamically linked with runtime libraries on win32.
#endif
#endif
diff --git a/gemrb/includes/globals.h b/gemrb/includes/globals.h
index aa2689f..19aa2fd 100644
--- a/gemrb/includes/globals.h
+++ b/gemrb/includes/globals.h
@@ -34,7 +34,7 @@
#include "ie_types.h"
-#define VERSION_GEMRB "0.6.4"
+#define VERSION_GEMRB "0.8.0"
#define GEMRB_STRING "GemRB v" VERSION_GEMRB
@@ -52,16 +52,20 @@
#include "errors.h"
#include "win32def.h"
-#include "AnimStructures.h"
-#include "System/DataStream.h"
#include "Region.h"
-#include "Sprite2D.h"
+#include "System/DataStream.h"
+#include "System/String.h"
#include <cstdio>
#include <cstdlib>
+#ifndef WIN32
+# include <sys/time.h>
+#endif
#endif //GLOBALS_ONLY_DEFS
+namespace GemRB {
+
//Global Variables
#define IE_NORMAL 0
@@ -82,10 +86,6 @@
#define BM_XOR 3
#define BM_NAND 4 //gemrb extension
-//IDS Importer Defines
-#define IDS_VALUE_NOT_LOCATED -65535 // GetValue returns this if text is not found in arrays ... this needs to be a unique number that does not exist in the value[] array
-#define GEM_ENCRYPTION_KEY "\x88\xa8\x8f\xba\x8a\xd3\xb9\xf5\xed\xb1\xcf\xea\xaa\xe4\xb5\xfb\xeb\x82\xf9\x90\xca\xc9\xb5\xe7\xdc\x8e\xb7\xac\xee\xf7\xe0\xca\x8e\xea\xca\x80\xce\xc5\xad\xb7\xc4\xd0\x84\x93\xd5\xf0\xeb\xc8\xb4\x9d\xcc\xaf\xa5\x95\xba\x99\x87\xd2\x9d\xe3\x91\xba\x90\xca"
-
/////feature flags
#define GF_HAS_KAPUTZ 0 //pst
#define GF_ALL_STRINGS_TAGGED 1 //bg1, pst, iwd1
@@ -149,8 +149,22 @@
#define GF_FORCE_AREA_SCRIPT 59 //how and iwd2 (maybe iwd1)
#define GF_AREA_OVERRIDE 60 //pst maze and other hardcode
#define GF_NO_NEW_VARIABLES 61 //pst
+#define GF_SOUNDS_INI 62 //iwd/how/iwd2
+#define GF_USEPOINT_400 63 //all except pst and iwd2
+#define GF_USEPOINT_200 64 //iwd2
+#define GF_HAS_FLOAT_MENU 65 //pst
+#define GF_RARE_ACTION_VB 66 //pst
+#define GF_NO_UNDROPPABLE 67 //iwd,how
+#define GF_START_ACTIVE 68 //bg1
+#define GF_CLEAR_UNUSED_AREA 69 //bg1
+#define GF_IMPLICIT_AREAANIM_BACKGROUND 70 //idw,how,iwd2
+#define GF_HEAL_ON_100PLUS 71 //bg1, bg2, pst
+#define GF_IN_PARTY_ALLOWS_DEAD 72 //all except bg2
+#define GF_ZERO_TIMER_IS_VALID 73 // how, not bg2, other unknown
+#define GF_SKIPUPDATE_HACK 74 // how, not bg2
+
//update this or bad things can happen
-#define GF_COUNT 62
+#define GF_COUNT 75
//the number of item usage fields (used in CREItem and STOItem)
#define CHARGE_COUNTERS 3
@@ -166,17 +180,6 @@
class Scriptable;
class Actor;
-/* this function will work with pl/cz special characters */
-
-extern unsigned char pl_uppercase[256];
-extern unsigned char pl_lowercase[256];
-
-GEM_EXPORT void strnlwrcpy(char* d, const char *s, int l);
-GEM_EXPORT void strnuprcpy(char* d, const char *s, int l);
-GEM_EXPORT void strnspccpy(char* d, const char *s, int l);
-#ifndef HAVE_STRNLEN
-GEM_EXPORT int strnlen(const char* string, int maxlen);
-#endif
GEM_EXPORT unsigned char GetOrient(const Point &s, const Point &d);
GEM_EXPORT unsigned int Distance(const Point pos, const Point pos2);
GEM_EXPORT unsigned int Distance(const Point pos, Scriptable *b);
@@ -189,29 +192,20 @@ GEM_EXPORT unsigned int PersonalDistance(Scriptable *a, Scriptable *b);
GEM_EXPORT unsigned int SquaredPersonalDistance(Scriptable *a, Scriptable *b);
GEM_EXPORT unsigned int SquaredMapDistance(Scriptable *a, Scriptable *b);
GEM_EXPORT int EARelation(Scriptable *a, Actor *b);
-GEM_EXPORT bool dir_exists(const char* path);
-GEM_EXPORT int strlench(const char* string, char ch);
-#ifndef HAVE_STRNDUP
-GEM_EXPORT char* strndup(const char* s, size_t l);
-#endif
+GEM_EXPORT void CopyResRef(ieResRef d, const ieResRef s);
-#ifndef WIN32
-GEM_EXPORT char* strupr(char* string);
-GEM_EXPORT char* strlwr(char* string);
-#endif
-#ifdef WIN32
-#define GetTime(store) store = GetTickCount()
-#else
-#include <sys/time.h>
-#define GetTime(store) \
- { \
- struct timeval tv; \
- gettimeofday(&tv, NULL); \
- store = (tv.tv_usec/1000) + (tv.tv_sec*1000); \
- }
+#ifndef WIN32
+inline unsigned long GetTickCount()
+{
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return (tv.tv_usec/1000) + (tv.tv_sec*1000);
+}
#endif
+#ifndef __APPLE__
+// MIN and MAX are already similarly defined by Cocoa
inline int MIN(int a, int b)
{
return (a > b ? b : a);
@@ -221,6 +215,7 @@ inline int MAX(int a, int b)
{
return (a < b ? b : a);
}
+#endif
inline bool valid_number(const char* string, long& val)
{
@@ -237,5 +232,8 @@ inline bool valid_number(const char* string, long& val)
//the maximum supported game CD count
#define MAX_CD 6
+}
+
#endif //! GLOBALS_H
+
diff --git a/gemrb/includes/ie_cursors.h b/gemrb/includes/ie_cursors.h
new file mode 100644
index 0000000..45c741c
--- /dev/null
+++ b/gemrb/includes/ie_cursors.h
@@ -0,0 +1,42 @@
+// IE specific cursor types
+#ifndef IE_CURSORS_H
+#define IE_CURSORS_H
+
+namespace GemRB {
+
+#define IE_CURSOR_INVALID -1
+#define IE_CURSOR_NORMAL 0
+#define IE_CURSOR_TAKE 2 //over pile type containers
+#define IE_CURSOR_WALK 4
+#define IE_CURSOR_BLOCKED 6
+#define IE_CURSOR_USE 8 //never hardcoded
+#define IE_CURSOR_WAIT 10 //hourglass
+#define IE_CURSOR_ATTACK 12
+#define IE_CURSOR_SWAP 14 //dragging portraits
+#define IE_CURSOR_DEFEND 16
+#define IE_CURSOR_TALK 18
+#define IE_CURSOR_CAST 20 //targeting with non weapon
+#define IE_CURSOR_INFO 22 //never hardcoded
+#define IE_CURSOR_LOCK 24 //locked door
+#define IE_CURSOR_LOCK2 26 //locked container
+#define IE_CURSOR_STAIR 28 //never hardcoded
+#define IE_CURSOR_DOOR 30 //doors
+#define IE_CURSOR_CHEST 32
+#define IE_CURSOR_TRAVEL 34
+#define IE_CURSOR_STEALTH 36
+#define IE_CURSOR_TRAP 38
+#define IE_CURSOR_PICK 40 //pickpocket
+#define IE_CURSOR_PASS 42 //never hardcoded
+#define IE_CURSOR_GRAB 44
+#define IE_CURSOR_WAY 46 //waypoint (not in PST)
+#define IE_CURSOR_INFO2 46 //PST
+#define IE_CURSOR_PORTAL 48 //PST
+#define IE_CURSOR_STAIR2 50 //PST
+#define IE_CURSOR_EXTRA 52 //PST
+
+#define IE_CURSOR_MASK 127
+#define IE_CURSOR_GRAY 128
+
+}
+
+#endif // ! IE_CURSORS_H
diff --git a/gemrb/includes/ie_feats.h b/gemrb/includes/ie_feats.h
index e30f384..a7c8d29 100644
--- a/gemrb/includes/ie_feats.h
+++ b/gemrb/includes/ie_feats.h
@@ -17,78 +17,83 @@
*
*
*/
-#define FEAT_AEGIS_OF_RIME 0
-#define FEAT_AMBIDEXTERITY 1
-#define FEAT_AQUA_MORTIS 2
-#define FEAT_ARMORED_ARCANA 3
-#define FEAT_ARMOUR_PROFICIENCY 4
-#define FEAT_ARTERIAL_STRIKE 5
-#define FEAT_BLIND_FIGHT 6
-#define FEAT_BULLHEADED 7
-#define FEAT_CLEAVE 8
-#define FEAT_COMBAT_CASTING 9
-#define FEAT_COURTEOUS_MAGOCRACY 10
-#define FEAT_CRIPPLING_STRIKE 11
-#define FEAT_DASH 12
-#define FEAT_DEFLECT_ARROWS 13
-#define FEAT_DIRTY_FIGHTING 14
-#define FEAT_DISCIPLINE 15
-#define FEAT_DODGE 16
-#define FEAT_ENVENOM_WEAPON 17
-#define FEAT_EXOTIC_BASTARD 18
-#define FEAT_EXPERTISE 19
-#define FEAT_EXTRA_RAGE 20
-#define FEAT_EXTRA_SHAPESHIFTING 21
-#define FEAT_EXTRA_SMITING 22
-#define FEAT_EXTRA_TURNING 23
-#define FEAT_FIENDSLAYER 24
-#define FEAT_FORESTER 25
-#define FEAT_GREAT_FORTITUDE 26
-#define FEAT_HAMSTRING 27
-#define FEAT_HERETICS_BANE 28
-#define FEAT_HEROIC_INSPIRATION 29
-#define FEAT_IMPROVED_CRITICAL 30
-#define FEAT_IMPROVED_EVASION 31
-#define FEAT_IMPROVED_INITIATIVE 32
-#define FEAT_IMPROVED_TURNING 33
-#define FEAT_IRON_WILL 34
-#define FEAT_LIGHTNING_REFLEXES 35
-#define FEAT_LINGERING_SONG 36
-#define FEAT_LUCK_OF_HEROES 37
-#define FEAT_MARTIAL_AXE 38
-#define FEAT_MARTIAL_BOW 39
-#define FEAT_MARTIAL_FLAIL 40
-#define FEAT_MARTIAL_GREATSWORD 41
-#define FEAT_MARTIAL_HAMMER 42
-#define FEAT_MARTIAL_LARGESWORD 43
-#define FEAT_MARTIAL_POLEARM 44
-#define FEAT_MAXIMIZED_ATTACKS 45
-#define FEAT_MERCANTILE_BACKGROUND 46
-#define FEAT_POWER_ATTACK 47
-#define FEAT_PRECISE_SHOT 48
-#define FEAT_RAPID_SHOT 49
-#define FEAT_RESIST_POISON 50
-#define FEAT_SCION_OF_STORMS 51
-#define FEAT_SHIELD_PROF 52
-#define FEAT_SIMPLE_CROSSBOW 53
-#define FEAT_SIMPLE_MACE 54
-#define FEAT_SIMPLE_MISSILE 55
-#define FEAT_SIMPLE_QUARTERSTAFF 56
-#define FEAT_SIMPLE_SMALLBLADE 57
-#define FEAT_SLIPPERY_MIND 58
-#define FEAT_SNAKE_BLOOD 59
-#define FEAT_SPELL_FOCUS_ENCHANTMENT 60
-#define FEAT_SPELL_FOCUS_EVOCATION 61
-#define FEAT_SPELL_FOCUS_NECROMANCY 62
-#define FEAT_SPELL_FOCUS_TRANSMUTE 63
-#define FEAT_SPELL_PENETRATION 64
-#define FEAT_SPIRIT_OF_FLAME 65
-#define FEAT_STRONG_BACK 66
-#define FEAT_STUNNING_FIST 67
-#define FEAT_SUBVOCAL_CASTING 68
-#define FEAT_TOUGHNESS 69
-#define FEAT_TWO_WEAPON_FIGHTING 70
-#define FEAT_WEAPON_FINESSE 71
-#define FEAT_WILDSHAPE_BOAR 72
-#define FEAT_WILDSHAPE_PANTHER 73
-#define FEAT_WILDSHAPE_SHAMBLER 74
+
+namespace GemRB {
+
+#define FEAT_AEGIS_OF_RIME 0
+#define FEAT_AMBIDEXTERITY 1
+#define FEAT_AQUA_MORTIS 2
+#define FEAT_ARMOUR_PROFICIENCY 3
+#define FEAT_ARMORED_ARCANA 4
+#define FEAT_ARTERIAL_STRIKE 5
+#define FEAT_BLIND_FIGHT 6
+#define FEAT_BULLHEADED 7
+#define FEAT_CLEAVE 8
+#define FEAT_COMBAT_CASTING 9
+#define FEAT_COURTEOUS_MAGOCRACY 10
+#define FEAT_CRIPPLING_STRIKE 11
+#define FEAT_DASH 12
+#define FEAT_DEFLECT_ARROWS 13
+#define FEAT_DIRTY_FIGHTING 14
+#define FEAT_DISCIPLINE 15
+#define FEAT_DODGE 16
+#define FEAT_ENVENOM_WEAPON 17
+#define FEAT_EXOTIC_BASTARD 18
+#define FEAT_EXPERTISE 19
+#define FEAT_EXTRA_RAGE 20
+#define FEAT_EXTRA_SHAPESHIFTING 21
+#define FEAT_EXTRA_SMITING 22
+#define FEAT_EXTRA_TURNING 23
+#define FEAT_FIENDSLAYER 24
+#define FEAT_FORESTER 25
+#define FEAT_GREAT_FORTITUDE 26
+#define FEAT_HAMSTRING 27
+#define FEAT_HERETICS_BANE 28
+#define FEAT_HEROIC_INSPIRATION 29
+#define FEAT_IMPROVED_CRITICAL 30
+#define FEAT_IMPROVED_EVASION 31
+#define FEAT_IMPROVED_INITIATIVE 32
+#define FEAT_IMPROVED_TURNING 33
+#define FEAT_IRON_WILL 34
+#define FEAT_LIGHTNING_REFLEXES 35
+#define FEAT_LINGERING_SONG 36
+#define FEAT_LUCK_OF_HEROES 37
+#define FEAT_MARTIAL_AXE 38
+#define FEAT_MARTIAL_BOW 39
+#define FEAT_MARTIAL_FLAIL 40
+#define FEAT_MARTIAL_GREATSWORD 41
+#define FEAT_MARTIAL_HAMMER 42
+#define FEAT_MARTIAL_LARGESWORD 43
+#define FEAT_MARTIAL_POLEARM 44
+#define FEAT_MAXIMIZED_ATTACKS 45
+#define FEAT_MERCANTILE_BACKGROUND 46
+#define FEAT_POWER_ATTACK 47
+#define FEAT_PRECISE_SHOT 48
+#define FEAT_RAPID_SHOT 49
+#define FEAT_RESIST_POISON 50
+#define FEAT_SCION_OF_STORMS 51
+#define FEAT_SHIELD_PROF 52
+#define FEAT_SIMPLE_CROSSBOW 53
+#define FEAT_SIMPLE_MACE 54
+#define FEAT_SIMPLE_MISSILE 55
+#define FEAT_SIMPLE_QUARTERSTAFF 56
+#define FEAT_SIMPLE_SMALLBLADE 57
+#define FEAT_SLIPPERY_MIND 58
+#define FEAT_SNAKE_BLOOD 59
+#define FEAT_SPELL_FOCUS_ENCHANTMENT 60
+#define FEAT_SPELL_FOCUS_EVOCATION 61
+#define FEAT_SPELL_FOCUS_NECROMANCY 62
+#define FEAT_SPELL_FOCUS_TRANSMUTE 63
+#define FEAT_SPELL_PENETRATION 64
+#define FEAT_SPIRIT_OF_FLAME 65
+#define FEAT_STRONG_BACK 66
+#define FEAT_STUNNING_FIST 67
+#define FEAT_SUBVOCAL_CASTING 68
+#define FEAT_TOUGHNESS 69
+#define FEAT_TWO_WEAPON_FIGHTING 70
+#define FEAT_WEAPON_FINESSE 71
+#define FEAT_WILDSHAPE_BOAR 72
+#define FEAT_WILDSHAPE_PANTHER 73
+#define FEAT_WILDSHAPE_SHAMBLER 74
+
+}
diff --git a/gemrb/includes/ie_stats.h b/gemrb/includes/ie_stats.h
index fa61ca1..aded14c 100644
--- a/gemrb/includes/ie_stats.h
+++ b/gemrb/includes/ie_stats.h
@@ -30,6 +30,8 @@
#ifndef IE_STATS_H
#define IE_STATS_H
+namespace GemRB {
+
//EA values
#define EA_INANIMATE 1
#define EA_PC 2
@@ -70,6 +72,7 @@
#define SEX_SUMMON 6
#define SEX_ILLUSION 7 // bg2
#define SEX_EXTRA 8 // bg2
+#define SEX_SUMMON_DEMON 9 //bg2
#define SEX_EXTRA2 0xa // ToB
#define SEX_MAXEXTRA 0x12 // ToB (extra10)
@@ -139,9 +142,9 @@
#define STATE_EMBALM 0x40000000
#define STATE_CONFUSED 0x80000000
-#define STATE_STILL (STATE_STUNNED | STATE_FROZEN | STATE_PETRIFIED) //not animated
+#define STATE_STILL (STATE_STUNNED | STATE_FROZEN | STATE_PETRIFIED) //0xc8: not animated
-#define STATE_CANTMOVE 0x80180fef
+#define STATE_CANTMOVE 0x180fef //can't walk or attack - confused characters can do these
#define STATE_CANTLISTEN 0x80080fef
#define STATE_CANTSTEAL 0x00180fc0 //can't steal from
#define STATE_CANTSEE 0x00080fc0 //can't explore (even itself)
@@ -190,11 +193,13 @@
#define MC_FALLEN_PALADIN 0x0200
#define MC_FALLEN_RANGER 0x0400
#define MC_EXPORTABLE 0x0800
-#define MC_HIDE_HP 0x1000
-#define MC_PLOT_CRITICAL 0x2000 //if dies, it means game over
+#define MC_HIDE_HP 0x1000 //also 'large creature' according to IE dev info
+#define MC_PLOT_CRITICAL 0x2000 //if dies, it means game over (IWD2)
+#define MC_LARGE_CREATURE 0x2000 //creature is subject to alternative melee damage - semi invulnerability (BG2)
+#define MC_LIMBO_CREATURE 0x4000
#define MC_BEENINPARTY 0x8000
-#define MC_HIDDEN 0x10000 //iwd
-
+#define MC_SEENPARTY 0x10000 //iwd2
+#define MC_INVULNERABLE 0x20000 //iwd2
#define MC_NO_TALK 0x80000 //ignore dialoginterrupt
//stats
@@ -341,6 +346,7 @@
#define IE_PROFICIENCYSLING 107
#define IE_PROFICIENCYBLACKJACK 108
#define IE_PROFICIENCYGUN 109
+#define IE_UNDEADLEVEL 109 //if i calculated correctly, this is the 21th byte in the profs array
#define IE_PROFICIENCYMARTIALARTS 110
#define IE_PROFICIENCY2HANDED 111
#define IE_PROFICIENCYSWORDANDSHIELD 112
@@ -388,7 +394,7 @@
#define IE_PUPPETID 141
#define IE_CHECKFORBERSERK 142
#define IE_BERSERKSTAGE1 143
-#define IE_BERSERKSTAGE2 144
+#define IE_BERSERKSTAGE2 144 //attack anyone
#define IE_DAMAGELUCK 145
#define IE_CRITICALHITBONUS 146
#define IE_VISUALRANGE 147
@@ -494,7 +500,8 @@
#define IE_TEAM 220
#define IE_FACTION 221
#define IE_SUBRACE 222
-#define IE_SPECIES 223
+#define IE_SPECIES 223 // pst specific
+#define IE_UNUSED_SKILLPTS 223 // iwd2 specific
//temporarily here for iwd2
#define IE_HATEDRACE2 224
#define IE_HATEDRACE3 225
@@ -521,11 +528,12 @@
#define IE_LEVELMONK 244
#define IE_LEVELPALADIN 245
#define IE_LEVELRANGER 246
-#define IE_LEVELSORCEROR 247
+#define IE_LEVELSORCERER 247
// place for 2 more classes
#define IE_LEVELCLASS12 248
#define IE_LEVELCLASS13 249
// these are iwd2 spell states, iwd2 uses ~180, we have place for 192
+// TODO: consider dropping these (move them to class variable) if unused by guiscript
#define IE_SPLSTATE_ID1 250
#define IE_SPLSTATE_ID2 251
#define IE_SPLSTATE_ID3 252
@@ -533,4 +541,6 @@
#define IE_SPLSTATE_ID5 254
#define IE_SPLSTATE_ID6 255
+}
+
#endif // ! IE_STATS_H
diff --git a/gemrb/includes/ie_types.h b/gemrb/includes/ie_types.h
index 23cbac7..1965b4a 100644
--- a/gemrb/includes/ie_types.h
+++ b/gemrb/includes/ie_types.h
@@ -32,6 +32,8 @@
#include <config.h>
#endif
+namespace GemRB {
+
//we need this for Windows and Android
#if defined (WIN32) || defined (ANDROID)
#define SIZEOF_INT 4
@@ -66,5 +68,6 @@ typedef ieDword ieStrRef;
typedef char ieResRef[9];
typedef char ieVariable[33];
-#endif //! IE_TYPES_H
+}
+#endif //! IE_TYPES_H
diff --git a/gemrb/includes/iless.h b/gemrb/includes/iless.h
index 389bd64..f06d2ee 100644
--- a/gemrb/includes/iless.h
+++ b/gemrb/includes/iless.h
@@ -21,6 +21,8 @@
#include "win32def.h" //for stricmp
+namespace GemRB {
+
struct iless {
bool operator () (const char *lhs, const char* rhs) const
{
@@ -28,4 +30,6 @@ struct iless {
}
};
+}
+
#endif
diff --git a/gemrb/includes/logging.h b/gemrb/includes/logging.h
deleted file mode 100644
index b993955..0000000
--- a/gemrb/includes/logging.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/* GemRB - Infinity Engine Emulator
- * Copyright (C) 2003 The GemRB Project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/**
- * @file logging.h
- * Logging definitions.
- * @author The GemRB Project
- */
-
-
-#ifndef LOGGING_H
-#define LOGGING_H
-
-#include "exports.h"
-
-#ifdef ANDROID
-# include <android/log.h>
-# include "android_log_printf.h"
-#endif
-
-#ifdef WIN32
-# define ADV_TEXT
-# include <conio.h>
-extern GEM_EXPORT HANDLE hConsole;
-# define textcolor(i) SetConsoleTextAttribute(hConsole, i)
-# ifndef __MINGW32__
-# define printf cprintf //broken in mingw !!
-# endif
-#else //WIN32
-# ifndef ANDROID
-# include <config.h>
-# endif
-# include <cstdio>
-# include <cstdlib>
-# define textcolor(i) i
-#endif //WIN32
-
-#ifdef NOCOLOR
-# define DEFAULT printf("%s","");
-# define BLACK printf("%s","");
-# define RED printf("%s","");
-# define GREEN printf("%s","");
-# define BROWN printf("%s","");
-# define BLUE printf("%s","");
-# define MAGENTA printf("%s","");
-# define CYAN printf("%s","");
-# define WHITE printf("%s","");
-# define LIGHT_RED printf("%s","");
-# define LIGHT_GREEN printf("%s","");
-# define YELLOW printf("%s","");
-# define LIGHT_BLUE printf("%s","");
-# define LIGHT_MAGENTA printf("%s","");
-# define LIGHT_CYAN printf("%s","");
-# define LIGHT_WHITE printf("%s","");
-#else
-# ifdef WIN32
-# define BLACK 0
-# define RED FOREGROUND_RED
-# define GREEN FOREGROUND_GREEN
-# define BROWN FOREGROUND_GREEN | FOREGROUND_RED
-# define BLUE FOREGROUND_BLUE
-# define MAGENTA FOREGROUND_RED | FOREGROUND_BLUE
-# define CYAN FOREGROUND_BLUE | FOREGROUND_GREEN
-# define WHITE FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
-# define LIGHT_RED (RED | FOREGROUND_INTENSITY)
-# define LIGHT_GREEN (GREEN | FOREGROUND_INTENSITY)
-# define YELLOW (GREEN | RED | FOREGROUND_INTENSITY)
-# define LIGHT_BLUE (BLUE | FOREGROUND_INTENSITY)
-# define LIGHT_MAGENTA (MAGENTA | FOREGROUND_INTENSITY)
-# define LIGHT_CYAN (CYAN | FOREGROUND_INTENSITY)
-# define LIGHT_WHITE (WHITE | FOREGROUND_INTENSITY)
-# define DEFAULT WHITE
-# else //WIN32
-# define DEFAULT printf("\033[0m");
-# define BLACK printf("\033[0m\033[30;40m");
-# define RED printf("\033[0m\033[31;40m");
-# define GREEN printf("\033[0m\033[32;40m");
-# define BROWN printf("\033[0m\033[33;40m");
-# define BLUE printf("\033[0m\033[34;40m");
-# define MAGENTA printf("\033[0m\033[35;40m");
-# define CYAN printf("\033[0m\033[36;40m");
-# define WHITE printf("\033[0m\033[37;40m");
-# define LIGHT_RED printf("\033[1m\033[31;40m");
-# define LIGHT_GREEN printf("\033[1m\033[32;40m");
-# define YELLOW printf("\033[1m\033[33;40m");
-# define LIGHT_BLUE printf("\033[1m\033[34;40m");
-# define LIGHT_MAGENTA printf("\033[1m\033[35;40m");
-# define LIGHT_CYAN printf("\033[1m\033[36;40m");
-# define LIGHT_WHITE printf("\033[1m\033[37;40m");
-# endif //WIN32
-#endif
-
-#ifndef ANDROID
-# define printBracket(status, color) textcolor(WHITE); printf("["); textcolor(color); printf("%s", status); textcolor(WHITE); printf("]")
-# define printStatus(status, color) printBracket(status, color); printf("\n")
-# define printMessage(owner, message, color) printBracket(owner, LIGHT_WHITE); printf(": "); textcolor(color); printf("%s", message)
-#else
-# define printf android_log_printf
-# define printBracket(status, color)
-# define printStatus(status, color) __android_log_print(ANDROID_LOG_INFO, "GemRB", "[%s]", status)
-# define printMessage(owner, message, color) __android_log_print(ANDROID_LOG_INFO, "GemRB", "%s: %s", owner, message)
-#endif
-
-#endif
diff --git a/gemrb/includes/opcode_params.h b/gemrb/includes/opcode_params.h
index 081dba6..83fd26b 100644
--- a/gemrb/includes/opcode_params.h
+++ b/gemrb/includes/opcode_params.h
@@ -27,6 +27,8 @@
#ifndef IE_OPCODE_PARAMS_H
#define IE_OPCODE_PARAMS_H
+namespace GemRB {
+
//regen/poison/disease types
#define RPD_PERCENT 1
#define RPD_POINTS 2
@@ -34,6 +36,10 @@
//only poison
#define RPD_ROUNDS 4
#define RPD_TURNS 5
+//iwd2 specific poison types
+#define RPD_SNAKE 6
+#define RPD_7 7
+#define RPD_ENVENOM 8
//only disease
#define RPD_STR 4
#define RPD_DEX 5
@@ -194,11 +200,13 @@
#define SS_ENFEEBLEMENT 123
#define SS_SEVENEYES 124
//#define SS_SOULEATER 125
-
#define SS_LOWERRESIST 140
#define SS_LUCK 141
+#define SS_VOCALIZE 157
//tested for this, splstate is wrong or this entry has two uses
#define SS_DAYBLINDNESS 178
#define SS_REBUKED 179
+}
+
#endif //IE_OPCODE_PARAMS_H
diff --git a/gemrb/includes/overlays.h b/gemrb/includes/overlays.h
index b49135c..fe28ebc 100644
--- a/gemrb/includes/overlays.h
+++ b/gemrb/includes/overlays.h
@@ -23,6 +23,8 @@
* @author The GemRB Project
*/
+namespace GemRB {
+
#define OVERLAY_COUNT 32
#define OV_SANCTUARY 0
@@ -58,3 +60,5 @@
#define OV_ICESHIELD2 29
#define OV_TORTOISE 30
#define OV_DEATHARMOR 31
+
+}
diff --git a/gemrb/includes/plugindef.h b/gemrb/includes/plugindef.h
index 72a74e7..4058ddc 100644
--- a/gemrb/includes/plugindef.h
+++ b/gemrb/includes/plugindef.h
@@ -30,7 +30,7 @@
* #include "plugindef.h"
*
* GEMRB_PLUGIN(0xD768B1, "BMP File Reader")
- * PLUGIN_IE_RESOURCE(BMPImporter, ".bmp", IE_BMP_CLASS_ID)
+ * PLUGIN_IE_RESOURCE(BMPImporter, "bmp", IE_BMP_CLASS_ID)
* END_PLUGIN()
* @endcode
*
@@ -102,6 +102,8 @@
#include "exports.h"
#include "PluginMgr.h"
+namespace GemRB {
+
template <typename T>
struct CreatePlugin {
static Plugin *func()
@@ -124,6 +126,8 @@ struct CreateResource {
}
};
+}
+
#ifndef STATIC_LINK
#ifdef WIN32
@@ -143,6 +147,7 @@ GEM_EXPORT_DLL const char* GemRBPlugin_Version()
}
#define GEMRB_PLUGIN(id, desc) \
+ namespace { using namespace GemRB; \
GEM_EXPORT_DLL PluginID GemRBPlugin_ID() { \
return id; \
} \
@@ -172,12 +177,14 @@ GEM_EXPORT_DLL const char* GemRBPlugin_Version()
/* mgr is not null (this makes mgr used) */
#define END_PLUGIN() \
return mgr!=0; \
+ } \
}
#else /* STATIC_LINK */
#define GEMRB_PLUGIN(id, desc) \
- namespace { bool doRegisterPlugin = (
+ namespace { using namespace GemRB; \
+ bool doRegisterPlugin = (
#define PLUGIN_CLASS(id, cls) \
PluginMgr::Get()->RegisterPlugin(id, &CreatePlugin<cls>::func ),
diff --git a/gemrb/includes/strrefs.h b/gemrb/includes/strrefs.h
index e960f71..39d6f83 100644
--- a/gemrb/includes/strrefs.h
+++ b/gemrb/includes/strrefs.h
@@ -30,6 +30,8 @@
#ifndef IE_STRINGS_H
#define IE_STRINGS_H
+namespace GemRB {
+
#define STR_SCATTERED 0
#define STR_WHOLEPARTY 1
#define STR_DOORLOCKED 2
@@ -83,10 +85,10 @@
#define STR_AP_ENEMY 50
#define STR_AP_TRAP 51
#define STR_AP_SPELLCAST 52
-#define STR_AP_RESERVED1 53
-#define STR_AP_RESERVED2 54
-#define STR_AP_RESERVED3 55
-#define STR_AP_RESERVED4 56
+#define STR_AP_GENERIC 53
+#define STR_AP_RESERVED1 54
+#define STR_AP_RESERVED2 55
+#define STR_AP_RESERVED3 56
#define STR_CHARMED 57
#define STR_DIRECHARMED 58
#define STR_CONTROLLED 59
@@ -148,15 +150,15 @@
#define STR_INJURED2 115
#define STR_INJURED3 116
#define STR_INJURED4 117 //near death
-#define STR_HOURS 118 //<HOUR> hours
-#define STR_HOUR 119
+#define STR_HOURS 118 //<HOUR> hours / Hours
+#define STR_HOUR 119 //<HOUR> hours / Hour
#define STR_DAYS 120 //<GAMEDAYS> days
#define STR_DAY 121
-#define STR_REST 122 //You have rested for <DURATION>
+#define STR_REST 122 //You have rested for <DURATION> / <HOUR> <DURATION>
#define STR_JOURNEY 123 //The journey took <DURATION>
-#define STR_PST_REST 124 //You have rested for <HOUR> <DURATION>
-#define STR_PST_HOUR 125
-#define STR_PST_HOURS 126
+#define STR_SUMMONINGLIMIT 124
+#define STR_INVFULL 125
+#define STR_TOOFARAWAY 126
#define STR_DAMAGE_IMMUNITY 127
#define STR_DAMAGE1 128
#define STR_DAMAGE2 129
@@ -196,6 +198,26 @@
#define STR_WILDSURGE 163
#define STR_FAMBLOCK 164
#define STR_FAMPROTAGONIST 165
-#define STRREF_COUNT 166
+#define STR_MAGIC_RESISTED 166
+#define STR_CANTSAVESTORE 167
+#define STR_NOSEE_NOCAST 168
+#define STR_AURACLEANSED 169
+#define STR_INDOOR_FAIL 170
+#define STR_SPELL_FAILED 171
+#define STR_CHAOSSHIELD 172
+#define STR_RAPIDSHOT 173
+#define STR_HAMSTRING 174
+#define STR_ARTERIAL 175
+#define STR_EXPERTISE 176
+#define STR_POWERATTACK 177
+#define STR_CLEAVE 178
+#define STR_HELD 179
+#define STR_HALFSPEED 180
+#define STR_CANTMOVE 181
+#define STR_CASTS 182
+#define STR_WEAPONINEFFECTIVE 183
+
+#define STRREF_COUNT 184
+}
#endif //! IE_STRINGS_H
diff --git a/gemrb/includes/win32def.h b/gemrb/includes/win32def.h
index 5b676e0..8abfea3 100644
--- a/gemrb/includes/win32def.h
+++ b/gemrb/includes/win32def.h
@@ -30,43 +30,24 @@
#include "exports.h"
+#include "System/String.h"
+
#ifdef WIN32
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
-# if _MSC_VER >= 1000
-// 4251 disables the annoying warning about missing dll interface in templates
-# pragma warning( disable: 4251 521 )
-# pragma warning( disable: 4275 )
-//disables annoying warning caused by STL:Map in msvc 6.0
-# if _MSC_VER < 7000
-# pragma warning(disable:4786)
-# endif
-# endif
-
-# if defined(__MINGW32__) && ! defined(HAVE_SNPRINTF)
-# define HAVE_SNPRINTF 1
-# endif
-
#else //WIN32
-# ifndef ANDROID
+# ifdef HAVE_CONFIG_H
# include <config.h>
# endif
# include <cstdio>
# include <cstdlib>
-# include <cstring>
-# define stricmp strcasecmp
-# define strnicmp strncasecmp
#endif //WIN32
-#ifndef HAVE_SNPRINTF
-# ifdef WIN32
-# define snprintf _snprintf
-# define HAVE_SNPRINTF 1
-# else
-# include "System/snprintf.h"
-# endif
+#if defined(WIN32) && !defined(__MINGW32__)
+# define snprintf _snprintf
+# define vsnprintf _vsnprintf
#endif
#include "System/VFS.h"
@@ -84,5 +65,5 @@
#define M_PI_2 1.57079632679489661923 // pi/2
#endif
-#include "logging.h"
+#include "System/Logging.h"
#endif //! WIN32DEF_H
diff --git a/gemrb/override/CMakeLists.txt b/gemrb/override/CMakeLists.txt
deleted file mode 100644
index 20c335e..0000000
--- a/gemrb/override/CMakeLists.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-ADD_SUBDIRECTORY( bg1 )
-ADD_SUBDIRECTORY( bg2 )
-ADD_SUBDIRECTORY( how )
-ADD_SUBDIRECTORY( iwd )
-ADD_SUBDIRECTORY( iwd2 )
-ADD_SUBDIRECTORY( pst )
-ADD_SUBDIRECTORY( shared )
diff --git a/gemrb/override/bg1/CMakeLists.txt b/gemrb/override/bg1/CMakeLists.txt
index f258b1b..ab4f4b2 100644
--- a/gemrb/override/bg1/CMakeLists.txt
+++ b/gemrb/override/bg1/CMakeLists.txt
@@ -1 +1,2 @@
-ADD_GEMRB_OVERRIDE (bg1)
\ No newline at end of file
+ADD_GEMRB_OVERRIDE (bg1)
+
diff --git a/gemrb/override/bg1/Makefile.am b/gemrb/override/bg1/Makefile.am
index e9c61f4..52ba22e 100644
--- a/gemrb/override/bg1/Makefile.am
+++ b/gemrb/override/bg1/Makefile.am
@@ -1,3 +1,3 @@
-bg1override_DATA = *.2da *.bmp *.ini *.chu *.ids *.pro
+bg1override_DATA = *.2da *.vvc
bg1overridedir = $(moddir)/override/bg1/
-EXTRA_DIST = *.2da *.bmp *.ini *.chu *.ids *.pro
+EXTRA_DIST = *.2da *.vvc
diff --git a/gemrb/override/bg1/avatars.2da b/gemrb/override/bg1/avatars.2da
deleted file mode 100644
index 40fa746..0000000
--- a/gemrb/override/bg1/avatars.2da
+++ /dev/null
@@ -1,322 +0,0 @@
-2DA V1.0
-*
- AT_1 AT_2 AT_3 AT_4 TYPE SPACE PALETTE SIZE
-0x0100 SPCHUNKS SPCHUNKS SPCHUNKS SPCHUNKS 13 0 0 *
-0x0300 SPSMPUFF SPSMPUFF SPSMPUFF SPSMPUFF 13 0 0 *
-0x0400 SKLH SKLH SKLH SKLH 13 0 1 *
-0x0410 GLPHWRDH GLPHWRDH GLPHWRDH GLPHWRDH 13 0 1 *
-0x1000 MWYV MWYV MWYV MWYV 11 3 1 *
-0x1100 MTAN MTAN MTAN MTAN 11 3 1 *
-0x1200 MDR1 MDR1 MDR1 MDR1 12 7 1 *
-0x1201 MDR2 MDR2 MDR2 MDR2 12 7 1 *
-0x1202 MDR3 MDR3 MDR3 MDR3 12 7 1 *
-0x1203 MDR1 MDR1 MDR1 MDR1 12 7 GR *
-0x1204 MDR1 MDR1 MDR1 MDR1 12 7 AQ *
-0x1205 MDR1 MDR1 MDR1 MDR1 12 7 BL *
-0x1206 MDR1 MDR1 MDR1 MDR1 12 7 BR *
-0x1207 MDR1 MDR1 MDR1 MDR1 12 7 MC *
-0x1208 MDR1 MDR1 MDR1 MDR1 12 7 PU *
-0x2000 MSIR MSIR MSIR MSIR 2 2 0 *
-0x2100 UVOL UVOL UVOL UVOL 2 2 1 *
-0x2200 MOGM MOGM MOGM MOGM 2 2 0 S
-0x2300 MDKN MDKN MDKN MDKN 2 2 1 *
-0x3000 MAKH MAKH MAKH MAKH 2 3 1 *
-0x4000 SNOMC SNOMC SNOMC SNOMC 1 2 0 *
-0x4002 SNOMM SNOMM SNOMM SNOMM 1 2 0 *
-0x4010 SNOWC SNOWC SNOWC SNOWC 1 2 0 *
-0x4012 SNOWM SNOWM SNOWM SNOWM 1 2 0 *
-0x4100 SSIMC SSIMC SSIMC SSIMC 1 2 0 *
-0x4101 SSIMS SSIMS SSIMS SSIMS 1 2 0 *
-0x4102 SSIMM SSIMM SSIMM SSIMM 1 2 0 *
-0x4110 SSIWC SSIWC SSIWC SSIWC 1 2 0 *
-0x4112 SSIWM SSIWM SSIWM SSIWM 1 2 0 *
-0x4200 SHMCM SHMCM SHMCM SHMCM 1 2 0 *
-0x4300 MSPLG1 MSPLG1 MSPLG1 MSPLG1 1 2 1 *
-0x4400 LHMC LHMC LHMC LHMC 1 2 0 *
-0x4410 LHFC LHFC LHFC LHFC 1 2 0 *
-0x4500 LFAM LFAM LFAM LFAM 1 2 0 *
-0x4600 LDMF LDMF LDMF LDMF 1 2 0 *
-0x4700 LEMF LEMF LEMF LEMF 1 2 0 *
-0x4710 LEFF LEFF LEFF LEFF 1 2 0 *
-0x4800 LIMC LIMC LIMC LIMC 1 2 0 *
-0x5000 CHMC1 CHMC2 CHMC3 CHMC4 6 2 0 L
-0x5001 CEMC1 CEMC2 CEMC3 CEMC4 6 2 0 M
-0x5002 CDMC1 CDMC2 CDMC3 CDMC4 6 2 0 S
-0x5003 CIMC1 CIMC2 CIMC3 CIMC4 6 2 0 S
-0x5010 CHFC1 CHFC2 CHFC3 CHFC4 6 2 0 M
-0x5011 CEFC1 CEFC2 CEFC3 CEFC4 6 2 0 M
-0x5012 CDMC1 CDMC2 CDMC3 CDMC4 6 2 0 S
-0x5013 CIFC1 CIFC2 CIFC3 CIFC4 6 2 0 S
-0x5100 CHMF1 CHMF2 CHMF3 CHMF4 6 2 0 L
-0x5101 CEMF1 CEMF2 CEMF3 CHMF4 6 2 0 M
-0x5102 CDMF1 CDMF2 CDMF3 CDMF4 6 2 0 S
-0x5103 CIMF1 CIMF2 CIMF3 CIMF4 6 2 0 S
-0x5110 CHFF1 CHFF2 CHFF3 CHFF4 6 2 0 M
-0x5111 CEFF1 CEFF2 CEFF3 CEFF4 6 2 0 M
-0x5112 CDMF1 CDMF2 CDMF3 CDMF4 6 2 0 S
-0x5113 CIFF1 CIFF2 CIFF3 CIFF4 6 2 0 S
-0x5200 CHMW1 CHMW2 CHMW3 CHMW4 6 2 0 L
-0x5201 CEMW1 CEMW2 CEMW3 CEMW4 6 2 0 M
-0x5202 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
-0x5203 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
-0x5210 CHFW1 CHFW2 CHFW3 CHFW4 6 2 0 M
-0x5211 CEFW1 CEFW2 CEFW3 CEFW4 6 2 0 M
-0x5212 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
-0x5213 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
-0x5300 CHMT1 CHMT2 CHMT2 CHMT2 6 2 0 L
-0x5301 CEMT1 CEMT2 CEMT2 CEMT2 6 2 0 M
-0x5302 CDMT1 CDMT2 CDMT2 CDMT2 6 2 0 S
-0x5303 CIMT1 CIMT2 CIMT2 CIMT2 6 2 0 S
-0x5310 CHFT1 CHFT2 CHFT2 CHFT2 6 2 0 M
-0x5311 CEFT1 CEFT2 CEFT2 CEFT2 6 2 0 M
-0x5312 CDMT1 CDMT2 CDMT2 CDMT2 6 2 0 S
-0x5313 CIFT1 CIFT2 CIFT2 CIFT2 6 2 0 S
-0x6000 CHMC1 CHMC2 CHMC3 CHMC4 6 2 0 L
-0x6001 CEMC1 CEMC2 CEMC3 CEMC4 6 2 0 M
-0x6002 CDMC1 CDMC2 CDMC3 CDMC4 6 2 0 S
-0x6003 CIMC1 CIMC2 CIMC3 CIMC4 6 2 0 S
-0x6004 CDMC1 CDMC2 CDMC3 CDMC4 6 2 0 S
-0x6005 CHMC1 CHMC2 CHMC3 CHMC4 6 2 0 L
-0x6010 CHFC1 CHFC2 CHFC3 CHFC4 6 2 0 M
-0x6011 CEFC1 CEFC2 CEFC3 CEFC4 6 2 0 M
-0x6012 CDMC1 CDMC2 CDMC3 CDMC4 6 2 0 S
-0x6013 CIFC1 CIFC2 CIFC3 CIFC4 6 2 0 S
-0x6014 CIFC1 CIFC2 CIFC3 CIFC4 6 2 0 S
-0x6015 CHFC1 CHFC2 CHFC3 CHFC4 6 2 0 L
-0x6100 CHMF1 CHMF2 CHMF3 CHMF4 6 2 0 L
-0x6101 CEMF1 CEMF2 CEMF3 CEMF4 6 2 0 M
-0x6102 CDMF1 CDMF2 CDMF3 CDMF4 6 2 0 S
-0x6103 CIMF1 CIMF2 CIMF3 CIMF4 6 2 0 S
-0x6104 CDMF1 CDMF2 CDMF3 CDMF4 6 2 0 S
-0x6105 CHMF1 CHMF2 CHMF3 CHMF4 6 2 0 L
-0x6110 CHFF1 CHFF2 CHFF3 CHFF4 6 2 0 M
-0x6111 CEFF1 CEFF2 CEFF3 CEFF4 6 2 0 M
-0x6112 CDMF1 CDMF2 CDMF3 CDMF4 6 2 0 S
-0x6113 CIFF1 CIFF2 CIFF3 CIFF4 6 2 0 S
-0x6114 CIFF1 CIFF2 CIFF3 CIFF4 6 2 0 S
-0x6115 CHFF1 CHFF2 CHFF3 CHFF4 6 2 0 L
-0x6200 CHMW1 CHMW2 CHMW3 CHMW4 6 2 0 L
-0x6201 CEMW1 CEMW2 CEMW3 CEMW4 6 2 0 M
-0x6202 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
-0x6203 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
-0x6204 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
-0x6205 CHMW1 CHMW2 CHMW3 CHMW4 6 2 0 L
-0x6210 CHFW1 CHFW2 CHFW3 CHFW4 6 2 0 M
-0x6211 CEFW1 CEFW2 CEFW3 CEFW4 6 2 0 M
-0x6212 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
-0x6213 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
-0x6214 CDMW1 CIFW2 CIFW3 CIFW4 6 2 0 S
-0x6215 CHFW1 CHFW2 CHFW3 CHFW4 6 2 0 L
-0x6300 CHMT1 CHMT2 CHMT2 CHMT2 6 2 0 L
-0x6301 CEMT1 CEMT2 CEMT2 CEMT2 6 2 0 M
-0x6302 CDMT1 CDMT2 CDMT2 CDMT2 6 2 0 S
-0x6303 CIMT1 CIMT2 CIMT2 CIMT2 6 2 0 S
-0x6304 CDMT1 CDMT2 CDMT2 CDMT2 6 2 0 S
-0x6305 CHMT1 CHMT2 CHMT2 CHMT2 6 2 0 L
-0x6310 CHFT1 CHFT2 CHFT2 CHFT2 6 2 0 M
-0x6311 CEFT1 CEFT2 CEFT2 CEFT2 6 2 0 M
-0x6312 CDMT1 CDMT2 CDMT2 CDMT2 6 2 0 S
-0x6313 CIFT1 CIFT2 CIFT2 CIFT2 6 2 0 S
-0x6314 CIFT1 CIFT2 CIFT2 CIFT2 6 2 0 S
-0x6315 CHFT1 CHFT2 CHFT2 CHFT2 6 2 0 L
-0x6400 UDRZ1 UDRZ1 UDRZ1 UDRZ1 6 2 0 *
-0x6401 UELM1 UELM1 UELM1 UELM1 6 2 1 *
-0x6402 CMNK1 CMNK1 CMNK1 CMNK1 6 2 0 *
-0x6403 MSKL1 MSKL1 MSKL1 MSKL1 6 2 1 M
-0x6404 USAR1 USAR1 USAR1 USAR1 6 2 1 *
-0x6405 MDGU1 MDGU1 MDGU1 MDGU1 6 2 0 M
-0x6406 MDGU1 MDGU1 MDGU1 MDGU1 6 2 0 L
-0x6500 CHMM1 CHMC2 CHMC3 CHMC4 0 2 0 *
-0x6510 CHFM1 CHFC2 CHFC3 CHFC4 0 2 0 *
-0x7000 MOGH MOGH MOGH MOGH 2 2 0 *
-0x7001 MOGN MOGN MOGN MOGN 2 2 0 *
-0x7100 MBAS MBAS MBAS MBAS 2 2 1 *
-0x7101 MBAS MBAS MBAS MBAS 2 2 GR *
-0x7200 MBER MBER MBER MBER 2 2 BL *
-0x7201 MBER MBER MBER MBER 2 2 1 *
-0x7202 MBER MBER MBER MBER 2 2 CA *
-0x7203 MBER MBER MBER MBER 2 2 PO *
-0x7300 MEAE MEAE MEAE MEAE 4 2 1 *
-0x7301 MEAS MEAS MEAS MEAS 4 2 1 *
-0x7302 MEAE MEAE MEAE MEAE 4 2 SH *
-0x7310 MFIE MFIE MFIE MFIE 4 2 1 *
-0x7311 MFIS MFIS MFIS MFIS 4 2 1 *
-0x7320 MAIR MAIR MAIR MAIR 4 2 1 *
-0x7321 MAIS MAIS MAIS MAIS 4 2 1 *
-0x7400 MDOG MDOG MDOG MDOG 2 2 WI *
-0x7401 MDOG MDOG MDOG MDOG 2 2 WA *
-0x7402 MDOG MDOG MDOG MDOG 2 2 MO *
-0x7500 MDOP MDOP MDOP MDOP 2 2 1 *
-0x7501 MDOP MDOP MDOP MDOP 2 2 GR *
-0x7600 METT METT METT METT 2 2 1 *
-0x7701 MGHL MGHL MGHL MGHL 2 2 1 *
-0x7702 MGHL MGHL MGHL MGHL 2 2 RE *
-0x7703 MGHL MGHL MGHL MGHL 2 2 GA *
-0x7704 MSHD MSHD MSHD MSHD 4 2 1 *
-0x7800 MGIB MGIB MGIB MGIB 2 2 1 *
-0x7900 MSLI MSLI MSLI MSLI 3 3 GR *
-0x7901 MSLI MSLI MSLI MSLI 3 3 OL *
-0x7902 MSLI MSLI MSLI MSLI 3 3 MU *
-0x7903 MSLI MSLI MSLI MSLI 3 3 OC *
-0x7904 MSLI MSLI MSLI MSLI 3 3 1 *
-0x7A00 MSPI MSPI MSPI MSPI 2 2 GI *
-0x7A01 MSPI MSPI MSPI MSPI 3 2 HU *
-0x7A02 MSPI MSPI MSPI MSPI 3 2 PH *
-0x7A03 MSPI MSPI MSPI MSPI 3 2 SW *
-0x7A04 MSPI MSPI MSPI MSPI 3 2 WR *
-0x7B00 MWLF MWLF MWLF MWLF 2 2 1 *
-0x7B01 MWLF MWLF MWLF MWLF 2 2 WO *
-0x7B02 MWLF MWLF MWLF MWLF 2 2 DI *
-0x7B03 MWLF MWLF MWLF MWLF 2 2 WI *
-0x7B04 MWLF MWLF MWLF MWLF 2 2 VA *
-0x7B05 MWLF MWLF MWLF MWLF 2 2 DR *
-0x7B06 MWLS MWLS MWLS MWLS 2 2 1 *
-0x7C00 MXVT MXVT MXVT MXVT 2 2 0 *
-0x7C01 MTAS MTAS MTAS MTAS 2 2 1 *
-0x7D00 MZOM MZOM MZOM MZOM 2 2 0 *
-0x7E00 MWER MWER MWER MWER 2 2 1 *
-0x7E01 MGWE MGWE MGWE MGWE 2 2 1 *
-0x7F00 MTRO MTRO MTRO MTRO 4 2 1 *
-0x7F01 MMIN MMIN MMIN MMIN 4 2 1 *
-0x7F02 MBEH MBEH MBEH MBEH 4 3 1 *
-0x7F03 MIMP MIMP MIMP MIMP 4 2 1 *
-0x7F04 MIGO MIGO MIGO MIGO 4 4 1 *
-0x7F05 MDJI MDJI MDJI MDJI 4 2 1 *
-0x7F06 MDJL MDJL MDJL MDJL 4 2 1 *
-0x7F07 MGLC MGLC MGLC MGLC 4 2 1 *
-0x7F08 MOTY MOTY MOTY MOTY 4 4 1 *
-0x7F09 MSAH MSAH MSAH MSAH 4 2 1 *
-0x7F0A MGCP MGCP MGCP MGCP 4 2 1 *
-0x7F0B MGCL MGCL MGCL MGCL 4 2 1 *
-0x7F0C MKUO MKUO MKUO MKUO 4 2 1 *
-0x7F0D MLIC MLIC MLIC MLIC 4 2 1 *
-0x7F0E MDLI MDLI MDLI MDLI 4 2 1 *
-0x7F0F MTRS MTRS MTRS MTRS 4 2 1 *
-0x7F10 MRAK MRAK MRAK MRAK 4 2 1 *
-0x7F11 MUMB MUMB MUMB MUMB 4 2 1 *
-0x7F12 MVAM MVAM MVAM MVAM 4 2 1 *
-0x7F13 MSNK MSNK MSNK MSNK 4 2 1 *
-0x7F14 MGIT MGIT MGIT MGIT 4 2 1 *
-0x7F15 MBES MBES MBES MBES 4 2 1 *
-0x7F16 AMOO AMOO AMOO AMOO 4 3 1 *
-0x7F17 ARAB ARAB ARAB ARAB 4 1 1 *
-0x7F18 ADER ADER ADER ADER 4 2 1 *
-0x7F19 MDSW MDSW MDSW MDSW 4 2 1 *
-0x7F20 AGRO AGRO AGRO AGRO 4 2 1 *
-0x7F21 APHE APHE APHE APHE 4 2 1 *
-0x7F22 MVAF MVAF MVAF MVAF 4 2 1 *
-0x7F23 MSAT MSAT MSAT MSAT 4 2 1 *
-0x7F24 NPIR NPIR NPIR NPIR 4 2 1 *
-0x7F27 MDRO MDRO MDRO MDRO 4 2 1 *
-0x7F28 MKUL MKUL MKUL MKUL 4 2 1 *
-0x7F29 MFDR MFDR MFDR MFDR 4 2 1 *
-0x7F2A NSAI NSAI NSAI NSAI 4 2 1 *
-0x7F2C NSOL NSOL NSOL NSOL 4 2 1 *
-0x7F2D MWFM MWFM MWFM MWFM 4 2 1 *
-0x7F2E MRAV MRAV MRAV MRAV 4 3 1 *
-0x7F2F MSPS MSPS MSPS MSPS 4 2 1 *
-0x7F30 NBOH NBOH NBOH NBOH 4 2 1 *
-0x7F31 NELL NELL NELL NELL 4 2 1 *
-0x7F32 MSLY MSLY MSLY MSLY 4 2 1 *
-0x7F35 MMIS MMIS MMIS MMIS 4 2 1 *
-0x7F36 NSHD NSHD NSHD NSHD 4 2 1 *
-0x7F37 NIRE NIRE NIRE NIRE 4 2 1 *
-0x8000 MGNL MGNL MGNL MGNL 2 2 0 *
-0x8100 MHOB MHOB MHOB MHOB 2 2 0 *
-0x8200 MKOB MKOB MKOB MKOB 2 2 0 *
-0x9000 MOGR MOGR MOGR MOGR 5 2 0 *
-0xA000 MWYV MWYV MWYV MWYV 8 3 1 *
-0xA100 MCAR MCAR MCAR MCAR 8 3 1 *
-0xB000 ACOW ACOW ACOW ACOW 10 3 1 *
-0xB100 AHRS AHRS AHRS AHRS 10 3 1 *
-0xB200 NBEGL NBEGL NBEGL NBEGL 3 2 0 *
-0xB210 NPROL NPROL NPROL NPROL 3 2 0 *
-0xB300 NBOYL NBOYL NBOYL NBOYL 3 2 0 *
-0xB310 NGRLL NGRLL NGRLL NGRLL 3 2 0 *
-0xB400 NFAML NFAML NFAML NFAML 3 2 0 *
-0xB410 NFAWL NFAWL NFAWL NFAWL 3 2 0 *
-0xB500 NSIML NSIML NSIML NSIML 3 2 0 *
-0xB510 NSIWL NSIWL NSIWL NSIWL 3 2 0 *
-0xB600 NNOML NNOML NNOML NNOML 3 2 0 *
-0xB610 NNOWL NNOWL NNOWL NNOWL 3 2 0 *
-0xB700 NSLVL NSLVL NSLVL NSLVL 3 2 0 *
-0xC000 ABAT ABAT ABAT ABAT 3 1 1 *
-0xC100 ACAT ACAT ACAT ACAT 3 1 1 *
-0xC200 ACHK ACHK ACHK ACHK 3 1 1 *
-0xC300 ARAT ARAT ARAT ARAT 3 1 1 *
-0xC400 ASQU ASQU ASQU ASQU 3 1 1 *
-0xC500 ABAT ABAT ABAT ABAT 3 1 1 *
-0xC600 NBEGH NBEGH NBEGH NBEGH 3 2 0 *
-0xC610 NPROH NPROH NPROH NPROH 3 2 0 *
-0xC700 NBOYH NBOYH NBOYH NBOYH 3 2 0 *
-0xC710 NGRLH NGRLH NGRLH NGRLH 3 2 0 *
-0xC800 NFAMH NFAMH NFAMH NFAMH 3 2 0 *
-0xC810 NFAWH NFAWH NFAWH NFAWH 3 2 0 *
-0xC900 NSIMH NSIMH NSIMH NSIMH 3 2 0 *
-0xC910 NSIWH NSIWH NSIWH NSIWH 3 2 0 *
-0xCA00 NNOMH NNOMH NNOMH NNOMH 3 2 0 *
-0xCA10 NNOWH NNOWH NNOWH NNOWH 3 2 0 *
-0xCB00 NSLVH NSLVH NSLVH NSLVH 3 2 0 *
-0xD000 AEAGG1 AEAGG1 AEAGG1 AEAGG1 7 0 1 *
-0xD100 AGULG1 AGULG1 AGULG1 AGULG1 7 0 1 *
-0xD200 AVULG1 AVULG1 AVULG1 AVULG1 7 0 1 *
-0xD300 ABIRG1 ABIRG1 ABIRG1 ABIRG1 7 0 1 *
-0xD400 ABIRG1 ABIRG1 ABIRG1 ABIRG1 7 0 1 *
-0xE000 MCYC MCYC MCYC MCYC 9 4 1 *
-0xE010 METN METN METN METN 9 4 1 *
-0xE020 MTAN MTAN MTAN MTAN 9 4 1 *
-0xE040 MHIS MHIS MHIS MHIS 9 2 1 *
-0xE050 MLER MLER MLER MLER 9 2 1 *
-0xE060 MLIC MLIC MLIC MLIC 9 2 1 *
-0xE070 MMIN MMIN MMIN MMIN 9 2 1 *
-0xE080 MMUM MMUM MMUM MMUM 9 2 1 *
-0xE090 MMER MMER MMER MMER 9 2 1 *
-0xE0A0 MTIC MTIC MTIC MTIC 9 2 1 *
-0xE0B0 MTRO MTRO MTRO MTRO 9 2 1 *
-0xE0C0 MTSN MTSN MTSN MTSN 9 2 1 *
-0xE0D0 MUMB MUMB MUMB MUMB 9 2 1 *
-0xE0E0 MCOR MCOR MCOR MCOR 9 2 1 *
-0xE0F0 MGIC MGIC MGIC MGIC 9 2 1 *
-0xE0F1 MGLA MGLA MGLA MGLA 9 2 1 *
-0xE0F2 MWAV MWAV MWAV MWAV 9 2 1 *
-0xE200 MBET MBET MBET MBET 9 2 1 *
-0xE210 MBFI MBFI MBFI MBFI 9 2 1 *
-0xE220 MBBM MBBM MBBM MBBM 9 2 1 *
-0xE230 MBRH MBRH MBRH MBRH 9 5 1 *
-0xE300 MGHO MGHO MGHO MGHO 9 2 1 *
-0xE310 MGH2 MGH2 MGH2 MGH2 9 2 1 *
-0xE320 MGH3 MGH3 MGH3 MGH3 9 2 1 *
-0xE400 MGO1 MGO1 MGO1 MGO1 9 2 1 *
-0xE410 MGO2 MGO2 MGO2 MGO2 9 2 1 *
-0xE420 MGO3 MGO3 MGO3 MGO3 9 2 1 *
-0xE430 MGO4 MGO4 MGO4 MGO4 9 2 1 *
-0xE500 MLIZ MLIZ MLIZ MLIZ 9 2 1 *
-0xE510 MLI2 MLI2 MLI2 MLI2 9 2 1 *
-0xE520 MLI3 MLI3 MLI3 MLI3 9 2 1 *
-0xE600 MMYC MMYC MMYC MMYC 9 2 1 *
-0xE610 MMY2 MMY2 MMY2 MMY2 9 2 1 *
-0xE700 MNO1 MNO1 MNO1 MNO1 9 2 1 *
-0xE710 MNO2 MNO2 MNO2 MNO2 9 2 1 *
-0xE720 MNO3 MNO3 MNO3 MNO3 9 2 1 *
-0xE800 MOR1 MOR1 MOR1 MOR1 9 2 1 *
-0xE810 MOR2 MOR2 MOR2 MOR2 9 2 1 *
-0xE820 MOR3 MOR3 MOR3 MOR3 9 2 1 *
-0xE830 MOR4 MOR4 MOR4 MOR4 9 2 1 *
-0xE840 MOR5 MOR5 MOR5 MOR5 9 2 1 *
-0xE900 MSAL MSAL MSAL MSAL 9 2 1 *
-0xE910 MSA2 MSA2 MSA2 MSA2 9 2 1 *
-0xEA00 MSHR MSHR MSHR MSHR 9 2 1 *
-0xEA10 MSH1 MSH1 MSH1 MSH1 9 2 1 *
-0xEA20 MSH2 MSH2 MSH2 MSH2 9 2 1 *
-0xEB00 MSKT MSKT MSKT MSKT 9 2 1 *
-0xEB10 MSKA MSKA MSKA MSKA 9 2 1 *
-0xEB20 MSKB MSKB MSKB MSKB 9 2 1 *
-0xEC00 MWIG MWIG MWIG MWIG 9 2 1 *
-0xEC10 MWI2 MWI2 MWI2 MWI2 9 2 1 *
-0xEC20 MWI3 MWI3 MWI3 MWI3 9 2 1 *
-0xED00 MYU1 MYU1 MYU1 MYU1 9 2 1 *
-0xED10 MYU2 MYU2 MYU2 MYU2 9 2 1 *
-0xED20 MYU3 MYU3 MYU3 MYU3 9 2 1 *
-0xEE00 MZO2 MZO2 MZO2 MZO2 9 2 1 *
-0xEE10 MZO3 MZO3 MZO3 MZO3 9 2 1 *
-0xEF00 MWWE MWWE MWWE MWWE 9 2 1 *
diff --git a/gemrb/override/bg1/bloodclr.2da b/gemrb/override/bg1/bloodclr.2da
deleted file mode 100644
index 1b33a30..0000000
--- a/gemrb/override/bg1/bloodclr.2da
+++ /dev/null
@@ -1,29 +0,0 @@
-2DA V1.0
-0
- VALUE MIN MAX
-NORMAL 0x2f 0x1000 0xffff
-PURPLE 0x2d 0x4300 0x43ff
-MSKEL 0x25 0x5403 0x5403
-DOOMG 0x22 0x5405 0x5406
-MSKEL 0x25 0x6403 0x6403
-DOOMG 0x22 0x6405 0x6406
-YELLOW 0x32 0x7300 0x73ff
-PURPLE 0x3c 0x7500 0x75ff
-YELLOW 0x32 0x7600 0x76ff
-BLACK 0x66 0x7700 0x77ff
-SLI_GR 7 0x7900 0x7900
-SLI_OL 0x24 0x7901 0x7901
-SLI_MU 0x33 0x7902 0x7902
-SLI_OC 0x25 0x7903 0x7903
-SLIME 0x1b 0x7904 0x7904
-SPIDER 0x33 0x7a00 0x7aff
-ZOMBIE 0x25 0x7c00 0x7cff
-MTRO 0x33 0x7f00 0x7f00
-MMIN 0x3d 0x7f01 0x7f03
-MIGO 0x1a 0x7f04 0x7f04
-MGLC 0x5d 0x7f07 0x7f07
-MTRS 0x32 0x7f0f 0x7f0f
-MBES 0x3d 0x7f15 0x7f15
-MCAR 0x38 0xa100 0xa1ff
-UNDEAD 0x66 0xe300 0xe3ff
-MWWE 0x38 0xef00 0xefff
diff --git a/gemrb/override/bg1/clskills.2da b/gemrb/override/bg1/clskills.2da
deleted file mode 100644
index 68c4e97..0000000
--- a/gemrb/override/bg1/clskills.2da
+++ /dev/null
@@ -1,24 +0,0 @@
-2DA V1.0
-*
- DRUIDSPELL CLERICSPELL MAGESPELL STARTXP BARDSKILL THIEFSKILL LAYHANDS TURNLEVEL BOOKTYPE HATERACE SAVEBONUS
-UNUSED * * * * * * * 0 0 * *
-MAGE * * MXSPLWIZ 89000 * * * 0 1 * 0
-FIGHTER * * * 89000 * * * 0 0 * 0
-CLERIC * MXSPLPRS * 89000 * * * 1 1 * 0
-THIEF * * * 89000 * SKILLS * 0 0 * 0
-BARD * * MXSPLBRD 89000 SKILLBRD * * 0 1 * 0
-PALADIN * MXSPLPAL * 89000 * * PALADIN 5 1 * 2
-FIGHTER_MAGE * * MXSPLWIZ 89000 * * * 0 1 * 0
-FIGHTER_CLERIC * MXSPLPRS * 89000 * * * 0 1 * 0
-FIGHTER_THIEF * * * 89000 * SKILLS * 0 0 * 0
-FIGHTER_MAGE_THIEF * * MXSPLWIZ 89000 * SKILLS * 0 1 * 0
-DRUID MXSPLPRS * * 89000 * * * 0 1 * 0
-RANGER MXSPLRAN * * 89000 * * * 0 1 HATERACE 0
-MAGE_THIEF * * MXSPLWIZ 89000 * SKILLS * 0 1 * 0
-CLERIC_MAGE * MXSPLPRS MXSPLWIZ 89000 * * * 0 1 * 0
-CLERIC_THIEF * MXSPLPRS * 89000 * SKILLS * 0 1 * 0
-FIGHTER_DRUID MXSPLPRS * * 89000 * * * 0 1 * 0
-FIGHTER_MAGE_CLERIC * MXSPLPRS MXSPLWIZ 89000 * * * 0 1 * 0
-CLERIC_RANGER MXSPLRAN MXSPLPRS * 89000 * * * 0 1 HATERACE 0
-SORCERER * * MXSPLSRC 89000 * * * 0 2 * 0
-MONK * * * 89000 * SKILLS * 0 0 * 0
diff --git a/gemrb/override/bg1/damage.2da b/gemrb/override/bg1/damage.2da
deleted file mode 100644
index 179722a..0000000
--- a/gemrb/override/bg1/damage.2da
+++ /dev/null
@@ -1,16 +0,0 @@
-2DA V1.0
-*
- MAIN SPARKS GRADIENT
-CRIT BLOODCR * 47
-SMALL BLOODS * 47
-MEDIUM BLOODM * 47
-LARGE BLOODL * 47
-FIRES SPFIRIMP SPBURN 19
-FIREM SPFIRIMP SPBURN 19
-FIREL SPFIRIMP SPBURN 19
-SPARKS SPSHKIMP SPSPARKS -1
-SPARKM SPSHKIMP SPSPARKS -1
-SPARKL SPSHKIMP SPSPARKS -1
-ICES FIRIMP * 71
-ICEM FIRIMP * 71
-ICEL FIRIMP * 71
diff --git a/gemrb/override/bg1/defsound.2da b/gemrb/override/bg1/defsound.2da
deleted file mode 100644
index 22cfee3..0000000
--- a/gemrb/override/bg1/defsound.2da
+++ /dev/null
@@ -1,29 +0,0 @@
-2DA V1.0
-*
- RESREF
-OPEN AMB_D03A
-CLOSE AMB_D03B
-HOPEN AMB_D04A
-HCLOSE AMB_D04B
-BUTTON1 GAM_09
-BUTTON2 GAM_03
-BUTTON3 GAM_04
-OPENFAIL *
-CLOSEFAIL *
-ITEM_GONE EFF_M02
-SECRET ACT_09
-11 *
-12 *
-13 *
-14 *
-15 *
-16 *
-17 *
-18 *
-19 *
-LIGHTNING1 AMB_E13A
-LIGHTNING2 AMB_E13B
-LIGHTNING3 AMB_E13F
-RAIN AMB_E11
-SNOW AMB_E02B
-
diff --git a/gemrb/override/bg1/effects.ids b/gemrb/override/bg1/effects.ids
deleted file mode 100644
index e122471..0000000
--- a/gemrb/override/bg1/effects.ids
+++ /dev/null
@@ -1,319 +0,0 @@
-IDS
-0x0 ACVsDamageTypeModifier
-0x1 AttacksPerRoundModifier
-0x2 Cure:Sleep
-0x3 State:Berserk
-0x4 Cure:Berserk
-0x5 State:Charmed
-0x6 CharismaModifier
-0x7 Color:SetPalette
-0x8 Color:SetRGB
-0x9 Color:PulseRGB
-0xa ConstitutionModifier
-0xb Cure:Poison
-0xc Damage
-0xd Death
-0xe Cure:Defrost
-0xf DexterityModifier
-0x10 State:Hasted
-0x11 CurrentHPModifier
-0x12 MaximumHPModifier
-0x13 IntelligenceModifier
-0x14 State:Invisible
-0x15 LoreModifier
-0x16 LuckModifier
-0x17 MoraleModifier
-0x18 State:Panic
-0x19 State:Poisoned
-0x1a RemoveCurse
-0x1b AcidResistanceModifier
-0x1c ColdResistanceModifier
-0x1d ElectricityResistanceModifier
-0x1e FireResistanceModifier
-0x1f MagicDamageResistanceModifier
-0x20 Cure:Death
-0x21 SaveVsDeathModifier
-0x22 SaveVsWandsModifier
-0x23 SaveVsPolyModifier
-0x24 SaveVsBreathModifier
-0x25 SaveVsSpellsModifier
-0x26 State:Silenced
-0x27 State:Helpless
-0x28 State:Slowed
-0x29 Sparkle
-0x2a WizardSpellSlotsModifier
-0x2b Cure:Petrification
-0x2c StrengthModifier
-0x2d State:Stun
-0x2e Cure:Stun
-0x2f Cure:Invisible
-0x30 Cure:Silence
-0x31 WisdomModifier
-0x32 Color:BriefRGB
-0x33 Color:DarkenRGB
-0x34 Color:GlowRGB
-0x35 AnimationIDModifier
-0x36 ToHitModifier
-0x37 KillCreatureType
-0x38 Alignment:Invert
-0x39 Alignment:Change
-0x3a DispelEffects
-0x3b StealthModifier
-0x3c MiscastMagicModifier
-0x3d AlchemyModifier
-0x3e PriestSpellSlotsModifier
-0x3f State:Infravision
-0x40 Cure:Infravision
-0x41 State:Blur
-0x42 TransparencyModifier
-0x43 SummonCreature
-0x44 UnsummonCreature
-0x45 State:NonDetection
-0x46 Cure:NonDetection
-0x47 SexModifier
-0x48 AIIdentifierModifier
-0x49 DamageBonusModifier
-0x4a State:Blind
-0x4b Cure:Blind
-0x4c State:Feeblemind
-0x4d Cure:Feeblemind
-0x4e State:Diseased
-0x4f Cure:Disease
-0x50 State:Deafness
-0x51 Cure:Deafness
-0x52 SetAIScript
-0x53 Protection:Projectile
-0x54 MagicalFireResistanceModifier
-0x55 MagicalColdResistanceModifier
-0x56 SlashingResistanceModifier
-0x57 CrushingResistanceModifier
-0x58 PiercingResistanceModifier
-0x59 MissilesResistanceModifier
-0x5a OpenLocksModifier
-0x5b FindTrapsModifier
-0x5c PickPocketsModifier
-0x5d FatigueModifier
-0x5e IntoxicationModifier
-0x5f TrackingModifier
-0x60 LevelModifier
-0x61 StrengthBonusModifier
-0x62 State:Regenerating
-0x63 SpellDurationModifier
-0x64 Protection:Creature
-0x65 Protection:Opcode
-0x66 Protection:SpellLevel
-0x67 ChangeName
-0x68 ExperienceModifier
-0x69 GoldModifier
-0x6a MoraleBreakModifier
-0x6b PortraitChange
-0x6c ReputationModifier
-0x6d State:HoldNoIcon
-0x6e RetreatFrom
-0x6f Item:CreateMagic
-0x70 Item:Remove
-0x71 Item:Equip
-0x72 Dither
-0x73 DetectAlignment
-0x74 Cure:Invisible2
-0x75 Reveal:Area
-0x76 Reveal:Creatures
-0x77 MirrorImage
-0x78 Protection:Weapons
-0x79 VisualAnimationEffect
-0x7a Item:CreateInventory
-0x7b Item:RemoveInventory
-0x7c DimensionDoor
-0x7d Unlock
-0x7e MovementRateModifier
-0x7f MonsterSummoning
-0x80 State:Confused
-0x81 AidNonCumulative
-0x82 BlessNonCumulative
-0x83 ChantNonCumulative
-0x84 HolyNonCumulative
-0x85 LuckNonCumulative
-0x86 State:Petrification
-0x87 Polymorph
-0x88 ForceVisible
-0x89 ChantBadNonCumulative
-0x8a AnimationStateChange
-0x8b DisplayString
-0x8c CastingGlow
-0x8d VisualSpellHit
-0x8e Icon:Display
-0x8f Item:CreateInSlot
-0x90 DisableButton
-0x91 DisableCasting
-0x92 Spell:Cast
-0x93 Spell:Learn
-0x94 Spell:CastPoint
-0x95 Identify
-0x96 FindTraps
-0x97 ReplaceCreature
-0x98 PlayMovie
-0x99 Overlay:Sanctuary
-0x9a Overlay:Entangle
-0x9b Overlay:MinorGlobe
-0x9c Overlay:ShieldGlobe
-0x9d Overlay:Web
-0x9e Overlay:Grease
-0x9f MirrorImageModifier
-0xa0 Cure:Sanctuary
-0xa1 Cure:Panic
-0xa2 Cure:Hold
-0xa3 FreeAction
-0xa4 Cure:Intoxication
-0xa5 PauseTarget
-0xa6 MagicResistanceModifier
-0xa7 MissileHitModifier
-0xa8 RemoveCreature
-0xa9 Icon:Disable
-0xaa DamageAnimation
-0xab Spell:Add
-0xac Spell:Remove
-0xad PoisonResistanceModifier
-0xae PlaySound
-0xaf State:Hold
-0xb0 MovementRateModifier2
-0xb1 ApplyEffect
-0xb2 ToHitVsCreature
-0xb3 DamageVsCreature
-0xb4 CantUseItem
-0xb5 CantUseItemType
-0xb6 ApplyEffectItem
-0xb7 ApplyEffectItemType
-0xb8 DontJumpModifier
-0xb9 State:Hold2
-0xba MoveToArea
-0xbb Variable:StoreLocalVariable
-0xbc AuraCleansingModifier
-0xbd CastingSpeedModifier
-0xbe AttackSpeedModifier
-0xbf CastingLevelModifier
-0xc0 FindFamiliar
-0xc1 InvisibleDetection
-0xc2 IgnoreDialogPause
-0xc3 FamiliarBond
-0xc4 FamiliarMarker
-0xc5 Bounce:Projectile
-0xc6 Bounce:Opcode
-0xc7 Bounce:SpellLevel
-0xc8 Bounce:SpellLevelDec
-0xc9 Protection:SpellLevelDec
-0xca Bounce:School
-0xcb Bounce:SecondaryType
-0xcc Protection:School
-0xcd Protection:SecondaryType
-0xce Protection:Spell
-0xcf Bounce:Spell
-0xd0 MinimumHPModifier
-0xd1 PowerWordKill
-0xd2 PowerWordStun
-0xd3 State:Imprisonment
-0xd4 Cure:Imprisonment
-0xd5 Maze
-0xd6 CastFromList
-0xd7 PlayVisualEffect
-0xd8 LevelDrainModifier
-0xd9 PowerWordSleep
-0xda StoneskinModifier
-0xdb ACVsCreatureType
-0xdc DispelSchool
-0xdd DispelSecondaryType
-0xde RandomTeleport
-0xdf Protection:SchoolDec
-0xe0 Cure:LevelDrain
-0xe1 Reveal:Magic
-0xe2 Protection:SecondaryTypeDec
-0xe3 Bounce:SchoolDec
-0xe4 Bounce:SecondaryTypeDec
-0xe5 DispelSchoolOne
-0xe6 DispelSecondaryTypeOne
-0xe7 TimeStop
-0xe8 CastSpellOnCondition
-0xe9 Proficiency
-0xea CreateContingency
-0xeb WingBuffet
-0xec ProjectImage
-0xed PuppetMarker
-0xee Disintegrate
-0xef Farsee
-0xf0 Icon:Remove
-0xf1 ControlCreature
-0xf2 Cure:Confusion
-0xf3 DrainItems
-0xf4 DrainSpells
-0xf5 CheckForBerserkModifier
-0xf6 BerserkStage1Modifier
-0xf7 BerserkStage2Modifier
-0xf8 SetMeleeEffect
-0xf9 SetRangedEffect
-0xfa DamageLuckModifier
-0xfb ChangeBardSong
-0xfc SetTrap
-0xfd SetMapNote
-0xfe RemoveMapNote
-0xff Item:CreateDays
-0x100 Sequencer:Store
-0x101 Sequencer:Create
-0x102 Sequencer:Activate
-0x103 SpellTrap
-0x104 *Crash*
-0x105 RestoreSpells
-0x106 VisualRangeModifier
-0x107 BackstabModifier
-0x108 DropWeapon
-0x109 ModifyGlobalVariable
-0x10a RemoveImmunity
-0x10b Protection:String
-0x10c ExploreModifier
-0x10d ScreenShake
-0x10e Cure:CasterHold
-0x10f SummonDisable
-0x110 ApplyEffectRepeat
-0x111 RemoveProjectile
-0x112 TeleportToTarget
-0x113 HideInShadowsModifier
-0x114 DetectIllusionsModifier
-0x115 SetTrapsModifier
-0x116 ToHitBonusModifier
-0x117 RenableButton
-0x118 ForceSurgeModifier
-0x119 WildSurgeModifier
-0x11a ScriptingState
-0x11b ApplyEffectCurse
-0x11c MeleeHitModifier
-0x11d MeleeDamageModifier
-0x11e MissileDamageModifier
-0x11f NoCircleState
-0x120 FistHitModifier
-0x121 FistDamageModifier
-0x122 TitleModifier
-0x123 DisableOverlay
-0x124 Protection:Backstab
-0x125 OffscreenAIModifier
-0x126 ExistanceDelayModifier
-0x127 DisableChunk
-0x128 Protection:Animation
-0x129 Protection:Turn
-0x12a Cutscene2
-0x12b ChaosShieldModifier
-0x12c NPCBump
-0x12d CriticalHitModifier
-0x12e CanUseAnyItem
-0x12f AlwaysBackstab
-0x130 MassRaiseDead
-0x131 OffhandHitModifier
-0x132 RightHitModifier
-0x133 Reveal:Tracks
-0x134 Protection:Tracking
-0x135 ModifyLocalVariable
-0x136 TimelessState
-0x137 GenerateWish
-0x138 *Crash*
-0x139 HLA
-0x13a StoneSkin2Modifier
-0x13b AvatarRemovalModifier
-0x13c MagicalRest
-0x13d State:Haste2
diff --git a/gemrb/override/bg1/efftext.2da b/gemrb/override/bg1/efftext.2da
new file mode 100644
index 0000000..78829b0
--- /dev/null
+++ b/gemrb/override/bg1/efftext.2da
@@ -0,0 +1,10 @@
+2DA V1.0
+-1
+ EFFECT_NAME STRREF
+25 POISON 14017
+13 DEATH 14026
+134 PETRIFICATION 14127
+#12 DAMAGE 14027
+39 SLEEP 20438
+68 UNSUMMON 14065
+
diff --git a/gemrb/override/bg1/fonts.2da b/gemrb/override/bg1/fonts.2da
deleted file mode 100644
index bfde90b..0000000
--- a/gemrb/override/bg1/fonts.2da
+++ /dev/null
@@ -1,14 +0,0 @@
-2DA V1.0
-NORMAL
- RESREF NEED_PALETTE FIRST_CHAR
-0 NORMAL 1 0
-1 TOOLFONT 1 0
-2 NUMBER 0 47
-3 INITIALS 0 0
-4 NUMBER2 0 47
-5 NUMBER3 0 47
-6 REALMS 0 0
-7 STONEBIG 0 0
-8 STONESML 0 0
-9 STATES 0 0
-10 STATES2 0 0
diff --git a/gemrb/override/bg1/gemrb.ini b/gemrb/override/bg1/gemrb.ini
deleted file mode 100644
index 6544362..0000000
--- a/gemrb/override/bg1/gemrb.ini
+++ /dev/null
@@ -1,80 +0,0 @@
-; GemRB - Infinity Engine Emulator
-; Copyright (C) 2003 The GemRB Project
-;
-; This program is free software; you can redistribute it and/or
-; modify it under the terms of the GNU General Public License
-; as published by the Free Software Foundation; either version 2
-; of the License, or (at your option) any later version.
-;
-; This program is distributed in the hope that it will be useful,
-; but WITHOUT ANY WARRANTY; without even the implied warranty of
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-; GNU General Public License for more details.
-;
-; You should have received a copy of the GNU General Public License
-; along with this program; if not, write to the Free Software
-; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-;
-
-
-; gemrb.ini - game type-specific settings for GemRB engine
-
-[resources]
-
-; Bitmap resource for cursors
-CursorBAM = CAROT
-
-; Bitmap resource for scroll cursor arrow
-ScrollCursorBAM = CURSARW
-
-; Bitmap resource for dialog buttons font
-ButtonFont = STONESML
-
-; Font used to display tooltips
-TooltipFont = TOOLFONT
-
-; Sprite displayed behind the tooltip text, if any
-TooltipBack = TOOLTIP
-
-; Tooltip text color (RGBA)
-TooltipColor = #f0b08000
-
-; Space between tooltip text and sides of TooltipBack (x2)
-#TooltipMargin = 10
-TooltipMargin = 5
-
-; INI file from the original games
-INIConfig = baldur.ini
-
-; Palette bitmaps in various widths
-Palette16 = MPALETTE
-Palette32 = MPALETTE
-Palette256 = MPAL256
-
-MaximumAbility = 25
-IgnoreButtonFrames = 0
-AllStringsTagged = 1
-HasDPLAYER = 1
-HasPickSound = 0
-HasDescIcon = 1
-HasEXPTABLE = 0
-SoundFolders = 0
-HasSongList = 0
-UpperButtonText = 1
-ReverseToHit = 1
-LowerLabelText = 1
-HasPartyINI = 0
-HasBeastsINI = 0
-ForceStereo = 1
-IWDMapDimensions = 0
-SmallFog = 1
-DialogueScrolls = 0
-RedrawTile = 1
-DeathOnZeroStat = 1
-BreakableWeapons = 1
-HasSpecificDamageBonus = 0
-CutsceneAreascripts = 1
-FlexibleWorldmap = 0
-AutoSearchHidden = 1
-PSTStateFlags = 0
-NoDropCanMove = 1
diff --git a/gemrb/override/bg1/guibtact.2da b/gemrb/override/bg1/guibtact.2da
deleted file mode 100644
index 2077854..0000000
--- a/gemrb/override/bg1/guibtact.2da
+++ /dev/null
@@ -1,37 +0,0 @@
-2DA V1.0
-100
- 1 2 3 4 TOOLTIP RESREF
-Stealth 30 31 32 33 4968 guibtact
-Thieving 26 27 28 29 4971 guibtact
-Cast 12 13 52 53 4688 guibtact
-QSpell1 8 9 32 33 4938 guibtbut
-QSpell2 10 11 34 35 4938 guibtbut
-QSpell3 12 13 36 37 4938 guibtbut
-Turn 8 9 10 11 4974 guibtact
-Talk 4 5 6 7 4933 guibtact
-UseItem 18 19 56 57 4978 guibtact
-QItem1 14 15 38 39 4937 guibtbut
-QItem4 16 17 40 41 4937 guibtbut
-QItem2 18 19 42 43 4937 guibtbut
-QItem3 20 21 44 45 4937 guibtbut
-Innate 38 39 54 55 4954 guibtact
-Defend 0 1 2 3 15925 guibtact
-Attack 14 15 16 17 4666 guibtact
-QWeapon1 0 1 24 25 4950 guibtbut
-QWeapon2 2 3 26 27 4950 guibtbut
-QWeapon3 4 5 28 29 4950 guibtbut
-QWeapon4 6 7 30 31 4950 guibtbut
-BardSong 22 23 24 25 11798 guibtact
-Stop 58 59 60 61 15924 guibtact
-Search 34 35 36 37 4927 guibtact
-23 * * * * * *
-24 * * * * * *
-25 * * * * * *
-26 * * * * * *
-27 * * * * * *
-28 * * * * * *
-29 * * * * * *
-30 * * * * * *
-31 * * * * * *
-Left 44 45 100 100 100 guibtact
-Right 43 44 100 100 100 guibtact
diff --git a/gemrb/override/bg1/magesch.2da b/gemrb/override/bg1/magesch.2da
deleted file mode 100644
index 3e8697b..0000000
--- a/gemrb/override/bg1/magesch.2da
+++ /dev/null
@@ -1,13 +0,0 @@
-2DA V1.0
--1
- NAME_REF DESC_REF CAP_REF KIT
-GENERALIST 18039 9563 9987 0x4000
-ABJURER 597 9564 502 0x40
-CONJURER 2179 9565 504 0x80
-DIVINER 2846 9566 2012 0x100
-ENCHANTER 2861 9567 2022 0x200
-ILLUSIONIST 2862 9568 8421 0x400
-INVOKER 3015 9569 12786 0x800
-NECROMANCER 12744 9570 12787 0x1000
-TRANSMUTER 12745 9571 12788 0x2000
-WILDMAGE 54893 54892 54894 0x8000
diff --git a/gemrb/override/bg1/minorglb.vvc b/gemrb/override/bg1/minorglb.vvc
new file mode 100644
index 0000000..cc2e83c
Binary files /dev/null and b/gemrb/override/bg1/minorglb.vvc differ
diff --git a/gemrb/override/bg1/overlay.2da b/gemrb/override/bg1/overlay.2da
deleted file mode 100644
index 84a944e..0000000
--- a/gemrb/override/bg1/overlay.2da
+++ /dev/null
@@ -1,35 +0,0 @@
-2DA V1.0
-*
- VVC UNDER FLAGS
-SANCTUARY SANCTRY 0 1
-ENTANGLE SPENTACI 0 0
-SPELLTRAP SPMAGGLO 0 0
-SHIELDGLOBE SPSHIELD 0 1
-GREASE GREASED 1 0
-WEB WEBENTD 1 0
-MINORGLOBE MINORGLB 0 1
-GLOBE GOINVUC 0 1
-FLAMESHROUD SOFLAMC 0 0
-ANTIMAGIC AMSHELC 0 0
-RESILIENT ORSPHEC 0 0
-PROTFROMMISS PFNMISC 0 0
-CLOAKOFFEAR COFEARC 0 0
-ENTROPY ESHIELC 0 0
-FIREAURA FIAURAC 0 0
-FROSTAURA FRAURAC 0 0
-INSECT IPLAGUC 0 0
-STORMSHELL SSHELLC 0 0
-LATHANDER1 SOLATC1 0 0
-LATHANDER2 SOLATC2 1 0
-GLATHANDER1 GSOLAC1 0 0
-GLATHANDER2 GSOLAC2 1 0
-SEVENEYES1 SEYESC1 0 0
-SEVENEYES2 SEYESC2 1 0
-BOUNCE SPTURNI2 1 0
-BOUNCE2 SPTURNI 1 0
-FIRESHIELD1 FSHIRC1 0 0
-FIRESHIELD2 FSHIRC2 1 0
-ICESHIELD1 FSHIBC1 0 0
-ICESHIELD2 FSHIBC2 1 0
-TORTOISE TSHELLC 0 0
-DEATHARMOR DARMORC 0 0
diff --git a/gemrb/override/bg1/pdolls.2da b/gemrb/override/bg1/pdolls.2da
deleted file mode 100644
index ec20464..0000000
--- a/gemrb/override/bg1/pdolls.2da
+++ /dev/null
@@ -1,86 +0,0 @@
-2DA V1.0
-*
- LEVEL1 LEVEL2 LEVEL3 LEVEL4 SIZE
-0x5000 CHMC1INV CHMC2INV CHMC3INV CHMC4INV L
-0x5001 CEMC1INV CEMC2INV CEMC3INV CEMC4INV M
-0x5002 CDMC1INV CDMC2INV CDMC3INV CDMC4INV S
-0x5003 CIMC1INV CIMC2INV CIMC3INV CIMC4INV S
-0x5010 CHFC1INV CHMC2INV CHMC3INV CHMC4INV M
-0x5011 CEFC1INV CEMC2INV CEMC3INV CEMC4INV M
-0x5012 CDMC1INV CDMC2INV CDMC3INV CDMC4INV S
-0x5013 CIFC1INV CIMC2INV CIMC3INV CIMC4INV S
-0x5100 CHMF1INV CHMF2INV CHMF3INV CHMC4INV L
-0x5101 CEMF1INV CEMF2INV CEMF3INV CEMC4INV M
-0x5102 CDMF1INV CDMF2INV CDMF3INV CDMC4INV S
-0x5103 CIMF1INV CIMF2INV CIMF3INV CIMC4INV S
-0x5110 CHFF1INV CHFF2INV CHMF3INV CHMC4INV M
-0x5111 CEFF1INV CEFF2INV CEMF3INV CEMC4INV M
-0x5112 CDMF1INV CDMF2INV CDMF3INV CDMC4INV S
-0x5113 CIFF1INV CIFF2INV CIMF3INV CIMC4INV S
-0x5200 CHMW1INV CHMW2INV CHMW3INV CHMW4INV L
-0x5201 CEMW1INV CEMW2INV CEMW3INV CEMW4INV M
-0x5202 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
-0x5203 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
-0x5210 CHFW1INV CHMW2INV CHMW3INV CHMW4INV M
-0x5211 CEFW1INV CEMW2INV CEMW3INV CEMW4INV M
-0x5212 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
-0x5213 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
-0x5300 CHMT1INV CHMT2INV CHMF3INV CHMF4INV L
-0x5301 CEMT1INV CEMT2INV CEMF3INV CEMF4INV M
-0x5302 CDMT1INV CDMT2INV CDMF3INV CDMF4INV S
-0x5303 CIMT1INV CIMT2INV CIMF3INV CIMF4INV S
-0x5310 CHFT1INV CHMT2INV CHMF3INV CHMF4INV M
-0x5311 CEFT1INV CEMT2INV CEMF3INV CEMF4INV M
-0x5312 CDMT1INV CDMT2INV CDMF3INV CDMF4INV S
-0x5313 CIFT1INV CIMT2INV CIMF3INV CIMF4INV S
-0x6000 CHMC1INV CHMC2INV CHMC3INV CHMC4INV L
-0x6001 CEMC1INV CEMC2INV CEMC3INV CEMC4INV M
-0x6002 CDMC1INV CDMC2INV CDMC3INV CDMC4INV S
-0x6003 CIMC1INV CIMC2INV CIMC3INV CIMC4INV S
-0x6004 CIMC1INV CIMC2INV CIMC3INV CIMC4INV S
-0x6005 CHMC1INV CHMC2INV CHMC3INV CHMC4INV L
-0x6010 CHFC1INV CHFC2INV CHFC3INV CHFC4INV M
-0x6011 CEFC1INV CEFC2INV CEFC3INV CEFC4INV M
-0x6012 CDMC1INV CDMC2INV CDMC3INV CDMC4INV S
-0x6013 CIFC1INV CIFC2INV CIFC3INV CIFC4INV S
-0x6014 CIFC1INV CIFC2INV CIFC3INV CIFC4INV S
-0x6015 CHFC1INV CHFC2INV CHFC3INV CHFC4INV M
-0x6100 CHMF1INV CHMF2INV CHMF3INV CHMF4INV L
-0x6101 CEMF1INV CEMF2INV CEMF3INV CEMF4INV M
-0x6102 CDMF1INV CDMF2INV CDMF3INV CDMF4INV S
-0x6103 CIMF1INV CIMF2INV CIMF3INV CIMF4INV S
-0x6104 CIMF1INV CIMF2INV CIMF3INV CIMF4INV S
-0x6105 CHMF1INV CHMF2INV CHMF3INV CHMF4INV L
-0x6110 CHFF1INV CHFF2INV CHFF3INV CHFF4INV M
-0x6111 CEFF1INV CEFF2INV CEFF3INV CEFF4INV M
-0x6112 CDMF1INV CDMF2INV CDMF3INV CDMF4INV S
-0x6113 CIFF1INV CIFF2INV CIFF3INV CIFF4INV S
-0x6114 CIFF1INV CIFF2INV CIFF3INV CIFF4INV S
-0x6115 CHFF1INV CHFF2INV CHFF3INV CHFF4INV M
-0x6200 CHMW1INV CHMW2INV CHMW3INV CHMW4INV L
-0x6201 CEMW1INV CEMW2INV CEMW3INV CHMW4INV M
-0x6202 CDMW1INV CDMW2INV CDMW3INV CHMW4INV S
-0x6203 CIMW1INV CIMW2INV CIMW3INV CHMW4INV S
-0x6204 CIMW1INV CIMW2INV CIMW3INV CHMW4INV S
-0x6205 CHMW1INV CHMW2INV CHMW3INV CHMW4INV L
-0x6210 CHFW1INV CHFW2INV CHFW3INV CHFW4INV M
-0x6211 CEFW1INV CEFW2INV CEFW3INV CHFW4INV M
-0x6212 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
-0x6213 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
-0x6214 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
-0x6215 CHFW1INV CHFW2INV CHFW3INV CHFW4INV M
-0x6300 CHMT1INV CHMT2INV CHMF3INV CHMF4INV L
-0x6301 CEMT1INV CEMT2INV CEMF3INV CEMF4INV M
-0x6302 CDMT1INV CDMT2INV CDMF3INV CDMF4INV S
-0x6303 CIMT1INV CIMT2INV CIMF3INV CIMF4INV S
-0x6304 CIMT1INV CIMT2INV CIMF3INV CIMF4INV S
-0x6305 CHMT1INV CHMT2INV CHMF3INV CHMF4INV L
-0x6310 CHFT1INV CHFT2INV CHFF3INV CHFF4INV M
-0x6311 CEFT1INV CEFT2INV CEFF3INV CEFF4INV M
-0x6312 CDMT1INV CDMT2INV CDMF3INV CDMF4INV S
-0x6313 CIFT1INV CIFT2INV CIFF3INV CIFF4INV S
-0x6314 CIFT1INV CIFT2INV CIFF3INV CIFF4INV S
-0x6315 CHFT1INV CHFT2INV CHFF3INV CHFF4INV M
-0x6402 CMNKINV CHMT2INV CHMF3INV CHMF4INV M
-0x6500 CHMM1INV CHMT2INV CHMF3INV CHMF4INV L
-0x6510 CHFM1INV CHFT2INV CHMF3INV CHMF4INV M
diff --git a/gemrb/override/bg1/qslots.2da b/gemrb/override/bg1/qslots.2da
deleted file mode 100644
index c9fc3d2..0000000
--- a/gemrb/override/bg1/qslots.2da
+++ /dev/null
@@ -1,24 +0,0 @@
-2DA V1.0
-100
- SLOT1 SLOT2 SLOT3 SLOT4 SLOT5 SLOT6 SLOT7 SLOT8 SLOT9
-DEFAULT 18 19 14 100 8 9 11 12 13
-MAGE 3 4 5 2 8 9 11 12 13
-FIGHTER 18 19 14 100 8 9 11 12 13
-CLERIC 6 3 4 2 8 9 11 12 13
-THIEF 22 0 1 100 8 9 11 12 13
-BARD 20 1 3 2 8 9 11 12 13
-PALADIN 18 14 6 2 8 9 11 12 13
-FIGHTER_MAGE 3 4 5 2 8 9 11 12 13
-FIGHTER_CLERIC 6 3 4 2 8 9 11 12 13
-FIGHTER_THIEF 18 22 0 1 8 9 11 12 13
-FIGHTER_MAGE_THIEF 22 0 1 2 8 9 11 12 13
-DRUID 3 4 5 2 8 9 11 12 13
-RANGER 18 14 0 2 8 9 11 12 13
-MAGE_THIEF 22 0 1 2 8 9 11 12 13
-CLERIC_MAGE 6 3 4 2 8 9 11 12 13
-CLERIC_THIEF 22 0 1 2 8 9 11 12 13
-FIGHTER_DRUID 3 4 5 2 8 9 11 12 13
-FIGHTER_MAGE_CLERIC 6 3 4 2 8 9 11 12 13
-CLERIC_RANGER 6 3 4 2 8 9 11 12 13
-SORCERER 3 4 5 2 8 9 11 12 13
-MONK 18 14 22 0 8 9 11 12 13
diff --git a/gemrb/override/bg1/shtable.2da b/gemrb/override/bg1/shtable.2da
deleted file mode 100644
index 5851966..0000000
--- a/gemrb/override/bg1/shtable.2da
+++ /dev/null
@@ -1,42 +0,0 @@
-2DA V1.0
-*
- RESREF
-0 SHAIR
-1 SHEARTH
-2 SHWATER
-3 *
-4 SHAIR
-5 SHEARTH
-6 SHWATER
-7 *
-8 SHAIR
-9 SHEARTH
-10 SHWATER
-11 *
-12 SHAIR
-13 SHEARTH
-14 SHWATER
-15 *
-16 SHAIR
-17 SHEARTH
-18 SHWATER
-19 *
-20 SHAIR
-21 SHEARTH
-22 SHWATER
-23 *
-24 SHAIR
-25 SHEARTH
-26 SHWATER
-27 *
-28 SHAIR
-29 SHEARTH
-30 SHWATER
-31 *
-32
-33
-34
-35 FLMSTRK
-36 HLYMITE
-37
-38 SPDIMDR
diff --git a/gemrb/override/bg1/strings.2da b/gemrb/override/bg1/strings.2da
deleted file mode 100644
index f18b722..0000000
--- a/gemrb/override/bg1/strings.2da
+++ /dev/null
@@ -1,170 +0,0 @@
-2DA V1.0
--1
- STRREF
-SCATTERED 16457
-WHOLEPARTY 16484
-DOORLOCKED 16485
-MAGICTRAP 16486
-NORMALTRAP 16487
-TRAP 16488
-CANNOTGO 16489
-TRAPREMOVED 16490
-OVERSTOCKED 16491
-SLEEP 16492
-AMBUSH 16493
-CONTLOCKED 16494
-NOMONEY 16495
-CURSED 16496
-SPELLDISRUPT 16497
-DIED 16498
-MAYNOTREST 16499
-CANTRESTMONS 16500
-CANTSAVEMONS 16501
-CANTSAVE 16502
-NODIALOG 10945
-CANTSAVEDIALOG 19253
-CANTSAVEDIALOG2 19254
-CANTSAVEMOVIE 19255
-TARGETBUSY -1
-CANTTALKTRANS -1
-GOTGOLD 17572
-LOSTGOLD 17573
-GOTXP 17574
-LOSTXP 17575
-GOTITEM 17576
-LOSTITEM 17577
-GOTREP 19686
-LOSTREP 19687
-GOTABILITY 10514
-GOTSPELL 10514
-GOTSONG 10514
-NOTHINGTOSAY -1
-JOURNALCHANGE 11359
-WORLDMAPCHANGE 11360
-PAUSED 16321
-UNPAUSED 16322
-SCRIPTPAUSED -1
-AP_UNUSABLE 17113
-AP_ATTACKED 17114
-AP_HIT 17115
-AP_WOUNDED 17116
-AP_DEAD 17117
-AP_NOTARGET 17118
-AP_ENDROUND 10014
-AP_ENEMY 23511
-AP_TRAP -1
-AP_SPELLCAST -1
-AP_RESERVED1 -1
-AP_RESERVED2 -1
-AP_RESERVED3 -1
-AP_RESERVED4 -1
-CHARMED 14672
-DIRECHARMED 14780
-CONTROLLED -1
-EVIL 16505
-GNE_NEUTRAL 16504
-GOOD 16503
-STR_LAWFUL -1
-LNC_NEUTRAL -1
-CHAOTIC -1
-ACTION_CAST 16464
-ACTION_ATTACK 16465
-ACTION_TURN 16466
-ACTION_SONG 16467
-ACTION_FINDTRAP 16468
-MAGICWEAPON 10141
-OFFHAND_USED 9380
-TWOHANDED_USED 9381
-CANNOT_USE_ITEM 9382
-CANT_DROP_ITEM 25697
-NOT_IN_OFFHAND 9375
-ITEM_IS_CURSED 16304
-NO_CRITICAL 20696
-TRACKING -1
-TRACKINGFAILED -1
-DOOR_NOPICK 23169
-CONT_NOPICK 23169
-CANTSAVECOMBAT -1
-CANTSAVENOCTRL -1
-LOCKPICK_DONE 16517
-LOCKPICK_FAILED 16518
-STATIC_DISSIPATE -1
-LIGHTNING_DISSIPATE -1
-HAS_NO_ABILITY 17317
-NEEDS_IDENTIFY 17316
-WRONG_ITEMTYPE 9375
-HAS_ITEMEXCL 20685
-PICKPOCKET_DONE 10072
-PICKPOCKET_NONE 10070
-PICKPOCKET_FAIL 10069
-PICKPOCKET_EVIL 10068
-PICKPOCKET_ARMOR 10067
-USING_FEAT -1
-STOPPED_FEAT -1
-DISARM_DONE 16520
-DISARM_FAIL 1608
-DOORBASH_DONE 9915
-DOORBASH_FAIL 9913
-CONTBASH_DONE 9916
-CONTBASH_FAIL 9914
-MAYNOTSETTRAP -1
-SNAREFAILED -1
-SNARESUCCEED -1
-NOMORETRAP -1
-DISABLEDMAGE 8856
-SAVESUCCEED 1682
-QSAVESUCCEED 10237
-UNINJURED -1
-INJURED1 -1
-INJURED2 -1
-INJURED3 -1
-INJURED4 -1
-HOURS 10700
-HOUR 10701
-DAYS 10697
-DAY 10698
-REST 10690
-JOURNEY 10689
-PST_REST -1
-PST_HOUR -1
-PST_HOURS -1
-DAMAGE_IMMUNITY -1
-DAMAGE_STR1 14027
-DAMAGE_STR2 -1
-DAMAGE_STR3 -1
-DMG_POISON -1
-DMG_MAGIC -1
-DMG_MISSILE -1
-DMG_SLASHING -1
-DMG_PIERCING -1
-DMG_CRUSHING -1
-DMG_FIRE -1
-DMG_ELECTRIC -1
-DMG_COLD -1
-DMG_ACID -1
-DMG_OTHER -1
-GOTQUESTXP -1
-LEVELUP 17119
-INVFULL_ITEMDROP 24106
-CONT_DUP -1
-CONT_TRIG -1
-CONT_FAIL -1
-SEQ_DUP -1
-CRITICAL_HIT 16462
-CRITICAL_MISS 16463
-DEATH 14026
-BACKSTAB 12128
-BACKSTAB_BAD 10013
-BACKSTAB_FAIL -1
-CASTER_LVL_INC -1
-CASTER_LVL_DEC -1
-CHARS_EXPORTED -1
-PALADIN_FALL 19620
-RANGER_FALL 19621
-RES_RESISTED -1
-DEADMAGIC_FAIL -1
-MISCASTMAGIC -1
-WILDSURGE -1
-FAMBLOCK -1
-FAMPROTAGONIST -1
-
diff --git a/gemrb/override/bg2/CMakeLists.txt b/gemrb/override/bg2/CMakeLists.txt
deleted file mode 100644
index 63e7249..0000000
--- a/gemrb/override/bg2/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-ADD_GEMRB_OVERRIDE (bg2)
\ No newline at end of file
diff --git a/gemrb/override/bg2/Makefile.am b/gemrb/override/bg2/Makefile.am
index 7589bd2..32e6c50 100644
--- a/gemrb/override/bg2/Makefile.am
+++ b/gemrb/override/bg2/Makefile.am
@@ -1,3 +1,3 @@
-bg2override_DATA = *.2da *.ini *.chu *.ids *.vvc *.spl *.pro
+bg2override_DATA = *.2da *.vvc
bg2overridedir = $(moddir)/override/bg2/
-EXTRA_DIST = *.2da *.ini *.chu *.ids *.vvc *.spl *.pro
+EXTRA_DIST = *.2da *.vvc
diff --git a/gemrb/override/bg2/avatars.2da b/gemrb/override/bg2/avatars.2da
deleted file mode 100644
index 7135565..0000000
--- a/gemrb/override/bg2/avatars.2da
+++ /dev/null
@@ -1,332 +0,0 @@
-2DA V1.0
-*
- AT_1 AT_2 AT_3 AT_4 TYPE SPACE PALETTE SIZE
-0x0100 SPCHUNKS SPCHUNKS SPCHUNKS SPCHUNKS 13 0 0 *
-0x0300 SPSMPUFF SPSMPUFF SPSMPUFF SPSMPUFF 13 0 0 *
-0x0400 SKLH SKLH SKLH SKLH 13 0 1 *
-0x0410 GLPHWRDH GLPHWRDH GLPHWRDH GLPHWRDH 13 0 1 *
-0x1000 MWYV MWYV MWYV MWYV 11 3 1 *
-0x1100 MTAN MTAN MTAN MTAN 11 3 1 *
-0x1200 MDR1 MDR1 MDR1 MDR1 12 7 1 *
-0x1201 MDR2 MDR2 MDR2 MDR2 12 7 1 *
-0x1202 MDR3 MDR3 MDR3 MDR3 12 7 1 *
-0x1203 MDR1 MDR1 MDR1 MDR1 12 7 GR *
-0x1204 MDR1 MDR1 MDR1 MDR1 12 7 AQ *
-0x1205 MDR1 MDR1 MDR1 MDR1 12 7 BL *
-0x1206 MDR1 MDR1 MDR1 MDR1 12 7 BR *
-0x1207 MDR1 MDR1 MDR1 MDR1 12 7 MC *
-0x1208 MDR1 MDR1 MDR1 MDR1 12 7 PU *
-0x2000 MSIR MSIR MSIR MSIR 2 2 0 *
-0x2100 UVOL UVOL UVOL UVOL 2 2 1 *
-0x2200 MOGM MOGM MOGM MOGM 2 2 0 S
-0x2300 MDKN MDKN MDKN MDKN 2 2 1 *
-0x3000 MAKH MAKH MAKH MAKH 2 3 1 *
-0x4000 SNOMC SNOMC SNOMC SNOMC 1 2 0 *
-0x4002 SNOMM SNOMM SNOMM SNOMM 1 2 0 *
-0x4010 SNOWC SNOWC SNOWC SNOWC 1 2 0 *
-0x4012 SNOWM SNOWM SNOWM SNOWM 1 2 0 *
-0x4100 SSIMC SSIMC SSIMC SSIMC 1 2 0 *
-0x4101 SSIMS SSIMS SSIMS SSIMS 1 2 0 *
-0x4102 SSIMM SSIMM SSIMM SSIMM 1 2 0 *
-0x4110 SSIWC SSIWC SSIWC SSIWC 1 2 0 *
-0x4112 SSIWM SSIWM SSIWM SSIWM 1 2 0 *
-0x4200 SHMCM SHMCM SHMCM SHMCM 1 2 0 *
-0x4300 MSPLG1 MSPLG1 MSPLG1 MSPLG1 1 2 1 *
-0x4400 LHMC LHMC LHMC LHMC 1 2 0 *
-0x4410 LHFC LHFC LHFC LHFC 1 2 0 *
-0x4500 LFAM LFAM LFAM LFAM 1 2 0 *
-0x4600 LDMF LDMF LDMF LDMF 1 2 0 *
-0x4700 LEMF LEMF LEMF LEMF 1 2 0 *
-0x4710 LEFF LEFF LEFF LEFF 1 2 0 *
-0x4800 LIMC LIMC LIMC LIMC 1 2 0 *
-0x5000 CHMB1 CHMB2 CHMB3 CHMC4 0 2 0 L
-0x5001 CEMB1 CEMB2 CEMB3 CEMC4 0 2 0 M
-0x5002 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 S
-0x5003 CIMB1 CIMB2 CIMB3 CIMC4 0 2 0 S
-0x5010 CHFB1 CHFB2 CHFB3 CHFC4 0 2 0 N
-0x5011 CEFB1 CEFB2 CEFB3 CEFC4 0 2 0 M
-0x5012 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 S
-0x5013 CIFB1 CIFB2 CIFB3 CIFC4 0 2 0 S
-0x5100 CHMB1 CHMB2 CHMB3 CHMF4 0 2 0 L
-0x5101 CEMB1 CEMB2 CEMB3 CHMF4 0 2 0 M
-0x5102 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 S
-0x5103 CIMB1 CIMB2 CIMB3 CIMF4 0 2 0 S
-0x5110 CHFB1 CHFB2 CHFB3 CHFF4 0 2 0 N
-0x5111 CEFB1 CEFB2 CEFB3 CEFF4 0 2 0 M
-0x5112 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 S
-0x5113 CIFB1 CIFB2 CIFB3 CIFF4 0 2 0 S
-0x5200 CHMW1 CHMW2 CHMW3 CHMW4 0 2 0 L
-0x5201 CEMW1 CEMW2 CEMW3 CEMW4 0 2 0 M
-0x5202 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
-0x5203 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
-0x5210 CHFW1 CHFW2 CHFW3 CHFW4 0 2 0 N
-0x5211 CEFW1 CEFW2 CEFW3 CEFW4 0 2 0 M
-0x5212 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
-0x5213 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
-0x5300 CHMB1 CHMT2 CHMB3 CHMF4 0 2 0 L
-0x5301 CEMB1 CEMT2 CEMB3 CEMF4 0 2 0 M
-0x5302 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 S
-0x5303 CIMB1 CIMT2 CIMB3 CIMF4 0 2 0 S
-0x5310 CHFB1 CHFT2 CHFB3 CHFF4 0 2 0 N
-0x5311 CEFB1 CEFT2 CEFB3 CEFF4 0 2 0 M
-0x5312 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 S
-0x5313 CIFB1 CIFT2 CIFB3 CIFF4 0 2 0 S
-0x6000 CHMB1 CHMB2 CHMB3 CHMC4 0 2 0 L
-0x6001 CEMB1 CEMB2 CEMB3 CEMC4 0 2 0 M
-0x6002 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 S
-0x6003 CIMB1 CIMB2 CIMB3 CIMC4 0 2 0 S
-0x6004 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 S
-0x6005 CHMB1 CHMB2 CHMB3 CHMC4 0 2 0 L
-0x6010 CHFB1 CHFB2 CHFB3 CHFC4 0 2 0 N
-0x6011 CEFB1 CEFB2 CEFB3 CEFC4 0 2 0 M
-0x6012 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 S
-0x6013 CIFB1 CIFB2 CIFB3 CIFC4 0 2 0 S
-0x6014 CIFB1 CIFB2 CIFB3 CIFC4 0 2 0 S
-0x6015 CHFB1 CHFB2 CHFB3 CHFC4 0 2 0 N
-0x6100 CHMB1 CHMB2 CHMB3 CHMF4 0 2 0 L
-0x6101 CEMB1 CEMB2 CEMB3 CEMF4 0 2 0 M
-0x6102 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 S
-0x6103 CIMB1 CIMB2 CIMB3 CIMF4 0 2 0 S
-0x6104 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 S
-0x6105 CHMB1 CHMB2 CHMB3 CHMF4 0 2 0 L
-0x6110 CHFB1 CHFB2 CHFB3 CHFF4 0 2 0 N
-0x6111 CEFB1 CEFB2 CEFB3 CEFF4 0 2 0 M
-0x6112 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 S
-0x6113 CIFB1 CIFB2 CIFB3 CIFF4 0 2 0 S
-0x6114 CIFB1 CIFB2 CIFB3 CIFF4 0 2 0 S
-0x6115 CHFB1 CHFB2 CHFB3 CHFF4 0 2 0 N
-0x6200 CHMW1 CHMW2 CHMW3 CHMW4 0 2 0 L
-0x6201 CEMW1 CEMW2 CEMW3 CEMW4 0 2 0 M
-0x6202 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
-0x6203 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
-0x6204 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
-0x6205 CHMW1 CHMW2 CHMW3 CHMW4 0 2 0 L
-0x6210 CHFW1 CHFW2 CHFW3 CHFW4 0 2 0 N
-0x6211 CEFW1 CEFW2 CEFW3 CEFW4 0 2 0 M
-0x6212 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
-0x6213 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
-0x6214 CDMW1 CIFW2 CIFW3 CIFW4 0 2 0 S
-0x6215 CHFW1 CHFW2 CHFW3 CHFW4 0 2 0 N
-0x6300 CHMB1 CHMT2 CHMB3 CHMF4 0 2 0 L
-0x6301 CEMB1 CEMT2 CEMB3 CEMF4 0 2 0 M
-0x6302 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 S
-0x6303 CIMB1 CIMT2 CIMB3 CIMF4 0 2 0 S
-0x6304 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 S
-0x6305 CHMB1 CHMT2 CHMB3 CHMF4 0 2 0 L
-0x6310 CHFB1 CHFT2 CHFB3 CHFF4 0 2 0 N
-0x6311 CEFB1 CEFT2 CEFB3 CEFF4 0 2 0 M
-0x6312 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 S
-0x6313 CIFB1 CIFT2 CIFB3 CIFF4 0 2 0 S
-0x6314 CIFB1 CIFT2 CIFB3 CIFF4 0 2 0 S
-0x6315 CHFB1 CHFT2 CHFT3 CHFF4 0 2 0 N
-0x6400 UDRZ1 UDRZ1 UDRZ1 UDRZ1 6 2 0 *
-0x6401 UELM1 UELM1 UELM1 UELM1 6 2 1 *
-0x6402 CMNK1 CMNK1 CMNK1 CMNK1 6 2 0 M
-0x6403 MSKL1 MSKL1 MSKL1 MSKL1 6 2 1 M
-0x6404 USAR1 USAR1 USAR1 USAR1 6 2 1 *
-0x6405 MDGU1 MDGU1 MDGU1 MDGU1 6 2 0 M
-0x6406 MDGU1 MDGU1 MDGU1 MDGU1 6 2 0 L
-0x6500 CHMM1 CHMB2 CHMB3 CHMC4 0 2 0 L
-0x6510 CHFM1 CHFB2 CHFB3 CHFC4 0 2 0 N
-0x7000 MOGH MOGH MOGH MOGH 3 2 0 *
-0x7001 MOGN MOGN MOGN MOGN 3 2 0 *
-0x7100 MBAS MBAS MBAS MBAS 2 2 1 *
-0x7101 MBAS MBAS MBAS MBAS 2 2 GR *
-0x7200 MBER MBER MBER MBER 2 2 BL *
-0x7201 MBER MBER MBER MBER 2 2 1 *
-0x7202 MBER MBER MBER MBER 2 2 CA *
-0x7203 MBER MBER MBER MBER 2 2 PO *
-0x7300 MEAE MEAE MEAE MEAE 4 2 1 *
-0x7301 MEAS MEAS MEAS MEAS 4 2 1 *
-0x7302 MEAE MEAE MEAE MEAE 4 2 SH *
-0x7310 MFIE MFIE MFIE MFIE 4 2 1 *
-0x7311 MFIS MFIS MFIS MFIS 4 2 1 *
-0x7320 MAIR MAIR MAIR MAIR 4 2 1 *
-0x7321 MAIS MAIS MAIS MAIS 4 2 1 *
-0x7400 MDOG MDOG MDOG MDOG 3 2 WI *
-0x7401 MDOG MDOG MDOG MDOG 3 2 WA *
-0x7402 MDOG MDOG MDOG MDOG 3 2 MO *
-0x7500 MDOP MDOP MDOP MDOP 2 2 1 *
-0x7501 MDOP MDOP MDOP MDOP 2 2 GR *
-0x7600 METT METT METT METT 14 2 1 *
-0x7701 MGHL MGHL MGHL MGHL 14 2 1 *
-0x7702 MGHL MGHL MGHL MGHL 14 2 RE *
-0x7703 MGHL MGHL MGHL MGHL 14 2 GA *
-0x7704 MSHD MSHD MSHD MSHD 4 2 1 *
-0x7800 MGIB MGIB MGIB MGIB 14 2 1 *
-0x7900 MSLI MSLI MSLI MSLI 3 3 GR *
-0x7901 MSLI MSLI MSLI MSLI 3 3 OL *
-0x7902 MSLI MSLI MSLI MSLI 3 3 MU *
-0x7903 MSLI MSLI MSLI MSLI 3 3 OC *
-0x7904 MSLI MSLI MSLI MSLI 3 3 1 *
-0x7A00 MSPI MSPI MSPI MSPI 14 2 GI *
-0x7A01 MSPI MSPI MSPI MSPI 3 2 HU *
-0x7A02 MSPI MSPI MSPI MSPI 3 2 PH *
-0x7A03 MSPI MSPI MSPI MSPI 3 2 SW *
-0x7A04 MSPI MSPI MSPI MSPI 3 2 WR *
-0x7B00 MWLF MWLF MWLF MWLF 2 2 1 *
-0x7B01 MWLF MWLF MWLF MWLF 2 2 WO *
-0x7B02 MWLF MWLF MWLF MWLF 2 2 DI *
-0x7B03 MWLF MWLF MWLF MWLF 2 2 WI *
-0x7B04 MWLF MWLF MWLF MWLF 2 2 VA *
-0x7B05 MWLF MWLF MWLF MWLF 2 2 DR *
-0x7B06 MWLS MWLS MWLS MWLS 2 2 1 *
-0x7C00 MXVT MXVT MXVT MXVT 2 2 0 *
-0x7C01 MTAS MTAS MTAS MTAS 2 2 1 *
-0x7D00 MZOM MZOM MZOM MZOM 2 2 0 *
-0x7E00 MWER MWER MWER MWER 2 2 1 *
-0x7E01 MGWE MGWE MGWE MGWE 2 2 1 *
-0x7F00 MTRO MTRO MTRO MTRO 4 2 1 *
-0x7F01 MMIN MMIN MMIN MMIN 4 2 1 *
-0x7F02 MBEH MBEH MBEH MBEH 4 3 1 *
-0x7F03 MIMP MIMP MIMP MIMP 4 2 1 *
-0x7F04 MIGO MIGO MIGO MIGO 15 4 1 *
-0x7F05 MDJI MDJI MDJI MDJI 4 2 1 *
-0x7F06 MDJL MDJL MDJL MDJL 4 2 1 *
-0x7F07 MGLC MGLC MGLC MGLC 4 2 1 *
-0x7F08 MOTY MOTY MOTY MOTY 4 4 1 *
-0x7F09 MSAH MSAH MSAH MSAH 4 2 1 *
-0x7F0A MGCP MGCP MGCP MGCP 4 2 1 *
-0x7F0B MGCL MGCL MGCL MGCL 4 2 1 *
-0x7F0C MKUO MKUO MKUO MKUO 4 2 1 *
-0x7F0D MLIC MLIC MLIC MLIC 4 2 1 *
-0x7F0E MDLI MDLI MDLI MDLI 4 2 1 *
-0x7F0F MTRS MTRS MTRS MTRS 4 2 1 *
-0x7F10 MRAK MRAK MRAK MRAK 4 2 1 *
-0x7F11 MUMB MUMB MUMB MUMB 4 2 1 *
-0x7F12 MVAM MVAM MVAM MVAM 4 2 1 *
-0x7F13 MSNK MSNK MSNK MSNK 4 2 1 *
-0x7F14 MGIT MGIT MGIT MGIT 4 2 1 *
-0x7F15 MBES MBES MBES MBES 4 2 1 *
-0x7F16 AMOO AMOO AMOO AMOO 4 3 1 *
-0x7F17 ARAB ARAB ARAB ARAB 4 2 1 *
-0x7F18 ADER ADER ADER ADER 4 2 1 *
-0x7F19 MDSW MDSW MDSW MDSW 4 2 1 *
-0x7F20 AGRO AGRO AGRO AGRO 4 2 1 *
-0x7F21 APHE APHE APHE APHE 4 2 1 *
-0x7F22 MVAF MVAF MVAF MVAF 4 2 1 *
-0x7F23 MSAT MSAT MSAT MSAT 4 2 1 *
-0x7F24 NPIR NPIR NPIR NPIR 4 2 1 *
-0x7F27 MDRO MDRO MDRO MDRO 4 2 1 *
-0x7F28 MKUL MKUL MKUL MKUL 15 2 1 *
-0x7F29 MFDR MFDR MFDR MFDR 4 2 1 *
-0x7F2A NSAI NSAI NSAI NSAI 4 2 1 *
-0x7F2B MMAX MMAX MMAX MMAX 4 2 1 *
-0x7F2C NSOL NSOL NSOL NSOL 4 2 1 *
-0x7F2D MWFM MWFM MWFM MWFM 4 2 1 *
-0x7F2E MRAV MRAV MRAV MRAV 4 3 1 *
-0x7F2F MSPS MSPS MSPS MSPS 15 2 1 *
-0x7F30 NBOH NBOH NBOH NBOH 4 2 1 *
-0x7F31 NELL NELL NELL NELL 4 2 1 *
-0x7F32 MSLY MSLY MSLY MSLY 4 2 1 *
-0x7F33 MKUR MKUR MKUR MKUR 4 2 1 *
-0x7F34 MDOC MDOC MDOC MDOC 4 2 1 *
-0x7F35 MMIS MMIS MMIS MMIS 4 2 1 *
-0x7F36 NSHD NSHD NSHD NSHD 4 2 1 *
-0x7F37 NIRE NIRE NIRE NIRE 4 2 1 *
-0x7F38 MEYE MEYE MEYE MEYE 2 1 1 *
-0x7F39 MMSTG1 MMSTG2 * * 57 2 1 *
-0x7F3A NIRO NIRO NIRO NIRO 4 2 1 *
-0x7F3B MSOL MSOL MSOL MSOL 4 2 1 *
-0x7F3C MASL MASL MASL MASL 4 2 1 *
-0x7F3D MMEL MMEL MMEL MMEL 4 2 1 *
-0x7F3E MFIG MFIG MFIG MFIG 4 3 1 *
-0x8000 MGNL MGNL MGNL MGNL 2 2 0 *
-0x8100 MHOB MHOB MHOB MHOB 2 2 0 *
-0x8200 MKOB MKOB MKOB MKOB 2 2 0 *
-0x9000 MOGR MOGR MOGR MOGR 5 2 0 *
-0xA000 MWYV MWYV MWYV MWYV 8 3 1 *
-0xA100 MCAR MCAR MCAR MCAR 8 3 1 *
-0xB000 ACOW ACOW ACOW ACOW 10 3 1 *
-0xB100 AHRS AHRS AHRS AHRS 10 3 1 *
-0xB200 NBEGL NBEGL NBEGL NBEGL 3 2 0 *
-0xB210 NPROL NPROL NPROL NPROL 3 2 0 *
-0xB300 NBOYL NBOYL NBOYL NBOYL 3 2 0 *
-0xB310 NGRLL NGRLL NGRLL NGRLL 3 2 0 *
-0xB400 NFAML NFAML NFAML NFAML 3 2 0 *
-0xB410 NFAWL NFAWL NFAWL NFAWL 3 2 0 *
-0xB500 NSIML NSIML NSIML NSIML 3 2 0 *
-0xB510 NSIWL NSIWL NSIWL NSIWL 3 2 0 *
-0xB600 NNOML NNOML NNOML NNOML 3 2 0 *
-0xB610 NNOWL NNOWL NNOWL NNOWL 3 2 0 *
-0xB700 NSLVL NSLVL NSLVL NSLVL 3 2 0 *
-0xC000 ABAT ABAT ABAT ABAT 3 1 1 *
-0xC100 ACAT ACAT ACAT ACAT 3 1 1 *
-0xC200 ACHK ACHK ACHK ACHK 3 1 1 *
-0xC300 ARAT ARAT ARAT ARAT 3 1 1 *
-0xC400 ASQU ASQU ASQU ASQU 3 1 1 *
-0xC500 ABAT ABAT ABAT ABAT 3 1 1 *
-0xC600 NBEGH NBEGH NBEGH NBEGH 3 2 0 *
-0xC610 NPROH NPROH NPROH NPROH 3 2 0 *
-0xC700 NBOYH NBOYH NBOYH NBOYH 3 2 0 *
-0xC710 NGRLH NGRLH NGRLH NGRLH 3 2 0 *
-0xC800 NFAMH NFAMH NFAMH NFAMH 3 2 0 *
-0xC810 NFAWH NFAWH NFAWH NFAWH 3 2 0 *
-0xC900 NSIMH NSIMH NSIMH NSIMH 3 2 0 *
-0xC910 NSIWH NSIWH NSIWH NSIWH 3 2 0 *
-0xCA00 NNOMH NNOMH NNOMH NNOMH 3 2 0 *
-0xCA10 NNOWH NNOWH NNOWH NNOWH 3 2 0 *
-0xCB00 NSLVH NSLVH NSLVH NSLVH 3 2 0 *
-0xD000 AEAGG1 AEAGG1 AEAGG1 AEAGG1 7 0 1 *
-0xD100 AGULG1 AGULG1 AGULG1 AGULG1 7 0 1 *
-0xD200 AVULG1 AVULG1 AVULG1 AVULG1 7 0 1 *
-0xD300 ABIRG1 ABIRG1 ABIRG1 ABIRG1 7 0 1 *
-0xD400 ABIRG1 ABIRG1 ABIRG1 ABIRG1 7 0 1 *
-0xE000 MCYC MCYC MCYC MCYC 9 4 1 *
-0xE010 METN METN METN METN 9 4 1 *
-0xE020 MTAN MTAN MTAN MTAN 9 4 1 *
-0xE040 MHIS MHIS MHIS MHIS 9 2 1 *
-0xE050 MLER MLER MLER MLER 9 2 1 *
-0xE060 MLIC MLIC MLIC MLIC 9 2 1 *
-0xE070 MMIN MMIN MMIN MMIN 9 2 1 *
-0xE080 MMUM MMUM MMUM MMUM 9 2 1 *
-0xE090 MMER MMER MMER MMER 9 2 1 *
-0xE0A0 MTIC MTIC MTIC MTIC 9 2 1 *
-0xE0B0 MTRO MTRO MTRO MTRO 9 2 1 *
-0xE0C0 MTSN MTSN MTSN MTSN 9 2 1 *
-0xE0D0 MUMB MUMB MUMB MUMB 9 2 1 *
-0xE0E0 MCOR MCOR MCOR MCOR 9 2 1 *
-0xE0F0 MGIC MGIC MGIC MGIC 9 2 1 *
-0xE0F1 MGLA MGLA MGLA MGLA 9 2 1 *
-0xE0F2 MWAV MWAV MWAV MWAV 9 2 1 *
-0xE200 MBET MBET MBET MBET 9 2 1 *
-0xE210 MBFI MBFI MBFI MBFI 9 2 1 *
-0xE220 MBBM MBBM MBBM MBBM 9 2 1 *
-0xE230 MBRH MBRH MBRH MBRH 9 5 1 *
-0xE300 MGHO MGHO MGHO MGHO 9 2 1 *
-0xE310 MGH2 MGH2 MGH2 MGH2 9 2 1 *
-0xE320 MGH3 MGH3 MGH3 MGH3 9 2 1 *
-0xE400 MGO1 MGO1 MGO1 MGO1 9 2 1 *
-0xE410 MGO2 MGO2 MGO2 MGO2 9 2 1 *
-0xE420 MGO3 MGO3 MGO3 MGO3 9 2 1 *
-0xE430 MGO4 MGO4 MGO4 MGO4 9 2 1 *
-0xE500 MLIZ MLIZ MLIZ MLIZ 9 2 1 *
-0xE510 MLI2 MLI2 MLI2 MLI2 9 2 1 *
-0xE520 MLI3 MLI3 MLI3 MLI3 9 2 1 *
-0xE600 MMYC MMYC MMYC MMYC 9 2 1 *
-0xE610 MMY2 MMY2 MMY2 MMY2 9 2 1 *
-0xE700 MNO1 MNO1 MNO1 MNO1 9 2 1 *
-0xE710 MNO2 MNO2 MNO2 MNO2 9 2 1 *
-0xE720 MNO3 MNO3 MNO3 MNO3 9 2 1 *
-0xE800 MOR1 MOR1 MOR1 MOR1 9 2 1 *
-0xE810 MOR2 MOR2 MOR2 MOR2 9 2 1 *
-0xE820 MOR3 MOR3 MOR3 MOR3 9 2 1 *
-0xE830 MOR4 MOR4 MOR4 MOR4 9 2 1 *
-0xE840 MOR5 MOR5 MOR5 MOR5 9 2 1 *
-0xE900 MSAL MSAL MSAL MSAL 9 2 1 *
-0xE910 MSA2 MSA2 MSA2 MSA2 9 2 1 *
-0xEA00 MSHR MSHR MSHR MSHR 9 2 1 *
-0xEA10 MSH1 MSH1 MSH1 MSH1 9 2 1 *
-0xEA20 MSH2 MSH2 MSH2 MSH2 9 2 1 *
-0xEB00 MSKT MSKT MSKT MSKT 9 2 1 *
-0xEB10 MSKA MSKA MSKA MSKA 9 2 1 *
-0xEB20 MSKB MSKB MSKB MSKB 9 2 1 *
-0xEC00 MWIG MWIG MWIG MWIG 9 2 1 *
-0xEC10 MWI2 MWI2 MWI2 MWI2 9 2 1 *
-0xEC20 MWI3 MWI3 MWI3 MWI3 9 2 1 *
-0xED00 MYU1 MYU1 MYU1 MYU1 9 2 1 *
-0xED10 MYU2 MYU2 MYU2 MYU2 9 2 1 *
-0xED20 MYU3 MYU3 MYU3 MYU3 9 2 1 *
-0xEE00 MZO2 MZO2 MZO2 MZO2 9 2 1 *
-0xEE10 MZO3 MZO3 MZO3 MZO3 9 2 1 *
-0xEF00 MWWE MWWE MWWE MWWE 9 2 1 *
diff --git a/gemrb/override/bg2/bloodclr.2da b/gemrb/override/bg2/bloodclr.2da
deleted file mode 100644
index 1b33a30..0000000
--- a/gemrb/override/bg2/bloodclr.2da
+++ /dev/null
@@ -1,29 +0,0 @@
-2DA V1.0
-0
- VALUE MIN MAX
-NORMAL 0x2f 0x1000 0xffff
-PURPLE 0x2d 0x4300 0x43ff
-MSKEL 0x25 0x5403 0x5403
-DOOMG 0x22 0x5405 0x5406
-MSKEL 0x25 0x6403 0x6403
-DOOMG 0x22 0x6405 0x6406
-YELLOW 0x32 0x7300 0x73ff
-PURPLE 0x3c 0x7500 0x75ff
-YELLOW 0x32 0x7600 0x76ff
-BLACK 0x66 0x7700 0x77ff
-SLI_GR 7 0x7900 0x7900
-SLI_OL 0x24 0x7901 0x7901
-SLI_MU 0x33 0x7902 0x7902
-SLI_OC 0x25 0x7903 0x7903
-SLIME 0x1b 0x7904 0x7904
-SPIDER 0x33 0x7a00 0x7aff
-ZOMBIE 0x25 0x7c00 0x7cff
-MTRO 0x33 0x7f00 0x7f00
-MMIN 0x3d 0x7f01 0x7f03
-MIGO 0x1a 0x7f04 0x7f04
-MGLC 0x5d 0x7f07 0x7f07
-MTRS 0x32 0x7f0f 0x7f0f
-MBES 0x3d 0x7f15 0x7f15
-MCAR 0x38 0xa100 0xa1ff
-UNDEAD 0x66 0xe300 0xe3ff
-MWWE 0x38 0xef00 0xefff
diff --git a/gemrb/override/bg2/clskills.2da b/gemrb/override/bg2/clskills.2da
deleted file mode 100644
index 0141e1b..0000000
--- a/gemrb/override/bg2/clskills.2da
+++ /dev/null
@@ -1,24 +0,0 @@
-2DA V1.0
-*
- DRUIDSPELL CLERICSPELL MAGESPELL STARTXP BARDSKILL THIEFSKILL LAYHANDS TURNLEVEL BOOKTYPE HATERACE ABILITIES STARTXP2 RANGERSKILL SAVEBONUS
-UNUSED * * * * * * * 0 0 * * * * *
-MAGE * * MXSPLWIZ 89000 * * * 0 1 * * 2500000 * 0
-FIGHTER * * * 89000 * * * 0 0 * CLABFI01 2500000 * 0
-CLERIC * MXSPLPRS * 89000 * * * 1 1 * CLABPR01 2500000 * 0
-THIEF * * * 89000 * SKILLS * 0 0 * CLABTH01 2500000 * 0
-BARD * * MXSPLBRD 89000 SKILLBRD * * 0 1 * CLABBA01 2500000 * 0
-PALADIN * MXSPLPAL * 89000 * * PALADIN 5 1 * CLABPA01 2500000 * 2
-FIGHTER_MAGE * * MXSPLWIZ 89000 * * * 0 1 * CLABFI01 2500000 * 0
-FIGHTER_CLERIC * MXSPLPRS * 89000 * * * 1 1 * FI01,PR01 2500000 * 0
-FIGHTER_THIEF * * * 89000 * SKILLS * 0 0 * FI01,TH01 2500000 * 0
-FIGHTER_MAGE_THIEF * * MXSPLWIZ 89000 * SKILLS * 0 1 * FI01,TH01 2500000 * 0
-DRUID MXSPLDRU * * 89000 * * * 0 1 * CLABDR01 2500000 * 0
-RANGER MXSPLRAN * * 89000 * * * 0 1 HATERACE CLABRN01 2500000 SKILLRNG 0
-MAGE_THIEF * * MXSPLWIZ 89000 * SKILLS * 0 1 * CLABTH01 2500000 * 0
-CLERIC_MAGE * MXSPLPRS MXSPLWIZ 89000 * * * 1 1 * CLABPR01 2500000 * 0
-CLERIC_THIEF * MXSPLPRS * 89000 * SKILLS * 1 1 * PR01,TH01 2500000 * 0
-FIGHTER_DRUID MXSPLDRU * * 89000 * * * 0 1 * FI01,DR01 2500000 * 0
-FIGHTER_MAGE_CLERIC * MXSPLPRS MXSPLWIZ 89000 * * * 1 1 * FI01,PR01 2500000 * 0
-CLERIC_RANGER MXSPLRAN MXSPLPRS * 89000 * * * 1 1 HATERACE PR01,RN01 2500000 SKILLRNG 0
-SORCERER * * MXSPLSRC 89000 * * * 0 2 * * 2500000 * 0
-MONK * * * 89000 * SKILLS * 0 0 * CLABMO01 2500000 * 0
diff --git a/gemrb/override/bg2/damage.2da b/gemrb/override/bg2/damage.2da
deleted file mode 100644
index 179722a..0000000
--- a/gemrb/override/bg2/damage.2da
+++ /dev/null
@@ -1,16 +0,0 @@
-2DA V1.0
-*
- MAIN SPARKS GRADIENT
-CRIT BLOODCR * 47
-SMALL BLOODS * 47
-MEDIUM BLOODM * 47
-LARGE BLOODL * 47
-FIRES SPFIRIMP SPBURN 19
-FIREM SPFIRIMP SPBURN 19
-FIREL SPFIRIMP SPBURN 19
-SPARKS SPSHKIMP SPSPARKS -1
-SPARKM SPSHKIMP SPSPARKS -1
-SPARKL SPSHKIMP SPSPARKS -1
-ICES FIRIMP * 71
-ICEM FIRIMP * 71
-ICEL FIRIMP * 71
diff --git a/gemrb/override/bg2/defsound.2da b/gemrb/override/bg2/defsound.2da
deleted file mode 100644
index 452610d..0000000
--- a/gemrb/override/bg2/defsound.2da
+++ /dev/null
@@ -1,29 +0,0 @@
-2DA V1.0
-*
- RESREF
-OPEN AMB_D03A
-CLOSE AMB_D03B
-HOPEN AMB_D04A
-HCLOSE AMB_D04B
-BUTTON1 GAM_09
-BUTTON2 GAM_03
-BUTTON3 GAM_04
-OPENFAIL AMB_D20
-CLOSEFAIL *
-ITEM_GONE EFF_M02
-SECRET ACT_09
-11 *
-12 *
-13 *
-14 *
-15 *
-16 *
-17 *
-18 *
-19 *
-LIGHTNING1 AMB_E13A
-LIGHTNING2 AMB_E13B
-LIGHTNING3 AMB_E13F
-RAIN AMB_E11
-SNOW AMB_E02B
-
diff --git a/gemrb/override/bg2/effects.ids b/gemrb/override/bg2/effects.ids
deleted file mode 100644
index 403aa9c..0000000
--- a/gemrb/override/bg2/effects.ids
+++ /dev/null
@@ -1,320 +0,0 @@
-IDS
-0x0 ACVsDamageTypeModifier
-0x1 AttacksPerRoundModifier
-0x2 Cure:Sleep
-0x3 State:Berserk
-0x4 Cure:Berserk
-0x5 State:Charmed
-0x6 CharismaModifier
-0x7 Color:SetPalette
-0x8 Color:SetRGB
-0x9 Color:PulseRGB
-0xa ConstitutionModifier
-0xb Cure:Poison
-0xc Damage
-0xd Death
-0xe Cure:Defrost
-0xf DexterityModifier
-0x10 State:Hasted
-0x11 CurrentHPModifier
-0x12 MaximumHPModifier
-0x13 IntelligenceModifier
-0x14 State:Invisible
-0x15 LoreModifier
-0x16 LuckModifier
-0x17 MoraleModifier
-0x18 State:Panic
-0x19 State:Poisoned
-0x1a RemoveCurse
-0x1b AcidResistanceModifier
-0x1c ColdResistanceModifier
-0x1d ElectricityResistanceModifier
-0x1e FireResistanceModifier
-0x1f MagicDamageResistanceModifier
-0x20 Cure:Death
-0x21 SaveVsDeathModifier
-0x22 SaveVsWandsModifier
-0x23 SaveVsPolyModifier
-0x24 SaveVsBreathModifier
-0x25 SaveVsSpellsModifier
-0x26 State:Silenced
-0x27 State:Helpless
-0x28 State:Slowed
-0x29 Sparkle
-0x2a WizardSpellSlotsModifier
-0x2b Cure:Petrification
-0x2c StrengthModifier
-0x2d State:Stun
-0x2e Cure:Stun
-0x2f Cure:Invisible
-0x30 Cure:Silence
-0x31 WisdomModifier
-0x32 Color:BriefRGB
-0x33 Color:DarkenRGB
-0x34 Color:GlowRGB
-0x35 AnimationIDModifier
-0x36 ToHitModifier
-0x37 KillCreatureType
-0x38 Alignment:Invert
-0x39 Alignment:Change
-0x3a DispelEffects
-0x3b StealthModifier
-0x3c MiscastMagicModifier
-0x3d AlchemyModifier
-0x3e PriestSpellSlotsModifier
-0x3f State:Infravision
-0x40 Cure:Infravision
-0x41 State:Blur
-0x42 TransparencyModifier
-0x43 SummonCreature
-0x44 UnsummonCreature
-0x45 State:NonDetection
-0x46 Cure:NonDetection
-0x47 SexModifier
-0x48 AIIdentifierModifier
-0x49 DamageBonusModifier
-0x4a State:Blind
-0x4b Cure:Blind
-0x4c State:Feeblemind
-0x4d Cure:Feeblemind
-0x4e State:Diseased
-0x4f Cure:Disease
-0x50 State:Deafness
-0x51 Cure:Deafness
-0x52 SetAIScript
-0x53 Protection:Projectile
-0x54 MagicalFireResistanceModifier
-0x55 MagicalColdResistanceModifier
-0x56 SlashingResistanceModifier
-0x57 CrushingResistanceModifier
-0x58 PiercingResistanceModifier
-0x59 MissilesResistanceModifier
-0x5a OpenLocksModifier
-0x5b FindTrapsModifier
-0x5c PickPocketsModifier
-0x5d FatigueModifier
-0x5e IntoxicationModifier
-0x5f TrackingModifier
-0x60 LevelModifier
-0x61 StrengthBonusModifier
-0x62 State:Regenerating
-0x63 SpellDurationModifier
-0x64 Protection:Creature
-0x65 Protection:Opcode
-0x66 Protection:SpellLevel
-0x67 ChangeName
-0x68 ExperienceModifier
-0x69 GoldModifier
-0x6a MoraleBreakModifier
-0x6b PortraitChange
-0x6c ReputationModifier
-0x6d State:HoldNoIcon
-0x6e RetreatFrom
-0x6f Item:CreateMagic
-0x70 Item:Remove
-0x71 Item:Equip
-0x72 Dither
-0x73 DetectAlignment
-0x74 Cure:Invisible2
-0x75 Reveal:Area
-0x76 Reveal:Creatures
-0x77 MirrorImage
-0x78 Protection:Weapons
-0x79 VisualAnimationEffect
-0x7a Item:CreateInventory
-0x7b Item:RemoveInventory
-0x7c DimensionDoor
-0x7d Unlock
-0x7e MovementRateModifier
-0x7f MonsterSummoning
-0x80 State:Confused
-0x81 AidNonCumulative
-0x82 BlessNonCumulative
-0x83 ChantNonCumulative
-0x84 HolyNonCumulative
-0x85 LuckNonCumulative
-0x86 State:Petrification
-0x87 Polymorph
-0x88 ForceVisible
-0x89 ChantBadNonCumulative
-0x8a AnimationStateChange
-0x8b DisplayString
-0x8c CastingGlow
-0x8d VisualSpellHit
-0x8e Icon:Display
-0x8f Item:CreateInSlot
-0x90 DisableButton
-0x91 DisableCasting
-0x92 Spell:Cast
-0x93 Spell:Learn
-0x94 Spell:CastPoint
-0x95 Identify
-0x96 FindTraps
-0x97 ReplaceCreature
-0x98 PlayMovie
-0x99 Overlay:Sanctuary
-0x9a Overlay:Entangle
-0x9b Overlay:MinorGlobe
-0x9c Overlay:ShieldGlobe
-0x9d Overlay:Web
-0x9e Overlay:Grease
-0x9f MirrorImageModifier
-0xa0 Cure:Sanctuary
-0xa1 Cure:Panic
-0xa2 Cure:Hold
-0xa3 FreeAction
-0xa4 Cure:Intoxication
-0xa5 PauseTarget
-0xa6 MagicResistanceModifier
-0xa7 MissileHitModifier
-0xa8 RemoveCreature
-0xa9 Icon:Disable
-0xaa DamageAnimation
-0xab Spell:Add
-0xac Spell:Remove
-0xad PoisonResistanceModifier
-0xae PlaySound
-0xaf State:Hold
-0xb0 MovementRateModifier2
-0xb1 ApplyEffect
-0xb2 ToHitVsCreature
-0xb3 DamageVsCreature
-0xb4 CantUseItem
-0xb5 CantUseItemType
-0xb6 ApplyEffectItem
-0xb7 ApplyEffectItemType
-0xb8 DontJumpModifier
-0xb9 State:Hold2
-0xba MoveToArea
-0xbb Variable:StoreLocalVariable
-0xbc AuraCleansingModifier
-0xbd CastingSpeedModifier
-0xbe AttackSpeedModifier
-0xbf CastingLevelModifier
-0xc0 FindFamiliar
-0xc1 InvisibleDetection
-0xc2 IgnoreDialogPause
-0xc3 FamiliarBond
-0xc4 FamiliarMarker
-0xc5 Bounce:Projectile
-0xc6 Bounce:Opcode
-0xc7 Bounce:SpellLevel
-0xc8 Bounce:SpellLevelDec
-0xc9 Protection:SpellLevelDec
-0xca Bounce:School
-0xcb Bounce:SecondaryType
-0xcc Protection:School
-0xcd Protection:SecondaryType
-0xce Protection:Spell
-0xcf Bounce:Spell
-0xd0 MinimumHPModifier
-0xd1 PowerWordKill
-0xd2 PowerWordStun
-0xd3 State:Imprisonment
-0xd4 Cure:Imprisonment
-0xd5 Maze
-0xd6 CastFromList
-0xd7 PlayVisualEffect
-0xd8 LevelDrainModifier
-0xd9 PowerWordSleep
-0xda StoneskinModifier
-0xdb ACVsCreatureType
-0xdc DispelSchool
-0xdd DispelSecondaryType
-0xde RandomTeleport
-0xdf Protection:SchoolDec
-0xe0 Cure:LevelDrain
-0xe1 Reveal:Magic
-0xe2 Protection:SecondaryTypeDec
-0xe3 Bounce:SchoolDec
-0xe4 Bounce:SecondaryTypeDec
-0xe5 DispelSchoolOne
-0xe6 DispelSecondaryTypeOne
-0xe7 TimeStop
-0xe8 CastSpellOnCondition
-0xe9 Proficiency
-0xea CreateContingency
-0xeb WingBuffet
-0xec ProjectImage
-0xed PuppetMarker
-0xee Disintegrate
-0xef Farsee
-0xf0 Icon:Remove
-0xf1 ControlCreature
-0xf2 Cure:Confusion
-0xf3 DrainItems
-0xf4 DrainSpells
-0xf5 CheckForBerserkModifier
-0xf6 BerserkStage1Modifier
-0xf7 BerserkStage2Modifier
-0xf8 SetMeleeEffect
-0xf9 SetRangedEffect
-0xfa DamageLuckModifier
-0xfb ChangeBardSong
-0xfc SetTrap
-0xfd SetMapNote
-0xfe RemoveMapNote
-0xff Item:CreateDays
-0x100 Sequencer:Store
-0x101 Sequencer:Create
-0x102 Sequencer:Activate
-0x103 SpellTrap
-0x104 *Crash*
-0x105 RestoreSpells
-0x106 VisualRangeModifier
-0x107 BackstabModifier
-0x108 DropWeapon
-0x109 ModifyGlobalVariable
-0x10a RemoveImmunity
-0x10b Protection:String
-0x10c ExploreModifier
-0x10d ScreenShake
-0x10e Cure:CasterHold
-0x10f SummonDisable
-0x110 ApplyEffectRepeat
-0x111 RemoveProjectile
-0x112 TeleportToTarget
-0x113 HideInShadowsModifier
-0x114 DetectIllusionsModifier
-0x115 SetTrapsModifier
-0x116 ToHitBonusModifier
-0x117 RenableButton
-0x118 ForceSurgeModifier
-0x119 WildSurgeModifier
-0x11a ScriptingState
-0x11b ApplyEffectCurse
-0x11c MeleeHitModifier
-0x11d MeleeDamageModifier
-0x11e MissileDamageModifier
-0x11f NoCircleState
-0x120 FistHitModifier
-0x121 FistDamageModifier
-0x122 TitleModifier
-0x123 DisableOverlay
-0x124 Protection:Backstab
-0x125 OffscreenAIModifier
-0x126 ExistanceDelayModifier
-0x127 DisableChunk
-0x128 Protection:Animation
-0x129 Protection:Turn
-0x12a CutScene2
-0x12b ChaosShieldModifier
-0x12c NPCBump
-0x12d CriticalHitModifier
-0x12e CanUseAnyItem
-0x12f AlwaysBackstab
-0x130 MassRaiseDead
-0x131 OffhandHitModifier
-0x132 RightHitModifier
-0x133 Reveal:Tracks
-0x134 Protection:Tracking
-0x135 ModifyLocalVariable
-0x136 TimelessState
-0x137 GenerateWish
-0x138 *Crash*
-0x139 HLA
-0x13a StoneSkin2Modifier
-0x13b AvatarRemovalModifier
-0x13c MagicalRest
-0x13d State:Haste2
-0x13e ChangeWeather
diff --git a/gemrb/override/bg2/fonts.2da b/gemrb/override/bg2/fonts.2da
deleted file mode 100644
index 8cb7595..0000000
--- a/gemrb/override/bg2/fonts.2da
+++ /dev/null
@@ -1,19 +0,0 @@
-2DA V1.0
-NORMAL
- RESREF NEED_PALETTE FIRST_CHAR
-0 NORMAL 1 0
-1 FLOATTXT 1 0
-2 NUMBER 0 47
-3 INITIALS 0 0
-4 NUMBER2 0 47
-5 NUMBER3 0 47
-6 REALMS 0 0
-7 STONEBIG 0 0
-8 STONESML 0 0
-9 TOOLFONT 1 0
-10 STONESM2 0 0
-11 TOOLTIP 1 0
-12 STONSML 0 0
-13 GAMETEXT 0 0
-14 STATES 0 0
-15 STATES2 0 0
diff --git a/gemrb/override/bg2/gametime.2da b/gemrb/override/bg2/gametime.2da
deleted file mode 100644
index 54ac077..0000000
--- a/gemrb/override/bg2/gametime.2da
+++ /dev/null
@@ -1,5 +0,0 @@
-2DA V1.0
-0
- DURATION
-ROUND_SECONDS 6
-TURN_SECONDS 60
diff --git a/gemrb/override/bg2/gemrb.ini b/gemrb/override/bg2/gemrb.ini
deleted file mode 100644
index c481423..0000000
--- a/gemrb/override/bg2/gemrb.ini
+++ /dev/null
@@ -1,92 +0,0 @@
-; GemRB - Infinity Engine Emulator
-; Copyright (C) 2003 The GemRB Project
-;
-; This program is free software; you can redistribute it and/or
-; modify it under the terms of the GNU General Public License
-; as published by the Free Software Foundation; either version 2
-; of the License, or (at your option) any later version.
-;
-; This program is distributed in the hope that it will be useful,
-; but WITHOUT ANY WARRANTY; without even the implied warranty of
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-; GNU General Public License for more details.
-;
-; You should have received a copy of the GNU General Public License
-; along with this program; if not, write to the Free Software
-; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-;
-
-
-; gemrb.ini - game type-specific settings for GemRB engine
-
-[resources]
-
-; Bitmap resource for cursors
-CursorBAM = CAROT
-
-; Bitmap resource for scroll cursor arrow
-ScrollCursorBAM = CURSARW
-
-; Bitmap resource for dialog buttons font
-ButtonFont = STONESML
-
-; Font used to display subtitles (ToB)
-MovieFont = STONESML
-
-; Font used to display tooltips
-TooltipFont = TOOLFONT
-
-; Sprite displayed behind the tooltip text, if any
-TooltipBack = TOOLSCRL
-
-; Tooltip text color (RGBA)
-TooltipColor = #f0b08000
-
-; Space between tooltip text and sides of TooltipBack (x2)
-#TooltipMargin = 10
-TooltipMargin = 5
-
-; INI file from the original games
-INIConfig = baldur.ini
-
-; Palette bitmaps in various widths
-Palette16 = MPALETTE
-Palette32 = MPALETTE
-Palette256 = MPAL256
-
-MaximumAbility = 25
-IgnoreButtonFrames = 1
-AllStringsTagged = 0
-HasDPLAYER = 1
-HasPickSound = 0
-HasDescIcon = 1
-HasEXPTABLE = 0
-SoundFolders = 0
-HasSongList = 1
-UpperButtonText = 1
-LowerLabelText = 0
-HasPartyINI = 0
-HasBeastsINI = 0
-ForceStereo = 0
-ReverseToHit = 1
-IWDMapDimensions = 0
-SmallFog = 0
-ReverseDoor = 0
-DialogueScrolls = 0
-RedrawTile = 0
-CheckAbilities = 1
-SpellBookIconHack = 1
-DeathOnZeroStat = 1
-BreakableWeapons = 0
-SelectiveMagicRes = 1
-HasHideInShadows = 1
-ProperBackstab = 1
-HasSpecificDamageBonus = 0
-StealIsAttack = 1
-CutsceneAreascripts = 0
-FlexibleWorldmap = 0
-AutoSearchHidden = 1
-PSTStateFlags = 0
-JournalHasSections = 1
-CastingSounds = 1
-EnhancedCastingSounds = 1
diff --git a/gemrb/override/bg2/magesch.2da b/gemrb/override/bg2/magesch.2da
deleted file mode 100644
index 3e8697b..0000000
--- a/gemrb/override/bg2/magesch.2da
+++ /dev/null
@@ -1,13 +0,0 @@
-2DA V1.0
--1
- NAME_REF DESC_REF CAP_REF KIT
-GENERALIST 18039 9563 9987 0x4000
-ABJURER 597 9564 502 0x40
-CONJURER 2179 9565 504 0x80
-DIVINER 2846 9566 2012 0x100
-ENCHANTER 2861 9567 2022 0x200
-ILLUSIONIST 2862 9568 8421 0x400
-INVOKER 3015 9569 12786 0x800
-NECROMANCER 12744 9570 12787 0x1000
-TRANSMUTER 12745 9571 12788 0x2000
-WILDMAGE 54893 54892 54894 0x8000
diff --git a/gemrb/override/bg2/overlay.2da b/gemrb/override/bg2/overlay.2da
deleted file mode 100644
index 84a944e..0000000
--- a/gemrb/override/bg2/overlay.2da
+++ /dev/null
@@ -1,35 +0,0 @@
-2DA V1.0
-*
- VVC UNDER FLAGS
-SANCTUARY SANCTRY 0 1
-ENTANGLE SPENTACI 0 0
-SPELLTRAP SPMAGGLO 0 0
-SHIELDGLOBE SPSHIELD 0 1
-GREASE GREASED 1 0
-WEB WEBENTD 1 0
-MINORGLOBE MINORGLB 0 1
-GLOBE GOINVUC 0 1
-FLAMESHROUD SOFLAMC 0 0
-ANTIMAGIC AMSHELC 0 0
-RESILIENT ORSPHEC 0 0
-PROTFROMMISS PFNMISC 0 0
-CLOAKOFFEAR COFEARC 0 0
-ENTROPY ESHIELC 0 0
-FIREAURA FIAURAC 0 0
-FROSTAURA FRAURAC 0 0
-INSECT IPLAGUC 0 0
-STORMSHELL SSHELLC 0 0
-LATHANDER1 SOLATC1 0 0
-LATHANDER2 SOLATC2 1 0
-GLATHANDER1 GSOLAC1 0 0
-GLATHANDER2 GSOLAC2 1 0
-SEVENEYES1 SEYESC1 0 0
-SEVENEYES2 SEYESC2 1 0
-BOUNCE SPTURNI2 1 0
-BOUNCE2 SPTURNI 1 0
-FIRESHIELD1 FSHIRC1 0 0
-FIRESHIELD2 FSHIRC2 1 0
-ICESHIELD1 FSHIBC1 0 0
-ICESHIELD2 FSHIBC2 1 0
-TORTOISE TSHELLC 0 0
-DEATHARMOR DARMORC 0 0
diff --git a/gemrb/override/bg2/pathfind.2da b/gemrb/override/bg2/pathfind.2da
deleted file mode 100644
index 7180fc2..0000000
--- a/gemrb/override/bg2/pathfind.2da
+++ /dev/null
@@ -1,6 +0,0 @@
-2DA V1.0
-*
- 0 1 2 3 4 5 6 7 8 9 a b c d e f
-PASSABLE 8 1 1 1 1 1 1 1 0 1 8 0 0 8 3 1
-COST 10 4
-SOUND * WAL_04 WAL_MT WAL_02 WAL_05 WAL_06 WAL_01 WAL_03 * WAL_02 * WAL_01 * * * WAL_04
diff --git a/gemrb/override/bg2/pdolls.2da b/gemrb/override/bg2/pdolls.2da
deleted file mode 100644
index 5a75653..0000000
--- a/gemrb/override/bg2/pdolls.2da
+++ /dev/null
@@ -1,106 +0,0 @@
-2DA V1.0
-*
- LEVEL1 LEVEL2 LEVEL3 LEVEL4 SIZE
-0x5000 CHMC1INV CHMC2INV CHMC3INV CHMC4INV L
-0x5001 CEMC1INV CEMC2INV CEMC3INV CEMC4INV M
-0x5002 CDMC1INV CDMC2INV CDMC3INV CDMC4INV S
-0x5003 CIMC1INV CIMC2INV CIMC3INV CIMC4INV H
-0x5010 CHFC1INV CHMC2INV CHMC3INV CHMC4INV N
-0x5011 CEFC1INV CEMC2INV CEMC3INV CEMC4INV M
-0x5012 CDMC1INV CDMC2INV CDMC3INV CDMC4INV S
-0x5013 CIFC1INV CIMC2INV CIMC3INV CIMC4INV S
-0x5100 CHMF1INV CHMF2INV CHMF3INV CHMC4INV L
-0x5101 CEMF1INV CEMF2INV CEMF3INV CEMC4INV M
-0x5102 CDMF1INV CDMF2INV CDMF3INV CDMC4INV S
-0x5103 CIMF1INV CIMF2INV CIMF3INV CIMC4INV H
-0x5110 CHFF1INV CHFF2INV CHMF3INV CHMC4INV N
-0x5111 CEFF1INV CEFF2INV CEMF3INV CEMC4INV M
-0x5112 CDMF1INV CDMF2INV CDMF3INV CDMC4INV S
-0x5113 CIFF1INV CIFF2INV CIMF3INV CIMC4INV S
-0x5200 CHMW1INV CHMW2INV CHMW3INV CHMW4INV L
-0x5201 CEMW1INV CEMW2INV CEMW3INV CEMW4INV M
-0x5202 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
-0x5203 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
-0x5210 CHFW1INV CHMW2INV CHMW3INV CHMW4INV N
-0x5211 CEFW1INV CEMW2INV CEMW3INV CEMW4INV M
-0x5212 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
-0x5213 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
-0x5300 CHMT1INV CHMT2INV CHMF3INV CHMF4INV L
-0x5301 CEMT1INV CEMT2INV CEMF3INV CEMF4INV M
-0x5302 CDMT1INV CDMT2INV CDMF3INV CDMF4INV S
-0x5303 CIMT1INV CIMT2INV CIMF3INV CIMF4INV H
-0x5310 CHFT1INV CHMT2INV CHMF3INV CHMF4INV N
-0x5311 CEFT1INV CEMT2INV CEMF3INV CEMF4INV M
-0x5312 CDMT1INV CDMT2INV CDMF3INV CDMF4INV S
-0x5313 CIFT1INV CIMT2INV CIMF3INV CIMF4INV S
-0x6000 CHMC1INV CHMC2INV CHMC3INV CHMC4INV L
-0x6001 CEMC1INV CEMC2INV CEMC3INV CEMC4INV M
-0x6002 CDMC1INV CDMC2INV CDMC3INV CDMC4INV S
-0x6003 CIMC1INV CIMC2INV CIMC3INV CIMC4INV H
-0x6004 CIMC1INV CIMC2INV CIMC3INV CIMC4INV H
-0x6005 CHMC1INV CHMC2INV CHMC3INV CHMC4INV L
-0x6010 CHFC1INV CHFC2INV CHFC3INV CHFC4INV N
-0x6011 CEFC1INV CEFC2INV CEFC3INV CEFC4INV M
-0x6012 CDMC1INV CDMC2INV CDMC3INV CDMC4INV S
-0x6013 CIFC1INV CIFC2INV CIFC3INV CIFC4INV S
-0x6014 CIFC1INV CIFC2INV CIFC3INV CIFC4INV S
-0x6015 CHFC1INV CHFC2INV CHFC3INV CHFC4INV N
-0x6100 CHMF1INV CHMF2INV CHMF3INV CHMF4INV L
-0x6101 CEMF1INV CEMF2INV CEMF3INV CEMF4INV M
-0x6102 CDMF1INV CDMF2INV CDMF3INV CDMF4INV S
-0x6103 CIMF1INV CIMF2INV CIMF3INV CIMF4INV H
-0x6104 CIMF1INV CIMF2INV CIMF3INV CIMF4INV H
-0x6105 CHMF1INV CHMF2INV CHMF3INV CHMF4INV L
-0x6110 CHFF1INV CHFF2INV CHFF3INV CHFF4INV N
-0x6111 CEFF1INV CEFF2INV CEFF3INV CEFF4INV M
-0x6112 CDMF1INV CDMF2INV CDMF3INV CDMF4INV S
-0x6113 CIFF1INV CIFF2INV CIFF3INV CIFF4INV S
-0x6114 CIFF1INV CIFF2INV CIFF3INV CIFF4INV S
-0x6115 CHFF1INV CHFF2INV CHFF3INV CHFF4INV N
-0x6200 CHMW1INV CHMW2INV CHMW3INV CHMW4INV L
-0x6201 CEMW1INV CEMW2INV CEMW3INV CEMW4INV M
-0x6202 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
-0x6203 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
-0x6204 CGMW1INV CGMW2INV CGMW3INV CGMW4INV S
-0x6205 CHMW1INV CHMW2INV CHMW3INV CHMW4INV L
-0x6210 CHFW1INV CHFW2INV CHFW3INV CHFW4INV N
-0x6211 CEFW1INV CEFW2INV CEFW3INV CEFW4INV M
-0x6212 CIFT1INV CIFT2INV CIFT3INV CIFT4INV S
-0x6213 CIFT1INV CIFT2INV CIFT3INV CIFT4INV S
-0x6214 CIFT1INV CIFT2INV CIFT3INV CIFT4INV S
-0x6215 CHFW1INV CHFW2INV CHFW3INV CHFW4INV N
-0x6300 CHMT1INV CHMT2INV CHMF3INV CHMF4INV L
-0x6301 CEMT1INV CEMT2INV CEMF3INV CEMF4INV M
-0x6302 CDMT1INV CDMT2INV CDMF3INV CDMF4INV S
-0x6303 CIMT1INV CIMT2INV CIMF3INV CIMF4INV H
-0x6304 CIMT1INV CIMT2INV CIMF3INV CIMF4INV H
-0x6305 CHMT1INV CHMT2INV CHMF3INV CHMF4INV L
-0x6310 CHFT1INV CHFT2INV CHFF3INV CHFF4INV N
-0x6311 CEFT1INV CEFT2INV CEFF3INV CEFF4INV M
-0x6312 CDMT1INV CDMT2INV CDMF3INV CDMF4INV S
-0x6313 CIFT1INV CIFT2INV CIFF3INV CIFF4INV S
-0x6314 CIFT1INV CIFT2INV CIFF3INV CIFF4INV S
-0x6315 CHFT1INV CHFT2INV CHFF3INV CHFF4INV N
-0x6402 CMNKINV CHMT2INV CHMF3INV CHMF4INV M
-0x6500 CHMM1INV CHMT2INV CHMF3INV CHMF4INV L
-0x6510 CHFM1INV CHFT2INV CHMF3INV CHMF4INV N
-0x7200 MBER0INV MBER0INV MBER0INV MBER0INV M
-0x7201 MBER1INV MBER1INV MBER1INV MBER1INV M
-0x7300 MEAEINV MEAEINV MEAEINV MEAEINV L
-0x7310 MFIEINV MFIEINV MFIEINV MFIEINV L
-0x7900 MSLI2INV MSLI2INV MSLI2INV MSLI2INV M
-0x7A00 MWYVINV MWYVINV MWYVINV MWYVINV M
-0x7A03 MSPI3INV MSPI3INV MSPI3INV MSPI3INV S
-0x7B00 MWLF0INV MWLF0INV MWLF0INV MWLF0INV S
-0x7B03 MWLF0INV MWLF0INV MWLF0INV MWLF0INV S
-0x7E00 MGWEINV MGWEINV MGWEINV MGWEINV M
-0x7E01 MGWEINV MGWEINV MGWEINV MGWEINV M
-0x7F00 MTROINV MTROINV MTROINV MTROINV L
-0x7F01 MMININV MMININV MMININV MMININV M
-0x7F04 MIGOINV MIGOINV MIGOINV MIGOINV L
-0x7F32 MSLYINV MSLYINV MSLYINV MSLYINV L
-0x8000 MGNLINV MGNLINV MGNLINV MGNLINV M
-0x9000 MOGRINV MOGRINV MOGRINV MOGRINV L
-0xC300 ARATINV ARATINV ARATINV ARATINV S
-0xC400 ASQUINV ASQUINV ASQUINV ASQUINV S
-0xE900 MSALINV MSALINV MSALINV MSALINV L
diff --git a/gemrb/override/bg2/qslots.2da b/gemrb/override/bg2/qslots.2da
deleted file mode 100644
index ee67138..0000000
--- a/gemrb/override/bg2/qslots.2da
+++ /dev/null
@@ -1,24 +0,0 @@
-2DA V1.0
-100
- SLOT1 SLOT2 SLOT3 SLOT4 SLOT5 SLOT6 SLOT7 SLOT8 SLOT9
-DEFAULT 3 4 5 2 8 9 11 12 13
-MAGE 3 4 5 2 8 9 11 12 13
-FIGHTER 18 19 14 100 8 9 11 12 13
-CLERIC 6 3 4 2 8 9 11 12 13
-THIEF 22 0 1 100 8 9 11 12 13
-BARD 20 1 3 2 8 9 11 12 13
-PALADIN 18 14 6 2 8 9 11 12 13
-FIGHTER_MAGE 3 4 5 2 8 9 11 12 13
-FIGHTER_CLERIC 6 3 4 2 8 9 11 12 13
-FIGHTER_THIEF 18 22 0 1 8 9 11 12 13
-FIGHTER_MAGE_THIEF 22 0 1 2 8 9 11 12 13
-DRUID 3 4 5 2 8 9 11 12 13
-RANGER 18 14 0 2 8 9 11 12 13
-MAGE_THIEF 22 0 1 2 8 9 11 12 13
-CLERIC_MAGE 6 3 4 2 8 9 11 12 13
-CLERIC_THIEF 22 0 1 2 8 9 11 12 13
-FIGHTER_DRUID 3 4 5 2 8 9 11 12 13
-FIGHTER_MAGE_CLERIC 6 3 4 2 8 9 11 12 13
-CLERIC_RANGER 6 3 4 2 8 9 11 12 13
-SORCERER 3 4 5 2 8 9 11 12 13
-MONK 18 14 22 0 8 9 11 12 13
diff --git a/gemrb/override/bg2/races.2da b/gemrb/override/bg2/races.2da
deleted file mode 100644
index e67424e..0000000
--- a/gemrb/override/bg2/races.2da
+++ /dev/null
@@ -1,11 +0,0 @@
-2DA V1.0
--1
- NAME_REF DESC_REF CAP_REF ID USABILITY SAVE
-HUMAN 7193 9550 1096 1 0x08000000 *
-ELF 7194 9552 1097 2 0x00800000 *
-HALF_ELF 7197 9555 1098 3 0x02000000 *
-GNOME 7196 9553 1099 6 0x10000000 SAVECNG
-HALFLING 7195 9554 1101 5 0x04000000 SAVECNDH
-DWARF 7182 9551 1100 4 0x01000000 SAVECNDH
-HALFORC 53186 53191 53212 7 0x80000000 *
-TIEFLING 8332 -1 8330 153 0 *
diff --git a/gemrb/override/bg2/splspec.2da b/gemrb/override/bg2/splspec.2da
deleted file mode 100644
index 6411a22..0000000
--- a/gemrb/override/bg2/splspec.2da
+++ /dev/null
@@ -1,8 +0,0 @@
-2DA V1.0
-*
- IDENTIFY_SILENCE
-SPWI110 1
-SPWI219 2
-SPIN649 2
-SPCL412 2
-SPCL414 2
diff --git a/gemrb/override/bg2/strings.2da b/gemrb/override/bg2/strings.2da
deleted file mode 100644
index 26ba8c0..0000000
--- a/gemrb/override/bg2/strings.2da
+++ /dev/null
@@ -1,169 +0,0 @@
-2DA V1.0
--1
- STRREF
-SCATTERED 16457
-WHOLEPARTY 16484
-DOORLOCKED 16485
-MAGICTRAP 16486
-NORMALTRAP 16487
-TRAP 16488
-CANNOTGO 16489
-TRAPREMOVED 16490
-OVERSTOCKED 16491
-SLEEP 16492
-AMBUSH 16493
-CONTLOCKED 15874
-NOMONEY 16495
-CURSED 16496
-SPELLDISRUPT 16497
-DIED 16498
-MAYNOTREST 16499
-CANTRESTMONS 16500
-CANTSAVEMONS 16501
-CANTSAVE 16502
-NODIALOG 10945
-CANTSAVEDIALOG 19253
-CANTSAVEDIALOG2 19254
-CANTSAVEMOVIE 19255
-TARGETBUSY 61393
-CANTTALKTRANS 62158
-GOTGOLD 17572
-LOSTGOLD 17573
-GOTXP 17574
-LOSTXP 17575
-GOTITEM 17576
-LOSTITEM 17577
-GOTREP 19686
-LOSTREP 19687
-GOTABILITY 10514
-GOTSPELL 61354
-GOTSONG 10514
-NOTHINGTOSAY 32092
-JOURNALCHANGE 11359
-WORLDMAPCHANGE 11360
-PAUSED 16321
-UNPAUSED 16322
-SCRIPTPAUSED 54381
-AP_UNUSABLE 17113
-AP_ATTACKED 17114
-AP_HIT 17115
-AP_WOUNDED 17116
-AP_DEAD 17117
-AP_NOTARGET 17118
-AP_ENDROUND 10014
-AP_ENEMY 23511
-AP_TRAP 58225
-AP_SPELLCAST 31874
-AP_RESERVED1 -1
-AP_RESERVED2 -1
-AP_RESERVED3 -1
-AP_RESERVED4 -1
-CHARMED 14672
-DIRECHARMED 14780
-CONTROLLED 61394
-EVIL 16505
-GNE_NEUTRAL 16504
-GOOD 16503
-STR_LAWFUL -1
-LNC_NEUTRAL -1
-CHAOTIC -1
-ACTION_CAST 16464
-ACTION_ATTACK 16465
-ACTION_TURN 16466
-ACTION_SONG 16467
-ACTION_FINDTRAP 16468
-MAGICWEAPON 10141
-OFFHAND_USED 9380
-TWOHANDED_USED 9381
-CANNOT_USE_ITEM 9382
-CANT_DROP_ITEM 25697
-NOT_IN_OFFHAND 26342
-ITEM_IS_CURSED 16304
-NO_CRITICAL 20696
-TRACKING 67807
-TRACKINGFAILED 19534
-DOOR_NOPICK 23169
-CONT_NOPICK 23169
-CANTSAVECOMBAT 3041
-CANTSAVENOCTRL 54401
-LOCKPICK_DONE 16517
-LOCKPICK_FAILED 16518
-STATIC_DISSIPATE -1
-LIGHTNING_DISSIPATE -1
-HAS_NO_ABILITY 17317
-NEEDS_IDENTIFY 17316
-WRONG_ITEMTYPE 9375
-HAS_ITEMEXCL 20685
-PICKPOCKET_DONE 10072
-PICKPOCKET_NONE 55369
-PICKPOCKET_FAIL 10069
-PICKPOCKET_EVIL 10068
-PICKPOCKET_ARMOR 10067
-USING_FEAT -1
-STOPPED_FEAT -1
-DISARM_DONE 16520
-DISARM_FAIL 1608
-DOORBASH_DONE 9915
-DOORBASH_FAIL 9913
-CONTBASH_DONE 9916
-CONTBASH_FAIL 9914
-MAYNOTSETTRAP 31891
-SNAREFAILED 56378
-SNARESUCCEED 3799
-NOMORETRAP 72712
-DISABLEDMAGE 8856
-SAVESUCCEED 1682
-QSAVESUCCEED 10237
-UNINJURED 38551
-INJURED1 38552
-INJURED2 38553
-INJURED3 38554
-INJURED4 38555
-HOURS 10700
-HOUR 10701
-DAYS 10697
-DAY 10698
-REST 10690
-JOURNEY 10689
-PST_REST -1
-PST_HOUR -1
-PST_HOURS -1
-DAMAGE_IMMUNITY 5199
-DAMAGE_STR1 14027
-DAMAGE_STR2 3805
-DAMAGE_STR3 -1
-DMG_POISON -1
-DMG_MAGIC -1
-DMG_MISSILE -1
-DMG_SLASHING -1
-DMG_PIERCING -1
-DMG_CRUSHING -1
-DMG_FIRE -1
-DMG_ELECTRIC -1
-DMG_COLD -1
-DMG_ACID -1
-DMG_OTHER -1
-GOTQUESTXP 46858
-LEVELUP 17119
-INVFULL_ITEMDROP 32879
-CONT_DUP 32876
-CONT_TRIG 36936
-CONT_FAIL 36937
-SEQ_DUP 39722
-CRITICAL_HIT 16462
-CRITICAL_MISS 16463
-DEATH 14026
-BACKSTAB 12128
-BACKSTAB_BAD 10013
-BACKSTAB_FAIL 3042
-CASTER_LVL_INC 73544
-CASTER_LVL_DEC 73545
-CHARS_EXPORTED -1
-PALADIN_FALL 19620
-RANGER_FALL 19621
-RES_RESISTED -1
-DEADMAGIC_FAIL 70306
-MISCASTMAGIC 467
-WILDSURGE 52260
-FAMBLOCK 8537
-FAMPROTAGONIST 8538
diff --git a/gemrb/override/how/CMakeLists.txt b/gemrb/override/how/CMakeLists.txt
deleted file mode 100644
index 727794c..0000000
--- a/gemrb/override/how/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-ADD_GEMRB_OVERRIDE (how)
\ No newline at end of file
diff --git a/gemrb/override/how/Makefile.am b/gemrb/override/how/Makefile.am
index 801744d..cbb7472 100644
--- a/gemrb/override/how/Makefile.am
+++ b/gemrb/override/how/Makefile.am
@@ -1,3 +1,3 @@
-howoverride_DATA = *.2da *.ini *.chu *.ids *.spl *.pro *.bcs
+howoverride_DATA = *.2da *.bcs
howoverridedir = $(moddir)/override/how/
-EXTRA_DIST = *.2da *.ini *.chu *.ids *.spl *.pro *.bcs
+EXTRA_DIST = *.2da *.bcs
diff --git a/gemrb/override/how/avatars.2da b/gemrb/override/how/avatars.2da
deleted file mode 100644
index 7dc5963..0000000
--- a/gemrb/override/how/avatars.2da
+++ /dev/null
@@ -1,417 +0,0 @@
-2DA V1.0
-*
- AT_1 AT_2 AT_3 AT_4 TYPE SPACE PALETTE SIZE
-0x0100 SPCHUNKS SPCHUNKS SPCHUNKS SPCHUNKS 13 0 0 *
-0x0300 SPSMPUFF SPSMPUFF SPSMPUFF SPSMPUFF 13 0 0 *
-0x0400 SKLH SKLH SKLH SKLH 13 0 1 *
-0x0410 GLPHWRDH GLPHWRDH GLPHWRDH GLPHWRDH 13 0 1 *
-0x1000 MWYV MWYV MWYV MWYV 11 5 1 *
-0x1001 MWYV MWYV MWYV MWYV 11 5 1 *
-0x1100 MTAN MTAN MTAN MTAN 11 5 1 *
-0x1200 MDR1 MDR1 MDR1 MDR1 12 5 1 *
-0x1201 MDR2 MDR2 MDR2 MDR2 12 5 1 *
-0x1202 MDR3 MDR3 MDR3 MDR3 12 5 1 *
-0x1203 MDR1 MDR1 MDR1 MDR1 12 7 GR *
-0x1204 MDR1 MDR1 MDR1 MDR1 12 7 AQ *
-0x1205 MDR1 MDR1 MDR1 MDR1 12 7 BL *
-0x1206 MDR1 MDR1 MDR1 MDR1 12 7 BR *
-0x1207 MDR1 MDR1 MDR1 MDR1 12 7 MC *
-0x1208 MDR1 MDR1 MDR1 MDR1 12 7 PU *
-0x2000 MSIR MSIR MSIR MSIR 2 2 0 *
-0x2100 UVOL UVOL UVOL UVOL 2 2 1 *
-0x2200 MOGM MOGM MOGM MOGM 2 2 0 S
-0x2300 MDKN MDKN MDKN MDKN 2 2 1 *
-0x3000 MAKH MAKH MAKH MAKH 2 3 1 *
-0x4000 SNOMC SNOMC SNOMC SNOMC 1 2 0 *
-0x4002 SNOMM SNOMM SNOMM SNOMM 1 2 0 *
-0x4010 SNOWC SNOWC SNOWC SNOWC 1 2 0 *
-0x4012 SNOWM SNOWM SNOWM SNOWM 1 2 0 *
-0x4100 SSIMC SSIMC SSIMC SSIMC 1 2 0 *
-0x4101 SSIMS SSIMS SSIMS SSIMS 1 2 0 *
-0x4102 SSIMM SSIMM SSIMM SSIMM 1 2 0 *
-0x4110 SSIWC SSIWC SSIWC SSIWC 1 2 0 *
-0x4112 SSIWM SSIWM SSIWM SSIWM 1 2 0 *
-0x4200 SHMCM SHMCM SHMCM SHMCM 1 2 0 *
-0x4300 MSPLG1 MSPLG1 MSPLG1 MSPLG1 1 2 1 *
-0x4400 LHMC LHMC LHMC LHMC 1 2 0 *
-0x4410 LHFC LHFC LHFC LHFC 1 2 0 *
-0x4500 LFAM LFAM LFAM LFAM 1 2 0 *
-0x4600 LDMF LDMF LDMF LDMF 1 2 0 *
-0x4700 LEMF LEMF LEMF LEMF 1 2 0 *
-0x4710 LEFF LEFF LEFF LEFF 1 2 0 *
-0x4800 LIMC LIMC LIMC LIMC 1 2 0 *
-0x5000 CHMB1 CHMB2 CHMB3 CHMC4 0 2 0 L
-0x5001 CEMB1 CEMB2 CEMB3 CEMC4 0 2 0 M
-0x5002 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 S
-0x5003 CIMB1 CIMB2 CIMB3 CIMC4 0 2 0 S
-0x5010 CHFB1 CHFB2 CHFB3 CHFC4 0 2 0 M
-0x5011 CEFB1 CEFB2 CEFB3 CEFC4 0 2 0 M
-0x5012 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 S
-0x5013 CIFB1 CIFB2 CIFB3 CIFC4 0 2 0 S
-0x5100 CHMB1 CHMB2 CHMB3 CHMF4 0 2 0 L
-0x5101 CEMB1 CEMB2 CEMB3 CHMF4 0 2 0 M
-0x5102 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 S
-0x5103 CIMB1 CIMB2 CIMB3 CIMF4 0 2 0 S
-0x5110 CHFB1 CHFB2 CHFB3 CHFF4 0 2 0 M
-0x5111 CEFB1 CEFB2 CEFB3 CEFF4 0 2 0 M
-0x5112 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 S
-0x5113 CIFB1 CIFB2 CIFB3 CIFF4 0 2 0 S
-0x5200 CHMW1 CHMW2 CHMW3 CHMW4 0 2 0 L
-0x5201 CEMW1 CEMW2 CEMW3 CEMW4 0 2 0 M
-0x5202 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
-0x5203 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
-0x5210 CHFW1 CHFW2 CHFW3 CHFW4 0 2 0 M
-0x5211 CEFW1 CEFW2 CEFW3 CEFW4 0 2 0 M
-0x5212 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
-0x5213 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
-0x5300 CHMB1 CHMT2 CHMB3 CHMF4 0 2 0 L
-0x5301 CEMB1 CEMT2 CEMB3 CEMF4 0 2 0 M
-0x5302 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 S
-0x5303 CIMB1 CIMT2 CIMB3 CIMF4 0 2 0 S
-0x5310 CHFB1 CHFT2 CHFB3 CHFF4 0 2 0 M
-0x5311 CEFB1 CEFT2 CEFB3 CEFF4 0 2 0 M
-0x5312 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 S
-0x5313 CIFB1 CIFT2 CIFB3 CIFF4 0 2 0 S
-0x6000 CHMB1 CHMB2 CHMB3 CHMC4 0 2 0 L
-0x6001 CEMB1 CEMB2 CEMB3 CEMC4 0 2 0 M
-0x6002 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 S
-0x6003 CIMB1 CIMB2 CIMB3 CIMC4 0 2 0 S
-0x6004 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 S
-0x6010 CHFB1 CHFB2 CHFB3 CHFC4 0 2 0 M
-0x6011 CEFB1 CEFB2 CEFB3 CEFC4 0 2 0 M
-0x6012 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 S
-0x6013 CIFB1 CIFB2 CIFB3 CIFC4 0 2 0 S
-0x6014 CIFB1 CIFB2 CIFB3 CIFC4 0 2 0 S
-0x6100 CHMB1 CHMB2 CHMB3 CHMF4 0 2 0 L
-0x6101 CEMB1 CEMB2 CEMB3 CEMF4 0 2 0 M
-0x6102 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 S
-0x6103 CIMB1 CIMB2 CIMB3 CIMF4 0 2 0 S
-0x6104 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 S
-0x6110 CHFB1 CHFB2 CHFB3 CHFF4 0 2 0 M
-0x6111 CEFB1 CEFB2 CEFB3 CEFF4 0 2 0 M
-0x6112 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 S
-0x6113 CIFB1 CIFB2 CIFB3 CIFF4 0 2 0 S
-0x6114 CIFB1 CIFB2 CIFB3 CIFF4 0 2 0 S
-0x6200 CHMW1 CHMW2 CHMW3 CHMW4 0 2 0 L
-0x6201 CEMW1 CEMW2 CEMW3 CEMW4 0 2 0 M
-0x6202 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
-0x6203 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
-0x6204 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
-0x6210 CHFW1 CHFW2 CHFW3 CHFW4 0 2 0 M
-0x6211 CEFW1 CEFW2 CEFW3 CEFW4 0 2 0 M
-0x6212 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
-0x6213 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
-0x6214 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
-0x6300 CHMB1 CHMT2 CHMB3 CHMF4 0 2 0 L
-0x6301 CEMB1 CEMT2 CEMB3 CEMF4 0 2 0 M
-0x6302 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 S
-0x6303 CIMB1 CIMT2 CIMB3 CIMF4 0 2 0 S
-0x6304 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 S
-0x6310 CHFB1 CHFT2 CHFB3 CHFF4 0 2 0 M
-0x6311 CEFB1 CEFT2 CEFB3 CEFF4 0 2 0 M
-0x6312 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 S
-0x6313 CIFB1 CIFT2 CIFB3 CIFF4 0 2 0 S
-0x6314 CIFB1 CIFT2 CIFB3 CIFF4 0 2 0 S
-0x6400 UDRZ1 UDRZ1 UDRZ1 UDRZ1 6 2 0 *
-0x6401 UELM1 UELM1 UELM1 UELM1 6 2 1 *
-0x6402 CMNK1 CMNK1 CMNK1 CMNK1 6 2 0 *
-0x6403 MSKL1 MSKL1 MSKL1 MSKL1 6 2 0 M
-0x6404 USAR1 USAR1 USAR1 USAR1 6 2 1 *
-0x6405 MDGU1 MDGU1 MDGU1 MDGU1 6 2 0 M
-0x6406 MDGU1 MDGU1 MDGU1 MDGU1 6 2 0 L
-0x6500 CHMM1 CHMB2 CHMB3 CHMC4 0 2 0 M
-0x6510 CHFM1 CHFB2 CHFB3 CHFC4 0 2 0 M
-0x7000 MOGH MOGH MOGH MOGH 2 2 0 *
-0x7001 MOGN MOGN MOGN MOGN 2 2 0 *
-0x7100 MBAS MBAS MBAS MBAS 2 2 1 *
-0x7101 MBAS MBAS MBAS MBAS 2 2 GR *
-0x7200 MBER MBER MBER MBER 3 2 BL *
-0x7201 MBER MBER MBER MBER 3 2 1 *
-0x7202 MBER MBER MBER MBER 3 2 CA *
-0x7203 MBER MBER MBER MBER 3 2 PO *
-0x7300 MEAE MEAE MEAE MEAE 4 2 1 *
-0x7301 MEAS MEAS MEAS MEAS 4 2 1 *
-0x7302 MEAE MEAE MEAE MEAE 4 2 SH *
-0x7310 MFIE MFIE MFIE MFIE 4 2 1 *
-0x7311 MFIS MFIS MFIS MFIS 4 2 1 *
-0x7320 MAIR MAIR MAIR MAIR 4 2 1 *
-0x7321 MAIS MAIS MAIS MAIS 4 2 1 *
-0x7400 MDOG MDOG MDOG MDOG 2 2 WI *
-0x7401 MDOG MDOG MDOG MDOG 2 2 WA *
-0x7402 MDOG MDOG MDOG MDOG 2 2 MO *
-0x7500 MDOP MDOP MDOP MDOP 3 2 1 *
-0x7501 MDOP MDOP MDOP MDOP 3 2 GR *
-0x7600 METT METT METT METT 2 2 1 *
-0x7701 MGHL MGHL MGHL MGHL 2 2 1 *
-0x7702 MGHL MGHL MGHL MGHL 2 2 RE *
-0x7703 MGHL MGHL MGHL MGHL 2 2 GA *
-0x7704 MSHD MSHD MSHD MSHD 4 2 1 *
-0x7800 MGIB MGIB MGIB MGIB 2 2 1 *
-0x7900 MSLI MSLI MSLI MSLI 3 3 GR *
-0x7901 MSLI MSLI MSLI MSLI 3 3 OL *
-0x7902 MSLI MSLI MSLI MSLI 3 3 MU *
-0x7903 MSLI MSLI MSLI MSLI 3 3 OC *
-0x7904 MSLI MSLI MSLI MSLI 3 3 1 *
-0x7A00 MSPI MSPI MSPI MSPI 3 2 GI *
-0x7A01 MSPI MSPI MSPI MSPI 3 2 HU *
-0x7A02 MSPI MSPI MSPI MSPI 3 2 PH *
-0x7A03 MSPI MSPI MSPI MSPI 3 2 SW *
-0x7A04 MSPI MSPI MSPI MSPI 3 2 WR *
-0x7B00 MWLF MWLF MWLF MWLF 2 2 1 *
-0x7B01 MWLF MWLF MWLF MWLF 2 2 WO *
-0x7B02 MWLF MWLF MWLF MWLF 2 2 DI *
-0x7B03 MWLF MWLF MWLF MWLF 2 2 WI *
-0x7B04 MWLF MWLF MWLF MWLF 2 2 VA *
-0x7B05 MWLF MWLF MWLF MWLF 2 2 DR *
-0x7B06 MWLS MWLS MWLS MWLS 2 2 1 *
-0x7C00 MXVT MXVT MXVT MXVT 2 2 0 *
-0x7C01 MTAS MTAS MTAS MTAS 2 2 0 *
-0x7D00 MZOM MZOM MZOM MZOM 2 2 0 *
-0x7E00 MWER MWER MWER MWER 2 2 1 *
-0x7E01 MGWE MGWE MGWE MGWE 2 2 1 *
-0x7F00 MTRO MTRO MTRO MTRO 4 2 1 *
-0x7F01 MMIN MMIN MMIN MMIN 4 2 1 *
-0x7F02 MBEH MBEH MBEH MBEH 4 3 1 *
-0x7F03 MIMP MIMP MIMP MIMP 4 2 1 *
-0x7F04 MIGO MIGO MIGO MIGO 4 2 1 *
-0x7F05 MDJI MDJI MDJI MDJI 4 2 1 *
-0x7F06 MDJL MDJL MDJL MDJL 4 2 1 *
-0x7F07 MGLC MGLC MGLC MGLC 4 3 1 *
-0x7F08 MOTY MOTY MOTY MOTY 4 4 1 *
-0x7F09 MSAH MSAH MSAH MSAH 4 2 1 *
-0x7F0A MGCP MGCP MGCP MGCP 4 2 1 *
-0x7F0B MGCL MGCL MGCL MGCL 4 2 1 *
-0x7F0C MKUO MKUO MKUO MKUO 4 2 1 *
-0x7F0D MLIC MLIC MLIC MLIC 4 2 1 *
-0x7F0E MDLI MDLI MDLI MDLI 4 2 1 *
-0x7F0F MTRS MTRS MTRS MTRS 4 2 1 *
-0x7F10 MRAK MRAK MRAK MRAK 4 2 1 *
-0x7F11 MUMB MUMB MUMB MUMB 4 2 1 *
-0x7F12 MVAM MVAM MVAM MVAM 4 2 1 *
-0x7F13 MSNK MSNK MSNK MSNK 4 2 1 *
-0x7F14 MGIT MGIT MGIT MGIT 4 2 1 *
-0x7F15 MBES MBES MBES MBES 4 2 1 *
-0x7F16 AMOO AMOO AMOO AMOO 4 3 1 *
-0x7F17 ARAB ARAB ARAB ARAB 4 1 1 *
-0x7F18 ADER ADER ADER ADER 4 2 1 *
-0x7F19 MDSW MDSW MDSW MDSW 4 2 1 *
-0x7F20 AGRO AGRO AGRO AGRO 4 2 1 *
-0x7F21 APHE APHE APHE APHE 4 2 1 *
-0x7F22 MVAF MVAF MVAF MVAF 4 2 1 *
-0x7F23 MSAT MSAT MSAT MSAT 4 3 1 *
-0x7F24 NPIR NPIR NPIR NPIR 4 2 1 *
-0x7F27 MDRO MDRO MDRO MDRO 4 2 1 *
-0x7F28 MKUL MKUL MKUL MKUL 4 3 1 *
-0x7F29 MFDR MFDR MFDR MFDR 4 2 1 *
-0x7F2A NSAI NSAI NSAI NSAI 4 2 1 *
-0x7F2C NSOL NSOL NSOL NSOL 4 2 1 *
-0x7F2D MWFM MWFM MWFM MWFM 4 2 1 *
-0x7F2E MRAV MRAV MRAV MRAV 4 3 1 *
-0x7F2F MSPS MSPS MSPS MSPS 4 2 1 *
-0x7F30 NBOH NBOH NBOH NBOH 4 2 1 *
-0x7F31 NELL NELL NELL NELL 4 2 1 *
-0x7F32 MSLY MSLY MSLY MSLY 4 2 1 *
-0x7F35 MMIS MMIS MMIS MMIS 4 3 1 *
-0x7F36 NSHD NSHD NSHD NSHD 4 2 1 *
-0x7F37 NIRE NIRE NIRE NIRE 4 2 1 *
-0x8000 MGNL MGNL MGNL MGNL 2 2 0 *
-0x8100 MHOB MHOB MHOB MHOB 2 2 0 *
-0x8200 MKOB MKOB MKOB MKOB 2 2 0 *
-0x9000 MOGR MOGR MOGR MOGR 5 2 0 *
-0xA000 MWYV MWYV MWYV MWYV 8 3 1 *
-0xA100 MCAR MCAR MCAR MCAR 8 3 1 *
-0xB000 ACOW ACOW ACOW ACOW 10 3 1 *
-0xB100 AHRS AHRS AHRS AHRS 10 3 1 *
-0xB200 NBEGL NBEGL NBEGL NBEGL 2 2 0 *
-0xB210 NPROL NPROL NPROL NPROL 2 2 0 *
-0xB300 NBOYL NBOYL NBOYL NBOYL 3 2 0 *
-0xB310 NGRLL NGRLL NGRLL NGRLL 3 2 0 *
-0xB400 NFAML NFAML NFAML NFAML 2 2 0 *
-0xB410 NFAWL NFAWL NFAWL NFAWL 2 2 0 *
-0xB500 NSIML NSIML NSIML NSIML 2 2 0 *
-0xB510 NSIWL NSIWL NSIWL NSIWL 2 2 0 *
-0xB600 NNOML NNOML NNOML NNOML 2 2 0 *
-0xB610 NNOWL NNOWL NNOWL NNOWL 2 2 0 *
-0xB700 NSVLL NSVLL NSIWL NSIWL 2 2 0 *
-0xC000 ABAT ABAT ABAT ABAT 2 1 1 *
-0xC100 ACAT ACAT ACAT ACAT 2 1 1 *
-0xC200 ACHK ACHK ACHK ACHK 2 1 1 *
-0xC300 ARAT ARAT ARAT ARAT 2 1 1 *
-0xC400 ASQU ASQU ASQU ASQU 2 1 1 *
-0xC500 ABAT ABAT ABAT ABAT 2 1 1 *
-0xC600 NBEGH NBEGH NBEGH NBEGH 2 2 0 *
-0xC610 NPROH NPROH NPROH NPROH 2 2 0 *
-0xC700 NBOYH NBOYH NBOYH NBOYH 3 2 0 *
-0xC710 NGRLH NGRLH NGRLH NGRLH 3 2 0 *
-0xC800 NFAMH NFAMH NFAMH NFAMH 2 2 0 *
-0xC810 NFAWH NFAWH NFAWH NFAWH 2 2 0 *
-0xC900 NSIMH NSIMH NSIMH NSIMH 2 2 0 *
-0xC910 NSIWH NSIWH NSIWH NSIWH 2 2 0 *
-0xCA00 NNOMH NNOMH NNOMH NNOMH 2 2 0 *
-0xCA10 NNOWH NNOWH NNOWH NNOWH 2 2 0 *
-0xCB00 NSLVH NSLVH NSLVH NSLVH 2 2 0 *
-0xD000 AEAGG1 AEAGG1 AEAGG1 AEAGG1 7 0 1 *
-0xD100 AGULG1 AGULG1 AGULG1 AGULG1 7 0 1 *
-0xD200 AVULG1 AVULG1 AVULG1 AVULG1 7 0 1 *
-0xD300 ABIRG1 ABIRG1 ABIRG1 ABIRG1 7 0 1 *
-0xD400 ABIRG1 ABIRG1 ABIRG1 ABIRG1 7 0 1 *
-0xE000 MBET MBET MBET MBET 9 2 1 *
-0xE010 MBBM MBBM MBBM MBBM 16 2 1 *
-0xE020 MBBR MBBR MBBR MBBR 9 2 1 *
-0xE030 MBFI MBFI MBFI MBFI 9 2 1 *
-0xE040 MBRH MBRH MBRH MBRH 9 5 1 *
-0xE050 MREM MREM MREM MREM 9 4 1 *
-0xE060 MLIC MLIC MLIC MLIC 9 2 1 *
-0xE068 MHOH MHOH MHOH MHOH 9 2 1 *
-0xE070 MMIN MMIN MMIN MMIN 9 2 1 *
-0xE090 MMER MMER MMER MMER 9 2 1 *
-0xE0A0 MTIC MTIC MTIC MTIC 9 2 1 *
-0xE0B0 MTRO MTRO MTRO MTRO 9 2 1 *
-0xE0C0 MTSN MTSN MTSN MTSN 9 2 1 *
-0xE0D0 MUMB MUMB MUMB MUMB 9 2 1 *
-0xE0E0 MCOR MCOR MCOR MCOR 9 3 1 *
-0xE0F0 MGLA MGLA MGLA MGLA 9 2 1 *
-0xE100 MCYC MCYC MCYC MCYC 9 4 1 *
-0xE110 METN METN METN METN 9 4 1 *
-0xE130 MGFR MGFR MGFR MGFR 9 4 1 *
-0xE140 MGVE MGVE MGVE MGVE 9 4 1 *
-0xE150 MGFO MGFO MGFO MGFO 9 4 1 *
-0xE200 MELA MELA MELA MELA 9 4 1 *
-0xE210 MELE MELE MELE MELE 9 4 1 *
-0xE220 MELF MELF MELF MELF 9 4 1 *
-0xE230 MELW MELW MELW MELW 9 4 1 *
-0xE240 MHAR MHAR MHAR MHAR 9 2 1 *
-0xE250 MWWE MWWE MWWE MWWE 9 2 1 *
-0xE260 MFEY MFEY MFEY MFEY 9 2 1 *
-0xE270 MDTR MDTR MDTR MDTR 9 3 1 *
-0xE280 MFE2 MFE2 MFE2 MFE2 9 3 1 *
-0xE290 MEW2 MEW2 MEW2 MEW2 9 2 1 *
-0xE300 MGH2 MGH2 MGH2 MGH2 9 2 1 *
-0xE310 MGH3 MGH3 MGH3 MGH3 9 2 1 *
-0xE320 MWIG MWIG MWIG MWIG 9 2 1 *
-0xE330 MZO2 MZO2 MZO2 MZO2 9 2 1 *
-0xE340 MZO3 MZO3 MZO3 MZO3 16 2 1 *
-0xE350 MWI2 MWI2 MWI2 MWI2 9 2 1 *
-0xE360 MWI3 MWI3 MWI3 MWI3 9 2 1 *
-0xE380 MMUM MMUM MMUM MMUM 9 2 1 *
-0xE380 MMUM MMUM MMUM MMUM 9 2 1 *
-0xE390 MHIS MHIS MHIS MHIS 9 2 1 *
-0xE3A0 MDRD MDRD MDRD MDRD 9 2 1 *
-0xE3B0 MWAV MWAV MWAV MWAV 9 2 1 *
-0xE400 MGO1 MGO1 MGO1 MGO1 9 2 1 *
-0xE410 MGO2 MGO2 MGO2 MGO2 16 2 1 *
-0xE420 MGO3 MGO3 MGO3 MGO3 9 2 1 *
-0xE430 MGO4 MGO4 MGO4 MGO4 16 2 1 *
-0xE440 MSVI MSVI MSVI MSVI 9 2 1 *
-0xE450 MSV2 MSV2 MSV2 MSV2 9 2 1 *
-0xE460 MGWO MGWO MGWO MGWO 9 2 1 *
-0xE470 MGOC MGOC MGOC MGOC 9 2 1 *
-0xE480 MGW2 MGW2 MGW2 MGW2 9 2 1 *
-0xE490 MGO5 MGO5 MGO5 MGO5 9 2 1 *
-0xE500 MLIZ MLIZ MLIZ MLIZ 9 2 1 *
-0xE510 MGIR MGIR MGIR MGIR 9 3 1 *
-0xE520 MGIC MGIC MGIC MGIC 9 2 1 *
-0xE600 MMYC MMYC MMYC MMYC 9 2 1 *
-0xE610 MMY2 MMY2 MMY2 MMY2 9 2 1 *
-0xE620 MSKB MSKB MSKB MSKB 9 2 1 *
-0xE700 MNO1 MNO1 MNO1 MNO1 9 2 1 *
-0xE710 MNO2 MNO2 MNO2 MNO2 9 2 1 *
-0xE718 MTRO MTRO MTRO MTRO 9 2 1 *
-0xE720 MNO3 MNO3 MNO3 MNO3 9 2 1 *
-0xE730 MTSN MTSN MTSN MTSN 9 2 1 *
-0xE750 MUMB MUMB MUMB MUMB 9 2 1 *
-0xE760 MYET MYET MYET MYET 9 2 1 *
-0xE770 MBA4 MBA4 MBA4 MBA4 9 2 1 *
-0xE780 MBA5 MBA5 MBA5 MBA5 9 2 1 *
-0xE790 MBA6 MBA6 MBA6 MBA6 9 2 1 *
-0xE7A0 MBAI MBAI MBAI MBAI 9 2 1 *
-0xE7B0 MBOA MBOA MBOA MBOA 9 2 1 *
-0xE7C0 MABW MABW MABW MABW 9 2 1 *
-0xE7D0 MMAL MMAL MMAL MMAL 9 2 1 *
-0xE7E0 MSCR MSCR MSCR MSCR 9 2 1 *
-0xE7F0 MUM2 MUM2 MUM2 MUM2 9 2 1 *
-0xE800 MOR6 MOR6 MOR6 MOR6 9 2 1 *
-0xE810 MOR1 MOR1 MOR1 MOR1 9 2 1 *
-0xE820 MOR2 MOR2 MOR2 MOR2 16 2 1 *
-0xE830 MOR3 MOR3 MOR3 MOR3 9 2 1 *
-0xE840 MOR4 MOR4 MOR4 MOR4 16 2 1 *
-0xE850 MOR5 MOR5 MOR5 MOR5 9 2 1 *
-0xE860 MNO1 MNO1 MNO1 MNO1 9 2 1 *
-0xE870 MNO2 MNO2 MNO2 MNO2 9 2 1 *
-0xE880 MNO3 MNO3 MNO3 MNO3 9 2 1 *
-0xE890 MLI3 MLI3 MLI3 MLI3 9 2 1 *
-0xE8A0 MYU3 MYU3 MYU3 MYU3 9 2 1 *
-0xE8B0 MYUH MYUH MYUH MYUH 9 2 1 *
-0xE8C0 MBUG MBUG MBUG MBUG 9 2 1 *
-0xE8D0 MNOS MNOS MNOS MNOS 9 2 1 *
-0xE8E0 MBU2 MBU2 MBU2 MBU2 9 2 1 *
-0xE8F0 MOR7 MOR7 MOR7 MOR7 9 2 1 *
-0xE900 MSAL MSAL MSAL MSAL 16 2 1 *
-0xE908 MSH1 MSH1 MSH1 MSH1 16 2 1 *
-0xE910 MSA2 MSA2 MSA2 MSA2 16 2 1 *
-0xE918 MSH2 MSH2 MSH2 MSH2 16 2 1 *
-0xE920 MGHO MGHO MGHO MGHO 9 2 1 *
-0xEA00 MSHR MSHR MSHR MSHR 9 2 1 *
-0xEA10 MSH1 MSH1 MSH1 MSH1 16 2 1 *
-0xEA20 MCRD MCRD MCRD MCRD 9 2 1 *
-0xEB00 MSKT MSKT MSKT MSKT 9 2 1 *
-0xEB00 MANI MANI MANI MANI 9 3 1 *
-0xEB10 MSKA MSKA MSKA MSKA 9 2 1 *
-0xEB10 MANI MANI MANI MANI 9 2 1 *
-0xEB20 MAN2 MAN2 MAN2 MAN2 9 2 1 *
-0xEB30 MBE1 MBE1 MBE1 MBE1 9 2 1 *
-0xEB40 MBE2 MBE2 MBE2 MBE2 9 2 1 *
-0xEB51 MSEE MSEE MSEE MSEE 9 2 1 *
-0xEB52 MFIR MFIR MFIR MFIR 9 2 1 *
-0xEB60 MLIC MLIC MLIC MLIC 9 2 1 *
-0xEB70 MLER MLER MLER MLER 9 2 1 *
-0xEB80 MMAN MMAN MMAN MMAN 9 2 1 *
-0xEB90 MMYC MMYC MMYC MMYC 9 2 1 *
-0xEBA0 MMY2 MMY2 MMY2 MMY2 9 2 1 *
-0xEBB0 MSHR MSHR MSHR MSHR 9 2 1 *
-0xEBC0 MTAN MTAN MTAN MTAN 9 4 1 *
-0xEBD0 MSAL MSAL MSAL MSAL 16 2 1 *
-0xEBE0 MSA2 MSA2 MSA2 MSA2 16 2 1 *
-0xEBF0 MARU MARU MARU MARU 9 2 1 *
-0xEC00 MWDR MWDR MWDR MWDR 9 2 1 *
-0xEC10 MCHY MCHY MCHY MCHY 9 2 1 *
-0xEC20 MSHE MSHE MSHE MSHE 9 2 1 *
-0xEC30 MCHI MCHI MCHI MCHI 9 2 1 *
-0xEC40 MDH1 MDH1 MDH1 MDH1 9 2 1 *
-0xEC50 MDH2 MDH2 MDH2 MDH2 9 2 1 *
-0xED00 MYU1 MYU1 MYU1 MYU1 9 2 1 *
-0xED09 MCOR MCOR MCOR MCOR 9 3 1 *
-0xED10 MYU2 MYU2 MYU2 MYU2 9 2 1 *
-0xED19 MGLA MGLA MGLA MGLA 9 2 1 *
-0xED20 MYU3 MYU3 MYU3 MYU3 9 2 1 *
-0xED20 MLEM MLEM MLEM MLEM 9 2 1 *
-0xEE00 MWEB MWEB MWEB MWEB 9 2 1 *
-0xEE10 MWRA MWRA MWRA MWRA 9 2 1 *
-0xEF00 MISA MISA MISA MISA 9 2 1 *
-0xEF10 MMAD MMAD MMAD MMAD 9 2 1 *
-0xEF20 MWOR MWOR MWOR MWOR 9 2 1 *
-0xEF50 MKG1 MKG1 MKG1 MKG1 9 2 1 *
-0xEF60 MKG2 MKG2 MKG2 MKG2 9 2 1 *
-0xEF70 MKG3 MKG3 MKG3 MKG3 9 2 1 *
-0xEF90 MWIL MWIL MWIL MWIL 9 2 1 *
-0xEFA0 MGEN MGEN MGEN MGEN 9 2 1 *
-0xEFB0 MGEN MGEN MGEN MGEN 9 3 1 *
-0xEFC0 MGEN MGEN MGEN MGEN 9 4 1 *
-0xEFD0 MGEN MGEN MGEN MGEN 9 5 1 *
-0xEFE0 MGEN MGEN MGEN MGEN 9 1 1 *
-0xEFF0 MGEN MGEN MGEN MGEN 9 6 1 *
-0xF000 MSKA MSKA MSKA MSKA 9 2 1 *
-0xF010 MSKT MSKT MSKT MSKT 9 2 1 *
-0xF020 MWI4 MWI4 MWI4 MWI4 9 2 1 *
-0xF100 MYU1 MYU1 MYU1 MYU1 9 2 1 *
-0xF110 MYU2 MYU2 MYU2 MYU2 9 2 1 *
-0xF200 MLIZ MLIZ MLIZ MLIZ 9 2 1 *
-0xF210 MLI2 MLI2 MLI2 MLI2 9 2 1 *
-0xF300 MGFI MGFI MGFI MGFI 9 4 1 *
-0xF400 MSAH MSAH MSAH MSAH 9 2 1 *
-0xF410 MSAT MSAT MSAT MSAT 9 2 1 *
-0xF500 MDRM MDRM MDRM MDRM 9 4 1 *
-0xF510 MDRF MDRF MDRF MDRF 9 4 1 *
-0xF770 MBA1 MBA1 MBA1 MBA1 9 2 1 *
-0xF780 MBA2 MBA2 MBA2 MBA2 9 2 1 *
-0xF790 MBA3 MBA3 MBA3 MBA3 9 2 1 *
diff --git a/gemrb/override/how/bloodclr.2da b/gemrb/override/how/bloodclr.2da
deleted file mode 100644
index 1b33a30..0000000
--- a/gemrb/override/how/bloodclr.2da
+++ /dev/null
@@ -1,29 +0,0 @@
-2DA V1.0
-0
- VALUE MIN MAX
-NORMAL 0x2f 0x1000 0xffff
-PURPLE 0x2d 0x4300 0x43ff
-MSKEL 0x25 0x5403 0x5403
-DOOMG 0x22 0x5405 0x5406
-MSKEL 0x25 0x6403 0x6403
-DOOMG 0x22 0x6405 0x6406
-YELLOW 0x32 0x7300 0x73ff
-PURPLE 0x3c 0x7500 0x75ff
-YELLOW 0x32 0x7600 0x76ff
-BLACK 0x66 0x7700 0x77ff
-SLI_GR 7 0x7900 0x7900
-SLI_OL 0x24 0x7901 0x7901
-SLI_MU 0x33 0x7902 0x7902
-SLI_OC 0x25 0x7903 0x7903
-SLIME 0x1b 0x7904 0x7904
-SPIDER 0x33 0x7a00 0x7aff
-ZOMBIE 0x25 0x7c00 0x7cff
-MTRO 0x33 0x7f00 0x7f00
-MMIN 0x3d 0x7f01 0x7f03
-MIGO 0x1a 0x7f04 0x7f04
-MGLC 0x5d 0x7f07 0x7f07
-MTRS 0x32 0x7f0f 0x7f0f
-MBES 0x3d 0x7f15 0x7f15
-MCAR 0x38 0xa100 0xa1ff
-UNDEAD 0x66 0xe300 0xe3ff
-MWWE 0x38 0xef00 0xefff
diff --git a/gemrb/override/how/clskills.2da b/gemrb/override/how/clskills.2da
deleted file mode 100644
index 593bfd8..0000000
--- a/gemrb/override/how/clskills.2da
+++ /dev/null
@@ -1,22 +0,0 @@
-2DA V1.0
-*
- HATERACE CLERICSPELL MAGESPELL STARTXP BARDSKILL THIEFSKILL LAYHANDS TURNLEVEL BOOKTYPE
-UNUSED * * * * * * * * *
-MAGE * * MXSPLWIZ 0 * * * *
-FIGHTER * * * 0 * * * *
-CLERIC * MXSPLPRS * 0 * * * 1
-THIEF * * * 0 * SKILLS * *
-BARD * * MXSPLBRD 0 SKILLBRD * * *
-PALADIN * MXSPLPAL * 0 * * PALADIN 5
-FIGHTER_MAGE * * MXSPLWIZ 0 * * * *
-FIGHTER_CLERIC * MXSPLPRS * 0 * * * *
-FIGHTER_THIEF * * * 0 * SKILLS * *
-FIGHTER_MAGE_THIEF * * MXSPLWIZ 0 * SKILLS * *
-DRUID * MXSPLDRU * 0 * * * *
-RANGER HATERACE MXSPLRAN * 0 * * * *
-MAGE_THIEF * * MXSPLWIZ 0 * SKILLS * *
-CLERIC_MAGE * MXSPLPRS MXSPLWIZ 0 * * * *
-CLERIC_THIEF * MXSPLPRS * 0 * SKILLS * *
-FIGHTER_DRUID * MXSPLDRU * 0 * * * *
-FIGHTER_MAGE_CLERIC * MXSPLPRS MXSPLWIZ 0 * * * *
-CLERIC_RANGER HATERACE MXSPLPRS * 0 * * * *
diff --git a/gemrb/override/how/defsound.2da b/gemrb/override/how/defsound.2da
deleted file mode 100644
index 22cfee3..0000000
--- a/gemrb/override/how/defsound.2da
+++ /dev/null
@@ -1,29 +0,0 @@
-2DA V1.0
-*
- RESREF
-OPEN AMB_D03A
-CLOSE AMB_D03B
-HOPEN AMB_D04A
-HCLOSE AMB_D04B
-BUTTON1 GAM_09
-BUTTON2 GAM_03
-BUTTON3 GAM_04
-OPENFAIL *
-CLOSEFAIL *
-ITEM_GONE EFF_M02
-SECRET ACT_09
-11 *
-12 *
-13 *
-14 *
-15 *
-16 *
-17 *
-18 *
-19 *
-LIGHTNING1 AMB_E13A
-LIGHTNING2 AMB_E13B
-LIGHTNING3 AMB_E13F
-RAIN AMB_E11
-SNOW AMB_E02B
-
diff --git a/gemrb/override/how/effects.ids b/gemrb/override/how/effects.ids
deleted file mode 100644
index be5bcb2..0000000
--- a/gemrb/override/how/effects.ids
+++ /dev/null
@@ -1,301 +0,0 @@
-IDS
-0x0 ACVsDamageTypeModifier
-0x1 AttacksPerRoundModifier
-0x2 Cure:Sleep
-0x3 State:Berserk
-0x4 Cure:Berserk
-0x5 State:Charmed
-0x6 CharismaModifier
-0x7 Color:SetPalette
-0x8 Color:SetRGB
-0x9 Color:PulseRGB
-0xa ConstitutionModifier
-0xb Cure:Poison
-0xc Damage
-0xd Death
-0xe Cure:Defrost
-0xf DexterityModifier
-0x10 State:Hasted
-0x11 CurrentHPModifier
-0x12 MaximumHPModifier
-0x13 IntelligenceModifier
-0x14 State:Invisible
-0x15 LoreModifier
-0x16 LuckModifier
-0x17 MoraleModifier
-0x18 State:Panic
-0x19 State:Poisoned
-0x1a RemoveCurse
-0x1b AcidResistanceModifier
-0x1c ColdResistanceModifier
-0x1d ElectricityResistanceModifier
-0x1e FireResistanceModifier
-0x1f MagicDamageResistanceModifier
-0x20 Cure:Death
-0x21 SaveVsDeathModifier
-0x22 SaveVsWandsModifier
-0x23 SaveVsPolyModifier
-0x24 SaveVsBreathModifier
-0x25 SaveVsSpellsModifier
-0x26 State:Silenced
-0x27 State:Helpless
-0x28 State:Slowed
-0x29 Sparkle
-0x2a WizardSpellSlotsModifier
-0x2b Cure:Petrification
-0x2c StrengthModifier
-0x2d State:Stun
-0x2e Cure:Stun
-0x2f Cure:Invisible
-0x30 Cure:Silence
-0x31 WisdomModifier
-0x32 Color:BriefRGB
-0x33 Color:DarkenRGB
-0x34 Color:GlowRGB
-0x35 AnimationIDModifier
-0x36 ToHitModifier
-0x37 KillCreatureType
-0x38 Alignment:Invert
-0x39 Alignment:Change
-0x3a DispelEffects
-0x3b StealthModifier
-0x3c MiscastMagicModifier
-0x3d AlchemyModifier
-0x3e PriestSpellSlotsModifier
-0x3f State:Infravision
-0x40 Cure:Infravision
-0x41 State:Blur
-0x42 TransparencyModifier
-0x43 SummonCreature
-0x44 UnsummonCreature
-0x45 State:NonDetection
-0x46 Cure:NonDetection
-0x47 SexModifier
-0x48 AIIdentifierModifier
-0x49 DamageBonusModifier
-0x4a State:Blind
-0x4b Cure:Blind
-0x4c State:Feeblemind
-0x4d Cure:Feeblemind
-0x4e State:Diseased
-0x4f Cure:Disease
-0x50 State:Deafness
-0x51 Cure:Deafness
-0x52 SetAIScript
-0x53 Protection:Projectile
-0x54 MagicalFireResistanceModifier
-0x55 MagicalColdResistanceModifier
-0x56 SlashingResistanceModifier
-0x57 CrushingResistanceModifier
-0x58 PiercingResistanceModifier
-0x59 MissilesResistanceModifier
-0x5a OpenLocksModifier
-0x5b FindTrapsModifier
-0x5c PickPocketsModifier
-0x5d FatigueModifier
-0x5e IntoxicationModifier
-0x5f TrackingModifier
-0x60 LevelModifier
-0x61 StrengthBonusModifier
-0x62 State:Regenerating
-0x63 SpellDurationModifier
-0x64 Protection:Creature
-0x65 Protection:Opcode
-0x66 Protection:SpellLevel
-0x67 ChangeName
-0x68 ExperienceModifier
-0x69 GoldModifier
-0x6a MoraleBreakModifier
-0x6b PortraitChange
-0x6c ReputationModifier
-0x6d State:Hold3
-0x6e RetreatFrom
-0x6f Item:CreateMagic
-0x70 Item:Remove
-0x71 Item:Equip
-0x72 Dither
-0x73 DetectAlignment
-0x74 Cure:Invisible2
-0x75 Reveal:Area
-0x76 Reveal:Creatures
-0x77 MirrorImage
-0x78 Protection:Weapons
-0x79 VisualAnimationEffect
-0x7a Item:CreateInventory
-0x7b Item:RemoveInventory
-0x7c DimensionDoor
-0x7d Unlock
-0x7e MovementRateModifier
-0x7f MonsterSummoning
-0x80 State:Confused
-0x81 AidNonCumulative
-0x82 BlessNonCumulative
-0x83 ChantNonCumulative
-0x84 HolyNonCumulative
-0x85 LuckNonCumulative
-0x86 State:Petrification
-0x87 Polymorph
-0x88 ForceVisible
-0x89 ChantBadNonCumulative
-0x8a AnimationStateChange
-0x8b DisplayString
-0x8c CastingGlow
-0x8d VisualSpellHit
-0x8e Icon:Display
-0x8f Item:CreateInSlot
-0x90 DisableButton
-0x91 DisableCasting
-0x92 Spell:Cast
-0x93 Spell:Learn
-0x94 Spell:CastPoint
-0x95 Identify
-0x96 FindTraps
-0x97 ReplaceCreature
-0x98 PlayMovie
-0x99 Overlay:Sanctuary
-0x9a Overlay:Entangle
-0x9b Overlay:MinorGlobe
-0x9c Overlay:ShieldGlobe
-0x9d Overlay:Web
-0x9e Overlay:Grease
-0x9f MirrorImageModifier
-0xa0 Cure:Sanctuary
-0xa1 Cure:Panic
-0xa2 Cure:Hold
-0xa3 FreeAction
-0xa4 Cure:Intoxication
-0xa5 PauseTarget
-0xa6 MagicResistanceModifier
-0xa7 MissileHitModifier
-0xa8 RemoveCreature
-0xa9 Icon:Disable
-0xaa DamageAnimation
-0xab Spell:Add
-0xac Spell:Remove
-0xad PoisonResistanceModifier
-0xae PlaySound
-0xaf State:Hold
-0xb0 MovementRateModifier2
-0xb1 ApplyEffect
-0xb2 ToHitVsCreature
-0xb3 DamageVsCreature
-0xb4 CantUseItem
-0xb5 CantUseItemType
-0xb6 ApplyEffectItem
-0xb7 ApplyEffectItemType
-0xb8 DontJumpModifier
-0xb9 State:Hold2
-0xba MoveToArea
-0xbb Variable:StoreLocalVariable
-0xbc AuraCleansingModifier
-0xbd CastingSpeedModifier
-0xbe AttackSpeedModifier
-0xbf CastingLevelModifier
-0xc0 FindFamiliar
-0xc1 InvisibleDetection
-0xc2 IgnoreDialogPause
-0xc3 FamiliarBond
-0xc4 FamiliarMarker
-0xc5 Bounce:Projectile
-0xc6 Bounce:Opcode
-0xc7 Bounce:SpellLevel
-0xc8 Bounce:SpellLevelDec
-0xc9 Protection:SpellLevelDec
-0xca Bounce:School
-0xcb Bounce:SecondaryType
-0xcc Protection:School
-0xcd Protection:SecondaryType
-0xce Protection:Spell2
-0xcf Bounce:Spell
-0xd0 MinimumHPModifier
-0xd1 PowerWordKill
-0xd2 PowerWordStun
-0xd3 State:Imprisonment
-0xd4 Cure:Imprisonment
-0xd5 Maze
-0xd6 CastFromList
-0xd7 PlayVisualEffect
-0xd8 LevelDrainModifier
-0xd9 PowerWordSleep
-0xda StoneskinModifier
-0xdb ACVsCreatureType
-0xdc DispelSchool
-0xdd DispelSecondaryType
-0xde RandomTeleport
-0xdf Protection:SchoolDec
-0xe0 Cure:LevelDrain
-0xe1 Reveal:Magic
-0xe2 Protection:SecondaryTypeDec
-0xe3 Bounce:SchoolDec
-0xe4 Bounce:SecondaryTypeDec
-0xe5 DispelSchoolOne
-0xe6 DispelSecondaryTypeOne
-0xe7 TimeStop
-0xe8 Color:FadeRGB
-0xe9 IWDVisualSpellHit
-0xea ColdDamage
-0xeb CastingGlow2
-0xec ChillTouch
-0xed CrushingDamage
-0xee SaveBonus
-0xef SlowPoison
-0xf0 IWDMonsterSummoning
-0xf1 VampiricTouch
-0xf2 Overlay
-0xf3 AnimateDead
-0xf4 Prayer2
-0xf5 Curse2
-0xf6 SummonMonster2
-0xf7 BurningBlood
-0xf8 SummonShadowMonster
-0xf9 Recitation
-0xfa RecitationBad
-0xfb Hold2
-0xfc BlindingOrb
-0xfd ACVsDamageTypeModifier2
-0xfe RemoveEffects
-0xff SalamanderAura
-0x100 UmberHulkGaze
-0x101 ZombieLordAura
-0x102 Protection:Spell
-0x103 SummonCreature2
-0x104 AvatarRemoval
-0x105 Protection:Opcode2
-0x106 SummonPomab
-0x107 ControlUndead
-0x108 StaticCharge
-0x109 CloakOfFear
-0x10a MovementRateModifier3
-0x10b Cure:Confusion
-0x10c EyeOfTheMind
-0x10d EyeOfTheSword
-0x10e EyeOfTheMage
-0x10f EyeOfVenom
-0x110 EyeOfTheSpirit
-0x111 EyeOfFortitude
-0x112 EyeOfStone
-0x113 RemoveSevenEyes
-0x114 RemoveEffect
-0x115 SoulEater
-0x116 ShroudOfFlame
-0x117 AnimalRage
-0x118 TurnUndead
-0x119 VitriolicSphere
-0x11a SuppressHP
-0x11b FloatText
-0x11c MaceOfDisruption
-0x11d State:Sleep
-0x11e Reveal:Tracks
-0x11f Protection:Backstab
-0x120 State:Set
-0x121 Cutscene
-0x122 Protection:Spell3
-0x123 RodOfSmithing
-0x124 MagicalRest
-0x125 BeholderDispelMagic
-0x126 HarpyWail
-0x127 JackalWereGaze
-0x128 ModifyGlobalVariable
-0x129 HideInShadowsModifier
-0x12a UseMagicDeviceModifier
-399 AlterAnimation
diff --git a/gemrb/override/how/fonts.2da b/gemrb/override/how/fonts.2da
deleted file mode 100644
index fe1ed92..0000000
--- a/gemrb/override/how/fonts.2da
+++ /dev/null
@@ -1,19 +0,0 @@
-2DA V1.0
-NORMAL
- RESREF NEED_PALETTE FIRST_CHAR
-0 NORMAL 1 0
-1 INFOFONT 1 0
-2 NUMBER 0 47
-3 INITIALS 0 0
-4 NUMBER2 0 47
-5 NUMBER3 0 47
-6 NUMFONT 1 0
-7 REALMS 0 0
-8 REALMS2 1 0
-9 STONEBIG 0 0
-10 STONESM2 0 0
-11 STONESM3 0 0
-12 STONESML 0 0
-13 TOOLFONT 1 0
-14 STATES 0 0
-15 STATES2 0 0
diff --git a/gemrb/override/how/gametime.2da b/gemrb/override/how/gametime.2da
deleted file mode 100644
index 2d29d2c..0000000
--- a/gemrb/override/how/gametime.2da
+++ /dev/null
@@ -1,5 +0,0 @@
-2DA V1.0
-0
- DURATION
-ROUND_SECONDS 7
-TURN_SECONDS 70
diff --git a/gemrb/override/how/gemrb.ini b/gemrb/override/how/gemrb.ini
deleted file mode 100644
index 2bc8091..0000000
--- a/gemrb/override/how/gemrb.ini
+++ /dev/null
@@ -1,123 +0,0 @@
-; GemRB - Infinity Engine Emulator
-; Copyright (C) 2003 The GemRB Project
-;
-; This program is free software; you can redistribute it and/or
-; modify it under the terms of the GNU General Public License
-; as published by the Free Software Foundation; either version 2
-; of the License, or (at your option) any later version.
-;
-; This program is distributed in the hope that it will be useful,
-; but WITHOUT ANY WARRANTY; without even the implied warranty of
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-; GNU General Public License for more details.
-;
-; You should have received a copy of the GNU General Public License
-; along with this program; if not, write to the Free Software
-; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-;
-
-
-; gemrb.ini - game type-specific settings for GemRB engine
-
-[resources]
-
-; Bitmap resource for cursors
-CursorBAM = CAROT
-
-; Bitmap resource for scroll cursor arrow
-ScrollCursorBAM = CURSARW
-
-; Bitmap resource for dialog buttons font
-ButtonFont = STONESML
-
-; Font used to display tooltips
-TooltipFont = TOOLFONT
-
-; Font used to display subtitles
-MovieFont = NORMAL
-
-; Sprite displayed behind the tooltip text, if any
-TooltipBack = TOOLTIP
-
-; Tooltip text color (RGBA)
-TooltipColor = #ffffffff
-
-; Space between tooltip text and sides of TooltipBack (x2)
-TooltipMargin = 2
-
-; INI file from the original games
-INIConfig = icewind.ini
-
-; Palette bitmaps in various widths
-Palette16 = MPALETTE
-Palette32 = MPALETTE
-Palette256 = MPAL256
-
-MaximumAbility = 25
-IgnoreButtonFrames = 0
-AllStringsTagged = 1
-HasDPLAYER = 1
-HasPickSound = 0
-HasDescIcon = 0
-HasEXPTABLE = 1
-SoundFolders = 1
-HasSongList = 0
-ReverseToHit = 1
-UpperButtonText = 0
-LowerLabelText = 0
-HasPartyINI = 0
-HasBeastsINI = 0
-ForceStereo = 0
-IWDMapDimensions = 1
-SmallFog = 0
-ReverseDoor = 0
-IWD2ScriptName = 1
-DialogueScrolls = 0
-CharNameIsGabber = 1
-MagicBit = 1
-SpawnIni = 1
-SelectiveMagicRes = 1
-HasHideInShadows = 1
-AreaVisitedVar = 1
-HasSpecificDamageBonus = 1
-BiographyIsRes = 1
-FlexibleWorldmap = 1
-AutoSearchHidden = 1
-CutsceneAreascripts = 0
-PSTStateFlags = 0
-CastingSounds = 1
-ForceAreaScript = 1
-
-[charset]
-CharCount = 31
-Letter1 = 192,224
-Letter2 = 193,225
-Letter3 = 194,226
-Letter4 = 195,227
-Letter5 = 196,228
-Letter6 = 197,229
-Letter7 = 198,230
-Letter8 = 199,231
-Letter9 = 200,232
-Letter10 = 201,233
-Letter11 = 202,234
-Letter12 = 203,235
-Letter13 = 204,236
-Letter14 = 205,237
-Letter15 = 206,238
-Letter16 = 207,239
-Letter17 = 208,240
-Letter18 = 209,241
-Letter19 = 210,242
-Letter20 = 211,243
-Letter21 = 212,244
-Letter22 = 213,245
-Letter23 = 214,246
-Letter24 = 140,156
-Letter25 = 216,248
-Letter26 = 217,249
-Letter27 = 218,250
-Letter28 = 219,251
-Letter29 = 220,252
-Letter30 = 221,253
-Letter31 = 222,254
diff --git a/gemrb/override/how/itemsnd.2da b/gemrb/override/how/itemsnd.2da
deleted file mode 100644
index 9678ee9..0000000
--- a/gemrb/override/how/itemsnd.2da
+++ /dev/null
@@ -1,80 +0,0 @@
-2DA V1.0
-*
- TAKE DROP
-AMULET G_NECK1 G_NECK2
-ARMOR G_CLOAK1 G_CLOAK2
-BELT G_BELT1 G_BELT2
-BOOT G_BOOT1 G_BOOT2
-ARROW G_ARRW1 G_ARRW2
-BRACER G_GLOVE1 G_GLOVE2
-HELMET G_HELM1 G_HELM2
-KEY G_KEY1 G_KEY2
-POTION G_POTN1 G_POTN2
-RING G_RING1 G_RING2
-SCROLL G_SCROL1 G_SCROL2
-SHIELD GAM_21A GAM_21B
-FOOD GAM_21A GAM_21B
-BULLET G_BULLT1 G_BULLT2
-BOW G_BOW1 G_BOW2
-DAGGER G_DAGGR1 G_DAGGR2
-MACE G_MACE1 G_MACE2
-SLING G_SLING1 G_SLING2
-SMSWORD G_SMSWD1 G_SMSWD2
-BGSWORD G_LGSWD1 G_LGSWD2
-HAMMER G_HAMMR1 G_HAMMR2
-MSTAR G_MSTAR1 G_MSTAR2
-FLAIL G_FLAIL1 G_FLAIL2
-DART G_DART1 G_DART2
-AXE G_AXE1 G_AXE2
-STAFF G_STAFF1 G_STAFF2
-XBOW G_CROSB1 G_CROSB2
-FIST GAM_21A GAM_21B
-SPEAR G_SPEAR1 G_SPEAR2
-POLEARM G_HALB1 G_HALB2
-BOLT G_BOLT1 G_BOLT2
-CLOAK G_CLOAK1 G_CLOAK2
-COIN G_GOLD1 G_GOLD2
-GEM G_GEM1 G_GEM2
-WAND G_WAND1 G_WAND2
-BROKEN1 G_B_ARM1 G_B_ARM2
-BROKEN2 G_B_SHD1 G_B_SHD2
-BROKEN3 G_B_WPN1 G_B_WPN2
-UNUSED1 GAM_21A GAM_21B
-UNUSED2 G_BROKN1 G_BROKN2
-BUCKLER G_BUCKR1 G_BUCKR2
-CANDLE G_CAND1 G_CAND2
-CBODY G_CHILD1 G_CHILD2
-CLUB G_CLUB1 G_CLUB2
-FBODY G_FEM1 G_FEM2
-KEY2 G_KEYS1 G_KEYS2
-LSHIELD G_LGSLD1 G_LGSLD2
-MBODY G_MALE1 G_MALE2
-MSHIELD G_MDSLD1 G_MDSLD2
-NOTES G_PAPR1 G_PAPR2
-ROD G_ROD1 G_ROD2
-SKULL G_SKULL1 G_SKULL2
-SSHIELD G_SMSLD1 G_SMSLD2
-SPIDER G_SPIDR1 G_SPIDR2
-TELESCOPE G_TELE1 G_TELE2
-DRINK G_WINE1 G_WINE2
-GTSWORD G_LGSWD1 G_LGSWD2
-BAG GAM_21A GAM_21B
-FUR G_LETHR1 G_LETHR2
-LARMOR G_CLOAK1 G_CLOAK2
-SLARMOR G_CLOAK1 G_CLOAK2
-CHARMOR G_CLOAK1 G_CLOAK2
-SPARMOR G_CLOAK1 G_CLOAK2
-HPARMOR G_CLOAK1 G_CLOAK2
-FPARMOR G_CLOAK1 G_CLOAK2
-HARMOR G_CLOAK1 G_CLOAK2
-ROBE G_CLOAK1 G_CLOAK2
-SCALE G_CLOAK1 G_CLOAK2
-BTSWORD G_LGSWD1 G_LGSWD2
-SCARF G_GLOVE1 G_GLOVE2
-FOOD2 G_SLING1 G_SLING2
-HAT G_GLOVE1 G_GLOVE2
-GAUNTLET G_CAND1 G_CAND2
-DEFAULT GAM_21A GAM_21B
-LEATHER G_LETHR1 G_LETHR2
-CHAIN G_Chain1 G_Chain2
-PLATE G_Plate1 G_Plate2
diff --git a/gemrb/override/how/itemtype.2da b/gemrb/override/how/itemtype.2da
deleted file mode 100644
index b7f7e28..0000000
--- a/gemrb/override/how/itemtype.2da
+++ /dev/null
@@ -1,77 +0,0 @@
-2DA V1.0
-0
- HELMET ARMOR SHIELD GLOVES RING AMULET BELT BOOTS WEAPON QUIVER CLOAK QUICK SCROLL BAG POTION
-MISC 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
-AMULET 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
-ARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-BELT 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
-BOOT 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
-ARROW 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
-BRACER 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
-HELMET 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-KEY 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-POTION 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
-RING 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
-SCROLL 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0
-SHIELD 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
-FOOD 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
-BULLET 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
-BOW 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-DAGGER 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-MACE 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-SLING 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-SMSWORD 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-BGSWORD 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-HAMMER 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-MSTAR 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-FLAIL 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-DART 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-AXE 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-STAFF 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-XBOW 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-FIST 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-SPEAR 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-POLEARM 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-BOLT 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
-CLOAK 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
-COIN 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-GEM 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
-WAND 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
-BROKEN1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-BROKEN2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-BROKEN3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-UNUSED1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-UNUSED2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-BUCKLER 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
-CANDLE 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-UNUSED3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-CLUB 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-UNUSED4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-UNUSED5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-LSHIELD 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
-UNUSED6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-MSHIELD 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
-NOTES 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-UNUSED7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-UNUSED8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-SSHIELD 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
-UNUSED9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-TELESCOPE 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-DRINK 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
-GTSWORD 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-BAG 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
-FUR 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-LARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-SLARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-CHARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-SPARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-HPARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-FPARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-HARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-ROBE 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-UNUSED10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-BTSWORD 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-SCARF 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-FOOD2 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
-HAT 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-GAUNTLET 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
diff --git a/gemrb/override/how/magesch.2da b/gemrb/override/how/magesch.2da
deleted file mode 100644
index acd3cef..0000000
--- a/gemrb/override/how/magesch.2da
+++ /dev/null
@@ -1,12 +0,0 @@
-2DA V1.0
--1
- NAME_REF DESC_REF CAP_REF KIT
-GENERALIST 18039 9563 9987 0x4000
-ABJURER 597 9564 502 0x40
-CONJURER 2179 9565 504 0x80
-DIVINER 2846 9566 2012 0x100
-ENCHANTER 2861 9567 2022 0x200
-ILLUSIONIST 2862 9568 8421 0x400
-INVOKER 3015 9569 12786 0x800
-NECROMANCER 12744 9570 12787 0x1000
-TRANSMUTER 12745 9571 12788 0x2000
diff --git a/gemrb/override/how/overlay.2da b/gemrb/override/how/overlay.2da
deleted file mode 100644
index 229ff10..0000000
--- a/gemrb/override/how/overlay.2da
+++ /dev/null
@@ -1,35 +0,0 @@
-2DA V1.0
-*
- VVC UNDER FLAGS
-SANCTUARY SANCTUC 0 1
-ENTANGLE ENTANGC 0 0
-WISP WISP 0 0
-SHIELDGLOBE SHIELDC 0 1
-GREASE GREASEC 1 0
-WEB WEBC 1 0
-MINORGLOBE MGOINVC 0 1
-GLOBE GOINVUC 0 1
-FLAMESHROUD SOFLAMC 0 0
-ANTIMAGIC AMSHELC 0 0
-RESILIENT ORSPHEC 0 0
-PROTFROMMISS PFNMISC 0 0
-CLOAKOFFEAR COFEARC 0 0
-ENTROPY ESHIELC 0 0
-FIREAURA FIAURAC 0 0
-FROSTAURA FRAURAC 0 0
-INSECT IPLAGUC 0 0
-STORMSHELL SSHELLC 0 0
-LATHANDER1 SOLATC1 0 0
-LATHANDER2 SOLATC2 1 0
-GLATHANDER1 GSOLAC1 0 0
-GLATHANDER2 GSOLAC2 1 0
-SEVENEYES1 SEYESC1 0 0
-SEVENEYES2 SEYESC2 1 0
-BOUNCE SPTURNI2 1 0
-BOUNCE2 SPTURNI 1 0
-FIRESHIELD1 FSHIRC1 0 0
-FIRESHIELD2 FSHIRC2 1 0
-ICESHIELD1 FSHIBC1 0 0
-ICESHIELD2 FSHIBC2 1 0
-TORTOISE TSHELLC 0 0
-DEATHARMOR DARMORC 0 0
diff --git a/gemrb/override/how/qslots.2da b/gemrb/override/how/qslots.2da
deleted file mode 100644
index c9fc3d2..0000000
--- a/gemrb/override/how/qslots.2da
+++ /dev/null
@@ -1,24 +0,0 @@
-2DA V1.0
-100
- SLOT1 SLOT2 SLOT3 SLOT4 SLOT5 SLOT6 SLOT7 SLOT8 SLOT9
-DEFAULT 18 19 14 100 8 9 11 12 13
-MAGE 3 4 5 2 8 9 11 12 13
-FIGHTER 18 19 14 100 8 9 11 12 13
-CLERIC 6 3 4 2 8 9 11 12 13
-THIEF 22 0 1 100 8 9 11 12 13
-BARD 20 1 3 2 8 9 11 12 13
-PALADIN 18 14 6 2 8 9 11 12 13
-FIGHTER_MAGE 3 4 5 2 8 9 11 12 13
-FIGHTER_CLERIC 6 3 4 2 8 9 11 12 13
-FIGHTER_THIEF 18 22 0 1 8 9 11 12 13
-FIGHTER_MAGE_THIEF 22 0 1 2 8 9 11 12 13
-DRUID 3 4 5 2 8 9 11 12 13
-RANGER 18 14 0 2 8 9 11 12 13
-MAGE_THIEF 22 0 1 2 8 9 11 12 13
-CLERIC_MAGE 6 3 4 2 8 9 11 12 13
-CLERIC_THIEF 22 0 1 2 8 9 11 12 13
-FIGHTER_DRUID 3 4 5 2 8 9 11 12 13
-FIGHTER_MAGE_CLERIC 6 3 4 2 8 9 11 12 13
-CLERIC_RANGER 6 3 4 2 8 9 11 12 13
-SORCERER 3 4 5 2 8 9 11 12 13
-MONK 18 14 22 0 8 9 11 12 13
diff --git a/gemrb/override/how/strings.2da b/gemrb/override/how/strings.2da
deleted file mode 100644
index aaa9aee..0000000
--- a/gemrb/override/how/strings.2da
+++ /dev/null
@@ -1,170 +0,0 @@
-2DA V1.0
--1
- STRREF
-SCATTERED 16457
-WHOLEPARTY 16484
-DOORLOCKED 16485
-MAGICTRAP 16486
-NORMALTRAP 16487
-TRAP 16488
-CANNOTGO 16489
-TRAPREMOVED 16490
-OVERSTOCKED 16491
-SLEEP 16492
-AMBUSH 16493
-CONTLOCKED 16494
-NOMONEY 16495
-CURSED 16496
-SPELLDISRUPT 16497
-DIED 16498
-MAYNOTREST 16499
-CANTRESTMONS 16500
-CANTSAVEMONS 16501
-CANTSAVE 16502
-NODIALOG 10945
-CANTSAVEDIALOG 19253
-CANTSAVEDIALOG2 19254
-CANTSAVEMOVIE 19255
-TARGETBUSY -1
-CANTTALKTRANS -1
-GOTGOLD 17572
-LOSTGOLD 17573
-GOTXP 17574
-LOSTXP 17575
-GOTITEM 17576
-LOSTITEM 17577
-GOTREP 19686
-LOSTREP 19687
-GOTABILITY 10514
-GOTSPELL 10514
-GOTSONG 26320
-NOTHINGTOSAY -1
-JOURNALCHANGE 11359
-WORLDMAPCHANGE 11360
-PAUSED 16321
-UNPAUSED 16322
-SCRIPTPAUSED 7666
-AP_UNUSABLE 17113
-AP_ATTACKED 17114
-AP_HIT 17115
-AP_WOUNDED 17116
-AP_DEAD 17117
-AP_NOTARGET 17118
-AP_ENDROUND 10014
-AP_ENEMY 23511
-AP_TRAP -1
-AP_SPELLCAST -1
-AP_RESERVED1 -1
-AP_RESERVED2 -1
-AP_RESERVED3 -1
-AP_RESERVED4 -1
-CHARMED 14672
-DIRECHARMED 14780
-CONTROLLED -1
-EVIL 16505
-GNE_NEUTRAL 16504
-GOOD 16503
-STR_LAWFUL -1
-LNC_NEUTRAL -1
-CHAOTIC -1
-ACTION_CAST 16464
-ACTION_ATTACK 16465
-ACTION_TURN 16466
-ACTION_SONG 16467
-ACTION_FINDTRAP 16468
-MAGICWEAPON 10141
-OFFHAND_USED 9380
-TWOHANDED_USED 9381
-CANNOT_USE_ITEM 9382
-CANT_DROP_ITEM 25697
-NOT_IN_OFFHAND 26342
-ITEM_IS_CURSED 16304
-NO_CRITICAL 20696
-TRACKING -1
-TRACKINGFAILED 19534
-DOOR_NOPICK 23169
-CONT_NOPICK 23169
-CANTSAVECOMBAT -1
-CANTSAVENOCTRL -1
-LOCKPICK_DONE 16517
-LOCKPICK_FAILED 16518
-STATIC_DISSIPATE 26518
-LIGHTNING_DISSIPATE -1
-HAS_NO_ABILITY 17317
-NEEDS_IDENTIFY 17316
-WRONG_ITEMTYPE 9375
-HAS_ITEMEXCL 20685
-PICKPOCKET_DONE 10072
-PICKPOCKET_NONE 18297
-PICKPOCKET_FAIL 10069
-PICKPOCKET_EVIL 10068
-PICKPOCKET_ARMOR 10067
-USING_FEAT -1
-STOPPED_FEAT -1
-DISARM_DONE 16520
-DISARM_FAIL 1608
-DOORBASH_DONE 9915
-DOORBASH_FAIL 9913
-CONTBASH_DONE 9916
-CONTBASH_FAIL 9914
-MAYNOTSETTRAP -1
-SNAREFAILED -1
-SNARESUCCEED -1
-NOMORETRAP -1
-DISABLEDMAGE -1
-SAVESUCCEED 1682
-QSAVESUCCEED 10237
-UNINJURED 2943
-INJURED1 2944
-INJURED2 2945
-INJURED3 2946
-INJURED4 2947
-HOURS 10700
-HOUR 10701
-DAYS 10697
-DAY 10698
-REST 10690
-JOURNEY 10689
-PST_REST -1
-PST_HOUR -1
-PST_HOURS -1
-DAMAGE_IMMUNITY 25038
-DAMAGE_STR1 25028
-DAMAGE_STR2 25017
-DAMAGE_STR3 26223
-DMG_POISON 25018
-DMG_MAGIC 25019
-DMG_MISSILE 25020
-DMG_SLASHING 25021
-DMG_PIERCING 25022
-DMG_CRUSHING 25023
-DMG_FIRE 25024
-DMG_ELECTRIC 25025
-DMG_COLD 25026
-DMG_ACID 25027
-DMG_OTHER 0
-GOTQUESTXP -1
-LEVELUP 17119
-INVFULL_ITEMDROP 32879
-CONT_DUP 32876
-CONT_TRIG -1
-CONT_FAIL -1
-SEQ_DUP -1
-CRITICAL_HIT 16462
-CRITICAL_MISS 16463
-DEATH 14026
-BACKSTAB 12128
-BACKSTAB_BAD 10013
-BACKSTAB_FAIL -1
-CASTER_LVL_INC -1
-CASTER_LVL_DEC -1
-CHARS_EXPORTED 26827
-PALADIN_FALL 19620
-RANGER_FALL 19621
-RES_RESISTED 26818
-DEADMAGIC_FAIL -1
-MISCASTMAGIC -1
-WILDSURGE -1
-FAMBLOCK 8537
-FAMPROTAGONIST 8538
-
diff --git a/gemrb/override/how/vcremap.2da b/gemrb/override/how/vcremap.2da
deleted file mode 100644
index b23c7aa..0000000
--- a/gemrb/override/how/vcremap.2da
+++ /dev/null
@@ -1,4 +0,0 @@
-2DA V1.0
-*
- ORIGINAL NEW
-BIO 74 63
diff --git a/gemrb/override/iwd/CMakeLists.txt b/gemrb/override/iwd/CMakeLists.txt
deleted file mode 100644
index a662b98..0000000
--- a/gemrb/override/iwd/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-ADD_GEMRB_OVERRIDE (iwd)
\ No newline at end of file
diff --git a/gemrb/override/iwd/Makefile.am b/gemrb/override/iwd/Makefile.am
index 9db0196..83bdd45 100644
--- a/gemrb/override/iwd/Makefile.am
+++ b/gemrb/override/iwd/Makefile.am
@@ -1,3 +1,3 @@
-iwdoverride_DATA = *.2da *.bmp *.ini *.chu *.ids *.bcs
+iwdoverride_DATA = *.2da *.bcs
iwdoverridedir = $(moddir)/override/iwd/
-EXTRA_DIST = *.2da *.bmp *.ini *.chu *.ids *.bcs
+EXTRA_DIST = *.2da *.bcs
diff --git a/gemrb/override/iwd/avatars.2da b/gemrb/override/iwd/avatars.2da
deleted file mode 100644
index 1db34c5..0000000
--- a/gemrb/override/iwd/avatars.2da
+++ /dev/null
@@ -1,414 +0,0 @@
-2DA V1.0
-*
- AT_1 AT_2 AT_3 AT_4 TYPE SPACE PALETTE SIZE
-0x0100 SPCHUNKS SPCHUNKS SPCHUNKS SPCHUNKS 13 0 0 *
-0x0300 SPSMPUFF SPSMPUFF SPSMPUFF SPSMPUFF 13 0 0 *
-0x0400 SKLH SKLH SKLH SKLH 13 0 1 *
-0x0410 GLPHWRDH GLPHWRDH GLPHWRDH GLPHWRDH 13 0 1 *
-0x1000 MWYV MWYV MWYV MWYV 11 5 1 *
-0x1001 MWYV MWYV MWYV MWYV 11 5 1 *
-0x1100 MTAN MTAN MTAN MTAN 11 5 1 *
-0x1200 MDR1 MDR1 MDR1 MDR1 12 5 1 *
-0x1201 MDR2 MDR2 MDR2 MDR2 12 5 1 *
-0x1202 MDR3 MDR3 MDR3 MDR3 12 5 1 *
-0x1203 MDR1 MDR1 MDR1 MDR1 12 7 GR *
-0x1204 MDR1 MDR1 MDR1 MDR1 12 7 AQ *
-0x1205 MDR1 MDR1 MDR1 MDR1 12 7 BL *
-0x1206 MDR1 MDR1 MDR1 MDR1 12 7 BR *
-0x1207 MDR1 MDR1 MDR1 MDR1 12 7 MC *
-0x1208 MDR1 MDR1 MDR1 MDR1 12 7 PU *
-0x2000 MSIR MSIR MSIR MSIR 2 2 0 *
-0x2100 UVOL UVOL UVOL UVOL 2 2 1 *
-0x2200 MOGM MOGM MOGM MOGM 2 2 0 S
-0x2300 MDKN MDKN MDKN MDKN 2 2 1 *
-0x3000 MAKH MAKH MAKH MAKH 2 3 1 *
-0x4000 SNOMC SNOMC SNOMC SNOMC 1 2 0 *
-0x4002 SNOMM SNOMM SNOMM SNOMM 1 2 0 *
-0x4010 SNOWC SNOWC SNOWC SNOWC 1 2 0 *
-0x4012 SNOWM SNOWM SNOWM SNOWM 1 2 0 *
-0x4100 SSIMC SSIMC SSIMC SSIMC 1 2 0 *
-0x4101 SSIMS SSIMS SSIMS SSIMS 1 2 0 *
-0x4102 SSIMM SSIMM SSIMM SSIMM 1 2 0 *
-0x4110 SSIWC SSIWC SSIWC SSIWC 1 2 0 *
-0x4112 SSIWM SSIWM SSIWM SSIWM 1 2 0 *
-0x4200 SHMCM SHMCM SHMCM SHMCM 1 2 0 *
-0x4300 MSPLG1 MSPLG1 MSPLG1 MSPLG1 1 2 1 *
-0x4400 LHMC LHMC LHMC LHMC 1 2 0 *
-0x4410 LHFC LHFC LHFC LHFC 1 2 0 *
-0x4500 LFAM LFAM LFAM LFAM 1 2 0 *
-0x4600 LDMF LDMF LDMF LDMF 1 2 0 *
-0x4700 LEMF LEMF LEMF LEMF 1 2 0 *
-0x4710 LEFF LEFF LEFF LEFF 1 2 0 *
-0x4800 LIMC LIMC LIMC LIMC 1 2 0 *
-0x5000 CHMC1 CHMC2 CHMC3 CHMC4 6 2 0 L
-0x5001 CEMC1 CEMC2 CEMC3 CEMC4 6 2 0 M
-0x5002 CDMC1 CDMC2 CDMC3 CDMC4 6 2 0 S
-0x5003 CIMC1 CIMC2 CIMC3 CIMC4 6 2 0 S
-0x5010 CHFC1 CHFC2 CHFC3 CHFC4 6 2 0 M
-0x5011 CEFC1 CEFC2 CEFC3 CEFC4 6 2 0 M
-0x5012 CDMC1 CDMC2 CDMC3 CDMC4 6 2 0 S
-0x5013 CIFC1 CIFC2 CIFC3 CIFC4 6 2 0 S
-0x5100 CHMF1 CHMF2 CHMF3 CHMF4 6 2 0 L
-0x5101 CEMF1 CEMF2 CEMF3 CHMF4 6 2 0 M
-0x5102 CDMF1 CDMF2 CDMF3 CDMF4 6 2 0 S
-0x5103 CIMF1 CIMF2 CIMF3 CIMF4 6 2 0 S
-0x5110 CHFF1 CHFF2 CHFF3 CHFF4 6 2 0 M
-0x5111 CEFF1 CEFF2 CEFF3 CEFF4 6 2 0 M
-0x5112 CDMF1 CDMF2 CDMF3 CDMF4 6 2 0 S
-0x5113 CIFF1 CIFF2 CIFF3 CIFF4 6 2 0 S
-0x5200 CHMW1 CHMW2 CHMW3 CHMW4 6 2 0 L
-0x5201 CEMW1 CEMW2 CEMW3 CEMW4 6 2 0 M
-0x5202 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
-0x5203 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
-0x5210 CHFW1 CHFW2 CHFW3 CHFW4 6 2 0 M
-0x5211 CEFW1 CEFW2 CEFW3 CEFW4 6 2 0 M
-0x5212 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
-0x5213 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
-0x5300 CHMT1 CHMT2 CHMT2 CHMT2 6 2 0 L
-0x5301 CEMT1 CEMT2 CEMT2 CEMT2 6 2 0 M
-0x5302 CDMT1 CDMT2 CDMT2 CDMT2 6 2 0 S
-0x5303 CIMT1 CIMT2 CIMT2 CIMT2 6 2 0 S
-0x5310 CHFT1 CHFT2 CHFT2 CHFT2 6 2 0 M
-0x5311 CEFT1 CEFT2 CEFT2 CEFT2 6 2 0 M
-0x5312 CDMT1 CDMT2 CDMT2 CDMT2 6 2 0 S
-0x5313 CIFT1 CIFT2 CIFT2 CIFT2 6 2 0 S
-0x6000 CHMC1 CHMC2 CHMC3 CHMC4 6 2 0 L
-0x6001 CEMC1 CEMC2 CEMC3 CEMC4 6 2 0 M
-0x6002 CDMC1 CDMC2 CDMC3 CDMC4 6 2 0 S
-0x6003 CIMC1 CIMC2 CIMC3 CIMC4 6 2 0 S
-0x6010 CHFC1 CHFC2 CHFC3 CHFC4 6 2 0 M
-0x6011 CEFC1 CEFC2 CEFC3 CEFC4 6 2 0 M
-0x6012 CDMC1 CDMC2 CDMC3 CDMC4 6 2 0 S
-0x6013 CIFC1 CIFC2 CIFC3 CIFC4 6 2 0 S
-0x6100 CHMF1 CHMF2 CHMF3 CHMF4 6 2 0 L
-0x6101 CEMF1 CEMF2 CEMF3 CEMF4 6 2 0 M
-0x6102 CDMF1 CDMF2 CDMF3 CDMF4 6 2 0 S
-0x6103 CIMF1 CIMF2 CIMF3 CIMF4 6 2 0 S
-0x6110 CHFF1 CHFF2 CHFF3 CHFF4 6 2 0 M
-0x6111 CEFF1 CEFF2 CEFF3 CEFF4 6 2 0 M
-0x6112 CDMF1 CDMF2 CDMF3 CDMF4 6 2 0 S
-0x6113 CIFF1 CIFF2 CIFF3 CIFF4 6 2 0 S
-0x6200 CHMW1 CHMW2 CHMW3 CHMW4 6 2 0 L
-0x6201 CEMW1 CEMW2 CEMW3 CEMW4 6 2 0 M
-0x6202 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
-0x6203 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
-0x6210 CHFW1 CHFW2 CHFW3 CHFW4 6 2 0 M
-0x6211 CEFW1 CEFW2 CEFW3 CEFW4 6 2 0 M
-0x6212 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
-0x6213 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
-0x6300 CHMT1 CHMT2 CHMT2 CHMT2 6 2 0 L
-0x6301 CEMT1 CEMT2 CEMT2 CEMT2 6 2 0 M
-0x6302 CDMT1 CDMT2 CDMT2 CDMT2 6 2 0 S
-0x6303 CIMT1 CIMT2 CIMT2 CIMT2 6 2 0 S
-0x6310 CHFT1 CHFT2 CHFT2 CHFT2 6 2 0 M
-0x6311 CEFT1 CEFT2 CEFT2 CEFT2 6 2 0 M
-0x6312 CDMT1 CDMT2 CDMT2 CDMT2 6 2 0 S
-0x6313 CIFT1 CIFT2 CIFT2 CIFT2 6 2 0 S
-0x6400 UDRZ1 UDRZ1 UDRZ1 UDRZ1 6 2 0 *
-0x6401 UELM1 UELM1 UELM1 UELM1 6 2 1 *
-0x6402 CMNK1 CMNK1 CMNK1 CMNK1 6 2 0 *
-0x6403 MSKL1 MSKL1 MSKL1 MSKL1 6 2 0 M
-0x6404 USAR1 USAR1 USAR1 USAR1 6 2 1 *
-0x6405 MDGU1 MDGU1 MDGU1 MDGU1 6 2 0 M
-0x6406 MDGU1 MDGU1 MDGU1 MDGU1 6 2 0 L
-0x6500 CHMM1 CHMB2 CHMB3 CHMC4 6 2 0 *
-0x6510 CHFM1 CHFB2 CHFB3 CHFC4 6 2 0 *
-0x7000 MOGH MOGH MOGH MOGH 2 2 0 *
-0x7001 MOGN MOGN MOGN MOGN 2 2 0 *
-0x7100 MBAS MBAS MBAS MBAS 2 2 0 *
-0x7101 MBAS MBAS MBAS MBAS 2 2 GR *
-0x7200 MBER MBER MBER MBER 3 2 BL *
-0x7201 MBER MBER MBER MBER 3 2 1 *
-0x7202 MBER MBER MBER MBER 3 2 CA *
-0x7203 MBER MBER MBER MBER 3 2 PO *
-0x7300 MEAE MEAE MEAE MEAE 4 2 1 *
-0x7301 MEAS MEAS MEAS MEAS 4 2 1 *
-0x7310 MFIE MFIE MFIE MFIE 4 2 1 *
-0x7311 MFIS MFIS MFIS MFIS 4 2 1 *
-0x7320 MAIR MAIR MAIR MAIR 4 2 1 *
-0x7321 MAIS MAIS MAIS MAIS 4 2 1 *
-0x7400 MDOG MDOG MDOG MDOG 2 2 WI *
-0x7401 MDOG MDOG MDOG MDOG 2 2 WA *
-0x7402 MDOG MDOG MDOG MDOG 2 2 MO *
-0x7500 MDOP MDOP MDOP MDOP 3 2 1 *
-0x7501 MDOP MDOP MDOP MDOP 3 2 GR *
-0x7600 METT METT METT METT 2 2 1 *
-0x7701 MGHL MGHL MGHL MGHL 2 2 1 *
-0x7702 MGHL MGHL MGHL MGHL 2 2 RE *
-0x7703 MGHL MGHL MGHL MGHL 2 2 GA *
-0x7704 MSHD MSHD MSHD MSHD 4 2 1 *
-0x7800 MGIB MGIB MGIB MGIB 2 2 1 *
-0x7900 MSLI MSLI MSLI MSLI 3 3 GR *
-0x7901 MSLI MSLI MSLI MSLI 3 3 OL *
-0x7902 MSLI MSLI MSLI MSLI 3 3 MU *
-0x7903 MSLI MSLI MSLI MSLI 3 3 OC *
-0x7904 MSLI MSLI MSLI MSLI 3 3 1 *
-0x7A00 MSPI MSPI MSPI MSPI 3 2 GI *
-0x7A01 MSPI MSPI MSPI MSPI 3 2 HU *
-0x7A02 MSPI MSPI MSPI MSPI 3 2 PH *
-0x7A03 MSPI MSPI MSPI MSPI 3 2 SW *
-0x7A04 MSPI MSPI MSPI MSPI 3 2 WR *
-0x7B00 MWLF MWLF MWLF MWLF 2 2 1 *
-0x7B01 MWLF MWLF MWLF MWLF 2 2 WO *
-0x7B02 MWLF MWLF MWLF MWLF 2 2 DI *
-0x7B03 MWLF MWLF MWLF MWLF 2 2 WI *
-0x7B04 MWLF MWLF MWLF MWLF 2 2 VA *
-0x7B05 MWLF MWLF MWLF MWLF 2 2 DR *
-0x7B06 MWLS MWLS MWLS MWLS 2 2 1 *
-0x7C00 MXVT MXVT MXVT MXVT 2 2 0 *
-0x7C01 MTAS MTAS MTAS MTAS 2 2 0 *
-0x7D00 MZOM MZOM MZOM MZOM 2 2 0 *
-0x7E00 MWER MWER MWER MWER 2 2 1 *
-0x7E01 MGWE MGWE MGWE MGWE 2 2 1 *
-0x7F00 MTRO MTRO MTRO MTRO 4 2 1 *
-0x7F01 MMIN MMIN MMIN MMIN 4 2 1 *
-0x7F02 MBEH MBEH MBEH MBEH 4 3 1 *
-0x7F03 MIMP MIMP MIMP MIMP 4 2 1 *
-0x7F04 MIGO MIGO MIGO MIGO 4 2 1 *
-0x7F05 MDJI MDJI MDJI MDJI 4 2 1 *
-0x7F06 MDJL MDJL MDJL MDJL 4 2 1 *
-0x7F07 MGLC MGLC MGLC MGLC 4 3 1 *
-0x7F08 MOTY MOTY MOTY MOTY 4 4 1 *
-0x7F09 MSAH MSAH MSAH MSAH 4 2 1 *
-0x7F0A MGCP MGCP MGCP MGCP 4 2 1 *
-0x7F0B MGCL MGCL MGCL MGCL 4 2 1 *
-0x7F0C MKUO MKUO MKUO MKUO 4 2 1 *
-0x7F0D MLIC MLIC MLIC MLIC 4 2 1 *
-0x7F0E MDLI MDLI MDLI MDLI 4 2 1 *
-0x7F0F MTRS MTRS MTRS MTRS 4 2 1 *
-0x7F10 MRAK MRAK MRAK MRAK 4 2 1 *
-0x7F11 MUMB MUMB MUMB MUMB 4 2 1 *
-0x7F12 MVAM MVAM MVAM MVAM 4 2 1 *
-0x7F13 MSNK MSNK MSNK MSNK 4 2 1 *
-0x7F14 MGIT MGIT MGIT MGIT 4 2 1 *
-0x7F15 MBES MBES MBES MBES 4 2 1 *
-0x7F16 AMOO AMOO AMOO AMOO 4 3 1 *
-0x7F17 ARAB ARAB ARAB ARAB 4 1 1 *
-0x7F18 ADER ADER ADER ADER 4 2 1 *
-0x7F19 MDSW MDSW MDSW MDSW 4 2 1 *
-0x7F20 AGRO AGRO AGRO AGRO 4 2 1 *
-0x7F21 APHE APHE APHE APHE 4 2 1 *
-0x7F22 MVAF MVAF MVAF MVAF 4 2 1 *
-0x7F23 MSAT MSAT MSAT MSAT 4 3 1 *
-0x7F24 NPIR NPIR NPIR NPIR 4 2 1 *
-0x7F27 MDRO MDRO MDRO MDRO 4 2 1 *
-0x7F28 MKUL MKUL MKUL MKUL 4 3 1 *
-0x7F29 MFDR MFDR MFDR MFDR 4 2 1 *
-0x7F2A NSAI NSAI NSAI NSAI 4 2 1 *
-0x7F2C NSOL NSOL NSOL NSOL 4 2 1 *
-0x7F2D MWFM MWFM MWFM MWFM 4 2 1 *
-0x7F2E MRAV MRAV MRAV MRAV 4 3 1 *
-0x7F2F MSPS MSPS MSPS MSPS 4 2 1 *
-0x7F30 NBOH NBOH NBOH NBOH 4 2 1 *
-0x7F31 NELL NELL NELL NELL 4 2 1 *
-0x7F32 MSLY MSLY MSLY MSLY 4 2 1 *
-0x7F35 MMIS MMIS MMIS MMIS 4 3 1 *
-0x7F36 NSHD NSHD NSHD NSHD 4 2 1 *
-0x7F37 NIRE NIRE NIRE NIRE 4 2 1 *
-0x8000 MGNL MGNL MGNL MGNL 2 2 0 *
-0x8100 MHOB MHOB MHOB MHOB 2 2 0 *
-0x8200 MKOB MKOB MKOB MKOB 2 2 0 *
-0x9000 MOGR MOGR MOGR MOGR 5 2 0 *
-0xA000 MWYV MWYV MWYV MWYV 8 3 1 *
-0xA100 MCAR MCAR MCAR MCAR 8 3 1 *
-0xB000 ACOW ACOW ACOW ACOW 10 3 1 *
-0xB100 AHRS AHRS AHRS AHRS 10 3 1 *
-0xB200 NBEGL NBEGL NBEGL NBEGL 2 2 0 *
-0xB210 NPROL NPROL NPROL NPROL 2 2 0 *
-0xB300 NBOYL NBOYL NBOYL NBOYL 3 2 0 *
-0xB310 NGRLL NGRLL NGRLL NGRLL 3 2 0 *
-0xB400 NFAML NFAML NFAML NFAML 2 2 0 *
-0xB410 NFAWL NFAWL NFAWL NFAWL 2 2 0 *
-0xB500 NSIML NSIML NSIML NSIML 2 2 0 *
-0xB510 NSIWL NSIWL NSIWL NSIWL 2 2 0 *
-0xB600 NNOML NNOML NNOML NNOML 2 2 0 *
-0xB610 NNOWL NNOWL NNOWL NNOWL 2 2 0 *
-0xB700 NSVLL NSVLL NSIWL NSIWL 2 2 0 *
-0xC000 ABAT ABAT ABAT ABAT 2 1 1 *
-0xC100 ACAT ACAT ACAT ACAT 2 1 1 *
-0xC200 ACHK ACHK ACHK ACHK 2 1 1 *
-0xC300 ARAT ARAT ARAT ARAT 2 1 1 *
-0xC400 ASQU ASQU ASQU ASQU 2 1 1 *
-0xC500 ABAT ABAT ABAT ABAT 2 1 1 *
-0xC600 NBEGH NBEGH NBEGH NBEGH 2 2 0 *
-0xC610 NPROH NPROH NPROH NPROH 2 2 0 *
-0xC700 NBOYH NBOYH NBOYH NBOYH 3 2 0 *
-0xC710 NGRLH NGRLH NGRLH NGRLH 3 2 0 *
-0xC800 NFAMH NFAMH NFAMH NFAMH 2 2 0 *
-0xC810 NFAWH NFAWH NFAWH NFAWH 2 2 0 *
-0xC900 NSIMH NSIMH NSIMH NSIMH 2 2 0 *
-0xC910 NSIWH NSIWH NSIWH NSIWH 2 2 0 *
-0xCA00 NNOMH NNOMH NNOMH NNOMH 2 2 0 *
-0xCA10 NNOWH NNOWH NNOWH NNOWH 2 2 0 *
-0xCB00 NSLVH NSLVH NSLVH NSLVH 2 2 0 *
-0xD000 AEAGG1 AEAGG1 AEAGG1 AEAGG1 7 0 1 *
-0xD100 AGULG1 AGULG1 AGULG1 AGULG1 7 0 1 *
-0xD200 AVULG1 AVULG1 AVULG1 AVULG1 7 0 1 *
-0xD300 ABIRG1 ABIRG1 ABIRG1 ABIRG1 7 0 1 *
-0xD400 ABIRG1 ABIRG1 ABIRG1 ABIRG1 7 0 1 *
-0xE000 MBET MBET MBET MBET 9 2 1 *
-0xE012 MBBM MBBM MBBM MBBM 16 2 1 *
-0xE020 MTAN MTAN MTAN MTAN 9 4 1 *
-0xE022 MBBR MBBR MBBR MBBR 9 2 1 *
-0xE038 MBFI MBFI MBFI MBFI 9 2 1 *
-0xE048 MBRH MBRH MBRH MBRH 9 5 1 *
-0xE050 MREM MREM MREM MREM 9 4 1 *
-0xE060 MLIC MLIC MLIC MLIC 9 2 1 *
-0xE068 MHOH MHOH MHOH MHOH 9 2 1 *
-0xE070 MMIN MMIN MMIN MMIN 9 2 1 *
-0xE090 MMER MMER MMER MMER 9 2 1 *
-0xE0A0 MTIC MTIC MTIC MTIC 9 2 1 *
-0xE0B0 MTRO MTRO MTRO MTRO 9 2 1 *
-0xE0C0 MTSN MTSN MTSN MTSN 9 2 1 *
-0xE0D0 MUMB MUMB MUMB MUMB 9 2 1 *
-0xE0E0 MCOR MCOR MCOR MCOR 9 3 1 *
-0xE0F0 MGIC MGIC MGIC MGIC 9 2 1 *
-0xE0F1 MGLA MGLA MGLA MGLA 9 2 1 *
-0xE108 MCYC MCYC MCYC MCYC 9 4 1 *
-0xE118 METN METN METN METN 9 4 1 *
-0xE138 MGFR MGFR MGFR MGFR 9 4 1 *
-0xE148 MGVE MGVE MGVE MGVE 9 4 1 *
-0xE15A MGFO MGFO MGFO MGFO 9 4 1 *
-0xE218 MELE MELE MELE MELE 9 4 1 *
-0xE228 MELF MELF MELF MELF 9 4 1 *
-0xE238 MELW MELW MELW MELW 9 4 1 *
-0xE249 MHAR MHAR MHAR MHAR 9 2 1 *
-0xE252 MWWE MWWE MWWE MWWE 9 2 1 *
-0xE269 MFEY MFEY MFEY MFEY 9 2 1 *
-0xE278 MDTR MDTR MDTR MDTR 9 3 1 *
-0xE289 MFE2 MFE2 MFE2 MFE2 9 3 1 *
-0xE298 MEW2 MEW2 MEW2 MEW2 9 2 1 *
-0xE300 MGHO MGHO MGHO MGHO 9 2 1 *
-0xE308 MGH2 MGH2 MGH2 MGH2 9 2 1 *
-0xE318 MGH3 MGH3 MGH3 MGH3 9 2 1 *
-0xE329 MWIG MWIG MWIG MWIG 9 2 1 *
-0xE338 MZO2 MZO2 MZO2 MZO2 9 2 1 *
-0xE348 MZO3 MZO3 MZO3 MZO3 16 2 1 *
-0xE359 MWI2 MWI2 MWI2 MWI2 9 2 1 *
-0xE369 MWI3 MWI3 MWI3 MWI3 9 2 1 *
-0xE388 MMUM MMUM MMUM MMUM 9 2 1 *
-0xE389 MMUM MMUM MMUM MMUM 9 2 1 *
-0xE39C MHIS MHIS MHIS MHIS 9 2 1 *
-0xE3A8 MDRD MDRD MDRD MDRD 9 2 1 *
-0xE3BB MWAV MWAV MWAV MWAV 9 2 1 *
-0xE408 MGO1 MGO1 MGO1 MGO1 9 2 1 *
-0xE412 MGO2 MGO2 MGO2 MGO2 16 2 1 *
-0xE428 MGO3 MGO3 MGO3 MGO3 9 2 1 *
-0xE432 MGO4 MGO4 MGO4 MGO4 16 2 1 *
-0xE449 MSVI MSVI MSVI MSVI 9 2 1 *
-0xE459 MSV2 MSV2 MSV2 MSV2 9 2 1 *
-0xE468 MGWO MGWO MGWO MGWO 9 2 1 *
-0xE479 MGOC MGOC MGOC MGOC 9 2 1 *
-0xE488 MGW2 MGW2 MGW2 MGW2 9 2 1 *
-0xE498 MGO5 MGO5 MGO5 MGO5 9 2 1 *
-0xE500 MLIZ MLIZ MLIZ MLIZ 9 2 1 *
-0xE510 MLI2 MLI2 MLI2 MLI2 9 2 1 *
-0xE51D MGIR MGIR MGIR MGIR 9 3 1 *
-0xE520 MLI3 MLI3 MLI3 MLI3 9 2 1 *
-0xE528 MGIC MGIC MGIC MGIC 9 2 1 *
-0xE600 MMYC MMYC MMYC MMYC 9 2 1 *
-0xE610 MMY2 MMY2 MMY2 MMY2 9 2 1 *
-0xE62C MSKB MSKB MSKB MSKB 9 2 1 *
-0xE700 MNO1 MNO1 MNO1 MNO1 9 2 1 *
-0xE708 MMIN MMIN MMIN MMIN 9 2 1 *
-0xE710 MNO2 MNO2 MNO2 MNO2 9 2 1 *
-0xE718 MTRO MTRO MTRO MTRO 9 2 1 *
-0xE720 MNO3 MNO3 MNO3 MNO3 9 2 1 *
-0xE728 MTIC MTIC MTIC MTIC 9 2 1 *
-0xE738 MTSN MTSN MTSN MTSN 9 2 1 *
-0xE759 MUMB MUMB MUMB MUMB 9 2 1 *
-0xE76C MYET MYET MYET MYET 9 2 1 *
-0xE771 MBA4 MBA4 MBA4 MBA4 9 2 1 *
-0xE781 MBA5 MBA5 MBA5 MBA5 9 2 1 *
-0xE791 MBA6 MBA6 MBA6 MBA6 9 2 1 *
-0xE7AC MBAI MBAI MBAI MBAI 9 2 1 *
-0xE7B8 MBOA MBOA MBOA MBOA 9 2 1 *
-0xE7C9 MABW MABW MABW MABW 9 2 1 *
-0xE7D9 MMAL MMAL MMAL MMAL 9 2 1 *
-0xE7E8 MSCR MSCR MSCR MSCR 9 2 1 *
-0xE7F9 MUM2 MUM2 MUM2 MUM2 9 2 1 *
-0xE800 MOR6 MOR6 MOR6 MOR6 9 2 1 *
-0xE810 MOR1 MOR1 MOR1 MOR1 9 2 1 *
-0xE820 MOR2 MOR2 MOR2 MOR2 16 2 1 *
-0xE830 MOR3 MOR3 MOR3 MOR3 9 2 1 *
-0xE840 MOR4 MOR4 MOR4 MOR4 16 2 1 *
-0xE850 MOR5 MOR5 MOR5 MOR5 9 2 1 *
-0xE860 MNO1 MNO1 MNO1 MNO1 9 2 1 *
-0xE870 MNO2 MNO2 MNO2 MNO2 9 2 1 *
-0xE880 MNO3 MNO3 MNO3 MNO3 9 2 1 *
-0xE890 MLI3 MLI3 MLI3 MLI3 9 2 1 *
-0xE8A0 MYU3 MYU3 MYU3 MYU3 9 2 1 *
-0xE8B0 MYUH MYUH MYUH MYUH 9 2 1 *
-0xE8C0 MBUG MBUG MBUG MBUG 9 2 1 *
-0xE8D0 MNOS MNOS MNOS MNOS 9 2 1 *
-0xE8E0 MBU2 MBU2 MBU2 MBU2 9 2 1 *
-0xE8F0 MOR7 MOR7 MOR7 MOR7 9 2 1 *
-0xE900 MSAL MSAL MSAL MSAL 16 2 1 *
-0xE908 MSH1 MSH1 MSH1 MSH1 16 2 1 *
-0xE910 MSA2 MSA2 MSA2 MSA2 16 2 1 *
-0xE918 MSH2 MSH2 MSH2 MSH2 16 2 1 *
-0xE928 MGHO MGHO MGHO MGHO 9 2 1 *
-0xEA00 MSHR MSHR MSHR MSHR 9 2 1 *
-0xEA10 MSH1 MSH1 MSH1 MSH1 16 2 1 *
-0xEA20 MCRD MCRD MCRD MCRD 9 2 1 *
-0xEB00 MSKT MSKT MSKT MSKT 9 2 1 *
-0xEB08 MANI MANI MANI MANI 9 3 1 *
-0xEB10 MSKA MSKA MSKA MSKA 9 2 1 *
-0xEB18 MANI MANI MANI MANI 9 2 1 *
-0xEB28 MAN2 MAN2 MAN2 MAN2 9 2 1 *
-0xEB39 MBE1 MBE1 MBE1 MBE1 9 2 1 *
-0xEB49 MBE2 MBE2 MBE2 MBE2 9 2 1 *
-0xEB51 MSEE MSEE MSEE MSEE 9 2 1 *
-0xEB52 MFIR MFIR MFIR MFIR 9 2 1 *
-0xEB69 MLIC MLIC MLIC MLIC 9 2 1 *
-0xEB79 MLER MLER MLER MLER 9 2 1 *
-0xEB89 MMAN MMAN MMAN MMAN 9 2 1 *
-0xEB99 MMYC MMYC MMYC MMYC 9 2 1 *
-0xEBA9 MMY2 MMY2 MMY2 MMY2 9 2 1 *
-0xEBB1 MSHR MSHR MSHR MSHR 9 2 1 *
-0xEBCD MTAN MTAN MTAN MTAN 9 4 1 *
-0xEBD8 MSAL MSAL MSAL MSAL 16 2 1 *
-0xEBE8 MSA2 MSA2 MSA2 MSA2 16 2 1 *
-0xEBF1 MARU MARU MARU MARU 9 2 1 *
-0xEC0B MWDR MWDR MWDR MWDR 9 2 1 *
-0xEC1D MCHY MCHY MCHY MCHY 9 2 1 *
-0xEC2B MSHE MSHE MSHE MSHE 9 2 1 *
-0xEC33 MCHI MCHI MCHI MCHI 9 2 1 *
-0xEC4B MDH1 MDH1 MDH1 MDH1 9 2 1 *
-0xEC5B MDH2 MDH2 MDH2 MDH2 9 2 1 *
-0xED00 MYU1 MYU1 MYU1 MYU1 9 2 1 *
-0xED09 MCOR MCOR MCOR MCOR 9 3 1 *
-0xED10 MYU2 MYU2 MYU2 MYU2 9 2 1 *
-0xED19 MGLA MGLA MGLA MGLA 9 2 1 *
-0xED20 MYU3 MYU3 MYU3 MYU3 9 2 1 *
-0xED28 MLEM MLEM MLEM MLEM 9 2 1 *
-0xEE08 MWEB MWEB MWEB MWEB 9 2 1 *
-0xEE18 MWRA MWRA MWRA MWRA 9 2 1 *
-0xEF0D MISA MISA MISA MISA 9 2 1 *
-0xEF1D MMAD MMAD MMAD MMAD 9 2 1 *
-0xEF28 MWOR MWOR MWOR MWOR 9 2 1 *
-0xEF50 MKG1 MKG1 MKG1 MKG1 9 2 1 *
-0xEF60 MKG2 MKG2 MKG2 MKG2 9 2 1 *
-0xEF70 MKG3 MKG3 MKG3 MKG3 9 2 1 *
-0xEF92 MWIL MWIL MWIL MWIL 9 2 1 *
-0xEFA3 MGEN MGEN MGEN MGEN 9 2 1 *
-0xEFB3 MGEN MGEN MGEN MGEN 9 3 1 *
-0xEFC3 MGEN MGEN MGEN MGEN 9 4 1 *
-0xEFD3 MGEN MGEN MGEN MGEN 9 5 1 *
-0xEFE3 MGEN MGEN MGEN MGEN 9 1 1 *
-0xEFF3 MGEN MGEN MGEN MGEN 9 6 1 *
-0xF008 MSKA MSKA MSKA MSKA 9 2 1 *
-0xF019 MSKT MSKT MSKT MSKT 9 2 1 *
-0xF029 MWI4 MWI4 MWI4 MWI4 9 2 1 *
-0xF10E MYU1 MYU1 MYU1 MYU1 9 2 1 *
-0xF11E MYU2 MYU2 MYU2 MYU2 9 2 1 *
-0xF209 MLIZ MLIZ MLIZ MLIZ 9 2 1 *
-0xF218 MLI2 MLI2 MLI2 MLI2 9 2 1 *
-0xF308 MGFI MGFI MGFI MGFI 9 4 1 *
-0xF40B MSAH MSAH MSAH MSAH 9 2 1 *
-0xF41B MSAT MSAT MSAT MSAT 9 2 1 *
-0xF50B MDRM MDRM MDRM MDRM 9 4 1 *
-0xF51B MDRF MDRF MDRF MDRF 9 4 1 *
-0xF77A MBA1 MBA1 MBA1 MBA1 9 2 1 *
-0xF78A MBA2 MBA2 MBA2 MBA2 9 2 1 *
-0xF798 MBA3 MBA3 MBA3 MBA3 9 2 1 *
diff --git a/gemrb/override/iwd/bloodclr.2da b/gemrb/override/iwd/bloodclr.2da
deleted file mode 100644
index 1b33a30..0000000
--- a/gemrb/override/iwd/bloodclr.2da
+++ /dev/null
@@ -1,29 +0,0 @@
-2DA V1.0
-0
- VALUE MIN MAX
-NORMAL 0x2f 0x1000 0xffff
-PURPLE 0x2d 0x4300 0x43ff
-MSKEL 0x25 0x5403 0x5403
-DOOMG 0x22 0x5405 0x5406
-MSKEL 0x25 0x6403 0x6403
-DOOMG 0x22 0x6405 0x6406
-YELLOW 0x32 0x7300 0x73ff
-PURPLE 0x3c 0x7500 0x75ff
-YELLOW 0x32 0x7600 0x76ff
-BLACK 0x66 0x7700 0x77ff
-SLI_GR 7 0x7900 0x7900
-SLI_OL 0x24 0x7901 0x7901
-SLI_MU 0x33 0x7902 0x7902
-SLI_OC 0x25 0x7903 0x7903
-SLIME 0x1b 0x7904 0x7904
-SPIDER 0x33 0x7a00 0x7aff
-ZOMBIE 0x25 0x7c00 0x7cff
-MTRO 0x33 0x7f00 0x7f00
-MMIN 0x3d 0x7f01 0x7f03
-MIGO 0x1a 0x7f04 0x7f04
-MGLC 0x5d 0x7f07 0x7f07
-MTRS 0x32 0x7f0f 0x7f0f
-MBES 0x3d 0x7f15 0x7f15
-MCAR 0x38 0xa100 0xa1ff
-UNDEAD 0x66 0xe300 0xe3ff
-MWWE 0x38 0xef00 0xefff
diff --git a/gemrb/override/iwd/clskills.2da b/gemrb/override/iwd/clskills.2da
deleted file mode 100644
index 0bd6f93..0000000
--- a/gemrb/override/iwd/clskills.2da
+++ /dev/null
@@ -1,22 +0,0 @@
-2DA V1.0
-*
- HATERACE CLERICSPELL MAGESPELL STARTXP BARDSKILL THIEFSKILL LAYHANDS TURNLEVEL BOOKTYPE
-UNUSED * * * * * * * * * 0
-MAGE * * MXSPLWIZ 0 * * * * * 1
-FIGHTER * * * 0 * * * * * 0
-CLERIC * MXSPLPRS * 0 * * * 1
-THIEF * * * 0 * SKILLS * *
-BARD * * MXSPLBRD 0 SKILLBRD * * *
-PALADIN * MXSPLPAL * 0 * * PALADIN 5
-FIGHTER_MAGE * * MXSPLWIZ 0 * * * *
-FIGHTER_CLERIC * MXSPLPRS * 0 * * * *
-FIGHTER_THIEF * * * 0 * SKILLS * *
-FIGHTER_MAGE_THIEF * * MXSPLWIZ 0 * SKILLS * *
-DRUID * MXSPLDRU * 0 * * * *
-RANGER HATERACE MXSPLRAN * 0 * * * *
-MAGE_THIEF * * MXSPLWIZ 0 * SKILLS * *
-CLERIC_MAGE * MXSPLPRS MXSPLWIZ 0 * * * *
-CLERIC_THIEF * MXSPLPRS * 0 * SKILLS * *
-FIGHTER_DRUID * MXSPLDRU * 0 * * * *
-FIGHTER_MAGE_CLERIC * MXSPLPRS MXSPLWIZ 0 * * * *
-CLERIC_RANGER HATERACE MXSPLPRS * 0 * * * *
diff --git a/gemrb/override/iwd/defsound.2da b/gemrb/override/iwd/defsound.2da
deleted file mode 100644
index 22cfee3..0000000
--- a/gemrb/override/iwd/defsound.2da
+++ /dev/null
@@ -1,29 +0,0 @@
-2DA V1.0
-*
- RESREF
-OPEN AMB_D03A
-CLOSE AMB_D03B
-HOPEN AMB_D04A
-HCLOSE AMB_D04B
-BUTTON1 GAM_09
-BUTTON2 GAM_03
-BUTTON3 GAM_04
-OPENFAIL *
-CLOSEFAIL *
-ITEM_GONE EFF_M02
-SECRET ACT_09
-11 *
-12 *
-13 *
-14 *
-15 *
-16 *
-17 *
-18 *
-19 *
-LIGHTNING1 AMB_E13A
-LIGHTNING2 AMB_E13B
-LIGHTNING3 AMB_E13F
-RAIN AMB_E11
-SNOW AMB_E02B
-
diff --git a/gemrb/override/iwd/effects.ids b/gemrb/override/iwd/effects.ids
deleted file mode 100644
index 8407a93..0000000
--- a/gemrb/override/iwd/effects.ids
+++ /dev/null
@@ -1,300 +0,0 @@
-IDS
-0x0 ACVsDamageTypeModifier
-0x1 AttacksPerRoundModifier
-0x2 Cure:Sleep
-0x3 State:Berserk
-0x4 Cure:Berserk
-0x5 State:Charmed
-0x6 CharismaModifier
-0x7 Color:SetPalette
-0x8 Color:SetRGB
-0x9 Color:PulseRGB
-0xa ConstitutionModifier
-0xb Cure:Poison
-0xc Damage
-0xd Death
-0xe Cure:Defrost
-0xf DexterityModifier
-0x10 State:Hasted
-0x11 CurrentHPModifier
-0x12 MaximumHPModifier
-0x13 IntelligenceModifier
-0x14 State:Invisible
-0x15 LoreModifier
-0x16 LuckModifier
-0x17 MoraleModifier
-0x18 State:Panic
-0x19 State:Poisoned
-0x1a RemoveCurse
-0x1b AcidResistanceModifier
-0x1c ColdResistanceModifier
-0x1d ElectricityResistanceModifier
-0x1e FireResistanceModifier
-0x1f MagicDamageResistanceModifier
-0x20 Cure:Death
-0x21 SaveVsDeathModifier
-0x22 SaveVsWandsModifier
-0x23 SaveVsPolyModifier
-0x24 SaveVsBreathModifier
-0x25 SaveVsSpellsModifier
-0x26 State:Silenced
-0x27 State:Helpless
-0x28 State:Slowed
-0x29 Sparkle
-0x2a WizardSpellSlotsModifier
-0x2b Cure:Petrification
-0x2c StrengthModifier
-0x2d State:Stun
-0x2e Cure:Stun
-0x2f Cure:Invisible
-0x30 Cure:Silence
-0x31 WisdomModifier
-0x32 Color:BriefRGB
-0x33 Color:DarkenRGB
-0x34 Color:GlowRGB
-0x35 AnimationIDModifier
-0x36 ToHitModifier
-0x37 KillCreatureType
-0x38 Alignment:Invert
-0x39 Alignment:Change
-0x3a DispelEffects
-0x3b StealthModifier
-0x3c MiscastMagicModifier
-0x3d AlchemyModifier
-0x3e PriestSpellSlotsModifier
-0x3f State:Infravision
-0x40 Cure:Infravision
-0x41 State:Blur
-0x42 TransparencyModifier
-0x43 SummonCreature
-0x44 UnsummonCreature
-0x45 State:NonDetection
-0x46 Cure:NonDetection
-0x47 SexModifier
-0x48 AIIdentifierModifier
-0x49 DamageBonusModifier
-0x4a State:Blind
-0x4b Cure:Blind
-0x4c State:Feeblemind
-0x4d Cure:Feeblemind
-0x4e State:Diseased
-0x4f Cure:Disease
-0x50 State:Deafness
-0x51 Cure:Deafness
-0x52 SetAIScript
-0x53 Protection:Projectile
-0x54 MagicalFireResistanceModifier
-0x55 MagicalColdResistanceModifier
-0x56 SlashingResistanceModifier
-0x57 CrushingResistanceModifier
-0x58 PiercingResistanceModifier
-0x59 MissilesResistanceModifier
-0x5a OpenLocksModifier
-0x5b FindTrapsModifier
-0x5c PickPocketsModifier
-0x5d FatigueModifier
-0x5e IntoxicationModifier
-0x5f TrackingModifier
-0x60 LevelModifier
-0x61 StrengthBonusModifier
-0x62 State:Regenerating
-0x63 SpellDurationModifier
-0x64 Protection:Creature
-0x65 Protection:Opcode
-0x66 Protection:SpellLevel
-0x67 ChangeName
-0x68 ExperienceModifier
-0x69 GoldModifier
-0x6a MoraleBreakModifier
-0x6b PortraitChange
-0x6c ReputationModifier
-0x6d State:HoldNoIcon
-0x6e RetreatFrom
-0x6f Item:CreateMagic
-0x70 Item:Remove
-0x71 Item:Equip
-0x72 Dither
-0x73 DetectAlignment
-0x74 Cure:Invisible2
-0x75 Reveal:Area
-0x76 Reveal:Creatures
-0x77 MirrorImage
-0x78 Protection:Weapons
-0x79 VisualAnimationEffect
-0x7a Item:CreateInventory
-0x7b Item:RemoveInventory
-0x7c DimensionDoor
-0x7d Unlock
-0x7e MovementRateModifier
-0x7f MonsterSummoning
-0x80 State:Confused
-0x81 AidNonCumulative
-0x82 BlessNonCumulative
-0x83 ChantNonCumulative
-0x84 HolyNonCumulative
-0x85 LuckNonCumulative
-0x86 State:Petrification
-0x87 Polymorph
-0x88 ForceVisible
-0x89 ChantBadNonCumulative
-0x8a AnimationStateChange
-0x8b DisplayString
-0x8c CastingGlow
-0x8d VisualSpellHit
-0x8e Icon:Display
-0x8f Item:CreateInSlot
-0x90 DisableButton
-0x91 DisableCasting
-0x92 Spell:Cast
-0x93 Spell:Learn
-0x94 Spell:CastPoint
-0x95 Identify
-0x96 FindTraps
-0x97 ReplaceCreature
-0x98 PlayMovie
-0x99 Overlay:Sanctuary
-0x9a Overlay:Entangle
-0x9b Overlay:MinorGlobe
-0x9c Overlay:ShieldGlobe
-0x9d Overlay:Web
-0x9e Overlay:Grease
-0x9f MirrorImageModifier
-0xa0 Cure:Sanctuary
-0xa1 Cure:Panic
-0xa2 Cure:Hold
-0xa3 FreeAction
-0xa4 Cure:Intoxication
-0xa5 PauseTarget
-0xa6 MagicResistanceModifier
-0xa7 MissileHitModifier
-0xa8 RemoveCreature
-0xa9 Icon:Disable
-0xaa DamageAnimation
-0xab Spell:Add
-0xac Spell:Remove
-0xad PoisonResistanceModifier
-0xae PlaySound
-0xaf State:Hold
-0xb0 MovementRateModifier2
-0xb1 ApplyEffect
-0xb2 ToHitVsCreature
-0xb3 DamageVsCreature
-0xb4 CantUseItem
-0xb5 CantUseItemType
-0xb6 ApplyEffectItem
-0xb7 ApplyEffectItemType
-0xb8 DontJumpModifier
-0xb9 State:Hold2
-0xba MoveToArea
-0xbb Variable:StoreLocalVariable
-0xbc AuraCleansingModifier
-0xbd CastingSpeedModifier
-0xbe AttackSpeedModifier
-0xbf CastingLevelModifier
-0xc0 FindFamiliar
-0xc1 InvisibleDetection
-0xc2 IgnoreDialogPause
-0xc3 FamiliarBond
-0xc4 FamiliarMarker
-0xc5 Bounce:Projectile
-0xc6 Bounce:Opcode
-0xc7 Bounce:SpellLevel
-0xc8 Bounce:SpellLevelDec
-0xc9 Protection:SpellLevelDec
-0xca Bounce:School
-0xcb Bounce:SecondaryType
-0xcc Protection:School
-0xcd Protection:SecondaryType
-0xce Protection:Spell2
-0xcf Bounce:Spell
-0xd0 MinimumHPModifier
-0xd1 PowerWordKill
-0xd2 PowerWordStun
-0xd3 State:Imprisonment
-0xd4 Cure:Imprisonment
-0xd5 Maze
-0xd6 CastFromList
-0xd7 PlayVisualEffect
-0xd8 LevelDrainModifier
-0xd9 PowerWordSleep
-0xda StoneskinModifier
-0xdb ACVsCreatureType
-0xdc DispelSchool
-0xdd DispelSecondaryType
-0xde RandomTeleport
-0xdf Protection:SchoolDec
-0xe0 Cure:LevelDrain
-0xe1 Reveal:Magic
-0xe2 Protection:SecondaryTypeDec
-0xe3 Bounce:SchoolDec
-0xe4 Bounce:SecondaryTypeDec
-0xe5 DispelSchoolOne
-0xe6 DispelSecondaryTypeOne
-0xe7 TimeStop
-0xe8 Color:FadeRGB
-0xe9 IWDVisualSpellHit
-0xea ColdDamage
-0xeb CastingGlow2
-0xec ChillTouch
-0xed CrushingDamage
-0xee SaveBonus
-0xef SlowPoison
-0xf0 IWDMonsterSummoning
-0xf1 VampiricTouch
-0xf2 Overlay
-0xf3 AnimateDead
-0xf4 Prayer2
-0xf5 Curse2
-0xf6 SummonMonster2
-0xf7 BurningBlood
-0xf8 SummonShadowMonster
-0xf9 Recitation
-0xfa RecitationBad
-0xfb Hold2
-0xfc BlindingOrb
-0xfd ACVsDamageTypeModifier2
-0xfe RemoveEffects
-0xff SalamanderAura
-0x100 UmberHulkGaze
-0x101 ZombieLordAura
-0x102 Protection:Spell
-0x103 SummonCreature2
-0x104 AvatarRemoval
-0x105 Protection:Opcode2
-0x106 SummonPomab
-0x107 ControlCreature
-0x108 StaticCharge
-0x109 CloakOfFear
-0x10a MovementRateModifier3
-0x10b Cure:Confusion
-0x10c EyeOfTheMind
-0x10d EyeOfTheSword
-0x10e EyeOfTheMage
-0x10f EyeOfVenom
-0x110 EyeOfTheSpirit
-0x111 EyeOfFortitude
-0x112 EyeOfStone
-0x113 RemoveSevenEyes
-0x114 RemoveEffect
-0x115 SoulEater
-0x116 ShroudOfFlame
-0x117 AnimalRage
-0x118 TurnUndead
-0x119 VitriolicSphere
-0x11a SuppressHP
-0x11b FloatText
-0x11c MaceOfDisruption
-0x11d State:Sleep
-0x11e Reveal:Tracks
-0x11f Protection:Backstab
-0x120 State:Set
-0x121 Cutscene
-0x122 Protection:Spell3
-0x123 RodOfSmithing
-0x124 MagicalRest
-0x125 BeholderDispelMagic
-0x126 HarpyWail
-0x127 JackalWereGaze
-0x128 ModifyGlobalVariable
-0x129 HideInShadowsModifier
-0x12a UseMagicDeviceModifier
diff --git a/gemrb/override/iwd/fonts.2da b/gemrb/override/iwd/fonts.2da
deleted file mode 100644
index fe1ed92..0000000
--- a/gemrb/override/iwd/fonts.2da
+++ /dev/null
@@ -1,19 +0,0 @@
-2DA V1.0
-NORMAL
- RESREF NEED_PALETTE FIRST_CHAR
-0 NORMAL 1 0
-1 INFOFONT 1 0
-2 NUMBER 0 47
-3 INITIALS 0 0
-4 NUMBER2 0 47
-5 NUMBER3 0 47
-6 NUMFONT 1 0
-7 REALMS 0 0
-8 REALMS2 1 0
-9 STONEBIG 0 0
-10 STONESM2 0 0
-11 STONESM3 0 0
-12 STONESML 0 0
-13 TOOLFONT 1 0
-14 STATES 0 0
-15 STATES2 0 0
diff --git a/gemrb/override/iwd/gametime.2da b/gemrb/override/iwd/gametime.2da
deleted file mode 100644
index 2d29d2c..0000000
--- a/gemrb/override/iwd/gametime.2da
+++ /dev/null
@@ -1,5 +0,0 @@
-2DA V1.0
-0
- DURATION
-ROUND_SECONDS 7
-TURN_SECONDS 70
diff --git a/gemrb/override/iwd/gemrb.ini b/gemrb/override/iwd/gemrb.ini
deleted file mode 100644
index 40f4286..0000000
--- a/gemrb/override/iwd/gemrb.ini
+++ /dev/null
@@ -1,121 +0,0 @@
-; GemRB - Infinity Engine Emulator
-; Copyright (C) 2003 The GemRB Project
-;
-; This program is free software; you can redistribute it and/or
-; modify it under the terms of the GNU General Public License
-; as published by the Free Software Foundation; either version 2
-; of the License, or (at your option) any later version.
-;
-; This program is distributed in the hope that it will be useful,
-; but WITHOUT ANY WARRANTY; without even the implied warranty of
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-; GNU General Public License for more details.
-;
-; You should have received a copy of the GNU General Public License
-; along with this program; if not, write to the Free Software
-; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-;
-
-
-; gemrb.ini - game type-specific settings for GemRB engine
-
-[resources]
-
-; Bitmap resource for cursors
-CursorBAM = CAROT
-
-; Bitmap resource for scroll cursor arrow
-ScrollCursorBAM = CURSARW
-
-; Bitmap resource for dialog buttons font
-ButtonFont = STONESML
-
-; Font used to display tooltips
-TooltipFont = TOOLFONT
-
-; Font used to display subtitles
-MovieFont = REALMS2
-
-; Sprite displayed behind the tooltip text, if any
-TooltipBack = TOOLTIP
-
-; Tooltip text color (RGBA)
-TooltipColor = #ffffffff
-
-; Space between tooltip text and sides of TooltipBack (x2)
-TooltipMargin = 2
-
-; INI file from the original games
-INIConfig = icewind.ini
-
-; Palette bitmaps in various widths
-Palette16 = MPALETTE
-Palette32 = MPALETTE
-Palette256 = MPAL256
-
-MaximumAbility = 25
-IgnoreButtonFrames = 0
-AllStringsTagged = 1
-HasDPLAYER = 1
-HasPickSound = 0
-HasDescIcon = 0
-HasEXPTABLE = 1
-SoundFolders = 1
-HasSongList = 0
-UpperButtonText = 0
-LowerLabelText = 0
-HasPartyINI = 0
-HasBeastsINI = 0
-ForceStereo = 0
-ReverseToHit = 1
-IWDMapDimensions = 1
-SmallFog = 0
-ReverseDoor = 0
-IWD2ScriptName = 1
-DialogueScrolls = 0
-CharNameIsGabber = 1
-SpawnIni = 1
-HasHideInShadows = 1
-AreaVisitedVar = 1
-HasSpecificDamageBonus = 0
-BiographyIsRes = 1
-FlexibleWorldmap = 1
-AutoSearchHidden = 1
-CutsceneAreascripts = 0
-PSTStateFlags = 0
-CastingSounds = 1
-ForceAreaScript = 1
-
-[charset]
-CharCount = 31
-Letter1 = 192,224
-Letter2 = 193,225
-Letter3 = 194,226
-Letter4 = 195,227
-Letter5 = 196,228
-Letter6 = 197,229
-Letter7 = 198,230
-Letter8 = 199,231
-Letter9 = 200,232
-Letter10 = 201,233
-Letter11 = 202,234
-Letter12 = 203,235
-Letter13 = 204,236
-Letter14 = 205,237
-Letter15 = 206,238
-Letter16 = 207,239
-Letter17 = 208,240
-Letter18 = 209,241
-Letter19 = 210,242
-Letter20 = 211,243
-Letter21 = 212,244
-Letter22 = 213,245
-Letter23 = 214,246
-Letter24 = 140,156
-Letter25 = 216,248
-Letter26 = 217,249
-Letter27 = 218,250
-Letter28 = 219,251
-Letter29 = 220,252
-Letter30 = 221,253
-Letter31 = 222,254
diff --git a/gemrb/override/iwd/itemsnd.2da b/gemrb/override/iwd/itemsnd.2da
deleted file mode 100644
index 9678ee9..0000000
--- a/gemrb/override/iwd/itemsnd.2da
+++ /dev/null
@@ -1,80 +0,0 @@
-2DA V1.0
-*
- TAKE DROP
-AMULET G_NECK1 G_NECK2
-ARMOR G_CLOAK1 G_CLOAK2
-BELT G_BELT1 G_BELT2
-BOOT G_BOOT1 G_BOOT2
-ARROW G_ARRW1 G_ARRW2
-BRACER G_GLOVE1 G_GLOVE2
-HELMET G_HELM1 G_HELM2
-KEY G_KEY1 G_KEY2
-POTION G_POTN1 G_POTN2
-RING G_RING1 G_RING2
-SCROLL G_SCROL1 G_SCROL2
-SHIELD GAM_21A GAM_21B
-FOOD GAM_21A GAM_21B
-BULLET G_BULLT1 G_BULLT2
-BOW G_BOW1 G_BOW2
-DAGGER G_DAGGR1 G_DAGGR2
-MACE G_MACE1 G_MACE2
-SLING G_SLING1 G_SLING2
-SMSWORD G_SMSWD1 G_SMSWD2
-BGSWORD G_LGSWD1 G_LGSWD2
-HAMMER G_HAMMR1 G_HAMMR2
-MSTAR G_MSTAR1 G_MSTAR2
-FLAIL G_FLAIL1 G_FLAIL2
-DART G_DART1 G_DART2
-AXE G_AXE1 G_AXE2
-STAFF G_STAFF1 G_STAFF2
-XBOW G_CROSB1 G_CROSB2
-FIST GAM_21A GAM_21B
-SPEAR G_SPEAR1 G_SPEAR2
-POLEARM G_HALB1 G_HALB2
-BOLT G_BOLT1 G_BOLT2
-CLOAK G_CLOAK1 G_CLOAK2
-COIN G_GOLD1 G_GOLD2
-GEM G_GEM1 G_GEM2
-WAND G_WAND1 G_WAND2
-BROKEN1 G_B_ARM1 G_B_ARM2
-BROKEN2 G_B_SHD1 G_B_SHD2
-BROKEN3 G_B_WPN1 G_B_WPN2
-UNUSED1 GAM_21A GAM_21B
-UNUSED2 G_BROKN1 G_BROKN2
-BUCKLER G_BUCKR1 G_BUCKR2
-CANDLE G_CAND1 G_CAND2
-CBODY G_CHILD1 G_CHILD2
-CLUB G_CLUB1 G_CLUB2
-FBODY G_FEM1 G_FEM2
-KEY2 G_KEYS1 G_KEYS2
-LSHIELD G_LGSLD1 G_LGSLD2
-MBODY G_MALE1 G_MALE2
-MSHIELD G_MDSLD1 G_MDSLD2
-NOTES G_PAPR1 G_PAPR2
-ROD G_ROD1 G_ROD2
-SKULL G_SKULL1 G_SKULL2
-SSHIELD G_SMSLD1 G_SMSLD2
-SPIDER G_SPIDR1 G_SPIDR2
-TELESCOPE G_TELE1 G_TELE2
-DRINK G_WINE1 G_WINE2
-GTSWORD G_LGSWD1 G_LGSWD2
-BAG GAM_21A GAM_21B
-FUR G_LETHR1 G_LETHR2
-LARMOR G_CLOAK1 G_CLOAK2
-SLARMOR G_CLOAK1 G_CLOAK2
-CHARMOR G_CLOAK1 G_CLOAK2
-SPARMOR G_CLOAK1 G_CLOAK2
-HPARMOR G_CLOAK1 G_CLOAK2
-FPARMOR G_CLOAK1 G_CLOAK2
-HARMOR G_CLOAK1 G_CLOAK2
-ROBE G_CLOAK1 G_CLOAK2
-SCALE G_CLOAK1 G_CLOAK2
-BTSWORD G_LGSWD1 G_LGSWD2
-SCARF G_GLOVE1 G_GLOVE2
-FOOD2 G_SLING1 G_SLING2
-HAT G_GLOVE1 G_GLOVE2
-GAUNTLET G_CAND1 G_CAND2
-DEFAULT GAM_21A GAM_21B
-LEATHER G_LETHR1 G_LETHR2
-CHAIN G_Chain1 G_Chain2
-PLATE G_Plate1 G_Plate2
diff --git a/gemrb/override/iwd/itemtype.2da b/gemrb/override/iwd/itemtype.2da
deleted file mode 100644
index b7f7e28..0000000
--- a/gemrb/override/iwd/itemtype.2da
+++ /dev/null
@@ -1,77 +0,0 @@
-2DA V1.0
-0
- HELMET ARMOR SHIELD GLOVES RING AMULET BELT BOOTS WEAPON QUIVER CLOAK QUICK SCROLL BAG POTION
-MISC 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
-AMULET 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
-ARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-BELT 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
-BOOT 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
-ARROW 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
-BRACER 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
-HELMET 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-KEY 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-POTION 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
-RING 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
-SCROLL 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0
-SHIELD 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
-FOOD 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
-BULLET 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
-BOW 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-DAGGER 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-MACE 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-SLING 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-SMSWORD 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-BGSWORD 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-HAMMER 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-MSTAR 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-FLAIL 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-DART 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-AXE 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-STAFF 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-XBOW 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-FIST 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-SPEAR 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-POLEARM 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-BOLT 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
-CLOAK 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
-COIN 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-GEM 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
-WAND 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
-BROKEN1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-BROKEN2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-BROKEN3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-UNUSED1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-UNUSED2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-BUCKLER 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
-CANDLE 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-UNUSED3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-CLUB 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-UNUSED4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-UNUSED5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-LSHIELD 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
-UNUSED6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-MSHIELD 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
-NOTES 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-UNUSED7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-UNUSED8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-SSHIELD 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
-UNUSED9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-TELESCOPE 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-DRINK 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
-GTSWORD 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-BAG 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
-FUR 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-LARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-SLARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-CHARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-SPARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-HPARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-FPARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-HARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-ROBE 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-UNUSED10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-BTSWORD 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-SCARF 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-FOOD2 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
-HAT 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-GAUNTLET 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
diff --git a/gemrb/override/iwd/magesch.2da b/gemrb/override/iwd/magesch.2da
deleted file mode 100644
index acd3cef..0000000
--- a/gemrb/override/iwd/magesch.2da
+++ /dev/null
@@ -1,12 +0,0 @@
-2DA V1.0
--1
- NAME_REF DESC_REF CAP_REF KIT
-GENERALIST 18039 9563 9987 0x4000
-ABJURER 597 9564 502 0x40
-CONJURER 2179 9565 504 0x80
-DIVINER 2846 9566 2012 0x100
-ENCHANTER 2861 9567 2022 0x200
-ILLUSIONIST 2862 9568 8421 0x400
-INVOKER 3015 9569 12786 0x800
-NECROMANCER 12744 9570 12787 0x1000
-TRANSMUTER 12745 9571 12788 0x2000
diff --git a/gemrb/override/iwd/overlay.2da b/gemrb/override/iwd/overlay.2da
deleted file mode 100644
index 0c05b4d..0000000
--- a/gemrb/override/iwd/overlay.2da
+++ /dev/null
@@ -1,35 +0,0 @@
-2DA V1.0
-*
- VVC UNDER FLAGS
-SANCTUARY SANCTUC 0 1
-ENTANGLE ENTANGC 0 0
-WISP WISP 0 0
-SHIELDGLOBE SHIELDC 0 1
-GREASE GREASEC 1 0
-WEB WEBC 1 0
-MINORGLOBE MGOINVC 0 1
-GLOBE GOINVUC 0 1
-FLAMESHROUD SOFLAMC 0 0
-ANTIMAGIC AMSHELC 0 0
-RESILIENT ORSPHEC 0 0
-PROTFROMMISS PFNMISC 0 0
-CLOAKOFFEAR COFEARC 0 0
-ENTROPY ESHIELC 0 0
-FIREAURA FIAURAC 0 0
-FROSTAURA FRAURAC 0 0
-INSECT IPLAGUC 0 0
-STORMSHELL SSHELLC 0 0
-LATHANDER1 SOLATC1 0 0
-LATHANDER2 SOLATC2 1 0
-GLATHANDER1 GSOLAC1 0 0
-GLATHANDER2 GSOLAC2 1 0
-SEVENEYES1 SEYESC1 0 0
-SEVENEYES2 SEYESC2 1 0
-BOUNCE SPTURNI2 1 0
-BOUNCE2 SPTURNI 1 0
-FIRESHIELD1 FSHIRC1 0 0
-FIRESHIELD2 FSHIRC2 1 0
-ICESHIELD1 FSHIBC1 0 0
-ICESHIELD2 FSHIBC2 1 0
-TORTOISE TSHELLC 0 0
-DEATHARMOR DARMORC 0 0
diff --git a/gemrb/override/iwd/qslots.2da b/gemrb/override/iwd/qslots.2da
deleted file mode 100644
index c9fc3d2..0000000
--- a/gemrb/override/iwd/qslots.2da
+++ /dev/null
@@ -1,24 +0,0 @@
-2DA V1.0
-100
- SLOT1 SLOT2 SLOT3 SLOT4 SLOT5 SLOT6 SLOT7 SLOT8 SLOT9
-DEFAULT 18 19 14 100 8 9 11 12 13
-MAGE 3 4 5 2 8 9 11 12 13
-FIGHTER 18 19 14 100 8 9 11 12 13
-CLERIC 6 3 4 2 8 9 11 12 13
-THIEF 22 0 1 100 8 9 11 12 13
-BARD 20 1 3 2 8 9 11 12 13
-PALADIN 18 14 6 2 8 9 11 12 13
-FIGHTER_MAGE 3 4 5 2 8 9 11 12 13
-FIGHTER_CLERIC 6 3 4 2 8 9 11 12 13
-FIGHTER_THIEF 18 22 0 1 8 9 11 12 13
-FIGHTER_MAGE_THIEF 22 0 1 2 8 9 11 12 13
-DRUID 3 4 5 2 8 9 11 12 13
-RANGER 18 14 0 2 8 9 11 12 13
-MAGE_THIEF 22 0 1 2 8 9 11 12 13
-CLERIC_MAGE 6 3 4 2 8 9 11 12 13
-CLERIC_THIEF 22 0 1 2 8 9 11 12 13
-FIGHTER_DRUID 3 4 5 2 8 9 11 12 13
-FIGHTER_MAGE_CLERIC 6 3 4 2 8 9 11 12 13
-CLERIC_RANGER 6 3 4 2 8 9 11 12 13
-SORCERER 3 4 5 2 8 9 11 12 13
-MONK 18 14 22 0 8 9 11 12 13
diff --git a/gemrb/override/iwd/strings.2da b/gemrb/override/iwd/strings.2da
deleted file mode 100644
index 490fbf1..0000000
--- a/gemrb/override/iwd/strings.2da
+++ /dev/null
@@ -1,170 +0,0 @@
-2DA V1.0
--1
- STRREF
-SCATTERED 16457
-WHOLEPARTY 16484
-DOORLOCKED 16485
-MAGICTRAP 16486
-NORMALTRAP 16487
-TRAP 16488
-CANNOTGO 16489
-TRAPREMOVED 16490
-OVERSTOCKED 16491
-SLEEP 16492
-AMBUSH 16493
-CONTLOCKED 16494
-NOMONEY 16495
-CURSED 16496
-SPELLDISRUPT 16497
-DIED 16498
-MAYNOTREST 16499
-CANTRESTMONS 16500
-CANTSAVEMONS 16501
-CANTSAVE 16502
-NODIALOG 10945
-CANTSAVEDIALOG 19253
-CANTSAVEDIALOG2 19254
-CANTSAVEMOVIE 19255
-TARGETBUSY -1
-CANTTALKTRANS -1
-GOTGOLD 17572
-LOSTGOLD 17573
-GOTXP 17574
-LOSTXP 17575
-GOTITEM 17576
-LOSTITEM 17577
-GOTREP 19686
-LOSTREP 19687
-GOTABILITY 10514
-GOTSPELL 10514
-GOTSONG 26320
-NOTHINGTOSAY -1
-JOURNALCHANGE 11359
-WORLDMAPCHANGE 11360
-PAUSED 16321
-UNPAUSED 16322
-SCRIPTPAUSED 7666
-AP_UNUSABLE 17113
-AP_ATTACKED 17114
-AP_HIT 17115
-AP_WOUNDED 17116
-AP_DEAD 17117
-AP_NOTARGET 17118
-AP_ENDROUND 10014
-AP_ENEMY 23511
-AP_TRAP -1
-AP_SPELLCAST -1
-AP_RESERVED1 -1
-AP_RESERVED2 -1
-AP_RESERVED3 -1
-AP_RESERVED4 -1
-CHARMED 14672
-DIRECHARMED 14780
-CONTROLLED -1
-EVIL 16505
-GNE_NEUTRAL 16504
-GOOD 16503
-STR_LAWFUL -1
-LNC_NEUTRAL -1
-CHAOTIC -1
-ACTION_CAST 16464
-ACTION_ATTACK 16465
-ACTION_TURN 16466
-ACTION_SONG 16467
-ACTION_FINDTRAP 16468
-MAGICWEAPON 10141
-OFFHAND_USED 9380
-TWOHANDED_USED 9381
-CANNOT_USE_ITEM 9382
-CANT_DROP_ITEM 25697
-NOT_IN_OFFHAND 26342
-ITEM_IS_CURSED 16304
-NO_CRITICAL 20696
-TRACKING -1
-TRACKINGFAILED 19534
-DOOR_NOPICK 23169
-CONT_NOPICK 23169
-CANTSAVECOMBAT -1
-CANTSAVENOCTRL -1
-LOCKPICK_DONE 16517
-LOCKPICK_FAILED 16518
-STATIC_DISSIPATE -1
-LIGHTNING_DISSIPATE -1
-HAS_NO_ABILITY 17317
-NEEDS_IDENTIFY 17316
-WRONG_ITEMTYPE 9375
-HAS_ITEMEXCL 20685
-PICKPOCKET_DONE 10072
-PICKPOCKET_NONE 18297
-PICKPOCKET_FAIL 10069
-PICKPOCKET_EVIL 10068
-PICKPOCKET_ARMOR 10067
-USING_FEAT -1
-STOPPED_FEAT -1
-DISARM_DONE 16520
-DISARM_FAIL 1608
-DOORBASH_DONE 9915
-DOORBASH_FAIL 9913
-CONTBASH_DONE 9916
-CONTBASH_FAIL 9914
-MAYNOTSETTRAP -1
-SNAREFAILED -1
-SNARESUCCEED -1
-NOMORETRAP -1
-DISABLEDMAGE -1
-SAVESUCCEED 1682
-QSAVESUCCEED 10237
-UNINJURED 2943
-INJURED1 2944
-INJURED2 2945
-INJURED3 2946
-INJURED4 2947
-HOURS 10700
-HOUR 10701
-DAYS 10697
-DAY 10698
-REST 10690
-JOURNEY 10689
-PST_REST -1
-PST_HOUR -1
-PST_HOURS -1
-DAMAGE_IMMUNITY -1
-DAMAGE_STR1 14027
-DAMAGE_STR2 -1
-DAMAGE_STR3 -1
-DMG_POISON -1
-DMG_MAGIC -1
-DMG_MISSILE -1
-DMG_SLASHING -1
-DMG_PIERCING -1
-DMG_CRUSHING -1
-DMG_FIRE -1
-DMG_ELECTRIC -1
-DMG_COLD -1
-DMG_ACID -1
-DMG_OTHER -1
-GOTQUESTXP -1
-LEVELUP 17119
-INVFULL_ITEMDROP 32879
-CONT_DUP 32876
-CONT_TRIG -1
-CONT_FAIL -1
-SEQ_DUP -1
-CRITICAL_HIT 16462
-CRITICAL_MISS 16463
-DEATH 14026
-BACKSTAB 12128
-BACKSTAB_BAD 10013
-BACKSTAB_FAIL -1
-CASTER_LVL_INC -1
-CASTER_LVL_DEC -1
-CHARS_EXPORTED 26827
-PALADIN_FALL 19620
-RANGER_FALL 19621
-RES_RESISTED 26818
-DEADMAGIC_FAIL -1
-MISCASTMAGIC -1
-WILDSURGE -1
-FAMBLOCK -1
-FAMPROTAGONIST -1
-
diff --git a/gemrb/override/iwd/vcremap.2da b/gemrb/override/iwd/vcremap.2da
deleted file mode 100644
index b23c7aa..0000000
--- a/gemrb/override/iwd/vcremap.2da
+++ /dev/null
@@ -1,4 +0,0 @@
-2DA V1.0
-*
- ORIGINAL NEW
-BIO 74 63
diff --git a/gemrb/override/iwd2/CMakeLists.txt b/gemrb/override/iwd2/CMakeLists.txt
deleted file mode 100644
index b03ca46..0000000
--- a/gemrb/override/iwd2/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-ADD_GEMRB_OVERRIDE (iwd2)
\ No newline at end of file
diff --git a/gemrb/override/iwd2/Makefile.am b/gemrb/override/iwd2/Makefile.am
index 08aee09..5f0c923 100644
--- a/gemrb/override/iwd2/Makefile.am
+++ b/gemrb/override/iwd2/Makefile.am
@@ -1,3 +1,3 @@
-iwd2override_DATA = *.2da *.ini *.chu *.ids *.pro
+iwd2override_DATA = *.2da
iwd2overridedir = $(moddir)/override/iwd2/
-EXTRA_DIST = *.2da *.ini *.chu *.ids *.pro
+EXTRA_DIST = *.2da
diff --git a/gemrb/override/iwd2/ability.2da b/gemrb/override/iwd2/ability.2da
deleted file mode 100644
index 2fa0989..0000000
--- a/gemrb/override/iwd2/ability.2da
+++ /dev/null
@@ -1,9 +0,0 @@
-2DA V1.0
--1
- NAME_REF DESC_REF CAP_REF STAT_ID
-STRENGTH 11975 9582 1145 36
-DEXTERITY 11977 9584 1151 40
-CONSTITUTION 11978 9583 1178 41
-INTELLIGENCE 11979 9585 1179 38
-WISDOM 11980 9586 1180 39
-CHARISMA 11981 9587 1181 42
diff --git a/gemrb/override/iwd2/avatars.2da b/gemrb/override/iwd2/avatars.2da
deleted file mode 100644
index a04e296..0000000
--- a/gemrb/override/iwd2/avatars.2da
+++ /dev/null
@@ -1,432 +0,0 @@
-2DA V1.0
-*
- AT_1 AT_2 AT_3 AT_4 TYPE SPACE PALETTE SIZE
-0x0100 SPCHUNKS SPCHUNKS SPCHUNKS SPCHUNKS 13 0 0 *
-0x0300 SPSMPUFF SPSMPUFF SPSMPUFF SPSMPUFF 13 0 0 *
-0x0400 SKLH SKLH SKLH SKLH 13 0 1 *
-0x0410 GLPHWRDH GLPHWRDH GLPHWRDH GLPHWRDH 13 0 1 *
-0x1001 MWYV MWYV MWYV MWYV 11 5 1 *
-0x1100 MTAN MTAN MTAN MTAN 11 5 1 *
-0x1200 MDR1 MDR1 MDR1 MDR1 12 5 1 *
-0x1201 MDR2 MDR2 MDR2 MDR2 12 5 1 *
-0x1202 MDR3 MDR3 MDR3 MDR3 12 5 1 *
-0x1203 MDR1 MDR1 MDR1 MDR1 12 7 GR *
-0x1204 MDR1 MDR1 MDR1 MDR1 12 7 AQ *
-0x1205 MDR1 MDR1 MDR1 MDR1 12 7 BL *
-0x1206 MDR1 MDR1 MDR1 MDR1 12 7 BR *
-0x1207 MDR1 MDR1 MDR1 MDR1 12 7 MC *
-0x1208 MDR1 MDR1 MDR1 MDR1 12 7 PU *
-0x2000 MSIR MSIR MSIR MSIR 2 2 0 *
-0x2100 UVOL UVOL UVOL UVOL 2 2 1 *
-0x2200 MOGM MOGM MOGM MOGM 2 2 0 S
-0x2300 MDKN MDKN MDKN MDKN 2 2 1 *
-0x3000 MAKH MAKH MAKH MAKH 2 3 1 *
-0x4000 SNOMC SNOMC SNOMC SNOMC 1 2 0 *
-0x4002 SNOMM SNOMM SNOMM SNOMM 1 2 0 *
-0x4010 SNOWC SNOWC SNOWC SNOWC 1 2 0 *
-0x4012 SNOWM SNOWM SNOWM SNOWM 1 2 0 *
-0x4100 SSIMC SSIMC SSIMC SSIMC 1 2 0 *
-0x4101 SSIMS SSIMS SSIMS SSIMS 1 2 0 *
-0x4102 SSIMM SSIMM SSIMM SSIMM 1 2 0 *
-0x4110 SSIWC SSIWC SSIWC SSIWC 1 2 0 *
-0x4112 SSIWM SSIWM SSIWM SSIWM 1 2 0 *
-0x4200 SHMCM SHMCM SHMCM SHMCM 1 2 0 *
-0x4300 MSPLG1 MSPLG1 MSPLG1 MSPLG1 1 2 1 *
-0x4400 LHMC LHMC LHMC LHMC 1 2 0 *
-0x4410 LHFC LHFC LHFC LHFC 1 2 0 *
-0x4500 LFAM LFAM LFAM LFAM 1 2 0 *
-0x4600 LDMF LDMF LDMF LDMF 1 2 0 *
-0x4700 LEMF LEMF LEMF LEMF 1 2 0 *
-0x4710 LEFF LEFF LEFF LEFF 1 2 0 *
-0x4800 LIMC LIMC LIMC LIMC 1 2 0 *
-0x5000 CHMB1 CHMB2 CHMB3 CHMC4 0 2 0 *
-0x5001 CEMB1 CEMB2 CEMB3 CEMC4 0 2 0 *
-0x5002 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 *
-0x5003 CIMB1 CIMB2 CIMB3 CIMC4 0 2 0 *
-0x5010 CHFB1 CHFB2 CHFB3 CHFC4 0 2 0 *
-0x5011 CEFB1 CEFB2 CEFB3 CEFC4 0 2 0 *
-0x5012 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 *
-0x5013 CIFB1 CIFB2 CIFB3 CIFC4 0 2 0 *
-0x5100 CHMB1 CHMB2 CHMB3 CHMF4 0 2 0 *
-0x5101 CEMB1 CEMB2 CEMB3 CHMF4 0 2 0 *
-0x5102 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 *
-0x5103 CIMB1 CIMB2 CIMB3 CIMF4 0 2 0 *
-0x5110 CHFB1 CHFB2 CHFB3 CHFF4 0 2 0 *
-0x5111 CEFB1 CEFB2 CEFB3 CEFF4 0 2 0 *
-0x5112 CDMB1 CDFB2 CDFB3 CDFF4 0 2 0 *
-0x5113 CIFB1 CIFB2 CIFB3 CIFF4 0 2 0 *
-0x5200 CHMW1 CHMW2 CHMW3 CHMW4 0 2 0 *
-0x5201 CEMW1 CEMW2 CEMW3 CEMW4 0 2 0 *
-0x5202 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 *
-0x5203 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 *
-0x5210 CHFW1 CHFW2 CHFW3 CHFW4 0 2 0 *
-0x5211 CEFW1 CEFW2 CEFW3 CEFW4 0 2 0 *
-0x5212 CDMW1 CDFW2 CDFW3 CDFW4 0 2 0 *
-0x5213 CDMW1 CDFW2 CDFW3 CDFW4 0 2 0 *
-0x5300 CHMB1 CHMT2 CHMB3 CHMF4 0 2 0 *
-0x5301 CEMB1 CEMT2 CEMB3 CEMF4 0 2 0 *
-0x5302 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 *
-0x5303 CIMB1 CIMT2 CIMB3 CIMF4 0 2 0 *
-0x5310 CHFB1 CHFT2 CHFB3 CHFF4 0 2 0 *
-0x5311 CEFB1 CEFT2 CEFB3 CEFF4 0 2 0 *
-0x5312 CDMB1 CDFT2 CDFB3 CDFF4 0 2 0 *
-0x5313 CIFB1 CIFT2 CIFB3 CIFF4 0 2 0 *
-0x6000 CHMB1 CHMB2 CHMB3 CHMC4 0 2 0 *
-0x6001 CEMB1 CEMB2 CEMB3 CEMC4 0 2 0 *
-0x6002 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 *
-0x6003 CIMB1 CIMB2 CIMB3 CIMC4 0 2 0 *
-0x6004 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 *
-0x6005 CHMB1 CHMB2 CHMB3 CHMC4 0 2 0 *
-0x6010 CHFB1 CHFB2 CHFB3 CHFC4 0 2 0 *
-0x6011 CEFB1 CEFB2 CEFB3 CEFC4 0 2 0 *
-0x6012 CDMB1 CDFB2 CDFB3 CDFC4 0 2 0 *
-0x6013 CIFB1 CIFB2 CIFB3 CIFC4 0 2 0 *
-0x6014 CIFB1 CIFB2 CIFB3 CIFC4 0 2 0 *
-0x6015 CHFB1 CHFB2 CHFB3 CHFC4 0 2 0 *
-0x6100 CHMB1 CHMB2 CHMB3 CHMF4 0 2 0 *
-0x6101 CEMB1 CEMB2 CEMB3 CEMF4 0 2 0 *
-0x6102 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 *
-0x6103 CIMB1 CIMB2 CIMB3 CIMF4 0 2 0 *
-0x6104 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 *
-0x6105 CHMB1 CHMB2 CHMB3 CHMF4 0 2 0 *
-0x6110 CHFB1 CHFB2 CHFB3 CHFF4 0 2 0 *
-0x6111 CEFB1 CEFB2 CEFB3 CEFF4 0 2 0 *
-0x6112 CDMB1 CDFB2 CDFB3 CDFF4 0 2 0 *
-0x6113 CIFB1 CIFB2 CIFB3 CIFF4 0 2 0 *
-0x6114 CIFB1 CIFB2 CIFB3 CIFF4 0 2 0 *
-0x6115 CHFB1 CHFB2 CHFB3 CHFF4 0 2 0 *
-0x6200 CHMW1 CHMW2 CHMW3 CHMW4 0 2 0 *
-0x6201 CEMW1 CEMW2 CEMW3 CEMW4 0 2 0 *
-0x6202 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 *
-0x6203 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 *
-0x6204 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 *
-0x6205 CHMW1 CHMW2 CHMW3 CHMW4 0 2 0 *
-0x6210 CHFW1 CHFW2 CHFW3 CHFW4 0 2 0 *
-0x6211 CEFW1 CEFW2 CEFW3 CEFW4 0 2 0 *
-0x6212 CDMW1 CDFW2 CDFW3 CDFW4 0 2 0 *
-0x6213 CDMW1 CDFW2 CDFW3 CDFW4 0 2 0 *
-0x6214 CDMW1 CIFW2 CIFW3 CIFW4 0 2 0 *
-0x6215 CHFW1 CHFW2 CHFW3 CHFW4 0 2 0 *
-0x6300 CHMB1 CHMT2 CHMB3 CHMF4 0 2 0 *
-0x6301 CEMB1 CEMT2 CEMB3 CEMF4 0 2 0 *
-0x6302 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 *
-0x6303 CIMB1 CIMT2 CIMB3 CIMF4 0 2 0 *
-0x6304 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 *
-0x6305 CHMB1 CHMT2 CHMB3 CHMF4 0 2 0 *
-0x6310 CHFB1 CHFT2 CHFB3 CHFF4 0 2 0 *
-0x6311 CEFB1 CEFT2 CEFB3 CEFF4 0 2 0 *
-0x6312 CDMB1 CDFT2 CDFB3 CDFF4 0 2 0 *
-0x6313 CIFB1 CIFT2 CIFB3 CIFF4 0 2 0 *
-0x6314 CIFB1 CIFT2 CIFB3 CIFF4 0 2 0 *
-0x6315 CHFB1 CHFT2 CHFT3 CHFF4 0 2 0 *
-0x6400 UDRZ1 UDRZ1 UDRZ1 UDRZ1 6 2 0 *
-0x6401 UELM1 UELM1 UELM1 UELM1 6 2 1 *
-0x6402 CMNK1 CMNK1 CMNK1 CMNK1 6 2 0 *
-0x6403 MSKL1 MSKL1 MSKL1 MSKL1 6 2 0 M
-0x6404 USAR1 USAR1 USAR1 USAR1 6 2 1 *
-0x6405 MDGU1 MDGU1 MDGU1 MDGU1 6 2 0 M
-0x6406 MDGU1 MDGU1 MDGU1 MDGU1 6 2 0 L
-0x6500 CHMM1 CHMB2 CHMB3 CHMC4 0 2 0 *
-0x6510 CHFM1 CHFB2 CHFB3 CHFC4 0 2 0 *
-0x7000 MOGH MOGH MOGH MOGH 2 2 0 *
-0x7001 MOGN MOGN MOGN MOGN 2 2 0 *
-0x7100 MBAS MBAS MBAS MBAS 2 2 1 *
-0x7101 MBAS MBAS MBAS MBAS 2 2 GR *
-0x7200 MBER MBER MBER MBER 3 2 BL *
-0x7201 MBER MBER MBER MBER 3 2 1 *
-0x7202 MBER MBER MBER MBER 3 2 CA *
-0x7203 MBER MBER MBER MBER 3 2 PO *
-0x7300 MEAE MEAE MEAE MEAE 4 2 1 *
-0x7301 MEAS MEAS MEAS MEAS 4 2 1 *
-0x7310 MFIE MFIE MFIE MFIE 4 2 1 *
-0x7311 MFIS MFIS MFIS MFIS 4 2 1 *
-0x7320 MAIR MAIR MAIR MAIR 4 2 1 *
-0x7321 MAIS MAIS MAIS MAIS 4 2 1 *
-0x7400 MDOG MDOG MDOG MDOG 2 2 WI *
-0x7401 MDOG MDOG MDOG MDOG 2 2 WA *
-0x7402 MDOG MDOG MDOG MDOG 2 2 MO *
-0x7500 MDOP MDOP MDOP MDOP 3 2 1 *
-0x7501 MDOP MDOP MDOP MDOP 3 2 GR *
-0x7600 METT METT METT METT 2 2 1 *
-0x7701 MGHL MGHL MGHL MGHL 2 2 1 *
-0x7702 MGHL MGHL MGHL MGHL 2 2 RE *
-0x7703 MGHL MGHL MGHL MGHL 2 2 GA *
-0x7704 MSHD MSHD MSHD MSHD 4 2 1 *
-0x7800 MGIB MGIB MGIB MGIB 2 2 1 *
-0x7900 MSLI MSLI MSLI MSLI 3 3 GR *
-0x7901 MSLI MSLI MSLI MSLI 3 3 OL *
-0x7902 MSLI MSLI MSLI MSLI 3 3 MU *
-0x7903 MSLI MSLI MSLI MSLI 3 3 OC *
-0x7904 MSLI MSLI MSLI MSLI 3 3 1 *
-0x7A00 MSPI MSPI MSPI MSPI 3 2 GI *
-0x7A01 MSPI MSPI MSPI MSPI 3 2 HU *
-0x7A02 MSPI MSPI MSPI MSPI 3 2 PH *
-0x7A03 MSPI MSPI MSPI MSPI 3 2 SW *
-0x7A04 MSPI MSPI MSPI MSPI 3 2 WR *
-0x7B00 MWLF MWLF MWLF MWLF 2 2 1 *
-0x7B01 MWLF MWLF MWLF MWLF 2 2 WO *
-0x7B02 MWLF MWLF MWLF MWLF 2 2 DI *
-0x7B03 MWLF MWLF MWLF MWLF 2 2 WI *
-0x7B04 MWLF MWLF MWLF MWLF 2 2 VA *
-0x7B05 MWLF MWLF MWLF MWLF 2 2 DR *
-0x7B06 MWLS MWLS MWLS MWLS 2 2 1 *
-0x7C00 MXVT MXVT MXVT MXVT 2 2 0 *
-0x7C01 MTAS MTAS MTAS MTAS 2 2 0 *
-0x7D00 MZOM MZOM MZOM MZOM 2 2 0 *
-0x7E00 MWER MWER MWER MWER 2 2 1 *
-0x7E01 MGWE MGWE MGWE MGWE 2 2 1 *
-0x7F00 MTRO MTRO MTRO MTRO 4 2 1 *
-0x7F01 MMIN MMIN MMIN MMIN 4 2 1 *
-0x7F02 MBEH MBEH MBEH MBEH 4 3 1 *
-0x7F03 MIMP MIMP MIMP MIMP 4 2 1 *
-0x7F04 MIGO MIGO MIGO MIGO 4 2 1 *
-0x7F05 MDJI MDJI MDJI MDJI 4 2 1 *
-0x7F06 MDJL MDJL MDJL MDJL 4 2 1 *
-0x7F07 MGLC MGLC MGLC MGLC 4 3 1 *
-0x7F08 MOTY MOTY MOTY MOTY 4 4 1 *
-0x7F09 MSAH MSAH MSAH MSAH 4 2 1 *
-0x7F0A MGCP MGCP MGCP MGCP 4 2 1 *
-0x7F0B MGCL MGCL MGCL MGCL 4 2 1 *
-0x7F0C MKUO MKUO MKUO MKUO 4 2 1 *
-0x7F0D MLIC MLIC MLIC MLIC 4 2 1 *
-0x7F0E MDLI MDLI MDLI MDLI 4 2 1 *
-0x7F0F MTRS MTRS MTRS MTRS 4 2 1 *
-0x7F10 MRAK MRAK MRAK MRAK 4 2 1 *
-0x7F11 MUMB MUMB MUMB MUMB 4 2 1 *
-0x7F12 MVAM MVAM MVAM MVAM 4 2 1 *
-0x7F13 MSNK MSNK MSNK MSNK 4 2 1 *
-0x7F14 MGIT MGIT MGIT MGIT 4 2 1 *
-0x7F15 MBES MBES MBES MBES 4 2 1 *
-0x7F16 AMOO AMOO AMOO AMOO 4 3 1 *
-0x7F17 ARAB ARAB ARAB ARAB 4 1 1 *
-0x7F18 ADER ADER ADER ADER 4 2 1 *
-0x7F19 MDSW MDSW MDSW MDSW 4 2 1 *
-0x7F20 AGRO AGRO AGRO AGRO 4 2 1 *
-0x7F21 APHE APHE APHE APHE 4 2 1 *
-0x7F22 MVAF MVAF MVAF MVAF 4 2 1 *
-0x7F23 MSAT MSAT MSAT MSAT 4 3 1 *
-0x7F24 NPIR NPIR NPIR NPIR 4 2 1 *
-0x7F27 MDRO MDRO MDRO MDRO 4 2 1 *
-0x7F28 MKUL MKUL MKUL MKUL 4 3 1 *
-0x7F29 MFDR MFDR MFDR MFDR 4 2 1 *
-0x7F2A NSAI NSAI NSAI NSAI 4 2 1 *
-0x7F2B MMAX MMAX MMAX MMAX 4 2 1 *
-0x7F2C NSOL NSOL NSOL NSOL 4 2 1 *
-0x7F2D MWFM MWFM MWFM MWFM 4 2 1 *
-0x7F2E MRAV MRAV MRAV MRAV 4 3 1 *
-0x7F2F MSPS MSPS MSPS MSPS 4 2 1 *
-0x7F30 NBOH NBOH NBOH NBOH 4 2 1 *
-0x7F31 NELL NELL NELL NELL 4 2 1 *
-0x7F32 MSLY MSLY MSLY MSLY 4 2 1 *
-0x7F33 MKUR MKUR MKUR MKUR 4 2 1 *
-0x7F34 MDOC MDOC MDOC MDOC 4 2 1 *
-0x7F35 MMIS MMIS MMIS MMIS 4 3 1 *
-0x7F36 NSHD NSHD NSHD NSHD 4 2 1 *
-0x7F37 NIRE NIRE NIRE NIRE 4 2 1 *
-0x8000 MGNL MGNL MGNL MGNL 2 2 0 *
-0x8100 MHOB MHOB MHOB MHOB 2 2 0 *
-0x8200 MKOB MKOB MKOB MKOB 2 2 0 *
-0x9000 MOGR MOGR MOGR MOGR 5 2 0 *
-0xA000 MWYV MWYV MWYV MWYV 8 3 1 *
-0xA100 MCAR MCAR MCAR MCAR 8 3 1 *
-0xB000 ACOW ACOW ACOW ACOW 10 3 1 *
-0xB100 AHRS AHRS AHRS AHRS 10 3 1 *
-0xB200 NBEGL NBEGL NBEGL NBEGL 3 2 0 *
-0xB210 NPROL NPROL NPROL NPROL 3 2 0 *
-0xB300 NBOYL NBOYL NBOYL NBOYL 3 2 0 *
-0xB310 NGRLL NGRLL NGRLL NGRLL 3 2 0 *
-0xB400 NFAML NFAML NFAML NFAML 3 2 0 *
-0xB410 NFAWL NFAWL NFAWL NFAWL 3 2 0 *
-0xB500 NSIML NSIML NSIML NSIML 3 2 0 *
-0xB510 NSIWL NSIWL NSIWL NSIWL 3 2 0 *
-0xB600 NNOML NNOML NNOML NNOML 3 2 0 *
-0xB610 NNOWL NNOWL NNOWL NNOWL 3 2 0 *
-0xB700 NSLVL NSLVL NSLVL NSLVL 3 2 0 *
-0xC000 ABAT ABAT ABAT ABAT 3 1 1 *
-0xC100 ACAT ACAT ACAT ACAT 3 1 1 *
-0xC200 ACHK ACHK ACHK ACHK 3 1 1 *
-0xC300 ARAT ARAT ARAT ARAT 3 1 1 *
-0xC400 ASQU ASQU ASQU ASQU 3 1 1 *
-0xC500 ABAT ABAT ABAT ABAT 3 1 1 *
-0xC600 NBEGH NBEGH NBEGH NBEGH 3 2 0 *
-0xC610 NPROH NPROH NPROH NPROH 3 2 0 *
-0xC700 NBOYH NBOYH NBOYH NBOYH 3 2 0 *
-0xC710 NGRLH NGRLH NGRLH NGRLH 3 2 0 *
-0xC800 NFAMH NFAMH NFAMH NFAMH 3 2 0 *
-0xC810 NFAWH NFAWH NFAWH NFAWH 3 2 0 *
-0xC900 NSIMH NSIMH NSIMH NSIMH 3 2 0 *
-0xC910 NSIWH NSIWH NSIWH NSIWH 3 2 0 *
-0xCA00 NNOMH NNOMH NNOMH NNOMH 3 2 0 *
-0xCA10 NNOWH NNOWH NNOWH NNOWH 3 2 0 *
-0xCB00 NSLVH NSLVH NSLVH NSLVH 3 2 0 *
-0xD000 AEAGG1 AEAGG1 AEAGG1 AEAGG1 7 0 1 *
-0xD100 AGULG1 AGULG1 AGULG1 AGULG1 7 0 1 *
-0xD200 AVULG1 AVULG1 AVULG1 AVULG1 7 0 1 *
-0xD300 ABIRG1 ABIRG1 ABIRG1 ABIRG1 7 0 1 *
-0xD400 ABIRG1 ABIRG1 ABIRG1 ABIRG1 7 0 1 *
-0xE000 MBET MBET MBET MBET 9 2 1 *
-0xE012 MBBM MBBM MBBM MBBM 9 2 1 *
-0xE020 MTAN MTAN MTAN MTAN 9 4 1 *
-0xEBCD MTAN MTAN MTAN MTAN 9 4 1 *
-0xE022 MBBR MBBR MBBR MBBR 9 2 1 *
-0xE038 MBFI MBFI MBFI MBFI 9 2 1 *
-0xE048 MBRH MBRH MBRH MBRH 9 5 1 *
-0xE050 MREM MREM MREM MREM 9 4 1 *
-0xE060 MLIC MLIC MLIC MLIC 9 2 1 *
-0xEB69 MLIC MLIC MLIC MLIC 9 2 1 *
-0xE068 MHOH MHOH MHOH MHOH 9 2 1 *
-0xE070 MMIN MMIN MMIN MMIN 9 2 1 *
-0xE090 MMER MMER MMER MMER 9 2 1 *
-0xE0A0 MTIC MTIC MTIC MTIC 9 2 1 *
-0xE728 MTIC MTIC MTIC MTIC 9 2 1 *
-0xE0B0 MTRO MTRO MTRO MTRO 9 2 1 *
-0xE718 MTRO MTRO MTRO MTRO 9 2 1 *
-0xE0C0 MTSN MTSN MTSN MTSN 9 2 1 *
-0xE738 MTSN MTSN MTSN MTSN 9 2 1 *
-0xE0D0 MUMB MUMB MUMB MUMB 9 2 1 *
-0xE759 MUMB MUMB MUMB MUMB 9 2 1 *
-0xE0E0 MCOR MCOR MCOR MCOR 9 3 1 *
-0xED09 MCOR MCOR MCOR MCOR 9 3 1 *
-0xE0F0 MGIC MGIC MGIC MGIC 9 2 1 *
-0xE0F1 MGLA MGLA MGLA MGLA 9 2 1 *
-0xE108 MCYC MCYC MCYC MCYC 9 4 1 *
-0xE118 METN METN METN METN 9 4 1 *
-0xE138 MGFR MGFR MGFR MGFR 9 4 1 *
-0xE148 MGVE MGVE MGVE MGVE 9 4 1 *
-0xE15A MGFO MGFO MGFO MGFO 9 4 1 *
-0xE218 MELE MELE MELE MELE 9 4 1 *
-0xE228 MELF MELF MELF MELF 9 4 1 *
-0xE238 MELW MELW MELW MELW 9 4 1 *
-0xE249 MHAR MHAR MHAR MHAR 9 2 1 *
-0xE252 MWWE MWWE MWWE MWWE 9 2 1 *
-0xE269 MFEY MFEY MFEY MFEY 9 2 1 *
-0xE278 MDTR MDTR MDTR MDTR 9 3 1 *
-0xE289 MFE2 MFE2 MFE2 MFE2 9 3 1 *
-0xE298 MEW2 MEW2 MEW2 MEW2 9 2 1 *
-0xE300 MGHO MGHO MGHO MGHO 9 2 1 *
-0xE928 MGHO MGHO MGHO MGHO 9 2 1 *
-0xE308 MGH2 MGH2 MGH2 MGH2 9 2 1 *
-0xE318 MGH3 MGH3 MGH3 MGH3 9 2 1 *
-0xE329 MWIG MWIG MWIG MWIG 9 2 1 *
-0xE338 MZO2 MZO2 MZO2 MZO2 9 2 1 *
-0xE348 MZO3 MZO3 MZO3 MZO3 9 2 1 *
-0xE359 MWI2 MWI2 MWI2 MWI2 9 2 1 *
-0xE369 MWI3 MWI3 MWI3 MWI3 9 2 1 *
-0xE388 MMUM MMUM MMUM MMUM 9 2 1 *
-0xE39C MHIS MHIS MHIS MHIS 9 2 1 *
-0xE3A8 MDRD MDRD MDRD MDRD 9 2 1 *
-0xE3BB MWAV MWAV MWAV MWAV 9 2 1 *
-0xE408 MGO1 MGO1 MGO1 MGO1 9 2 1 *
-0xE412 MGO2 MGO2 MGO2 MGO2 9 2 1 *
-0xE428 MGO3 MGO3 MGO3 MGO3 9 2 1 *
-0xE432 MGO4 MGO4 MGO4 MGO4 9 2 1 *
-0xE449 MSVI MSVI MSVI MSVI 9 2 1 *
-0xE459 MSV2 MSV2 MSV2 MSV2 9 2 1 *
-0xE468 MGWO MGWO MGWO MGWO 9 2 1 *
-0xE479 MGOC MGOC MGOC MGOC 9 2 1 *
-0xE488 MGW2 MGW2 MGW2 MGW2 9 2 1 *
-0xE498 MGO5 MGO5 MGO5 MGO5 9 2 1 *
-0xE500 MLIZ MLIZ MLIZ MLIZ 9 2 1 *
-0xF209 MLIZ MLIZ MLIZ MLIZ 9 2 1 *
-0xE510 MLI2 MLI2 MLI2 MLI2 9 2 1 *
-0xF218 MLI2 MLI2 MLI2 MLI2 9 2 1 *
-0xE51D MGIR MGIR MGIR MGIR 9 2 1 *
-0xE520 MLI3 MLI3 MLI3 MLI3 9 2 1 *
-0xE899 MLI3 MLI3 MLI3 MLI3 9 2 1 *
-0xE528 MGIC MGIC MGIC MGIC 9 2 1 *
-0xE600 MMYC MMYC MMYC MMYC 9 2 1 *
-0xEB99 MMYC MMYC MMYC MMYC 9 2 1 *
-0xE610 MMY2 MMY2 MMY2 MMY2 9 2 1 *
-0xEBA9 MMY2 MMY2 MMY2 MMY2 9 2 1 *
-0xE62C MSKB MSKB MSKB MSKB 9 2 1 *
-0xE700 MNO1 MNO1 MNO1 MNO1 9 2 1 *
-0xE868 MNO1 MNO1 MNO1 MNO1 9 2 1 *
-0xE710 MNO2 MNO2 MNO2 MNO2 9 2 1 *
-0xE878 MNO2 MNO2 MNO2 MNO2 9 2 1 *
-0xE720 MNO3 MNO3 MNO3 MNO3 9 2 1 *
-0xE888 MNO3 MNO3 MNO3 MNO3 9 2 1 *
-0xE88C MNO3 MNO3 MNO3 MNO3 9 2 1 *
-0xE76C MYET MYET MYET MYET 9 2 1 *
-0xE771 MBA4 MBA4 MBA4 MBA4 9 2 1 *
-0xE781 MBA5 MBA5 MBA5 MBA5 9 2 1 *
-0xE791 MBA6 MBA6 MBA6 MBA6 9 2 1 *
-0xE7AC MBAI MBAI MBAI MBAI 9 2 1 *
-0xE7B8 MBOA MBOA MBOA MBOA 9 2 1 *
-0xE7C9 MABW MABW MABW MABW 9 2 1 *
-0xE7E8 MSCR MSCR MSCR MSCR 9 2 1 *
-0xE7F9 MUM2 MUM2 MUM2 MUM2 9 2 1 *
-0xE800 MOR1 MOR1 MOR1 MOR1 9 2 1 *
-0xE818 MOR1 MOR1 MOR1 MOR1 9 2 1 *
-0xE808 MOR6 MOR6 MOR6 MOR6 9 2 1 *
-0xE810 MOR2 MOR2 MOR2 MOR2 9 2 1 *
-0xE822 MOR2 MOR2 MOR2 MOR2 9 2 1 *
-0xE820 MOR3 MOR3 MOR3 MOR3 9 2 1 *
-0xE838 MOR3 MOR3 MOR3 MOR3 9 2 1 *
-0xE830 MOR4 MOR4 MOR4 MOR4 9 2 1 *
-0xE842 MOR4 MOR4 MOR4 MOR4 9 2 1 *
-0xE840 MOR5 MOR5 MOR5 MOR5 9 2 1 *
-0xE859 MOR5 MOR5 MOR5 MOR5 9 2 1 *
-0xE8C8 MBUG MBUG MBUG MBUG 9 2 1 *
-0xE8D9 MNOS MNOS MNOS MNOS 9 2 1 *
-0xE8E8 MBU2 MBU2 MBU2 MBU2 9 2 1 *
-0xE8F9 MOR7 MOR7 MOR7 MOR7 9 2 1 *
-0xE900 MSAL MSAL MSAL MSAL 9 2 1 *
-0xEBD8 MSAL MSAL MSAL MSAL 9 2 1 *
-0xE910 MSA2 MSA2 MSA2 MSA2 9 2 1 *
-0xEBE8 MSA2 MSA2 MSA2 MSA2 9 2 1 *
-0xE918 MSH2 MSH2 MSH2 MSH2 9 2 1 *
-0xEA00 MSHR MSHR MSHR MSHR 9 2 1 *
-0xEBB1 MSHR MSHR MSHR MSHR 9 2 1 *
-0xEBF1 MARU MARU MARU MARU 9 2 1 *
-0xEA10 MSH1 MSH1 MSH1 MSH1 9 2 1 *
-0xE908 MSH1 MSH1 MSH1 MSH1 9 2 1 *
-0xEA20 MCRD MCRD MCRD MCRD 9 2 1 *
-0xEB00 MSKT MSKT MSKT MSKT 9 2 1 *
-0xF019 MSKT MSKT MSKT MSKT 9 2 1 *
-0xEB10 MSKA MSKA MSKA MSKA 9 2 1 *
-0xEB18 MANI MANI MANI MANI 9 2 1 *
-0xEB28 MAN2 MAN2 MAN2 MAN2 9 2 1 *
-0xEB39 MBE1 MBE1 MBE1 MBE1 9 2 1 *
-0xEB49 MBE2 MBE2 MBE2 MBE2 9 2 1 *
-0xEB79 MLER MLER MLER MLER 9 2 1 *
-0xEC0B MWDR MWDR MWDR MWDR 9 2 1 *
-0xEC2B MSHE MSHE MSHE MSHE 9 2 1 *
-0xEC33 MCHI MCHI MCHI MCHI 9 2 1 *
-0xEC4B MDH1 MDH1 MDH1 MDH1 9 2 1 *
-0xEC5B MDH2 MDH2 MDH2 MDH2 9 2 1 *
-0xF008 MSKA MSKA MSKA MSKA 9 2 1 *
-0xED00 MYU1 MYU1 MYU1 MYU1 9 2 1 *
-0xF10E MYU1 MYU1 MYU1 MYU1 9 2 1 *
-0xED10 MYU2 MYU2 MYU2 MYU2 9 2 1 *
-0xF11E MYU2 MYU2 MYU2 MYU2 9 2 1 *
-0xED19 MGLA MGLA MGLA MGLA 9 2 1 *
-0xED20 MYU3 MYU3 MYU3 MYU3 9 2 1 *
-0xE8A1 MYU3 MYU3 MYU3 MYU3 9 2 1 *
-0xED28 MLEM MLEM MLEM MLEM 9 2 1 *
-0xEE08 MWEB MWEB MWEB MWEB 9 2 1 *
-0xEE18 MWRA MWRA MWRA MWRA 9 2 1 *
-0xEF0D MISA MISA MISA MISA 9 2 1 *
-0xEF28 MWOR MWOR MWOR MWOR 9 2 1 *
-0xEF50 MKG1 MKG1 MKG1 MKG1 9 2 1 *
-0xEF60 MKG2 MKG2 MKG2 MKG2 9 2 1 *
-0xEF70 MKG3 MKG3 MKG3 MKG3 9 2 1 *
-0xEF92 MWIL MWIL MWIL MWIL 9 2 1 *
-0xEFA3 MGEN MGEN MGEN MGEN 9 2 1 *
-0xEFB3 MGEN MGEN MGEN MGEN 9 3 1 *
-0xEFC3 MGEN MGEN MGEN MGEN 9 4 1 *
-0xEFD3 MGEN MGEN MGEN MGEN 9 5 1 *
-0xEFE3 MGEN MGEN MGEN MGEN 9 1 1 *
-0xEFF3 MGEN MGEN MGEN MGEN 9 6 1 *
-0xE708 MMIN MMIN MMIN MMIN 9 2 1 *
-0xE7D9 MMAL MMAL MMAL MMAL 9 2 1 *
-0xE8B9 MYUH MYUH MYUH MYUH 9 2 1 *
-0xEF1D MMAD MMAD MMAD MMAD 9 2 1 *
-0xF029 MWI4 MWI4 MWI4 MWI4 9 2 1 *
-0xF308 MGFI MGFI MGFI MGFI 9 4 1 *
-0xF40B MSAH MSAH MSAH MSAH 9 2 1 *
-0xF41B MSAT MSAT MSAT MSAT 9 2 1 *
-0xF50B MDRM MDRM MDRM MDRM 9 4 1 *
-0xF51B MDRF MDRF MDRF MDRF 9 4 1 *
-0xF77A MBA1 MBA1 MBA1 MBA1 9 2 1 *
-0xF78A MBA2 MBA2 MBA2 MBA2 9 2 1 *
-0xF798 MBA3 MBA3 MBA3 MBA3 9 2 1 *
diff --git a/gemrb/override/iwd2/bios.2da b/gemrb/override/iwd2/bios.2da
deleted file mode 100644
index 4a8fcad..0000000
--- a/gemrb/override/iwd2/bios.2da
+++ /dev/null
@@ -1,14 +0,0 @@
-2DA V1.0
-*
- CLASS BIO
-0 BARBARIAN 27862
-1 BARD 19425
-2 CLERIC 19422
-3 DRUID 19421
-4 FIGHTER 19423
-5 MONK 27860
-6 PALADIN 13427
-7 RANGER 19429
-8 ROGUE 19428
-9 SORCEROR 27863
-10 WIZARD 19430
diff --git a/gemrb/override/iwd2/bloodclr.2da b/gemrb/override/iwd2/bloodclr.2da
deleted file mode 100644
index 1b33a30..0000000
--- a/gemrb/override/iwd2/bloodclr.2da
+++ /dev/null
@@ -1,29 +0,0 @@
-2DA V1.0
-0
- VALUE MIN MAX
-NORMAL 0x2f 0x1000 0xffff
-PURPLE 0x2d 0x4300 0x43ff
-MSKEL 0x25 0x5403 0x5403
-DOOMG 0x22 0x5405 0x5406
-MSKEL 0x25 0x6403 0x6403
-DOOMG 0x22 0x6405 0x6406
-YELLOW 0x32 0x7300 0x73ff
-PURPLE 0x3c 0x7500 0x75ff
-YELLOW 0x32 0x7600 0x76ff
-BLACK 0x66 0x7700 0x77ff
-SLI_GR 7 0x7900 0x7900
-SLI_OL 0x24 0x7901 0x7901
-SLI_MU 0x33 0x7902 0x7902
-SLI_OC 0x25 0x7903 0x7903
-SLIME 0x1b 0x7904 0x7904
-SPIDER 0x33 0x7a00 0x7aff
-ZOMBIE 0x25 0x7c00 0x7cff
-MTRO 0x33 0x7f00 0x7f00
-MMIN 0x3d 0x7f01 0x7f03
-MIGO 0x1a 0x7f04 0x7f04
-MGLC 0x5d 0x7f07 0x7f07
-MTRS 0x32 0x7f0f 0x7f0f
-MBES 0x3d 0x7f15 0x7f15
-MCAR 0x38 0xa100 0xa1ff
-UNDEAD 0x66 0xe300 0xe3ff
-MWWE 0x38 0xef00 0xefff
diff --git a/gemrb/override/iwd2/classes.2da b/gemrb/override/iwd2/classes.2da
deleted file mode 100644
index e0fcf85..0000000
--- a/gemrb/override/iwd2/classes.2da
+++ /dev/null
@@ -1,38 +0,0 @@
-2DA V1.0
-*
- NAME_REF DESC_REF ID CLASS CLAB SAVE HP USABILITY HUMAN ELF HALF_ELF DWARF HALFLING GNOME HALFORC
-BARBARIAN 34 37 1 0 CLABFI05 SAVEWAR HPBARB 1 1 1 1 1 1 1 1
-BARD 1083 9562 2 0 CLABBA01 SAVEBRD HPBRD 2 1 1 1 1 1 1 1
-CLERIC 1079 9559 3 0 CLABPR01 SAVEPRS HPPRS 4 1 1 1 1 1 1 1
-DRUID 1080 9560 4 0 CLABDR01 SAVEPRS HPPRS 8 1 1 1 1 1 1 1
-FIGHTER 10174 9556 5 0 CLABFI01 SAVEWAR HPWAR 16 1 1 1 1 1 1 1
-MONK 33 36 6 0 CLABMO01 SAVEMONK HPMONK 32 1 1 1 1 1 1 1
-PALADIN 1078 9558 7 0 CLABPA01 SAVEWAR HPWAR 64 1 1 1 1 1 1 1
-RANGER 1077 9557 8 0 CLABRN01 SAVEWAR HPWAR 128 1 1 1 1 1 1 1
-ROGUE 1082 9561 9 0 CLABTH01 SAVEROG HPROG 256 1 1 1 1 1 1 1
-SORCERER 32 35 10 0 CLABSR01 SAVEWIZ HPWIZ 512 1 1 1 1 1 1 1
-WIZARD 9987 9563 11 0 CLABMA01 SAVEWIZ HPWIZ 1024 1 1 1 1 1 1 1
-PALADIN_ILMATER 36875 39407 1 7 CLABPA01 SAVEWAR HPWAR 1 1 1 1 1 1 1 1
-PALADIN_HELM 36872 39408 2 7 CLABPA01 SAVEWAR HPWAR 2 1 1 1 1 1 1 1
-PALADIN_MYSTRA 36873 39409 4 7 CLABPA01 SAVEWAR HPWAR 4 1 1 1 1 1 1 1
-MONK_OLD_ORDER 36877 39410 8 6 CLABMO01 SAVEMONK HPMONK 8 1 1 1 1 1 1 1
-MONK_BROKEN_ONES 36878 39411 0x10 6 CLABMO01 SAVEMONK HPMONK 16 1 1 1 1 1 1 1
-MONK_DARK_MOON 36879 39412 0x20 6 CLABMO01 SAVEMONK HPMONK 32 1 1 1 1 1 1 1
-MAGE_GENERALIST 9987 9563 0x4000 11 CLABMA01 SAVEWIZ HPWIZ 0x4000 1 1 1 1 1 1 1
-MAGE_ABJURER 502 9564 0x40 11 CLABMA02 SAVEWIZ HPWIZ 0x40 1 1 1 1 1 1 1
-MAGE_CONJURER 504 9565 0x80 11 CLABMA06 SAVEWIZ HPWIZ 0x80 1 1 1 1 1 1 1
-MAGE_DIVINER 2012 9566 0x100 11 CLABMA05 SAVEWIZ HPWIZ 0x100 1 1 1 1 1 1 1
-MAGE_ENCHANTER 2022 9567 0x200 11 CLABMA09 SAVEWIZ HPWIZ 0x200 1 1 1 1 1 1 1
-MAGE_EVOKER 12786 9569 0x800 11 CLABMA07 SAVEWIZ HPWIZ 0x400 1 1 1 1 1 1 1
-MAGE_ILLUSIONIST 12785 9568 0x400 11 CLABMA08 SAVEWIZ HPWIZ 0x800 1 1 1 1 1 1 1
-MAGE_NECROMANCER 12787 9570 0x1000 11 CLABMA03 SAVEWIZ HPWIZ 0x1000 1 1 1 1 1 1 1
-MAGE_TRANSMUTER 12788 9571 0x2000 11 CLABMA04 SAVEWIZ HPWIZ 0x2000 1 1 1 1 1 1 1
-CLERIC_ILMATER 38097 38118 0x8000 3 CLABCL01 SAVEPRS HPPRS 0x8000 1 1 1 1 1 1 1
-CLERIC_LATHANDER 38098 38119 0x10000 3 CLABCL02 SAVEPRS HPPRS 0x10000 1 1 1 1 1 1 1
-CLERIC_SELUNE 38099 38120 0x20000 3 CLABCL03 SAVEPRS HPPRS 0x20000 1 1 1 1 1 1 1
-CLERIC_HELM 38100 38121 0x40000 3 CLABCL04 SAVEPRS HPPRS 0x40000 1 1 1 1 1 1 1
-CLERIC_OGHMA 38101 38122 0x80000 3 CLABCL05 SAVEPRS HPPRS 0x80000 1 1 1 1 1 1 1
-CLERIC_TEMPUS 38102 38123 0x100000 3 CLABCL06 SAVEPRS HPPRS 0x100000 1 1 1 1 1 1 1
-CLERIC_BANE 38103 38124 0x200000 3 CLABCL07 SAVEPRS HPPRS 0x200000 1 1 1 1 1 1 1
-CLERIC_MASK 38106 38125 0x400000 3 CLABCL08 SAVEPRS HPPRS 0x400000 1 1 1 1 1 1 1
-CLERIC_TALOS 38107 38126 0x800000 3 CLABCL09 SAVEPRS HPPRS 0x800000 1 1 1 1 1 1 1
diff --git a/gemrb/override/iwd2/clskills.2da b/gemrb/override/iwd2/clskills.2da
deleted file mode 100644
index 3c0cf56..0000000
--- a/gemrb/override/iwd2/clskills.2da
+++ /dev/null
@@ -1,15 +0,0 @@
-2DA V1.0
-*
- HATERACE CLERICSPELL MAGESPELL STARTXP BARDSKILL THIEFSKILL LAYHANDS TURNLEVEL BOOKTYPE
-UNUSED * * * * 0 * * * 0 0
-BARBARIAN * * * 0 * SKILLS * 0 0
-BARD * * MXSPLBRD 0 SKILLBRD SKILLS * 0 1
-CLERIC * MXSPLPRS * 0 * SKILLS * 1 1
-DRUID * MXSPLDRU * 0 * SKILLS * 0 1
-FIGHTER * * * 0 * SKILLS * 0 0
-MONK * * * 0 * SKILLS * 0 0
-PALADIN * MXSPLPAL * 0 * SKILLS LAYHANDS 5 1
-RANGER HATERACE MXSPLRAN * 0 * SKILLS * 0 1
-ROGUE * * * 0 * SKILLS * 0 0
-SORCERER * * MXSPLSRC 0 * SKILLS * 0 2
-WIZARD * * MXSPLWIZ 0 * SKILLS * 0 1
diff --git a/gemrb/override/iwd2/damage.2da b/gemrb/override/iwd2/damage.2da
deleted file mode 100644
index cbb1b63..0000000
--- a/gemrb/override/iwd2/damage.2da
+++ /dev/null
@@ -1,16 +0,0 @@
-2DA V1.0
-*
- MAIN SPARKS GRADIENT
-CRIT BLOODCR * 47
-SMALL BLOODS * 47
-MEDIUM BLOODM * 47
-LARGE BLOODL * 47
-FIRES FIRIMP SPBURN 19
-FIREM FIRIMP SPBURN 19
-FIREL FIRIMP SPBURN 19
-SPARKS SPSHKIMP SPSPARKS -1
-SPARKM SPSHKIMP SPSPARKS -1
-SPARKL SPSHKIMP SPSPARKS -1
-ICES FIRIMP * 71
-ICEM FIRIMP * 71
-ICEL FIRIMP * 71
diff --git a/gemrb/override/iwd2/defsound.2da b/gemrb/override/iwd2/defsound.2da
deleted file mode 100644
index 22cfee3..0000000
--- a/gemrb/override/iwd2/defsound.2da
+++ /dev/null
@@ -1,29 +0,0 @@
-2DA V1.0
-*
- RESREF
-OPEN AMB_D03A
-CLOSE AMB_D03B
-HOPEN AMB_D04A
-HCLOSE AMB_D04B
-BUTTON1 GAM_09
-BUTTON2 GAM_03
-BUTTON3 GAM_04
-OPENFAIL *
-CLOSEFAIL *
-ITEM_GONE EFF_M02
-SECRET ACT_09
-11 *
-12 *
-13 *
-14 *
-15 *
-16 *
-17 *
-18 *
-19 *
-LIGHTNING1 AMB_E13A
-LIGHTNING2 AMB_E13B
-LIGHTNING3 AMB_E13F
-RAIN AMB_E11
-SNOW AMB_E02B
-
diff --git a/gemrb/override/iwd2/effects.ids b/gemrb/override/iwd2/effects.ids
deleted file mode 100644
index 3aeb09f..0000000
--- a/gemrb/override/iwd2/effects.ids
+++ /dev/null
@@ -1,356 +0,0 @@
-IDS
-0x0 ACVsDamageTypeModifierIWD2
-0x1 AttacksPerRoundModifier
-0x2 Cure:Sleep
-0x3 State:Berserk
-0x4 Cure:Berserk
-0x5 State:Charmed
-0x6 CharismaModifier
-0x7 Color:SetPalette
-0x8 Color:SetRGB
-0x9 Color:PulseRGB
-0xa ConstitutionModifier
-0xb Cure:Poison
-0xc Damage
-0xd Death
-0xe Cure:Defrost
-0xf DexterityModifier
-0x10 State:Hasted
-0x11 CurrentHPModifier
-0x12 MaximumHPModifier
-0x13 IntelligenceModifier
-0x14 State:Invisible
-0x15 LoreModifier
-0x16 LuckModifier
-0x17 MoraleModifier
-0x18 State:Panic
-0x19 State:Poisoned
-0x1a RemoveCurse
-0x1b AcidResistanceModifier
-0x1c ColdResistanceModifier
-0x1d ElectricityResistanceModifier
-0x1e FireResistanceModifier
-0x1f MagicDamageResistanceModifier
-0x20 Cure:Death
-0x21 SaveVsDeathModifier
-0x22 SaveVsWandsModifier
-0x23 SaveVsPolyModifier
-0x24 SaveVsBreathModifier
-0x25 SaveVsSpellsModifier
-0x26 State:Silenced
-0x27 State:Helpless
-0x28 State:Slowed
-0x29 Sparkle
-0x2a WizardSpellSlotsModifier
-0x2b Cure:Petrification
-0x2c StrengthModifier
-0x2d State:Stun
-0x2e Cure:Stun
-0x2f Cure:Invisible
-0x30 Cure:Silence
-0x31 WisdomModifier
-0x32 Color:BriefRGB
-0x33 Color:DarkenRGB
-0x34 Color:GlowRGB
-0x35 AnimationIDModifier
-0x36 ToHitModifier
-0x37 KillCreatureType
-0x38 Alignment:Invert
-0x39 Alignment:Change
-0x3a DispelEffects
-0x3b StealthModifier
-0x3c MiscastMagicModifier
-0x3d AlchemyModifier
-0x3e PriestSpellSlotsModifier
-0x3f State:Infravision
-0x40 Cure:Infravision
-0x41 State:Blur
-0x42 TransparencyModifier
-0x43 SummonCreature
-0x44 UnsummonCreature
-0x45 State:NonDetection
-0x46 Cure:NonDetection
-0x47 SexModifier
-0x48 AIIdentifierModifier
-0x49 DamageBonusModifier
-0x4a State:Blind
-0x4b Cure:Blind
-0x4c State:Feeblemind
-0x4d Cure:Feeblemind
-0x4e State:Diseased
-0x4f Cure:Disease
-0x50 State:Deafness
-0x51 Cure:Deafness
-0x52 SetAIScript
-0x53 Protection:Projectile
-0x54 MagicalFireResistanceModifier
-0x55 MagicalColdResistanceModifier
-0x56 SlashingResistanceModifier
-0x57 CrushingResistanceModifier
-0x58 PiercingResistanceModifier
-0x59 MissilesResistanceModifier
-0x5a OpenLocksModifier
-0x5b FindTrapsModifier
-0x5c PickPocketsModifier
-0x5d FatigueModifier
-0x5e IntoxicationModifier
-0x5f TrackingModifier
-0x60 LevelModifier
-0x61 StrengthBonusModifier
-0x62 State:Regenerating
-0x63 SpellDurationModifier
-0x64 Protection:Creature
-0x65 Protection:Opcode
-0x66 Protection:SpellLevel
-0x67 ChangeName
-0x68 ExperienceModifier
-0x69 GoldModifier
-0x6a MoraleBreakModifier
-0x6b PortraitChange
-0x6c ReputationModifier
-0x6d State:Hold3
-0x6e RetreatFrom
-0x6f Item:CreateMagic
-0x70 Item:Remove
-0x71 Item:Equip
-0x72 Dither
-0x73 DetectAlignment
-0x74 Cure:Invisible2
-0x75 Reveal:Area
-0x76 Reveal:Creatures
-0x77 MirrorImage
-0x78 Protection:Weapons
-0x79 VisualAnimationEffect
-0x7a Item:CreateInventory
-0x7b Item:RemoveInventory
-0x7c DimensionDoor
-0x7d Unlock
-0x7e MovementRateModifier
-0x7f MonsterSummoning
-0x80 State:Confused
-0x81 AidNonCumulative
-0x82 BlessNonCumulative
-0x83 ChantNonCumulative
-0x84 DrawUponHolyMight
-0x85 LuckCumulative
-0x86 State:Petrification
-0x87 Polymorph
-0x88 ForceVisible
-0x89 ChantBadNonCumulative
-0x8a AnimationStateChange
-0x8b DisplayString
-0x8c CastingGlow
-0x8d VisualSpellHit
-0x8e Icon:Display
-0x8f Item:CreateInSlot
-0x90 DisableButton
-0x91 DisableCasting
-0x92 Spell:Cast
-0x93 Spell:Learn
-0x94 Spell:CastPoint
-0x95 Identify
-0x96 FindTraps
-0x97 ReplaceCreature
-0x98 PlayMovie
-0x99 Overlay:Sanctuary
-0x9a Overlay:Entangle
-0x9b Overlay:MinorGlobe
-0x9c Overlay:ShieldGlobe
-0x9d Overlay:Web
-0x9e Overlay:Grease
-0x9f MirrorImageModifier
-0xa0 Cure:Sanctuary
-0xa1 Cure:Panic
-0xa2 Cure:Hold
-0xa3 FreeAction
-0xa4 Cure:Intoxication
-0xa5 PauseTarget
-0xa6 MagicResistanceModifier
-0xa7 MissileHitModifier
-0xa8 RemoveCreature
-0xa9 Icon:Disable
-0xaa DamageAnimation
-0xab Spell:Add
-0xac Spell:Remove
-0xad PoisonResistanceModifier
-0xae PlaySound
-0xaf State:Hold
-0xb0 MovementRateModifier2
-0xb1 ApplyEffect
-0xb2 ToHitVsCreature
-0xb3 DamageVsCreature
-0xb4 CantUseItem
-0xb5 CantUseItemType
-0xb6 ApplyEffectItem
-0xb7 ApplyEffectItemType
-0xb8 DontJumpModifier
-0xb9 State:Hold2
-0xba MoveToArea
-0xbb Variable:StoreLocalVariable
-0xbc AuraCleansingModifier
-0xbd CastingSpeedModifier
-0xbe AttackSpeedModifier
-0xbf CastingLevelModifier
-0xc0 FindFamiliar
-0xc1 InvisibleDetection
-0xc2 IgnoreDialogPause
-0xc3 FamiliarBond
-0xc4 FamiliarMarker
-0xc5 Bounce:Projectile
-0xc6 Bounce:Opcode
-0xc7 Bounce:SpellLevel
-0xc8 Bounce:SpellLevelDec
-0xc9 Protection:SpellLevelDec
-0xca Bounce:School
-0xcb Bounce:SecondaryType
-0xcc Protection:School
-0xcd Protection:SecondaryType
-0xce Protection:Spell2
-0xcf Bounce:Spell
-0xd0 MinimumHPModifier
-0xd1 PowerWordKill
-0xd2 PowerWordStun
-0xd3 State:Imprisonment
-0xd4 Cure:Imprisonment
-0xd5 Maze
-0xd6 CastFromList
-0xd7 PlayVisualEffect
-0xd8 LevelDrainModifier
-0xd9 PowerWordSleep
-0xda IronSkins
-0xdb ACVsCreatureType
-0xdc DispelSchool
-0xdd DispelSecondaryType
-0xde RandomTeleport
-0xdf Protection:SchoolDec
-0xe0 Cure:LevelDrain
-0xe1 Reveal:Magic
-0xe2 Protection:SecondaryTypeDec
-0xe3 Bounce:SchoolDec
-0xe4 Bounce:SecondaryTypeDec
-0xe5 DispelSchoolOne
-0xe6 DispelSecondaryTypeOne
-0xe7 TimeStop
-0xe8 Color:FadeRGB
-0xe9 IWDVisualSpellHit
-0xea ColdDamage
-0xeb CastingGlow2
-0xec ChillTouchPanic
-0xed CrushingDamage
-0xee SaveBonus
-0xef SlowPoison
-0xf0 IWDMonsterSummoning
-0xf1 VampiricTouch
-0xf2 Overlay
-0xf3 AnimateDead
-0xf4 Prayer2
-0xf5 Curse2
-0xf6 SummonMonster2
-0xf7 BurningBlood
-0xf8 SummonShadowMonster
-0xf9 Recitation
-0xfa RecitationBad
-0xfb State:HoldNoIcon2
-0xfc BlindingOrb
-0xfd ACVsDamageTypeModifier2
-0xfe RemoveEffects
-0xff SalamanderAura
-0x100 UmberHulkGaze
-0x101 ZombieLordAura
-0x102 Protection:Spell
-0x103 SummonCreature2
-0x104 AvatarRemoval
-0x105 Protection:Opcode2
-0x106 SummonPomab
-0x107 ControlUndead
-0x108 StaticCharge
-0x109 CloakOfFear
-0x10a MovementRateModifier3
-0x10b Cure:Confusion
-0x10c EyeOfTheMind
-0x10d EyeOfTheSword
-0x10e EyeOfTheMage
-0x10f EyeOfVenom
-0x110 EyeOfTheSpirit
-0x111 EyeOfFortitude
-0x112 EyeOfStone
-0x113 RemoveSevenEyes
-0x114 RemoveEffect
-0x115 SoulEater
-0x116 ShroudOfFlame
-0x117 AnimalRage
-0x118 TurnUndead
-0x119 VitriolicSphere
-0x11a SuppressHP
-0x11b FloatText
-0x11c MaceOfDisruption
-0x11d State:Sleep
-0x11e Reveal:Tracks
-0x11f Protection:Backstab
-0x120 State:Set
-0x121 Cutscene
-0x122 Protection:Spell3
-0x123 RodOfSmithing
-0x124 MagicalRest
-0x125 BeholderDispelMagic
-0x126 HarpyWail
-0x127 JackalWereGaze
-0x128 ModifyGlobalVariable
-0x129 HideInShadowsModifier
-0x12a UseMagicDeviceModifier
-400 Hopelessness
-401 ProtectionFromEvil
-402 AddEffectsList
-403 ArmorOfFaith
-404 Nausea
-405 Enfeeblement
-406 FireShield
-407 DeathWard
-408 HolyPower
-409 RighteousWrath
-410 SummonAlly
-411 SummonEnemy
-412 Control2
-413 VisualEffectIWD2
-414 ResilientSphere
-415 Barkskin
-416 BleedingWounds
-417 AreaEffect
-418 FreeAction2
-419 Unconsciousness
-420 Death2
-421 EntropyShield
-422 StormShell
-423 ProtectionFromElements
-424 State:HoldNoIcon3
-425 ControlUndead2
-426 Aegis
-427 ExecutionerEyes
-428 Death3
-429 EffectsOnStruck
-430 ProjectileUseEffectList
-431 EnergyDrain
-432 TortoiseShell
-433 Blink
-434 PersistentUseEffectList
-435 DayBlindness
-436 DamageReduction
-437 Disguise
-438 HeroicInspiration
-439 OffscreenAIModifier
-440 BarbarianRage
-441 MovementRateModifier4
-443 MissileDamageReduction
-444 TensersTransformation
-446 SmiteEvil
-447 Restoration
-448 AlicornLance
-449 CallLightning
-450 GlobeInvulnerability
-451 LowerResistance
-452 Bane
-453 PowerAttack
-454 Expertise
-455 ArterialStrike
-456 Hamstring
-457 RapidShot
diff --git a/gemrb/override/iwd2/efftext.2da b/gemrb/override/iwd2/efftext.2da
index 6044889..c427e7a 100644
--- a/gemrb/override/iwd2/efftext.2da
+++ b/gemrb/override/iwd2/efftext.2da
@@ -2,7 +2,7 @@
-1
EFFECT_NAME STRREF
13 DEATH 14026
-12 DAMAGE 14027
+#12 DAMAGE 14027
68 UNSUMMON 14065
132 DRAWUPONHOLY 14125
400 HOPELESSNESS 1280
diff --git a/gemrb/override/iwd2/featreq.2da b/gemrb/override/iwd2/featreq.2da
deleted file mode 100644
index 06ebb23..0000000
--- a/gemrb/override/iwd2/featreq.2da
+++ /dev/null
@@ -1,79 +0,0 @@
-2DA V1.0
-4
- MULTIPLE MAX_LEVEL A_STAT A_VALUE B_STAT B_VALUE C_STAT C_VALUE D_STAT D_VALUE A_OP B_OP C_OP D_OP
-AEGIS_OF_RIME 0 1 SPELLCRAFT 10 0 0 CLASSLEVELMAGE 7 CLASSLEVELSORCEROR 7 * * * *
-AMBIDEXTERITY 0 1 DEX 15 0 0 0 0 0 0 * * * *
-AQUA_MORTIS 0 1 SPELLCRAFT 10 0 0 CLASSLEVELMAGE 7 CLASSLEVELSORCEROR 7 * * * *
-ARMOR_PROF FEAT_ARMOUR 3 0 0 0 0 0 0 0 0 * * * *
-ARMORED_ARCANA FEAT_ARMORED_ARCANA 3 CLASSLEVELMAGE 1 CLASSLEVELSORCEROR 1 0 0 0 0 * * * *
-ARTERIAL_STRIKE 0 1 CLASSLEVELTHIEF 1 0 0 HITBONUS 4 0 0 * * * *
-BLIND_FIGHT 0 1 0 0 0 0 0 0 0 0 * * * *
-BULLHEADED 0 1 RACE 1 RACE 4 0 0 0 0 1 1 * *
-CLEAVE FEAT_CLEAVE 2 HITBONUS 4 FEAT_CLEAVE 1 FEATS2 32 0 0 * 0 8 *
-COMBAT_CASTING 0 1 0 0 0 0 0 0 0 0 * * * *
-COURTEOUS_MAGOCRACY 0 1 0 0 0 0 0 0 0 0 * * * *
-CRIPPLING_STRIKE 0 1 CLASSLEVELTHIEF 10 0 0 0 0 0 0 * * * *
-DASH 0 1 0 0 0 0 0 0 0 0 * * * *
-DEFLECT_ARROWS 0 1 DEX 13 0 0 0 0 0 0 * * * *
-DIRTY_FIGHTING 0 1 DEX 13 0 0 HITBONUS 2 0 0 * * * *
-DISCIPLINE 0 1 0 0 0 0 0 0 0 0 * * * *
-DODGE 0 1 DEX 13 0 0 0 0 0 0 * * * *
-ENVENOM_WEAPON 0 1 CLASSLEVELTHIEF 1 0 0 ALCHEMY 8 0 0 * * * *
-EXOTIC_BASTARD FEAT_BASTARDSWORD 3 0 0 0 0 0 0 0 0 * * * *
-EXPERTISE 0 1 INT 13 0 0 0 0 0 0 * * * *
-EXTRA_RAGE FEAT_EXTRA_RAGE 3 CLASSLEVELBARBARIAN 1 0 0 0 0 0 0 * * * *
-EXTRA_SHAPESHIFTING FEAT_EXTRA_SHAPE 3 CLASSLEVELDRUID 3 0 0 0 0 0 0 * * * *
-EXTRA_SMITING FEAT_EXTRA_SMITING 3 CLASSLEVELPALADIN 2 0 0 0 0 0 0 * * * *
-EXTRA_TURNING FEAT_EXTRA_TURNING 3 TURNUNDEADLEVEL 1 0 0 0 0 0 0 * * * *
-FIENDSLAYER 0 1 CLASSLEVELPALADIN 8 0 0 FEAT_LARGE_SWORD 2 FEAT_GREAT_SWORD 2 * * * *
-FORESTER 0 1 0 0 0 0 0 0 0 0 * * * *
-GREAT_FORTITUDE 0 1 0 0 0 0 0 0 0 0 * * * *
-HAMSTRING 0 1 CLASSLEVELTHIEF 3 0 0 0 0 0 0 * * * *
-HERETICS_BANE 0 1 CLASSLEVELCLERIC 1 CLASSLEVELPALADIN 3 HITBONUS 4 0 0 * * * *
-HEROIC_INSPIRATION 0 1 AnyOfThreeGE -1 CLASSLEVELPALADIN 1 CLASSLEVELBARBARIAN 1 CLASSLEVELBARD 1 * * * *
-IMPROVED_CRITICAL 0 1 HITBONUS 8 0 0 0 0 0 0 * * * *
-IMPROVED_EVASION 0 1 CLASSLEVELTHIEF 10 0 0 0 0 0 0 * * * *
-IMPROVED_INITIATIVE 0 1 0 0 0 0 0 0 0 0 * * * *
-IMPROVED_TURNING 0 1 CLASSLEVELCLERIC 1 0 0 CLASSLEVELPALADIN 3 0 0 * * * *
-IRON_WILL 0 1 0 0 0 0 0 0 0 0 * * * *
-LIGHTNING_REFLEXES 0 1 0 0 0 0 0 0 0 0 * * * *
-LINGERING_SONG 0 1 CLASSLEVELBARD 1 0 0 0 0 0 0 * * * *
-LUCK_OF_HEROES 0 1 RACE 1 0 0 0 0 0 0 1 * * *
-MARTIAL_AXE FEAT_AXE 3 CLASSLEVELFIGHTER 4 FEAT_AXE 2 0 0 0 0 * 0 * *
-MARTIAL_BOW FEAT_BOW 3 CLASSLEVELFIGHTER 4 FEAT_BOW 2 0 0 0 0 * 0 * *
-MARTIAL_FLAIL FEAT_FLAIL 3 CLASSLEVELFIGHTER 4 FEAT_FLAIL 2 0 0 0 0 * 0 * *
-MARTIAL_GREATSWORD FEAT_GREAT_SWORD 3 CLASSLEVELFIGHTER 4 FEAT_GREAT_SWORD 2 0 0 0 0 * 0 * *
-MARTIAL_HAMMER FEAT_HAMMER 3 CLASSLEVELFIGHTER 4 FEAT_HAMMER 2 0 0 0 0 * 0 * *
-MARTIAL_LARGESWORD FEAT_LARGE_SWORD 3 CLASSLEVELFIGHTER 4 FEAT_LARGE_SWORD 2 0 0 0 0 * 0 * *
-MARTIAL_POLEARM FEAT_POLEARM 3 CLASSLEVELFIGHTER 4 FEAT_POLEARM 2 0 0 0 0 * 0 * *
-MAXIMIZED_ATTACKS 0 1 MaximizedAttacks -1 CONCENTRATION 4 0 0 0 0 * * * *
-MERCANTILE_BACKGROUND 0 1 AnyOfThree -1 SUBRACE 0x40002 SUBRACE 0x60002 RACE 1 * * * *
-POWER_ATTACK 0 1 STR 13 0 0 0 0 0 0 * * * *
-PRECISE_SHOT 0 1 0 0 0 0 0 0 0 0 * * * *
-RAPID_SHOT 0 1 DEX 13 0 0 0 0 0 0 * * * *
-RESIST_POISON 0 1 CLASSLEVELSUM 1 0 0 SUBRACE 0x40002 RACE 7 1 * 1 1
-SCION_OF_STORMS 0 1 SPELLCRAFT 10 0 0 CLASSLEVELMAGE 7 CLASSLEVELSORCEROR 7 * * * *
-SHIELD_PROF 0 1 0 0 0 0 0 0 0 0 * * * *
-SIMPLE_CROSSBOW FEAT_CROSSBOW 3 CLASSLEVELFIGHTER 4 FEAT_CROSSBOW 2 0 0 0 0 * 0 * *
-SIMPLE_MACE FEAT_MACE 3 CLASSLEVELFIGHTER 4 FEAT_MACE 2 0 0 0 0 * 0 * *
-SIMPLE_MISSILE FEAT_SLING 3 CLASSLEVELFIGHTER 4 FEAT_SLING 2 0 0 0 0 * 0 * *
-SIMPLE_QUARTERSTAFF FEAT_STAFF 3 CLASSLEVELFIGHTER 4 FEAT_STAFF 2 0 0 0 0 * 0 * *
-SIMPLE_SMALLBLADE FEAT_SMALL_SWORD 3 CLASSLEVELFIGHTER 4 FEAT_SMALL_SWORD 2 0 0 0 0 * 0 * *
-SLIPPERY_MIND 0 1 CLASSLEVELTHIEF 10 0 0 0 0 0 0 * * * *
-SNAKE_BLOOD 0 1 RACE 1 0 0 CLASSLEVELSUM 1 0 0 1 * 1 *
-SPELL_FOCUS_ENCHANTMENT FEAT_ENCHANTMENT 2 0 0 0 0 0 0 0 0 * * * *
-SPELL_FOCUS_EVOCATION FEAT_EVOCATION 2 0 0 0 0 0 0 0 0 * * * *
-SPELL_FOCUS_NECROMANCY FEAT_NECROMANCY 2 0 0 0 0 0 0 0 0 * * * *
-SPELL_FOCUS_TRANSMUTE FEAT_TRANSMUTE 2 0 0 0 0 0 0 0 0 * * * *
-SPELL_PENETRATION FEAT_SPELL_PENETRATION 2 0 0 0 0 0 0 0 0 * * * *
-SPIRIT_OF_FLAME 0 1 SPELLCRAFT 10 0 0 CLASSLEVELMAGE 7 CLASSLEVELSORCEROR 7 * * * *
-STRONG_BACK 0 1 0 0 0 0 0 0 0 0 * * * *
-STUNNING_FIST 0 1 AllOfThreeGE -1 DEX 13 WIS 13 HITBONUS 8 * * * *
-SUBVOCAL_CASTING 0 1 IsCaster -1 0 0 0 0 0 0 * * * *
-TOUGHNESS FEAT_TOUGHNESS 5 0 0 0 0 0 0 0 0 * * * *
-TWO_WEAPON_FIGHTING 0 1 0 0 0 0 0 0 0 0 * * * *
-WEAPON_FINESSE 0 1 FEAT_SMALL_SWORD 1 0 0 HITBONUS 1 0 0 * * * *
-WILDSHAPE_BOAR 0 1 CLASSLEVELDRUID 5 0 0 0 0 0 0 * * * *
-WILDSHAPE_PANTHER 0 1 CLASSLEVELDRUID 5 0 0 0 0 0 0 * * * *
-WILDSHAPE_SHAMBLER 0 1 CLASSLEVELDRUID 8 0 0 0 0 0 0 * * * *
-
diff --git a/gemrb/override/iwd2/fireball.pro b/gemrb/override/iwd2/fireball.pro
deleted file mode 100644
index 4acc632..0000000
Binary files a/gemrb/override/iwd2/fireball.pro and /dev/null differ
diff --git a/gemrb/override/iwd2/fistweap.2da b/gemrb/override/iwd2/fistweap.2da
deleted file mode 100644
index 3fe215a..0000000
--- a/gemrb/override/iwd2/fistweap.2da
+++ /dev/null
@@ -1,4 +0,0 @@
-2DA V1.0
-00FIST
- 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
-MONK 00MFIST1 00MFIST1 00MFIST2 00MFIST2 00MFIST2 00MFIST3 00MFIST3 00MFIST3 00MFIST4 00MFIST4 00MFIST4 00MFIST5 00MFIST5 00MFIST5 00MFIST6 00MFIST6 00MFIST6 00MFIST7 00MFIST7 00MFIST7 00MFIST7 00MFIST7 00MFIST7 00MFIST7 00MFIST8 00MFIST8 00MFIST8 00MFIST8 00MFIST8 00MFIST8 00MFIST9
diff --git a/gemrb/override/iwd2/fonts.2da b/gemrb/override/iwd2/fonts.2da
deleted file mode 100644
index 031b409..0000000
--- a/gemrb/override/iwd2/fonts.2da
+++ /dev/null
@@ -1,19 +0,0 @@
-2DA V1.0
-NORMAL
- RESREF NEED_PALETTE FIRST_CHAR
-0 NORMAL 1 0
-1 INFOFONT 1 0
-2 NUMBER 0 47
-3 INITIALS 0 0
-4 NUMBER2 0 47
-5 NUMBER3 0 47
-6 NUMFONT 1 0
-7 REALMS 0 0
-8 REALMS2 1 0
-9 STONEBIG 0 0
-10 STONESM2 0 0
-11 STONESM3 0 0
-12 STONESML 0 0
-13 TOOLFONT 1 0
-14 STATES 0 0
-14 STATES2 0 0
diff --git a/gemrb/override/iwd2/gametime.2da b/gemrb/override/iwd2/gametime.2da
deleted file mode 100644
index 2d29d2c..0000000
--- a/gemrb/override/iwd2/gametime.2da
+++ /dev/null
@@ -1,5 +0,0 @@
-2DA V1.0
-0
- DURATION
-ROUND_SECONDS 7
-TURN_SECONDS 70
diff --git a/gemrb/override/iwd2/gemrb.ini b/gemrb/override/iwd2/gemrb.ini
deleted file mode 100644
index b619c47..0000000
--- a/gemrb/override/iwd2/gemrb.ini
+++ /dev/null
@@ -1,98 +0,0 @@
-; GemRB - Infinity Engine Emulator
-; Copyright (C) 2003 The GemRB Project
-;
-; This program is free software; you can redistribute it and/or
-; modify it under the terms of the GNU General Public License
-; as published by the Free Software Foundation; either version 2
-; of the License, or (at your option) any later version.
-;
-; This program is distributed in the hope that it will be useful,
-; but WITHOUT ANY WARRANTY; without even the implied warranty of
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-; GNU General Public License for more details.
-;
-; You should have received a copy of the GNU General Public License
-; along with this program; if not, write to the Free Software
-; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-;
-
-
-; gemrb.ini - game type-specific settings for GemRB engine
-
-[resources]
-
-; Bitmap resource for cursors
-CursorBAM = CAROT
-
-; Bitmap resource for scroll cursor arrow
-ScrollCursorBAM = CURSARW
-
-; Bitmap resource for dialog buttons font
-ButtonFont = NORMAL
-
-; Font used to display tooltips
-TooltipFont = TOOLFONT
-
-; Sprite displayed behind the tooltip text, if any
-TooltipBack = TOOLTIP
-
-; Tooltip text color (RGBA)
-TooltipColor = #ffffffff
-
-; Space between tooltip text and sides of TooltipBack (x2)
-TooltipMargin = 2
-#TooltipMargin = 20
-
-; INI file from the original games
-INIConfig = icewind2.ini
-
-; Palette bitmaps in various widths
-Palette16 = MPALETTE
-Palette32 = MPALETTE
-Palette256 = MPAL256
-
-MaximumAbility = 40
-IgnoreButtonFrames = 0
-AllStringsTagged = 1
-HasDPLAYER = 1
-HasPickSound = 0
-HasDescIcon = 0
-HasEXPTABLE = 1
-SoundFolders = 1
-HasSongList = 0
-HasSpellList = 1
-UpperButtonText = 0
-LowerLabelText = 0
-HasPartyINI = 1
-HasBeastsINI = 0
-ForceStereo = 0
-IWDMapDimensions = 1
-SmallFog = 0
-IWD2ScriptName = 1
-DialogueScrolls = 0
-KnowWorld = 1
-ReverseToHit = 0
-CharNameIsGabber = 1
-MagicBit = 1
-ChallengeRating = 1
-DeathOnZeroStat = 0
-SpawnIni = 1
-IWD2DeathVarFormat = 1
-OverrideCursorPos = 1
-EnhancedEffects = 1
-BreakableWeapons = 0
-3EdRules = 1
-LevelslotPerClass = 1
-SelectiveMagicRes = 1
-HasHideInShadows = 1
-AreaVisitedVar = 1
-ProperBackstab = 1
-HasSpecificDamageBonus = 1
-StrrefSaveGame = 1
-BiographyIsRes = 1
-CutsceneAreascripts = 0
-FlexibleWorldmap = 1
-AutoSearchHidden = 0
-PSTStateFlags = 0
-CastingSounds = 1
-ForceAreaScript = 1
diff --git a/gemrb/override/iwd2/guibtact.2da b/gemrb/override/iwd2/guibtact.2da
deleted file mode 100644
index 9749e6c..0000000
--- a/gemrb/override/iwd2/guibtact.2da
+++ /dev/null
@@ -1,30 +0,0 @@
-2DA V1.0
-guibtact
- 1 2 3 4 TOOLTIP RESREF
-Stealth 28 29 30 31 4968 guibtact
-Thieving 24 25 26 27 4971 guibtact
-Cast 8 9 10 11 4688 guibtact
-QSpell1 0 1 24 25 4938 guibtbut
-QSpell2 2 3 26 27 4938 guibtbut
-QSpell3 4 5 28 29 4938 guibtbut
-Turn 0 0 0 0 0 guibtact
-Talk 0 0 0 0 0 guibtact
-UseItem 16 17 18 19 4978 guibtact
-QItem1 0 1 24 25 4937 guibtbut
-QItem4 2 3 26 27 4937 guibtbut
-QItem2 4 5 28 29 4937 guibtbut
-QItem3 6 7 30 31 4937 guibtbut
-Innate 40 41 42 43 4954 guibtact
-Defend 0 1 2 3 15925 guibtact
-Attack 12 13 14 15 4666 guibtact
-QWeapon1 0 1 24 25 4950 guibtbut
-QWeapon2 2 3 26 27 4950 guibtbut
-QWeapon3 4 5 28 29 4950 guibtbut
-QWeapon4 6 7 30 31 4950 guibtbut
-BardSong 20 21 22 23 4918 guibtact
-Stop 44 45 46 47 15924 guibtact
-Search 36 37 38 39 4927 guibtact
-ShapeChange 0 0 0 0 4958 guibtact
-Taming 124 125 126 127 4974 guibtact
-Skills 96 97 98 99 4933 guibtact
-Wilderness 92 93 94 95 32186 guibtact
diff --git a/gemrb/override/iwd2/itemsnd.2da b/gemrb/override/iwd2/itemsnd.2da
deleted file mode 100644
index 9678ee9..0000000
--- a/gemrb/override/iwd2/itemsnd.2da
+++ /dev/null
@@ -1,80 +0,0 @@
-2DA V1.0
-*
- TAKE DROP
-AMULET G_NECK1 G_NECK2
-ARMOR G_CLOAK1 G_CLOAK2
-BELT G_BELT1 G_BELT2
-BOOT G_BOOT1 G_BOOT2
-ARROW G_ARRW1 G_ARRW2
-BRACER G_GLOVE1 G_GLOVE2
-HELMET G_HELM1 G_HELM2
-KEY G_KEY1 G_KEY2
-POTION G_POTN1 G_POTN2
-RING G_RING1 G_RING2
-SCROLL G_SCROL1 G_SCROL2
-SHIELD GAM_21A GAM_21B
-FOOD GAM_21A GAM_21B
-BULLET G_BULLT1 G_BULLT2
-BOW G_BOW1 G_BOW2
-DAGGER G_DAGGR1 G_DAGGR2
-MACE G_MACE1 G_MACE2
-SLING G_SLING1 G_SLING2
-SMSWORD G_SMSWD1 G_SMSWD2
-BGSWORD G_LGSWD1 G_LGSWD2
-HAMMER G_HAMMR1 G_HAMMR2
-MSTAR G_MSTAR1 G_MSTAR2
-FLAIL G_FLAIL1 G_FLAIL2
-DART G_DART1 G_DART2
-AXE G_AXE1 G_AXE2
-STAFF G_STAFF1 G_STAFF2
-XBOW G_CROSB1 G_CROSB2
-FIST GAM_21A GAM_21B
-SPEAR G_SPEAR1 G_SPEAR2
-POLEARM G_HALB1 G_HALB2
-BOLT G_BOLT1 G_BOLT2
-CLOAK G_CLOAK1 G_CLOAK2
-COIN G_GOLD1 G_GOLD2
-GEM G_GEM1 G_GEM2
-WAND G_WAND1 G_WAND2
-BROKEN1 G_B_ARM1 G_B_ARM2
-BROKEN2 G_B_SHD1 G_B_SHD2
-BROKEN3 G_B_WPN1 G_B_WPN2
-UNUSED1 GAM_21A GAM_21B
-UNUSED2 G_BROKN1 G_BROKN2
-BUCKLER G_BUCKR1 G_BUCKR2
-CANDLE G_CAND1 G_CAND2
-CBODY G_CHILD1 G_CHILD2
-CLUB G_CLUB1 G_CLUB2
-FBODY G_FEM1 G_FEM2
-KEY2 G_KEYS1 G_KEYS2
-LSHIELD G_LGSLD1 G_LGSLD2
-MBODY G_MALE1 G_MALE2
-MSHIELD G_MDSLD1 G_MDSLD2
-NOTES G_PAPR1 G_PAPR2
-ROD G_ROD1 G_ROD2
-SKULL G_SKULL1 G_SKULL2
-SSHIELD G_SMSLD1 G_SMSLD2
-SPIDER G_SPIDR1 G_SPIDR2
-TELESCOPE G_TELE1 G_TELE2
-DRINK G_WINE1 G_WINE2
-GTSWORD G_LGSWD1 G_LGSWD2
-BAG GAM_21A GAM_21B
-FUR G_LETHR1 G_LETHR2
-LARMOR G_CLOAK1 G_CLOAK2
-SLARMOR G_CLOAK1 G_CLOAK2
-CHARMOR G_CLOAK1 G_CLOAK2
-SPARMOR G_CLOAK1 G_CLOAK2
-HPARMOR G_CLOAK1 G_CLOAK2
-FPARMOR G_CLOAK1 G_CLOAK2
-HARMOR G_CLOAK1 G_CLOAK2
-ROBE G_CLOAK1 G_CLOAK2
-SCALE G_CLOAK1 G_CLOAK2
-BTSWORD G_LGSWD1 G_LGSWD2
-SCARF G_GLOVE1 G_GLOVE2
-FOOD2 G_SLING1 G_SLING2
-HAT G_GLOVE1 G_GLOVE2
-GAUNTLET G_CAND1 G_CAND2
-DEFAULT GAM_21A GAM_21B
-LEATHER G_LETHR1 G_LETHR2
-CHAIN G_Chain1 G_Chain2
-PLATE G_Plate1 G_Plate2
diff --git a/gemrb/override/iwd2/itemtype.2da b/gemrb/override/iwd2/itemtype.2da
deleted file mode 100644
index 6bb5e72..0000000
--- a/gemrb/override/iwd2/itemtype.2da
+++ /dev/null
@@ -1,77 +0,0 @@
-2DA V1.0
-0
- HELMET ARMOR SHIELD GLOVES RING AMULET BELT BOOTS WEAPON QUIVER CLOAK QUICK SCROLL BAG POTION
-BOOK 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
-AMULET 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
-ARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-BELT 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
-BOOT 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
-ARROW 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
-BRACER 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
-HELMET 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-KEY 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-POTION 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
-RING 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
-SCROLL 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0
-SHIELD 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
-FOOD 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
-BULLET 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
-BOW 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-DAGGER 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-MACE 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-SLING 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-SMSWORD 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-BGSWORD 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-HAMMER 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-MSTAR 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-FLAIL 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-DART 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-AXE 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-STAFF 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-XBOW 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-FIST 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-SPEAR 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-POLEARM 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-BOLT 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
-CLOAK 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
-COIN 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-GEM 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
-WAND 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
-BROKEN1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-BROKEN2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-BROKEN3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-UNUSED1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-UNUSED2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-BUCKLER 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
-CANDLE 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
-CBODY 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-CLUB 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-FBODY 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-KEY2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-LSHIELD 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
-MBODY 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-MSHIELD 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
-NOTES 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-ROD 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
-SKULL 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-SSHIELD 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
-SPIDER 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-TELESCOPE 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
-DRINK 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
-GTSWORD 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-BAG 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
-FUR 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-LARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-SLARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-CHARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-SPARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-HPARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-FPARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-HARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-ROBE 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-SCALE 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-BTSWORD 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
-SCARF 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-FOOD2 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
-HAT 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-GAUNTLET 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
diff --git a/gemrb/override/iwd2/races.2da b/gemrb/override/iwd2/races.2da
deleted file mode 100644
index 48c4784..0000000
--- a/gemrb/override/iwd2/races.2da
+++ /dev/null
@@ -1,19 +0,0 @@
-2DA V1.0
--1
- NAME_REF DESC_REF CAP_REF ID USABILITY HAIR SKIN SKILL_COLUMN FAVORED_CLASS FEATBONUS
-HUMAN 7193 9550 1096 1 0x08000000 HAIRNORM SKINNORM 23 -1 1
-DWARF 7182 9551 1100 4 0x01000000 HAIRNORM SKINNORM 29 0x505 0
-ELF 7194 9552 1097 2 0x00800000 HAIRNORM SKINNORM 26 0xb0b 0
-GNOME 7196 9553 1099 6 0x10000000 HAIRNORM SKINNORM 35 0xb0b 0
-HALF_ELF 7197 9555 1098 3 0x02000000 HAIRNORM SKINNORM 37 -1 0
-HALF_ORC 22 25 23 7 0x80000000 HAIRNORM SKINNORM 38 0x101 0
-HALFLING 7195 9554 5374 5 0x04000000 HAIRNORM SKINNORM 32 0x909 0
-HUMAN_AASIMAR 5377 5386 5377 0x10001 0x00000000 HAIRAASM SKINAASM 24 0x707 0
-HUMAN_TIEFLING 5378 5388 5378 0x10002 0x00000000 HAIRTIEF SKINTIEF 25 0x909 0
-ELF_DROW 5379 5394 5379 0x20001 0x00000000 HAIRDARK SKINDARK 27 0x30b 0
-ELF_WILD 5380 5397 5380 0x20002 0x00000000 HAIRWOOD SKINWOOD 28 0xa0a 0
-DWARF_GOLD 5381 5413 5381 0x40001 0x00000000 HAIRGOLD SKINGOLD 30 0x505 0
-DWARF_GRAY 5382 5416 5382 0x40002 0x00000000 HAIRGRAY SKINGRAY 31 0x505 0
-HALFLING_STRONGHEART 5383 5660 5383 0x50001 0x00000000 HAIRNORM SKINNORM 33 0x909 0
-HALFLING_GHOSTWISE 5384 5661 5384 0x50002 0x00000000 HAIRNORM SKINNORM 34 0x101 0
-GNOME_DEEP 5385 5662 5385 0x60001 0x00000000 HAIRNORM SKINNORM 36 0xb0b 0
diff --git a/gemrb/override/iwd2/slottype.2da b/gemrb/override/iwd2/slottype.2da
deleted file mode 100644
index bb9600a..0000000
--- a/gemrb/override/iwd2/slottype.2da
+++ /dev/null
@@ -1,54 +0,0 @@
-2DA V1.0
-*
- BITS SCRIPT ICON STRREF EFFECT FLAGS
-10 0 0 * 0 2 0
-6 1 13 STONHELM 11999 7 0
-1 2 11 STONARM 11997 1 0
-9 0 0 * 0 0 0
-5 8 12 STONGLET 11998 1 0
-7 16 22 STONRING 12002 1 1
-8 16 23 STONRING 12003 1 1
-0 32 14 STONAMUL 12000 1 0
-2 64 21 STONBELT 12001 1 0
-3 128 25 STONBOOT 12005 1 0
-43 256 101 STONWEAP 12010 4 1
-44 4 102 STONSHIL 12010 6 0
-45 256 103 STONWEAP 12010 4 1
-46 4 104 STONSHIL 12010 6 0
-47 256 105 STONWEAP 12010 4 1
-48 4 106 STONSHIL 12010 6 0
-49 256 107 STONWEAP 12010 4 1
-50 4 108 STONSHIL 12010 6 0
-4 1024 24 STONCLOK 12004 1 0
-11 512 15 STONQUIV 12009 5 1
-12 512 16 STONQUIV 12009 5 1
-13 512 17 STONQUIV 12009 5 1
-14 0 0 * 0 5 0
-15 2048 5 STONITEM 12012 0 1
-16 2048 6 STONITEM 12012 0 1
-17 2048 7 STONITEM 12012 0 1
-18 -1 30 * 12013 0 1
-19 -1 31 * 12013 0 1
-20 -1 32 * 12013 0 1
-21 -1 33 * 12013 0 1
-22 -1 34 * 12013 0 1
-23 -1 35 * 12013 0 1
-24 -1 36 * 12013 0 1
-25 -1 37 * 12013 0 1
-26 -1 38 * 12013 0 1
-27 -1 39 * 12013 0 1
-28 -1 40 * 12013 0 1
-29 -1 41 * 12013 0 1
-30 -1 42 * 12013 0 1
-31 -1 43 * 12013 0 1
-32 -1 44 * 12013 0 1
-33 -1 45 * 12013 0 1
-34 -1 73 * 12013 0 1
-35 -1 74 * 12013 0 1
-36 -1 75 * 12013 0 1
-37 -1 76 * 12013 0 1
-38 -1 77 * 12013 0 1
-39 -1 78 * 12013 0 1
-40 -1 79 * 12013 0 1
-41 -1 80 * 12013 0 1
-42 0 0 * 0 3 0
diff --git a/gemrb/override/iwd2/splprot.2da b/gemrb/override/iwd2/splprot.2da
deleted file mode 100644
index 74254a4..0000000
--- a/gemrb/override/iwd2/splprot.2da
+++ /dev/null
@@ -1,105 +0,0 @@
-2DA V1.0
-0
- STAT VALUE RELATION COMMENT
-0 EA 0 4 anything
-1 GENERAL 4 1 general/undead
-2 GENERAL 4 5 general/not_undead
-3 RESISTFIRE 100 4 fire_resistance>=100
-4 RESISTFIRE 100 2 fire_resistance<100
-5 GENERAL 1 1 general/humanoid
-6 GENERAL 1 5 general/not_humanoid
-7 GENERAL 2 1 general/animal
-8 GENERAL 2 5 general/not_animal
-9 RACE 152 1 race/elemental
-10 RACE 152 5 race/not_elemental
-11 RACE 159 1 race/fungus
-12 RACE 159 5 race/not_fungus
-13 0x102 3 0 huge_creature
-14 0x102 3 3 not_huge_creature
-15 RACE 2 1 race/elf
-16 RACE 2 5 race/not_elf
-17 RACE 166 1 race/umberhulk
-18 RACE 166 5 race/not_umberhulk
-19 RACE 3 1 race/halfelf
-20 RACE 3 5 race/not_halfelf
-21 0x103 5 7 humanoid_or_animal
-22 0x104 5 7 not_humanoid_or_animal
-23 STATE 0x40000 9 state/blind
-24 STATE 0x40000 8 state/not_blind
-25 RESISTCOLD 100 4 cold_resistance>=100
-26 RESISTCOLD 100 2 cold_resistance<100
-27 RACE 156 1 race/golem
-28 RACE 156 5 race/not_golem
-29 RACE 179 1 race/minotaur
-30 RACE 179 5 race/not_minotaur
-31 0x103 1 11 undead_or_fungus
-32 0x104 1 11 not_undead_or_fungus
-33 ALIGNMENT 2 9 alignment/good
-34 ALIGNMENT 2 8 alignment/not_good
-35 ALIGNMENT 1 9 alignment/neutral
-36 ALIGNMENT 1 8 alignment/not_neutral
-37 ALIGNMENT 3 7 alignment/evil
-38 ALIGNMENT 3 11 alignment/not_evil
-39 CLASS 7 1 class/paladin
-40 CLASS 7 5 class/not_paladin
-41 0x105 217 1 moral_alignment_same
-42 0x105 217 5 moral_alignment_not_same
-43 0x100 * * source
-44 0x101 * * not_source
-45 ? * * water_using-FIXME
-46 ? * * not_water_using-FIXME
-47 0x104 32 27 breathes/not_undead_fungus_golem
-48 0x103 32 27 not_breathes/undead_fungus_or_golem
-49 EA 30 0 allies
-50 EA 30 3 not_allies
-51 EA 200 4 enemies
-52 EA 200 2 not_enemies
-53 0x103 3 25 race/fire_or_cold_using
-54 0x104 3 25 race/not_fire_or_cold_using
-55 ? * * unnatural
-56 ? * * not_unnatural
-57 SEX 1 1 gender/male
-58 SEX 1 5 gender/not_male
-59 ALIGNMENT 0x10 1 alignment/lawful
-60 ALIGNMENT 0x10 5 alignment/not_lawful
-61 ALIGNMENT 0x30 1 alignment/chaotic
-62 ALIGNMENT 0x30 5 alignment/not_chaotic
-63 ? * * evasion_check
-64 RACE 160 1 race/orc
-65 RACE 160 5 race/not_orc
-66 EXTSTATE ? 9 extstate/deaf
-67 EXTSTATE ? 8 extstate/not_deaf
-68 SEX 6 1 gender/summoned
-69 SEX 6 5 gender/not_summoned
-70 RACE 184 1 race/mindflayer
-71 RACE 184 5 race/not_mindflayer
-72 STATE 0x1000 9 state/silenced
-73 STATE 0x1000 8 state/not_silenced
-74 INT -1 4 int/less
-75 INT -1 0 int/greater
-76 INT -1 3 int/less_or_equal
-77 INT -1 2 int/greater_or_equal
-78 CLASS 2 1 class/bard
-79 CLASS 2 5 class/not_bard
-80 0x108 1 * near_enemies
-81 0x108 0 * not_near_enemies
-82 SUBRACE 0x20001 1 subrace/drow
-83 SUBRACE 0x20001 5 subrace/not_drow
-84 SUBRACE 0x40002 1 subrace/gray_dwarf
-85 SUBRACE 0x40002 5 subrace/not_gray_dwarf
-86 0x107 1 * daytime
-87 0x107 0 * not_daytime
-88 0x106 1 9 outdoor
-89 0x106 1 8 not_outdoor
-90 RACE 190 1 race/keg
-91 RACE 190 5 race/not_keg
-92 RACE * * outsider
-93 RACE * * not_outsider
-94 RACE 215 1 race/plate
-95 RACE 215 5 race/not_plate
-96 0x103 90 94 race/keg_or_plate
-97 0x104 90 94 race/not_keg_or_plate
-98 RACE 161 1 race/salamander
-99 RACE 161 5 race/not_salamander
-100 RACE 164 1 race/tanari
-101 RACE 164 5 race/not_tanari
diff --git a/gemrb/override/iwd2/strings.2da b/gemrb/override/iwd2/strings.2da
deleted file mode 100644
index 2707938..0000000
--- a/gemrb/override/iwd2/strings.2da
+++ /dev/null
@@ -1,170 +0,0 @@
-2DA V1.0
--1
- STRREF
-SCATTERED 16457
-WHOLEPARTY 16484
-DOORLOCKED 16485
-MAGICTRAP 16486
-NORMALTRAP 16487
-TRAP 16488
-CANNOTGO 16489
-TRAPREMOVED 16490
-OVERSTOCKED 16491
-SLEEP 16492
-AMBUSH 16493
-CONTLOCKED 16494
-NOMONEY 16495
-CURSED 16496
-SPELLDISRUPT 16497
-DIED 16498
-MAYNOTREST 16499
-CANTRESTMONS 16500
-CANTSAVEMONS 16501
-CANTSAVE 16502
-NODIALOG 10945
-CANTSAVEDIALOG 19253
-CANTSAVEDIALOG2 19254
-CANTSAVEMOVIE 19255
-TARGETBUSY -1
-CANTTALKTRANS -1
-GOTGOLD 17572
-LOSTGOLD 17573
-GOTXP 17574
-LOSTXP 17575
-GOTITEM 17576
-LOSTITEM 17577
-GOTREP 19686
-LOSTREP 19687
-GOTABILITY 10514
-GOTSPELL 10514
-GOTSONG 26320
-NOTHINGTOSAY -1
-JOURNALCHANGE 11359
-WORLDMAPCHANGE 11360
-PAUSED 16321
-UNPAUSED 16322
-SCRIPTPAUSED 7666
-AP_UNUSABLE 17113
-AP_ATTACKED 17114
-AP_HIT 17115
-AP_WOUNDED 17116
-AP_DEAD 17117
-AP_NOTARGET 17118
-AP_ENDROUND 10014
-AP_ENEMY 23511
-AP_TRAP -1
-AP_SPELLCAST -1
-AP_RESERVED1 -1
-AP_RESERVED2 -1
-AP_RESERVED3 -1
-AP_RESERVED4 -1
-CHARMED 14672
-DIRECHARMED 14780
-CONTROLLED -1
-EVIL 16505
-GNE_NEUTRAL 16504
-GOOD 16503
-STR_LAWFUL -1
-LNC_NEUTRAL -1
-CHAOTIC -1
-ACTION_CAST 16464
-ACTION_ATTACK 16465
-ACTION_TURN 16466
-ACTION_SONG 16467
-ACTION_FINDTRAP 16468
-MAGICWEAPON 10141
-OFFHAND_USED 9380
-TWOHANDED_USED 9381
-CANNOT_USE_ITEM 9382
-CANT_DROP_ITEM 25697
-NOT_IN_OFFHAND 26342
-ITEM_IS_CURSED 16304
-NO_CRITICAL 20696
-TRACKING -1
-TRACKINGFAILED 19534
-DOOR_NOPICK 23169
-CONT_NOPICK 23169
-CANTSAVECOMBAT -1
-CANTSAVENOCTRL -1
-LOCKPICK_DONE 16517
-LOCKPICK_FAILED 16518
-STATIC_DISSIPATE 26518
-LIGHTNING_DISSIPATE 41008
-HAS_NO_ABILITY 17317
-NEEDS_IDENTIFY 17316
-WRONG_ITEMTYPE 9375
-HAS_ITEMEXCL 20685
-PICKPOCKET_DONE 10072
-PICKPOCKET_NONE 18297
-PICKPOCKET_FAIL 10069
-PICKPOCKET_EVIL 10068
-PICKPOCKET_ARMOR 10067
-USING_FEAT -1
-STOPPED_FEAT -1
-DISARM_DONE 16520
-DISARM_FAIL 1608
-DOORBASH_DONE 9915
-DOORBASH_FAIL 9913
-CONTBASH_DONE 9916
-CONTBASH_FAIL 9914
-MAYNOTSETTRAP -1
-SNAREFAILED -1
-SNARESUCCEED -1
-NOMORETRAP -1
-DISABLEDMAGE -1
-SAVESUCCEED 1682
-QSAVESUCCEED 10237
-UNINJURED 2943
-INJURED1 2944
-INJURED2 2945
-INJURED3 2946
-INJURED4 2947
-HOURS 10700
-HOUR 10701
-DAYS 10697
-DAY 10698
-REST 10690
-JOURNEY 10689
-PST_REST -1
-PST_HOUR -1
-PST_HOURS -1
-DAMAGE_IMMUNITY 25038
-DAMAGE_STR1 25028
-DAMAGE_STR2 25017
-DAMAGE_STR3 26223
-DMG_POISON 25018
-DMG_MAGIC 25019
-DMG_MISSILE 25020
-DMG_SLASHING 25021
-DMG_PIERCING 25022
-DMG_CRUSHING 25023
-DMG_FIRE 25024
-DMG_ELECTRIC 25025
-DMG_COLD 25026
-DMG_ACID 25027
-DMG_OTHER 0
-GOTQUESTXP -1
-LEVELUP 17119
-INVFULL_ITEMDROP 32879
-CONT_DUP 32876
-CONT_TRIG -1
-CONT_FAIL -1
-SEQ_DUP -1
-CRITICAL_HIT 16462
-CRITICAL_MISS 16463
-DEATH 14026
-BACKSTAB 12128
-BACKSTAB_BAD 10013
-BACKSTAB_FAIL 121
-CASTER_LVL_INC -1
-CASTER_LVL_DEC -1
-CHARS_EXPORTED 26827
-PALADIN_FALL 19620
-RANGER_FALL 19621
-RES_RESISTED 26818
-DEADMAGIC_FAIL -1
-MISCASTMAGIC -1
-WILDSURGE -1
-FAMBLOCK 8537
-FAMPROTAGONIST 8538
-
diff --git a/gemrb/override/pst/CMakeLists.txt b/gemrb/override/pst/CMakeLists.txt
deleted file mode 100644
index 4a3f3c6..0000000
--- a/gemrb/override/pst/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-ADD_GEMRB_OVERRIDE (pst)
diff --git a/gemrb/override/pst/Makefile.am b/gemrb/override/pst/Makefile.am
index 1f148cc..f99b4a8 100644
--- a/gemrb/override/pst/Makefile.am
+++ b/gemrb/override/pst/Makefile.am
@@ -1,3 +1,3 @@
-pstoverride_DATA = *.2da *.bmp *.ini *.chu *.ids *.bcs *.pro
+pstoverride_DATA = *.2da *.bcs
pstoverridedir = $(moddir)/override/pst/
-EXTRA_DIST = *.2da *.bmp *.ini *.chu *.ids *.bcs *.pro
+EXTRA_DIST = *.2da *.bcs
diff --git a/gemrb/override/pst/baldur.bcs b/gemrb/override/pst/baldur.bcs
index 69daf1e..75db741 100644
--- a/gemrb/override/pst/baldur.bcs
+++ b/gemrb/override/pst/baldur.bcs
@@ -399,4 +399,156 @@ OB
RE
RS
CR
+CR
+CO
+TR
+16436 49 0 0 0 [0,0] "GLOBALlady" "" OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+TR
+TR
+16399 0 0 0 0 [0,0] "GLOBALar1900_visited" "" OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+TR
+TR
+16639 0 0 0 0 [0,0] "sigil" "" OB
+0 0 0 0 0 0 0 0 0 27 0 0 0 0 [-1.-1.-1.-1] ""OB
+TR
+TR
+16510 0 1 0 0 [0,0] "ar1900" "" OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+TR
+CO
+RS
+RE
+100AC
+123OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+0 0 0 0 0"" "" AC
+AC
+21OB
+0 0 0 0 0 0 0 0 0 26 0 0 0 0 [-1.-1.-1.-1] ""OB
+OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+0 0 0 0 0"" "" AC
+AC
+21OB
+0 0 0 0 0 0 0 0 0 25 0 0 0 0 [-1.-1.-1.-1] ""OB
+OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+0 0 0 0 0"" "" AC
+AC
+21OB
+0 0 0 0 0 0 0 0 0 24 0 0 0 0 [-1.-1.-1.-1] ""OB
+OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+0 0 0 0 0"" "" AC
+AC
+21OB
+0 0 0 0 0 0 0 0 0 23 0 0 0 0 [-1.-1.-1.-1] ""OB
+OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+0 0 0 0 0"" "" AC
+AC
+21OB
+0 0 0 0 0 0 0 0 0 22 0 0 0 0 [-1.-1.-1.-1] ""OB
+OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+0 0 0 0 0"" "" AC
+AC
+281OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+0 2559 1895 0 0"ar1900" "" AC
+RE
+RS
+CR
+CR
+CO
+TR
+16399 5 0 0 0 [0,0] "GLOBALsabotage" "" OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+TR
+TR
+16510 0 0 0 0 [0,0] "ar0512" "" OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+TR
+TR
+16639 0 0 0 0 [0,0] "foundry" "" OB
+2 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+TR
+CO
+RS
+RE
+100AC
+123OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+0 0 0 0 0"" "" AC
+AC
+281OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+0 1078 892 0 0"ar0513" "" AC
+RE
+RS
+CR
+CR
+CO
+TR
+16399 7 0 0 0 [0,0] "GLOBALsabotage" "" OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+TR
+TR
+16510 0 0 0 0 [0,0] "ar0512" "" OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+TR
+TR
+16639 0 0 0 0 [0,0] "foundry" "" OB
+2 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+TR
+CO
+RS
+RE
+100AC
+123OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+0 0 0 0 0"" "" AC
+AC
+281OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+OB
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 [-1.-1.-1.-1] ""OB
+0 1078 892 0 0"ar0513" "" AC
+RE
+RS
+CR
SC
diff --git a/gemrb/override/pst/cloudkil.pro b/gemrb/override/pst/cloudkil.pro
deleted file mode 100644
index eee63d6..0000000
Binary files a/gemrb/override/pst/cloudkil.pro and /dev/null differ
diff --git a/gemrb/override/pst/clskills.2da b/gemrb/override/pst/clskills.2da
deleted file mode 100644
index f9d6c1f..0000000
--- a/gemrb/override/pst/clskills.2da
+++ /dev/null
@@ -1,13 +0,0 @@
-2DA V1.0
-*
- HATERACE CLERICSPELL MAGESPELL STARTXP BARD THIEF LAYHANDS TURN BOOK
-UNUSED * * * * * * * 0 0
-MAGE * * MXSPLWIZ 0 * * * 0 1
-FIGHTER * * * 0 * * * 0 0
-CLERIC * MXSPLPRS * 0 * * * 1 1
-THIEF * * * 0 * SKILLS * 0 0
-BARD * * MXSPLBRD 0 * * * 0 1
-PALADIN * MXSPLPAL * 0 * * PALADIN 3 1
-FIGHTER_MAGE * * MXSPLWIZ 0 * * * 0 1
-FIGHTER_CLERIC * MXSPLPRS * 0 * * * 0 1
-FIGHTER_THIEF * * * 0 * SKILLS * 0 0
diff --git a/gemrb/override/pst/damage.2da b/gemrb/override/pst/damage.2da
deleted file mode 100644
index cbb1b63..0000000
--- a/gemrb/override/pst/damage.2da
+++ /dev/null
@@ -1,16 +0,0 @@
-2DA V1.0
-*
- MAIN SPARKS GRADIENT
-CRIT BLOODCR * 47
-SMALL BLOODS * 47
-MEDIUM BLOODM * 47
-LARGE BLOODL * 47
-FIRES FIRIMP SPBURN 19
-FIREM FIRIMP SPBURN 19
-FIREL FIRIMP SPBURN 19
-SPARKS SPSHKIMP SPSPARKS -1
-SPARKM SPSHKIMP SPSPARKS -1
-SPARKL SPSHKIMP SPSPARKS -1
-ICES FIRIMP * 71
-ICEM FIRIMP * 71
-ICEL FIRIMP * 71
diff --git a/gemrb/override/pst/defsound.2da b/gemrb/override/pst/defsound.2da
deleted file mode 100644
index e901ae6..0000000
--- a/gemrb/override/pst/defsound.2da
+++ /dev/null
@@ -1,29 +0,0 @@
-2DA V1.0
-*
- RESREF
-OPEN *
-CLOSE *
-HOPEN *
-HCLOSE *
-BUTTON1 INT_09
-BUTTON2 INT_03
-BUTTON3 INT_04
-OPENFAIL *
-CLOSEFAIL *
-ITEM_GONE INT_11
-SECRET *
-11 *
-12 *
-13 *
-14 *
-15 *
-16 *
-17 *
-18 *
-19 *
-LIGHTNING1 AMB_E13A
-LIGHTNING2 AMB_E13B
-LIGHTNING3 AMB_E13F
-RAIN AMB_E11
-SNOW AMB_E02B
-
diff --git a/gemrb/override/pst/fonts.2da b/gemrb/override/pst/fonts.2da
deleted file mode 100644
index dfad859..0000000
--- a/gemrb/override/pst/fonts.2da
+++ /dev/null
@@ -1,12 +0,0 @@
-2DA V1.0
-FONTDLG
- RESREF NEED_PALETTE FIRST_CHAR
-0 FONTDLG 1 0
-1 TRMTFONT 1 0
-2 EXOFONT 1 0
-3 POSTANT 1 0
-4 NUMBER 0 47
-5 NUMBER2 0 47
-6 NUMBER3 0 47
-7 SYSFONT 1 0
-8 FONTDLG 1 0
diff --git a/gemrb/override/pst/gametime.2da b/gemrb/override/pst/gametime.2da
deleted file mode 100644
index 237370a..0000000
--- a/gemrb/override/pst/gametime.2da
+++ /dev/null
@@ -1,5 +0,0 @@
-2DA V1.0
-0
- DURATION
-ROUND_SECONDS 5
-TURN_SECONDS 50
diff --git a/gemrb/override/pst/gemprjtl.ids b/gemrb/override/pst/gemprjtl.ids
deleted file mode 100644
index fe6ebca..0000000
--- a/gemrb/override/pst/gemprjtl.ids
+++ /dev/null
@@ -1,292 +0,0 @@
-IDS V1.0
-1 ARROW
-2 ARROWEX
-3 ARROWFLM
-4 ARROWHVY
-5 ARROW
-6 AXE
-7 AXEEX
-8 AXEFLM
-9 AXE
-10 AXE
-11 BOLT
-12 BOLTEX
-13 ARROWHVY
-14 BOLT
-15 BOLT
-16 BULLET
-17 BULLETEX
-18 <flamingbullet>
-19 BULLET
-20 BULLET
-21 SPBRNHND
-22 SKYBOLT
-23 CHROMORB
-24 SPCONECO
-25 SPCONEFI
-26 DAGGER
-27 DAGGEREX
-28 <flamingdagger>
-29 DAGGER
-30 DAGGER
-31 DART
-32 DARTEX
-33 <flamingdart>
-34 DART
-35 DART
-36 MAGICMIS
-37 FIREBALL
-38 ICE
-39 LIGHTB
-40 STONE
-41 SLEEP
-42 <skeleton>
-43 SPSMPUFF
-44 SPSMKJET
-45 SPSMOLD
-46 SPARKLBL
-47 SPARKLGO
-48 SPARKLPU
-49 SPARKLIC
-50 SPARKLST
-51 SPARKLBK
-52 SPARKLCH
-53 SPARKLRE
-54 SPARKLGR
-55 SPEAR
-56 SPEAREX
-57 <flamingspear>
-58 SPEAR
-59 SPEAR
-60 <starsprite>
-61 <stoned>
-62 <webtravel>
-63 WEB
-64 GAZE
-65 HLYMITE
-66 FLMSTRK
-67 MAGICMIS
-68 SPMAGMIS
-69 SPMAGMIS
-70 SPMAGMIS
-71 SPMAGMIS
-72 SPMAGMIS
-73 SPMAGMIS
-74 SPMAGMIS
-75 SPMAGMIS
-76 SPMAGMIS
-77 SPMAGMIS
-78 INVTRAV
-79 FIREBOLT
-80 SKYBOLT
-81 SKYBOLT2
-82 SKYBOLT2
-83 SKYBOLT2
-84 SKYBOLT2
-85 SKYBOLT2
-86 SKYBOLT2
-87 SKYBOLT2
-88 SKYBOLT2
-89 SKYBOLT2
-90 SKYBOLT2
-91 FIRESTOR
-92 LIGHTSTO
-93 INAREA
-94 CLOUD
-95 TRAPSKUL
-96 COLRSPRY
-97 ICESTORM
-98 SPFIREWL
-99 TRAPGLYP
-100 GREASE
-101 ARROWFLG
-102 ARROWFLB
-103 FIREBLGR
-104 FIREBTBL
-105 <potion>
-106 <potionexplode>
-107 ACIDBLOB
-108 SPSCORCH
-109 SPDIMDR
-110 CGNECROM
-111 CGALTERA
-112 CGENCHAN
-113 CGABJURA
-114 CGILLUSI
-115 CGCONJUR
-116 CGINVOCA
-117 CGDIVINA
-118 SHAIR
-119 SHEARTH
-120 SHWATER
-121 SHAIR1
-122 SHEARTH1
-123 SHWATER1
-124 SHAIR2
-125 SHEARTH2
-126 SHWATER2
-127 SHAIR3
-128 SHEARTH3
-129 SHWATER3
-130 SHAIR4
-131 SHEARTH4
-132 SHWATER4
-133 SHAIR5
-134 SHEARTH5
-135 SHWATER5
-136 SHAIR6
-137 SHEARTH6
-138 SHWATER6
-139 SHAIR7
-140 SHEARTH7
-141 SHWATER7
-142 SPBOOM1
-143 SPBOOM2
-144 SPBOOM3
-145 FLMSTRK
-146 HLYMITE
-147 SHAIR7
-148 SPKLARBL
-149 SPKLARGO
-150 SPKLARPU
-151 SPKLARIC
-152 SPKLARST
-153 SPKLARBK
-154 SPKLARCH
-155 SPKLARRE
-156 SPKLARGR
-157 INAREAPA
-158 INAREANP
-159 SPARBLPA
-160 SPARGOPA
-161 SPARPUPA
-162 SPARICPA
-163 SPARSTPA
-164 SPARBKPA
-165 SPARCHPA
-166 SPARREPA
-167 SPARGRPA
-168 SPARBLNP
-169 SPARGONP
-170 SPARPUNP
-171 SPARICNP
-172 SPARSTNP
-173 SPARBKNP
-174 SPARCHNP
-175 SPARRENP
-176 SPARGRNP
-177 SPARMANP
-178 SPARORNP
-179 SPARMAPA
-180 SPARORPA
-181 SPKLARMA
-182 SPKLAROR
-183 SPARKLMA
-184 SPARKLOR
-185 INAREANS
-186 CLOUDKIL
-187 ARROWFLI
-188 COW
-189 HOLD
-190 SPSCORIC
-191 ACIDBLMU
-192 ACIDBLGR
-193 ACIDBLOC
-194 REDHOLY
-195 SHAREA
-196 SHAREA1
-197 SHAREA
-198 SHAREA2
-199 SHAREA3
-200 SHAREA4
-201 SHAREA5
-202 SHAREA6
-203 LITANY
-204 STORIES
-205 MMISS
-206 MMISS2
-207 MMISS2
-208 MMISS2
-209 MMISS2
-210 MMISS2
-211 MMISS2
-212 MMISS2
-213 MMISS2
-214 MMISS2
-215 SKMOB
-216 SKMOB2
-217 ISWARM
-218 ISWARM2
-219 ADDER
-220 IKNIFE
-221 PACIFY
-222 STRENGTH
-223 BLIGHT
-224 BLIGHT2
-225 BBRIDGE
-226 FMISS
-227 ISTR
-228 SSHADOW
-229 CLOUDKIL
-230 HOPAND
-231 BSTORM
-232 ELYFIRE
-233 FURY
-234 HORROR
-235 KNOCK
-236 HOLDUND
-237 LMISS
-238 ELYTEAR
-239 TLAUGH
-240 AOTORM
-241 BSPHERE
-242 COCOLD
-243 DHELL
-244 FIREICE
-245 LSTORM
-246 ASTORM
-247 ISTORM
-248 MSWARM
-249 DBOLT
-250 IFURY
-251 PWBLIND
-252 MCANNON
-253 CHOST
-254 ROTORM
-255 BLESSED
-256 CURSED
-258 FFIRE
-259 SHAMMER
-260 CALLIH
-262 VTOUCH
-263 CONFUS
-264 PWKILL
-265 GOINVUL
-266 NBOLT
-267 RDEAD
-268 FEARAURA
-269 CONFLAG
-271 FBYELLO
-272 IMISS
-273 IMISS2
-274 IMISS2
-275 IMISS2
-276 IMISS2
-277 ITERROR
-278 IGNUSORB
-279 FRAIN
-280 ESTRIKE
-281 AMISS
-282 AMISS2
-283 AMISS2
-284 AMISS2
-285 AMISS2
-286 POONE
-287 KISS
-288 EMBALM
-289 FBOMB
-290 EBOMB
-291 RUNE
-292 LSTORM2
-293 CHOST2
-294 BSTORM2
diff --git a/gemrb/override/pst/gemrb.ini b/gemrb/override/pst/gemrb.ini
deleted file mode 100644
index 367a2e0..0000000
--- a/gemrb/override/pst/gemrb.ini
+++ /dev/null
@@ -1,121 +0,0 @@
-; GemRB - Infinity Engine Emulator
-; Copyright (C) 2003 The GemRB Project
-;
-; This program is free software; you can redistribute it and/or
-; modify it under the terms of the GNU General Public License
-; as published by the Free Software Foundation; either version 2
-; of the License, or (at your option) any later version.
-;
-; This program is distributed in the hope that it will be useful,
-; but WITHOUT ANY WARRANTY; without even the implied warranty of
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-; GNU General Public License for more details.
-;
-; You should have received a copy of the GNU General Public License
-; along with this program; if not, write to the Free Software
-; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-;
-
-
-; gemrb.ini - game type-specific settings for GemRB engine
-
-[resources]
-
-; Bitmap resource for cursors
-CursorBAM = CARET
-
-; Bitmap resource for scroll cursor arrow
-ScrollCursorBAM = CURSARW
-
-; Bitmap resource for dialog buttons font
-ButtonFont = FONTDLG
-
-; Font used to display tooltips
-TooltipFont = TRMTFONT
-
-; Bitmap resource for ground circles
-GroundCircleBAM1 = WMPICKL/3
-GroundCircleBAM2 = WMPICKR
-GroundCircleBAM3 = WMPICKL
-NoteString = NOTE:
-
-; INI file from the original games
-INIConfig = torment.ini
-
-; Palette bitmaps in various widths
-Palette16 = MPALETTE
-Palette32 = PAL32
-Palette256 = MPAL256
-
-;other games got a class specific fist (for monk)
-FistStat = 235
-MaximumAbility = 25
-IgnoreButtonFrames = 1
-AllStringsTagged = 1
-HasDPLAYER = 0
-HasPickSound = 1
-HasDescIcon = 0
-HasEXPTABLE = 0
-SoundFolders = 0
-HasSongList = 0
-UpperButtonText = 0
-ReverseToHit = 1
-LowerLabelText = 0
-HasPartyINI = 0
-HasBeastsINI = 1
-ForceStereo = 1
-TeamMovement = 1
-OneByteAnimationID = 1
-AutomapINI = 1
-SmallFog = 1
-ReverseDoor = 1
-ProtagonistTalks = 1
-HasKaputz = 1
-DialogueScrolls = 1
-SaveForHalfDamage = 1
-SpawnIni = 1
-HasResDataIni = 1
-OverrideCursorPos = 1
-OnScreenText = 1
-HasSpecificDamageBonus = 0
-HasWisdomBonusTable = 1
-AutoSearchHidden = 1
-CutsceneAreascripts = 1
-PSTStateFlags = 1
-NoDropCanMove = 1
-AreaOverride = 1
-NoNewVariables = 1
-
-[charset]
-CharCount = 31
-Letter1 = 192,224
-Letter2 = 193,225
-Letter3 = 194,226
-Letter4 = 195,227
-Letter5 = 196,228
-Letter6 = 197,229
-Letter7 = 198,230
-Letter8 = 199,231
-Letter9 = 200,232
-Letter10 = 201,233
-Letter11 = 202,234
-Letter12 = 203,235
-Letter13 = 204,236
-Letter14 = 205,237
-Letter15 = 206,238
-Letter16 = 207,239
-Letter17 = 208,240
-Letter18 = 209,241
-Letter19 = 210,242
-Letter20 = 211,243
-Letter21 = 212,244
-Letter22 = 213,245
-Letter23 = 214,246
-Letter24 = 140,156
-Letter25 = 216,248
-Letter26 = 217,249
-Letter27 = 218,250
-Letter28 = 219,251
-Letter29 = 220,252
-Letter30 = 221,253
-Letter31 = 222,254
diff --git a/gemrb/override/pst/overlay.2da b/gemrb/override/pst/overlay.2da
deleted file mode 100644
index d972ec7..0000000
--- a/gemrb/override/pst/overlay.2da
+++ /dev/null
@@ -1,35 +0,0 @@
-2DA V1.0
-*
- VVC UNDER FLAGS
-SANCTUARY SANCTRY 0 1
-ENTANGLE WEBENTD 1 0
-WISP WISP 0 0
-SHIELDGLOBE SPSHIELD 0 1
-GREASE GREASED 1 0
-WEB WEBENTD 1 0
-MINORGLOBE MINORGLB 0 1
-GLOBE GOINVUC 0 1
-FLAMESHROUD SOFLAMC 0 0
-ANTIMAGIC AMSHELC 0 0
-RESILIENT ORSPHEC 0 0
-PROTFROMMISS PFNMISC 0 0
-CLOAKOFFEAR COFEARC 0 0
-ENTROPY ESHIELC 0 0
-FIREAURA FIAURAC 0 0
-FROSTAURA FRAURAC 0 0
-INSECT IPLAGUC 0 0
-STORMSHELL SSHELLC 0 0
-LATHANDER1 SOLATC1 0 0
-LATHANDER2 SOLATC2 1 0
-GLATHANDER1 GSOLAC1 0 0
-GLATHANDER2 GSOLAC2 1 0
-SEVENEYES1 SEYESC1 0 0
-SEVENEYES2 SEYESC2 1 0
-BOUNCE SPTURNI2 1 0
-BOUNCE2 SPTURNI 1 0
-FIRESHIELD1 FSHIRC1 0 0
-FIRESHIELD2 FSHIRC2 1 0
-ICESHIELD1 FSHIBC1 0 0
-ICESHIELD2 FSHIBC2 1 0
-TORTOISE TSHELLC 0 0
-DEATHARMOR DARMORC 0 0
diff --git a/gemrb/override/pst/pathfind.2da b/gemrb/override/pst/pathfind.2da
deleted file mode 100644
index b331d3f..0000000
--- a/gemrb/override/pst/pathfind.2da
+++ /dev/null
@@ -1,5 +0,0 @@
-2DA V1.0
-*
- 0 1 2 3 4 5 6 7 8 9 a b c d e f
-PASSABLE 8 1 1 1 1 1 1 1 0 1 8 0 0 8 3 1
-COST 10 4
diff --git a/gemrb/override/pst/source/baldur.baf b/gemrb/override/pst/source/baldur.baf
new file mode 100644
index 0000000..bd2b993
--- /dev/null
+++ b/gemrb/override/pst/source/baldur.baf
@@ -0,0 +1,157 @@
+IF
+ !Faction(Protagonist,ANARCHIST)
+ Global("JOIN_ANARCHISTS","GLOBAL",1)
+THEN
+ RESPONSE #100
+ ChangeFaction(Protagonist,ANARCHIST)
+END
+
+IF
+ !Faction(Protagonist,SENSATE)
+ Global("JOIN_SENSATES","GLOBAL",1)
+ !Global("JOIN_ANARCHISTS","GLOBAL",1)
+THEN
+ RESPONSE #100
+ ChangeFaction(Protagonist,SENSATE)
+END
+
+IF
+ !Faction(Protagonist,DUSTMEN)
+ Global("JOIN_DUSTMEN","GLOBAL",1)
+ !Global("JOIN_ANARCHISTS","GLOBAL",1)
+THEN
+ RESPONSE #100
+ ChangeFaction(Protagonist,DUSTMEN)
+END
+
+IF
+ !Faction(Protagonist,GODSMAN)
+ Global("JOIN_GODSMEN","GLOBAL",6)
+ !Global("JOIN_ANARCHISTS","GLOBAL",1)
+THEN
+ RESPONSE #100
+ ChangeFaction(Protagonist,GODSMAN)
+END
+
+IF
+ !Faction(Protagonist,XAOSITECT)
+ Global("JOIN_CHAOSMEN","GLOBAL",1)
+ !Global("JOIN_ANARCHISTS","GLOBAL",1)
+THEN
+ RESPONSE #100
+ ChangeFaction(Protagonist,XAOSITECT)
+END
+
+IF
+ Global("game_over","GLOBAL",1)
+THEN
+ RESPONSE #100
+ GlobalSet("game_over","GLOBAL",0)
+ QuitGame(0,0,44963)
+END
+
+IF
+ Global("game_over","GLOBAL",2)
+THEN
+ RESPONSE #100
+ GlobalSet("game_over","GLOBAL",0)
+ QuitGame(0,0,48153)
+END
+
+IF
+ Global("game_over","GLOBAL",3)
+THEN
+ RESPONSE #100
+ GlobalSet("game_over","GLOBAL",0)
+ QuitGame(0,0,48154)
+END
+
+IF
+ Global("game_over","GLOBAL",4)
+THEN
+ RESPONSE #100
+ GlobalSet("game_over","GLOBAL",0)
+ QuitGame(0,0,48155)
+END
+
+IF
+ Global("game_over","GLOBAL",5)
+THEN
+ RESPONSE #100
+ GlobalSet("game_over","GLOBAL",0)
+ QuitGame(0,0,41656)
+END
+
+IF
+ Global("game_over","GLOBAL",6)
+THEN
+ RESPONSE #100
+ GlobalSet("game_over","GLOBAL",0)
+ QuitGame(0,0,67295)
+END
+
+IF
+ Global("AR0200_Visited","GLOBAL",1)
+ Global("Played_Shadow_Movie","GLOBAL",0)
+THEN
+ RESPONSE #100
+ GlobalSet("Played_Shadow_Movie","GLOBAL",1)
+ StartMovie("SS_MSLAB")
+END
+
+IF
+ Global("AR0206_Visited","GLOBAL",1)
+ Global("Played_Shadow_Movie","GLOBAL",0)
+THEN
+ RESPONSE #100
+ GlobalSet("Played_Shadow_Movie","GLOBAL",1)
+ StartMovie("SS_MSLAB")
+END
+
+IF
+ Global("AR0200_Visited","GLOBAL",1)
+ Global("Played_Sigil_Movie","GLOBAL",0)
+THEN
+ RESPONSE #100
+ GlobalSet("Played_Sigil_Movie","GLOBAL",1)
+ StartMovie("SIGIL")
+END
+
+IF
+ GlobalGT("lady","GLOBAL",49)
+ Global("ar1900_visited","GLOBAL",0)
+ UsedExit("sigil",Protagonist)
+ !CreatureInArea("ar1900")
+THEN
+ RESPONSE #100
+ ClearAllActions()
+ ActionOverride(Player6,LeaveParty())
+ ActionOverride(Player5,LeaveParty())
+ ActionOverride(Player4,LeaveParty())
+ ActionOverride(Player3,LeaveParty())
+ ActionOverride(Player2,LeaveParty())
+ //should be the position of mazeentr in ar1900
+ TeleportParty("ar1900",[2559.1895],0)
+END
+
+IF
+ Global("sabotage","GLOBAL",5)
+ CreatureInArea("ar0512")
+ UsedExit("foundry",[PC])
+THEN
+ RESPONSE #100
+ ClearAllActions()
+ TeleportParty("ar0513",[1078.892],0)
+END
+
+IF
+ Global("sabotage","GLOBAL",7)
+ CreatureInArea("ar0512")
+ UsedExit("foundry",[PC])
+THEN
+ RESPONSE #100
+ ClearAllActions()
+ TeleportParty("ar0513",[1078.892],0)
+END
+
+
diff --git a/gemrb/override/pst/strings.2da b/gemrb/override/pst/strings.2da
deleted file mode 100644
index c42108a..0000000
--- a/gemrb/override/pst/strings.2da
+++ /dev/null
@@ -1,170 +0,0 @@
-2DA V1.0
--1
- STRREF
-SCATTERED 55021
-WHOLEPARTY -1
-DOORLOCKED 19309
-MAGICTRAP 19289
-NORMALTRAP 19289
-TRAP -1
-CANNOTGO -1
-TRAPREMOVED 19287
-OVERSTOCKED 19283
-SLEEP -1
-AMBUSH -1
-CONTLOCKED 22031
-NOMONEY -1
-CURSED 50538
-SPELLDISRUPT -1
-DIED -1
-MAYNOTREST 34599
-CANTRESTMONS 34600
-CANTSAVEMONS 34598
-CANTSAVE 34592
-NODIALOG -1
-CANTSAVEDIALOG 34593
-CANTSAVEDIALOG2 -1
-CANTSAVEMOVIE 34594
-TARGETBUSY -1
-CANTTALKTRANS -1
-GOTGOLD 19252
-LOSTGOLD 19253
-GOTXP 19254
-LOSTXP 19255
-GOTITEM 19256
-LOSTITEM 19258
-GOTREP 19259
-LOSTREP 19260
-GOTABILITY 19307
-GOTSPELL -1
-GOTSONG -1
-NOTHINGTOSAY -1
-JOURNALCHANGE 37096
-WORLDMAPCHANGE 19264
-PAUSED 39436
-UNPAUSED -1
-SCRIPTPAUSED 39436
-AP_UNUSABLE 39436
-AP_ATTACKED 39436
-AP_HIT 39436
-AP_WOUNDED 39436
-AP_DEAD 39436
-AP_NOTARGET 39436
-AP_ENDROUND 39436
-AP_ENEMY 39436
-AP_TRAP 39436
-AP_SPELLCAST 39436
-AP_RESERVED1 39436
-AP_RESERVED2 39436
-AP_RESERVED3 39436
-AP_RESERVED4 39436
-CHARMED -1
-DIRECHARMED -1
-CONTROLLED -1
-EVIL -1
-GNE_NEUTRAL -1
-GOOD -1
-STR_LAWFUL -1
-LNC_NEUTRAL -1
-CHAOTIC -1
-ACTION_CAST -1
-ACTION_ATTACK -1
-ACTION_TURN -1
-ACTION_SONG -1
-ACTION_FINDTRAP -1
-MAGICWEAPON -1
-OFFHAND_USED -1
-TWOHANDED_USED -1
-CANNOT_USE_ITEM 50532
-CANT_DROP_ITEM 50569
-NOT_IN_OFFHAND -1
-ITEM_IS_CURSED 50538
-NO_CRITICAL 19273
-TRACKING -1
-TRACKINGFAILED -1
-DOOR_NOPICK 23169
-CONT_NOPICK 23169
-CANTSAVECOMBAT -1
-CANTSAVENOCTRL -1
-LOCKPICK_DONE 19281
-LOCKPICK_FAILED 19282
-STATIC_DISSIPATE -1
-LIGHTNING_DISSIPATE -1
-HAS_NO_ABILITY 50545
-NEEDS_IDENTIFY 50544
-WRONG_ITEMTYPE 50537
-HAS_ITEMEXCL -1
-PICKPOCKET_DONE -1
-PICKPOCKET_NONE 19304
-PICKPOCKET_FAIL 19303
-PICKPOCKET_EVIL 19302
-PICKPOCKET_ARMOR 19301
-USING_FEAT -1
-STOPPED_FEAT -1
-DISARM_DONE 16520
-DISARM_FAIL 1608
-DOORBASH_DONE -1
-DOORBASH_FAIL -1
-CONTBASH_DONE -1
-CONTBASH_FAIL -1
-MAYNOTSETTRAP -1
-SNAREFAILED -1
-SNARESUCCEED -1
-NOMORETRAP -1
-DISABLEDMAGE -1
-SAVESUCCEED 28646
-QSAVESUCCEED 50461
-UNINJURED -1
-INJURED1 -1
-INJURED2 -1
-INJURED3 -1
-INJURED4 -1
-HOURS -1
-HOUR -1
-DAYS -1
-DAY -1
-REST -1
-JOURNEY -1
-PST_REST 19262
-PST_HOUR 19312
-PST_HOURS 19313
-DAMAGE_IMMUNITY -1
-DAMAGE_STR1 -1
-DAMAGE_STR2 -1
-DAMAGE_STR3 -1
-DMG_POISON -1
-DMG_MAGIC -1
-DMG_MISSILE -1
-DMG_SLASHING -1
-DMG_PIERCING -1
-DMG_CRUSHING -1
-DMG_FIRE -1
-DMG_ELECTRIC -1
-DMG_COLD -1
-DMG_ACID -1
-DMG_OTHER -1
-GOTQUESTXP -1
-LEVELUP 4246
-INVFULL_ITEMDROP 37079
-CONT_DUP -1
-CONT_TRIG -1
-CONT_FAIL -1
-SEQ_DUP -1
-CRITICAL_HIT 19272
-CRITICAL_MISS 19274
-DEATH -1
-BACKSTAB 12128
-BACKSTAB_BAD 19271
-BACKSTAB_FAIL -1
-CASTER_LVL_INC -1
-CASTER_LVL_DEC -1
-CHARS_EXPORTED -1
-PALADIN_FALL -1
-RANGER_FALL -1
-RES_RESISTED -1
-DEADMAGIC_FAIL -1
-MISCASTMAGIC -1
-WILDSURGE -1
-FAMBLOCK -1
-FAMPROTAGONIST -1
-
diff --git a/gemrb/override/shared/CMakeLists.txt b/gemrb/override/shared/CMakeLists.txt
deleted file mode 100644
index e954707..0000000
--- a/gemrb/override/shared/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-ADD_GEMRB_OVERRIDE (shared)
diff --git a/gemrb/override/shared/Makefile.am b/gemrb/override/shared/Makefile.am
index 752a81a..cfd0276 100644
--- a/gemrb/override/shared/Makefile.am
+++ b/gemrb/override/shared/Makefile.am
@@ -1,3 +1,3 @@
-sharedoverride_DATA = *.2da *.ids *.spl *.pro
+sharedoverride_DATA = *.ids
sharedoverridedir = $(moddir)/override/shared/
-EXTRA_DIST = *.2da *.ids *.spl *.pro
+EXTRA_DIST = *.ids
diff --git a/gemrb/override/shared/bardsong.spl b/gemrb/override/shared/bardsong.spl
deleted file mode 100644
index 38cd8f2..0000000
Binary files a/gemrb/override/shared/bardsong.spl and /dev/null differ
diff --git a/gemrb/override/shared/dmgtypes.2da b/gemrb/override/shared/dmgtypes.2da
deleted file mode 100644
index 0d7516a..0000000
--- a/gemrb/override/shared/dmgtypes.2da
+++ /dev/null
@@ -1,22 +0,0 @@
-2DA V1.0
--1
- LOWER RESIST_STAT VALUE IWDMOD
-DAMAGE_CRUSHING 136 RESISTCRUSHING 0 9
-DAMAGE_ACID 140 RESISTACID 1 4
-DAMAGE_COLD 139 RESISTCOLD 2 2
-DAMAGE_ELECTRICITY 138 RESISTELECTRICITY 4 3
-DAMAGE_FIRE 137 RESISTFIRE 8 1
-DAMAGE_PIERCING 135 RESISTPIERCING 0x10 8
-DAMAGE_POISON 131 RESISTPOISON 0x20 6
-DAMAGE_MAGIC 132 MAGICDAMAGERESISTANCE 0x40 5
-DAMAGE_MISSILE 133 RESISTMISSILE 0x80 10
-DAMAGE_SLASHING 134 RESISTSLASHING 0x100 7
-DAMAGE_MAGICFIRE 137 RESISTMAGICFIRE 0x200 -1
-DAMAGE_PIERCINGMISSILE 133 RESISTMISSILE 0x80 -1
-DAMAGE_MAGICCOLD 139 RESISTMAGICCOLD 0x400 -1
-DAMAGE_CRUSHINGMISSILE 133 RESISTMISSILE 0x80 -1
-DAMAGE_STUNNING 141 0 0x800 -1
-DAMAGE_SOULEATER 132 0 0x1000 -1
-DAMAGE_DISEASE 141 0 0x4000 -1
-DAMAGE_CHUNKING 141 0 0x8000 -1
-
diff --git a/gemrb/override/shared/gemact.ids b/gemrb/override/shared/gemact.ids
deleted file mode 100644
index b23f6b2..0000000
--- a/gemrb/override/shared/gemact.ids
+++ /dev/null
@@ -1,10 +0,0 @@
-IDS
-399 ApplySpellPoint(P:Target*,I:Spell*Spell)
-399 ApplySpellPointRES(P:Target*,S:SpellName*)
-398 ChangeDestination(O:Object*,S:Destination*)
-397 UnmakeGlobal(O:Object*)
-396 SetToken2DA(S:ResRef*)
-395 StartDialogOverride(S:DialogFile*,O:Target*,I:Unused,I:Unused,I:ConverseAsItem)
-394 SetTrackString(I:StrRef, I:Flags, I:Difficulty)
-148 BashDoor(O:Object)
-93 LeaveAreaName(O:Target*)
diff --git a/gemrb/override/shared/stats.ids b/gemrb/override/shared/stats.ids
index f1f1a70..5d69ba3 100644
--- a/gemrb/override/shared/stats.ids
+++ b/gemrb/override/shared/stats.ids
@@ -301,7 +301,7 @@ IDS
244 CLASSLEVELMONK
245 CLASSLEVELPALADIN
246 CLASSLEVELRANGER
-247 CLASSLEVELSORCEROR
+247 CLASSLEVELSORCERER
248 CLASSLEVEL12
249 CLASSLEVEL13
250 SPLSTATE1
diff --git a/gemrb/plugins/2DAImporter/2DAImporter.cpp b/gemrb/plugins/2DAImporter/2DAImporter.cpp
index fcb046f..703c182 100644
--- a/gemrb/plugins/2DAImporter/2DAImporter.cpp
+++ b/gemrb/plugins/2DAImporter/2DAImporter.cpp
@@ -25,35 +25,27 @@
#include "Interface.h"
#include "System/FileStream.h"
+using namespace GemRB;
+
#define MAXLENGTH 4096 //if a 2da has longer lines, change this
#define SIGNLENGTH 256 //if a 2da has longer default value, change this
p2DAImporter::p2DAImporter(void)
{
- str = NULL;
- autoFree = false;
}
p2DAImporter::~p2DAImporter(void)
{
- if (str && autoFree) {
- delete( str );
- }
for (unsigned int i = 0; i < ptrs.size(); i++) {
free( ptrs[i] );
}
}
-bool p2DAImporter::Open(DataStream* stream, bool autoFree)
+bool p2DAImporter::Open(DataStream* str)
{
- if (stream == NULL) {
+ if (str == NULL) {
return false;
}
- if (str && this->autoFree) {
- delete( str );
- }
- str = stream;
- this->autoFree = autoFree;
char Signature[SIGNLENGTH];
str->CheckEncrypted();
@@ -62,9 +54,10 @@ bool p2DAImporter::Open(DataStream* stream, bool autoFree)
while (*strp == ' ')
strp++;
if (strncmp( strp, "2DA V1.0", 8 ) != 0) {
- printMessage("2DAImporter", "Bad signature!\n",YELLOW );
-// we don't care about this, so exptable.2da of iwd2 won't cause a bigger problem
-// return false;
+ Log(WARNING, "2DAImporter", "Bad signature (%s)! Ignoring...", str->filename );
+ // we don't care about this, so exptable.2da of iwd2 won't cause a bigger problem
+ // also, certain creatures are described by 2da's without signature.
+ // return false;
}
Signature[0] = 0;
str->ReadLine( Signature, sizeof(Signature) );
@@ -110,6 +103,7 @@ bool p2DAImporter::Open(DataStream* stream, bool autoFree)
row++;
}
}
+ delete str;
return true;
}
diff --git a/gemrb/plugins/2DAImporter/2DAImporter.h b/gemrb/plugins/2DAImporter/2DAImporter.h
index 0e83b5c..81d9112 100644
--- a/gemrb/plugins/2DAImporter/2DAImporter.h
+++ b/gemrb/plugins/2DAImporter/2DAImporter.h
@@ -26,13 +26,14 @@
#include "globals.h"
#include <cstring>
+#include <vector>
+
+namespace GemRB {
typedef std::vector< char*> RowEntry;
class p2DAImporter : public TableMgr {
private:
- DataStream* str;
- bool autoFree;
std::vector< char*> colNames;
std::vector< char*> rowNames;
std::vector< char*> ptrs;
@@ -41,7 +42,7 @@ private:
public:
p2DAImporter(void);
~p2DAImporter(void);
- bool Open(DataStream* stream, bool autoFree = true);
+ bool Open(DataStream* stream);
/** Returns the actual number of Rows in the Table */
inline ieDword GetRowCount() const
{
@@ -164,6 +165,20 @@ public:
}
return -1;
}
+
+ inline int FindTableValue(const char* col, long val, int start) const
+ {
+ ieDword coli = GetColumnIndex(col);
+ return FindTableValue(coli, val, start);
+ }
+
+ inline int FindTableValue(const char* col, const char* val, int start) const
+ {
+ ieDword coli = GetColumnIndex(col);
+ return FindTableValue(coli, val, start);
+ }
};
+}
+
#endif
diff --git a/gemrb/plugins/ACMReader/ACMReader.cpp b/gemrb/plugins/ACMReader/ACMReader.cpp
index f0c5f9c..9a97f96 100644
--- a/gemrb/plugins/ACMReader/ACMReader.cpp
+++ b/gemrb/plugins/ACMReader/ACMReader.cpp
@@ -20,6 +20,8 @@
#include "general.h"
+using namespace GemRB;
+
bool ACMReader::Open(DataStream* stream)
{
str = stream;
@@ -112,6 +114,6 @@ int ACMReader::read_samples(short* buffer, int count)
#include "plugindef.h"
GEMRB_PLUGIN(0x10373EE, "ACM File Importer")
-PLUGIN_IE_RESOURCE(ACMReader, ".acm", (ieWord)IE_ACM_CLASS_ID)
-PLUGIN_IE_RESOURCE(ACMReader, ".wav", (ieWord)IE_WAV_CLASS_ID)
+PLUGIN_IE_RESOURCE(ACMReader, "acm", (ieWord)IE_ACM_CLASS_ID)
+PLUGIN_IE_RESOURCE(ACMReader, "wav", (ieWord)IE_WAV_CLASS_ID)
END_PLUGIN()
diff --git a/gemrb/plugins/ACMReader/ACMReader.h b/gemrb/plugins/ACMReader/ACMReader.h
index d34615c..d51700a 100644
--- a/gemrb/plugins/ACMReader/ACMReader.h
+++ b/gemrb/plugins/ACMReader/ACMReader.h
@@ -31,6 +31,8 @@
#include <cstring>
#include <cstdlib>
+namespace GemRB {
+
// IP's ACM files
class ACMReader : public SoundMgr {
private:
@@ -70,4 +72,6 @@ public:
virtual int read_samples(short* buffer, int count);
};
+}
+
#endif
diff --git a/gemrb/plugins/ACMReader/unpacker.h b/gemrb/plugins/ACMReader/unpacker.h
index 64eaace..6664b04 100644
--- a/gemrb/plugins/ACMReader/unpacker.h
+++ b/gemrb/plugins/ACMReader/unpacker.h
@@ -23,6 +23,8 @@
#include "System/DataStream.h"
+using namespace GemRB;
+
#define UNPACKER_BUFFER_SIZE 16384
class CValueUnpacker {
@@ -37,7 +39,7 @@ private:
unsigned char bits_buffer[UNPACKER_BUFFER_SIZE];
unsigned int buffer_bit_offset;
- int sb_size, block_size;
+ int sb_size;
short* amp_buffer, * buff_middle;
int* block_ptr;
@@ -71,7 +73,7 @@ public:
: levels( lev_cnt ), subblocks( sb_count ), next_bits( 0 ),
avail_bits( 0 ), buffer_bit_offset( UNPACKER_BUFFER_SIZE ),
sb_size( 1 << levels ),
- block_size( sb_size*subblocks ), amp_buffer( NULL ),
+ amp_buffer( NULL ),
buff_middle( NULL ), block_ptr( NULL )
{
this->stream = stream;
diff --git a/gemrb/plugins/AREImporter/AREImporter.cpp b/gemrb/plugins/AREImporter/AREImporter.cpp
index 45e1a81..92ddd11 100644
--- a/gemrb/plugins/AREImporter/AREImporter.cpp
+++ b/gemrb/plugins/AREImporter/AREImporter.cpp
@@ -22,6 +22,7 @@
#include "win32def.h"
#include "strrefs.h"
+#include "ie_cursors.h"
#include "ActorMgr.h"
#include "Ambient.h"
@@ -33,6 +34,7 @@
#include "ImageMgr.h"
#include "Interface.h"
#include "Palette.h"
+#include "PluginMgr.h"
#include "ProjectileServer.h"
#include "TileMapMgr.h"
#include "Video.h"
@@ -40,8 +42,10 @@
#include "Scriptable/Container.h"
#include "Scriptable/Door.h"
#include "Scriptable/InfoPoint.h"
-#include "System/CachedFileStream.h"
#include "System/FileStream.h"
+#include "System/SlicedStream.h"
+
+using namespace GemRB;
#define DEF_OPEN 0
#define DEF_CLOSE 1
@@ -50,8 +54,6 @@
#define DEF_COUNT 4
-#define DOOR_HIDDEN 128
-
//something non signed, non ascii
#define UNINITIALIZED_BYTE 0x11
@@ -70,7 +72,7 @@ Holder<DataFileMgr> INInote;
ResRefToStrRef *tracks = NULL;
int trackcount = 0;
-void ReleaseMemory()
+static void ReleaseMemory()
{
INInote.release();
@@ -78,23 +80,22 @@ void ReleaseMemory()
tracks = NULL;
}
-void ReadAutonoteINI()
+static void ReadAutonoteINI()
{
INInote = PluginHolder<DataFileMgr>(IE_INI_CLASS_ID);
- FileStream* fs = new FileStream();
char tINInote[_MAX_PATH];
PathJoin( tINInote, core->GamePath, "autonote.ini", NULL );
- fs->Open( tINInote, true );
- INInote->Open( fs, true );
+ FileStream* fs = FileStream::OpenFile( tINInote );
+ INInote->Open(fs);
}
-int GetTrackString(const ieResRef areaName)
+static int GetTrackString(const ieResRef areaName)
{
int i;
bool trackflag = displaymsg->HasStringReference(STR_TRACKING);
if (!tracks) {
- AutoTable tm("tracking");
+ AutoTable tm("tracking", true);
if (!tm.ok())
return -1;
trackcount = tm->GetRowCount();
@@ -123,7 +124,6 @@ int GetTrackString(const ieResRef areaName)
AREImporter::AREImporter(void)
{
- autoFree = false;
str = NULL;
if (Sounds[0][0] == UNINITIALIZED_BYTE) {
memset( Sounds, 0, sizeof( Sounds ) );
@@ -141,22 +141,17 @@ AREImporter::AREImporter(void)
AREImporter::~AREImporter(void)
{
- if (autoFree) {
- delete str;
- }
+ delete str;
Sounds[0][0]=UNINITIALIZED_BYTE;
}
-bool AREImporter::Open(DataStream* stream, bool autoFree)
+bool AREImporter::Open(DataStream* stream)
{
if (stream == NULL) {
return false;
}
- if (this->autoFree) {
- delete str;
- }
+ delete str;
str = stream;
- this->autoFree = autoFree;
char Signature[8];
str->Read( Signature, 8 );
@@ -253,13 +248,18 @@ bool AREImporter::ChangeMap(Map *map, bool day_or_night)
}
tm = tmm->GetTileMap(tm);
if (!tm) {
- printf( "[AREImporter]: No Tile Map Available.\n" );
+ print("[AREImporter]: No Tile Map Available.");
return false;
}
// Small map for MapControl
ResourceHolder<ImageMgr> sm(TmpResRef);
- // small map is *optional*!
+
+ // night small map is *optional*!
+ if (!sm) {
+ //fall back to day minimap
+ sm = ResourceHolder<ImageMgr> (map->WEDResRef);
+ }
//the map state was altered, no need to hold this off for any later
map->DayNight = day_or_night;
@@ -273,7 +273,7 @@ bool AREImporter::ChangeMap(Map *map, bool day_or_night)
ResourceHolder<ImageMgr> lm(TmpResRef);
if (!lm) {
- printf( "[AREImporter]: No lightmap available.\n" );
+ print("[AREImporter]: No lightmap available.");
return false;
}
@@ -282,6 +282,34 @@ bool AREImporter::ChangeMap(Map *map, bool day_or_night)
return true;
}
+// everything is the same up to DOOR_FOUND, but then it gets messy (see Door.h)
+static const ieDword gemrbDoorFlags[6] = { DOOR_TRANSPARENT, DOOR_KEY, DOOR_SLIDE, DOOR_USEUPKEY, DOOR_LOCKEDINFOTEXT, DOOR_WARNINGINFOTEXT };
+// the last two are 0, since they are outside the original bit range, so all the constants can coexist
+static const ieDword iwd2DoorFlags[6] = { DOOR_LOCKEDINFOTEXT, DOOR_TRANSPARENT, DOOR_WARNINGINFOTEXT, DOOR_KEY, 0, 0 };
+inline ieDword FixIWD2DoorFlags(ieDword Flags, bool reverse)
+{
+ if (!core->HasFeature(GF_IWD2_SCRIPTNAME)) {
+ return Flags;
+ }
+
+ ieDword bit, otherbit, maskOff = 0, maskOn= 0;
+ for (int i=0; i < 6; i++) {
+ if (!reverse) {
+ bit = gemrbDoorFlags[i];
+ otherbit = iwd2DoorFlags[i];
+ } else {
+ bit = iwd2DoorFlags[i];
+ otherbit = gemrbDoorFlags[i];
+ }
+ if (Flags & bit) {
+ maskOff |= bit;
+ maskOn |= otherbit;
+ }
+ }
+ // delayed bad bit removal due to chain overlapping
+ return Flags = (Flags & ~maskOff) | maskOn;
+}
+
Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
{
unsigned int i,x;
@@ -292,8 +320,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
Map* map = new Map();
if(!map) {
- printf("Can't allocate map (out of memory).\n");
- abort();
+ error("AREImporter", "Can't allocate map (out of memory).\n");
}
if (core->SaveAsOriginal) {
map->version = bigheader;
@@ -321,7 +348,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
}
if (!core->IsAvailable( IE_WED_CLASS_ID )) {
- printf( "[AREImporter]: No Tile Map Manager Available.\n" );
+ print("[AREImporter]: No Tile Map Manager Available.");
return NULL;
}
ieResRef TmpResRef;
@@ -339,13 +366,16 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
//there was no tilemap set yet, so lets just send a NULL
TileMap* tm = tmm->GetTileMap(NULL);
if (!tm) {
- printf( "[AREImporter]: No Tile Map Available.\n" );
+ print("[AREImporter]: No Tile Map Available.");
return NULL;
}
// Small map for MapControl
- // small map is *optional*!
ResourceHolder<ImageMgr> sm(TmpResRef);
+ if (!sm) {
+ //fall back to day minimap
+ sm = ResourceHolder<ImageMgr> (map->WEDResRef);
+ }
//if the Script field is empty, the area name will be copied into it on first load
//this works only in the iwd branch of the games
@@ -368,7 +398,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
ResourceHolder<ImageMgr> lm(TmpResRef);
if (!lm) {
- printf( "[AREImporter]: No lightmap available.\n" );
+ print("[AREImporter]: No lightmap available.");
return NULL;
}
@@ -376,7 +406,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
ResourceHolder<ImageMgr> sr(TmpResRef);
if (!sr) {
- printf( "[AREImporter]: No searchmap available.\n" );
+ print("[AREImporter]: No searchmap available.");
return NULL;
}
@@ -384,7 +414,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
ResourceHolder<ImageMgr> hm(TmpResRef);
if (!hm) {
- printf( "[AREImporter]: No heightmap available.\n" );
+ print("[AREImporter]: No heightmap available.");
return NULL;
}
@@ -415,7 +445,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
str->ReadWord( &map->RestHeader.DayChance );
str->ReadWord( &map->RestHeader.NightChance );
- printf( "Loading regions\n" );
+ print("Loading regions");
core->LoadProgress(70);
//Loading InfoPoints
for (i = 0; i < InfoPointsCount; i++) {
@@ -446,7 +476,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
str->ReadWord( &VertexCount );
str->ReadDword( &FirstVertex );
ieDword tmp2;
- str->ReadDword( &tmp2 );
+ str->ReadDword( &tmp2 ); //named triggerValue in the IE source
str->ReadDword( &Cursor );
str->ReadResRef( Destination );
str->Read( Entrance, 32 );
@@ -466,11 +496,21 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
str->ReadWord( &PosY);
//maybe we have to store this
str->Seek( 36, GEM_CURRENT_POS );
- str->ReadResRef( WavResRef );
- str->ReadWord( &TalkX);
- str->ReadWord( &TalkY);
- str->ReadDword( &DialogName );
- str->ReadResRef( DialogResRef );
+
+ if (core->HasFeature(GF_CLEAR_UNUSED_AREA)) {
+ memset( WavResRef, 0, sizeof(WavResRef));
+ TalkX = 0;
+ TalkY = 0;
+ DialogName = -1;
+ memset( DialogResRef, 0, sizeof(DialogResRef));
+ } else {
+ str->ReadResRef( WavResRef );
+ str->ReadWord( &TalkX);
+ str->ReadWord( &TalkY);
+ str->ReadDword( &DialogName );
+ str->ReadResRef( DialogResRef );
+ }
+
char* string = core->GetString( StrRef );
str->Seek( VerticesOffset + ( FirstVertex * 4 ), GEM_STREAM_START );
Point* points = ( Point* ) malloc( VertexCount*sizeof( Point ) );
@@ -499,7 +539,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
ip->UsePoint.x = PosX;
ip->UsePoint.y = PosY;
//FIXME: PST doesn't use this field
- if (ip->Flags&TRAP_USEPOINT) {
+ if (ip->GetUsePoint()) {
ip->Pos = ip->UsePoint;
} else {
ip->Pos.x = bbox.x + ( bbox.w / 2 );
@@ -523,7 +563,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
}
}
- printf( "Loading containers\n" );
+ print("Loading containers");
//Loading Containers
for (i = 0; i < ContainersCount; i++) {
str->Seek( ContainersOffset + ( i * 0xC0 ), GEM_STREAM_START );
@@ -569,11 +609,11 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
//the vertex count is only 16 bits, there is a weird flag
//after it, which is usually 0, but sometimes set to 1
str->ReadWord( &vertCount );
- str->ReadWord( &unknown );
- //str->Read( Name, 32 );
+ str->ReadWord( &unknown ); //trigger range
+ //str->Read( Name, 32 ); //owner's scriptname
str->Seek( 32, GEM_CURRENT_POS);
str->ReadResRef( KeyResRef);
- str->Seek( 4, GEM_CURRENT_POS);
+ str->Seek( 4, GEM_CURRENT_POS); //break difficulty
str->ReadDword( &OpenFail );
str->Seek( VerticesOffset + ( firstIndex * 4 ), GEM_STREAM_START );
@@ -630,7 +670,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
c->OpenFail = OpenFail;
}
- printf( "Loading doors\n" );
+ print("Loading doors");
//Loading Doors
for (i = 0; i < DoorsCount; i++) {
str->Seek( DoorsOffset + ( i * 0xc8 ), GEM_STREAM_START );
@@ -653,12 +693,13 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
ieStrRef OpenStrRef;
ieStrRef NameStrRef;
ieResRef Dialog;
- ieDword Unknown54;
+ ieWord hp, ac;
str->Read( LongName, 32 );
LongName[32] = 0;
str->ReadResRef( ShortName );
str->ReadDword( &Flags );
+ Flags = FixIWD2DoorFlags(Flags, false);
str->ReadDword( &OpenFirstVertex );
str->ReadWord( &OpenVerticesCount );
str->ReadWord( &ClosedVerticesCount );
@@ -683,7 +724,8 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
str->ReadWord( &OpenImpededCount );
str->ReadWord( &ClosedImpededCount );
str->ReadDword( &ClosedFirstImpeded );
- str->ReadDword( &Unknown54);
+ str->ReadWord( &hp); //TODO: store these
+ str->ReadWord( &ac); //hitpoints AND armorclass, according to IE dev info
ieResRef OpenResRef, CloseResRef;
str->ReadResRef( OpenResRef );
str->ReadResRef( CloseResRef );
@@ -788,7 +830,8 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
door->cibcount = ClosedImpededCount;
door->SetMap(map);
- door->Unknown54 = Unknown54;
+ door->hp = hp;
+ door->ac = ac;
door->TrapDetectionDiff = TrapDetect;
door->TrapRemovalDiff = TrapRemoval;
door->Trapped = Trapped;
@@ -810,7 +853,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
if (OpenResRef[0])
memcpy( door->OpenSound, OpenResRef, sizeof(OpenResRef) );
else {
- if (Flags & DOOR_HIDDEN)
+ if (Flags & DOOR_SECRET)
memcpy( door->OpenSound, Sounds[DEF_HOPEN], 9 );
else
memcpy( door->OpenSound, Sounds[DEF_OPEN], 9 );
@@ -818,7 +861,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
if (CloseResRef[0])
memcpy( door->CloseSound, CloseResRef, sizeof(CloseResRef) );
else {
- if (Flags & DOOR_HIDDEN)
+ if (Flags & DOOR_SECRET)
memcpy( door->CloseSound, Sounds[DEF_HCLOSE], 9 );
else
memcpy( door->CloseSound, Sounds[DEF_CLOSE], 9 );
@@ -833,7 +876,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
door->SetDialog(Dialog);
}
- printf( "Loading spawnpoints\n" );
+ print("Loading spawnpoints");
//Loading SpawnPoints
for (i = 0; i < SpawnCount; i++) {
str->Seek( SpawnOffset + (i*0xc8), GEM_STREAM_START );
@@ -888,11 +931,11 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
}
core->LoadProgress(75);
- printf( "Loading actors\n" );
+ print("Loading actors");
//Loading Actors
str->Seek( ActorOffset, GEM_STREAM_START );
if (!core->IsAvailable( IE_CRE_CLASS_ID )) {
- printf( "[AREImporter]: No Actor Manager Available, skipping actors\n" );
+ print("[AREImporter]: No Actor Manager Available, skipping actors");
} else {
PluginHolder<ActorMgr> actmgr(IE_CRE_CLASS_ID);
for (i = 0; i < ActorCount; i++) {
@@ -922,9 +965,9 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
memset(Scripts,0,sizeof(Scripts));
str->ReadResRef( Scripts[SCR_OVERRIDE] );
+ str->ReadResRef( Scripts[SCR_GENERAL] );
str->ReadResRef( Scripts[SCR_CLASS] );
str->ReadResRef( Scripts[SCR_RACE] );
- str->ReadResRef( Scripts[SCR_GENERAL] );
str->ReadResRef( Scripts[SCR_DEFAULT] );
str->ReadResRef( Scripts[SCR_SPECIFICS] );
str->ReadResRef( CreResRef );
@@ -943,28 +986,42 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
//actually, Flags&1 signs that the creature
//is not loaded yet, so !(Flags&1) means it is embedded
if (CreOffset != 0 && !(Flags&1) ) {
- CachedFileStream *fs = new CachedFileStream( (CachedFileStream *) str, CreOffset, CreSize, true);
- crefile = (DataStream *) fs;
+ crefile = SliceStream( str, CreOffset, CreSize, true );
} else {
crefile = gamedata->GetResource( CreResRef, IE_CRE_CLASS_ID );
}
- if(!actmgr->Open( crefile, true )) {
- printf("Couldn't read actor: %s!\n", CreResRef);
+ if(!actmgr->Open(crefile)) {
+ print("Couldn't read actor: %s!", CreResRef);
continue;
}
ab = actmgr->GetActor(0);
if(!ab)
continue;
- map->AddActor(ab);
+ map->AddActor(ab, false);
ab->Pos.x = XPos;
ab->Pos.y = YPos;
- ab->Destination.x = XDes;
- ab->Destination.y = YDes;
+ ab->Destination.x = XPos;
+ ab->Destination.y = YPos;
+ ab->HomeLocation.x = XDes;
+ ab->HomeLocation.y = YDes;
//copying the scripting name into the actor
//if the CreatureAreaFlag was set to 8
if ((Flags&AF_NAME_OVERRIDE) || (core->HasFeature(GF_IWD2_SCRIPTNAME)) ) {
ab->SetScriptName(DefaultName);
}
+ //IWD2 specific hacks
+ if (core->HasFeature(GF_IWD2_SCRIPTNAME)) {
+ //This flag is used for something else in IWD2
+ if (Flags&AF_NAME_OVERRIDE) {
+ ab->BaseStats[IE_EA]=EA_EVILCUTOFF;
+ }
+ if (Flags&AF_SEEN_PARTY) {
+ ab->SetMCFlag(MC_SEENPARTY,BM_OR);
+ }
+ if (Flags&AF_INVULNERABLE) {
+ ab->SetMCFlag(MC_INVULNERABLE,BM_OR);
+ }
+ }
if (Dialog[0]) {
ab->SetDialog(Dialog);
@@ -984,16 +1041,16 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
}
core->LoadProgress(90);
- printf( "Loading animations\n" );
+ print("Loading animations");
//Loading Animations
str->Seek( AnimOffset, GEM_STREAM_START );
if (!core->IsAvailable( IE_BAM_CLASS_ID )) {
- printf( "[AREImporter]: No Animation Manager Available, skipping animations\n" );
+ print("[AREImporter]: No Animation Manager Available, skipping animations");
} else {
for (i = 0; i < AnimCount; i++) {
AreaAnimation* anim = new AreaAnimation();
str->Read(anim->Name, 32);
- ieWord animX, animY;
+ ieWord animX, animY, startFrameRange;
str->ReadWord( &animX );
str->ReadWord( &animY );
anim->Pos.x=animX;
@@ -1005,11 +1062,15 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
str->ReadDword( &anim->Flags );
str->ReadWordSigned( &anim->height );
str->ReadWord( &anim->transparency );
- str->ReadWord( &anim->unknown3c ); //not completely understood, if not 0, sequence is started
+ str->ReadWord( &startFrameRange );
str->Read( &anim->startchance,1 );
if (anim->startchance<=0) {
anim->startchance=100; //percentage of starting a cycle
}
+ if (startFrameRange && (anim->Flags&A_ANI_RANDOM_START) ) {
+ anim->frame = rand() % startFrameRange;
+ }
+ anim->startFrameRange = 0; //this will never get resaved (iirc)
str->Read( &anim->skipcycle,1 ); //how many cycles are skipped (100% skippage)
str->ReadResRef( anim->PaletteRef );
str->ReadDword( &anim->unknown48 );
@@ -1023,7 +1084,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
}
}
- printf( "Loading entrances\n" );
+ print("Loading entrances");
//Loading Entrances
str->Seek( EntrancesOffset, GEM_STREAM_START );
for (i = 0; i < EntrancesCount; i++) {
@@ -1038,7 +1099,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
map->AddEntrance( Name, XPos, YPos, Face );
}
- printf( "Loading variables\n" );
+ print("Loading variables");
map->locals->LoadInitialValues(ResRef);
//Loading Variables
str->Seek( VariablesOffset, GEM_STREAM_START );
@@ -1053,7 +1114,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
map->locals->SetAt( Name, Value );
}
- printf( "Loading ambients\n" );
+ print("Loading ambients");
str->Seek( AmbiOffset, GEM_STREAM_START );
for (i = 0; i < AmbiCount; i++) {
int j;
@@ -1093,14 +1154,9 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
map->AddAmbient(ambi);
}
- printf( "Loading automap notes\n" );
+ print("Loading automap notes");
str->Seek( NoteOffset, GEM_STREAM_START );
- //this feature exists in all blackisle games but not in bioware games
- if (core->HasFeature(GF_SPAWN_INI)) {
- map->LoadIniSpawn();
- }
-
Point point;
ieDword color;
char *text;
@@ -1168,14 +1224,13 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
}
//this is a ToB feature (saves the unexploded projectiles)
- printf( "Loading traps\n" );
+ print("Loading traps");
for (i = 0; i < TrapCount; i++) {
ieResRef TrapResRef;
ieDword TrapEffOffset;
ieWord TrapSize, ProID;
- ieWord X,Y;
+ ieWord X,Y,Z;
ieDword Ticks;
- ieWord Unknown;
ieByte PartyID;
ieByte Owner;
@@ -1185,16 +1240,16 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
str->ReadDword( &TrapEffOffset );
str->ReadWord( &TrapSize );
str->ReadWord( &ProID );
- str->ReadDword( &Ticks );
+ str->ReadDword( &Ticks ); //actually, delaycount/repetitioncount
str->ReadWord( &X );
str->ReadWord( &Y );
- str->ReadWord( &Unknown );
- str->Read( &PartyID,1 );
+ str->ReadWord( &Z );
+ str->Read( &PartyID,1 ); //according to dev info, this is 'targettype'
str->Read( &Owner,1 );
int TrapEffectCount = TrapSize/0x108;
if(TrapEffectCount*0x108!=TrapSize) {
- printMessage("AREImporter", " ", LIGHT_RED);
- printf("TrapEffectSize in game: %d != %d. Clearing it\n", TrapSize, TrapEffectCount*0x108);
+ Log(ERROR, "AREImporter", "TrapEffectSize in game: %d != %d. Clearing it",
+ TrapSize, TrapEffectCount*0x108);
continue;
}
//The projectile is always created, the worst that can happen
@@ -1205,7 +1260,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
//This could be wrong on msvc7 with its separate memory managers
EffectQueue *fxqueue = new EffectQueue();
- CachedFileStream *fs = new CachedFileStream( (CachedFileStream *) str, TrapEffOffset, TrapSize, true);
+ DataStream *fs = new SlicedStream( str, TrapEffOffset, TrapSize);
ReadEffects((DataStream *) fs,fxqueue, TrapEffectCount);
Actor * caster = core->GetGame()->FindPC(PartyID);
@@ -1218,30 +1273,43 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
map->AddProjectile( pro, pos, pos);
}
- printf( "Loading tiles\n" );
+ print("Loading tiles");
//Loading Tiled objects (if any)
str->Seek( TileOffset, GEM_STREAM_START );
for (i = 0; i < TileCount; i++) {
ieVariable Name;
ieResRef ID;
ieDword Flags;
- ieDword OpenIndex, OpenCount;
- ieDword ClosedIndex, ClosedCount;
+ //these fields could be different size
+ //ieDword ClosedCount, OpenCount;
+ ieWord ClosedCount, OpenCount;
+ ieDword ClosedIndex, OpenIndex;
str->Read( Name, 32 );
Name[32] = 0;
str->ReadResRef( ID );
str->ReadDword( &Flags );
+ //TODO check this structure again
+/*
str->ReadDword( &OpenIndex );
str->ReadDword( &OpenCount );
str->ReadDword( &ClosedIndex );
str->ReadDword( &ClosedCount );
+*/
+ //IE dev info says this:
+ str->ReadDword( &OpenIndex );
+ str->ReadWord( &OpenCount );
+ str->ReadWord( &ClosedCount );
+ str->ReadDword( &ClosedIndex );
+ //end of disputed section
+
+
str->Seek( 48, GEM_CURRENT_POS );
//absolutely no idea where these 'tile indices' are stored
//are they tileset tiles or impeded block tiles
map->TMap->AddTile( ID, Name, Flags, NULL,0, NULL, 0 );
}
- printf( "Loading explored bitmap\n" );
+ print("Loading explored bitmap");
i = map->GetExploredMapSize();
if (ExploredBitmapSize==i) {
map->ExploredBitmap = (ieByte *) malloc(i);
@@ -1250,21 +1318,22 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night)
}
else {
if( ExploredBitmapSize ) {
- printMessage("AREImporter", " ", LIGHT_RED);
- printf("ExploredBitmapSize in game: %d != %d. Clearing it\n", ExploredBitmapSize, i);
+ Log(ERROR, "AREImporter", "ExploredBitmapSize in game: %d != %d. Clearing it",
+ ExploredBitmapSize, i);
}
ExploredBitmapSize = i;
map->ExploredBitmap = (ieByte *) calloc(i, 1);
}
map->VisibleBitmap = (ieByte *) calloc(i, 1);
- printf( "Loading wallgroups\n");
+ print("Loading wallgroups");
map->SetWallGroups( tmm->GetPolygonsCount(),tmm->GetWallGroups() );
//setting up doors
for (i=0;i<DoorsCount;i++) {
Door *door = tm->GetDoor(i);
door->SetDoorOpen(door->IsOpen(), false, 0);
}
+
return map;
}
@@ -1273,7 +1342,7 @@ void AREImporter::ReadEffects(DataStream *ds, EffectQueue *fxqueue, ieDword Effe
unsigned int i;
PluginHolder<EffectMgr> eM(IE_EFF_CLASS_ID);
- eM->Open( ds, true );
+ eM->Open(ds);
for (i = 0; i < EffectsCount; i++) {
Effect fx;
@@ -1499,6 +1568,7 @@ int AREImporter::PutDoors( DataStream *stream, Map *map, ieDword &VertIndex)
stream->Write( d->GetScriptName(), 32);
stream->WriteResRef( d->ID);
+ d->Flags = FixIWD2DoorFlags(d->Flags, true);
stream->WriteDword( &d->Flags);
stream->WriteDword( &VertIndex);
tmpWord = (ieWord) d->open->count;
@@ -1535,7 +1605,8 @@ int AREImporter::PutDoors( DataStream *stream, Map *map, ieDword &VertIndex)
stream->WriteWord( &tmpWord);
stream->WriteDword( &VertIndex);
VertIndex += tmpWord;
- stream->WriteDword( &d->Unknown54);
+ stream->WriteWord( &d->hp);
+ stream->WriteWord( &d->ac);
stream->WriteResRef( d->OpenSound);
stream->WriteResRef( d->CloseSound);
stream->WriteDword( &d->Cursor);
@@ -1841,9 +1912,9 @@ int AREImporter::PutActors( DataStream *stream, Map *map)
stream->WriteWord( &tmpWord);
tmpWord = (ieWord) ac->Pos.y;
stream->WriteWord( &tmpWord);
- tmpWord = (ieWord) ac->Destination.x;
+ tmpWord = (ieWord) ac->HomeLocation.x;
stream->WriteWord( &tmpWord);
- tmpWord = (ieWord) ac->Destination.y;
+ tmpWord = (ieWord) ac->HomeLocation.y;
stream->WriteWord( &tmpWord);
stream->WriteDword( &tmpDword); //used fields flag always 0 for saved areas
@@ -1859,9 +1930,9 @@ int AREImporter::PutActors( DataStream *stream, Map *map)
stream->WriteDword( &ac->TalkCount);
stream->WriteResRef( ac->GetDialog());
PutScript(stream, ac, SCR_OVERRIDE);
+ PutScript(stream, ac, SCR_GENERAL);
PutScript(stream, ac, SCR_CLASS);
PutScript(stream, ac, SCR_RACE);
- PutScript(stream, ac, SCR_GENERAL);
PutScript(stream, ac, SCR_DEFAULT);
PutScript(stream, ac, SCR_SPECIFICS);
//creature reference is empty because we are embedding it
@@ -1907,7 +1978,7 @@ int AREImporter::PutAnimations( DataStream *stream, Map *map)
stream->WriteDword( &an->Flags);
stream->WriteWord( (ieWord *) &an->height);
stream->WriteWord( &an->transparency);
- stream->WriteWord( &an->unknown3c); //animation already played?
+ stream->WriteWord( &an->startFrameRange); //used by A_ANI_RANDOM_START
stream->Write( &an->startchance,1);
stream->Write( &an->skipcycle,1);
stream->WriteResRef( an->PaletteRef);
@@ -2010,7 +2081,7 @@ int AREImporter::PutMapnotes( DataStream *stream, Map *map)
int x;
if (pst) {
- tmpDword = (ieWord) mn->Pos.x;
+ tmpDword = (ieDword) mn->Pos.x;
stream->WriteDword( &tmpDword );
tmpDword = (ieDword) mn->Pos.y;
stream->WriteDword( &tmpDword );
@@ -2025,8 +2096,8 @@ int AREImporter::PutMapnotes( DataStream *stream, Map *map)
if (x) {
stream->Write( filling, x);
}
- stream->WriteWord( &mn->color);
- stream->WriteWord( &tmpWord);
+ tmpDword = (ieDword) mn->color;
+ stream->WriteDword(&tmpDword);
for (x=0;x<5;x++) { //5 empty dwords
stream->Write( filling, 4);
}
diff --git a/gemrb/plugins/AREImporter/AREImporter.h b/gemrb/plugins/AREImporter/AREImporter.h
index db80154..825864b 100644
--- a/gemrb/plugins/AREImporter/AREImporter.h
+++ b/gemrb/plugins/AREImporter/AREImporter.h
@@ -23,13 +23,17 @@
#include "MapMgr.h"
+#include "Map.h" // proIterator
+
+namespace GemRB {
+
class Animation;
class AnimationFactory;
+class EffectQueue;
class AREImporter : public MapMgr {
private:
DataStream* str;
- bool autoFree;
int bigheader;
ieResRef WEDResRef;
ieDword LastSave;
@@ -57,7 +61,7 @@ private:
public:
AREImporter(void);
~AREImporter(void);
- bool Open(DataStream* stream, bool autoFree = true);
+ bool Open(DataStream* stream);
bool ChangeMap(Map *map, bool day_or_night);
Map* GetMap(const char* ResRef, bool day_or_night);
int GetStoredFileSize(Map *map);
@@ -89,4 +93,6 @@ private:
int PutSongHeader(DataStream *stream, Map *map);
};
+}
+
#endif
diff --git a/gemrb/plugins/BAMImporter/BAMFont.cpp b/gemrb/plugins/BAMImporter/BAMFont.cpp
new file mode 100644
index 0000000..b35bc63
--- /dev/null
+++ b/gemrb/plugins/BAMImporter/BAMFont.cpp
@@ -0,0 +1,88 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "BAMFont.h"
+#include "Interface.h"
+#include "Sprite2D.h"
+#include "Video.h"
+
+namespace GemRB {
+
+BAMFont::BAMFont(AnimationFactory* af, int* baseline)
+{
+ factory = af;
+ maxHeight = 0;
+ Sprite2D* curGlyph = NULL;
+ bool isNumeric = (af->GetCycleCount() <= 1);
+
+ for (size_t i = 0; i < af->GetFrameCount(); i++) {
+ curGlyph = af->GetFrameWithoutCycle(i);
+ if (curGlyph) {
+ if (curGlyph->Height > maxHeight)
+ maxHeight = curGlyph->Height;
+ curGlyph->XPos = 0;
+ if (isNumeric) {
+ // we want them to have the same baseline as the rest
+ curGlyph->YPos = 13 - curGlyph->Height;
+ } else if (baseline) {
+ curGlyph->YPos = *baseline;
+ }
+ curGlyph->release();
+ }
+ }
+
+ // assume all sprites have same palette
+ Sprite2D* first = af->GetFrameWithoutCycle(0);
+ Palette* pal = first->GetPalette();
+ SetPalette(pal);
+ pal->Release();
+ first->release();
+
+ blank = core->GetVideoDriver()->CreateSprite8(0, 0, 8, NULL, palette->col);
+}
+
+BAMFont::~BAMFont()
+{
+ delete factory;
+}
+
+const Sprite2D* BAMFont::GetCharSprite(ieWord chr) const
+{
+ if (chr == 0) return blank;
+ Sprite2D* spr = NULL;
+ size_t cycleCount = factory->GetCycleCount();
+ if (cycleCount > 1) {
+ ieByte frame = ((chr >> 8) > 0) ? (chr >> 8) - 1 : 0; // multibyte char when > 0
+ ieByte cycle = chr; // purposely truncating bits
+ spr = factory->GetFrame(frame, cycle-1);
+ } else {
+ // numeric font
+ spr = factory->GetFrameWithoutCycle(chr - '0');
+ }
+ if (!spr) {
+ Log(ERROR, "BAMFont", "%s missing glyph for character '%x' using %s encoding.", name, chr, core->TLKEncoding.c_str());
+ spr = blank;
+ } else {
+ spr->release();
+ }
+ return spr;
+}
+
+}
diff --git a/gemrb/plugins/BAMImporter/BAMFont.h b/gemrb/plugins/BAMImporter/BAMFont.h
new file mode 100644
index 0000000..298b565
--- /dev/null
+++ b/gemrb/plugins/BAMImporter/BAMFont.h
@@ -0,0 +1,46 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+//This class represents game fonts. Fonts are special .bam files.
+//Each cycle stands for a letter. except for numerical or "multibyte" fonts
+
+#ifndef __GemRB__BAMFont__
+#define __GemRB__BAMFont__
+
+#include "AnimationFactory.h"
+#include "Font.h"
+
+namespace GemRB {
+
+class BAMFont : public Font
+{
+private:
+ AnimationFactory* factory;
+
+public:
+ BAMFont(AnimationFactory* af, int* baseline = NULL);
+ ~BAMFont(void);
+
+ const Sprite2D* GetCharSprite(ieWord chr) const;
+};
+
+}
+
+#endif /* defined(__GemRB__BAMFont__) */
diff --git a/gemrb/plugins/BAMImporter/BAMFontManager.cpp b/gemrb/plugins/BAMImporter/BAMFontManager.cpp
new file mode 100644
index 0000000..6c967f7
--- /dev/null
+++ b/gemrb/plugins/BAMImporter/BAMFontManager.cpp
@@ -0,0 +1,79 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "BAMFont.h"
+#include "BAMFontManager.h"
+#include "Palette.h"
+#include "Sprite2D.h"
+
+using namespace GemRB;
+
+BAMFontManager::~BAMFontManager(void)
+{
+ delete bamImp;
+}
+
+BAMFontManager::BAMFontManager(void)
+{
+ isStateFont = false;
+ bamImp = new BAMImporter();
+ memset(resRef, 0, sizeof(ieResRef));
+}
+
+bool BAMFontManager::Open(DataStream* stream)
+{
+ ieWord len = strlench(stream->filename, '.');
+ len = (len <= sizeof(ieResRef)-1) ? len : sizeof(ieResRef)-1;
+ strncpy(resRef, stream->filename, len);
+ // compare only first 6 chars so we can match states2 or others
+ if (strnicmp(resRef, "STATES", 6) == 0) {
+ isStateFont = true;
+ }
+ return bamImp->Open(stream);
+}
+
+Font* BAMFontManager::GetFont(unsigned short /*ptSize*/,
+ FontStyle /*style*/, Palette* pal)
+{
+ AnimationFactory* af = bamImp->GetAnimationFactory(resRef); // released by BAMFont
+
+ Font* fnt = NULL;
+ if (isStateFont) {
+ // Hack to work around original data where some status icons have inverted x and y positions (ie level up icon)
+ // isStateFont is set in Open() and simply compares the first 6 characters of the file with "STATES"
+
+ // since state icons should all be the same size/position we can just take the position of the first one
+ Sprite2D* first = af->GetFrame(0, 0);
+ int pos = first->YPos; // baseline
+ first->release();
+ fnt = new BAMFont(af, &pos);
+ } else {
+ fnt = new BAMFont(af, NULL);
+ }
+
+ if (!fnt) {
+ delete af;
+ return NULL;
+ }
+ if (pal) {
+ fnt->SetPalette(pal);
+ }
+ return fnt;
+}
diff --git a/gemrb/plugins/BAMImporter/BAMFontManager.h b/gemrb/plugins/BAMImporter/BAMFontManager.h
new file mode 100644
index 0000000..7567c54
--- /dev/null
+++ b/gemrb/plugins/BAMImporter/BAMFontManager.h
@@ -0,0 +1,53 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef GemRB_BAMFontManager_h
+#define GemRB_BAMFontManager_h
+
+#include "FontManager.h"
+#include "BAMImporter.h"
+
+namespace GemRB {
+
+class BAMFontManager : public FontManager
+{
+private:
+ /** private data members */
+ BAMImporter* bamImp;
+ bool isStateFont;
+ ieResRef resRef;
+public:
+ /** public data members */
+private:
+ void AddChar(unsigned char* spr, int w, int h, short xPos, short yPos);
+public:
+ /** public methods */
+ ~BAMFontManager(void);
+ BAMFontManager(void);
+
+ bool Open(DataStream* stream);
+
+ Font* GetFont(unsigned short ptSize,
+ FontStyle style, Palette* pal = NULL);
+};
+
+}
+
+#endif
diff --git a/gemrb/plugins/BAMImporter/BAMImporter.cpp b/gemrb/plugins/BAMImporter/BAMImporter.cpp
index 8531158..38262ba 100644
--- a/gemrb/plugins/BAMImporter/BAMImporter.cpp
+++ b/gemrb/plugins/BAMImporter/BAMImporter.cpp
@@ -18,10 +18,6 @@
*
*/
-#if defined(__HAIKU__)
-#include <unistd.h>
-#endif
-
#ifdef ANDROID
#include "swab.h"
#endif
@@ -30,17 +26,23 @@
#include "win32def.h"
-#include "Compressor.h"
+#include "FileCache.h"
#include "GameData.h"
#include "Interface.h"
#include "Palette.h"
+#include "Sprite2D.h"
#include "Video.h"
#include "System/FileStream.h"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+using namespace GemRB;
+
BAMImporter::BAMImporter(void)
{
str = NULL;
- autoFree = false;
frames = NULL;
cycles = NULL;
palette = NULL;
@@ -50,72 +52,35 @@ BAMImporter::BAMImporter(void)
BAMImporter::~BAMImporter(void)
{
- if (str && autoFree) {
- delete( str );
- }
+ delete str;
delete[] frames;
delete[] cycles;
gamedata->FreePalette(palette);
}
-bool BAMImporter::Open(DataStream* stream, bool autoFree)
+bool BAMImporter::Open(DataStream* stream)
{
unsigned int i;
if (stream == NULL) {
return false;
}
- if (str && this->autoFree) {
- delete( str );
- }
+ delete str;
delete[] frames;
delete[] cycles;
gamedata->FreePalette(palette);
str = stream;
- this->autoFree = autoFree;
char Signature[8];
str->Read( Signature, 8 );
if (strncmp( Signature, "BAMCV1 ", 8 ) == 0) {
- //Check if Decompressed file has already been Cached
- char cpath[_MAX_PATH];
- strcpy( cpath, core->CachePath );
- strcat( cpath, stream->filename );
- FILE* exist_in_cache = fopen( cpath, "rb" );
- if (exist_in_cache) {
- //File was previously cached, using local copy
- if (autoFree) {
- delete( str );
- }
- fclose( exist_in_cache );
- FileStream* s = new FileStream();
- s->Open( cpath );
- str = s;
- str->Read( Signature, 8 );
- } else {
- //No file found in Cache, Decompressing and storing for further use
- str->Seek( 4, GEM_CURRENT_POS );
-
- if (!core->IsAvailable( PLUGIN_COMPRESSION_ZLIB )) {
- printf( "No Compression Manager Available.\nCannot Load Compressed Bam File.\n" );
- return false;
- }
- FILE* newfile = fopen( cpath, "wb" );
- if (!newfile) {
- printMessage("BAMImporter", " ", RED);
- printf( "Cannot write %s.\n", cpath );
- return false;
- }
- PluginHolder<Compressor> comp(PLUGIN_COMPRESSION_ZLIB);
- comp->Decompress( newfile, str );
- fclose( newfile );
- if (autoFree)
- delete( str );
- FileStream* s = new FileStream();
- s->Open( cpath );
- str = s;
- str->Read( Signature, 8 );
- }
+ str->Seek( 4, GEM_CURRENT_POS );
+ DataStream* cached = CacheCompressedStream(stream, stream->filename);
+ delete str;
+ if (!cached)
+ return false;
+ str = cached;
+ str->Read( Signature, 8 );
}
if (strncmp( Signature, "BAM V1 ", 8 ) != 0) {
return false;
@@ -167,8 +132,8 @@ int BAMImporter::GetCycleSize(unsigned char Cycle)
}
Sprite2D* BAMImporter::GetFrameInternal(unsigned short findex, unsigned char mode,
- bool BAMsprite, const unsigned char* data,
- AnimationFactory* datasrc)
+ bool BAMsprite, const unsigned char* data,
+ AnimationFactory* datasrc)
{
Sprite2D* spr = 0;
@@ -178,15 +143,12 @@ Sprite2D* BAMImporter::GetFrameInternal(unsigned short findex, unsigned char mod
assert(data);
const unsigned char* framedata = data;
framedata += (frames[findex].FrameData & 0x7FFFFFFF) - DataStart;
- if (RLECompressed) {
- spr = core->GetVideoDriver()->CreateSpriteBAM8(
- frames[findex].Width, frames[findex].Height,
- true, framedata, datasrc, palette, CompressedColorIndex);
- } else {
- spr = core->GetVideoDriver()->CreateSpriteBAM8(
- frames[findex].Width, frames[findex].Height, false,
- framedata, datasrc, palette, CompressedColorIndex );
- }
+ spr = core->GetVideoDriver()->CreateSpriteBAM8(frames[findex].Width,
+ frames[findex].Height,
+ RLECompressed,
+ framedata, datasrc,
+ palette,
+ CompressedColorIndex);
} else {
void* pixels = GetFramePixels(findex);
spr = core->GetVideoDriver()->CreateSprite8(
@@ -228,6 +190,7 @@ void* BAMImporter::GetFramePixels(unsigned short findex)
unsigned char* inpix;
inpix = (unsigned char*)malloc( RLESize );
if (str->Read( inpix, RLESize ) == GEM_ERROR) {
+ free( pixels );
free( inpix );
return NULL;
}
@@ -244,7 +207,7 @@ void* BAMImporter::GetFramePixels(unsigned short findex)
// into override/ dir?
if (i + ( *p ) + 1 > pixelcount) {
memset( &Buffer[i], CompressedColorIndex, pixelcount - i );
- printf ("Broken frame %d\n", findex);
+ print("Broken frame %d", findex);
} else {
memset( &Buffer[i], CompressedColorIndex, ( *p ) + 1 );
}
@@ -314,68 +277,6 @@ AnimationFactory* BAMImporter::GetAnimationFactory(const char* ResRef, unsigned
return af;
}
-/** This function will load the Animation as a Font */
-Font* BAMImporter::GetFont()
-{
- unsigned int i;
-
- int w = 0, h = 0;
- unsigned int Count;
-
- ieWord *FLT = CacheFLT(Count);
-
- // Numeric fonts have all frames in single cycle
- if (CyclesCount > 1) {
- Count = CyclesCount;
- } else {
- Count = FramesCount;
- }
-
- for (i = 0; i < Count; i++) {
- unsigned int index;
- if (CyclesCount > 1) {
- index = FLT[cycles[i].FirstFrame];
- if (index >= FramesCount)
- continue;
- } else {
- index = i;
- }
-
- w = w + frames[index].Width;
- if (frames[index].Height > h)
- h = frames[index].Height;
- }
-
- Font* fnt = new Font( w, h, palette );
- for (i = 0; i < Count; i++) {
- unsigned int index;
- if (CyclesCount > 1) {
- index = FLT[cycles[i].FirstFrame];
- if (index >= FramesCount) {
- fnt->AddChar( NULL, 0, 0, 0, 0 );
- continue;
- }
- } else {
- index = i;
- }
-
- unsigned char* pixels = (unsigned char*)GetFramePixels( index );
- if( !pixels) {
- fnt->AddChar( NULL, 0, 0, 0, 0 );
- continue;
- }
- fnt->AddChar( pixels, frames[index].Width,
- frames[index].Height,
- frames[index].XPos,
- frames[index].YPos );
- free( pixels );
- }
- free( FLT );
-
- fnt->FinalizeSprite( true, 0 );
-
- return fnt;
-}
/** Debug Function: Returns the Global Animation Palette as a Sprite2D Object.
If the Global Animation Palette is NULL, returns NULL. */
Sprite2D* BAMImporter::GetPalette()
@@ -388,8 +289,11 @@ Sprite2D* BAMImporter::GetPalette()
return core->GetVideoDriver()->CreateSprite8( 16, 16, 8, pixels, palette->col, false );
}
+#include "BAMFontManager.h"
+
#include "plugindef.h"
GEMRB_PLUGIN(0x3AD6427A, "BAM File Importer")
+PLUGIN_IE_RESOURCE(BAMFontManager, "bam", (ieWord)IE_BAM_CLASS_ID)
PLUGIN_CLASS(IE_BAM_CLASS_ID, BAMImporter)
END_PLUGIN()
diff --git a/gemrb/plugins/BAMImporter/BAMImporter.h b/gemrb/plugins/BAMImporter/BAMImporter.h
index be59c35..9e67008 100644
--- a/gemrb/plugins/BAMImporter/BAMImporter.h
+++ b/gemrb/plugins/BAMImporter/BAMImporter.h
@@ -26,6 +26,8 @@
#include "RGBAColor.h"
#include "globals.h"
+namespace GemRB {
+
struct FrameEntry {
ieWord Width;
ieWord Height;
@@ -39,7 +41,6 @@ class Palette;
class BAMImporter : public AnimationMgr {
private:
DataStream* str;
- bool autoFree;
FrameEntry* frames;
CycleEntry* cycles;
ieWord FramesCount;
@@ -57,12 +58,10 @@ private:
public:
BAMImporter(void);
~BAMImporter(void);
- bool Open(DataStream* stream, bool autoFree = true);
+ bool Open(DataStream* stream);
int GetCycleSize(unsigned char Cycle);
AnimationFactory* GetAnimationFactory(const char* ResRef,
unsigned char mode = IE_NORMAL);
- /** This function will load the Animation as a Font */
- Font* GetFont();
/** Debug Function: Returns the Global Animation Palette as a Sprite2D Object.
If the Global Animation Palette is NULL, returns NULL. */
Sprite2D* GetPalette();
@@ -87,4 +86,6 @@ public:
}
};
+}
+
#endif
diff --git a/gemrb/plugins/BAMImporter/CMakeLists.txt b/gemrb/plugins/BAMImporter/CMakeLists.txt
index 1152b8e..d43a241 100644
--- a/gemrb/plugins/BAMImporter/CMakeLists.txt
+++ b/gemrb/plugins/BAMImporter/CMakeLists.txt
@@ -1 +1 @@
-ADD_GEMRB_PLUGIN (BAMImporter BAMImporter.cpp)
+ADD_GEMRB_PLUGIN (BAMImporter BAMImporter.cpp BAMFontManager BAMFont.cpp)
diff --git a/gemrb/plugins/BAMImporter/Makefile.am b/gemrb/plugins/BAMImporter/Makefile.am
index 8907c33..6178327 100644
--- a/gemrb/plugins/BAMImporter/Makefile.am
+++ b/gemrb/plugins/BAMImporter/Makefile.am
@@ -1,3 +1,3 @@
plugin_LTLIBRARIES = BAMImporter.la
BAMImporter_la_LDFLAGS = -module -avoid-version -shared
-BAMImporter_la_SOURCES = BAMImporter.cpp BAMImporter.h
+BAMImporter_la_SOURCES = BAMImporter.cpp BAMImporter.h BAMFontManager.cpp BAMFontManager.h
diff --git a/gemrb/plugins/BIFImporter/BIFImporter.cpp b/gemrb/plugins/BIFImporter/BIFImporter.cpp
index ccee859..0138fdc 100644
--- a/gemrb/plugins/BIFImporter/BIFImporter.cpp
+++ b/gemrb/plugins/BIFImporter/BIFImporter.cpp
@@ -23,10 +23,14 @@
#include "win32def.h"
#include "Compressor.h"
+#include "FileCache.h"
#include "Interface.h"
-#include "System/CachedFileStream.h"
+#include "PluginMgr.h"
+#include "System/SlicedStream.h"
#include "System/FileStream.h"
+using namespace GemRB;
+
BIFImporter::BIFImporter(void)
{
stream = NULL;
@@ -47,237 +51,113 @@ BIFImporter::~BIFImporter(void)
}
}
-int BIFImporter::DecompressSaveGame(DataStream *compressed)
+DataStream* BIFImporter::DecompressBIFC(DataStream* compressed, const char* path)
{
- char Signature[8];
- compressed->Read( Signature, 8 );
- if (strncmp( Signature, "SAV V1.0", 8 ) ) {
- return GEM_ERROR;
- }
- int All = compressed->Remains();
- int Current;
- if (!All) return GEM_ERROR;
- do {
- ieDword fnlen, complen, declen;
- compressed->ReadDword( &fnlen );
- char* fname = ( char* ) malloc( fnlen );
- compressed->Read( fname, fnlen );
- strlwr(fname);
+ print("Decompressing");
+ if (!core->IsAvailable( PLUGIN_COMPRESSION_ZLIB ))
+ return NULL;
+ PluginHolder<Compressor> comp(PLUGIN_COMPRESSION_ZLIB);
+ ieDword unCompBifSize;
+ compressed->ReadDword( &unCompBifSize );
+ //print( "\nDecompressing file: [..........]" );
+ fflush(stdout);
+ FileStream out;
+ if (!out.Create(path)) {
+ Log(ERROR, "BIFImporter", "Cannot write %s.", path);
+ return NULL;
+ }
+ ieDword finalsize = 0;
+ int laststep = 0;
+ while (finalsize < unCompBifSize) {
+ ieDword complen, declen;
compressed->ReadDword( &declen );
compressed->ReadDword( &complen );
- PathJoin( path, core->CachePath, fname, NULL );
- printf( "Decompressing %s\n",fname );
- free( fname );
- if (!core->IsAvailable( PLUGIN_COMPRESSION_ZLIB ))
- return GEM_ERROR;
- FILE *in_cache = fopen( path, "wb" );
- if (!in_cache) {
- printMessage("BIFImporter", " ", RED);
- printf( "Cannot write %s.\n", path );
- return GEM_ERROR;
+ if (comp->Decompress( &out, compressed, complen ) != GEM_OK) {
+ return NULL;
}
- PluginHolder<Compressor> comp(PLUGIN_COMPRESSION_ZLIB);
- if (comp->Decompress( in_cache, compressed, complen ) != GEM_OK) {
- return GEM_ERROR;
+ finalsize = out.GetPos();
+ if (( int ) ( finalsize * ( 10.0 / unCompBifSize ) ) != laststep) {
+ laststep++;
+ /*
+ print( "\b\b\b\b\b\b\b\b\b\b\b" );
+ int l;
+
+ for (l = 0; l < laststep; l++)
+ print( "|" );
+ for (; l < 10; l++)//l starts from laststep
+ print( "." );
+ print( "]" );
+ fflush(stdout);
+ */
}
- fclose( in_cache );
- Current = compressed->Remains();
- //starting at 20% going up to 70%
- core->LoadProgress( 20+(All-Current)*50/All );
- }
- while(Current);
- return GEM_OK;
-}
-
-//this one can create .sav files only
-int BIFImporter::CreateArchive(DataStream *compressed)
-{
- if (stream) {
- delete( stream );
- stream = NULL;
}
- if (!compressed) {
- return GEM_ERROR;
- }
- char Signature[8];
-
- memcpy(Signature,"SAV V1.0",8);
- compressed->Write(Signature, 8);
-
- return GEM_OK;
+ //print("\n");
+ out.Close(); // This is necesary, since windows won't open the file otherwise.
+ return FileStream::OpenFile(path);
}
-int BIFImporter::AddToSaveGame(DataStream *str, DataStream *uncompressed)
+DataStream* BIFImporter::DecompressBIF(DataStream* compressed, const char* /*path*/)
{
- ieDword fnlen, declen, complen;
-
- fnlen = strlen(uncompressed->filename)+1;
- declen = uncompressed->Size();
- str->WriteDword( &fnlen);
- str->Write( uncompressed->filename, fnlen);
- str->WriteDword( &declen);
- //baaah, we dump output right in the stream, we get the compressed length
- //only after the compressed data was written
- complen = 0xcdcdcdcd; //placeholder
- unsigned long Pos = str->GetPos(); //storing the stream position
- str->WriteDword( &complen);
-
- PluginHolder<Compressor> comp(PLUGIN_COMPRESSION_ZLIB);
- comp->Compress( str, uncompressed );
-
- //writing compressed length (calculated)
- unsigned long Pos2 = str->GetPos();
- complen = Pos2-Pos-sizeof(ieDword); //calculating the compressed stream size
- str->Seek(Pos, GEM_STREAM_START); //going back to the placeholder
- str->WriteDword( &complen); //updating size
- str->Seek(Pos2, GEM_STREAM_START);//resuming work
- return GEM_OK;
+ ieDword fnlen, complen, declen;
+ compressed->ReadDword( &fnlen );
+ compressed->Seek(fnlen, GEM_CURRENT_POS);
+ compressed->ReadDword(&declen);
+ compressed->ReadDword(&complen);
+ print("Decompressing");
+ return CacheCompressedStream(compressed, compressed->filename, complen);
}
-int BIFImporter::OpenArchive(const char* filename)
+int BIFImporter::OpenArchive(const char* path)
{
if (stream) {
delete( stream );
stream = NULL;
}
- FILE* in_cache = fopen( filename, "rb" );
- if( !in_cache) {
- return GEM_ERROR;
- }
+
+ char filename[_MAX_PATH];
+ ExtractFileFromPath(filename, path);
+
+ char cachePath[_MAX_PATH];
+ PathJoin(cachePath, core->CachePath, filename, NULL);
+ stream = FileStream::OpenFile(cachePath);
+
char Signature[8];
- if (fread( &Signature, 1, 8, in_cache ) != 8) {
- fclose ( in_cache );
- return GEM_ERROR;
- }
- fclose( in_cache );
- //normal bif, not in cache
- if (strncmp( Signature, "BIFFV1 ", 8 ) == 0) {
- stream = new CachedFileStream( filename );
- stream->Read( Signature, 8 );
- strcpy( path, filename );
- ReadBIF();
- return GEM_OK;
- }
- //not found as normal bif
- //checking compression type
- FileStream* compressed = new FileStream();
- compressed->Open( filename, true );
- compressed->Read( Signature, 8 );
- if (strncmp( Signature, "BIF V1.0", 8 ) == 0) {
- ieDword fnlen, complen, declen;
- compressed->ReadDword( &fnlen );
- char* fname = ( char* ) malloc( fnlen );
- compressed->Read( fname, fnlen );
- strlwr(fname);
- compressed->ReadDword( &declen );
- compressed->ReadDword( &complen );
- PathJoin( path, core->CachePath, fname, NULL );
- free( fname );
- in_cache = fopen( path, "rb" );
- if (in_cache) {
- //printf("Found in Cache\n");
- fclose( in_cache );
- delete( compressed );
- stream = new CachedFileStream( path );
- stream->Read( Signature, 8 );
- if (strncmp( Signature, "BIFFV1 ", 8 ) == 0)
- ReadBIF();
- else
- return GEM_ERROR;
- return GEM_OK;
- }
- printf( "Decompressing\n" );
- if (!core->IsAvailable( PLUGIN_COMPRESSION_ZLIB )) {
- printMessage("BIFImporter", "No Compression Manager Available.", RED);
+ if (!stream) {
+ FileStream* file = FileStream::OpenFile(path);
+ if (!file) {
return GEM_ERROR;
}
- in_cache = fopen( path, "wb" );
- if (!in_cache) {
- printMessage("BIFImporter", " ", RED);
- printf( "Cannot write %s.\n", path );
+ if (file->Read(Signature, 8) == GEM_ERROR) {
+ delete file;
return GEM_ERROR;
}
- PluginHolder<Compressor> comp(PLUGIN_COMPRESSION_ZLIB);
- if (comp->Decompress( in_cache, compressed, complen ) != GEM_OK) {
+
+ if (strncmp(Signature, "BIF V1.0", 8) == 0) {
+ stream = DecompressBIF(file, cachePath);
+ delete file;
+ } else if (strncmp(Signature, "BIFCV1.0", 8) == 0) {
+ stream = DecompressBIFC(file, cachePath);
+ delete file;
+ } else if (strncmp( Signature, "BIFFV1 ", 8 ) == 0) {
+ file->Seek(0, GEM_STREAM_START);
+ stream = file;
+ } else {
+ delete file;
return GEM_ERROR;
}
- fclose( in_cache );
- delete( compressed );
- stream = new CachedFileStream( path );
- stream->Read( Signature, 8 );
- if (strncmp( Signature, "BIFFV1 ", 8 ) == 0)
- ReadBIF();
- else
- return GEM_ERROR;
- return GEM_OK;
}
- if (strncmp( Signature, "BIFCV1.0", 8 ) == 0) {
- //printf("'BIFCV1.0' Compressed File Found\n");
- PathJoin( path, core->CachePath, compressed->filename, NULL );
- in_cache = fopen( path, "rb" );
- if (in_cache) {
- //printf("Found in Cache\n");
- fclose( in_cache );
- delete( compressed );
- stream = new CachedFileStream( path );
- stream->Read( Signature, 8 );
- if (strncmp( Signature, "BIFFV1 ", 8 ) == 0) {
- ReadBIF();
- } else
- return GEM_ERROR;
- return GEM_OK;
- }
- printf( "Decompressing\n" );
- if (!core->IsAvailable( PLUGIN_COMPRESSION_ZLIB ))
- return GEM_ERROR;
- PluginHolder<Compressor> comp(PLUGIN_COMPRESSION_ZLIB);
- ieDword unCompBifSize;
- compressed->ReadDword( &unCompBifSize );
- printf( "\nDecompressing file: [..........]" );
- fflush(stdout);
- in_cache = fopen( path, "wb" );
- if (!in_cache) {
- printMessage("BIFImporter", " ", RED);
- printf( "Cannot write %s.\n", path );
- return GEM_ERROR;
- }
- ieDword finalsize = 0;
- int laststep = 0;
- while (finalsize < unCompBifSize) {
- ieDword complen, declen;
- compressed->ReadDword( &declen );
- compressed->ReadDword( &complen );
- if (comp->Decompress( in_cache, compressed, complen ) != GEM_OK) {
- return GEM_ERROR;
- }
- finalsize = ftell( in_cache );
- if (( int ) ( finalsize * ( 10.0 / unCompBifSize ) ) != laststep) {
- laststep++;
- printf( "\b\b\b\b\b\b\b\b\b\b\b" );
- int l;
+ if (!stream)
+ return GEM_ERROR;
- for (l = 0; l < laststep; l++)
- printf( "|" );
- for (; l < 10; l++)//l starts from laststep
- printf( "." );
- printf( "]" );
- fflush(stdout);
- }
- }
- printf( "\n" );
- fclose( in_cache );
- delete( compressed );
- stream = new CachedFileStream( path );
- stream->Read( Signature, 8 );
- if (strncmp( Signature, "BIFFV1 ", 8 ) == 0)
- ReadBIF();
- else
- return GEM_ERROR;
- return GEM_OK;
+ stream->Read( Signature, 8 );
+
+ if (strncmp( Signature, "BIFFV1 ", 8 ) != 0) {
+ return GEM_ERROR;
}
- delete (compressed);
- return GEM_ERROR;
+
+ ReadBIF();
+ return GEM_OK;
}
DataStream* BIFImporter::GetStream(unsigned long Resource, unsigned long Type)
@@ -286,7 +166,7 @@ DataStream* BIFImporter::GetStream(unsigned long Resource, unsigned long Type)
unsigned int srcResLoc = Resource & 0xFC000;
for (unsigned int i = 0; i < tentcount; i++) {
if (( tentries[i].resLocator & 0xFC000 ) == srcResLoc) {
- return new CachedFileStream( stream, tentries[i].dataOffset,
+ return SliceStream( stream, tentries[i].dataOffset,
tentries[i].tileSize * tentries[i].tilesCount );
}
}
@@ -294,7 +174,7 @@ DataStream* BIFImporter::GetStream(unsigned long Resource, unsigned long Type)
ieDword srcResLoc = Resource & 0x3FFF;
for (ieDword i = 0; i < fentcount; i++) {
if (( fentries[i].resLocator & 0x3FFF ) == srcResLoc) {
- return new CachedFileStream( stream, fentries[i].dataOffset,
+ return SliceStream( stream, fentries[i].dataOffset,
fentries[i].fileSize );
}
}
diff --git a/gemrb/plugins/BIFImporter/BIFImporter.h b/gemrb/plugins/BIFImporter/BIFImporter.h
index eaabc32..260e387 100644
--- a/gemrb/plugins/BIFImporter/BIFImporter.h
+++ b/gemrb/plugins/BIFImporter/BIFImporter.h
@@ -21,11 +21,13 @@
#ifndef BIFIMPORTER_H
#define BIFIMPORTER_H
-#include "ArchiveImporter.h"
+#include "IndexedArchive.h"
#include "globals.h"
-#include "System/CachedFileStream.h"
+#include "System/DataStream.h"
+
+namespace GemRB {
struct FileEntry {
ieDword resLocator;
@@ -44,23 +46,23 @@ struct TileEntry {
ieWord u1; //Unknown Field
};
-class BIFImporter : public ArchiveImporter {
+class BIFImporter : public IndexedArchive {
private:
- char path[_MAX_PATH];
FileEntry* fentries;
TileEntry* tentries;
ieDword fentcount, tentcount;
- CachedFileStream* stream;
+ DataStream* stream;
public:
BIFImporter(void);
~BIFImporter(void);
- int DecompressSaveGame(DataStream *compressed);
- int AddToSaveGame(DataStream *str, DataStream *uncompressed);
int OpenArchive(const char* filename);
- int CreateArchive(DataStream *compressed);
DataStream* GetStream(unsigned long Resource, unsigned long Type);
private:
+ static DataStream* DecompressBIF(DataStream* compressed, const char* path);
+ static DataStream* DecompressBIFC(DataStream* compressed, const char* path);
void ReadBIF(void);
};
+}
+
#endif
diff --git a/gemrb/plugins/BIKPlayer/BIKPlayer.cpp b/gemrb/plugins/BIKPlayer/BIKPlayer.cpp
index 5a7da6e..29b5472 100644
--- a/gemrb/plugins/BIKPlayer/BIKPlayer.cpp
+++ b/gemrb/plugins/BIKPlayer/BIKPlayer.cpp
@@ -30,10 +30,6 @@
* Copyright (c) 2009 Konstantin Shishkov
*/
-#if defined(__HAIKU__)
-#include <unistd.h>
-#endif
-
#include "BIKPlayer.h"
#include "rational.h"
@@ -48,6 +44,12 @@
#include <cassert>
#include <cstdio>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+using namespace GemRB;
+
static int g_truecolor;
static ieDword *cbAtFrame = NULL;
static ieDword *strRef = NULL;
@@ -218,7 +220,8 @@ int BIKPlayer::Play()
frameCount = 0;
int ret = doPlay( );
- EndAudio();
+ if (s_stream > -1)
+ EndAudio();
EndVideo();
av_freep((void **) &inbuff);
return ret;
@@ -286,7 +289,7 @@ bool BIKPlayer::next_frame()
ieDword audframesize;
str->ReadDword(&audframesize);
frame.size = str->Read( inbuff, frame.size - 4 );
- if (DecodeAudioFrame(inbuff, audframesize)) {
+ if (s_stream > -1 && DecodeAudioFrame(inbuff, audframesize)) {
//buggy frame, we stop immediately
//return false;
}
@@ -329,6 +332,7 @@ int BIKPlayer::doPlay()
done = video->PollMovieEvents();
}
+ video->DestroyMovieScreen();
return 0;
}
@@ -1152,7 +1156,8 @@ int BIKPlayer::read_colors(Bundle *b)
int BIKPlayer::read_dcs(Bundle *b, int start_bits, int has_sign)
{
int i, j, len, len2, bsize, v, v2;
- SET_INT_TYPE *dst = (SET_INT_TYPE*)b->cur_dec;
+
+ SET_INT_TYPE *dst = reinterpret_cast<SET_INT_TYPE*>(b->cur_dec);
//int16_t *dst = (int16_t*)b->cur_dec;
CHECK_READ_VAL(v_gb, b, len);
@@ -1503,7 +1508,7 @@ int BIKPlayer::DecodeVideoFrame(void *data, int data_size)
}
break;
default:
- printf("Incorrect 16x16 block type!\n");
+ print("Incorrect 16x16 block type!");
return -1;
}
bx++;
@@ -1586,7 +1591,7 @@ int BIKPlayer::DecodeVideoFrame(void *data, int data_size)
c_bundle[BINK_SRC_COLORS].cur_ptr += 64;
break;
default:
- printf("Unknown block type!\n");
+ print("Unknown block type!");
return -1;
}
}
@@ -1613,5 +1618,5 @@ int BIKPlayer::DecodeVideoFrame(void *data, int data_size)
#include "plugindef.h"
GEMRB_PLUGIN(0x316E2EDE, "BIK Video Player")
-PLUGIN_RESOURCE(BIKPlayer, ".mve")
+PLUGIN_RESOURCE(BIKPlayer, "mve")
END_PLUGIN()
diff --git a/gemrb/plugins/BIKPlayer/BIKPlayer.h b/gemrb/plugins/BIKPlayer/BIKPlayer.h
index baba425..94a0738 100644
--- a/gemrb/plugins/BIKPlayer/BIKPlayer.h
+++ b/gemrb/plugins/BIKPlayer/BIKPlayer.h
@@ -35,6 +35,8 @@
#include "dsputil.h"
#include "rational.h"
+namespace GemRB {
+
#define BIK_SIGNATURE_LEN 4
#define BIK_SIGNATURE_DATA "BIKi"
@@ -62,7 +64,7 @@
(ptr)++;
#else
#define GET_INT_VALUE(value, ptr)\
- (value) = *(int16_t*)(ptr); \
+ (value) = *reinterpret_cast<int16_t*>(ptr); \
(ptr) += 2;
#endif
@@ -256,4 +258,6 @@ public:
int Play();
};
+}
+
#endif
diff --git a/gemrb/plugins/BIKPlayer/GetBitContext.cpp b/gemrb/plugins/BIKPlayer/GetBitContext.cpp
index 5ef416a..815fcbb 100644
--- a/gemrb/plugins/BIKPlayer/GetBitContext.cpp
+++ b/gemrb/plugins/BIKPlayer/GetBitContext.cpp
@@ -26,6 +26,7 @@
#include <math.h>
#include "GetBitContext.h"
+#include "System/Logging.h"
//don't return more than 25 bits this way
unsigned int GetBitContext::get_bits(int n) {
@@ -158,7 +159,7 @@ void GetBitContext::merge( uint8_t *dst, uint8_t *src, int size)
void GetBitContext::debug(const char *prefix)
{
- printf("%s: %d\n", prefix, index);
+ GemRB::print("%s: %d", prefix, index);
}
//VLC specific code from bitstream.c
diff --git a/gemrb/plugins/BIKPlayer/GetBitContext.h b/gemrb/plugins/BIKPlayer/GetBitContext.h
index d056f37..47bf917 100644
--- a/gemrb/plugins/BIKPlayer/GetBitContext.h
+++ b/gemrb/plugins/BIKPlayer/GetBitContext.h
@@ -64,16 +64,16 @@ private:
#else
#define GET_DATA(v, table, i, wrap, size) \
{\
- const uint8_t *ptr = (const uint8_t *)table + i * wrap;\
+ const uint8_t *ptr = reinterpret_cast<const uint8_t *>(table) + i * wrap;\
switch(size) {\
case 1:\
- v = *(const uint8_t *)ptr;\
+ v = *reinterpret_cast<const uint8_t *>(ptr);\
break;\
case 2:\
- v = *(const uint16_t *)ptr;\
+ v = *reinterpret_cast<const uint16_t *>(ptr);\
break;\
default:\
- v = *(const uint32_t *)ptr;\
+ v = *reinterpret_cast<const uint32_t *>(ptr);\
break;\
}\
}
diff --git a/gemrb/plugins/BMPImporter/BMPImporter.cpp b/gemrb/plugins/BMPImporter/BMPImporter.cpp
index 284aa00..ed8426b 100644
--- a/gemrb/plugins/BMPImporter/BMPImporter.cpp
+++ b/gemrb/plugins/BMPImporter/BMPImporter.cpp
@@ -26,21 +26,14 @@
#include "Interface.h"
#include "Video.h"
-#define BMP_HEADER_SIZE 54
+using namespace GemRB;
-static ieDword red_mask = 0x00ff0000;
-static ieDword green_mask = 0x0000ff00;
-static ieDword blue_mask = 0x000000ff;
+#define BMP_HEADER_SIZE 54
BMPImporter::BMPImporter(void)
{
Palette = NULL;
pixels = NULL;
- if (DataStream::IsEndianSwitch()) {
- red_mask = 0x000000ff;
- green_mask = 0x0000ff00;
- blue_mask = 0x00ff0000;
- }
}
BMPImporter::~BMPImporter(void)
@@ -64,7 +57,7 @@ bool BMPImporter::Open(DataStream* stream)
str->Read( Signature, 2 );
if (strncmp( Signature, "BM", 2 ) != 0) {
- printMessage( "BMPImporter","Not a valid BMP File.\n",LIGHT_RED);
+ Log(ERROR, "BMPImporter", "Not a valid BMP File.");
return false;
}
str->ReadDword( &FileSize );
@@ -76,7 +69,7 @@ bool BMPImporter::Open(DataStream* stream)
str->ReadDword( &Size );
//some IE palettes are of a different format (OS/2 BMP)!
if (Size < 24) {
- printMessage( "BMPImporter","OS/2 Bitmap, not supported.\n", LIGHT_RED);
+ Log(ERROR, "BMPImporter", "OS/2 Bitmap, not supported.");
return false;
}
str->ReadDword( &Width );
@@ -93,8 +86,7 @@ bool BMPImporter::Open(DataStream* stream)
//str->ReadDword(&ColorsUsed );
//str->ReadDword(&ColorsImportant );
if (Compression != 0) {
- printMessage( "BMPImporter"," ", LIGHT_RED);
- printf( "Compressed %d-bits Image, not supported.\n", BitCount );
+ Log(ERROR, "BMPImporter", "Compressed %d-bits Image, not supported.", BitCount);
return false;
}
//COLORTABLE
@@ -136,8 +128,7 @@ bool BMPImporter::Open(DataStream* stream)
PaddedRowLength = ( Width >> 1 );
break;
default:
- printMessage( "BMPImporter"," ", LIGHT_RED);
- printf( "BitCount %d is not supported.\n", BitCount );
+ Log(ERROR, "BMPImporter", "BitCount %d is not supported.", BitCount);
return false;
}
//if(BitCount!=4)
@@ -149,33 +140,35 @@ bool BMPImporter::Open(DataStream* stream)
void* rpixels = malloc( PaddedRowLength* Height );
str->Read( rpixels, PaddedRowLength * Height );
if (BitCount == 32) {
- //convert to 24 bits on the fly
- int size = Width * Height * 3;
+ int size = Width * Height * 4;
pixels = malloc( size );
- unsigned char * dest = ( unsigned char * ) pixels;
- dest += size;
+ unsigned int * dest = ( unsigned int * ) pixels;
+ dest += Width * Height;
unsigned char * src = ( unsigned char * ) rpixels;
for (int i = Height; i; i--) {
- dest -= ( Width * 3 );
- for (unsigned int j=0;j<Width;j++) {
- dest[j*3]=src[j*4];
- dest[j*3+1]=src[j*4+1];
- dest[j*3+2]=src[j*4+2];
- }
+ dest -= Width;
+ // BGRX
+ for (unsigned int j=0;j<Width;j++)
+ dest[j] = (0xFF << 24) | (src[j*4+0] << 16) |
+ (src[j*4+1] << 8) | (src[j*4+2]);
src += PaddedRowLength;
}
- BitCount = 24;
} else if (BitCount == 24) {
- int size = Width * Height * 3;
+ //convert to 32 bits on the fly
+ int size = Width * Height * 4;
pixels = malloc( size );
- unsigned char * dest = ( unsigned char * ) pixels;
- dest += size;
+ unsigned int * dest = ( unsigned int * ) pixels;
+ dest += Width * Height;
unsigned char * src = ( unsigned char * ) rpixels;
for (int i = Height; i; i--) {
- dest -= ( Width * 3 );
- memcpy( dest, src, Width * 3 );
+ dest -= Width;
+ // BGR
+ for (unsigned int j=0;j<Width;j++)
+ dest[j] = (0xFF << 24) | (src[j*3+0] << 16) |
+ (src[j*3+1] << 8) | (src[j*3+2]);
src += PaddedRowLength;
}
+ BitCount = 32;
} else if (BitCount == 8) {
pixels = malloc( Width * Height );
unsigned char * dest = ( unsigned char * ) pixels;
@@ -229,10 +222,13 @@ void BMPImporter::Read4To8(void *rpixels)
Sprite2D* BMPImporter::GetSprite2D()
{
Sprite2D* spr = NULL;
- if (BitCount == 24) {
- void* p = malloc( Width * Height * 3 );
- memcpy( p, pixels, Width * Height * 3 );
- spr = core->GetVideoDriver()->CreateSprite( Width, Height, 24,
+ if (BitCount == 32) {
+ const ieDword red_mask = 0x000000ff;
+ const ieDword green_mask = 0x0000ff00;
+ const ieDword blue_mask = 0x00ff0000;
+ void* p = malloc( Width * Height * 4 );
+ memcpy( p, pixels, Width * Height * 4 );
+ spr = core->GetVideoDriver()->CreateSprite( Width, Height, 32,
red_mask, green_mask, blue_mask, 0x00000000, p,
true, green_mask );
} else if (BitCount == 8) {
@@ -273,13 +269,11 @@ Bitmap* BMPImporter::GetBitmap()
}
}
break;
- case 24:
- printMessage("BMPImporter", "Don't know how to handle 24bit bitmap from ", WHITE);
- printf( "%s...", str->filename );
- printStatus( "ERROR", LIGHT_RED );
+ case 32:
+ Log(ERROR, "BMPImporter", "Don't know how to handle 32bpp bitmap from %s...", str->filename);
for (y = 0; y < Height; y++) {
for (unsigned int x = 0; x < Width; x++) {
- data->SetAt(x,y,p[3*(y*Width + x)]);
+ data->SetAt(x,y,p[4*(y*Width + x)]);
}
}
break;
@@ -288,8 +282,41 @@ Bitmap* BMPImporter::GetBitmap()
return data;
}
+Image* BMPImporter::GetImage()
+{
+ Image *data = new Image(Width,Height);
+
+ switch (BitCount) {
+ case 8: {
+ unsigned char *p = ( unsigned char * ) pixels;
+ unsigned int y;
+ for (y = 0; y < Height; y++) {
+ for (unsigned int x = 0; x < Width; x++) {
+ data->SetPixel(x,y,Palette[p[y*Width + x]%NumColors]);
+ }
+ }
+ break;
+ }
+ case 32: {
+ unsigned int *p = ( unsigned int * ) pixels;
+ unsigned int y;
+ for (y = 0; y < Height; y++) {
+ for (unsigned int x = 0; x < Width; x++) {
+ unsigned int col = *p++;
+ Color c = { (unsigned char)col, (unsigned char)(col >> 8),
+ (unsigned char)(col >> 16), 0xFF };
+ data->SetPixel(x,y,c);
+ }
+ }
+ break;
+ }
+ }
+
+ return data;
+}
+
#include "plugindef.h"
GEMRB_PLUGIN(0xD768B1, "BMP File Reader")
-PLUGIN_IE_RESOURCE(BMPImporter, ".bmp", (ieWord)IE_BMP_CLASS_ID)
+PLUGIN_IE_RESOURCE(BMPImporter, "bmp", (ieWord)IE_BMP_CLASS_ID)
END_PLUGIN()
diff --git a/gemrb/plugins/BMPImporter/BMPImporter.h b/gemrb/plugins/BMPImporter/BMPImporter.h
index 2470a35..a2b7444 100644
--- a/gemrb/plugins/BMPImporter/BMPImporter.h
+++ b/gemrb/plugins/BMPImporter/BMPImporter.h
@@ -23,10 +23,12 @@
#include "ImageMgr.h"
+namespace GemRB {
+
class BMPImporter : public ImageMgr {
private:
//BITMAPINFOHEADER
- ieDword Size, Width, Height, Compression, ImageSize, ColorsUsed, ColorsImportant;
+ ieDword Size, Width, Height, Compression, ImageSize/*, ColorsUsed, ColorsImportant*/;
ieWord Planes, BitCount;
//COLORTABLE
@@ -44,6 +46,7 @@ public:
bool Open(DataStream* stream);
Sprite2D* GetSprite2D();
virtual Bitmap* GetBitmap();
+ virtual Image* GetImage();
void GetPalette(int colors, Color* pal);
int GetWidth() { return (int) Width; }
@@ -53,4 +56,6 @@ private:
void Read4To8(void *rpixels);
};
+}
+
#endif
diff --git a/gemrb/plugins/BMPWriter/BMPWriter.cpp b/gemrb/plugins/BMPWriter/BMPWriter.cpp
index a89ad5d..4bc23bf 100644
--- a/gemrb/plugins/BMPWriter/BMPWriter.cpp
+++ b/gemrb/plugins/BMPWriter/BMPWriter.cpp
@@ -5,6 +5,8 @@
#include <cstring>
+using namespace GemRB;
+
#define BMP_HEADER_SIZE 54 //FIXME: duplicate
#define GET_SCANLINE_LENGTH(width, bitsperpixel) (((width)*(bitsperpixel)+7)/8)
diff --git a/gemrb/plugins/BMPWriter/BMPWriter.h b/gemrb/plugins/BMPWriter/BMPWriter.h
index a8c3ce8..2b32606 100644
--- a/gemrb/plugins/BMPWriter/BMPWriter.h
+++ b/gemrb/plugins/BMPWriter/BMPWriter.h
@@ -1,5 +1,7 @@
#include "ImageWriter.h"
+namespace GemRB {
+
class BMPWriter : public ImageWriter {
public:
BMPWriter(void);
@@ -7,3 +9,5 @@ public:
void PutImage(DataStream *output, Sprite2D *sprite);
};
+
+}
diff --git a/gemrb/plugins/CHUImporter/CHUImporter.cpp b/gemrb/plugins/CHUImporter/CHUImporter.cpp
index 4d9609d..1e84672 100644
--- a/gemrb/plugins/CHUImporter/CHUImporter.cpp
+++ b/gemrb/plugins/CHUImporter/CHUImporter.cpp
@@ -34,35 +34,32 @@
#include "GUI/Slider.h"
#include "GUI/TextArea.h"
#include "GUI/TextEdit.h"
+#include "GUI/Window.h"
+
+using namespace GemRB;
CHUImporter::CHUImporter()
{
str = NULL;
- autoFree = false;
}
CHUImporter::~CHUImporter()
{
- if (autoFree) {
- delete str;
- }
+ delete str;
}
/** This function loads all available windows from the 'stream' parameter. */
-bool CHUImporter::Open(DataStream* stream, bool autoFree)
+bool CHUImporter::Open(DataStream* stream)
{
if (stream == NULL) {
return false;
}
- if (this->autoFree) {
- delete str;
- }
+ delete str;
str = stream;
- this->autoFree = autoFree;
char Signature[8];
str->Read( Signature, 8 );
if (strncmp( Signature, "CHUIV1 ", 8 ) != 0) {
- printMessage( "CHUImporter","Not a Valid CHU File\n",LIGHT_RED );
+ Log(ERROR, "CHUImporter", "Not a Valid CHU File");
return false;
}
str->ReadDword( &WindowCount );
@@ -79,6 +76,11 @@ Window* CHUImporter::GetWindow(unsigned int wid)
ieResRef MosFile;
unsigned int i;
+ if (!str) {
+ Log(ERROR, "CHUImporter", "No data stream to read from, skipping controls");
+ return NULL;
+ }
+
bool found = false;
for (unsigned int c = 0; c < WindowCount; c++) {
str->Seek( WEOffset + ( 0x1c * c ), GEM_STREAM_START );
@@ -106,11 +108,10 @@ Window* CHUImporter::GetWindow(unsigned int wid)
ResourceHolder<ImageMgr> mos(MosFile);
if (mos != NULL) {
win->SetBackGround( mos->GetSprite2D(), true );
- } else
- printMessage( "CHUImporter","Cannot Load BackGround, skipping\n",YELLOW );
+ }
}
if (!core->IsAvailable( IE_BAM_CLASS_ID )) {
- printMessage( "CHUImporter","No BAM Importer Available, skipping controls\n",LIGHT_RED );
+ Log(ERROR, "CHUImporter", "No BAM Importer Available, skipping controls");
return win;
}
for (i = 0; i < ControlsCount; i++) {
@@ -183,7 +184,7 @@ Window* CHUImporter::GetWindow(unsigned int wid)
gamedata->GetFactoryResource( BAMFile,
IE_BAM_CLASS_ID, IE_NORMAL );
if (!bam ) {
- printMessage( "CHUImporter","Cannot Load Button Images, skipping control\n",LIGHT_RED );
+ Log(ERROR, "CHUImporter", "Cannot Load Button Images, skipping control");
/* IceWind Dale 2 has fake BAM ResRefs for some Buttons,
this will handle bad ResRefs */
win->AddControl( btn );
@@ -513,7 +514,7 @@ endalign:
break;
default:
- printMessage( "CHUImporter","Control Not Supported\n",LIGHT_RED );
+ Log(ERROR, "CHUImporter", "Control Not Supported");
}
}
return win;
diff --git a/gemrb/plugins/CHUImporter/CHUImporter.h b/gemrb/plugins/CHUImporter/CHUImporter.h
index 512bb73..6e7fa6a 100644
--- a/gemrb/plugins/CHUImporter/CHUImporter.h
+++ b/gemrb/plugins/CHUImporter/CHUImporter.h
@@ -25,6 +25,8 @@
#include "System/DataStream.h"
+namespace GemRB {
+
/**CHU File Importer Class
*@author GemRB Developement Team
*/
@@ -32,7 +34,7 @@
class CHUImporter : public WindowMgr {
private:
DataStream* str;
- bool autoFree;
+// bool autoFree;
ieDword WindowCount, CTOffset, WEOffset;
public:
CHUImporter();
@@ -42,7 +44,9 @@ public:
/** Returns the i-th window in the Previously Loaded Stream */
Window* GetWindow(unsigned int i);
/** This function loads all available windows from the 'stream' parameter. */
- bool Open(DataStream* stream, bool autoFree = true);
+ bool Open(DataStream* stream);
};
+}
+
#endif
diff --git a/gemrb/plugins/CMakeLists.txt b/gemrb/plugins/CMakeLists.txt
index 6c48216..d5f72cf 100644
--- a/gemrb/plugins/CMakeLists.txt
+++ b/gemrb/plugins/CMakeLists.txt
@@ -23,18 +23,22 @@ ADD_SUBDIRECTORY( MOSImporter )
ADD_SUBDIRECTORY( MUSImporter )
ADD_SUBDIRECTORY( MVEPlayer )
ADD_SUBDIRECTORY( NullSound )
+ADD_SUBDIRECTORY( NullSource )
ADD_SUBDIRECTORY( OGGReader )
ADD_SUBDIRECTORY( OpenALAudio )
ADD_SUBDIRECTORY( PLTImporter )
ADD_SUBDIRECTORY( PNGImporter )
ADD_SUBDIRECTORY( PROImporter )
ADD_SUBDIRECTORY( PSTOpcodes )
+ADD_SUBDIRECTORY( SAVImporter )
ADD_SUBDIRECTORY( SDLAudio )
ADD_SUBDIRECTORY( SDLVideo )
ADD_SUBDIRECTORY( SPLImporter )
ADD_SUBDIRECTORY( STOImporter )
ADD_SUBDIRECTORY( TISImporter )
ADD_SUBDIRECTORY( TLKImporter )
+ADD_SUBDIRECTORY( TTFImporter )
+ADD_SUBDIRECTORY( VLCPlayer )
ADD_SUBDIRECTORY( WAVReader )
ADD_SUBDIRECTORY( WEDImporter )
ADD_SUBDIRECTORY( WMPImporter )
diff --git a/gemrb/plugins/CREImporter/CREImporter.cpp b/gemrb/plugins/CREImporter/CREImporter.cpp
index a28e301..b7dee3b 100644
--- a/gemrb/plugins/CREImporter/CREImporter.cpp
+++ b/gemrb/plugins/CREImporter/CREImporter.cpp
@@ -26,10 +26,14 @@
#include "EffectMgr.h"
#include "GameData.h"
#include "Interface.h"
+#include "PluginMgr.h"
+#include "TableMgr.h"
#include "GameScript/GameScript.h"
#include <cassert>
+using namespace GemRB;
+
#define MAXCOLOR 12
typedef unsigned char ColorSet[MAXCOLOR];
@@ -53,8 +57,8 @@ static int shpcount=-1;
struct LevelAndKit
{
- int level;
- int kit;
+ unsigned int level;
+ unsigned int kit;
};
class SpellEntry
@@ -62,10 +66,12 @@ class SpellEntry
public:
~SpellEntry();
SpellEntry();
- const ieResRef *FindSpell(int level, int kit) const;
+ const ieResRef *GetSpell() const;
+ const ieResRef *FindSpell(unsigned int level, unsigned int kit) const;
+ int FindSpell(unsigned int kit) const;
bool Equals(const char *spl) const;
void SetSpell(const char *spl);
- void AddLevel(int level, int kit);
+ void AddLevel(unsigned int level, unsigned int kit);
private:
ieResRef spell;
LevelAndKit *levels;
@@ -85,7 +91,12 @@ SpellEntry::~SpellEntry()
levels = NULL;
}
-const ieResRef *SpellEntry::FindSpell(int level, int kit) const
+const ieResRef *SpellEntry::GetSpell() const
+{
+ return &spell;
+}
+
+const ieResRef *SpellEntry::FindSpell(unsigned int level, unsigned int kit) const
{
int i = count;
while(i--) {
@@ -96,6 +107,28 @@ const ieResRef *SpellEntry::FindSpell(int level, int kit) const
return NULL;
}
+int SpellEntry::FindSpell(unsigned int kit) const
+{
+ int i = count;
+ while(i--) {
+ if (levels[i].kit==kit) {
+ return levels[i].level;
+ }
+ }
+ return 0;
+}
+
+static int FindSpell(ieResRef spellref, SpellEntry* list, int listsize)
+{
+ int i = listsize;
+ while (i--) {
+ if (list[i].Equals(spellref)) {
+ return i;
+ }
+ }
+ return -1;
+}
+
bool SpellEntry::Equals(const char *spl) const
{
return !strnicmp(spell, spl, sizeof(ieResRef));
@@ -106,15 +139,16 @@ void SpellEntry::SetSpell(const char *spl)
strnlwrcpy(spell, spl, 8);
}
-void SpellEntry::AddLevel(int level, int kit)
+void SpellEntry::AddLevel(unsigned int level,unsigned int kit)
{
if(!level) {
return;
}
- level--;
+ level--; // convert to 0-based for internal use
for(int i=0;i<count;i++) {
if(levels[i].kit==kit && levels[i].level==level) {
+ Log(WARNING, "CREImporter", "Skipping duplicate spell list table entry for: %s", spell);
return;
}
}
@@ -124,6 +158,36 @@ void SpellEntry::AddLevel(int level, int kit)
count++;
}
+static int IsInnate(ieResRef name)
+{
+ for(int i=0;i<inncount;i++) {
+ if(!strnicmp(name, innlist[i], 8) ) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+static int IsSong(ieResRef name)
+{
+ for(int i=0;i<sngcount;i++) {
+ if(!strnicmp(name, snglist[i], 8) ) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+static int IsShape(ieResRef name)
+{
+ for(int i=0;i<shpcount;i++) {
+ if(!strnicmp(name, shplist[i], 8) ) {
+ return i;
+ }
+ }
+ return -1;
+}
+
static SpellEntry* spllist=NULL;
static int splcount=-1;
static SpellEntry* domlist=NULL;
@@ -131,6 +195,54 @@ static int domcount=-1;
static SpellEntry* maglist=NULL;
static int magcount=-1;
+static int IsDomain(ieResRef name, unsigned short &level, unsigned int kit)
+{
+ for(int i=0;i<domcount;i++) {
+ if (domlist[i].Equals(name) ) {
+ level = domlist[i].FindSpell(kit);
+ return i;
+ }
+ }
+ return -1;
+}
+
+static int IsSpecial(ieResRef name, unsigned short &level, unsigned int kit)
+{
+ for(int i=0;i<magcount;i++) {
+ if (maglist[i].Equals(name) ) {
+ level = maglist[i].FindSpell(kit);
+ return i;
+ }
+ }
+ return -1;
+}
+
+static int SpellType(ieResRef name, unsigned short &level, unsigned int clsmsk)
+{
+ for (int i = 0;i<splcount;i++) {
+ if (spllist[i].Equals(name) ) {
+ for(int type=0;type<7;type++) {
+ if (clsmsk & i) {
+ level = spllist[i].FindSpell(type);
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+int CREImporter::FindSpellType(char *name, unsigned short &level, unsigned int clsmsk, unsigned int kit) const
+{
+ level = 0;
+ if (IsSong(name)>=0) return IE_IWD2_SPELL_SONG;
+ if (IsShape(name)>=0) return IE_IWD2_SPELL_SHAPE;
+ if (IsInnate(name)>=0) return IE_IWD2_SPELL_INNATE;
+ if (IsDomain(name, level, kit)>=0) return IE_IWD2_SPELL_DOMAIN;
+ if (IsSpecial(name, level, kit)>=0) return IE_IWD2_SPELL_WIZARD;
+ return SpellType(name, level, clsmsk);
+}
+
+//int CREImporter::ResolveSpellName(ieResRef name, int level, ieIWD2SpellType type) const
int ResolveSpellName(ieResRef name, int level, ieIWD2SpellType type)
{
int i;
@@ -162,15 +274,28 @@ int ResolveSpellName(ieResRef name, int level, ieIWD2SpellType type)
}
break;
case IE_IWD2_SPELL_DOMAIN:
- return -1;
default:
- return -1;
+ for(i=0;i<splcount;i++) {
+ if (spllist[i].Equals(name) ) return i;
+ }
}
return -1;
}
+// just returns the integer part of the log
+// perfect for deducing kit values, since they are bitfields and we don't care about any noise
+static int log2(int value)
+{
+ int pow = -1;
+ while (value) {
+ value = value>>1;
+ pow++;
+ }
+ return pow;
+}
+
//input: index, level, type, kit
-const ieResRef *ResolveSpellIndex(int index, int level, ieIWD2SpellType type, int kit)
+static const ieResRef *ResolveSpellIndex(int index, int level, ieIWD2SpellType type, int kit)
{
const ieResRef *ret;
@@ -196,14 +321,26 @@ const ieResRef *ResolveSpellIndex(int index, int level, ieIWD2SpellType type, in
}
return &shplist[index];
case IE_IWD2_SPELL_DOMAIN:
- if (index>=domcount) {
+ if (index>=splcount) {
return NULL;
}
- return domlist[index].FindSpell(level, kit);
+ // translate the actual kit to a column index to make them comparable
+ // luckily they are in order
+ kit = log2(kit/0x8000); // 0x8000 is the first cleric kit
+ ret = domlist[index].FindSpell(level, kit);
+ if (ret) {
+ return ret;
+ }
+ // sigh, retry with wizard spells, since the table does not cover everything npcs have
+ kit = -1;
+ type = IE_IWD2_SPELL_WIZARD;
+ break;
case IE_IWD2_SPELL_WIZARD:
- if (index>=magcount) {
+ if (index>=splcount) {
break;
}
+ // translate the actual kit to a column index to make them comparable
+ kit = log2(kit/0x40); // 0x40 is the first mage kit
//if it is a specialist spell, return it now
ret = maglist[index].FindSpell(level, kit);
if ( ret) {
@@ -216,22 +353,38 @@ const ieResRef *ResolveSpellIndex(int index, int level, ieIWD2SpellType type, in
break;
}
+ // type matches the table columns (0-bard to 6-wizard)
ret = spllist[index].FindSpell(level, type);
- if ( !ret || (kit==-1) ) {
+ if (!ret) {
+ // some npcs have spells at odd levels, so the lookup just failed
+ // eg. slayer knights of xvim with sppr325 at level 2 instead of 3
+ Log(ERROR, "CREImporter", "Spell (%d of type %d) found at unexpected level (%d)!", index, type, level);
+ int level2 = spllist[index].FindSpell(type);
+ // grrr, some rows have no levels set - they're all 0, but with a valid resref, so just return that
+ if (!level2) {
+ Log(DEBUG, "CREImporter", "Spell entry (%d) without any levels set!", index);
+ return spllist[index].GetSpell();
+ }
+ ret = spllist[index].FindSpell(level2, type);
+ if (ret) Log(DEBUG, "CREImporter", "The spell was found at level %d!", level2);
+ }
+ if (ret || (kit==-1) ) {
return ret;
}
+ error("CREImporter", "Doing extra mage spell lookups!");
+ // FIXME: is this really needed? reachable only if wizard index was too high
+ kit = log2(kit/0x40); // 0x40 is the first mage kit
int i;
-
for(i=0;i<magcount;i++) {
if (maglist[i].Equals(*ret)) {
- return maglist[i].FindSpell(level, kit);
+ return maglist[i].FindSpell(level, kit);
}
}
return NULL;
}
-void ReleaseMemoryCRE()
+static void ReleaseMemoryCRE()
{
if (randcolors) {
delete [] randcolors;
@@ -296,6 +449,7 @@ static ieResRef *GetSpellTable(const ieResRef tableresref, int &count)
return reslist;
}
+// different tables, but all use listspll.2da for the spell indices
static SpellEntry *GetKitSpell(const ieResRef tableresref, int &count)
{
count = 0;
@@ -309,11 +463,32 @@ static SpellEntry *GetKitSpell(const ieResRef tableresref, int &count)
}
count = tab->GetRowCount();
- SpellEntry *reslist = new SpellEntry[count];
+ SpellEntry *reslist;
+ bool indexlist = false;
+ if (!strnicmp(tableresref, "listspll", 8)) {
+ indexlist = true;
+ reslist = new SpellEntry[count];
+ } else {
+ reslist = new SpellEntry[splcount]; // needs to be the same size for the simple index lookup we do!
+ }
+ int index;
for(int i = 0;i<count;i++) {
- reslist[i].SetSpell(tab->QueryField(i,column));
+ if (indexlist) {
+ index = i;
+ } else {
+ // find the correct index in listspll.2da
+ ieResRef spellref;
+ strnlwrcpy(spellref, tab->QueryField(i, column), 8);
+ // the table has disabled spells in it and they all have the first two chars replaced by '*'
+ if (spellref[0] == '*') {
+ continue;
+ }
+ index = FindSpell(spellref, spllist, splcount);
+ assert (index != -1);
+ }
+ reslist[index].SetSpell(tab->QueryField(i, column));
for(int col=0;col<column;col++) {
- reslist[i].AddLevel(atoi(tab->QueryField(i,col)), col);
+ reslist[index].AddLevel(atoi(tab->QueryField(i, col)), col);
}
}
return reslist;
@@ -329,7 +504,7 @@ static void InitSpellbook()
innlist = GetSpellTable("listinnt", inncount);
snglist = GetSpellTable("listsong", sngcount);
shplist = GetSpellTable("listshap", shpcount);
- spllist = GetKitSpell("listspll", splcount);
+ spllist = GetKitSpell("listspll", splcount); // need to init this one first, since the other two rely on it
maglist = GetKitSpell("listmage", magcount);
domlist = GetKitSpell("listdomn", domcount);
}
@@ -338,7 +513,6 @@ static void InitSpellbook()
CREImporter::CREImporter(void)
{
str = NULL;
- autoFree = false;
TotSCEFF = 0xff;
CREVersion = 0xff;
InitSpellbook();
@@ -346,21 +520,16 @@ CREImporter::CREImporter(void)
CREImporter::~CREImporter(void)
{
- if (str && autoFree) {
- delete( str );
- }
+ delete str;
}
-bool CREImporter::Open(DataStream* stream, bool aF)
+bool CREImporter::Open(DataStream* stream)
{
- if (str && this->autoFree) {
- delete( str );
- }
- str = stream;
- autoFree = aF;
if (stream == NULL) {
return false;
}
+ delete str;
+ str = stream;
char Signature[8];
str->Read( Signature, 8 );
IsCharacter = false;
@@ -394,8 +563,7 @@ bool CREImporter::Open(DataStream* stream, bool aF)
return true;
}
- printMessage( "CREImporter"," ",LIGHT_RED);
- printf("Not a CRE File or File Version not supported: %8.8s\n", Signature );
+ Log(ERROR, "CREImporter", "Not a CRE File or File Version not supported: %8.8s", Signature);
return false;
}
@@ -428,10 +596,10 @@ void CREImporter::SetupSlotCounts()
void CREImporter::WriteChrHeader(DataStream *stream, Actor *act)
{
char Signature[8];
+ char filling[10];
ieVariable name;
ieDword tmpDword, CRESize;
ieWord tmpWord;
- ieByte tmpByte;
CRESize = GetStoredFileSize (act);
switch (CREVersion) {
@@ -455,7 +623,7 @@ void CREImporter::WriteChrHeader(DataStream *stream, Actor *act)
tmpDword = 0x68; //headersize
TotSCEFF = 0;
break;
- case IE_CRE_V2_2: //iwd2
+ case IE_CRE_V2_2: //iwd2
memcpy(Signature, "CHR V2.2",8);
tmpDword = 0x21c; //headersize
TotSCEFF = 1;
@@ -466,7 +634,7 @@ void CREImporter::WriteChrHeader(DataStream *stream, Actor *act)
TotSCEFF = 1;
break;
default:
- printMessage("CREImporter","Unknown CHR version!\n",LIGHT_RED);
+ Log(ERROR, "CREImporter", "Unknown CHR version!");
return;
}
stream->Write( Signature, 8);
@@ -495,11 +663,12 @@ void CREImporter::WriteChrHeader(DataStream *stream, Actor *act)
if (QSPCount==9) {
//NOTE: the gemrb internal format stores
//0xff or 0xfe in case of innates and bardsongs
- //if IWD2 doesn't tolerate this, then this field
- //should be sanitized for IWD2 (not for GemRB)
- stream->Write( act->PCStats->QuickSpellClass,9);
- tmpByte = 0;
- stream->Write( &tmpByte, 1);
+ memset(filling,0,sizeof(filling));
+ memcpy(filling,act->PCStats->QuickSpellClass,MAX_QSLOTS);
+ for(i=0;i<MAX_QSLOTS;i++) {
+ if ( (ieByte) filling[i]>=0xfe) filling[i]=0;
+ }
+ stream->Write( filling, 10);
}
for (i=0;i<QITCount;i++) {
tmpWord = act->PCStats->QuickItemSlots[i];
@@ -531,7 +700,7 @@ void CREImporter::WriteChrHeader(DataStream *stream, Actor *act)
//fallthrough
case IE_CRE_GEMRB:
for (i=0;i<QSPCount;i++) {
- tmpDword = act->PCStats->QSlots[i];
+ tmpDword = act->PCStats->QSlots[i+3];
stream->WriteDword( &tmpDword);
}
for (i=0;i<13;i++) {
@@ -539,7 +708,13 @@ void CREImporter::WriteChrHeader(DataStream *stream, Actor *act)
}
stream->Write( act->PCStats->SoundFolder, 32);
stream->Write( act->PCStats->SoundSet, 8);
- for (i=0;i<32;i++) {
+ for (i=0;i<ES_COUNT;i++) {
+ tmpDword = act->PCStats->ExtraSettings[i];
+ stream->WriteDword( &tmpDword);
+ }
+ //Reserved
+ tmpDword = 0;
+ for (i=0;i<16;i++) {
stream->WriteDword( &tmpDword);
}
break;
@@ -553,6 +728,7 @@ void CREImporter::ReadChrHeader(Actor *act)
ieVariable name;
char Signature[8];
ieDword offset, size;
+ ieDword tmpDword;
ieWord tmpWord;
ieByte tmpByte;
@@ -591,7 +767,43 @@ void CREImporter::ReadChrHeader(Actor *act)
str->ReadWord (&tmpWord);
act->PCStats->QuickItemHeaders[i]=tmpWord;
}
+
//here comes the version specific read
+ switch (CREVersion) {
+ case IE_CRE_V2_2:
+ //gemrb format doesn't save these redundantly
+ for (i=0;i<QSPCount;i++) {
+ str->ReadResRef(Signature);
+ if (Signature[0]) {
+ act->PCStats->QuickSpellClass[i]=0xff;
+ memcpy(act->PCStats->QuickSpells[i], Signature, sizeof(ieResRef));
+ }
+ }
+ for (i=0;i<QSPCount;i++) {
+ str->ReadResRef(Signature);
+ if (Signature[0]) {
+ act->PCStats->QuickSpellClass[i]=0xfe;
+ memcpy(act->PCStats->QuickSpells[i], Signature, sizeof(ieResRef));
+ }
+ }
+ //fallthrough
+ case IE_CRE_GEMRB:
+ for (i=0;i<QSPCount;i++) {
+ str->ReadDword( &tmpDword);
+ act->PCStats->QSlots[i+3] = (ieByte) tmpDword;
+ }
+ str->Seek(26, GEM_CURRENT_POS);
+ str->Read( act->PCStats->SoundFolder, 32);
+ str->Read( act->PCStats->SoundSet, 8);
+ for (i=0;i<ES_COUNT;i++) {
+ str->ReadDword( &act->PCStats->ExtraSettings[i] );
+ }
+ //Reserved
+ str->Seek(64, GEM_CURRENT_POS);
+ break;
+ default:
+ break;
+ }
}
bool CREImporter::SeekCreHeader(char *Signature)
@@ -643,9 +855,9 @@ CRESpellMemorization* CREImporter::GetSpellMemorization(Actor *act)
str->ReadDword( &MemorizedCount );
CRESpellMemorization* spl = act->spellbook.GetSpellMemorization(Type, Level);
- assert(spl && spl->Number == 0 && spl->Number2 == 0); // unused
- spl->Number = Number;
- spl->Number2 = Number;
+ assert(spl && spl->SlotCount == 0 && spl->SlotCountWithBonus == 0); // unused
+ spl->SlotCount = Number;
+ spl->SlotCountWithBonus = Number;
return spl;
}
@@ -655,7 +867,7 @@ void CREImporter::SetupColor(ieDword &stat)
if (RandColor==-1) {
RandColor=0;
RandRows=0;
- AutoTable rndcol("randcolr");
+ AutoTable rndcol("randcolr", true);
if (rndcol) {
RandColor = rndcol->GetColumnCount();
RandRows = rndcol->GetRowCount();
@@ -793,17 +1005,16 @@ Actor* CREImporter::GetActor(unsigned char is_in_party)
GetActorIWD1(act);
break;
default:
- Inventory_Size=0;
- printMessage("CREImporter","Unknown creature signature: ", RED);
- printf("%d\n", CREVersion);
- abort();
+ Log(ERROR, "CREImporter", "Unknown creature signature: %d\n", CREVersion);
+ delete act;
+ return NULL;
}
// Read saved effects
if (core->IsAvailable(IE_EFF_CLASS_ID) ) {
ReadEffects( act );
} else {
- printMessage("CREImporter", "Effect importer is unavailable!\n", RED);
+ Log(ERROR, "CREImporter", "Effect importer is unavailable!");
}
// Reading inventory, spellbook, etc
ReadInventory( act, Inventory_Size );
@@ -830,7 +1041,7 @@ void CREImporter::GetActorPST(Actor *act)
str->ReadWord( &tmpWord );
//skipping a word
str->ReadWord( &tmpWord );
- act->BaseStats[IE_ARMORCLASS]=(ieWordSigned) tmpWord;
+ act->AC.SetNatural((ieWordSigned) tmpWord);
str->ReadWord( &tmpWord );
act->BaseStats[IE_ACCRUSHINGMOD]=(ieWordSigned) tmpWord;
str->ReadWord( &tmpWord );
@@ -840,7 +1051,7 @@ void CREImporter::GetActorPST(Actor *act)
str->ReadWord( &tmpWord );
act->BaseStats[IE_ACSLASHINGMOD]=(ieWordSigned) tmpWord;
str->Read( &tmpByte, 1 );
- act->BaseStats[IE_TOHIT]=(ieByteSigned) tmpByte;
+ act->ToHit.SetBase((ieByteSigned) tmpByte);
str->Read( &tmpByte, 1 );
tmpByte = tmpByte * 2;
if (tmpByte>10) tmpByte-=11;
@@ -898,12 +1109,14 @@ void CREImporter::GetActorPST(Actor *act)
act->BaseStats[IE_INTOXICATION]=tmpByte;
str->Read( &tmpByte, 1 );
act->BaseStats[IE_LUCK]=tmpByte;
+ //last byte is actually an undead level (according to IE dev info)
for (i=0;i<21;i++) {
str->Read( &tmpByte, 1 );
act->BaseStats[IE_PROFICIENCYBASTARDSWORD+i]=tmpByte;
}
str->Read( &tmpByte, 1 );
act->BaseStats[IE_TRACKING]=tmpByte;
+ //scriptname of tracked creature (according to IE dev info)
str->Seek( 32, GEM_CURRENT_POS );
for (i=0;i<100;i++) {
str->ReadDword( &act->StrRefs[i] );
@@ -971,8 +1184,6 @@ void CREImporter::GetActorPST(Actor *act)
str->Read( &tmpByte, 1 );
- //str->ReadWord( &act->AppearanceFlags1 );
- //str->ReadWord( &act->AppearanceFlags2 );
str->ReadDword( &act->AppearanceFlags );
for (i = 0; i < 7; i++) {
@@ -1048,7 +1259,7 @@ void CREImporter::ReadInventory(Actor *act, unsigned int Inventory_Size)
str->ReadWordSigned( &act->Equipped );
//the equipped slot's selected ability is stored here
str->ReadWord( &act->EquippedHeader );
-
+
//read the item entries based on the previously read indices
//an item entry may be read multiple times if the indices are repeating
for (i = 0;i<Inventory_Size;) {
@@ -1056,8 +1267,7 @@ void CREImporter::ReadInventory(Actor *act, unsigned int Inventory_Size)
ieWord index = indices[i++];
if (index != 0xffff) {
if (index>=ItemsCount) {
- printMessage("CREImporter"," ",LIGHT_RED);
- printf("Invalid item index (%d) in creature!\n", index);
+ Log(ERROR, "CREImporter", "Invalid item index (%d) in creature!", index);
continue;
}
//20 is the size of CREItem on disc (8+2+3x2+4)
@@ -1068,8 +1278,7 @@ void CREImporter::ReadInventory(Actor *act, unsigned int Inventory_Size)
if (item) {
act->inventory.SetSlotItem(item, Slot);
} else {
- printMessage("CREImporter"," ",LIGHT_RED);
- printf("Invalid item index (%d) in creature!\n", index);
+ Log(ERROR, "CREImporter", "Invalid item index (%d) in creature!", index);
}
}
}
@@ -1114,15 +1323,15 @@ void CREImporter::ReadInventory(Actor *act, unsigned int Inventory_Size)
memorized_spells[k] = NULL;
continue;
}
- printf("[CREImporter]: Duplicate memorized spell (%d) in creature!\n", k);
+ Log(WARNING, "CREImporter", "Duplicate memorized spell(%d) in creature!", k);
}
}
i=KnownSpellsCount;
while(i--) {
if (known_spells[i]) {
- printMessage("CREImporter"," ", YELLOW);
- printf("Dangling spell in creature: %s!\n", known_spells[i]->SpellResRef);
+ Log(WARNING, "CREImporter", "Dangling spell in creature: %s!",
+ known_spells[i]->SpellResRef);
delete known_spells[i];
}
}
@@ -1131,8 +1340,8 @@ void CREImporter::ReadInventory(Actor *act, unsigned int Inventory_Size)
i=MemorizedSpellsCount;
while(i--) {
if (memorized_spells[i]) {
- printMessage("CREImporter"," ", YELLOW);
- printf("Dangling spell in creature: %s!\n", memorized_spells[i]->SpellResRef);
+ Log(WARNING, "CREImporter", "Dangling spell in creature: %s!",
+ memorized_spells[i]->SpellResRef);
delete memorized_spells[i];
}
}
@@ -1177,7 +1386,7 @@ ieDword CREImporter::GetActorGemRB(Actor *act)
//skipping a word( useful for something)
str->ReadWord( &tmpWord );
str->ReadWord( &tmpWord );
- act->BaseStats[IE_ARMORCLASS]=(ieWordSigned) tmpWord;
+ act->AC.SetNatural((ieWordSigned) tmpWord);
str->ReadWord( &tmpWord );
act->BaseStats[IE_ACCRUSHINGMOD]=(ieWordSigned) tmpWord;
str->ReadWord( &tmpWord );
@@ -1187,7 +1396,7 @@ ieDword CREImporter::GetActorGemRB(Actor *act)
str->ReadWord( &tmpWord );
act->BaseStats[IE_ACSLASHINGMOD]=(ieWordSigned) tmpWord;
str->Read( &tmpByte, 1 );
- act->BaseStats[IE_TOHIT]=(ieByteSigned) tmpByte;
+ act->ToHit.SetBase((ieByteSigned) tmpByte);
str->Read( &tmpByte, 1 );
act->BaseStats[IE_NUMBEROFATTACKS]=tmpByte;
str->Read( &tmpByte, 1 );
@@ -1265,7 +1474,7 @@ void CREImporter::GetActorBG(Actor *act)
str->ReadWord( &tmpWord );
//skipping a word
str->ReadWord( &tmpWord );
- act->BaseStats[IE_ARMORCLASS]=(ieWordSigned) tmpWord;
+ act->AC.SetNatural((ieWordSigned) tmpWord);
str->ReadWord( &tmpWord );
act->BaseStats[IE_ACCRUSHINGMOD]=(ieWordSigned) tmpWord;
str->ReadWord( &tmpWord );
@@ -1275,7 +1484,7 @@ void CREImporter::GetActorBG(Actor *act)
str->ReadWord( &tmpWord );
act->BaseStats[IE_ACSLASHINGMOD]=(ieWordSigned) tmpWord;
str->Read( &tmpByte, 1 );
- act->BaseStats[IE_TOHIT]=(ieByteSigned) tmpByte;
+ act->ToHit.SetBase((ieByteSigned) tmpByte);
str->Read( &tmpByte, 1 );
tmpWord = tmpByte * 2;
if (tmpWord>10) tmpWord-=11;
@@ -1433,7 +1642,7 @@ void CREImporter::GetIWD2Spellpage(Actor *act, ieIWD2SpellType type, int level,
int check = 0;
CRESpellMemorization* sm = act->spellbook.GetSpellMemorization(type, level);
- assert(sm && sm->Number == 0 && sm->Number2 == 0); // unused
+ assert(sm && sm->SlotCount == 0 && sm->SlotCountWithBonus == 0); // unused
while(count--) {
str->ReadDword(&spellindex);
str->ReadDword(&totalcount);
@@ -1451,7 +1660,7 @@ void CREImporter::GetIWD2Spellpage(Actor *act, ieIWD2SpellType type, int level,
if(totalcount) {
totalcount--;
} else {
- printMessage("CREImporter", "More spells still known than memorised.\n", LIGHT_RED);
+ Log(ERROR, "CREImporter", "More spells still known than memorised.");
break;
}
CREMemorizedSpell *memory = new CREMemorizedSpell;
@@ -1459,7 +1668,7 @@ void CREImporter::GetIWD2Spellpage(Actor *act, ieIWD2SpellType type, int level,
strnlwrcpy(memory->SpellResRef,*tmp,8);
sm->memorized_spells.push_back(memory);
}
-
+
while(totalcount--) {
CREMemorizedSpell *memory = new CREMemorizedSpell;
memory->Flags=0;
@@ -1467,14 +1676,24 @@ void CREImporter::GetIWD2Spellpage(Actor *act, ieIWD2SpellType type, int level,
sm->memorized_spells.push_back(memory);
}
} else {
- printMessage("CREImporter","Unresolved spell index: ", LIGHT_RED);
- printf("%d level:%d, type: %d\n", spellindex, level+1, type);
+ error("CREImporter", "Unresolved spell index: %d level:%d, type: %d",
+ spellindex, level+1, type);
}
}
+ // hacks for domain spells, since their count is not stored and also always 1
+ // NOTE: luckily this does not cause save game incompatibility
str->ReadDword(&tmpDword);
- sm->Number = (ieWord) tmpDword;
+ if (type == IE_IWD2_SPELL_DOMAIN) {
+ sm->SlotCount = 1;
+ } else {
+ sm->SlotCount = (ieWord) tmpDword;
+ }
str->ReadDword(&tmpDword);
- sm->Number2 = (ieWord) tmpDword;
+ if (type == IE_IWD2_SPELL_DOMAIN) {
+ sm->SlotCountWithBonus = 1;
+ } else {
+ sm->SlotCountWithBonus = (ieWord) tmpDword;
+ }
}
void CREImporter::GetActorIWD2(Actor *act)
@@ -1488,7 +1707,7 @@ void CREImporter::GetActorIWD2(Actor *act)
str->Read( &tmpByte, 1 );
act->BaseStats[IE_HIDEINSHADOWS]=tmpByte;
str->ReadWord( &tmpWord );
- act->BaseStats[IE_ARMORCLASS]=(ieWordSigned) tmpWord;
+ act->AC.SetNatural((ieWordSigned) tmpWord);
str->ReadWord( &tmpWord );
act->BaseStats[IE_ACCRUSHINGMOD]=(ieWordSigned) tmpWord;
str->ReadWord( &tmpWord );
@@ -1498,7 +1717,7 @@ void CREImporter::GetActorIWD2(Actor *act)
str->ReadWord( &tmpWord );
act->BaseStats[IE_ACSLASHINGMOD]=(ieWordSigned) tmpWord;
str->Read( &tmpByte, 1 );
- act->BaseStats[IE_TOHIT]=(ieByteSigned) tmpByte;//Unknown in CRE V2.2
+ act->ToHit.SetBase((ieByteSigned) tmpByte);//Unknown in CRE V2.2
str->Read( &tmpByte, 1 );
act->BaseStats[IE_NUMBEROFATTACKS]=tmpByte;//Unknown in CRE V2.2
str->Read( &tmpByte, 1 );
@@ -1560,7 +1779,7 @@ void CREImporter::GetActorIWD2(Actor *act)
str->Read( & tmpByte, 1 );
act->BaseStats[IE_LEVELTHIEF]=tmpByte;
str->Read( & tmpByte, 1 );
- act->BaseStats[IE_LEVELSORCEROR]=tmpByte;
+ act->BaseStats[IE_LEVELSORCERER]=tmpByte;
str->Read( & tmpByte, 1 );
act->BaseStats[IE_LEVELMAGE]=tmpByte;
str->Seek( 22, GEM_CURRENT_POS ); //levels for classes
@@ -1681,7 +1900,17 @@ void CREImporter::GetActorIWD2(Actor *act)
act->BaseStats[IE_SAVEDYPOS] = tmpWord;
str->ReadWord( &tmpWord );
act->BaseStats[IE_SAVEDFACE] = tmpWord;
- str->Seek( 146, GEM_CURRENT_POS );
+
+ str->Seek( 15, GEM_CURRENT_POS );
+ str->Read( &tmpByte, 1);
+ act->BaseStats[IE_TRANSLUCENT]=tmpByte;
+ str->Read( &tmpByte, 1); //fade speed
+ str->Read( &tmpByte, 1); //spec. flags
+ str->Read( &tmpByte, 1); //invisible
+ str->ReadWord( &tmpWord); //unknown
+ str->Read( &tmpByte, 1); //unused skill points
+ act->BaseStats[IE_UNUSED_SKILLPTS] = tmpByte;
+ str->Seek( 124, GEM_CURRENT_POS );
str->Read( &tmpByte, 1);
act->BaseStats[IE_EA]=tmpByte;
str->Read( &tmpByte, 1);
@@ -1755,8 +1984,8 @@ void CREImporter::GetActorIWD2(Actor *act)
for(i=0;i<8;i++) {
for(int lev=0;lev<9;lev++) {
- //if everything is alright, then this seek is not needed
- str->Seek(CREOffset+ClassSpellOffsets[i*9+lev], GEM_STREAM_START);
+ //if everything is alright, then seeking is not needed
+ assert(str->GetPos() == CREOffset+ClassSpellOffsets[i*9+lev]);
GetIWD2Spellpage(act, (ieIWD2SpellType) i, lev, ClassSpellCounts[i*9+lev]);
}
}
@@ -1783,7 +2012,7 @@ void CREImporter::GetActorIWD1(Actor *act) //9.0
str->ReadWord( &tmpWord );
//skipping a word
str->ReadWord( &tmpWord );
- act->BaseStats[IE_ARMORCLASS]=(ieWordSigned) tmpWord;
+ act->AC.SetNatural((ieWordSigned) tmpWord);
str->ReadWord( &tmpWord );
act->BaseStats[IE_ACCRUSHINGMOD]=(ieWordSigned) tmpWord;
str->ReadWord( &tmpWord );
@@ -1793,7 +2022,7 @@ void CREImporter::GetActorIWD1(Actor *act) //9.0
str->ReadWord( &tmpWord );
act->BaseStats[IE_ACSLASHINGMOD]=(ieWordSigned) tmpWord;
str->Read( &tmpByte, 1 );
- act->BaseStats[IE_TOHIT]=(ieByteSigned) tmpByte;
+ act->ToHit.SetBase((ieByteSigned) tmpByte);
str->Read( &tmpByte, 1 );
tmpByte = tmpByte * 2;
if (tmpByte>10) tmpByte-=11;
@@ -2011,9 +2240,17 @@ int CREImporter::GetStoredFileSize(Actor *actor)
KnownSpellsOffset = headersize;
if (actor->version==IE_CRE_V2_2) { //iwd2
- //adding spellbook header sizes
- //class spells, domains, (shapes,songs,innates)
- headersize += 7*9*8 + 9*8 + 3*8;
+ int type, level;
+
+ for (type=IE_IWD2_SPELL_BARD;type<IE_IWD2_SPELL_DOMAIN;type++) for(level=0;level<9;level++) {
+ headersize += GetIWD2SpellpageSize(actor, (ieIWD2SpellType) type, level)*16+8;
+ }
+ for(level=0;level<9;level++) {
+ headersize += GetIWD2SpellpageSize(actor, IE_IWD2_SPELL_DOMAIN, level)*16+8;
+ }
+ for (type=IE_IWD2_SPELL_INNATE;type<NUM_IWD2_SPELLTYPES;type++) {
+ headersize += GetIWD2SpellpageSize(actor, (ieIWD2SpellType) type, 0)*16+8;
+ }
} else {//others
//adding known spells
KnownSpellsCount = actor->spellbook.GetTotalKnownSpellsCount();
@@ -2132,7 +2369,7 @@ int CREImporter::PutHeader(DataStream *stream, Actor *actor)
stream->WriteDword( &actor->BaseStats[IE_STATE_ID]);
tmpWord = actor->BaseStats[IE_HITPOINTS];
//decrease the hp back to the one without constitution bonus
- //this is probably still not perfect
+ // (but only player classes can have it)
tmpWord = (ieWord) (tmpWord - actor->GetHpAdjustment(actor->GetXPLevel(false)));
stream->WriteWord( &tmpWord);
tmpWord = actor->BaseStats[IE_MAXHITPOINTS];
@@ -2151,12 +2388,12 @@ int CREImporter::PutHeader(DataStream *stream, Actor *actor)
tmpByte = actor->BaseStats[IE_HIDEINSHADOWS];
stream->Write( &tmpByte, 1 );
//from here it differs, slightly
- tmpWord = actor->BaseStats[IE_ARMORCLASS];
+ tmpWord = actor->AC.GetNatural();
stream->WriteWord( &tmpWord);
//iwd2 doesn't store this a second time,
//probably gemrb format shouldn't either?
if (actor->version != IE_CRE_V2_2) {
- tmpWord = actor->BaseStats[IE_ARMORCLASS];
+ tmpWord = actor->AC.GetNatural();
stream->WriteWord( &tmpWord);
}
tmpWord = actor->BaseStats[IE_ACCRUSHINGMOD];
@@ -2167,7 +2404,7 @@ int CREImporter::PutHeader(DataStream *stream, Actor *actor)
stream->WriteWord( &tmpWord);
tmpWord = actor->BaseStats[IE_ACSLASHINGMOD];
stream->WriteWord( &tmpWord);
- tmpByte = actor->BaseStats[IE_TOHIT];
+ tmpByte = actor->ToHit.GetBase();
stream->Write( &tmpByte, 1);
tmpByte = actor->BaseStats[IE_NUMBEROFATTACKS];
if (actor->version == IE_CRE_V2_2) {
@@ -2271,7 +2508,7 @@ int CREImporter::PutHeader(DataStream *stream, Actor *actor)
stream->Write( &tmpByte, 1);
tmpByte = actor->BaseStats[IE_LEVELTHIEF];
stream->Write( &tmpByte, 1);
- tmpByte = actor->BaseStats[IE_LEVELSORCEROR];
+ tmpByte = actor->BaseStats[IE_LEVELSORCERER];
stream->Write( &tmpByte, 1);
tmpByte = actor->BaseStats[IE_LEVELMAGE];
stream->Write( &tmpByte, 1);
@@ -2518,8 +2755,6 @@ int CREImporter::PutActorPST(DataStream *stream, Actor *actor)
stream->Write( filling,3); //unknown
tmpByte=actor->BaseStats[IE_COLORCOUNT];
stream->Write( &tmpByte, 1);
- //stream->WriteWord( &actor->AppearanceFlags1);
- //stream->WriteWord( &actor->AppearanceFlags2);
stream->WriteDword( &actor->AppearanceFlags);
for (i=0;i<7;i++) {
@@ -2607,13 +2842,13 @@ int CREImporter::PutActorIWD2(DataStream *stream, Actor *actor)
ieByte tmpByte;
ieWord tmpWord;
int i;
- char filling[146];
+ char filling[124];
memset(filling,0,sizeof(filling));
tmpByte=(ieByte) actor->BaseStats[IE_AVATARREMOVAL];
stream->Write( &tmpByte, 1);
stream->Write( &actor->SetDeathVar, 1);
- stream->Write( &actor->IncKillCount, 1);
+ stream->Write( &actor->IncKillCount, 1);
stream->Write( &actor->UnknownField, 1); //unknown
for (i=0;i<5;i++) {
tmpWord = actor->BaseStats[IE_INTERNAL_0+i];
@@ -2628,7 +2863,13 @@ int CREImporter::PutActorIWD2(DataStream *stream, Actor *actor)
stream->WriteWord( &tmpWord);
tmpWord = actor->BaseStats[IE_SAVEDFACE];
stream->WriteWord( &tmpWord);
- stream->Write( filling, 146);
+ stream->Write( filling, 15);
+ tmpByte = actor->BaseStats[IE_TRANSLUCENT];
+ stream->Write(&tmpByte, 1);
+ stream->Write( filling, 5); //fade speed, spec flags, invisible
+ tmpByte = actor->BaseStats[IE_UNUSED_SKILLPTS];
+ stream->Write( &tmpByte, 1);
+ stream->Write( filling, 124);
//similar in all engines
tmpByte = actor->BaseStats[IE_EA];
stream->Write( &tmpByte, 1);
@@ -2691,7 +2932,7 @@ int CREImporter::PutSpellPages( DataStream *stream, Actor *actor)
tmpWord = i;
stream->WriteWord( &tmpWord);
stream->WriteDword( &SpellIndex);
- tmpDword = actor->spellbook.GetMemorizedSpellsCount(i,j);
+ tmpDword = actor->spellbook.GetMemorizedSpellsCount(i,j, false);
stream->WriteDword( &tmpDword);
SpellIndex += tmpDword;
}
@@ -2705,7 +2946,7 @@ int CREImporter::PutMemorizedSpells(DataStream *stream, Actor *actor)
for (int i=0;i<type;i++) {
unsigned int level = actor->spellbook.GetSpellLevelCount(i);
for (unsigned int j=0;j<level;j++) {
- unsigned int count = actor->spellbook.GetMemorizedSpellsCount(i,j);
+ unsigned int count = actor->spellbook.GetMemorizedSpellsCount(i,j, false);
for (unsigned int k=0;k<count;k++) {
CREMemorizedSpell *cm = actor->spellbook.GetMemorizedSpell(i,j,k);
@@ -2750,9 +2991,9 @@ int CREImporter::PutEffects( DataStream *stream, Actor *actor)
tmpByte = (ieByte) fx->Resistance;
stream->Write(&tmpByte, 1);
stream->WriteDword( &fx->Duration);
- tmpByte = (ieByte) fx->Probability1;
+ tmpByte = (ieByte) fx->ProbabilityRangeMax;
stream->Write(&tmpByte, 1);
- tmpByte = (ieByte) fx->Probability2;
+ tmpByte = (ieByte) fx->ProbabilityRangeMin;
stream->Write(&tmpByte, 1);
stream->Write(fx->Resource, 8);
stream->WriteDword( &fx->DiceThrown );
@@ -2797,6 +3038,39 @@ int CREImporter::PutVariables( DataStream *stream, Actor *actor)
return 0;
}
+//Don't forget to add 8 for the totals/bonus fields
+ieDword CREImporter::GetIWD2SpellpageSize(Actor *actor, ieIWD2SpellType type, int level) const
+{
+ CRESpellMemorization* sm = actor->spellbook.GetSpellMemorization(type, level);
+ ieDword cnt = sm->known_spells.size();
+ return cnt;
+}
+
+int CREImporter::PutIWD2Spellpage(DataStream *stream, Actor *actor, ieIWD2SpellType type, int level)
+{
+ ieDword ID, max, known;
+
+ CRESpellMemorization* sm = actor->spellbook.GetSpellMemorization(type, level);
+ for (unsigned int k = 0; k < sm->known_spells.size(); k++) {
+ CREKnownSpell *ck = sm->known_spells[k];
+ ID = ResolveSpellName(ck->SpellResRef, level, type);
+ stream->WriteDword ( &ID);
+ max = actor->spellbook.CountSpells(ck->SpellResRef, type, 1);
+ known = actor->spellbook.CountSpells(ck->SpellResRef, type, 0);
+ stream->WriteDword ( &max);
+ stream->WriteDword ( &known);
+ //unknown field (always 0)
+ known = 0;
+ stream->WriteDword (&known);
+ }
+
+ max = sm->SlotCount;
+ known = sm->SlotCountWithBonus;
+ stream->WriteDword ( &max);
+ stream->WriteDword ( &known);
+ return 0;
+}
+
/* this function expects GetStoredFileSize to be called before */
int CREImporter::PutActor(DataStream *stream, Actor *actor, bool chr)
{
@@ -2852,30 +3126,35 @@ int CREImporter::PutActor(DataStream *stream, Actor *actor, bool chr)
return ret;
}
- //writing offsets
+ //writing offsets and counts
if (actor->version==IE_CRE_V2_2) {
- int i;
+ int type, level;
//class spells
- for (i=0;i<7*9;i++) {
+ for (type=IE_IWD2_SPELL_BARD;type<IE_IWD2_SPELL_DOMAIN;type++) for(level=0;level<9;level++) {
+ tmpDword = GetIWD2SpellpageSize(actor, (ieIWD2SpellType) type, level);
stream->WriteDword(&KnownSpellsOffset);
- KnownSpellsOffset+=8;
+ KnownSpellsOffset+=tmpDword*16+8;
}
- for (i=0;i<7*9;i++) {
+ for (type=IE_IWD2_SPELL_BARD;type<IE_IWD2_SPELL_DOMAIN;type++) for(level=0;level<9;level++) {
+ tmpDword = GetIWD2SpellpageSize(actor, (ieIWD2SpellType) type, level);
stream->WriteDword(&tmpDword);
}
//domain spells
- for (i=0;i<9;i++) {
+ for (level=0;level<9;level++) {
+ tmpDword = GetIWD2SpellpageSize(actor, IE_IWD2_SPELL_DOMAIN, level);
stream->WriteDword(&KnownSpellsOffset);
- KnownSpellsOffset+=8;
+ KnownSpellsOffset+=tmpDword*16+8;
}
- for (i=0;i<9;i++) {
+ for (level=0;level<9;level++) {
+ tmpDword = GetIWD2SpellpageSize(actor, IE_IWD2_SPELL_DOMAIN, level);
stream->WriteDword(&tmpDword);
}
//innates, shapes, songs
- for (i=0;i<3;i++) {
+ for (type=IE_IWD2_SPELL_INNATE;type<NUM_IWD2_SPELLTYPES;type++) {
+ tmpDword = GetIWD2SpellpageSize(actor, (ieIWD2SpellType) type, 0);
stream->WriteDword(&KnownSpellsOffset);
- KnownSpellsOffset+=8;
+ KnownSpellsOffset+=tmpDword*16+8;
stream->WriteDword(&tmpDword);
}
} else {
@@ -2897,22 +3176,21 @@ int CREImporter::PutActor(DataStream *stream, Actor *actor, bool chr)
//spells, spellbook etc
if (actor->version==IE_CRE_V2_2) {
- int i;
+ int type, level;
- //putting out book headers
- for (i=0;i<7*9;i++) {
- stream->WriteDword(&tmpDword);
- stream->WriteDword(&tmpDword);
+ //writing out spell page headers
+ for (type=IE_IWD2_SPELL_BARD;type<IE_IWD2_SPELL_DOMAIN;type++) for(level=0;level<9;level++) {
+ PutIWD2Spellpage(stream, actor, (ieIWD2SpellType) type, level);
}
- //domain headers
- for (i=0;i<9;i++) {
- stream->WriteDword(&tmpDword);
- stream->WriteDword(&tmpDword);
+
+ //writing out domain page headers
+ for (level=0;level<9;level++) {
+ PutIWD2Spellpage(stream, actor, IE_IWD2_SPELL_DOMAIN, level);
}
+
//innates, shapes, songs
- for (i=0;i<3;i++) {
- stream->WriteDword(&tmpDword);
- stream->WriteDword(&tmpDword);
+ for (type = IE_IWD2_SPELL_INNATE; type<NUM_IWD2_SPELLTYPES; type ++) {
+ PutIWD2Spellpage(stream, actor, (ieIWD2SpellType) type, 0);
}
} else {
assert(stream->GetPos() == CREOffset+KnownSpellsOffset);
diff --git a/gemrb/plugins/CREImporter/CREImporter.h b/gemrb/plugins/CREImporter/CREImporter.h
index a0417e1..56a71ea 100644
--- a/gemrb/plugins/CREImporter/CREImporter.h
+++ b/gemrb/plugins/CREImporter/CREImporter.h
@@ -22,6 +22,12 @@
#define CREIMPORTER_H
#include "ActorMgr.h"
+#include "Spellbook.h"
+
+namespace GemRB {
+
+class CREItem;
+struct Effect;
#define IE_CRE_GEMRB 0
#define IE_CRE_V1_0 10 //bg1
@@ -33,7 +39,6 @@
class CREImporter : public ActorMgr {
private:
DataStream* str;
- bool autoFree;
unsigned char CREVersion;
ieDword KnownSpellsOffset;
ieDword KnownSpellsCount;
@@ -61,9 +66,11 @@ private:
public:
CREImporter(void);
~CREImporter(void);
- bool Open(DataStream* stream, bool autoFree = true);
+ bool Open(DataStream* stream);
Actor* GetActor(unsigned char is_in_party);
+ int FindSpellType(char *name, unsigned short &level, unsigned int clsmsk, unsigned int kit) const;
+
//returns saved size, updates internal offsets before save
int GetStoredFileSize(Actor *ac);
//saves file
@@ -82,6 +89,7 @@ private:
void GetActorBG(Actor *actor);
void GetActorIWD1(Actor *actor);
void GetActorIWD2(Actor *actor);
+ ieDword GetIWD2SpellpageSize(Actor *actor, ieIWD2SpellType type, int level) const;
void GetIWD2Spellpage(Actor *act, ieIWD2SpellType type, int level, int count);
void ReadInventory(Actor*, unsigned int);
void ReadEffects(Actor* actor);
@@ -100,6 +108,7 @@ private:
int PutActorBG(DataStream *stream, Actor *actor);
int PutActorIWD1(DataStream *stream, Actor *actor);
int PutActorIWD2(DataStream *stream, Actor *actor);
+ int PutIWD2Spellpage(DataStream *stream, Actor *actor, ieIWD2SpellType type, int level);
int PutKnownSpells(DataStream *stream, Actor *actor);
int PutSpellPages(DataStream *stream, Actor *actor);
int PutMemorizedSpells(DataStream *stream, Actor *actor);
@@ -109,4 +118,6 @@ private:
int PutHeader(DataStream *stream, Actor *actor);
};
+}
+
#endif
diff --git a/gemrb/plugins/DLGImporter/DLGImporter.cpp b/gemrb/plugins/DLGImporter/DLGImporter.cpp
index 576831b..1ed863f 100644
--- a/gemrb/plugins/DLGImporter/DLGImporter.cpp
+++ b/gemrb/plugins/DLGImporter/DLGImporter.cpp
@@ -26,35 +26,30 @@
#include "GameScript/GameScript.h"
#include "System/FileStream.h"
+using namespace GemRB;
+
DLGImporter::DLGImporter(void)
{
str = NULL;
- autoFree = false;
Version = 0;
}
DLGImporter::~DLGImporter(void)
{
- if (str && autoFree) {
- delete( str );
- }
+ delete str;
}
-bool DLGImporter::Open(DataStream* stream, bool autoFree)
+bool DLGImporter::Open(DataStream* stream)
{
if (stream == NULL) {
return false;
}
- if (str && this->autoFree) {
- delete( str );
- }
+ delete str;
str = stream;
- this->autoFree = autoFree;
char Signature[8];
str->Read( Signature, 8 );
if (strnicmp( Signature, "DLG V1.0", 8 ) != 0) {
- printMessage( "DLGImporter", "Not a valid DLG File...", WHITE );
- printStatus( "ERROR", LIGHT_RED );
+ Log(ERROR, "DLGImporter", "Not a valid DLG File...");
Version = 0;
return false;
}
@@ -166,7 +161,7 @@ DialogTransition* DLGImporter::GetTransition(unsigned int index) const
static char** GetStrings(char* string, unsigned int& count);
-Condition* GetCondition(char* string)
+static Condition* GetCondition(char* string)
{
unsigned int count;
char **lines = GetStrings( string, count );
@@ -174,14 +169,13 @@ Condition* GetCondition(char* string)
for (size_t i = 0; i < count; ++i) {
Trigger *trigger = GenerateTrigger(lines[i]);
if (!trigger) {
- printMessage( "DLGImporter", "Can't compile trigger: " ,YELLOW);
- printf("%s\n", lines[i]);
+ Log(WARNING, "DLGImporter", "Can't compile trigger: %s", lines[i]);
} else {
condition->triggers.push_back(trigger);
}
- free(lines[i]);
+ free( lines[i] );
}
- free(lines);
+ free( lines );
return condition;
}
@@ -206,7 +200,7 @@ Condition* DLGImporter::GetStateTrigger(unsigned int index) const
str->Read( string, Length );
string[Length] = 0;
Condition *condition = GetCondition(string);
- free(string);
+ free( string );
return condition;
}
@@ -247,18 +241,19 @@ std::vector<Action*> DLGImporter::GetAction(unsigned int index) const
for (size_t i = 0; i < count; ++i) {
Action *action = GenerateAction(lines[i]);
if (!action) {
- printMessage( "DLGImporter", "Can't compile action: " ,YELLOW);
- printf("%s\n", lines[i]);
+ Log(WARNING, "DLGImporter", "Can't compile action: %s", lines[i]);
} else {
action->IncRef();
actions.push_back(action);
}
- free(lines[i]);
+ free( lines[i] );
}
+ free( lines );
+ free( string );
return actions;
}
-int GetActionLength(const char* string)
+static int GetActionLength(const char* string)
{
int i;
int level = 0;
@@ -303,7 +298,7 @@ int GetActionLength(const char* string)
pst's FORGE.DLG (trigger split across two lines),
bg2's SAHIMP02.DLG (missing quotemark in string),
bg2's QUAYLE.DLG (missing closing bracket) */
-char** GetStrings(char* string, unsigned int& count)
+static char** GetStrings(char* string, unsigned int& count)
{
int col = 0;
int level = 0;
diff --git a/gemrb/plugins/DLGImporter/DLGImporter.h b/gemrb/plugins/DLGImporter/DLGImporter.h
index 10cade5..886ef87 100644
--- a/gemrb/plugins/DLGImporter/DLGImporter.h
+++ b/gemrb/plugins/DLGImporter/DLGImporter.h
@@ -25,6 +25,8 @@
#include "globals.h"
+namespace GemRB {
+
/*
struct State {
ieStrRef StrRef;
@@ -53,7 +55,6 @@ struct VarOffset {
class DLGImporter : public DialogMgr {
private:
DataStream* str;
- bool autoFree;
ieDword StatesCount;
ieDword StatesOffset;
ieDword TransitionsCount;
@@ -70,7 +71,7 @@ private:
public:
DLGImporter(void);
~DLGImporter(void);
- bool Open(DataStream* stream, bool autoFree = true);
+ bool Open(DataStream* stream);
Dialog* GetDialog() const;
private:
DialogState* GetDialogState(Dialog *d, unsigned int index) const;
@@ -82,4 +83,6 @@ private:
unsigned int count) const;
};
+}
+
#endif
diff --git a/gemrb/plugins/DirectoryImporter/DirectoryImporter.cpp b/gemrb/plugins/DirectoryImporter/DirectoryImporter.cpp
index 9a4ba39..775bc99 100644
--- a/gemrb/plugins/DirectoryImporter/DirectoryImporter.cpp
+++ b/gemrb/plugins/DirectoryImporter/DirectoryImporter.cpp
@@ -25,6 +25,8 @@
#include "ResourceDesc.h"
#include "System/FileStream.h"
+using namespace GemRB;
+
DirectoryImporter::DirectoryImporter(void)
{
description = NULL;
@@ -37,6 +39,9 @@ DirectoryImporter::~DirectoryImporter(void)
bool DirectoryImporter::Open(const char *dir, const char *desc)
{
+ if (!dir_exists(dir))
+ return false;
+
free(description);
description = strdup(desc);
strcpy(path, dir);
@@ -47,29 +52,21 @@ static bool FindIn(const char *Path, const char *ResRef, const char *Type)
{
char p[_MAX_PATH], f[_MAX_PATH] = {0};
strcpy(f, ResRef);
- strcat(f, Type);
strlwr(f);
- return PathJoin(p, Path, f, NULL);
+ return PathJoinExt(p, Path, f, Type);
}
static FileStream *SearchIn(const char * Path,const char * ResRef, const char *Type)
{
char p[_MAX_PATH], f[_MAX_PATH] = {0};
strcpy(f, ResRef);
- strcat(f, Type);
strlwr(f);
- if (!PathJoin(p, Path, f, NULL))
+ if (!PathJoinExt(p, Path, f, Type))
return NULL;
- FileStream * fs = new FileStream();
- if(!fs) return NULL;
- if(!fs->Open(p, true)) {
- delete fs;
- return NULL;
- }
- return fs;
+ return FileStream::OpenFile(p);
}
bool DirectoryImporter::HasResource(const char* resname, SClass_ID type)
@@ -92,8 +89,105 @@ DataStream* DirectoryImporter::GetResource(const char* resname, const ResourceDe
return SearchIn( path, resname, type.GetExt() );
}
+CachedDirectoryImporter::CachedDirectoryImporter()
+{
+}
+
+CachedDirectoryImporter::~CachedDirectoryImporter()
+{
+}
+
+bool CachedDirectoryImporter::Open(const char *dir, const char *desc)
+{
+ if (!DirectoryImporter::Open(dir, desc))
+ return false;
+
+ Refresh();
+
+ return true;
+}
+
+void CachedDirectoryImporter::Refresh()
+{
+ cache.clear();
+
+ DirectoryIterator it(path);
+ if (!it)
+ return;
+
+ unsigned int count = 0;
+ do {
+ if (it.IsDirectory())
+ continue;
+ count++;
+ } while (++it);
+
+ // limit to 4k buckets
+ // less than 1% of the bg2+fixpack override are of bucket length >4
+ cache.init(count > 4 * 1024 ? 4 * 1024 : count, count);
+
+ it.Rewind();
+
+ char buf[_MAX_PATH];
+ do {
+ if (it.IsDirectory())
+ continue;
+ const char *name = it.GetName();
+ strnlwrcpy(buf, name, _MAX_PATH, false);
+ if (cache.set(buf, name)) {
+ Log(ERROR, "CachedDirectoryImporter", "Duplicate '%s' files in '%s' directory", buf, path);
+ }
+ } while (++it);
+}
+
+static const char *ConstructFilename(const char* resname, const char* ext)
+{
+ static char buf[_MAX_PATH];
+ strnlwrcpy(buf, resname, _MAX_PATH-4, false);
+ strcat(buf, ".");
+ strcat(buf, ext);
+ return buf;
+}
+
+bool CachedDirectoryImporter::HasResource(const char* resname, SClass_ID type)
+{
+ const char* filename = ConstructFilename(resname, core->TypeExt(type));
+ return cache.has(filename);
+}
+
+bool CachedDirectoryImporter::HasResource(const char* resname, const ResourceDesc &type)
+{
+ const char* filename = ConstructFilename(resname, type.GetExt());
+ return cache.has(filename);
+}
+
+DataStream* CachedDirectoryImporter::GetResource(const char* resname, SClass_ID type)
+{
+ const char* filename = ConstructFilename(resname, core->TypeExt(type));
+ const std::string *s = cache.get(filename);
+ if (!s)
+ return NULL;
+ char buf[_MAX_PATH];
+ strcpy(buf, path);
+ PathAppend(buf, s->c_str());
+ return FileStream::OpenFile(buf);
+}
+
+DataStream* CachedDirectoryImporter::GetResource(const char* resname, const ResourceDesc &type)
+{
+ const char* filename = ConstructFilename(resname, type.GetExt());
+ const std::string *s = cache.get(filename);
+ if (!s)
+ return NULL;
+ char buf[_MAX_PATH];
+ strcpy(buf, path);
+ PathAppend(buf, s->c_str());
+ return FileStream::OpenFile(buf);
+}
+
#include "plugindef.h"
GEMRB_PLUGIN(0xAB4534, "Directory Importer")
PLUGIN_CLASS(PLUGIN_RESOURCE_DIRECTORY, DirectoryImporter)
+PLUGIN_CLASS(PLUGIN_RESOURCE_CACHEDDIRECTORY, CachedDirectoryImporter)
END_PLUGIN()
diff --git a/gemrb/plugins/DirectoryImporter/DirectoryImporter.h b/gemrb/plugins/DirectoryImporter/DirectoryImporter.h
index 46a0c84..ef3877a 100644
--- a/gemrb/plugins/DirectoryImporter/DirectoryImporter.h
+++ b/gemrb/plugins/DirectoryImporter/DirectoryImporter.h
@@ -20,17 +20,17 @@
#define KEYIMP_H
#include "ResourceSource.h"
+#include "StringMap.h"
-#include <cstring>
-#include <map>
-#include <vector>
+namespace GemRB {
class Resource;
class ResourceDesc;
class DirectoryImporter : public ResourceSource {
-private:
+protected:
char path[_MAX_PATH];
+
public:
DirectoryImporter(void);
~DirectoryImporter(void);
@@ -43,4 +43,25 @@ public:
DataStream* GetResource(const char* resname, const ResourceDesc &type);
};
+class CachedDirectoryImporter : public DirectoryImporter {
+protected:
+ StringMap cache;
+
+public:
+ CachedDirectoryImporter();
+ ~CachedDirectoryImporter();
+
+ bool Open(const char *dir, const char *desc);
+ void Refresh();
+ /** predicts the availability of a resource */
+ bool HasResource(const char* resname, SClass_ID type);
+ bool HasResource(const char* resname, const ResourceDesc &type);
+ /** returns resource */
+ DataStream* GetResource(const char* resname, SClass_ID type);
+ DataStream* GetResource(const char* resname, const ResourceDesc &type);
+};
+
+
+}
+
#endif
diff --git a/gemrb/plugins/EFFImporter/EFFImporter.cpp b/gemrb/plugins/EFFImporter/EFFImporter.cpp
index 5da8be8..e780377 100644
--- a/gemrb/plugins/EFFImporter/EFFImporter.cpp
+++ b/gemrb/plugins/EFFImporter/EFFImporter.cpp
@@ -24,6 +24,8 @@
#include "Interface.h"
+using namespace GemRB;
+
EFFImporter::EFFImporter(void)
{
str = NULL;
@@ -63,10 +65,11 @@ bool EFFImporter::Open(DataStream* stream, bool autoFree)
//if level>than maximum affected or level<than minimum affected, then the
//effect is resisted
// copy the info into the EFFV2 fields (separate), so it is clearer
-inline static void fixAffectedLevels(Effect *fx) {
+static inline void fixAffectedLevels(Effect *fx) {
if (fx->DiceSides > 0 || fx->DiceThrown > 0) {
- fx->MinAffectedLevel = fx->DiceThrown;
- fx->MaxAffectedLevel = fx->DiceSides;
+ //cloudkill needs these in this order
+ fx->MinAffectedLevel = fx->DiceSides;
+ fx->MaxAffectedLevel = fx->DiceThrown;
}
}
@@ -103,9 +106,9 @@ Effect* EFFImporter::GetEffectV1(Effect *fx)
fx->Resistance = tmpByte;
str->ReadDword( &fx->Duration );
str->Read( &tmpByte, 1 );
- fx->Probability1 = tmpByte;
+ fx->ProbabilityRangeMax = tmpByte;
str->Read( &tmpByte, 1 );
- fx->Probability2 = tmpByte;
+ fx->ProbabilityRangeMin = tmpByte;
str->ReadResRef( fx->Resource );
str->ReadDword( &fx->DiceThrown );
str->ReadDword( &fx->DiceSides );
@@ -134,8 +137,8 @@ Effect* EFFImporter::GetEffectV20(Effect *fx)
str->ReadWord( &fx->TimingMode );
str->ReadWord( &fx->unknown2 );
str->ReadDword( &fx->Duration );
- str->ReadWord( &fx->Probability1 );
- str->ReadWord( &fx->Probability2 );
+ str->ReadWord( &fx->ProbabilityRangeMax );
+ str->ReadWord( &fx->ProbabilityRangeMin );
str->ReadResRef( fx->Resource );
str->ReadDword( &fx->DiceThrown );
str->ReadDword( &fx->DiceSides );
@@ -150,7 +153,8 @@ Effect* EFFImporter::GetEffectV20(Effect *fx)
str->ReadDword( &fx->Resistance );
str->ReadDword( &fx->Parameter3 );
str->ReadDword( &fx->Parameter4 );
- str->Seek( 8, GEM_CURRENT_POS );
+ str->ReadDword( &fx->Parameter5 );
+ str->ReadDword( &fx->Parameter6 );
str->ReadResRef( fx->Resource2 );
str->ReadResRef( fx->Resource3 );
str->ReadDword( &fx->PosX);
@@ -195,25 +199,28 @@ void EFFImporter::PutEffectV2(DataStream *stream, const Effect *fx) {
stream->WriteWord( &fx->TimingMode);
stream->WriteWord( &fx->unknown2);
stream->WriteDword( &fx->Duration);
- stream->WriteWord( &fx->Probability1);
- stream->WriteWord( &fx->Probability2);
- stream->WriteResRef(fx->Resource);
+ stream->WriteWord( &fx->ProbabilityRangeMax);
+ stream->WriteWord( &fx->ProbabilityRangeMin);
+ if (fx->IsVariable) {
+ stream->Write( filling,8 );
+ } else {
+ stream->WriteResRef(fx->Resource);
+ }
stream->WriteDword( &fx->DiceThrown );
stream->WriteDword( &fx->DiceSides );
stream->WriteDword( &fx->SavingThrowType );
stream->WriteDword( &fx->SavingThrowBonus );
- //isvariable
- stream->Write( filling,4 );
+ stream->WriteWord( &fx->IsVariable );
+ stream->Write( filling,2 ); // SaveForHalfDamage
stream->WriteDword( &fx->PrimaryType );
- stream->Write( filling,12 );
+ stream->Write( filling,12 ); // MinAffectedLevel, MaxAffectedLevel, Resistance
stream->WriteDword( &fx->Resistance );
stream->WriteDword( &fx->Parameter3 );
stream->WriteDword( &fx->Parameter4 );
- stream->Write( filling,8 );
+ stream->WriteDword( &fx->Parameter5 );
+ stream->WriteDword( &fx->Parameter6 );
if (fx->IsVariable) {
- stream->Write(fx->Resource+8, 8);
- //resource1-4 are used as a continuous memory
- stream->Write(((ieByte *) fx->Resource)+16, 8);
+ stream->Write( filling,16 );
} else {
stream->WriteResRef(fx->Resource2);
stream->WriteResRef(fx->Resource3);
@@ -231,7 +238,14 @@ void EFFImporter::PutEffectV2(DataStream *stream, const Effect *fx) {
stream->WriteDword( &fx->Projectile );
tmpDword1 = (ieDword) fx->InventorySlot;
stream->WriteDword( &tmpDword1 );
- stream->Write( filling,40 ); //12+32+8
+ if (fx->IsVariable) {
+ //resource1-4 are used as a continuous memory
+ stream->Write(fx->Resource, 32);
+ } else {
+ stream->Write( filling,32 );
+ }
+ stream->WriteDword( &fx->CasterLevel);
+ stream->Write( filling,4);
stream->WriteDword( &fx->SecondaryType );
stream->Write( filling,60 );
}
diff --git a/gemrb/plugins/EFFImporter/EFFImporter.h b/gemrb/plugins/EFFImporter/EFFImporter.h
index b978257..0a34154 100644
--- a/gemrb/plugins/EFFImporter/EFFImporter.h
+++ b/gemrb/plugins/EFFImporter/EFFImporter.h
@@ -27,6 +27,8 @@
#include "Effect.h"
+namespace GemRB {
+
class EFFImporter : public EffectMgr {
private:
DataStream* str;
@@ -36,6 +38,8 @@ private:
public:
EFFImporter(void);
~EFFImporter(void);
+ // We need this autoFree, since Effects are included inline
+ // in other file types, without a size header.
bool Open(DataStream* stream, bool autoFree = true);
Effect* GetEffect(Effect *fx);
Effect* GetEffectV1(Effect *fx);
@@ -44,4 +48,6 @@ public:
};
+}
+
#endif
diff --git a/gemrb/plugins/FXOpcodes/FXOpcodes.cpp b/gemrb/plugins/FXOpcodes/FXOpcodes.cpp
index ee921da..a90180e 100644
--- a/gemrb/plugins/FXOpcodes/FXOpcodes.cpp
+++ b/gemrb/plugins/FXOpcodes/FXOpcodes.cpp
@@ -29,9 +29,11 @@
#include "EffectQueue.h"
#include "Game.h"
#include "GameData.h"
+#include "GlobalTimer.h"
#include "Interface.h"
#include "PolymorphCache.h" // fx_polymorph
#include "Projectile.h" //needs for clearair
+#include "ScriptedAnimation.h"
#include "Spell.h" //needed for fx_cast_spell feedback
#include "TileMap.h" //needs for knock!
#include "damages.h"
@@ -44,11 +46,14 @@
#include "Scriptable/InfoPoint.h"
#include "Scriptable/PCStatStruct.h" //fx_polymorph (action definitions)
+using namespace GemRB;
+
//FIXME: find a way to handle portrait icons better
#define PI_RIGID 2
#define PI_CONFUSED 3
#define PI_BERSERK 4
#define PI_POISONED 6
+#define PI_BLIND 8
#define PI_HELD 13
#define PI_SLEEP 14
#define PI_BLESS 17
@@ -65,6 +70,7 @@
#define PI_BOUNCE 65
#define PI_BOUNCE2 67
+#define PI_CONTINGENCY 75
#define PI_BLOODRAGE 76 //iwd2
#define PI_MAZE 78
#define PI_PRISON 79
@@ -80,13 +86,13 @@
static ieResRef *casting_glows = NULL;
static int cgcount = -1;
static ieResRef *spell_hits = NULL;
-static bool enhanced_effects = false;
+static ieDword enhanced_effects = 0;
static int shcount = -1;
static int *spell_abilities = NULL;
static ieDword splabcount = 0;
static int *polymorph_stats = NULL;
static int polystatcount = 0;
-static bool pstflags = false;
+static ieDword pstflags = false;
//the original engine stores the colors in sprklclr.2da in a different order
@@ -205,7 +211,7 @@ int fx_morale_break_modifier (Scriptable* Owner, Actor* target, Effect* fx);//6a
int fx_portrait_change (Scriptable* Owner, Actor* target, Effect* fx);//6b
int fx_reputation_modifier (Scriptable* Owner, Actor* target, Effect* fx);//6c
int fx_hold_creature_no_icon (Scriptable* Owner, Actor* target, Effect* fx);//6d
-//int fx_retreat_from (Scriptable* Owner, Actor* target, Effect* fx);//6e reused
+int fx_turn_undead (Scriptable* Owner, Actor* target, Effect* fx);//6e reused
int fx_create_magic_item (Scriptable* Owner, Actor* target, Effect* fx);//6f
int fx_remove_item (Scriptable* Owner, Actor* target, Effect* fx);//70
int fx_equip_item (Scriptable* Owner, Actor* target, Effect* fx);//71
@@ -416,7 +422,7 @@ int fx_golem_stoneskin_modifier (Scriptable* Owner, Actor* target, Effect* fx);/
int fx_avatar_removal_modifier (Scriptable* Owner, Actor* target, Effect* fx);//13b
int fx_magical_rest (Scriptable* Owner, Actor* target, Effect* fx);//13c
//int fx_improved_haste_state (Scriptable* Owner, Actor* target, Effect* fx);//13d same as haste
-int fx_change_weather (Scriptable* Owner, Actor* target, Effect* fx);//13e ChangeWeather
+int fx_change_weather (Scriptable* Owner, Actor* target, Effect* fx);//13e ChangeWeather
int fx_unknown (Scriptable* Owner, Actor* target, Effect* fx);//???
@@ -435,7 +441,7 @@ static EffectDesc effectnames[] = {
{ "AlwaysBackstab", fx_always_backstab_modifier, 0, -1 },
{ "AnimationIDModifier", fx_animation_id_modifier, 0, -1 },
{ "AnimationStateChange", fx_animation_stance, 0, -1 },
- { "ApplyEffect", fx_apply_effect, 0, -1 },
+ { "ApplyEffect", fx_apply_effect, EFFECT_NO_ACTOR, -1 },
{ "ApplyEffectCurse", fx_apply_effect_curse, 0, -1 },
{ "ApplyEffectItem", fx_apply_effect_item, 0, -1 },
{ "ApplyEffectItemType", fx_apply_effect_item_type, 0, -1 },
@@ -675,6 +681,7 @@ static EffectDesc effectnames[] = {
{ "ReplaceCreature", fx_replace_creature, 0, -1 },
{ "ReputationModifier", fx_reputation_modifier, 0, -1 },
{ "RestoreSpells", fx_restore_spell_level, 0, -1 },
+ { "RetreatFrom2", fx_turn_undead, 0, -1 },
{ "RightHitModifier", fx_right_to_hit_modifier, 0, -1 },
{ "SaveVsBreathModifier", fx_save_vs_breath_modifier, 0, -1 },
{ "SaveVsDeathModifier", fx_save_vs_death_modifier, 0, -1 },
@@ -701,6 +708,8 @@ static EffectDesc effectnames[] = {
{ "Spell:CastPoint", fx_cast_spell_point, 0, -1 },
{ "Spell:Learn", fx_learn_spell, 0, -1 },
{ "Spell:Remove", fx_remove_spell, 0, -1 },
+ { "SpellFocus",fx_generic_effect , 0, -1 }, //to implement school specific saving throw penalty to opponent
+ { "SpellResistance",fx_generic_effect , 0, -1 }, //to implement school specific saving throw bonus
{ "Spelltrap",fx_spelltrap , 0, -1 }, //overlay: spmagglo
{ "State:Berserk", fx_set_berserk_state, 0, -1 },
{ "State:Blind", fx_set_blind_state, 0, -1 },
@@ -716,7 +725,7 @@ static EffectDesc effectnames[] = {
{ "State:Hold", fx_hold_creature, 0, -1 }, //175 (doesn't work in original iwd2)
{ "State:Hold2", fx_hold_creature, 0, -1 },//185 (doesn't work in original iwd2)
{ "State:Hold3", fx_hold_creature, 0, -1 },//109 iwd2
- { "State:HoldNoIcon", fx_hold_creature_no_icon, 0, -1 }, //109
+ { "State:HoldNoIcon", fx_hold_creature_no_icon, 0, -1 }, //109 (bg2) 0x6d
{ "State:HoldNoIcon2", fx_hold_creature_no_icon, 0, -1 }, //0xfb (iwd/iwd2)
{ "State:HoldNoIcon3", fx_hold_creature_no_icon, 0, -1 }, //0x1a8 (iwd2)
{ "State:Imprisonment", fx_imprisonment, 0, -1 },
@@ -748,6 +757,7 @@ static EffectDesc effectnames[] = {
{ "ToHitVsCreature", fx_generic_effect, 0, -1 },
{ "TrackingModifier", fx_tracking_modifier, 0, -1 },
{ "TransparencyModifier", fx_transparency_modifier, 0, -1 },
+ { "TurnUndead", fx_turn_undead, 0, -1 },
{ "Unknown", fx_unknown, EFFECT_NO_ACTOR, -1 },
{ "Unlock", fx_knock, EFFECT_NO_ACTOR, -1 }, //open doors/containers
{ "UnsummonCreature", fx_unsummon_creature, 0, -1 },
@@ -762,6 +772,61 @@ static EffectDesc effectnames[] = {
{ NULL, NULL, 0, 0 },
};
+static EffectRef fx_set_berserk_state_ref = { "State:Berserk", -1 };//0x3
+static EffectRef fx_constitution_modifier_ref = { "ConstitutionModifier", -1 }; //0xa
+static EffectRef fx_damage_opcode_ref = { "Damage", -1 }; //0xc
+static EffectRef fx_death_ref = { "Death", -1 }; //0xd
+static EffectRef fx_set_haste_state_ref = { "State:Hasted", -1 }; //0x10
+static EffectRef fx_maximum_hp_modifier_ref = { "MaximumHPModifier", -1 }; //0x12
+static EffectRef fx_set_invisible_state_ref = { "State:Invisible", -1 }; //0x14
+static EffectRef fx_set_panic_state_ref = { "State:Panic", -1 }; //0x18
+static EffectRef fx_poisoned_state_ref = { "State:Poisoned", -1 }; //0x19
+static EffectRef fx_set_silenced_state_ref = { "State:Silenced", -1 }; //0x26
+static EffectRef fx_set_sleep_state_ref = { "State:Helpless", -1 }; //0x27
+static EffectRef fx_set_slow_state_ref = { "State:Slowed", -1 }; //0x28
+static EffectRef fx_sparkle_ref = { "Sparkle", -1 }; //0x29
+static EffectRef fx_set_stun_state_ref = { "State:Stun", -1 }; //0x2d
+static EffectRef fx_animation_id_modifier_ref = { "AnimationIDModifier", -1 }; //0x35
+static EffectRef fx_set_infravision_state_ref = { "State:Infravision", -1 }; //0x3f
+static EffectRef fx_set_nondetection_state_ref = { "State:Nondetection", -1 }; //0x45
+static EffectRef fx_set_blind_state_ref = { "State:Blind", -1 }; //0x4a
+static EffectRef fx_set_feebleminded_state_ref = { "State:Feeblemind", -1 }; //0x4c
+static EffectRef fx_diseased_state_ref = { "State:Diseased", -1 }; //0x4e
+static EffectRef fx_deaf_state_ref = { "State:Deafness", -1 }; //0x50
+static EffectRef fx_fatigue_ref = { "FatigueModifier", -1 }; //0x5d
+static EffectRef fx_intoxication_ref = { "IntoxicationModifier", -1 }; //0x5e
+static EffectRef fx_hold_creature_no_icon_ref = { "State:HoldNoIcon", -1 }; //0x6d
+static EffectRef fx_remove_item_ref = { "Item:Remove", -1 }; //0x70
+static EffectRef fx_remove_inventory_item_ref = { "Item:RemoveInventory", -1 }; //0x7b
+static EffectRef fx_confused_state_ref = { "State:Confused", -1 }; //0x80
+static EffectRef fx_polymorph_ref = { "Polymorph", -1 }; //0x87
+static EffectRef fx_animation_stance_ref = { "AnimationStateChange", -1 }; //0x8a
+static EffectRef fx_display_portrait_icon_ref = { "Icon:Display", -1 };//0x8e
+static EffectRef fx_disable_button_ref = { "DisableButton", -1 }; //0x90
+static EffectRef fx_sanctuary_state_ref = { "Overlay:Sanctuary", -1 }; //0x99
+static EffectRef fx_mirror_image_modifier_ref = { "MirrorImageModifier", -1 }; //0x9f
+static EffectRef fx_pause_caster_modifier_ref = { "PauseTarget", -1 }; //0xa5
+static EffectRef fx_hold_creature_ref = { "State:Hold", -1 }; //0xaf
+static EffectRef fx_movement_modifier_ref = { "MovementRateModifier2", -1 }; //0xb0
+static EffectRef fx_familiar_constitution_loss_ref = { "FamiliarBond", -1 }; //0xc3
+static EffectRef fx_familiar_marker_ref = { "FamiliarMarker", -1 }; //0xc4
+static EffectRef fx_immunity_effect_ref = { "Protection:Spell", -1 }; //0xce
+static EffectRef fx_imprisonment_ref = { "Imprisonment", -1 }; //0xd3
+static EffectRef fx_maze_ref = { "Maze", -1 }; //0xd5
+static EffectRef fx_leveldrain_ref = { "LevelDrainModifier", -1 }; //0xd8
+static EffectRef fx_contingency_ref = { "CastSpellOnCondition", -1 }; //0xe8
+static EffectRef fx_puppetmarker_ref = { "PuppetMarker", -1 }; //0xed
+static EffectRef fx_spell_sequencer_active_ref = { "Sequencer:Store", -1 }; //0x100
+static EffectRef fx_protection_from_display_string_ref = { "Protection:String", -1 }; //0x10b
+static EffectRef fx_apply_effect_repeat_ref = { "ApplyEffectRepeat", -1 }; //0x110
+static EffectRef fx_death_ward_ref = { "DeathWard", -1 }; //iwd2 specific
+static EffectRef fx_death_magic_ref = { "Death2", -1 }; //iwd2 specific
+static EffectRef fx_apply_effect_curse_ref = { "ApplyEffectCurse", -1 }; //0x11b
+static EffectRef fx_pst_jumble_curse_ref = { "JumbleCurse", -1 }; //PST specific
+static EffectRef fx_deaf_state_iwd2_ref = { "State:DeafnessIWD2", -1 }; //iwd2
+static EffectRef fx_bane_ref = { "Bane", -1 }; //iwd2
+static EffectRef fx_protection_from_animation_ref = { "Protection:Animation", -1 }; //0x128
+
static void Cleanup()
{
core->FreeResRefTable(casting_glows, cgcount);
@@ -775,19 +840,25 @@ static void Cleanup()
void RegisterCoreOpcodes()
{
core->RegisterOpcodes( sizeof( effectnames ) / sizeof( EffectDesc ) - 1, effectnames );
- enhanced_effects=!!core->HasFeature(GF_ENHANCED_EFFECTS);
- pstflags=!!core->HasFeature(GF_PST_STATE_FLAGS);
+ enhanced_effects=core->HasFeature(GF_ENHANCED_EFFECTS);
+ pstflags=core->HasFeature(GF_PST_STATE_FLAGS);
default_spell_hit.SequenceFlags|=IE_VVC_BAM;
}
-static inline void SetGradient(Actor *target, ieDword gradient)
+#define STONE_GRADIENT 14
+#define ICE_GRADIENT 71
+
+static inline void SetGradient(Actor *target,const ieDword *gradients)
{
- gradient |= (gradient <<16);
- gradient |= (gradient <<8);
for(int i=0;i<7;i++) {
+ int gradient = gradients[i];
+ gradient |= (gradient <<16);
+ gradient |= (gradient <<8);
+
STAT_SET(IE_COLORS+i, gradient);
}
+ target->SetLockedPalette(gradients);
}
static inline void HandleBonus(Actor *target, int stat, int mod, int mode)
@@ -807,52 +878,9 @@ static inline void HandleBonus(Actor *target, int stat, int mod, int mode)
}
}
-//whoseeswho:
-#define ENEMY_SEES_ORIGIN 1
-#define ORIGIN_SEES_ENEMY 2
-
-inline Actor *GetNearestEnemyOf(Map *map, Actor *origin, int whoseeswho)
+static inline void PlayRemoveEffect(const char *defsound, Actor *target, Effect* fx)
{
- //determining the allegiance of the origin
- int type = GetGroup(origin);
-
- //neutral has no enemies
- if (type==2) {
- return NULL;
- }
-
- Targets *tgts = new Targets();
-
- int i = map->GetActorCount(true);
- Actor *ac;
- while (i--) {
- ac=map->GetActor(i,true);
- int distance = Distance(ac, origin);
- if (whoseeswho&ENEMY_SEES_ORIGIN) {
- if (!CanSee(ac, origin, true, GA_NO_DEAD)) {
- continue;
- }
- }
- if (whoseeswho&ORIGIN_SEES_ENEMY) {
- if (!CanSee(ac, origin, true, GA_NO_DEAD)) {
- continue;
- }
- }
-
- if (type) { //origin is PC
- if (ac->GetStat(IE_EA) >= EA_EVILCUTOFF) {
- tgts->AddTarget(ac, distance, GA_NO_DEAD);
- }
- }
- else {
- if (ac->GetStat(IE_EA) <= EA_GOODCUTOFF) {
- tgts->AddTarget(ac, distance, GA_NO_DEAD);
- }
- }
- }
- ac = (Actor *) tgts->GetTarget(0, ST_ACTOR);
- delete tgts;
- return ac;
+ core->GetAudioDrv()->Play(fx->Resource[0]?fx->Resource:defsound, target->Pos.x, target->Pos.y);
}
//resurrect code used in many places
@@ -882,28 +910,49 @@ inline void HandlePercentageDamage(Effect *fx, Actor *target) {
// Effect opcodes
// 0x00 ACVsDamageTypeModifier
+// Known values for Parameter2 are:
+// 0 All
+// 1 Crushing
+// 2 Missile
+// 4 Piercing
+// 8 Slashing
+// 16 Base AC setting (sets the targets AC to the value specifiedg)
+// since the implemented ad&d doesn't have separate stats for all, we use them as the generic bonus
int fx_ac_vs_damage_type_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_ac_vs_damage_type_modifier (%2d): AC Modif: %d ; Type: %d ; MinLevel: %d ; MaxLevel: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2, (int) fx->DiceSides, (int) fx->DiceThrown );
- //check level was pulled outside as a common functionality
- //CHECK_LEVEL();
+ if(0) print("fx_ac_vs_damage_type_modifier(%2d): AC Modif: %d ; Type: %d ; MinLevel: %d ; MaxLevel: %d", fx->Opcode, fx->Parameter1, fx->Parameter2,(int) fx->DiceSides,(int) fx->DiceThrown);
+
+ if (fx->IsVariable) {
+ //has a second weapon or shield, cannot deflect arrows
+ int slot = target->inventory.GetShieldSlot();
+ if (slot>0 && target->inventory.GetItem(slot) ) return FX_APPLIED;
+
+ //has a twohanded weapon equipped
+ slot = target->inventory.GetWeaponSlot();
+ if (slot>0) {
+ CREItem *item = target->inventory.GetItem(slot);
+ if (item->Flags&IE_INV_ITEM_TWOHANDED) return FX_APPLIED;
+ }
+ }
// it is a bitmask
int type = fx->Parameter2;
- if (type == 0) {
- HandleBonus(target, IE_ARMORCLASS, fx->Parameter1, fx->TimingMode);
+ if (type == 0) { // generic bonus
+ target->AC.HandleFxBonus(fx->Parameter1, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
return FX_PERMANENT;
}
//convert to signed so -1 doesn't turn to an astronomical number
- if (type == 16) {
+ if (type == 16) { // natural AC
if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
- if ((signed)BASE_GET( IE_ARMORCLASS) > (signed)fx->Parameter1) {
- BASE_SET( IE_ARMORCLASS, fx->Parameter1 );
+ if ((signed)target->AC.GetNatural() > (signed)fx->Parameter1) {
+ target->AC.SetNatural(fx->Parameter1);
}
} else {
- if ((signed)STAT_GET( IE_ARMORCLASS) > (signed)fx->Parameter1) {
- STAT_SET( IE_ARMORCLASS, fx->Parameter1 );
+ if ((signed)target->AC.GetTotal() > (signed)fx->Parameter1) {
+ // previously we were overriding the whole stat, but now we can be finegrained
+ // and reuse the deflection bonus, since iwd2 has its own version of this effect
+ target->AC.SetDeflectionBonus(- (target->AC.GetNatural()-fx->Parameter1));
}
}
return FX_INSERT;
@@ -930,7 +979,7 @@ int fx_ac_vs_damage_type_modifier (Scriptable* /*Owner*/, Actor* target, Effect*
// 0x01 AttacksPerRoundModifier
int fx_attacks_per_round_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_attacks_per_round_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_attacks_per_round_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
int tmp = (signed) fx->Parameter1;
if (fx->Parameter2!=2) {
if (tmp>10) tmp=10;
@@ -950,14 +999,10 @@ int fx_attacks_per_round_modifier (Scriptable* /*Owner*/, Actor* target, Effect*
// 0x02 Cure:Sleep (Awaken)
// this effect clears the STATE_SLEEP (1) bit, but clearing it alone wouldn't remove the
-// unconscious effect, which is combined with STATE_HELPLESS (0x20+1)
-static EffectRef fx_set_sleep_state_ref = { "State:Helpless", -1 };
-//this reference is used by many other effects
-static EffectRef fx_display_portrait_icon_ref = { "Icon:Display", -1 };
int fx_cure_sleep_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cure_sleep_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_cure_sleep_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
BASE_STATE_CURE( STATE_SLEEP );
target->fxqueue.RemoveAllEffects(fx_set_sleep_state_ref);
target->fxqueue.RemoveAllEffectsWithParam(fx_display_portrait_icon_ref, PI_SLEEP);
@@ -968,7 +1013,7 @@ int fx_cure_sleep_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// this effect sets the STATE_BERSERK bit, but bg2 actually ignores the bit
int fx_set_berserk_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_berserk_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_berserk_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
// atleast how and bg2 allow this to only work on pcs
if (!core->HasFeature(GF_3ED_RULES) && !target->InParty) {
return FX_NOT_APPLIED;
@@ -1014,11 +1059,10 @@ int fx_set_berserk_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x04 Cure:Berserk
// this effect clears the STATE_BERSERK (2) bit, but bg2 actually ignores the bit
// it also removes effect 04
-static EffectRef fx_set_berserk_state_ref = { "State:Berserk", -1 };
int fx_cure_berserk_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cure_berserk_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_cure_berserk_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
BASE_STATE_CURE( STATE_BERSERK );
target->fxqueue.RemoveAllEffects(fx_set_berserk_state_ref);
return FX_NOT_APPLIED;
@@ -1028,7 +1072,7 @@ int fx_cure_berserk_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0xf1 ControlCreature (iwd2)
int fx_set_charmed_state (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_charmed_state (%2d): General: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_charmed_state(%2d): General: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//blood rage berserking gives immunity to charm (in iwd2)
if (target->HasSpellState(SS_BLOODRAGE)) {
@@ -1047,6 +1091,9 @@ int fx_set_charmed_state (Scriptable* Owner, Actor* target, Effect* fx)
bool playercharmed;
bool casterenemy;
if (fx->FirstApply) {
+ //when charmed, the target forgets its current action
+ target->ClearActions();
+
Scriptable *caster = GetCasterObject();
if (!caster) caster = Owner;
if (caster->Type==ST_ACTOR) {
@@ -1057,7 +1104,7 @@ int fx_set_charmed_state (Scriptable* Owner, Actor* target, Effect* fx)
fx->DiceThrown=casterenemy;
playercharmed = target->InParty;
- fx->DiceSides = playercharmed;
+ fx->DiceSides = playercharmed;
} else {
casterenemy = fx->DiceThrown;
playercharmed = fx->DiceSides;
@@ -1067,13 +1114,13 @@ int fx_set_charmed_state (Scriptable* Owner, Actor* target, Effect* fx)
switch (fx->Parameter2) {
case 0: //charmed (target neutral after charm)
if (fx->FirstApply) {
- displaymsg->DisplayConstantStringName(STR_CHARMED, 0xf0f0f0, target);
+ displaymsg->DisplayConstantStringName(STR_CHARMED, DMC_WHITE, target);
}
case 1000:
break;
case 1: //charmed (target hostile after charm)
if (fx->FirstApply) {
- displaymsg->DisplayConstantStringName(STR_CHARMED, 0xf0f0f0, target);
+ displaymsg->DisplayConstantStringName(STR_CHARMED, DMC_WHITE, target);
}
case 1001:
if (!target->InParty) {
@@ -1082,13 +1129,13 @@ int fx_set_charmed_state (Scriptable* Owner, Actor* target, Effect* fx)
break;
case 2: //dire charmed (target neutral after charm)
if (fx->FirstApply) {
- displaymsg->DisplayConstantStringName(STR_DIRECHARMED, 0xf0f0f0, target);
+ displaymsg->DisplayConstantStringName(STR_DIRECHARMED, DMC_WHITE, target);
}
case 1002:
break;
case 3: //dire charmed (target hostile after charm)
if (fx->FirstApply) {
- displaymsg->DisplayConstantStringName(STR_DIRECHARMED, 0xf0f0f0, target);
+ displaymsg->DisplayConstantStringName(STR_DIRECHARMED, DMC_WHITE, target);
}
case 1003:
if (!target->InParty) {
@@ -1097,16 +1144,17 @@ int fx_set_charmed_state (Scriptable* Owner, Actor* target, Effect* fx)
break;
case 4: //controlled by cleric
if (fx->FirstApply) {
- displaymsg->DisplayConstantStringName(STR_CONTROLLED, 0xf0f0f0, target);
+ displaymsg->DisplayConstantStringName(STR_CONTROLLED, DMC_WHITE, target);
}
case 1004:
if (!target->InParty) {
target->SetBaseNoPCF(IE_EA, EA_ENEMY);
}
+ target->SetSpellState(SS_DOMINATION);
break;
case 5: //thrall (typo comes from original engine doc)
if (fx->FirstApply) {
- displaymsg->DisplayConstantStringName(STR_CHARMED, 0xf0f0f0, target);
+ displaymsg->DisplayConstantStringName(STR_CHARMED, DMC_WHITE, target);
}
case 1005:
STAT_SET(IE_EA, EA_ENEMY );
@@ -1127,7 +1175,7 @@ int fx_set_charmed_state (Scriptable* Owner, Actor* target, Effect* fx)
// 0x06 CharismaModifier
int fx_charisma_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_charisma_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_charisma_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
BASE_MOD( IE_CHR );
@@ -1141,7 +1189,7 @@ int fx_charisma_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// this effect might not work in pst, they don't have separate weapon slots
int fx_set_color_gradient (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_color_gradient (%2d): Gradient: %d, Location: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_color_gradient(%2d): Gradient: %d, Location: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
EffectQueue::HackColorEffects(target, fx);
target->SetColor( fx->Parameter2, fx->Parameter1 );
return FX_APPLIED;
@@ -1150,7 +1198,7 @@ int fx_set_color_gradient (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 08 Color:SetRGB
int fx_set_color_rgb (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_color_rgb (%2d): RGB: %x, Location: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_color_rgb(%2d): RGB: %x, Location: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
EffectQueue::HackColorEffects(target, fx);
ieDword location = fx->Parameter2 & 0xff;
target->SetColorMod(location, RGBModifier::ADD, -1, fx->Parameter1 >> 8,
@@ -1161,7 +1209,7 @@ int fx_set_color_rgb (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 08 Color:SetRGBGlobal
int fx_set_color_rgb_global (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_color_rgb_global (%2d): RGB: %x, Location: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_color_rgb_global(%2d): RGB: %x, Location: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
target->SetColorMod(0xff, RGBModifier::ADD, -1, fx->Parameter1 >> 8,
fx->Parameter1 >> 16, fx->Parameter1 >> 24);
@@ -1172,7 +1220,7 @@ int fx_set_color_rgb_global (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 09 Color:PulseRGB
int fx_set_color_pulse_rgb (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_color_pulse_rgb (%2d): RGB: %x, Location: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_color_pulse_rgb(%2d): RGB: %x, Location: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
EffectQueue::HackColorEffects(target, fx);
ieDword location = fx->Parameter2 & 0xff;
int speed = (fx->Parameter2 >> 16) & 0xFF;
@@ -1186,7 +1234,7 @@ int fx_set_color_pulse_rgb (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 09 Color:PulseRGBGlobal (pst variant)
int fx_set_color_pulse_rgb_global (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_color_pulse_rgb_global (%2d): RGB: %x, Location: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_color_pulse_rgb_global(%2d): RGB: %x, Location: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
int speed = (fx->Parameter2 >> 16) & 0xFF;
target->SetColorMod(0xff, RGBModifier::ADD, speed,
@@ -1199,7 +1247,7 @@ int fx_set_color_pulse_rgb_global (Scriptable* /*Owner*/, Actor* target, Effect*
// 0x0A ConstitutionModifier
int fx_constitution_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_constitution_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_constitution_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
BASE_MOD( IE_CON );
@@ -1210,11 +1258,10 @@ int fx_constitution_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
}
// 0x0B Cure:Poison
-static EffectRef fx_poisoned_state_ref = { "State:Poisoned", -1 };
int fx_cure_poisoned_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cure_poisoned_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_cure_poisoned_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//all three steps are present in bg2 and iwd2
BASE_STATE_CURE( STATE_POISONED );
target->fxqueue.RemoveAllEffects( fx_poisoned_state_ref );
@@ -1226,7 +1273,7 @@ int fx_cure_poisoned_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// this is a very important effect
int fx_damage (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_damage (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_damage(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//save for half damage type
ieDword damagetype = fx->Parameter2>>16;
ieDword modtype = fx->Parameter2&3;
@@ -1235,15 +1282,37 @@ int fx_damage (Scriptable* /*Owner*/, Actor* target, Effect* fx)
}
Scriptable *caster = GetCasterObject();
- target->Damage(fx->Parameter1, damagetype, caster, modtype);
+ // gemrb extension
+ if (fx->Parameter3) {
+ if(caster && caster->Type==ST_ACTOR) {
+ target->AddTrigger(TriggerEntry(trigger_hitby, caster->GetGlobalID()));
+ target->LastHitter=caster->GetGlobalID();
+ } else {
+ //Maybe it should be something impossible like 0xffff, and use 'Someone'
+ Log(ERROR, "Actor", "LastHitter (type %d) falling back to target: %s.", caster ? caster->Type : -1, target->GetName(1));
+ target->LastHitter=target->GetGlobalID();
+ }
+ }
+
+ target->Damage(fx->Parameter1, damagetype, caster, modtype, fx->IsVariable, fx->SavingThrowType);
//this effect doesn't stick
return FX_NOT_APPLIED;
}
// 0x0d Death
-int fx_death (Scriptable* Owner, Actor* target, Effect* fx)
+
+int fx_death (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_death (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_death(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+
+ //if the opcode of this effect is associated with Death2 (iwd2's death magic opcode) and
+ //there is an active death ward effect, ignore this opcode
+ if (target->fxqueue.HasEffect(fx_death_ward_ref) ) {
+ //find the opcode for death magic (should be 420 in original IWD2)
+ EffectQueue::ResolveEffect(fx_death_magic_ref);
+ if (fx->Opcode==(ieDword) fx_death_magic_ref.opcode) return FX_NOT_APPLIED;
+ }
+
ieDword damagetype = 0;
switch (fx->Parameter2) {
case 1:
@@ -1278,17 +1347,28 @@ int fx_death (Scriptable* Owner, Actor* target, Effect* fx)
case 256:
damagetype = DAMAGE_ELECTRICITY;
break;
- case 512:
-
+ case 512: //disintegration
+ damagetype = DAMAGE_MAGIC;
+ break;
default:
damagetype = DAMAGE_ACID;
}
- //these two bits are turned off on death
- BASE_STATE_CURE(STATE_FROZEN|STATE_PETRIFIED);
+ if (fx->Parameter3) {
+ // disintegration marked this, so it can be discerned from other magic damage
+ // hack: reuse a state bit to convey this info to Actor::CheckOnDeath
+ target->SetBaseNoPCF(IE_SPELLDURATIONMODPRIEST, 1);
+ }
+
+ if (damagetype!=DAMAGE_COLD) {
+ //these two bits are turned off on death
+ BASE_STATE_CURE(STATE_FROZEN|STATE_PETRIFIED);
+ }
+ BASE_SET(IE_MORALE, 10);
- target->Damage(0, damagetype, Owner);
+ Scriptable *killer = GetCasterObject();
+ target->Damage(0, damagetype, killer);
//death has damage type too
- target->Die(Owner);
+ target->Die(killer);
//this effect doesn't stick
return FX_NOT_APPLIED;
}
@@ -1296,7 +1376,10 @@ int fx_death (Scriptable* Owner, Actor* target, Effect* fx)
// 0xE Cure:Defrost
int fx_cure_frozen_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cure_frozen_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_cure_frozen_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+ if (STATE_GET(STATE_FROZEN) && (STAT_GET(IE_HITPOINTS)<1) ) {
+ BASE_SET(IE_HITPOINTS,1);
+ }
BASE_STATE_CURE( STATE_FROZEN );
return FX_NOT_APPLIED;
}
@@ -1335,7 +1418,7 @@ int SpellAbilityDieRoll(Actor *target, int which)
int fx_dexterity_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_dexterity_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_dexterity_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
////how cat's grace: value is based on class
if (fx->Parameter2==3) {
@@ -1351,12 +1434,11 @@ int fx_dexterity_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
return FX_PERMANENT;
}
-static EffectRef fx_set_slow_state_ref = { "State:Slowed", -1 };
// 0x10 State:Hasted
// this function removes slowed state, or sets hasted state
int fx_set_hasted_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_hasted_state (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_set_hasted_state(%2d): Type: %d", fx->Opcode, fx->Parameter2);
target->fxqueue.RemoveAllEffects(fx_set_slow_state_ref);
target->fxqueue.RemoveAllEffectsWithParam( fx_display_portrait_icon_ref, PI_SLOWED );
if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
@@ -1395,9 +1477,25 @@ int fx_set_hasted_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
}
// 0x11 CurrentHPModifier
+int GetSpecialHealAmount(int type, Scriptable *caster)
+{
+ if (!caster || caster->Type!=ST_ACTOR) return 0;
+ Actor *actor = (Actor *) caster;
+ switch(type) {
+ case 3: //paladin's lay on hands, the amount is already calculated in a compatible way
+ return actor->GetSafeStat(IE_LAYONHANDSAMOUNT);
+ case 4: //monk wholeness of body
+ return actor->GetSafeStat(IE_LEVELMONK)*2; //ignore level 7 restriction, since the spell won't be granted under level 7
+ case 5: //lathander's renewal
+ return actor->GetSafeStat(IE_LEVELCLERIC)*2; //ignore kit restriction, since the spell won't be granted to non lathander
+ default:
+ return 0;
+ }
+}
+
int fx_current_hp_modifier (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_current_hp_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_current_hp_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (fx->Parameter2&0x10000) {
Point p(fx->PosX, fx->PosY);
@@ -1412,13 +1510,18 @@ int fx_current_hp_modifier (Scriptable* Owner, Actor* target, Effect* fx)
}
//current hp percent is relative to modified max hp
- switch(fx->Parameter2&0xffff) {
+ int type = fx->Parameter2&0xffff;
+ switch(type) {
case MOD_ADDITIVE:
case MOD_ABSOLUTE:
- target->NewBase( IE_HITPOINTS, fx->Parameter1, fx->Parameter2&0xffff);
+ target->NewBase( IE_HITPOINTS, fx->Parameter1, type);
break;
case MOD_PERCENT:
target->NewBase( IE_HITPOINTS, target->GetSafeStat(IE_MAXHITPOINTS)*fx->Parameter1/100, MOD_ABSOLUTE);
+ break;
+ default: // lay on hands amount, wholeness of body, lathander's renewal
+ target->NewBase( IE_HITPOINTS, GetSpecialHealAmount(type, GetCasterObject()), MOD_ADDITIVE);
+ break;
}
//never stay permanent
return FX_NOT_APPLIED;
@@ -1429,7 +1532,7 @@ int fx_current_hp_modifier (Scriptable* Owner, Actor* target, Effect* fx)
// 1,4 and 2,5 are analogous to them, but with different modifiers
int fx_maximum_hp_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_maximum_hp_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_maximum_hp_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//state_exploding is different in PST, probably not needed anyway
if (STATE_GET(STATE_DEAD|STATE_PETRIFIED|STATE_FROZEN|STATE_ACID|STATE_FLAME) ) {
@@ -1496,7 +1599,7 @@ int fx_maximum_hp_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x13 IntelligenceModifier
int fx_intelligence_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_intelligence_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_intelligence_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
BASE_MOD( IE_INT );
@@ -1518,11 +1621,15 @@ int fx_set_invisible_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
} else {
STATE_SET( STATE_INVISIBLE );
}
- STAT_ADD(IE_TOHIT, 4);
+ if (fx->FirstApply || fx->TimingMode != FX_DURATION_INSTANT_PERMANENT) {
+ target->ToHit.HandleFxBonus(4, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
+ }
break;
case 1:
STATE_SET( STATE_INVIS2 );
- HandleBonus(target, IE_ARMORCLASS, 4, fx->TimingMode);
+ if (fx->FirstApply || fx->TimingMode != FX_DURATION_INSTANT_PERMANENT) {
+ target->AC.HandleFxBonus(4, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
+ }
break;
default:
break;
@@ -1530,45 +1637,56 @@ int fx_set_invisible_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
ieDword Trans = fx->Parameter4;
if (fx->Parameter3) {
if (Trans>=240) {
- fx->Parameter3=0;
+ fx->Parameter3 = 0;
} else {
Trans+=16;
}
} else {
if (Trans<=32) {
- fx->Parameter3=1;
+ fx->Parameter3 = 1;
} else {
Trans-=16;
}
}
- fx->Parameter4=Trans;
+ fx->Parameter4 = Trans;
STAT_SET( IE_TRANSLUCENT, Trans);
+ //FIXME: probably FX_PERMANENT, but TRANSLUCENT has no saved base stat
+ // we work around it by only applying the tohit/ac bonus once
return FX_APPLIED;
}
// 0x15 LoreModifier
int fx_lore_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_lore_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_lore_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
- STAT_MOD( IE_LORE );
- return FX_APPLIED;
+ if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
+ BASE_MOD( IE_LORE );
+ } else {
+ STAT_MOD( IE_LORE );
+ }
+ return FX_PERMANENT;
}
// 0x16 LuckModifier
int fx_luck_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_luck_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_luck_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
- STAT_MOD( IE_LUCK );
- STAT_MOD( IE_DAMAGELUCK );
- return FX_APPLIED;
+ if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
+ BASE_MOD( IE_LUCK );
+ } else {
+ STAT_MOD( IE_LUCK );
+ //I checked, it doesn't modify damage luck stat in bg2 (Avenger)
+ //STAT_MOD( IE_DAMAGELUCK );
+ }
+ return FX_PERMANENT;
}
// 0x17 MoraleModifier
int fx_morale_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_morale_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_morale_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//FIXME: in bg2 this is hacked to set param1=10, param2=1, we might need some flag for this
STAT_MOD( IE_MORALE );
@@ -1578,7 +1696,7 @@ int fx_morale_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x18 State:Panic
int fx_set_panic_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_panic_state (%2d)\n", fx->Opcode );
+ if(0) print("fx_set_panic_state(%2d)", fx->Opcode);
if (target->HasSpellState(SS_BLOODRAGE)) {
return FX_NOT_APPLIED;
@@ -1598,24 +1716,35 @@ int fx_set_panic_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x19 State:Poisoned
int fx_set_poisoned_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_poisoned_state (%2d): Damage: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_poisoned_state(%2d): Damage: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+ if (STATE_GET(STATE_DEAD) ) {
+ return FX_NOT_APPLIED;
+ }
+
+ int count = target->fxqueue.CountEffects(fx_poisoned_state_ref, fx->Parameter1, fx->Parameter2, fx->Resource);
+ if (count > 1) {
+ return FX_APPLIED;
+ }
+
STATE_SET( STATE_POISONED );
- ieDword damage;
+ ieDword damage = 0;
int tmp = fx->Parameter1;
HandlePercentageDamage(fx, target);
+ Scriptable *caster = GetCasterObject();
switch(fx->Parameter2) {
case RPD_ROUNDS:
- tmp *= core->Time.round_sec;
- damage = 1;
+ tmp = core->Time.round_sec;
+ damage = fx->Parameter1;
break;
case RPD_TURNS:
- tmp *= core->Time.turn_sec;
- damage = 1;
+ tmp = core->Time.turn_sec;
+ damage = fx->Parameter1;
break;
case RPD_SECONDS:
+ tmp *= core->Time.round_sec;
damage = 1;
break;
case RPD_PERCENT: // handled in HandlePercentageDamage
@@ -1623,6 +1752,31 @@ int fx_set_poisoned_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
tmp = 1; // hit points per second
damage = fx->Parameter1;
break;
+ case RPD_SNAKE: //iwd2 snakebite (a poison causing paralysis)
+ STAT_SET(IE_HELD, 1);
+ target->AddPortraitIcon(PI_HELD);
+ target->SetSpellState(SS_HELD);
+ STATE_SET(STATE_HELPLESS);
+ if (fx->FirstApply) {
+ displaymsg->DisplayConstantStringName(STR_HELD, DMC_WHITE, target);
+ }
+ break;
+ case RPD_7:
+ damage = fx->Parameter1;
+ tmp = fx->Parameter3;
+ break;
+ case RPD_ENVENOM:
+ //call the constitution effect like it was this one (don't add it to the effect queue)
+ //can't simply convert this effect to the constitution effect, because a poison effect
+ //could be removed and there is a portrait icon
+ Effect *newfx;
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_constitution_modifier_ref, fx->Parameter1, 0);
+ target->fxqueue.ApplyEffect(target, newfx, fx->FirstApply, 0);
+ delete newfx;
+ damage = 0;
+ tmp = 1;
+ break;
+ break;
default:
tmp = 1;
damage = 1;
@@ -1635,21 +1789,18 @@ int fx_set_poisoned_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
return FX_APPLIED;
}
- Scriptable *caster = GetCasterObject();
-
- //percent
- target->Damage(damage, DAMAGE_POISON, caster);
+ if (damage) {
+ target->Damage(damage, DAMAGE_POISON, caster);
+ }
return FX_APPLIED;
}
// 0x1a RemoveCurse
-static EffectRef fx_apply_effect_curse_ref = { "ApplyEffectCurse", -1 };
-static EffectRef fx_pst_jumble_curse_ref = { "JumbleCurse", -1 };
// gemrb extension: if the resource field is filled, it will remove curse only from the specified item
int fx_remove_curse (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_remove_curse (%2d): Resource: %s Type: %d\n", fx->Opcode, fx->Resource, fx->Parameter2 );
+ if(0) print("fx_remove_curse(%2d): Resource: %s Type: %d", fx->Opcode, fx->Resource, fx->Parameter2);
switch(fx->Parameter2)
{
@@ -1691,44 +1842,61 @@ int fx_remove_curse (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x1b AcidResistanceModifier
int fx_acid_resistance_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_acid_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_acid_resistance_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
- STAT_MOD( IE_RESISTACID );
- return FX_APPLIED;
+ if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
+ BASE_MOD( IE_RESISTACID );
+ } else {
+ STAT_MOD( IE_RESISTACID );
+ }
+ return FX_PERMANENT;
}
// 0x1c ColdResistanceModifier
int fx_cold_resistance_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cold_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_cold_resistance_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
- STAT_MOD( IE_RESISTCOLD );
- return FX_APPLIED;
+ if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
+ BASE_MOD( IE_RESISTCOLD );
+ } else {
+ STAT_MOD( IE_RESISTCOLD );
+ }
+ return FX_PERMANENT;
}
// 0x1d ElectricityResistanceModifier
int fx_electricity_resistance_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_electricity_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_electricity_resistance_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
- STAT_MOD( IE_RESISTELECTRICITY );
- return FX_APPLIED;
+ if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
+ BASE_MOD( IE_RESISTELECTRICITY );
+ } else {
+ STAT_MOD( IE_RESISTELECTRICITY );
+ }
+ return FX_PERMANENT;
}
// 0x1e FireResistanceModifier
int fx_fire_resistance_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_fire_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_fire_resistance_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
- STAT_MOD( IE_RESISTFIRE );
- return FX_APPLIED;
+ if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
+ BASE_MOD( IE_RESISTFIRE );
+ } else {
+ STAT_MOD( IE_RESISTFIRE );
+ }
+ return FX_PERMANENT;
}
// 0x1f MagicDamageResistanceModifier
int fx_magic_damage_resistance_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_magic_damage_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_magic_damage_resistance_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+ //This stat has no saved basestat variant, so this effect is always stored (not FX_PERMANENT)
STAT_MOD( IE_MAGICDAMAGERESISTANCE );
return FX_APPLIED;
}
@@ -1736,7 +1904,7 @@ int fx_magic_damage_resistance_modifier (Scriptable* /*Owner*/, Actor* target, E
// 0x20 Cure:Death
int fx_cure_dead_state (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cure_dead_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_cure_dead_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//call this only if the target is dead, otherwise some variables can get wrong
if (STATE_GET(STATE_DEAD) ) {
Point p(fx->PosX, fx->PosY);
@@ -1748,64 +1916,66 @@ int fx_cure_dead_state (Scriptable* Owner, Actor* target, Effect* fx)
// 0x21 SaveVsDeathModifier
int fx_save_vs_death_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_save_vs_death_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_save_vs_death_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
HandleBonus( target, IE_SAVEVSDEATH, fx->Parameter1, fx->TimingMode );
- return FX_APPLIED;
+ return FX_PERMANENT;
}
// 0x22 SaveVsWandsModifier
int fx_save_vs_wands_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_save_vs_wands_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_save_vs_wands_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
HandleBonus( target, IE_SAVEVSWANDS, fx->Parameter1, fx->TimingMode );
- return FX_APPLIED;
+ return FX_PERMANENT;
}
// 0x23 SaveVsPolyModifier
int fx_save_vs_poly_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_save_vs_poly_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_save_vs_poly_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
HandleBonus( target, IE_SAVEVSPOLY, fx->Parameter1, fx->TimingMode );
- return FX_APPLIED;
+ return FX_PERMANENT;
}
// 0x24 SaveVsBreathModifier
int fx_save_vs_breath_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_save_vs_breath_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_save_vs_breath_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
HandleBonus( target, IE_SAVEVSBREATH, fx->Parameter1, fx->TimingMode );
- return FX_APPLIED;
+ return FX_PERMANENT;
}
// 0x25 SaveVsSpellsModifier
int fx_save_vs_spell_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_save_vs_spell_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_save_vs_spell_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
HandleBonus( target, IE_SAVEVSSPELL, fx->Parameter1, fx->TimingMode );
- return FX_APPLIED;
+ return FX_PERMANENT;
}
// 0x26 State:Silenced
int fx_set_silenced_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_silenced_state (%2d)\n", fx->Opcode );
- STATE_SET( STATE_SILENCED );
- return FX_APPLIED;
+ if(0) print("fx_set_silenced_state(%2d)", fx->Opcode);
+ if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
+ BASE_STATE_SET( STATE_SILENCED );
+ } else {
+ STATE_SET( STATE_SILENCED );
+ }
+ return FX_PERMANENT;
}
-static EffectRef fx_animation_stance_ref = { "AnimationStateChange", -1 };
-
-// 0x27 State:Helpless
+// 0x27 State:Helpless, State:Sleep
// this effect sets both bits, but 'awaken' only removes the sleep bit
// FIXME: this is probably a persistent effect
int fx_set_unconscious_state (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_unconscious_state (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_set_unconscious_state(%2d): Type: %d", fx->Opcode, fx->Parameter2);
if (target->HasSpellState(SS_BLOODRAGE)) {
return FX_NOT_APPLIED;
@@ -1829,16 +1999,16 @@ int fx_set_unconscious_state (Scriptable* Owner, Actor* target, Effect* fx)
}
target->AddPortraitIcon(PI_SLEEP);
}
+ target->InterruptCasting = true;
return FX_PERMANENT;
}
// 0x28 State:Slowed
// this function removes hasted state, or sets slowed state
-static EffectRef fx_set_haste_state_ref = { "State:Hasted", -1 };
int fx_set_slowed_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_slowed_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_slowed_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//iwd2 free action or aegis disables this effect
if (target->HasSpellState(SS_FREEACTION)) return FX_NOT_APPLIED;
@@ -1848,6 +2018,9 @@ int fx_set_slowed_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
BASE_STATE_CURE( STATE_HASTED );
target->fxqueue.RemoveAllEffects( fx_set_haste_state_ref );
target->fxqueue.RemoveAllEffectsWithParam( fx_display_portrait_icon_ref, PI_HASTED );
+ } else if (STATE_GET(STATE_SLOWED)) {
+ // already slowed
+ return FX_NOT_APPLIED;
} else {
STATE_SET( STATE_SLOWED );
target->AddPortraitIcon(PI_SLOWED);
@@ -1861,7 +2034,7 @@ int fx_set_slowed_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x29 Sparkle
int fx_sparkle (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_sparkle (%2d): Sparkle colour: %d ; Sparkle type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_sparkle(%2d): Sparkle colour: %d ; Sparkle type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (!target) {
return FX_NOT_APPLIED;
}
@@ -1879,7 +2052,7 @@ int fx_sparkle (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x2A WizardSpellSlotsModifier
int fx_bonus_wizard_spells (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_bonus_wizard_spells (%2d): Spell Add: %d ; Spell Level: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_bonus_wizard_spells(%2d): Spell Add: %d ; Spell Level: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
int i=1;
//if param2 is 0, then double spells up to param1
@@ -1910,7 +2083,7 @@ int fx_bonus_wizard_spells (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x2B Cure:Petrification
int fx_cure_petrified_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cure_petrified_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_cure_petrified_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
BASE_STATE_CURE( STATE_PETRIFIED );
return FX_NOT_APPLIED;
}
@@ -1918,7 +2091,7 @@ int fx_cure_petrified_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x2C StrengthModifier
int fx_strength_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_strength_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_strength_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
////how strength: value is based on class
////pst power of one also depends on this!
@@ -1955,7 +2128,7 @@ int power_word_stun_iwd2(Actor *target, Effect *fx)
int fx_set_stun_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_stun_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_stun_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//actually the original engine just skips this effect if the target is dead
if ( STATE_GET(STATE_DEAD) ) {
@@ -1982,12 +2155,9 @@ int fx_set_stun_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
}
// 0x2E Cure:Stun
-static EffectRef fx_set_stun_state_ref = { "State:Stun", -1 };
-static EffectRef fx_hold_creature_no_icon_ref = { "State:HoldNoIcon", -1 };
-
int fx_cure_stun_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cure_stun_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_cure_stun_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
BASE_STATE_CURE( STATE_STUNNED );
target->fxqueue.RemoveAllEffects(fx_set_stun_state_ref);
target->fxqueue.RemoveAllEffects(fx_hold_creature_no_icon_ref);
@@ -1998,11 +2168,10 @@ int fx_cure_stun_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x2F Cure:Invisible
// 0x74 Cure:Invisible2
-static EffectRef fx_set_invisible_state_ref = { "State:Invisible", -1 };
int fx_cure_invisible_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cure_invisible_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_cure_invisible_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (!STATE_GET(STATE_NONDET)) {
if (pstflags) {
BASE_STATE_CURE( STATE_PST_INVIS );
@@ -2015,11 +2184,10 @@ int fx_cure_invisible_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
}
// 0x30 Cure:Silence
-static EffectRef fx_set_silenced_state_ref = { "State:Silenced", -1 };
int fx_cure_silenced_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cure_silenced_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_cure_silenced_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
BASE_STATE_CURE( STATE_SILENCED );
target->fxqueue.RemoveAllEffects(fx_set_silenced_state_ref);
return FX_NOT_APPLIED;
@@ -2028,7 +2196,7 @@ int fx_cure_silenced_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x31 WisdomModifier
int fx_wisdom_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_wisdom_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_wisdom_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
BASE_MOD( IE_WIS );
@@ -2041,7 +2209,7 @@ int fx_wisdom_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x32 Color:BriefRGB
int fx_brief_rgb (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_brief_rgb (%2d): RGB: %d, Location and speed: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_brief_rgb(%2d): RGB: %d, Location and speed: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
int speed = (fx->Parameter2 >> 16) & 0xff;
target->SetColorMod(0xff, RGBModifier::ADD, speed,
@@ -2054,7 +2222,7 @@ int fx_brief_rgb (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x33 Color:DarkenRGB
int fx_darken_rgb (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_darken_rgb (%2d): RGB: %d, Location and speed: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_darken_rgb(%2d): RGB: %d, Location and speed: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
EffectQueue::HackColorEffects(target, fx);
ieDword location = fx->Parameter2 & 0xff;
target->SetColorMod(location, RGBModifier::TINT, -1, fx->Parameter1 >> 8,
@@ -2065,7 +2233,7 @@ int fx_darken_rgb (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x34 Color:GlowRGB
int fx_glow_rgb (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_glow_rgb (%2d): RGB: %d, Location and speed: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_glow_rgb(%2d): RGB: %d, Location and speed: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
EffectQueue::HackColorEffects(target, fx);
ieDword location = fx->Parameter2 & 0xff;
target->SetColorMod(location, RGBModifier::BRIGHTEN, -1,
@@ -2076,22 +2244,21 @@ int fx_glow_rgb (Scriptable* /*Owner*/, Actor* target, Effect* fx)
}
// 0x35 AnimationIDModifier
-static EffectRef fx_animation_id_modifier_ref = { "AnimationIDModifier", -1 };
-
int fx_animation_id_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_animation_id_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_animation_id_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
switch (fx->Parameter2) {
case 0: //non permanent animation change
default:
- STAT_SET( IE_ANIMATION_ID, fx->Parameter1 );
+ STAT_SET_PCF( IE_ANIMATION_ID, fx->Parameter1 );
return FX_APPLIED;
case 1: //remove any non permanent change
target->fxqueue.RemoveAllEffects(fx_animation_id_modifier_ref);
//return FX_NOT_APPLIED;
//intentionally passing through (perma change removes previous changes)
case 2: //permanent animation id change
+ //FIXME: Why no PCF here? (Avenger)
target->SetBaseNoPCF(IE_ANIMATION_ID, fx->Parameter1);
return FX_NOT_APPLIED;
}
@@ -2100,18 +2267,17 @@ int fx_animation_id_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x36 ToHitModifier
int fx_to_hit_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_to_hit_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_to_hit_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
- HandleBonus( target, IE_TOHIT, fx->Parameter1, fx->TimingMode );
- return FX_APPLIED;
+ target->ToHit.HandleFxBonus(fx->Parameter1, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
+ return FX_PERMANENT;
}
// 0x37 KillCreatureType
-static EffectRef fx_death_ref = { "Death", -1 };
int fx_kill_creature_type (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_kill_creature_type (%2d): Value: %d, IDS: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_kill_creature_type(%2d): Value: %d, IDS: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (EffectQueue::match_ids( target, fx->Parameter2, fx->Parameter1) ) {
//convert it to a death opcode or apply the new effect?
fx->Opcode = EffectQueue::ResolveEffect(fx_death_ref);
@@ -2125,23 +2291,27 @@ int fx_kill_creature_type (Scriptable* /*Owner*/, Actor* target, Effect* fx)
}
// 0x38 Alignment:Invert
-//switch good to evil and evil to good
-//also switch chaotic to lawful and vice versa
+//switch good to evil and evil to good (neutral unchanged)
+//also switch chaotic to lawful and vice versa (neutral unchanged)
//gemrb extension: param2 actually controls which parts should be reversed
// 0 - switch both (as original)
// 1 - switch good and evil
// 2 - switch lawful and chaotic
-static int al_switch_both[16]={0,0x33,0x32,0x31,0,0x23,0x22,0x21,0,0x13,0x12,0x11};
-static int al_switch_law[16]={0,0x31,0x32,0x33,0,0x21,0x22,0x23,0,0x11,0x12,0x13};
-static int al_switch_good[16]={0,0x13,0x12,0x11,0,0x23,0x22,0x21,0,0x33,0x32,0x31};
+static int al_switch_both[12]={0,0x33,0x32,0x31,0,0x23,0x22,0x21,0,0x13,0x12,0x11};
+static int al_switch_law[12]={0,0x31,0x32,0x33,0,0x21,0x22,0x23,0,0x11,0x12,0x13};
+static int al_switch_good[12]={0,0x13,0x12,0x11,0,0x23,0x22,0x21,0,0x33,0x32,0x31};
int fx_alignment_invert (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_alignment_invert (%2d)\n", fx->Opcode );
+ if(0) print("fx_alignment_invert(%2d)", fx->Opcode);
register ieDword newalign = target->GetStat( IE_ALIGNMENT );
+ if (!newalign) {
+ // unset, so just do nothing;
+ return FX_APPLIED;
+ }
//compress the values. GNE is the first 2 bits originally
//LNC is the 4/5. bits.
- newalign = (newalign & AL_GE_MASK) | ((newalign & AL_LC_MASK)>>2);
+ newalign = (newalign & AL_GE_MASK) | (((newalign & AL_LC_MASK)-0x10)>>2);
switch (fx->Parameter2) {
default:
newalign = al_switch_both[newalign];
@@ -2160,7 +2330,7 @@ int fx_alignment_invert (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x39 Alignment:Change
int fx_alignment_change (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_alignment_change (%2d): Value: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_alignment_change(%2d): Value: %d", fx->Opcode, fx->Parameter2);
STAT_SET( IE_ALIGNMENT, fx->Parameter2 );
return FX_APPLIED;
}
@@ -2168,7 +2338,7 @@ int fx_alignment_change (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x3a DispelEffects
int fx_dispel_effects (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_dispel_effects (%2d): Value: %d, IDS: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_dispel_effects(%2d): Value: %d, IDS: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
ieResRef Removed;
ieDword level;
@@ -2196,7 +2366,7 @@ int fx_dispel_effects (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x3B StealthModifier
int fx_stealth_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_stealth_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_stealth_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_STEALTH );
return FX_APPLIED;
@@ -2205,7 +2375,7 @@ int fx_stealth_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x3C MiscastMagicModifier
int fx_miscast_magic_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_miscast_magic_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_miscast_magic_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
switch (fx->Parameter2) {
case 3:
@@ -2234,7 +2404,7 @@ int fx_miscast_magic_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// and in iwd it doesn't really follow the stat_mod convention (quite lame)
int fx_alchemy_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_alchemy_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_alchemy_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
switch(fx->Parameter2) {
case 0:
@@ -2253,7 +2423,7 @@ int fx_alchemy_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x3E PriestSpellSlotsModifier
int fx_bonus_priest_spells (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_bonus_priest_spells (%2d): Spell Add: %d ; Spell Level: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_bonus_priest_spells(%2d): Spell Add: %d ; Spell Level: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
int i=1;
//if param2 is 0, then double spells up to param1
@@ -2284,17 +2454,20 @@ int fx_bonus_priest_spells (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x3F State:Infravision
int fx_set_infravision_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_infravision_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
- STATE_SET( STATE_INFRA );
- return FX_APPLIED;
+ if(0) print("fx_set_infravision_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+ if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
+ BASE_STATE_SET( STATE_INFRA );
+ } else {
+ STATE_SET( STATE_INFRA );
+ }
+ return FX_PERMANENT;
}
// 0x40 Cure:Infravision
-static EffectRef fx_set_infravision_state_ref = { "State:Infravision", -1 };
int fx_cure_infravision_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cure_infravision_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_cure_infravision_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
BASE_STATE_CURE( STATE_INFRA );
target->fxqueue.RemoveAllEffects(fx_set_infravision_state_ref);
return FX_NOT_APPLIED;
@@ -2303,7 +2476,7 @@ int fx_cure_infravision_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x41 State:Blur
int fx_set_blur_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_blur_state (%2d)\n", fx->Opcode );
+ if(0) print("fx_set_blur_state(%2d)", fx->Opcode);
//death stops this effect
if (STATE_GET( STATE_DEAD) ) {
return FX_NOT_APPLIED;
@@ -2323,7 +2496,7 @@ int fx_set_blur_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x42 TransparencyModifier
int fx_transparency_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_transparency_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_transparency_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//maybe this needs some timing
switch (fx->Parameter2) {
@@ -2352,7 +2525,7 @@ static int eamods[]={EAM_ALLY,EAM_ALLY,EAM_DEFAULT,EAM_ALLY,EAM_DEFAULT,EAM_ENEM
int fx_summon_creature (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_summon_creature (%2d): ResRef:%s Anim:%s Type: %d\n", fx->Opcode, fx->Resource, fx->Resource2, fx->Parameter2 );
+ if(0) print("fx_summon_creature(%2d): ResRef:%s Anim:%s Type: %d", fx->Opcode, fx->Resource, fx->Resource2, fx->Parameter2);
//summon creature (resource), play vvc (resource2)
//creature's lastsummoner is Owner
@@ -2375,38 +2548,46 @@ int fx_summon_creature (Scriptable* Owner, Actor* target, Effect* fx)
// 0x44 UnsummonCreature
int fx_unsummon_creature (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_unsummon_creature (%2d)\n", fx->Opcode );
+ if(0) print("fx_unsummon_creature(%2d)", fx->Opcode);
//to be compatible with the original engine, unsummon doesn't work with PC's
//but it works on anything else
- if (!target->InParty) {
+ Map *area = target->GetCurrentArea();
+ if (!target->InParty && area) {
//play the vanish animation
ScriptedAnimation* sca = gamedata->GetScriptedAnimation(fx->Resource, false);
if (sca) {
sca->XPos+=target->Pos.x;
sca->YPos+=target->Pos.y;
- target->GetCurrentArea()->AddVVCell(sca);
+ area->AddVVCell(sca);
}
//remove the creature
target->DestroySelf();
+ return FX_NOT_APPLIED;
}
- return FX_NOT_APPLIED;
+
+ //the original keeps the effect around on partymembers or
+ //on those who don't have an area and executes it when the conditions apply.
+ return FX_APPLIED;
}
// 0x45 State:Nondetection
int fx_set_nondetection_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_nondetection_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
- STATE_SET( STATE_NONDET );
- return FX_APPLIED;
+ if(0) print("fx_set_nondetection_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+ if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
+ BASE_STATE_SET( STATE_NONDET );
+ } else {
+ STATE_SET( STATE_NONDET );
+ }
+ return FX_PERMANENT;
}
// 0x46 Cure:Nondetection
-static EffectRef fx_set_nondetection_state_ref = { "State:Nondetection", -1 };
int fx_cure_nondetection_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cure_nondetection_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_cure_nondetection_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
BASE_STATE_CURE( STATE_NONDET );
target->fxqueue.RemoveAllEffects(fx_set_nondetection_state_ref);
return FX_NOT_APPLIED;
@@ -2415,7 +2596,7 @@ int fx_cure_nondetection_state (Scriptable* /*Owner*/, Actor* target, Effect* fx
// 0x47 SexModifier
int fx_sex_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_sex_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_sex_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
ieDword value;
if (fx->Parameter2) {
value = fx->Parameter1;
@@ -2438,49 +2619,78 @@ int fx_sex_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x48 AIIdentifierModifier
int fx_ids_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_ids_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_ids_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+ bool permanent = fx->TimingMode==FX_DURATION_INSTANT_PERMANENT;
switch (fx->Parameter2) {
case 0:
- STAT_SET(IE_EA, fx->Parameter1);
+ if (permanent) {
+ BASE_SET(IE_EA, fx->Parameter1);
+ } else {
+ STAT_SET(IE_EA, fx->Parameter1);
+ }
break;
case 1:
- STAT_SET(IE_GENERAL, fx->Parameter1);
+ if (permanent) {
+ BASE_SET(IE_GENERAL, fx->Parameter1);
+ } else {
+ STAT_SET(IE_GENERAL, fx->Parameter1);
+ }
break;
case 2:
- STAT_SET(IE_RACE, fx->Parameter1);
+ if (permanent) {
+ BASE_SET(IE_RACE, fx->Parameter1);
+ } else {
+ STAT_SET(IE_RACE, fx->Parameter1);
+ }
break;
case 3:
- STAT_SET(IE_CLASS, fx->Parameter1);
+ if (permanent) {
+ BASE_SET(IE_CLASS, fx->Parameter1);
+ } else {
+ STAT_SET(IE_CLASS, fx->Parameter1);
+ }
break;
case 4:
- STAT_SET(IE_SPECIFIC, fx->Parameter1);
+ if (permanent) {
+ BASE_SET(IE_SPECIFIC, fx->Parameter1);
+ } else {
+ STAT_SET(IE_SPECIFIC, fx->Parameter1);
+ }
break;
case 5:
- STAT_SET(IE_SEX, fx->Parameter1);
+ if (permanent) {
+ BASE_SET(IE_SEX, fx->Parameter1);
+ } else {
+ STAT_SET(IE_SPECIFIC, fx->Parameter1);
+ }
break;
case 6:
- STAT_SET(IE_ALIGNMENT, fx->Parameter1);
+ if (permanent) {
+ BASE_SET(IE_ALIGNMENT, fx->Parameter1);
+ } else {
+ STAT_SET(IE_ALIGNMENT, fx->Parameter1);
+ }
break;
default:
return FX_NOT_APPLIED;
}
- //not sure, need a check if this action could be permanent
- return FX_APPLIED;
+ return FX_PERMANENT;
}
// 0x49 DamageBonusModifier
int fx_damage_bonus_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_damage_bonus_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_damage_bonus_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_DAMAGEBONUS );
+ //the basestat is not saved, so no FX_PERMANENT
return FX_APPLIED;
}
// 0x4a State:Blind
int fx_set_blind_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_blind_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_blind_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//pst power word blind projectile support
if (fx->Parameter2==1) {
@@ -2494,7 +2704,6 @@ int fx_set_blind_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
stat = core->Roll(1,30,15);
} else stat = 0;
fx->Duration = core->GetGame()->GameTime+stat;
-
}
//don't do this effect twice (bug exists in BG2, but fixed in IWD2)
@@ -2502,18 +2711,29 @@ int fx_set_blind_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
STATE_SET( STATE_BLIND );
//the feat normally exists only in IWD2, but won't hurt
if (!target->GetFeat(FEAT_BLIND_FIGHT)) {
- STAT_SUB (IE_TOHIT, 10); // all other tohit stats are treated as bonuses
+ target->AddPortraitIcon(PI_BLIND);
+ if (core->HasFeature(GF_REVERSE_TOHIT)) {
+ //BG2
+ target->AC.HandleFxBonus(-4, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
+ target->ToHit.HandleFxBonus(-4, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
+ } else {
+ //IWD2
+ target->AC.HandleFxBonus(-2, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
+ // TODO: 50% inherent miss chance (full concealment)
+ target->AC.SetDexterityBonus(0); // no dexterity bonus to AC (caught flatfooted)
+ target->ToHit.HandleFxBonus(-5, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
+ }
}
}
+ //this should be FX_PERMANENT, but the current code is a mess here. Review after cleaned up
return FX_APPLIED;
}
// 0x4b Cure:Blind
-static EffectRef fx_set_blind_state_ref = { "State:Blind", -1 };
int fx_cure_blind_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cure_blind_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_cure_blind_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
BASE_STATE_CURE( STATE_BLIND );
target->fxqueue.RemoveAllEffects(fx_set_blind_state_ref);
return FX_NOT_APPLIED;
@@ -2522,21 +2742,22 @@ int fx_cure_blind_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x4c State:Feeblemind
int fx_set_feebleminded_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_feebleminded_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_feebleminded_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STATE_SET( STATE_FEEBLE );
STAT_SET( IE_INT, 3);
if (enhanced_effects) {
target->AddPortraitIcon(PI_FEEBLEMIND);
}
+ //This state is better off with always stored, because of the portrait icon and the int stat
+ //it wouldn't be easily cured if it would go away after irrevocably altering another stat
return FX_APPLIED;
}
// 0x4d Cure:Feeblemind
-static EffectRef fx_set_feebleminded_state_ref = { "State:Feeblemind", -1 };
int fx_cure_feebleminded_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cure_feebleminded_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_cure_feebleminded_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
BASE_STATE_CURE( STATE_FEEBLE );
target->fxqueue.RemoveAllEffects(fx_set_feebleminded_state_ref);
target->fxqueue.RemoveAllEffectsWithParam(fx_display_portrait_icon_ref, PI_FEEBLEMIND);
@@ -2546,11 +2767,16 @@ int fx_cure_feebleminded_state (Scriptable* /*Owner*/, Actor* target, Effect* fx
// 0x4e State:Diseased
int fx_set_diseased_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_diseased_state (%2d): Damage: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_diseased_state(%2d): Damage: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (STATE_GET(STATE_DEAD|STATE_PETRIFIED|STATE_FROZEN) ) {
return FX_NOT_APPLIED;
}
+ int count = target->fxqueue.CountEffects(fx_diseased_state_ref, fx->Parameter1, fx->Parameter2, fx->Resource);
+ if (count > 1) {
+ return FX_APPLIED;
+ }
+
//setting damage to 0 because not all types do damage
ieDword damage = 0;
@@ -2572,74 +2798,79 @@ int fx_set_diseased_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
}
break;
case RPD_STR: //strength
- STAT_ADD(IE_STR, fx->Parameter1);
+ STAT_SUB(IE_STR, fx->Parameter1);
break;
case RPD_DEX: //dex
- STAT_ADD(IE_DEX, fx->Parameter1);
+ STAT_SUB(IE_DEX, fx->Parameter1);
break;
case RPD_CON: //con
- STAT_ADD(IE_CON, fx->Parameter1);
+ STAT_SUB(IE_CON, fx->Parameter1);
break;
case RPD_INT: //int
- STAT_ADD(IE_INT, fx->Parameter1);
+ STAT_SUB(IE_INT, fx->Parameter1);
break;
case RPD_WIS: //wis
- STAT_ADD(IE_WIS, fx->Parameter1);
+ STAT_SUB(IE_WIS, fx->Parameter1);
break;
case RPD_CHA: //cha
- STAT_ADD(IE_CHR, fx->Parameter1);
+ STAT_SUB(IE_CHR, fx->Parameter1);
break;
+ case RPD_CONTAGION: //contagion (iwd2) - an aggregate of STR,DEX,CHR,SLOW diseases
+ STAT_SUB(IE_STR, 2);
+ STAT_SUB(IE_DEX, 2);
+ STAT_SUB(IE_CHR, 2);
+ //falling through
case RPD_SLOW: //slow
+ //TODO: in iwd2
+ //-2 AC, BaB, reflex, damage
+ //-1 attack#
+ //speed halved
+ //in bg2
+ //TBD
+ target->AddPortraitIcon(PI_SLOWED);
break;
case RPD_MOLD: //mold touch (how)
EXTSTATE_SET(EXTSTATE_MOLD);
+ target->SetSpellState(SS_MOLDTOUCH);
damage = 1;
break;
case RPD_MOLD2:
break;
+ case RPD_PEST: //cloud of pestilence (iwd2)
+ break;
+ case RPD_DOLOR: //dolorous decay (iwd2)
+ break;
default:
damage = 1;
break;
}
//percent
Scriptable *caster = GetCasterObject();
-
if (damage) {
target->Damage(damage, DAMAGE_POISON, caster);
}
+
return FX_APPLIED;
}
// 0x4f Cure:Disease
-static EffectRef fx_diseased_state_ref = { "State:Diseased", -1 };
-
int fx_cure_diseased_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cure_diseased_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_cure_diseased_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//STATE_CURE( STATE_DISEASED ); //the bit flagged as disease is actually the active state. so this is even more unlikely to be used as advertised
target->fxqueue.RemoveAllEffects( fx_diseased_state_ref ); //this is what actually happens in bg2
return FX_NOT_APPLIED;
}
// 0x50 State:Deafness
-// gemrb extension: modifiable amount
-// none of the engines care about stacking
int fx_set_deaf_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_deaf_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_deaf_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
- //gemrb fix
+ //adopted IWD2 method, spellfailure will be handled internally based on the spell state
if (target->SetSpellState(SS_DEAF)) return FX_APPLIED;
- if (!fx->Parameter1) {
- fx->Parameter1 = 50;
- }
- STAT_ADD(IE_SPELLFAILUREMAGE, fx->Parameter1);
- if (!fx->Parameter2) {
- fx->Parameter1 = 50;
- }
- STAT_ADD(IE_SPELLFAILUREPRIEST, fx->Parameter2);
EXTSTATE_SET(EXTSTATE_DEAF); //iwd1/how needs this
if (enhanced_effects) {
target->AddPortraitIcon(PI_DEAFNESS);
@@ -2649,7 +2880,7 @@ int fx_set_deaf_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
int fx_set_deaf_state_iwd2 (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_deaf_state_iwd2 (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_deaf_state_iwd2(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//gemrb fix
if (target->SetSpellState(SS_DEAF)) return FX_APPLIED;
@@ -2660,7 +2891,7 @@ int fx_set_deaf_state_iwd2 (Scriptable* /*Owner*/, Actor* target, Effect* fx)
}
STAT_ADD(IE_SPELLFAILUREMAGE, fx->Parameter1);
if (!fx->Parameter2) {
- fx->Parameter1 = 20;
+ fx->Parameter2 = 20;
}
STAT_ADD(IE_SPELLFAILUREPRIEST, fx->Parameter2);
EXTSTATE_SET(EXTSTATE_DEAF); //iwd1/how needs this
@@ -2669,13 +2900,10 @@ int fx_set_deaf_state_iwd2 (Scriptable* /*Owner*/, Actor* target, Effect* fx)
}
// 0x51 Cure:Deafness
-static EffectRef fx_deaf_state_ref = { "State:Deafness", -1 };
-static EffectRef fx_deaf_state_iwd2_ref = { "State:DeafnessIWD2", -1 };
-
//removes the deafness effect
int fx_cure_deaf_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cure_deaf_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_cure_deaf_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
target->fxqueue.RemoveAllEffects(fx_deaf_state_ref);
target->fxqueue.RemoveAllEffects(fx_deaf_state_iwd2_ref);
@@ -2685,7 +2913,7 @@ int fx_cure_deaf_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x52 SetAIScript
int fx_set_ai_script (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_ai_state (%2d): Resource: %s, Type: %d\n", fx->Opcode, fx->Resource, fx->Parameter2 );
+ if(0) print("fx_set_ai_state(%2d): Resource: %s, Type: %d", fx->Opcode, fx->Resource, fx->Parameter2);
target->SetScript (fx->Resource, fx->Parameter2);
return FX_NOT_APPLIED;
}
@@ -2693,7 +2921,7 @@ int fx_set_ai_script (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x53 Protection:Projectile
int fx_protection_from_projectile (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_protection_from_projectile (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_protection_from_projectile(%2d): Type: %d", fx->Opcode, fx->Parameter2);
STAT_BIT_OR( IE_IMMUNITY, IMM_PROJECTILE);
return FX_APPLIED;
}
@@ -2701,150 +2929,199 @@ int fx_protection_from_projectile (Scriptable* /*Owner*/, Actor* target, Effect*
// 0x54 MagicalFireResistanceModifier
int fx_magical_fire_resistance_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_magical_fire_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_magical_fire_resistance_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
- STAT_MOD( IE_RESISTMAGICFIRE );
- return FX_APPLIED;
+ if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
+ BASE_MOD( IE_RESISTMAGICFIRE );
+ } else {
+ STAT_MOD( IE_RESISTMAGICFIRE );
+ }
+ return FX_PERMANENT;
}
// 0x55 MagicalColdResistanceModifier
int fx_magical_cold_resistance_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_magical_cold_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_magical_cold_resistance_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
- STAT_MOD( IE_RESISTMAGICCOLD );
- return FX_APPLIED;
+ if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
+ BASE_MOD( IE_RESISTMAGICCOLD );
+ } else {
+ STAT_MOD( IE_RESISTMAGICCOLD );
+ }
+ return FX_PERMANENT;
}
// 0x56 SlashingResistanceModifier
int fx_slashing_resistance_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_slashing_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_slashing_resistance_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
- STAT_MOD( IE_RESISTSLASHING );
- return FX_APPLIED;
+ if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
+ BASE_MOD( IE_RESISTSLASHING );
+ } else {
+ STAT_MOD( IE_RESISTSLASHING );
+ }
+ return FX_PERMANENT;
}
// 0x57 CrushingResistanceModifier
int fx_crushing_resistance_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_crushing_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_crushing_resistance_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
- STAT_MOD( IE_RESISTCRUSHING );
- return FX_APPLIED;
+ if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
+ BASE_MOD( IE_RESISTCRUSHING );
+ } else {
+ STAT_MOD( IE_RESISTCRUSHING );
+ }
+ return FX_PERMANENT;
}
// 0x58 PiercingResistanceModifier
int fx_piercing_resistance_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_piercing_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_piercing_resistance_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
- STAT_MOD( IE_RESISTPIERCING );
- return FX_APPLIED;
+ if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
+ BASE_MOD( IE_RESISTPIERCING );
+ } else {
+ STAT_MOD( IE_RESISTPIERCING );
+ }
+ return FX_PERMANENT;
}
// 0x59 MissilesResistanceModifier
int fx_missiles_resistance_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_missiles_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_missiles_resistance_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
- STAT_MOD( IE_RESISTMISSILE );
- return FX_APPLIED;
+ if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
+ BASE_MOD( IE_RESISTMISSILE );
+ } else {
+ STAT_MOD( IE_RESISTMISSILE );
+ }
+ return FX_PERMANENT;
}
// 0x5A OpenLocksModifier
int fx_open_locks_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_open_locks_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_open_locks_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
- STAT_MOD( IE_LOCKPICKING );
- return FX_APPLIED;
+ if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
+ BASE_MOD( IE_LOCKPICKING );
+ } else {
+ STAT_MOD( IE_LOCKPICKING );
+ }
+ return FX_PERMANENT;
}
// 0x5B FindTrapsModifier
int fx_find_traps_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_find_traps_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_find_traps_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
- STAT_MOD( IE_TRAPS );
- return FX_APPLIED;
+ if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
+ BASE_MOD( IE_TRAPS );
+ } else {
+ STAT_MOD( IE_TRAPS );
+ }
+ return FX_PERMANENT;
}
// 0x5C PickPocketsModifier
int fx_pick_pockets_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_pick_pockets_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_pick_pockets_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
- STAT_MOD( IE_PICKPOCKET );
- return FX_APPLIED;
+ if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
+ BASE_MOD( IE_PICKPOCKET );
+ } else {
+ STAT_MOD( IE_PICKPOCKET );
+ }
+ return FX_PERMANENT;
}
// 0x5D FatigueModifier
int fx_fatigue_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_fatigue_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_fatigue_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
- STAT_MOD( IE_FATIGUE );
- // TODO: fatigue has a negative effect on luck -> add fatigmod.2da support
- return FX_APPLIED;
+ if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
+ BASE_MOD( IE_FATIGUE );
+ } else {
+ STAT_MOD( IE_FATIGUE );
+ }
+ return FX_PERMANENT;
}
// 0x5E IntoxicationModifier
int fx_intoxication_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_intoxication_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_intoxication_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
- STAT_MOD( IE_INTOXICATION );
- return FX_APPLIED;
+ if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
+ BASE_MOD( IE_INTOXICATION );
+ } else {
+ STAT_MOD( IE_INTOXICATION );
+ }
+ return FX_PERMANENT;
}
// 0x5F TrackingModifier
int fx_tracking_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_tracking_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_tracking_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
- STAT_MOD( IE_TRACKING );
- return FX_APPLIED;
+ if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
+ BASE_MOD( IE_TRACKING );
+ } else {
+ STAT_MOD( IE_TRACKING );
+ }
+ return FX_PERMANENT;
}
// 0x60 LevelModifier
int fx_level_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_level_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_level_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_LEVEL );
+ //While the original can, i would rather not modify the base stat here...
return FX_APPLIED;
}
// 0x61 StrengthBonusModifier
int fx_strength_bonus_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_strength_bonus_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_strength_bonus_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
- STAT_MOD( IE_STREXTRA );
+ if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
+ BASE_MOD( IE_STREXTRA );
+ } else {
+ STAT_MOD( IE_STREXTRA );
+ }
return FX_APPLIED;
}
// 0x62 State:Regenerating
int fx_set_regenerating_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_regenerating_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_regenerating_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
int damage;
int tmp = fx->Parameter1;
ieDword gameTime = core->GetGame()->GameTime;
- ieDword nextHeal;
- if (!fx->Parameter3) {
- //hack to ensure our first call gets through
- nextHeal = gameTime-1;
+ if (fx->FirstApply) {
+ //ensure we prepare Parameter3 now
} else {
- nextHeal = fx->Parameter3;
+ //we can have multiple calls at the same gameTime, so we
+ //just go to gameTime+1 to ensure one call
+ ieDword nextHeal = fx->Parameter3;
+ if (nextHeal>=gameTime) return FX_APPLIED;
}
- //we can have multiple calls at the same gameTime, so we
- //just go to gameTime+1 to ensure one call
- if (nextHeal>=gameTime) return FX_APPLIED;
-
HandlePercentageDamage(fx, target);
switch(fx->Parameter2) {
@@ -2855,30 +3132,32 @@ int fx_set_regenerating_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
tmp *= core->Time.round_sec;
//fall
case RPD_SECONDS: //restore param3 hp every param1 seconds
- fx->Parameter3 = nextHeal + tmp*AI_UPDATE_TIME;
+ fx->Parameter3 = gameTime + tmp*AI_UPDATE_TIME;
damage = 1;
break;
case RPD_PERCENT: // handled in HandlePercentageDamage
case RPD_POINTS: //restore param1 hp every second? that's crazy!
damage = fx->Parameter1;
- fx->Parameter3 = nextHeal + AI_UPDATE_TIME;
+ fx->Parameter3 = gameTime + AI_UPDATE_TIME;
break;
default:
- fx->Parameter3 = nextHeal + AI_UPDATE_TIME;
+ fx->Parameter3 = gameTime + AI_UPDATE_TIME;
damage = 1;
break;
}
- //This should take care of the change of the modified stat
- //So there is no need to do anything else here other than increasing
- //the base current hp
+ if (fx->FirstApply) {
+ //don't add hp in the first occasion, so it cannot be used for cheat heals
+ return FX_APPLIED;
+ }
+
target->NewBase(IE_HITPOINTS, damage, MOD_ADDITIVE);
return FX_APPLIED;
}
// 0x63 SpellDurationModifier
int fx_spell_duration_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_spell_duration_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_spell_duration_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
switch (fx->Parameter2) {
case 0:
@@ -2895,14 +3174,14 @@ int fx_spell_duration_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx
// 0x64 Protection:Creature
int fx_generic_effect (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
{
- if (0) printf( "fx_generic_effect (%2d): Param1: %d, Param2: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_generic_effect(%2d): Param1: %d, Param2: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
return FX_APPLIED;
}
// 0x65 Protection:Opcode
int fx_protection_opcode (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_protection_opcode (%2d): Opcode: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_protection_opcode(%2d): Opcode: %d", fx->Opcode, fx->Parameter2);
STAT_BIT_OR(IE_IMMUNITY, IMM_OPCODE);
return FX_APPLIED;
}
@@ -2910,7 +3189,7 @@ int fx_protection_opcode (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x66 Protection:SpellLevel
int fx_protection_spelllevel (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_protection_spelllevel (%2d) Level: %d\n", fx->Opcode, fx->Parameter1);
+ if(0) print("fx_protection_spelllevel(%2d) Level: %d", fx->Opcode, fx->Parameter1);
int value = fx->Parameter1;
if (value<9) {
@@ -2924,7 +3203,7 @@ int fx_protection_spelllevel (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x67 ChangeName
int fx_change_name (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_change_name_modifier (%2d): StrRef: %d\n", fx->Opcode, fx->Parameter1 );
+ if(0) print("fx_change_name_modifier(%2d): StrRef: %d", fx->Opcode, fx->Parameter1);
//this also changes the base stat
target->SetName(fx->Parameter1, 0);
return FX_NOT_APPLIED;
@@ -2933,7 +3212,7 @@ int fx_change_name (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x68 ExperienceModifier
int fx_experience_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_experience_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_experience_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//FIXME: this has mode too
//target->AddExperience (fx->Parameter1);
STAT_MOD( IE_XP );
@@ -2945,7 +3224,7 @@ int fx_experience_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//no one uses it, though. To keep the function, the default branch will do the subtraction
int fx_gold_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_gold_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_gold_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (!target->InParty) {
STAT_MOD( IE_GOLD );
return FX_NOT_APPLIED;
@@ -2974,39 +3253,76 @@ int fx_gold_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x6a MoraleBreakModifier
int fx_morale_break_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_morale_break_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
- STAT_MOD(IE_MORALEBREAK);
+ if(0) print("fx_morale_break_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+ if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
+ BASE_MOD(IE_MORALEBREAK);
+ } else {
+ STAT_MOD(IE_MORALEBREAK);
+ }
return FX_PERMANENT; //permanent morale break doesn't stick
}
// 0x6b PortraitChange
+// 0 - small
+// 1 - large
+// 2 - both
int fx_portrait_change (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_portrait_change (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
- target->SetPortrait( fx->Resource, fx->Parameter2);
+ if(0) print("fx_portrait_change(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+ //in gemrb this is 0 both, 1 Large, 2 Small so we have to swap 2 and 0
+ target->SetPortrait( fx->Resource, 2-fx->Parameter2);
return FX_NOT_APPLIED;
}
// 0x6c ReputationModifier
int fx_reputation_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_reputation_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_reputation_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD(IE_REPUTATION);
- return FX_NOT_APPLIED; //needs testing
+ //needs testing and thinking, the original engine can permanently modify the basestat
+ //but it is unclear how a timed reputation change alters the global reputation stored in game
+ //our current solution immediately transfers the reputation to game (in case of pc)
+ return FX_NOT_APPLIED;
}
// 0x6d --> see later
-// 0x6e works only in PST, reused for turning undead
+//0x6e works only in PST, reused for turning undead in bg
+//0x118 TurnUndead how
+int fx_turn_undead (Scriptable* Owner, Actor* target, Effect* fx)
+{
+ if(0) print("fx_turn_undead(%2d): Level %d", fx->Opcode, fx->Parameter1);
+ if (fx->Parameter1) {
+ target->Turn(Owner, fx->Parameter1);
+ } else {
+ if (Owner->Type!=ST_ACTOR) {
+ return FX_NOT_APPLIED;
+ }
+ target->Turn(Owner, ((Actor *) Owner)->GetStat(IE_TURNUNDEADLEVEL));
+ }
+ return FX_APPLIED;
+}
// 0x6f Item:CreateMagic
-
-static EffectRef fx_remove_item_ref = { "Item:Remove", -1 };
-
int fx_create_magic_item (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- //charge count is incorrect
- target->inventory.SetSlotItemRes(fx->Resource, target->inventory.GetMagicSlot(),fx->Parameter1,fx->Parameter3,fx->Parameter4);
+ //charge count is the same for all slots by default
+ if (!fx->Parameter3) fx->Parameter3 = fx->Parameter1;
+ if (!fx->Parameter4) fx->Parameter4 = fx->Parameter1;
+ int slot = target->inventory.GetMagicSlot();
+ target->inventory.SetSlotItemRes(fx->Resource, slot, fx->Parameter1, fx->Parameter3, fx->Parameter4);
+ //IWD doesn't let you create two handed weapons (actually only decastave) if shield slot is filled
+ //modders can still force two handed weapons with Parameter2
+ if (!fx->Parameter2) {
+ if (target->inventory.GetItemFlag(slot)&IE_ITEM_TWO_HANDED) {
+ if (target->inventory.HasItemInSlot("",target->inventory.GetShieldSlot())) {
+ target->inventory.RemoveItem(slot);
+ displaymsg->DisplayConstantStringNameString(STR_SPELL_FAILED, DMC_WHITE, STR_OFFHAND_USED, target);
+ return FX_NOT_APPLIED;
+ }
+ }
+ }
+
//equip the weapon
target->inventory.SetEquippedSlot(target->inventory.GetMagicSlot()-target->inventory.GetWeaponSlot(), 0);
if ((fx->TimingMode&0xff) == FX_DURATION_INSTANT_LIMITED) {
@@ -3023,6 +3339,7 @@ int fx_create_magic_item (Scriptable* /*Owner*/, Actor* target, Effect* fx)
int fx_remove_item (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
//will destroy the first item
+print("Destroy Item: %s\n", fx->Resource);
if (target->inventory.DestroyItem(fx->Resource,0,1)) {
target->ReinitQuickSlots();
}
@@ -3049,8 +3366,8 @@ int fx_equip_item (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x72 Dither
int fx_dither (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
{
- if (0) printf( "fx_dither (%2d): Value: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
- //this effect doesn't work in any engine versions
+ if(0) print("fx_dither(%2d): Value: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+ //this effect doesn't work in any original engine versions
return FX_NOT_APPLIED;
}
@@ -3122,13 +3439,12 @@ int fx_detect_alignment (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 1 reveal area in pattern
int fx_reveal_area (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_reveal_area (%2d): Value: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_reveal_area(%2d): Value: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
Map *map = NULL;
-
+
if (target) {
map = target->GetCurrentArea();
- }
- else {
+ } else {
map = core->GetGame()->GetCurrentArea();
}
if (!map) {
@@ -3146,17 +3462,15 @@ int fx_reveal_area (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x76 Reveal:Creatures
int fx_reveal_creatures (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
{
- if (0) printf( "fx_reveal_creatures (%2d): Value: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
- //reveals creatures (not working in original IE)
+ if(0) print("fx_reveal_creatures(%2d): Value: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+ //this effect doesn't work in any original engine versions
return FX_NOT_APPLIED;
}
// 0x77 MirrorImage
-static EffectRef fx_mirror_image_modifier_ref = { "MirrorImageModifier", -1 };
-
int fx_mirror_image (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_mirror_image (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_mirror_image(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
ieDword images;
if (fx->Parameter2) {
@@ -3192,7 +3506,7 @@ int fx_mirror_image (Scriptable* Owner, Actor* target, Effect* fx)
// 0x78 Protection:Weapons
int fx_immune_to_weapon (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
{
- if (0) printf( "fx_immune_to_weapon (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_immune_to_weapon(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (!fx->FirstApply) return FX_APPLIED;
int level;
@@ -3257,17 +3571,15 @@ int fx_immune_to_weapon (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
// 0x79 VisualAnimationEffect (unknown)
int fx_visual_animation_effect (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
{
-//this is an unknown effect
- if (0) printf( "fx_visual_animation_effect (%2d)\n", fx->Opcode );
+ //this effect doesn't work in any original engine versions
+ if(0) print("fx_visual_animation_effect(%2d)", fx->Opcode);
return FX_NOT_APPLIED;
}
// 0x7a Item:CreateInventory
-static EffectRef fx_remove_inventory_item_ref = { "Item:RemoveInventory", -1 };
-
int fx_create_inventory_item (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_create_inventory_item (%2d)\n", fx->Opcode );
+ if(0) print("fx_create_inventory_item(%2d)", fx->Opcode);
target->inventory.AddSlotItemRes( fx->Resource, SLOT_ONLYINVENTORY, fx->Parameter1, fx->Parameter3, fx->Parameter4 );
if ((fx->TimingMode&0xff) == FX_DURATION_INSTANT_LIMITED) {
//if this effect has expiration, then it will remain as a remove_item
@@ -3282,10 +3594,13 @@ int fx_create_inventory_item (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x7b Item:RemoveInventory
int fx_remove_inventory_item (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_remove_inventory_item (%2d)\n", fx->Opcode );
+ if(0) print("fx_remove_inventory_item(%2d)", fx->Opcode);
//FIXME: now equipped items are only wielded weapons
//why would it not let equipped items to be destructed?
- target->inventory.DestroyItem(fx->Resource,IE_INV_ITEM_EQUIPPED,1);
+ //changed to work on any items - book of infinite spells relies on this
+ //selective destruction is available if you set Parameter2 to nonzero
+ //and Parameter1 to the bitfield
+ target->inventory.DestroyItem(fx->Resource,fx->Parameter2?fx->Parameter1:0,1);
return FX_NOT_APPLIED;
}
@@ -3293,7 +3608,7 @@ int fx_remove_inventory_item (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// iwd2 has several options
int fx_dimension_door (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_dimension_door (%2d) Type:%d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_dimension_door(%2d) Type:%d", fx->Opcode, fx->Parameter2);
Point p;
switch(fx->Parameter2)
@@ -3330,17 +3645,15 @@ int fx_dimension_door (Scriptable* Owner, Actor* target, Effect* fx)
// 0x7d Unlock
int fx_knock (Scriptable* Owner, Actor* /*target*/, Effect* fx)
{
- if (0) printf( "fx_knock (%2d) [%d.%d]\n", fx->Opcode, fx->PosX, fx->PosY );
+ if(0) print("fx_knock(%2d) [%d.%d]", fx->Opcode, fx->PosX, fx->PosY);
Map *map = Owner->GetCurrentArea();
if (!map) {
return FX_NOT_APPLIED;
}
Point p(fx->PosX, fx->PosY);
-printf("KNOCK Pos: %d.%d\n", fx->PosX, fx->PosY);
Door *door = map->TMap->GetDoorByPosition(p);
if (door) {
-printf("Got a door\n");
if (door->LockDifficulty<100) {
door->SetDoorLocked(false, true);
}
@@ -3348,7 +3661,6 @@ printf("Got a door\n");
}
Container *container = map->TMap->GetContainerByPosition(p);
if (container) {
-printf("Got a container\n");
if(container->LockDifficulty<100) {
container->SetContainerLocked(false);
}
@@ -3361,7 +3673,7 @@ printf("Got a container\n");
// 0xb0 MovementRateModifier2
int fx_movement_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_movement_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_movement_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//iwd2 freeaction disables only 0xb0, who cares
if (target->HasSpellState(SS_FREEACTION)) return FX_NOT_APPLIED;
@@ -3369,7 +3681,11 @@ int fx_movement_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//definitely a bug
if (target->HasSpellState(SS_AEGIS)) return FX_NOT_APPLIED;
+ ieDword value = target->GetStat(IE_MOVEMENTRATE);
STAT_MOD(IE_MOVEMENTRATE);
+ if (value < target->GetStat(IE_MOVEMENTRATE)) {
+ target->AddPortraitIcon(PI_HASTED);
+ }
return FX_APPLIED;
}
@@ -3380,7 +3696,7 @@ static const ieResRef monster_summoning_2da[FX_MS]={"MONSUM01","MONSUM02","MONSU
// 0x7f MonsterSummoning
int fx_monster_summoning (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_monster_summoning (%2d): Number: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_monster_summoning(%2d): Number: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//check the summoning limit?
if (!Owner) {
return FX_NOT_APPLIED;
@@ -3408,7 +3724,7 @@ int fx_monster_summoning (Scriptable* Owner, Actor* target, Effect* fx)
} else {
strnuprcpy(table, monster_summoning_2da[fx->Parameter2], 8);
}
- core->GetResRefFrom2DA(monster_summoning_2da[fx->Parameter2], monster, hit, areahit);
+ core->GetResRefFrom2DA(table, monster, hit, areahit);
if (!hit[0]) {
strnuprcpy(hit, fx->Resource2, 8);
@@ -3445,7 +3761,7 @@ int fx_monster_summoning (Scriptable* Owner, Actor* target, Effect* fx)
// 0x80 State:Confused
int fx_set_confused_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_confused_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_confused_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (target->HasSpellState(SS_BLOODRAGE)) {
return FX_NOT_APPLIED;
@@ -3469,7 +3785,7 @@ int fx_set_confused_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x81 AidNonCumulative
int fx_set_aid_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_aid_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_aid_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (!fx->Parameter2) {
fx->Parameter2=core->Roll(fx->Parameter1,8,0);
}
@@ -3488,8 +3804,8 @@ int fx_set_aid_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
STAT_ADD( IE_SAVEVSBREATH, fx->Parameter1);
STAT_ADD( IE_SAVEVSSPELL, fx->Parameter1);
//bless effect too?
- STAT_ADD( IE_TOHIT, fx->Parameter1);
- STAT_ADD( IE_MORALEBREAK, fx->Parameter1);
+ target->ToHit.HandleFxBonus(fx->Parameter1, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
+ STAT_ADD( IE_DAMAGEBONUS, fx->Parameter1);
if (enhanced_effects) {
target->AddPortraitIcon(PI_AID);
target->SetColorMod(0xff, RGBModifier::ADD, 30, 50, 50, 50);
@@ -3498,12 +3814,9 @@ int fx_set_aid_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
}
// 0x82 BlessNonCumulative
-
-static EffectRef fx_bane_ref = { "Bane", -1 };
-
int fx_set_bless_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_bless_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_bless_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (STATE_GET (STATE_BLESS) ) //bless is non cumulative
return FX_NOT_APPLIED;
@@ -3513,7 +3826,8 @@ int fx_set_bless_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
STATE_SET( STATE_BLESS );
target->SetSpellState(SS_BLESS);
- STAT_ADD( IE_TOHIT, fx->Parameter1);
+ target->ToHit.HandleFxBonus(fx->Parameter1, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
+ STAT_ADD( IE_DAMAGEBONUS, fx->Parameter1);
STAT_ADD( IE_MORALEBREAK, fx->Parameter1);
if (enhanced_effects) {
target->AddPortraitIcon(PI_BLESS);
@@ -3524,7 +3838,7 @@ int fx_set_bless_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x83 ChantNonCumulative
int fx_set_chant_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_chant_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_chant_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (STATE_GET (STATE_CHANT) ) //chant is non cumulative
return FX_NOT_APPLIED;
@@ -3537,7 +3851,7 @@ int fx_set_chant_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x84 HolyNonCumulative
int fx_set_holy_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_holy_state (%2d): Modifier: %d\n", fx->Opcode, fx->Parameter1 );
+ if(0) print("fx_set_holy_state(%2d): Modifier: %d", fx->Opcode, fx->Parameter1);
if (STATE_GET (STATE_HOLY) ) //holy power is non cumulative
return FX_NOT_APPLIED;
@@ -3557,24 +3871,26 @@ int fx_set_holy_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x85 LuckNonCumulative
int fx_luck_non_cumulative (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_luck_non_cumulative (%2d): Modifier: %d\n", fx->Opcode, fx->Parameter1);
+ if(0) print("fx_luck_non_cumulative(%2d): Modifier: %d", fx->Opcode, fx->Parameter1);
if (STATE_GET (STATE_LUCK) ) //this luck is non cumulative
return FX_NOT_APPLIED;
STATE_SET( STATE_LUCK );
target->SetSpellState(SS_LUCK);
STAT_ADD( IE_LUCK, fx->Parameter1 );
- STAT_ADD( IE_DAMAGELUCK, fx->Parameter1 );
+ //no, this isn't in BG2, this modifies only the state bitfield and the stat
+ //STAT_ADD( IE_DAMAGELUCK, fx->Parameter1 );
return FX_APPLIED;
}
// 0x85 LuckCumulative (iwd2)
int fx_luck_cumulative (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_luck_cumulative (%2d): Modifier: %d\n", fx->Opcode, fx->Parameter1);
+ if(0) print("fx_luck_cumulative(%2d): Modifier: %d", fx->Opcode, fx->Parameter1);
target->SetSpellState(SS_LUCK);
STAT_ADD( IE_LUCK, fx->Parameter1 );
+ //TODO:check this in IWD2
STAT_ADD( IE_DAMAGELUCK, fx->Parameter1 );
return FX_APPLIED;
}
@@ -3582,15 +3898,16 @@ int fx_luck_cumulative (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x86 State:Petrification
int fx_set_petrified_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_petrified_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_petrified_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
BASE_STATE_SET( STATE_PETRIFIED );
- return FX_NOT_APPLIED; //permanent effect
+ target->SendDiedTrigger();
+ //always permanent effect, in fact in the original it is a death opcode (Avenger)
+ //i just would like this to be less difficult to use in mods (don't destroy petrified creatures)
+ return FX_NOT_APPLIED;
}
// 0x87 Polymorph
-static EffectRef fx_polymorph_ref = { "Polymorph", -1 };
-
void CopyPolymorphStats(Actor *source, Actor *target)
{
int i;
@@ -3622,7 +3939,7 @@ void CopyPolymorphStats(Actor *source, Actor *target)
int fx_polymorph (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_polymorph_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_polymorph_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (!gamedata->Exists(fx->Resource,IE_CRE_CLASS_ID)) {
//kill all polymorph effects
@@ -3632,6 +3949,11 @@ int fx_polymorph (Scriptable* /*Owner*/, Actor* target, Effect* fx)
return FX_NOT_APPLIED;
}
+ // kill all other polymorph effects
+ if (fx->FirstApply) {
+ target->fxqueue.RemoveAllEffects(fx_polymorph_ref);
+ }
+
// to avoid repeatedly loading the file or keeping all the data around
// wasting memory, we keep a PolymorphCache object around, with only
// the data we need from the polymorphed creature
@@ -3675,7 +3997,7 @@ int fx_polymorph (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x88 ForceVisible
int fx_force_visible (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_force_visible (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_force_visible(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (pstflags) {
BASE_STATE_CURE(STATE_PST_INVIS);
@@ -3684,13 +4006,30 @@ int fx_force_visible (Scriptable* /*Owner*/, Actor* target, Effect* fx)
}
target->fxqueue.RemoveAllEffectsWithParam(fx_set_invisible_state_ref,0);
target->fxqueue.RemoveAllEffectsWithParam(fx_set_invisible_state_ref,2);
+
+ //fix the hiding puppet while mislead bug, by
+ if (target->GetSafeStat(IE_PUPPETTYPE)==1) {
+ //hack target to use the plain type
+ target->Modified[IE_PUPPETTYPE]=0;
+
+ //go after the original puppetmarker in the puppet too
+ Actor *puppet = core->GetGame()->GetActorByGlobalID(target->GetSafeStat(IE_PUPPETID) );
+ if (puppet) {
+ Effect *puppetmarker = puppet->fxqueue.HasEffect(fx_puppetmarker_ref);
+
+ //hack the puppet type to normal, where it doesn't grant invisibility
+ if (puppetmarker) {
+ puppetmarker->Parameter2 = 0;
+ }
+ }
+ }
return FX_NOT_APPLIED;
}
// 0x89 ChantBadNonCumulative
int fx_set_chantbad_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_chantbad_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_chantbad_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (STATE_GET (STATE_CHANTBAD) ) //chant is non cumulative
return FX_NOT_APPLIED;
@@ -3703,7 +4042,7 @@ int fx_set_chantbad_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x8A AnimationStateChange
int fx_animation_stance (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_animation_stance (%2d): Stance: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_animation_stance(%2d): Stance: %d", fx->Opcode, fx->Parameter2);
//this effect works only on living actors
if ( !STATE_GET(STATE_DEAD) ) {
@@ -3715,11 +4054,14 @@ int fx_animation_stance (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x8B DisplayString
// gemrb extension: rgb colour for displaystring
// gemrb extension: resource may be an strref list (src or 2da)
-static EffectRef fx_protection_from_display_string_ref = { "Protection:String", -1 };
int fx_display_string (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_display_string (%2d): StrRef: %d\n", fx->Opcode, fx->Parameter1 );
+ if(0) print("fx_display_string(%2d): StrRef: %d", fx->Opcode, fx->Parameter1);
+ if (STATE_GET(STATE_DEAD) ) {
+ return FX_NOT_APPLIED;
+ }
+
if(fx->Resource[0]) {
//TODO: create a single list reader that handles src and 2da too
SrcVector *rndstr=LoadSrc(fx->Resource);
@@ -3736,11 +4078,11 @@ int fx_display_string (Scriptable* /*Owner*/, Actor* target, Effect* fx)
int cnt = rndstr2[0];
if (cnt) {
fx->Parameter1 = rndstr2[core->Roll(1,cnt,0)];
- }
+ }
}
if (!target->fxqueue.HasEffectWithParamPair(fx_protection_from_display_string_ref, fx->Parameter1, 0) ) {
- displaymsg->DisplayStringName(fx->Parameter1, fx->Parameter2?fx->Parameter2:0xffffff, target, IE_STR_SOUND|IE_STR_SPEECH);
+ displaymsg->DisplayStringName(fx->Parameter1, fx->Parameter2?fx->Parameter2:DMC_WHITE, target, IE_STR_SOUND|IE_STR_SPEECH);
}
return FX_NOT_APPLIED;
}
@@ -3749,9 +4091,9 @@ int fx_display_string (Scriptable* /*Owner*/, Actor* target, Effect* fx)
static const int ypos_by_direction[16]={10,10,10,0,-10,-10,-10,-10,-10,-10,-10,-10,0,10,10,10};
static const int xpos_by_direction[16]={0,-10,-12,-14,-16,-14,-12,-10,0,10,12,14,16,14,12,10};
-int fx_casting_glow (Scriptable* /*Owner*/, Actor* target, Effect* fx)
+int fx_casting_glow (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_casting_glow (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_casting_glow(%2d): Type: %d", fx->Opcode, fx->Parameter2);
if (cgcount<0) {
cgcount = core->ReadResRefTable("cgtable",casting_glows);
}
@@ -3781,14 +4123,23 @@ int fx_casting_glow (Scriptable* /*Owner*/, Actor* target, Effect* fx)
sca->SetDefaultDuration(10000);
}
map->AddVVCell(sca);
+ } else {
+ //simulate sparkle casting glows
+ Effect *newfx;
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_sparkle_ref, fx->Parameter2, 3);
+ core->ApplyEffect(newfx, target, Owner);
+
+ delete newfx;
}
+
return FX_NOT_APPLIED;
}
//0x8d VisualSpellHit
int fx_visual_spell_hit (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_visual_spell_hit (%2d): Target: %d Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_visual_spell_hit(%2d): Target: %d Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (shcount<0) {
shcount = core->ReadResRefTable("shtable",spell_hits);
}
@@ -3820,7 +4171,7 @@ int fx_visual_spell_hit (Scriptable* /*Owner*/, Actor* target, Effect* fx)
sca->PlayOnce();
map->AddVVCell(sca);
} else {
- printf("fx_visual_spell_hit: Unhandled Type: %d\n", fx->Parameter2);
+ print("fx_visual_spell_hit: Unhandled Type: %d", fx->Parameter2);
}
return FX_NOT_APPLIED;
}
@@ -3828,7 +4179,7 @@ int fx_visual_spell_hit (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0x8e Icon:Display
int fx_display_portrait_icon (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_display_string (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_display_string(%2d): Type: %d", fx->Opcode, fx->Parameter2);
target->AddPortraitIcon(fx->Parameter2);
return FX_APPLIED;
}
@@ -3836,7 +4187,7 @@ int fx_display_portrait_icon (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0x8f Item:CreateInSlot
int fx_create_item_in_slot (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_create_item_in_slot (%2d): Button: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_create_item_in_slot(%2d): Button: %d", fx->Opcode, fx->Parameter2);
//create item and set it in target's slot
target->inventory.SetSlotItemRes( fx->Resource, core->QuerySlot(fx->Parameter2), fx->Parameter1, fx->Parameter3, fx->Parameter4 );
if ((fx->TimingMode&0xff) == FX_DURATION_INSTANT_LIMITED) {
@@ -3852,7 +4203,7 @@ int fx_create_item_in_slot (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// different in iwd2 and the rest (maybe also in how: 0-7?)
int fx_disable_button (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_disable_button (%2d): Button: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_disable_button(%2d): Button: %d", fx->Opcode, fx->Parameter2);
// iwd2 has a flexible action bar, so there are more possible parameter values
// only values 0-5 match the bg2 constants (which map to ACT_*)
@@ -3862,7 +4213,6 @@ int fx_disable_button (Scriptable* /*Owner*/, Actor* target, Effect* fx)
} else {
STAT_BIT_OR( IE_DISABLEDBUTTON, 1<<fx->Parameter2 );
}
-
if (fx->FirstApply && target->GetStat(IE_EA) < EA_CONTROLLABLE) {
core->SetEventFlag(EF_ACTION);
}
@@ -3885,7 +4235,7 @@ static ieDword dsc_bits_iwd2[7]={1, 14, 6, 2, 4, 8, 16};
static ieDword dsc_bits_bg2[7]={1, 4, 2, 8, 16, 14, 6};
int fx_disable_spellcasting (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_disable_spellcasting (%2d): Button: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_disable_spellcasting(%2d): Button: %d", fx->Opcode, fx->Parameter2);
bool display_warning = false;
ieDword tmp = fx->Parameter2+1;
@@ -3897,7 +4247,7 @@ int fx_disable_spellcasting (Scriptable* /*Owner*/, Actor* target, Effect* fx)
case 1: // mage and cleric
case 2: // mage
if (target->spellbook.GetKnownSpellsCount(IE_IWD2_SPELL_BARD, 0)) display_warning = true;
- if (target->spellbook.GetKnownSpellsCount(IE_IWD2_SPELL_SORCEROR, 0)) display_warning = true;
+ if (target->spellbook.GetKnownSpellsCount(IE_IWD2_SPELL_SORCERER, 0)) display_warning = true;
if (target->spellbook.GetKnownSpellsCount(IE_IWD2_SPELL_WIZARD, 0)) display_warning = true;
break;
}
@@ -3913,12 +4263,12 @@ int fx_disable_spellcasting (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//1 -> 2 (cleric)
//2 -> 8 (innate)
//3 -> 16 (class)
- if (tmp<31) {
+ if (tmp<7) {
STAT_BIT_OR(IE_CASTING, dsc_bits_bg2[tmp] );
}
}
- if (fx->FirstApply && display_warning && target->GetStat(IE_EA) < EA_CONTROLLABLE) {
- displaymsg->DisplayConstantStringName(STR_DISABLEDMAGE, 0xff0000, target);
+ if (fx->FirstApply && target->GetStat(IE_EA) < EA_CONTROLLABLE) {
+ if (display_warning) displaymsg->DisplayConstantStringName(STR_DISABLEDMAGE, DMC_RED, target);
core->SetEventFlag(EF_ACTION);
}
return FX_APPLIED;
@@ -3927,55 +4277,54 @@ int fx_disable_spellcasting (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0x92 Spell:Cast
int fx_cast_spell (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cast_spell (%2d): Resource:%s Mode: %d\n", fx->Opcode, fx->Resource, fx->Parameter2 );
- if (fx->Parameter2) {
- //apply spell on target
- core->ApplySpell(fx->Resource, target, Owner, fx->Parameter1);
-
- // give feedback: Caster - spellname : target
- char tmp[100];
- Spell *spl = gamedata->GetSpell(fx->Resource);
- if (spl) {
- snprintf(tmp, sizeof(tmp), "%s : %s", core->GetString(spl->SpellName), target->GetName(-1));
- displaymsg->DisplayStringName(tmp, 0xffffff, Owner);
+ if(0) print("fx_cast_spell(%2d): Resource:%s Mode: %d", fx->Opcode, fx->Resource, fx->Parameter2);
+ if (Owner->Type == ST_ACTOR) {
+ Actor *owner = (Actor *) Owner;
+ // prevent eg. True Sight continuing after death
+ if (!owner->ValidTarget(GA_NO_DEAD)) {
+ return FX_NOT_APPLIED;
}
- } else {
- // save the current spell ref, so the rest of its effects can be applied afterwards
- ieResRef OldSpellResRef;
- memcpy(OldSpellResRef, Owner->SpellResRef, sizeof(OldSpellResRef));
- Owner->SetSpellResRef(fx->Resource);
- //cast spell on target
- Owner->CastSpell(fx->Resource, target, false);
- //actually finish casting (if this is not good enough, use an action???)
- Owner->CastSpellEnd(fx->Parameter1);
- Owner->SetSpellResRef(OldSpellResRef);
}
+ // save the current spell ref, so the rest of its effects can be applied afterwards
+ ieResRef OldSpellResRef;
+ memcpy(OldSpellResRef, Owner->SpellResRef, sizeof(OldSpellResRef));
+ Owner->SetSpellResRef(fx->Resource);
+ //cast spell on target
+ //flags: deplete, instant, no interrupt
+ Owner->CastSpell(target, false, fx->Parameter2==1, true);
+ //actually finish casting (if this is not good enough, use an action???)
+ //flag: no casting animation
+ Owner->CastSpellEnd(fx->Parameter1, fx->Parameter2);
+ Owner->SetSpellResRef(OldSpellResRef);
+
return FX_NOT_APPLIED;
}
// 0x93 Spell:Learn
int fx_learn_spell (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_learn_spell (%2d): Resource:%s Mode: %d\n", fx->Opcode, fx->Resource, fx->Parameter2 );
+ if(0) print("fx_learn_spell(%2d): Resource:%s Flags: %d Mode: %d", fx->Opcode, fx->Resource, fx->Parameter1, fx->Parameter2);
//parameter1 is unused, gemrb lets you to make it not give XP
//probably we should also let this via a game flag if we want
//full compatibility with bg1
//parameter2 is used in bg1 and pst to specify the spell type; bg2 and iwd2 figure it out from the resource
- target->LearnSpell(fx->Resource, fx->Parameter1);
+ //LS_STATS is on by default (int check)
+ int x= target->LearnSpell(fx->Resource, fx->Parameter1^LS_STATS);
+ print("Learnspell returned: %d", x);
return FX_NOT_APPLIED;
}
// 0x94 Spell:CastSpellPoint
int fx_cast_spell_point (Scriptable* Owner, Actor* /*target*/, Effect* fx)
{
- if (0) printf( "fx_cast_spell_point (%2d): Resource:%s Mode: %d\n", fx->Opcode, fx->Resource, fx->Parameter2 );
+ if(0) print("fx_cast_spell_point(%2d): Resource:%s Mode: %d", fx->Opcode, fx->Resource, fx->Parameter2);
// save the current spell ref, so the rest of its effects can be applied afterwards
ieResRef OldSpellResRef;
memcpy(OldSpellResRef, Owner->SpellResRef, sizeof(OldSpellResRef));
Owner->SetSpellResRef(fx->Resource);
Point p(fx->PosX, fx->PosY);
- Owner->CastSpellPoint(fx->Resource, p, false);
+ Owner->CastSpellPoint(p, false);
//actually finish casting (if this is not good enough, use an action???)
- Owner->CastSpellPointEnd(fx->Parameter1);
+ Owner->CastSpellPointEnd(fx->Parameter1, fx->Parameter2);
Owner->SetSpellResRef(OldSpellResRef);
return FX_NOT_APPLIED;
}
@@ -3983,7 +4332,7 @@ int fx_cast_spell_point (Scriptable* Owner, Actor* /*target*/, Effect* fx)
// 0x95 Identify
int fx_identify (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_identify (%2d): Resource:%s Mode: %d\n", fx->Opcode, fx->Resource, fx->Parameter2 );
+ if(0) print("fx_identify(%2d): Resource:%s Mode: %d", fx->Opcode, fx->Resource, fx->Parameter2);
if (target->InParty) {
BASE_SET (IE_IDENTIFYMODE, 1);
core->SetEventFlag(EF_IDENTIFY);
@@ -4000,23 +4349,28 @@ int fx_identify (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 3 - detect secret doors by luck
int fx_find_traps (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_find_traps (%2d)\n", fx->Opcode );
+ if(0) print("fx_find_traps(%2d)", fx->Opcode);
//reveal trapped containers, doors, triggers that are in the visible range
+ ieDword id = target->GetGlobalID();
ieDword range = target->GetStat(IE_VISUALRANGE)*10;
ieDword skill;
bool detecttraps = true;
switch(fx->Parameter2) {
case 1:
+ //find traps
skill = target->GetStat(IE_TRAPS);
- break; //find traps
+ break;
case 3:
//detect secret doors
- skill = target->LuckyRoll(1, 100, 0, 0);
+ //FIXME: is 1d100 the real base value?
+ skill = target->LuckyRoll(1, 100, 0, 0)+core->ResolveStatBonus(target, "dstable");
detecttraps = false;
break;
case 2:
+ //automatic secret door detection
detecttraps = false;
+ //fall through is intentional here
default:
//automatic find traps
skill = 256;
@@ -4031,11 +4385,11 @@ int fx_find_traps (Scriptable* /*Owner*/, Actor* target, Effect* fx)
if (!door)
break;
if (Distance(door->Pos, target->Pos)<range) {
- if (detecttraps) {
+ door->TryDetectSecret(skill, id);
+ if (detecttraps && door->Visible()) {
//when was door trap noticed
- door->DetectTrap(skill);
+ door->DetectTrap(skill, id);
}
- door->TryDetectSecret(skill);
}
}
@@ -4050,7 +4404,7 @@ int fx_find_traps (Scriptable* /*Owner*/, Actor* target, Effect* fx)
break;
if (Distance(container->Pos, target->Pos)<range) {
//when was door trap noticed
- container->DetectTrap(skill);
+ container->DetectTrap(skill, id);
}
}
@@ -4062,7 +4416,7 @@ int fx_find_traps (Scriptable* /*Owner*/, Actor* target, Effect* fx)
break;
if (Distance(trap->Pos, target->Pos)<range) {
//when was door trap noticed
- trap->DetectTrap(skill);
+ trap->DetectTrap(skill, id);
}
}
@@ -4072,7 +4426,7 @@ int fx_find_traps (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x97 ReplaceCreature
int fx_replace_creature (Scriptable* Owner, Actor* target, Effect *fx)
{
- if (0) printf( "fx_replace_creature (%2d): Resource: %s\n", fx->Opcode, fx->Resource );
+ if(0) print("fx_replace_creature(%2d): Resource: %s", fx->Opcode, fx->Resource);
//this safeguard exists in the original engine too
if (!gamedata->Exists(fx->Resource,IE_CRE_CLASS_ID)) {
@@ -4107,20 +4461,22 @@ int fx_replace_creature (Scriptable* Owner, Actor* target, Effect *fx)
// 0x98 PlayMovie
int fx_play_movie (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
{
- if (0) printf( "fx_play_movie (%2d): Resource: %s\n", fx->Opcode, fx->Resource );
+ if(0) print("fx_play_movie(%2d): Resource: %s", fx->Opcode, fx->Resource);
core->PlayMovie (fx->Resource);
return FX_NOT_APPLIED;
}
// 0x99 Overlay:Sanctuary
-#define ICE_GRADIENT 71
-
static const ieDword fullwhite[7]={ICE_GRADIENT,ICE_GRADIENT,ICE_GRADIENT,ICE_GRADIENT,ICE_GRADIENT,ICE_GRADIENT,ICE_GRADIENT};
int fx_set_sanctuary_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
//iwd and bg are a bit different, but we solve the whole stuff in a single opcode
- if (0) printf( "fx_set_sanctuary_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
- if (target->HasSpellState(SS_SANCTUARY)) return FX_NOT_APPLIED;
+ if(0) print("fx_set_sanctuary_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+
+ // don't set the state twice
+ // SetSpellState will also check if it is already set first
+ if (target->SetSpellState(SS_SANCTUARY)) return FX_NOT_APPLIED;
+
if (!fx->Parameter2) {
fx->Parameter2=1;
}
@@ -4128,8 +4484,7 @@ int fx_set_sanctuary_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
STAT_SET_PCF( IE_SANCTUARY, fx->Parameter2);
//a rare event, but this effect gives more in bg2 than in iwd2
//so we use this flag
- if (!enhanced_effects)
- {
+ if (!enhanced_effects) {
target->SetLockedPalette(fullwhite);
}
return FX_APPLIED;
@@ -4138,7 +4493,7 @@ int fx_set_sanctuary_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x9a Overlay:Entangle
int fx_set_entangle_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_entangle_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_entangle_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//iwd2 effects that disable entangle
if (target->HasSpellState(SS_FREEACTION)) return FX_NOT_APPLIED;
@@ -4154,7 +4509,11 @@ int fx_set_entangle_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x9b Overlay:MinorGlobe
int fx_set_minorglobe_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_minorglobe_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_minorglobe_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+ //the globe vanishes on death
+ if (STATE_GET(STATE_DEAD) ) {
+ return FX_NOT_APPLIED;
+ }
//the resisted levels are stored in minor globe (bit 2-)
//the globe effect is stored in the first bit
STAT_BIT_OR_PCF( IE_MINORGLOBE, 1);
@@ -4164,7 +4523,7 @@ int fx_set_minorglobe_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x9c Overlay:ShieldGlobe
int fx_set_shieldglobe_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_shieldglobe_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_shieldglobe_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//the shield vanishes on dead
if (STATE_GET(STATE_DEAD) ) {
return FX_NOT_APPLIED;
@@ -4176,7 +4535,7 @@ int fx_set_shieldglobe_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x9d Overlay:Web
int fx_set_web_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_web_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_web_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//iwd2 effects that disable web
if (target->HasSpellState(SS_FREEACTION)) return FX_NOT_APPLIED;
@@ -4192,7 +4551,7 @@ int fx_set_web_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x9e Overlay:Grease
int fx_set_grease_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_grease_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_grease_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//iwd2 effects that disable grease
if (target->HasSpellState(SS_FREEACTION)) return FX_NOT_APPLIED;
@@ -4207,7 +4566,7 @@ int fx_set_grease_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x9f MirrorImageModifier
int fx_mirror_image_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_mirror_image_modifier (%2d): Mod: %d\n", fx->Opcode, fx->Parameter1 );
+ if(0) print("fx_mirror_image_modifier(%2d): Mod: %d", fx->Opcode, fx->Parameter1);
if (STATE_GET(STATE_DEAD) ) {
return FX_NOT_APPLIED;
}
@@ -4231,33 +4590,29 @@ int fx_mirror_image_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
}
// 0xa0 Cure:Sanctuary
-static EffectRef fx_sanctuary_state_ref = { "Overlay:Sanctuary", -1 };
int fx_cure_sanctuary_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cure_sanctuary_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_cure_sanctuary_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_SET( IE_SANCTUARY, 0);
target->fxqueue.RemoveAllEffects(fx_sanctuary_state_ref);
return FX_NOT_APPLIED;
}
// 0xa1 Cure:Panic
-static EffectRef fx_set_panic_state_ref = { "State:Panic", -1 };
int fx_cure_panic_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cure_panic_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_cure_panic_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
BASE_STATE_CURE( STATE_PANIC );
target->fxqueue.RemoveAllEffects(fx_set_panic_state_ref);
return FX_NOT_APPLIED;
}
// 0xa2 Cure:Hold
-static EffectRef fx_hold_creature_ref = { "State:Hold", -1 };
-
int fx_cure_hold_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cure_hold_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_cure_hold_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//note that this effect doesn't remove 185 (another hold effect)
target->fxqueue.RemoveAllEffects( fx_hold_creature_ref );
target->fxqueue.RemoveAllEffects(fx_hold_creature_no_icon_ref);
@@ -4266,22 +4621,19 @@ int fx_cure_hold_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
}
// 0xa3 FreeAction
-static EffectRef fx_movement_modifier_ref = { "MovementRateModifier2", -1 };
-
int fx_cure_slow_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cure_slow_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_cure_slow_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
target->fxqueue.RemoveAllEffects( fx_movement_modifier_ref );
// STATE_CURE( STATE_SLOWED );
return FX_NOT_APPLIED;
}
// 0xa4 Cure:Intoxication
-static EffectRef fx_intoxication_ref = { "IntoxicationModifier", -1 };
int fx_cure_intoxication (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cure_intoxication (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_cure_intoxication(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
target->fxqueue.RemoveAllEffects( fx_intoxication_ref );
BASE_SET(IE_INTOXICATION,0);
return FX_NOT_APPLIED;
@@ -4290,7 +4642,7 @@ int fx_cure_intoxication (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0xa5 PauseTarget
int fx_pause_target (Scriptable* /*Owner*/, Actor * target, Effect* fx)
{
- if (0) printf( "fx_pause_target (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_pause_target(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_CASTERHOLD );
return FX_PERMANENT;
}
@@ -4298,7 +4650,7 @@ int fx_pause_target (Scriptable* /*Owner*/, Actor * target, Effect* fx)
// 0xa6 MagicResistanceModifier
int fx_magic_resistance_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_magic_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_magic_resistance_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_RESISTMAGIC );
return FX_APPLIED;
@@ -4307,7 +4659,7 @@ int fx_magic_resistance_modifier (Scriptable* /*Owner*/, Actor* target, Effect*
// 0xa7 MissileHitModifier
int fx_missile_to_hit_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_missile_to_hit_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_missile_to_hit_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_MISSILEHITBONUS );
return FX_APPLIED;
@@ -4318,10 +4670,10 @@ int fx_missile_to_hit_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx
// removes creature specified by resource key (gemrb extension)
int fx_remove_creature (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_remove_creature (%2d)\n", fx->Opcode);
+ if(0) print("fx_remove_creature(%2d)", fx->Opcode);
Map *map = NULL;
-
+
if (target) {
map = target->GetCurrentArea();
}
@@ -4331,7 +4683,11 @@ int fx_remove_creature (Scriptable* /*Owner*/, Actor* target, Effect* fx)
Actor *actor = target;
if (fx->Resource[0]) {
- actor = map->GetActorByResource(fx->Resource);
+ if (map) {
+ actor = map->GetActorByResource(fx->Resource);
+ } else {
+ actor = NULL;
+ }
}
if (actor) {
@@ -4345,7 +4701,7 @@ int fx_remove_creature (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0xa9 Icon:Disable
int fx_disable_portrait_icon (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_disable_portrait_icon (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_disable_portrait_icon(%2d): Type: %d", fx->Opcode, fx->Parameter2);
target->DisablePortraitIcon(fx->Parameter2);
return FX_APPLIED;
}
@@ -4353,9 +4709,10 @@ int fx_disable_portrait_icon (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0xaa DamageAnimation
int fx_damage_animation (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_damage_animation (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_damage_animation(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//Parameter1 is a gemrb extension
+ //Parameter2's high byte has effect on critical damage animations (PST compatibility hack)
target->PlayDamageAnimation(fx->Parameter2, !fx->Parameter1);
return FX_NOT_APPLIED;
}
@@ -4363,8 +4720,8 @@ int fx_damage_animation (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0xab Spell:Add
int fx_add_innate (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_add_innate (%2d): Resource: %s Mode: %d\n", fx->Opcode, fx->Resource, fx->Parameter2 );
- target->LearnSpell(fx->Resource, fx->Parameter2^LS_MEMO);
+ if(0) print("fx_add_innate(%2d): Resource: %s Mode: %d", fx->Opcode, fx->Resource, fx->Parameter2);
+ target->LearnSpell(fx->Resource, fx->Parameter2);
//this is an instant, so it shouldn't stick
return FX_NOT_APPLIED;
}
@@ -4373,7 +4730,7 @@ int fx_add_innate (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//gemrb extension: deplete spell by resref
int fx_remove_spell (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_remove_spell (%2d): Resource: %s Type:%d\n", fx->Opcode, fx->Resource, fx->Parameter2);
+ if(0) print("fx_remove_spell(%2d): Resource: %s Type:%d", fx->Opcode, fx->Resource, fx->Parameter2);
switch (fx->Parameter2) {
default:
target->spellbook.RemoveSpell(fx->Resource);
@@ -4394,7 +4751,7 @@ int fx_remove_spell (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0xad PoisonResistanceModifier
int fx_poison_resistance_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_poison_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_poison_resistance_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_RESISTPOISON );
return FX_APPLIED;
@@ -4403,7 +4760,7 @@ int fx_poison_resistance_modifier (Scriptable* /*Owner*/, Actor* target, Effect*
//0xae PlaySound
int fx_playsound (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_playsound (%s)", fx->Resource );
+ if (0) print( "fx_playsound (%s)", fx->Resource );
//this is probably inaccurate
if (target) {
core->GetAudioDrv()->Play(fx->Resource, target->Pos.x, target->Pos.y);
@@ -4418,7 +4775,7 @@ int fx_playsound (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0xfb State:Hold4
int fx_hold_creature_no_icon (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_hold_creature_no_icon (%2d): Value: %d, IDS: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_hold_creature_no_icon(%2d): Value: %d, IDS: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//actually the original engine just skips this effect if the target is dead
if ( STATE_GET(STATE_DEAD) ) {
@@ -4439,7 +4796,7 @@ int fx_hold_creature_no_icon (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//(0x6d/0x1a8 for iwd2)
int fx_hold_creature (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_hold_creature (%2d): Value: %d, IDS: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_hold_creature(%2d): Value: %d, IDS: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//actually the original engine just skips this effect if the target is dead
if ( STATE_GET(STATE_DEAD) ) {
@@ -4463,37 +4820,50 @@ int fx_hold_creature (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0xb0 see: fx_movement_modifier
//0xb1 ApplyEffect
-int fx_apply_effect (Scriptable* /*Owner*/, Actor* target, Effect* fx)
+int fx_apply_effect (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_apply_effect (%2d) %s", fx->Opcode, fx->Resource );
+ if (0) print( "fx_apply_effect (%2d) %s", fx->Opcode, fx->Resource );
//this effect executes a file effect in place of this effect
//the file effect inherits the target and the timingmode, but gets
//a new chance to roll percents
- int ret = FX_NOT_APPLIED;
- if (!target) {
- return ret;
+ if (target && !EffectQueue::match_ids( target, fx->Parameter2, fx->Parameter1) ) {
+ return FX_NOT_APPLIED;
}
- if (EffectQueue::match_ids( target, fx->Parameter2, fx->Parameter1) ) {
- Point p(fx->PosX, fx->PosY);
- //apply effect, if the effect is a goner, then kill
- //this effect too
- Effect *newfx = core->GetEffect(fx->Resource, fx->Power, p);
- if (newfx) {
- Effect *myfx = new Effect;
- memcpy(myfx, newfx, sizeof(Effect));
- myfx->random_value = core->Roll(1,100,-1);
- myfx->Target = FX_TARGET_PRESET;
- myfx->TimingMode = fx->TimingMode;
- myfx->Duration = fx->Duration;
- myfx->CasterID = fx->CasterID;
- ret = target->fxqueue.ApplyEffect(target, myfx, fx->FirstApply, !fx->Parameter3);
- fx->Parameter3 = 1;
- delete myfx;
+ Point p(fx->PosX, fx->PosY);
+
+ //apply effect, if the effect is a goner, then kill
+ //this effect too
+ Effect *newfx = core->GetEffect(fx->Resource, fx->Power, p);
+ if (!newfx)
+ return FX_NOT_APPLIED;
+
+ Effect *myfx = new Effect;
+ memcpy(myfx, newfx, sizeof(Effect));
+ myfx->random_value = core->Roll(1,100,-1);
+ myfx->Target = FX_TARGET_PRESET;
+ myfx->TimingMode = fx->TimingMode;
+ myfx->Duration = fx->Duration;
+ myfx->CasterID = fx->CasterID;
+
+ int ret;
+ if (target) {
+ if (fx->FirstApply && fx->IsVariable) {
+ //hack to entirely replace this effect with the applied effect, this is required for some generic effects
+ //that must be put directly in the effect queue to have any impact (to be counted by BonusAgainstCreature, etc)
+ target->fxqueue.AddEffect(myfx);
+ return FX_NOT_APPLIED;
}
- //newfx is a borrowed reference don't delete it
+ ret = target->fxqueue.ApplyEffect(target, myfx, fx->FirstApply, !fx->Parameter3);
+ } else {
+ EffectQueue fxqueue;
+ fxqueue.SetOwner(Owner);
+ ret = fxqueue.ApplyEffect(NULL, myfx, fx->FirstApply, !fx->Parameter3);
}
+
+ fx->Parameter3 = 1;
+ delete myfx;
return ret;
}
@@ -4505,7 +4875,7 @@ int fx_apply_effect (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// b6 generic effect ApplyEffectItem
int fx_apply_effect_item (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf("fx_apply_effect_item (%2d) (%.8s)\n", fx->Opcode, fx->Resource);
+ if(0) print("fx_apply_effect_item(%2d)(%.8s)", fx->Opcode, fx->Resource);
if (target->inventory.HasItem(fx->Resource, 0) ) {
core->ApplySpell(fx->Resource2, target, Owner, fx->Parameter1);
return FX_NOT_APPLIED;
@@ -4516,7 +4886,7 @@ int fx_apply_effect_item (Scriptable* Owner, Actor* target, Effect* fx)
// b7 generic effect ApplyEffectItemType
int fx_apply_effect_item_type (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf("fx_apply_effect_item (%2d), Type: %d\n", fx->Opcode, fx->Parameter2);
+ if(0) print("fx_apply_effect_item(%2d), Type: %d", fx->Opcode, fx->Parameter2);
if (target->inventory.HasItemType(fx->Parameter2) ) {
core->ApplySpell(fx->Resource, target, Owner, fx->Parameter1);
return FX_NOT_APPLIED;
@@ -4527,7 +4897,7 @@ int fx_apply_effect_item_type (Scriptable* Owner, Actor* target, Effect* fx)
// b8 DontJumpModifier
int fx_dontjump_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_dontjump_modifier (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_dontjump_modifier(%2d): Type: %d", fx->Opcode, fx->Parameter2);
STAT_SET( IE_DONOTJUMP, fx->Parameter2 );
return FX_APPLIED;
}
@@ -4537,25 +4907,50 @@ int fx_dontjump_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0xba MoveToArea
int fx_move_to_area (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_move_to_area (%2d) %s", fx->Opcode, fx->Resource );
- //delay effect until the target has finished the previous move to an area
- //hopefully this fixes an evil bug
- Map *map = target->GetCurrentArea();
- if (!map || !map->HasActor(target)) {
- //stay around for the next evaluation
- return FX_APPLIED;
+ if (0) print( "fx_move_to_area (%2d) %s", fx->Opcode, fx->Resource );
+
+ Game *game = core->GetGame();
+ //remove actor from current map, and set destination map
+ if (fx->FirstApply) {
+ //if current area is different from target area
+ if (strnicmp(game->CurrentArea, fx->Resource, 8) ) {
+ //make global
+ game->AddNPC( target );
+ //remove from current area
+ Map *map = target->GetCurrentArea();
+ if (map) {
+ map->RemoveActor( target );
+ }
+ //set the destination area
+ strnuprcpy(target->Area, fx->Resource, 8);
+ return FX_APPLIED;
+ }
}
- Point p(fx->PosX,fx->PosY);
- MoveBetweenAreasCore(target, fx->Resource, p, fx->Parameter2, true);
- //this effect doesn't stick
- return FX_NOT_APPLIED;
+
+ if (!strnicmp(game->CurrentArea, fx->Resource, 8) ) {
+ //UnMakeGlobal only if it was not in the party
+ int slot = core->GetGame()->InStore( target );
+ if (slot >= 0) {
+ game->DelNPC( slot );
+ if (!target->InParty) {
+ target->SetPersistent(-1);
+ }
+ }
+ //move to area
+ Point p(fx->PosX,fx->PosY);
+ MoveBetweenAreasCore(target, fx->Resource, p, fx->Parameter2, true);
+ //remove the effect now
+ return FX_NOT_APPLIED;
+ }
+ //stick around, waiting for the time
+ return FX_APPLIED;
}
// 0xbb Variable:StoreLocalVariable
int fx_local_variable (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
//this is a hack, the variable name spreads across the resources
- if (0) printf( "fx_local_variable (%2d) %s=%d", fx->Opcode, fx->Resource, fx->Parameter1 );
+ if (0) print( "fx_local_variable (%2d) %s=%d", fx->Opcode, fx->Resource, fx->Parameter1 );
target->locals->SetAt(fx->Resource, fx->Parameter1);
//local variable effects are not applied, they will be resaved though
return FX_NOT_APPLIED;
@@ -4564,7 +4959,7 @@ int fx_local_variable (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0xbc AuraCleansingModifier
int fx_auracleansing_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_auracleansing_modifier (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_auracleansing_modifier(%2d): Type: %d", fx->Opcode, fx->Parameter2);
STAT_SET( IE_AURACLEANSING, fx->Parameter2 );
return FX_APPLIED;
}
@@ -4572,7 +4967,7 @@ int fx_auracleansing_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0xbd CastingSpeedModifier
int fx_castingspeed_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_castingspeed_modifier (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_castingspeed_modifier(%2d): Type: %d", fx->Opcode, fx->Parameter2);
STAT_MOD( IE_MENTALSPEED );
return FX_APPLIED;
}
@@ -4580,7 +4975,7 @@ int fx_castingspeed_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0xbe PhysicalSpeedModifier
int fx_attackspeed_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_attackspeed_modifier (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_attackspeed_modifier(%2d): Type: %d", fx->Opcode, fx->Parameter2);
STAT_MOD( IE_PHYSICALSPEED );
return FX_APPLIED;
}
@@ -4589,7 +4984,7 @@ int fx_attackspeed_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// gemrb extension: if the resource key is set, apply param1 as a percentual modifier
int fx_castinglevel_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_castinglevel_modifier (%2d) Value:%d Type:%d", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if (0) print( "fx_castinglevel_modifier (%2d) Value:%d Type:%d", fx->Opcode, fx->Parameter1, fx->Parameter2 );
switch (fx->Parameter2) {
case 0:
if (fx->Resource[0]) {
@@ -4618,15 +5013,75 @@ int fx_castinglevel_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
#define FAMILIAR_ALIGNMENT 1
#define FAMILIAR_RESOURCE 2
-static EffectRef fx_familiar_constitution_loss_ref = { "FamiliarBond", -1 };
-static EffectRef fx_familiar_marker_ref = { "FamiliarMarker", -1 };
-static EffectRef fx_maximum_hp_modifier_ref = { "MaximumHPModifier", -1 };
+//returns the familiar if there was no error
+Actor *GetFamiliar(Scriptable *Owner, Actor *target, Effect *fx, ieResRef resource)
+{
+ //summon familiar
+ Actor *fam = gamedata->GetCreature(resource);
+ if (!fam) {
+ return NULL;
+ }
+ fam->SetBase(IE_EA, EA_FAMILIAR);
+
+ //when upgrading, there is no need for the script to be triggered again, so this isn't a problem
+ if (Owner) {
+ fam->LastSummoner = Owner->GetGlobalID();
+ }
+
+ Map *map = target->GetCurrentArea();
+ if (!map) return NULL;
+
+ map->AddActor(fam, true);
+ Point p(fx->PosX, fx->PosY);
+ fam->SetPosition(p, true, 0);
+ fam->RefreshEffects(NULL);
+ //Make the familiar an NPC (MoveGlobal needs this)
+ Game *game = core->GetGame();
+ game->AddNPC(fam);
+
+ //Add some essential effects
+ Effect *newfx = EffectQueue::CreateEffect(fx_familiar_constitution_loss_ref, fam->GetBase(IE_HITPOINTS)/2, 0, FX_DURATION_INSTANT_PERMANENT);
+ core->ApplyEffect(newfx, fam, fam);
+ delete newfx;
+
+ //the familiar marker needs to be set to 2 in case of ToB
+ ieDword fm = 0;
+ if (game->Expansion==5) {
+ fm = 2;
+ }
+ newfx = EffectQueue::CreateEffect(fx_familiar_marker_ref, fm, 0, FX_DURATION_INSTANT_PERMANENT);
+ core->ApplyEffect(newfx, fam, fam);
+ delete newfx;
+
+ //maximum hp bonus of half the familiar's hp, there is no hp new bonus upgrade when upgrading familiar
+ //this is a bug even in the original engine, so I don't care
+ if (Owner) {
+ newfx = EffectQueue::CreateEffect(fx_maximum_hp_modifier_ref, fam->GetBase(IE_HITPOINTS)/2, MOD_ADDITIVE, FX_DURATION_INSTANT_PERMANENT);
+ core->ApplyEffect(newfx, (Actor *) Owner, Owner);
+ delete newfx;
+ }
+
+ if (fx->Resource2[0]) {
+ ScriptedAnimation* vvc = gamedata->GetScriptedAnimation(fx->Resource2, false);
+ if (vvc) {
+ //This is the final position of the summoned creature
+ //not the original target point
+ vvc->XPos=fam->Pos.x;
+ vvc->YPos=fam->Pos.y;
+ //force vvc to play only once
+ vvc->PlayOnce();
+ map->AddVVCell( vvc );
+ }
+ }
+
+ return fam;
+}
int fx_find_familiar (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_find_familiar (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_find_familiar(%2d): Type: %d", fx->Opcode, fx->Parameter2);
- if (!target) {
+ if (!target || !Owner) {
return FX_NOT_APPLIED;
}
@@ -4636,20 +5091,19 @@ int fx_find_familiar (Scriptable* Owner, Actor* target, Effect* fx)
}
Game *game = core->GetGame();
- //FIXME: the familiar block field is not saved in the game and not set when the
+ //FIXME: the familiar block field is not saved in the game and not set when the
//familiar is itemized, so a game reload will clear it (see how this is done in original)
if (game->familiarBlock) {
- displaymsg->DisplayConstantStringName(STR_FAMBLOCK, 0xff0000, target);
+ displaymsg->DisplayConstantStringName(STR_FAMBLOCK, DMC_RED, target);
return FX_NOT_APPLIED;
}
//The protagonist is ALWAYS in the first slot
if (game->GetPC(0, false)!=target) {
- displaymsg->DisplayConstantStringName(STR_FAMPROTAGONIST, 0xff0000, target);
+ displaymsg->DisplayConstantStringName(STR_FAMPROTAGONIST, DMC_RED, target);
return FX_NOT_APPLIED;
}
-
if (fx->Parameter2!=FAMILIAR_RESOURCE) {
ieDword alignment;
@@ -4662,61 +5116,24 @@ int fx_find_familiar (Scriptable* Owner, Actor* target, Effect* fx)
if (alignment>8) {
return FX_NOT_APPLIED;
}
- memcpy(fx->Resource, core->GetGame()->Familiars[alignment],sizeof(ieResRef) );
- fx->Parameter2=FAMILIAR_RESOURCE;
- }
+ Game *game = core->GetGame();
- //summon familiar with fx->Resource
- Actor *fam = gamedata->GetCreature(fx->Resource);
- if (!fam) {
- return FX_NOT_APPLIED;
- }
- fam->SetBase(IE_EA, EA_FAMILIAR);
- fam->LastSummoner = Owner->GetGlobalID();
-
- Map *map = target->GetCurrentArea();
- map->AddActor(fam);
- Point p(fx->PosX, fx->PosY);
- fam->SetPosition(p, true, 0);
- fam->RefreshEffects(NULL);
-
- if (fx->Resource2[0]) {
- ScriptedAnimation* vvc = gamedata->GetScriptedAnimation(fx->Resource2, false);
- if (vvc) {
- //This is the final position of the summoned creature
- //not the original target point
- vvc->XPos=fam->Pos.x;
- vvc->YPos=fam->Pos.y;
- //force vvc to play only once
- vvc->PlayOnce();
- map->AddVVCell( vvc );
+ memcpy(fx->Resource, game->Familiars[alignment],sizeof(ieResRef) );
+ //ToB familiars
+ if (game->Expansion==5) {
+ strncat(fx->Resource,"25",8);
}
+ fx->Parameter2=FAMILIAR_RESOURCE;
}
- //Make the familiar an NPC (MoveGlobal needs this)
- core->GetGame()->AddNPC(fam);
-
- //Add some essential effects
- Effect *newfx = EffectQueue::CreateEffect(fx_familiar_constitution_loss_ref, fam->GetBase(IE_HITPOINTS)/2, 0, FX_DURATION_INSTANT_PERMANENT);
- core->ApplyEffect(newfx, fam, fam);
- delete newfx;
-
- newfx = EffectQueue::CreateEffect(fx_familiar_marker_ref, 0, 0, FX_DURATION_INSTANT_PERMANENT);
- core->ApplyEffect(newfx, fam, fam);
- delete newfx;
-
- //maximum hp bonus of half the familiar's hp
- newfx = EffectQueue::CreateEffect(fx_maximum_hp_modifier_ref, fam->GetBase(IE_HITPOINTS)/2, MOD_ADDITIVE, FX_DURATION_INSTANT_PERMANENT);
- core->ApplyEffect(newfx, (Actor *) Owner, Owner);
- delete newfx;
-
+ GetFamiliar(Owner, target, fx, fx->Resource);
return FX_NOT_APPLIED;
}
// 0xc1 InvisibleDetection
int fx_see_invisible_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_see_invisible_modifier (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_see_invisible_modifier(%2d): Type: %d", fx->Opcode, fx->Parameter2);
STAT_SET( IE_SEEINVISIBLE, fx->Parameter2 );
return FX_APPLIED;
}
@@ -4724,19 +5141,16 @@ int fx_see_invisible_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0xc2 IgnoreDialogPause
int fx_ignore_dialogpause_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_ignore_dialogpause_modifier (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_ignore_dialogpause_modifier(%2d): Type: %d", fx->Opcode, fx->Parameter2);
STAT_SET( IE_IGNOREDIALOGPAUSE, fx->Parameter2 );
return FX_APPLIED;
}
//0xc3 FamiliarBond
//when this effect's target dies it should incur damage on protagonist
-static EffectRef fx_damage_opcode_ref = { "Damage", -1 };
-static EffectRef fx_constitution_modifier_ref = { "ConstitutionModifier", -1 };
-
int fx_familiar_constitution_loss (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_familiar_constitution_loss (%2d): Loss: %d\n", fx->Opcode,(signed) fx->Parameter1 );
+ if(0) print("fx_familiar_constitution_loss(%2d): Loss: %d", fx->Opcode,(signed) fx->Parameter1);
if (! (STAT_GET(IE_STATE_ID)&STATE_NOSAVE)) {
return FX_APPLIED;
}
@@ -4756,7 +5170,7 @@ int fx_familiar_constitution_loss (Scriptable* /*Owner*/, Actor* target, Effect*
delete newfx;
//damage for half of the familiar's hitpoints
- newfx = EffectQueue::CreateEffect(fx_damage_opcode_ref, fx->Parameter1, DAMAGE_CRUSHING, FX_DURATION_INSTANT_PERMANENT);
+ newfx = EffectQueue::CreateEffect(fx_damage_opcode_ref, fx->Parameter1, DAMAGE_CRUSHING<<16, FX_DURATION_INSTANT_PERMANENT);
core->ApplyEffect(newfx, master, master);
delete newfx;
@@ -4766,28 +5180,55 @@ int fx_familiar_constitution_loss (Scriptable* /*Owner*/, Actor* target, Effect*
//0xc4 FamiliarMarker
int fx_familiar_marker (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_familiar_marker (%2d)\n", fx->Opcode );
+ if(0) print("fx_familiar_marker(%2d)", fx->Opcode);
+ if (!target) {
+ return FX_NOT_APPLIED;
+ }
+
+ Game *game = core->GetGame();
+
+ //upgrade familiar to ToB version
+ if ((fx->Parameter1!=2) && (game->Expansion == 5) ) {
+ ieResRef resource;
+
+ memset(resource,0,sizeof(resource));
+ memcpy(resource,target->GetScriptName(),6);
+ strncat(resource,"25",8);
+ //set this field, so the upgrade is triggered only once
+ fx->Parameter1 = 2;
+
+ //the NULL here is probably fine when upgrading, Owner (Original summoner) is not needed.
+ Actor *fam = GetFamiliar(NULL, target, fx, resource);
+
+ if (fam) {
+ //upgrade successful
+ //TODO: copy stuff from old familiar if needed
+ target->DestroySelf();
+ return FX_NOT_APPLIED;
+ }
+ }
+
if (! (STAT_GET(IE_STATE_ID)&STATE_NOSAVE)) {
- core->GetGame()->familiarBlock=true;
+ game->familiarBlock=true;
return FX_APPLIED;
}
- core->GetGame()->familiarBlock=false;
+ game->familiarBlock=false;
return FX_NOT_APPLIED;
}
// 0xc5 Bounce:Projectile
int fx_bounce_projectile (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_bounce_projectile (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
- STAT_BIT_OR( IE_BOUNCE, BNC_PROJECTILE );
+ if(0) print("fx_bounce_projectile(%2d): Type: %d", fx->Opcode, fx->Parameter2);
+ STAT_BIT_OR_PCF( IE_BOUNCE, BNC_PROJECTILE );
return FX_APPLIED;
}
// 0xc6 Bounce:Opcode
int fx_bounce_opcode (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_bounce_opcode (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
- STAT_BIT_OR( IE_BOUNCE, BNC_OPCODE );
+ if(0) print("fx_bounce_opcode(%2d): Type: %d", fx->Opcode, fx->Parameter2);
+ STAT_BIT_OR_PCF( IE_BOUNCE, BNC_OPCODE );
target->AddPortraitIcon(PI_BOUNCE2);
return FX_APPLIED;
}
@@ -4795,8 +5236,8 @@ int fx_bounce_opcode (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0xc7 Bounce:SpellLevel
int fx_bounce_spelllevel (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_bounce_spellevel (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
- STAT_BIT_OR( IE_BOUNCE, BNC_LEVEL );
+ if(0) print("fx_bounce_spellevel(%2d): Type: %d", fx->Opcode, fx->Parameter2);
+ STAT_BIT_OR_PCF( IE_BOUNCE, BNC_LEVEL );
target->AddPortraitIcon(PI_BOUNCE2);
return FX_APPLIED;
}
@@ -4804,8 +5245,13 @@ int fx_bounce_spelllevel (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0xc8 Bounce:SpellLevelDec
int fx_bounce_spelllevel_dec (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_bounce_spellevel_dec (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
- STAT_BIT_OR( IE_BOUNCE, BNC_LEVEL_DEC );
+ if(0) print("fx_bounce_spellevel_dec(%2d): Type: %d", fx->Opcode, fx->Parameter2);
+ if (fx->Parameter1<1) {
+ PlayRemoveEffect("EFF_E02", target, fx);
+ return FX_NOT_APPLIED;
+ }
+
+ STAT_BIT_OR_PCF( IE_BOUNCE, BNC_LEVEL_DEC );
target->AddPortraitIcon(PI_BOUNCE);
return FX_APPLIED;
}
@@ -4813,7 +5259,11 @@ int fx_bounce_spelllevel_dec (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0xc9 Protection:SpellLevelDec
int fx_protection_spelllevel_dec (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_protection_spelllevel_dec (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_protection_spelllevel_dec(%2d): Type: %d", fx->Opcode, fx->Parameter2);
+ if (fx->Parameter1<1) {
+ PlayRemoveEffect("EFF_E02", target, fx);
+ return FX_NOT_APPLIED;
+ }
STAT_BIT_OR( IE_IMMUNITY, IMM_LEVEL_DEC );
target->AddPortraitIcon(PI_BOUNCE2);
return FX_APPLIED;
@@ -4822,8 +5272,8 @@ int fx_protection_spelllevel_dec (Scriptable* /*Owner*/, Actor* target, Effect*
//0xca Bounce:School
int fx_bounce_school (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_bounce_school (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
- STAT_BIT_OR( IE_BOUNCE, BNC_SCHOOL );
+ if(0) print("fx_bounce_school(%2d): Type: %d", fx->Opcode, fx->Parameter2);
+ STAT_BIT_OR_PCF( IE_BOUNCE, BNC_SCHOOL );
target->AddPortraitIcon(PI_BOUNCE2);
return FX_APPLIED;
}
@@ -4831,8 +5281,8 @@ int fx_bounce_school (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0xcb Bounce:SecondaryType
int fx_bounce_secondary_type (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_bounce_secondary_type (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
- STAT_BIT_OR( IE_BOUNCE, BNC_SECTYPE );
+ if(0) print("fx_bounce_secondary_type(%2d): Type: %d", fx->Opcode, fx->Parameter2);
+ STAT_BIT_OR_PCF( IE_BOUNCE, BNC_SECTYPE );
target->AddPortraitIcon(PI_BOUNCE2);
return FX_APPLIED;
}
@@ -4840,7 +5290,7 @@ int fx_bounce_secondary_type (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0xcc //resist school
int fx_protection_school (Scriptable* /*Owner*/, Actor* target, Effect *fx)
{
- if (0) printf( "fx_protection_school (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_protection_school(%2d): Type: %d", fx->Opcode, fx->Parameter2);
STAT_BIT_OR( IE_IMMUNITY, IMM_SCHOOL);
return FX_APPLIED;
}
@@ -4848,7 +5298,7 @@ int fx_protection_school (Scriptable* /*Owner*/, Actor* target, Effect *fx)
// 0xcd //resist sectype
int fx_protection_secondary_type (Scriptable* /*Owner*/, Actor* target, Effect *fx)
{
- if (0) printf( "fx_protection_secondary_type (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_protection_secondary_type(%2d): Type: %d", fx->Opcode, fx->Parameter2);
STAT_BIT_OR( IE_IMMUNITY, IMM_SECTYPE);
return FX_APPLIED;
}
@@ -4856,7 +5306,7 @@ int fx_protection_secondary_type (Scriptable* /*Owner*/, Actor* target, Effect *
//0xce Protection:Spell
int fx_resist_spell (Scriptable* /*Owner*/, Actor* target, Effect *fx)
{
- if (0) printf( "fx_resist_spell (%2d): Resource: %s\n", fx->Opcode, fx->Resource );
+ if(0) print("fx_resist_spell(%2d): Resource: %s", fx->Opcode, fx->Resource);
if (strnicmp(fx->Resource,fx->Source,sizeof(fx->Resource)) ) {
STAT_BIT_OR( IE_IMMUNITY, IMM_RESOURCE);
return FX_APPLIED;
@@ -4866,9 +5316,16 @@ int fx_resist_spell (Scriptable* /*Owner*/, Actor* target, Effect *fx)
}
// ??? Protection:SpellDec
+// This is a fictional opcode, it isn't implemented in the original engine
int fx_resist_spell_dec (Scriptable* /*Owner*/, Actor* target, Effect *fx)
{
- if (0) printf( "fx_resist_spell_dec (%2d): Resource: %s\n", fx->Opcode, fx->Resource );
+ if(0) print("fx_resist_spell_dec(%2d): Resource: %s", fx->Opcode, fx->Resource);
+
+ if (fx->Parameter1<1) {
+ PlayRemoveEffect("EFF_E02", target, fx);
+ return FX_NOT_APPLIED;
+ }
+
if (strnicmp(fx->Resource,fx->Source,sizeof(fx->Resource)) ) {
STAT_BIT_OR( IE_IMMUNITY, IMM_RESOURCE_DEC);
return FX_APPLIED;
@@ -4880,16 +5337,21 @@ int fx_resist_spell_dec (Scriptable* /*Owner*/, Actor* target, Effect *fx)
// 0xcf Bounce:Spell
int fx_bounce_spell (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_bounce_spell (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
- STAT_BIT_OR( IE_BOUNCE, BNC_RESOURCE );
+ if(0) print("fx_bounce_spell(%2d): Type: %d", fx->Opcode, fx->Parameter2);
+ STAT_BIT_OR_PCF( IE_BOUNCE, BNC_RESOURCE );
return FX_APPLIED;
}
// ??? Bounce:SpellDec
+// This is a fictional opcode, it isn't implemented in the original engine
int fx_bounce_spell_dec (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_bounce_spell (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
- STAT_BIT_OR( IE_BOUNCE, BNC_RESOURCE_DEC );
+ if(0) print("fx_bounce_spell(%2d): Type: %d", fx->Opcode, fx->Parameter2);
+ if (fx->Parameter1<1) {
+ PlayRemoveEffect("EFF_E02", target, fx);
+ return FX_NOT_APPLIED;
+ }
+ STAT_BIT_OR_PCF( IE_BOUNCE, BNC_RESOURCE_DEC );
return FX_APPLIED;
}
@@ -4898,7 +5360,7 @@ int fx_bounce_spell_dec (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// it allowed only setting it, and only by one instance
int fx_minimum_hp_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_minimum_hp_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_minimum_hp_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_MINHITPOINTS );
return FX_APPLIED;
@@ -4907,7 +5369,7 @@ int fx_minimum_hp_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0xd1 PowerWordKill
int fx_power_word_kill (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_power_word_kill (%2d): HP: %d Stat: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_power_word_kill(%2d): HP: %d Stat: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
ieDword limit = 60;
if (fx->Parameter1) {
@@ -4926,7 +5388,7 @@ int fx_power_word_kill (Scriptable* Owner, Actor* target, Effect* fx)
//0xd2 PowerWordStun
int fx_power_word_stun (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_power_word_stun (%2d): HP: %d Stat: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_power_word_stun(%2d): HP: %d Stat: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
ieDword limit = 90;
if (fx->Parameter1) {
@@ -4954,19 +5416,17 @@ int fx_power_word_stun (Scriptable* Owner, Actor* target, Effect* fx)
//0xd3 State:Imprisonment (avatar removal plus portrait icon)
int fx_imprisonment (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_imprisonment (%2d)\n", fx->Opcode );
- target->SetMCFlag(MC_HIDDEN, BM_OR);
+ if(0) print("fx_imprisonment(%2d)", fx->Opcode);
+ STAT_SET(IE_AVATARREMOVAL, 1);
target->AddPortraitIcon(PI_PRISON);
+ target->SendDiedTrigger();
return FX_APPLIED;
}
//0xd4 Cure:Imprisonment
-static EffectRef fx_imprisonment_ref = { "Imprisonment", -1 };
-static EffectRef fx_maze_ref = { "Maze", -1 };
-
int fx_freedom (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_freedom (%2d)\n", fx->Opcode );
+ if(0) print("fx_freedom(%2d)", fx->Opcode);
target->fxqueue.RemoveAllEffects( fx_imprisonment_ref );
target->fxqueue.RemoveAllEffects( fx_maze_ref );
return FX_NOT_APPLIED;
@@ -4975,15 +5435,24 @@ int fx_freedom (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0xd5 Maze
int fx_maze (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_maze (%2d)\n", fx->Opcode );
- if (!fx->Parameter2 && fx->FirstApply) {
- //get the maze dice number (column 3)
- int stat = target->GetSafeStat(IE_INT);
- int size = core->GetIntelligenceBonus(3, stat);
- int dice = core->GetIntelligenceBonus(4, stat);
- fx->Duration = core->GetGame()->GameTime+target->LuckyRoll(dice, size, 0, 0)*100;
+ if(0) print("fx_maze(%2d)", fx->Opcode);
+ Game *game = core->GetGame();
+ if (fx->Parameter2) {
+ //this version of maze works only in combat
+ if (!fx->FirstApply && !game->CombatCounter) {
+ return FX_NOT_APPLIED;
+ }
+ } else {
+ if (fx->FirstApply) {
+ //get the maze dice number (column 3)
+ int stat = target->GetSafeStat(IE_INT);
+ int size = core->GetIntelligenceBonus(3, stat);
+ int dice = core->GetIntelligenceBonus(4, stat);
+ fx->Duration = game->GameTime+target->LuckyRoll(dice, size, 0, 0)*100;
+ }
}
- target->SetMCFlag(MC_HIDDEN, BM_OR);
+
+ STAT_SET(IE_AVATARREMOVAL, 1);
target->AddPortraitIcon(PI_MAZE);
return FX_APPLIED;
}
@@ -4992,14 +5461,12 @@ int fx_maze (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//GemRB extension: if fx->Parameter1 is set, it is the bitfield of spell types (could be priest spells)
int fx_select_spell (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_select_spell (%2d) %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_select_spell(%2d) %d", fx->Opcode, fx->Parameter2);
Spellbook *sb = &target->spellbook;
if(fx->Parameter2) {
//all known spells, no need to memorize
- if (!fx->Parameter1) {
- fx->Parameter1=1<<IE_SPELL_TYPE_WIZARD;
- }
- sb->SetCustomSpellInfo(NULL, fx->Source, fx->Parameter1);
+ // the details are all handled by the Spellbook guiscript
+ core->GetDictionary()->SetAt("ActionLevel", 5);
} else {
//all spells listed in 2da
ieResRef *data = NULL;
@@ -5007,22 +5474,22 @@ int fx_select_spell (Scriptable* /*Owner*/, Actor* target, Effect* fx)
int count = core->ReadResRefTable(fx->Resource, data);
sb->SetCustomSpellInfo(data, fx->Source, count);
core->FreeResRefTable(data, count);
+ core->GetDictionary()->SetAt("ActionLevel", 11);
}
- core->GetDictionary()->SetAt("Type",-1);
+ // force a redraw of the action bar
//this is required, because not all of these opcodes are firing right at casting
- core->GetDictionary()->SetAt("ActionLevel", 2);
+ core->GetDictionary()->SetAt("Type",-1);
core->SetEventFlag(EF_ACTION);
return FX_NOT_APPLIED;
}
// 0xd7 PlayVisualEffect
-static EffectRef fx_protection_from_animation_ref = { "Protection:Animation", -1 };
int fx_play_visual_effect (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_play_visual_effect (%2d): Resource: %s Type: %d\n", fx->Opcode, fx->Resource, fx->Parameter2 );
+ if(0) print("fx_play_visual_effect(%2d): Resource: %s Type: %d", fx->Opcode, fx->Resource, fx->Parameter2);
//this is in the original engine (dead actors lose this effect)
- if (STATE_GET( STATE_DEAD) ) {
+ if (!target || STATE_GET(STATE_DEAD)) {
return FX_NOT_APPLIED;
}
@@ -5059,13 +5526,13 @@ int fx_play_visual_effect (Scriptable* /*Owner*/, Actor* target, Effect* fx)
}
if (fx->Parameter2 == 1) {
//play over target (sticky)
- sca->effect_owned = true;
+ sca->SetEffectOwned(true);
target->AddVVCell( sca );
return FX_APPLIED;
}
//not sticky
- if (fx->Parameter2 == 2 || !target) {
+ if (fx->Parameter2 == 2) {
sca->XPos = fx->PosX;
sca->YPos = fx->PosY;
} else {
@@ -5077,14 +5544,11 @@ int fx_play_visual_effect (Scriptable* /*Owner*/, Actor* target, Effect* fx)
return FX_NOT_APPLIED;
}
-//d8 LevelDrainModifier
-
-static EffectRef fx_leveldrain_ref = { "LevelDrainModifier", -1 };
-
+//0xd8 LevelDrainModifier
// FIXME: BG2 level drain uses parameter3 to decrease the MaxHp, and parameter4 to decrease level. (unset)
int fx_leveldrain_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_leveldrain_modifier (%2d): Mod: %d\n", fx->Opcode, fx->Parameter1 );
+ if(0) print("fx_leveldrain_modifier(%2d): Mod: %d", fx->Opcode, fx->Parameter1);
//never subtract more than the maximum hitpoints
ieDword x = STAT_GET(IE_MAXHITPOINTS)-1;
@@ -5109,11 +5573,10 @@ int fx_leveldrain_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
}
//d9 PowerWordSleep
-static EffectRef fx_sleep_ref = { "State:Sleep", -1 };
int fx_power_word_sleep (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_power_word_sleep (%2d): HP: %d Stat: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_power_word_sleep(%2d): HP: %d Stat: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
ieDword limit = 20;
if (fx->Parameter1) {
@@ -5131,16 +5594,19 @@ int fx_power_word_sleep (Scriptable* Owner, Actor* target, Effect* fx)
//recalculate delay
fx->Duration = core->GetGame()->GameTime+x*core->Time.round_size;
fx->TimingMode = FX_DURATION_ABSOLUTE;
- fx->Opcode = EffectQueue::ResolveEffect(fx_sleep_ref);
+ fx->Opcode = EffectQueue::ResolveEffect(fx_set_sleep_state_ref);
fx->Parameter2=0;
return fx_set_unconscious_state(Owner,target,fx);
}
+static const ieDword fullstone[7]={STONE_GRADIENT,STONE_GRADIENT,STONE_GRADIENT,STONE_GRADIENT,STONE_GRADIENT,STONE_GRADIENT,STONE_GRADIENT};
+
// 0xda StoneSkinModifier
int fx_stoneskin_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_stoneskin_modifier (%2d): Mod: %d\n", fx->Opcode, fx->Parameter1 );
+ if(0) print("fx_stoneskin_modifier(%2d): Mod: %d", fx->Opcode, fx->Parameter1);
if (!fx->Parameter1) {
+ PlayRemoveEffect("EFF_E02",target, fx);
return FX_NOT_APPLIED;
}
@@ -5156,7 +5622,7 @@ int fx_stoneskin_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//gradient for iron skins?
} else {
target->SetSpellState(SS_STONESKIN);
- SetGradient(target, 14);
+ SetGradient(target, fullstone);
}
STAT_SET(IE_STONESKINS, fx->Parameter1);
target->AddPortraitIcon(PI_STONESKIN);
@@ -5169,7 +5635,7 @@ int fx_dispel_school (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
ieResRef Removed;
- if (0) printf( "fx_dispel_school (%2d): Level: %d Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_dispel_school(%2d): Level: %d Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
target->fxqueue.RemoveLevelEffects(Removed, fx->Parameter1, RL_MATCHSCHOOL, fx->Parameter2);
return FX_NOT_APPLIED;
}
@@ -5178,7 +5644,7 @@ int fx_dispel_secondary_type (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
ieResRef Removed;
- if (0) printf( "fx_dispel_secondary_type (%2d): Level: %d Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_dispel_secondary_type(%2d): Level: %d Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
target->fxqueue.RemoveLevelEffects(Removed, fx->Parameter1, RL_MATCHSECTYPE, fx->Parameter2);
return FX_NOT_APPLIED;
}
@@ -5186,7 +5652,7 @@ int fx_dispel_secondary_type (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0xde RandomTeleport
int fx_teleport_field (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_teleport_field (%2d): Distance: %d\n", fx->Opcode, fx->Parameter1 );
+ if(0) print("fx_teleport_field(%2d): Distance: %d", fx->Opcode, fx->Parameter1);
Map *map = target->GetCurrentArea();
if (!map) {
@@ -5203,19 +5669,22 @@ int fx_teleport_field (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0xdf //Protection:SchoolDec
int fx_protection_school_dec (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_protection_school_dec (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
- if (fx->Parameter1) {
- STAT_BIT_OR( IE_IMMUNITY, IMM_SCHOOL_DEC );
- return FX_APPLIED;
+ if(0) print("fx_protection_school_dec(%2d): Type: %d", fx->Opcode, fx->Parameter2);
+ if (fx->Parameter1<1) {
+ //The original doesn't have anything here
+ PlayRemoveEffect(NULL, target, fx);
+ return FX_NOT_APPLIED;
}
- return FX_NOT_APPLIED;
+
+ STAT_BIT_OR( IE_IMMUNITY, IMM_SCHOOL_DEC );
+ return FX_APPLIED;
}
//0xe0 Cure:LevelDrain
int fx_cure_leveldrain (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cure_leveldrain (%2d)\n", fx->Opcode );
+ if(0) print("fx_cure_leveldrain(%2d)", fx->Opcode);
//all level drain removed at once???
//if not, then find old effect, remove a number
target->fxqueue.RemoveAllEffects( fx_leveldrain_ref );
@@ -5226,7 +5695,7 @@ int fx_cure_leveldrain (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//gemrb special: speed and color are custom
int fx_reveal_magic (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_reveal_magic (%2d)\n", fx->Opcode );
+ if(0) print("fx_reveal_magic(%2d)", fx->Opcode);
if (target->fxqueue.HasAnyDispellableEffect()) {
if (!fx->Parameter1) {
fx->Parameter1=0xff00; //blue
@@ -5244,19 +5713,26 @@ int fx_reveal_magic (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0xe2 Protection:SecondaryTypeDec
int fx_protection_secondary_type_dec (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_protection_secondary_type_dec (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
- if (fx->Parameter1) {
- STAT_BIT_OR( IE_IMMUNITY, IMM_SECTYPE_DEC );
- return FX_APPLIED;
+ if(0) print("fx_protection_secondary_type_dec(%2d): Type: %d", fx->Opcode, fx->Parameter2);
+ if (fx->Parameter1<1) {
+ //The original doesn't have anything here
+ PlayRemoveEffect(NULL, target, fx);
+ return FX_NOT_APPLIED;
}
- return FX_NOT_APPLIED;
+ STAT_BIT_OR( IE_IMMUNITY, IMM_SECTYPE_DEC );
+ return FX_APPLIED;
}
//0xe3 Bounce:SchoolDecrement
int fx_bounce_school_dec (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_bounce_school_dec (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
- STAT_BIT_OR( IE_BOUNCE, BNC_SCHOOL_DEC );
+ if(0) print("fx_bounce_school_dec(%2d): Type: %d", fx->Opcode, fx->Parameter2);
+ if (fx->Parameter1<1) {
+ //The original doesn't have anything here
+ PlayRemoveEffect(NULL, target, fx);
+ return FX_NOT_APPLIED;
+ }
+ STAT_BIT_OR_PCF( IE_BOUNCE, BNC_SCHOOL_DEC );
target->AddPortraitIcon(PI_BOUNCE2);
return FX_APPLIED;
}
@@ -5264,8 +5740,13 @@ int fx_bounce_school_dec (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0xe4 Bounce:SecondaryTypeDecrement
int fx_bounce_secondary_type_dec (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_bounce_secondary_type_dec (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
- STAT_BIT_OR( IE_BOUNCE, BNC_SECTYPE_DEC );
+ if(0) print("fx_bounce_secondary_type_dec(%2d): Type: %d", fx->Opcode, fx->Parameter2);
+ if (fx->Parameter1<1) {
+ //The original doesn't have anything here
+ PlayRemoveEffect(NULL, target, fx);
+ return FX_NOT_APPLIED;
+ }
+ STAT_BIT_OR_PCF( IE_BOUNCE, BNC_SECTYPE_DEC );
target->AddPortraitIcon(PI_BOUNCE2);
return FX_APPLIED;
}
@@ -5275,7 +5756,7 @@ int fx_dispel_school_one (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
ieResRef Removed;
- if (0) printf( "fx_dispel_school_one (%2d): Level: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_dispel_school_one(%2d): Level: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
target->fxqueue.RemoveLevelEffects(Removed, fx->Parameter1, RL_MATCHSCHOOL|RL_REMOVEFIRST, fx->Parameter2);
return FX_NOT_APPLIED;
}
@@ -5285,7 +5766,7 @@ int fx_dispel_secondary_type_one (Scriptable* /*Owner*/, Actor* target, Effect*
{
ieResRef Removed;
- if (0) printf( "fx_dispel_secondary_type_one (%2d): Level: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_dispel_secondary_type_one(%2d): Level: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
target->fxqueue.RemoveLevelEffects(Removed, fx->Parameter1, RL_MATCHSECTYPE|RL_REMOVEFIRST, fx->Parameter2);
return FX_NOT_APPLIED;
}
@@ -5293,7 +5774,7 @@ int fx_dispel_secondary_type_one (Scriptable* /*Owner*/, Actor* target, Effect*
//0xe7 Timestop
int fx_timestop (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_timestop (%2d)\n", fx->Opcode);
+ if(0) print("fx_timestop(%2d)", fx->Opcode);
core->GetGame()->TimeStop(target, fx->Duration);
return FX_NOT_APPLIED;
}
@@ -5301,92 +5782,182 @@ int fx_timestop (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0xe8 CastSpellOnCondition
int fx_cast_spell_on_condition (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cast_spell_on_condition (%2d): Target: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_cast_spell_on_condition(%2d): Target: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+ /*
+ * This is used for Fire Shield, etc, to cast spells when certain
+ * triggers are true. It is also used for contingencies, which set
+ * Parameter3 and expect some special processing.
+ * In the original engine, this constructs a 'contingency list' in the
+ * target's stats, which is checked in two cases: every 100 ticks
+ * (for 0x4xxx-type triggers) and every time a trigger is added (for
+ * other triggers).
+ * Instead, we handle the first type directly here in the effect
+ * itself, and the normal type by marking triggers with the flag
+ * TEF_PROCESSED_EFFECTS after every effect run, so we can tell that
+ * only triggers without the flag should be checked.
+ * Conveniently, since contingency versions self-destruct and
+ * non-contingency versions are only allowed to run once per
+ * frame, we need only check a single trigger per effect run.
+ */
if (fx->FirstApply && fx->Parameter3) {
+ // TODO: display strings
+
target->spellbook.HaveSpell( fx->Resource, HS_DEPLETE );
target->spellbook.HaveSpell( fx->Resource2, HS_DEPLETE );
target->spellbook.HaveSpell( fx->Resource3, HS_DEPLETE );
target->spellbook.HaveSpell( fx->Resource4, HS_DEPLETE );
}
- //get subject of check
+ if (fx->Parameter3) {
+ target->AddPortraitIcon(PI_CONTINGENCY);
+ }
+
+ // TODO: resist source spell, if any
+
+ // get the actor to cast spells at
Actor *actor = NULL;
Map *map = target->GetCurrentArea();
- switch(fx->Parameter1) {
- //self
- case 0: actor = target; break;
- //last attacker
- case 1: actor = map->GetActorByGlobalID(target->LastHitter); break;
- //nearest enemy
- //fix this!
- //case 2: actor = map->GetActorByGlobalID(target->LastSeen); break;
- case 2: actor = GetNearestEnemyOf(map, target, 0); break;
- //nearest creature
- case 3: actor = map->GetActorByGlobalID(target->LastSeen); break;
+ if (!map) return FX_APPLIED;
+
+ switch (fx->Parameter1) {
+ case 0:
+ // Myself
+ actor = target;
+ break;
+ case 1:
+ // LastHitter
+ actor = map->GetActorByGlobalID(target->LastHitter);
+ break;
+ case 2:
+ // NearestEnemyOf
+ actor = GetNearestEnemyOf(map, target, 0);
+ break;
+ case 3:
+ // Nearest?
+ actor = map->GetActorByGlobalID(target->LastSeen);
+ break;
}
+
if (!actor) {
return FX_APPLIED;
}
- int condition;
- //check condition
- switch(fx->Parameter2) {
- case COND_GOTHIT: //on hit
- condition = target->LastDamage;
+
+ bool condition;
+ bool per_round = true; // 4xxx trigger?
+ const TriggerEntry *entry = NULL;
+
+ // check the condition
+ switch (fx->Parameter2) {
+ case COND_GOTHIT:
+ // HitBy([ANYONE])
+ // TODO: should we ignore this for self-hits in non-contingency mode?
+ entry = target->GetMatchingTrigger(trigger_hitby, TEF_PROCESSED_EFFECTS);
+ per_round = false;
break;
- case COND_NEAR: //
- condition = PersonalDistance(actor, target)<30;
+ case COND_NEAR:
+ // See(NearestEnemyOf())
+ // FIXME
+ condition = PersonalDistance(actor, target) < 30;
break;
case COND_HP_HALF:
- condition = actor->GetBase(IE_HITPOINTS)<actor->GetStat(IE_MAXHITPOINTS)/2;
+ // HPPercentLT(Myself, 50)
+ condition = target->GetBase(IE_HITPOINTS) < (target->GetStat(IE_MAXHITPOINTS) / 2);
break;
case COND_HP_QUART:
- condition = actor->GetBase(IE_HITPOINTS)<actor->GetStat(IE_MAXHITPOINTS)/4;
+ // HPPercentLT(Myself, 25)
+ condition = target->GetBase(IE_HITPOINTS) < (target->GetStat(IE_MAXHITPOINTS) / 4);
break;
case COND_HP_LOW:
- condition = actor->GetBase(IE_HITPOINTS)<actor->GetStat(IE_MAXHITPOINTS)/10;
+ // HPPercentLT(Myself, 10)
+ condition = target->GetBase(IE_HITPOINTS) < (target->GetStat(IE_MAXHITPOINTS) / 10);
break;
case COND_HELPLESS:
- condition = actor->GetStat(IE_STATE_ID) & STATE_CANTMOVE;
+ // StateCheck(Myself, STATE_HELPLESS)
+ condition = (bool)(target->GetStat(IE_STATE_ID) & STATE_CANTMOVE);
break;
case COND_POISONED:
- condition = actor->GetStat(IE_STATE_ID) & STATE_POISONED;
+ // StateCheck(Myself, STATE_POISONED)
+ condition = (bool)(target->GetStat(IE_STATE_ID) & STATE_POISONED);
break;
- case COND_ATTACKED: // once per round
- condition = actor->LastHitter;
+ case COND_ATTACKED:
+ // AttackedBy([ANYONE])
+ entry = target->GetMatchingTrigger(trigger_attackedby, TEF_PROCESSED_EFFECTS);
+ per_round = false;
break;
- case COND_NEAR4: // closer than 4'
- condition = PersonalDistance(actor, target)<4;
+ case COND_NEAR4:
+ // PersonalSpaceDistance([ANYONE], 4)
+ // FIXME
+ condition = PersonalDistance(actor, target) < 4;
break;
- case COND_NEAR10: // closer than 10'
- condition = PersonalDistance(actor, target)<10;
+ case COND_NEAR10:
+ // PersonalSpaceDistance([ANYONE], 10)
+ // FIXME
+ condition = PersonalDistance(target, actor) < 10;
break;
case COND_EVERYROUND:
- condition = 1;
+ condition = true;
break;
case COND_TOOKDAMAGE:
- condition = actor->LastDamage;
+ // TookDamage()
+ entry = target->GetMatchingTrigger(trigger_tookdamage, TEF_PROCESSED_EFFECTS);
+ per_round = false;
break;
default:
- condition = 0;
+ condition = false;
+ }
+
+ if (per_round) {
+ // This is a 4xxx trigger which is only checked every round.
+ if (Owner->AdjustedTicks % core->Time.round_size)
+ condition = false;
+ } else {
+ // This is a normal trigger which gets a single opportunity every frame.
+ condition = (entry != NULL);
}
if (condition) {
- core->ApplySpell(fx->Resource, actor, Owner, fx->Power);
- core->ApplySpell(fx->Resource2, actor, Owner, fx->Power);
- core->ApplySpell(fx->Resource3, actor, Owner, fx->Power);
- core->ApplySpell(fx->Resource4, actor, Owner, fx->Power);
+ // The trigger was evaluated as true, cast the spells now.
+ // TODO: fail remaining spells if an earlier one fails?
+ unsigned int i, dist;
+ ieResRef refs[4];
+ strncpy(refs[0], fx->Resource, sizeof(ieResRef));
+ strncpy(refs[1], fx->Resource2, sizeof(ieResRef));
+ strncpy(refs[2], fx->Resource3, sizeof(ieResRef));
+ strncpy(refs[3], fx->Resource4, sizeof(ieResRef));
+ for (i=0; i < 4; i++) {
+ if (!refs[i][0]) {
+ continue;
+ }
+ // Actually, atleast fire shields also have a range check
+ if (fx->Parameter2 == COND_GOTHIT) {
+ dist = GetSpellDistance(refs[i], target);
+ if (!dist) {
+ displaymsg->DisplayConstantStringName(STR_CONTFAIL, DMC_RED, target);
+ continue;
+ }
+ if (PersonalDistance(target, actor) > dist) {
+ //display 'One of the spells has failed.'
+ displaymsg->DisplayConstantStringName(STR_CONTFAIL, DMC_RED, target);
+ continue;
+ }
+ }
+ core->ApplySpell(refs[i], actor, Owner, fx->Power);
+ }
+
if (fx->Parameter3) {
+ // Contingencies only run once, remove ourselves.
return FX_NOT_APPLIED;
}
}
+
return FX_APPLIED;
}
// 0xe9 Proficiency
int fx_proficiency (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_proficiency (%2d): Value: %d, Stat: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_proficiency(%2d): Value: %d, Stat: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (fx->Parameter2>=MAX_STATS) return FX_NOT_APPLIED;
@@ -5398,14 +5969,16 @@ int fx_proficiency (Scriptable* /*Owner*/, Actor* target, Effect* fx)
}
// 0xea CreateContingency
-static EffectRef fx_contingency_ref = { "CastSpellOnCondition", -1 };
int fx_create_contingency (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_create_contingency (%2d): Level: %d, Count: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_create_contingency(%2d): Level: %d, Count: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+
+ //this effect terminates in cutscene mode
+ if (core->InCutSceneMode()) return FX_NOT_APPLIED;
if (target->fxqueue.HasEffectWithSource(fx_contingency_ref, fx->Source)) {
- displaymsg->DisplayConstantStringName(STR_CONTDUP, 0xf0f0f0, target);
+ displaymsg->DisplayConstantStringName(STR_CONTDUP, DMC_WHITE, target);
return FX_NOT_APPLIED;
}
@@ -5420,26 +5993,49 @@ int fx_create_contingency (Scriptable* /*Owner*/, Actor* target, Effect* fx)
return FX_NOT_APPLIED;
}
-#define WB_AWAY 0
-#define WB_TOWARDS 1
-#define WB_FIXDIR 2
-#define WB_OWNDIR 3
-#define WB_AWAYOWNDIR 4
+#define WB_AWAY 2
+#define WB_TOWARDS 4
+#define WB_FIXDIR 5
+#define WB_OWNDIR 6
+#define WB_AWAYOWNDIR 7
+
+static int coords[16][2]={ {0,12},{-4,9},{-8,6},{-12,3},{-16,0},{-12,-3},{-8,-6},{-4,-9},
+{0,-12},{4,-9},{8,-6},{12,-3},{16,0},{12,3},{8,6},{4,9},};
// 0xeb WingBuffet
-int fx_wing_buffet (Scriptable* Owner, Actor* target, Effect* fx)
+int fx_wing_buffet (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_wing_buffet (%2d): Value: %d, Stat: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
- //create movement in actor
+ if(0) print("fx_wing_buffet(%2d): Mode: %d, Strength: %d", fx->Opcode, fx->Parameter2, fx->Parameter1);
+ //creature immunity is based on creature size (though the original is rather cheesy)
+ if (target->GetAnims()->GetCircleSize()>5) {
+ return FX_NOT_APPLIED;
+ }
+ if (!target->GetCurrentArea()) {
+ //no area, no movement
+ return FX_APPLIED;
+ }
+
+ Game *game = core->GetGame();
+
+ if (fx->FirstApply) {
+ fx->Parameter4 = game->GameTime;
+ return FX_APPLIED;
+ }
+
+ int ticks = game->GameTime-fx->Parameter4;
+ if (!ticks)
+ return FX_APPLIED;
+
+ //create movement in actor
ieDword dir;
switch(fx->Parameter2) {
case WB_AWAY:
default:
- dir = GetOrient(Owner->Pos, target->Pos);
+ dir = GetOrient(target->Pos, GetCasterObject()->Pos);
break;
case WB_TOWARDS:
- dir = GetOrient(target->Pos, Owner->Pos);
+ dir = GetOrient(GetCasterObject()->Pos, target->Pos);
break;
case WB_FIXDIR:
dir = fx->Parameter3;
@@ -5451,22 +6047,27 @@ int fx_wing_buffet (Scriptable* Owner, Actor* target, Effect* fx)
dir = target->GetOrientation()^8;
break;
}
- //could be GL_REBOUND too :)
- //add effect to alter target's stance
- target->MoveLine( fx->Parameter1, GL_NORMAL, dir );
- return FX_NOT_APPLIED;
-}
+ Point newpos=target->Pos;
-// 0xec ProjectImage
+ newpos.x += coords[dir][0]*(signed) fx->Parameter1*ticks/16;///AI_UPDATE_TIME;
+ newpos.y += coords[dir][1]*(signed) fx->Parameter1*ticks/12;///AI_UPDATE_TIME;
+
+ //change is minimal, lets try later
+ if (newpos.x==target->Pos.x && newpos.y==target->Pos.y)
+ return FX_APPLIED;
-static EffectRef fx_puppetmarker_ref = { "PuppetMarker", -1 };
+ target->SetPosition(newpos, true, 0);
+
+ fx->Parameter4 = game->GameTime;
+ return FX_APPLIED;
+}
+// 0xec ProjectImage
int fx_puppet_master (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
const char * resref = NULL;
- if (0) printf( "fx_puppet_master (%2d): Value: %d, Stat: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
- STAT_SET (IE_PUPPETMASTERTYPE, fx->Parameter1);
+ if(0) print("fx_puppet_master(%2d): Value: %d, Stat: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//copyself doesn't copy scripts, so the script clearing code is not needed
Actor *copy = target->CopySelf(fx->Parameter2 == 1);
@@ -5501,7 +6102,7 @@ int fx_puppet_master (Scriptable* /*Owner*/, Actor* target, Effect* fx)
case 3:
resref = "simulacr";
// healable level drain
- // FIXME: second generation simulacri are supposedly at a different level:
+ // second generation simulacri are supposedly at a different level, but that makes little sense:
// level = original caster - caster / 2; eg. lvl 32 -> 16 -> 24 -> 20 -> 22 -> 21
newfx = EffectQueue::CreateEffect(fx_leveldrain_ref, copy->GetXPLevel(1)/2, 0, FX_DURATION_INSTANT_PERMANENT);
if (newfx) {
@@ -5517,8 +6118,7 @@ int fx_puppet_master (Scriptable* /*Owner*/, Actor* target, Effect* fx)
core->ApplySpell(resref,copy,copy,0);
}
- //FIXME: parameter1 is unsure, but something similar to what the original engine has there
- newfx = EffectQueue::CreateEffectCopy(fx, fx_puppetmarker_ref, target->InParty-1, fx->Parameter2);
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_puppetmarker_ref, fx->CasterID, fx->Parameter2);
if (newfx) {
core->ApplyEffect(newfx, copy, copy);
delete newfx;
@@ -5529,24 +6129,32 @@ int fx_puppet_master (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0xed PuppetMarker
int fx_puppet_marker (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_puppet_marker (%2d): Value: %d, Stat: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
- //actually the Type is in parameter2 and the ID is in parameter1
- //but for some reason the defines are in the opposite order
- STAT_SET (IE_PUPPETTYPE, fx->Parameter1); //cb4 - the ID of the controller
- STAT_SET (IE_PUPPETID, fx->Parameter2); //cb8 - the control type
+ if(0) print("fx_puppet_marker(%2d): Value: %d, Stat: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+ Actor *master = core->GetGame()->GetActorByGlobalID(fx->Parameter1);
+ // selfdestruct if the master is gone
+ if (!master || master->Modified[IE_STATE_ID]&STATE_DEAD) {
+ target->DestroySelf();
+ return FX_NOT_APPLIED;
+ }
+ STAT_SET (IE_PUPPETMASTERTYPE, fx->Parameter2);
+ STAT_SET (IE_PUPPETMASTERID, fx->Parameter1);
+ //These will be seen in PrevStats after an update in Master
+ master->SetStat(IE_PUPPETID, target->GetGlobalID(), 0);
+ master->SetStat(IE_PUPPETTYPE, fx->Parameter2, 0);
return FX_APPLIED;
}
// 0xee Disintegrate
int fx_disintegrate (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_disintegrate (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_disintegrate(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (EffectQueue::match_ids( target, fx->Parameter2, fx->Parameter1) ) {
//convert it to a death opcode or apply the new effect?
fx->Opcode = EffectQueue::ResolveEffect(fx_death_ref);
fx->TimingMode = FX_DURATION_INSTANT_PERMANENT;
fx->Parameter1 = 0;
fx->Parameter2 = 0x200;
+ fx->Parameter3 = 1; // mark it as disintegration, so we can destroy items later properly
return FX_APPLIED;
}
return FX_NOT_APPLIED;
@@ -5564,7 +6172,7 @@ int fx_disintegrate (Scriptable* /*Owner*/, Actor* target, Effect* fx)
int fx_farsee (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_farsee (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_farsee(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
Map *map = target->GetCurrentArea();
if (!map) {
return FX_APPLIED;
@@ -5601,18 +6209,16 @@ int fx_farsee (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0xf0 Icon:Remove
int fx_remove_portrait_icon (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_remove_portrait_icon (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_remove_portrait_icon(%2d): Type: %d", fx->Opcode, fx->Parameter2);
target->fxqueue.RemoveAllEffectsWithParam( fx_display_portrait_icon_ref, fx->Parameter2 );
return FX_NOT_APPLIED;
}
// 0xf1 control creature (same as charm)
// 0xF2 Cure:Confusion
-static EffectRef fx_confused_state_ref = { "State:Confused", -1 };
-
int fx_cure_confused_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cure_confused_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_cure_confused_state(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
BASE_STATE_CURE( STATE_CONFUSED );
target->fxqueue.RemoveAllEffects(fx_confused_state_ref);
//FIXME:oddly enough, HoW removes the confused icon
@@ -5630,7 +6236,7 @@ int fx_cure_confused_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0xf3 DrainItems (this is disabled in ToB)
int fx_drain_items (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_drain_items (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_drain_items(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
ieDword i=fx->Parameter1;
while (i--) {
//deplete magic item = 0
@@ -5642,7 +6248,7 @@ int fx_drain_items (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0xf4 DrainSpells
int fx_drain_spells (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_drain_spells (%2d): Count: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_drain_spells(%2d): Count: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
ieDword i=fx->Parameter1;
if (fx->Parameter2) {
while(i--) {
@@ -5662,21 +6268,21 @@ int fx_drain_spells (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0xf5 CheckForBerserk
int fx_checkforberserk_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_checkforberserk_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_checkforberserk_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_SET( IE_CHECKFORBERSERK, fx->Parameter2 );
return FX_APPLIED;
}
// 0xf6 BerserkStage1Modifier
int fx_berserkstage1_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_berserkstage1_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_berserkstage1_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_SET( IE_BERSERKSTAGE1, fx->Parameter2 );
return FX_APPLIED;
}
// 0xf7 BerserkStage2Modifier
int fx_berserkstage2_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_berserkstage2_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_berserkstage2_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_SET( IE_BERSERKSTAGE2, fx->Parameter2 );
STATE_SET (STATE_BERSERK);
return FX_APPLIED;
@@ -5693,7 +6299,7 @@ int fx_berserkstage2_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0xfa DamageLuckModifier
int fx_damageluck_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_damageluck_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_damageluck_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_DAMAGELUCK );
return FX_APPLIED;
}
@@ -5702,7 +6308,7 @@ int fx_damageluck_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
int fx_change_bardsong (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_change_bardsong (%2d): %s\n", fx->Opcode, fx->Resource);
+ if(0) print("fx_change_bardsong(%2d): %s", fx->Opcode, fx->Resource);
memcpy(target->BardSong, fx->Resource, 8);
return FX_APPLIED;
}
@@ -5710,7 +6316,7 @@ int fx_change_bardsong (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0xfc SetTrap
int fx_set_area_effect (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_trap (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_trap(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
ieDword skill, roll;
Map *map;
@@ -5722,13 +6328,13 @@ int fx_set_area_effect (Scriptable* Owner, Actor* target, Effect* fx)
//check if trap count is over an amount (only saved traps count)
//actually, only projectiles in trigger phase should count here
if (map->GetTrapCount(iter)>6) {
- displaymsg->DisplayConstantStringName(STR_NOMORETRAP, 0xf0f0f0, target);
+ displaymsg->DisplayConstantStringName(STR_NOMORETRAP, DMC_WHITE, target);
return FX_NOT_APPLIED;
}
//check if we are under attack
if (GetNearestEnemyOf(map, target, ORIGIN_SEES_ENEMY|ENEMY_SEES_ORIGIN)) {
- displaymsg->DisplayConstantStringName(STR_MAYNOTSETTRAP, 0xf0f0f0, target);
+ displaymsg->DisplayConstantStringName(STR_MAYNOTSETTRAP, DMC_WHITE, target);
return FX_NOT_APPLIED;
}
@@ -5742,10 +6348,10 @@ int fx_set_area_effect (Scriptable* Owner, Actor* target, Effect* fx)
if (roll>skill) {
//failure
- displaymsg->DisplayConstantStringName(STR_SNAREFAILED, 0xf0f0f0, target);
+ displaymsg->DisplayConstantStringName(STR_SNAREFAILED, DMC_WHITE, target);
if (target->LuckyRoll(1,100,0)<25) {
ieResRef spl;
-
+
strnuprcpy(spl, fx->Resource, 8);
if (strlen(spl)<8) {
strcat(spl,"F");
@@ -5757,13 +6363,13 @@ int fx_set_area_effect (Scriptable* Owner, Actor* target, Effect* fx)
return FX_NOT_APPLIED;
}
//success
- displaymsg->DisplayConstantStringName(STR_SNARESUCCEED, 0xf0f0f0, target);
+ displaymsg->DisplayConstantStringName(STR_SNARESUCCEED, DMC_WHITE, target);
// save the current spell ref, so the rest of its effects can be applied afterwards
ieResRef OldSpellResRef;
memcpy(OldSpellResRef, Owner->SpellResRef, sizeof(OldSpellResRef));
Owner->SetSpellResRef(fx->Resource);
- Owner->CastSpellPoint(fx->Resource, target->Pos, false);
- Owner->CastSpellPointEnd(0);
+ Owner->CastSpellPoint(target->Pos, false, true, true);
+ Owner->CastSpellPointEnd(0, 1);
Owner->SetSpellResRef(OldSpellResRef);
return FX_NOT_APPLIED;
}
@@ -5771,7 +6377,7 @@ int fx_set_area_effect (Scriptable* Owner, Actor* target, Effect* fx)
// 0xfd SetMapNote
int fx_set_map_note (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_map_note (%2d): StrRef: %d Color: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_map_note(%2d): StrRef: %d Color: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
Scriptable *marker = target?target:Owner;
Map *map = marker->GetCurrentArea();
if (!map) return FX_APPLIED; //delay effect
@@ -5784,7 +6390,7 @@ int fx_set_map_note (Scriptable* Owner, Actor* target, Effect* fx)
// 0xfe RemoveMapNote
int fx_remove_map_note (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_remove_map_note (%2d)\n", fx->Opcode);
+ if(0) print("fx_remove_map_note(%2d)", fx->Opcode);
Scriptable *marker = target?target:Owner;
Map *map = marker->GetCurrentArea();
if (!map) return FX_APPLIED; //delay effect
@@ -5796,7 +6402,7 @@ int fx_remove_map_note (Scriptable* Owner, Actor* target, Effect* fx)
// 0xff Item:CreateDays
int fx_create_item_days (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_create_item_days (%2d)\n", fx->Opcode );
+ if(0) print("fx_create_item_days(%2d)", fx->Opcode);
target->inventory.AddSlotItemRes( fx->Resource, SLOT_ONLYINVENTORY, fx->Parameter1, fx->Parameter3, fx->Parameter4 );
if ((fx->TimingMode&0xff) == FX_DURATION_INSTANT_LIMITED) {
//if this effect has expiration, then it will remain as a remove_item
@@ -5814,7 +6420,7 @@ int fx_create_item_days (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x100 Sequencer:Store
int fx_store_spell_sequencer(Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_store_spell_sequencer (%2d)\n", fx->Opcode );
+ if(0) print("fx_store_spell_sequencer(%2d)", fx->Opcode);
//just display the spell sequencer portrait icon
target->AddPortraitIcon(PI_SEQUENCER);
if (fx->FirstApply && fx->Parameter3) {
@@ -5827,13 +6433,11 @@ int fx_store_spell_sequencer(Scriptable* /*Owner*/, Actor* target, Effect* fx)
}
// 0x101 Sequencer:Create
-static EffectRef fx_spell_sequencer_active_ref = { "Sequencer:Store", -1 };
-
int fx_create_spell_sequencer(Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_create_spell_sequencer (%2d): Level: %d, Count: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_create_spell_sequencer(%2d): Level: %d, Count: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (target->fxqueue.HasEffectWithSource(fx_spell_sequencer_active_ref, fx->Source)) {
- displaymsg->DisplayConstantStringName(STR_SEQDUP, 0xf0f0f0, target);
+ displaymsg->DisplayConstantStringName(STR_SEQDUP, DMC_WHITE, target);
return FX_NOT_APPLIED;
}
//just a call to activate the spell sequencer creation gui
@@ -5852,7 +6456,7 @@ int fx_create_spell_sequencer(Scriptable* /*Owner*/, Actor* target, Effect* fx)
int fx_activate_spell_sequencer(Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_activate_spell_sequencer (%2d): Resource: %s\n", fx->Opcode, fx->Resource );
+ if(0) print("fx_activate_spell_sequencer(%2d): Resource: %s", fx->Opcode, fx->Resource);
if (Owner->Type!=ST_ACTOR) {
return FX_NOT_APPLIED;
}
@@ -5873,10 +6477,10 @@ int fx_activate_spell_sequencer(Scriptable* Owner, Actor* target, Effect* fx)
// 0x103 SpellTrap (Protection:SpellLevelDec + recall spells)
int fx_spelltrap(Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_spelltrap (%2d): Count: %d, Level: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_spelltrap(%2d): Count: %d, Level: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (fx->Parameter3) {
target->RestoreSpellLevel(fx->Parameter3, 0);
- fx->Parameter3=0;
+ fx->Parameter3 = 0;
}
if (fx->Parameter1<=0) {
//gone down to zero
@@ -5891,21 +6495,21 @@ int fx_spelltrap(Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0x138 Crash138
int fx_crash (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
{
- if (0) printf( "fx_crash (%2d): Param1: %d, Param2: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_crash(%2d): Param1: %d, Param2: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
return FX_NOT_APPLIED;
}
// 0x105 RestoreSpells
int fx_restore_spell_level(Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_restore_spell_level (%2d): Level: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_restore_spell_level(%2d): Level: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
target->RestoreSpellLevel(fx->Parameter1, fx->Parameter2);
return FX_NOT_APPLIED;
}
// 0x106 VisualRangeModifier
int fx_visual_range_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_visual_range_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_visual_range_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_VISUALRANGE );
return FX_APPLIED;
}
@@ -5913,7 +6517,7 @@ int fx_visual_range_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x107 BackstabModifier
int fx_backstab_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_visual_range_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_visual_range_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//this is how it is done in the original engine, i don't know why they would do this
//ctrl-r would probably remove it otherwise
//Why they didn't fix it in the spell/item is beyond me
@@ -5963,7 +6567,7 @@ int fx_modify_global_variable (Scriptable* /*Owner*/, Actor* /*target*/, Effect*
strnuprcpy(fx->Resource,"RETURN_TO_LONELYWOOD",32);
}
- if (0) printf( "fx_modify_global_variable (%2d): Variable: %s Value: %d Type: %d\n", fx->Opcode, fx->Resource, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_modify_global_variable(%2d): Variable: %s Value: %d Type: %d", fx->Opcode, fx->Resource, fx->Parameter1, fx->Parameter2);
if (fx->Parameter2) {
ieDword var = 0;
//use resource memory area as variable name
@@ -5974,13 +6578,12 @@ int fx_modify_global_variable (Scriptable* /*Owner*/, Actor* /*target*/, Effect*
}
return FX_NOT_APPLIED;
}
-// 0x10a RemoveImmunity
-static EffectRef immunity_effect_ref = { "Protection:Spell", -1 };
+// 0x10a RemoveImmunity
int fx_remove_immunity(Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_remove_immunity (%2d): %s\n", fx->Opcode, fx->Resource );
- target->fxqueue.RemoveAllEffectsWithResource(immunity_effect_ref, fx->Resource);
+ if(0) print("fx_remove_immunity(%2d): %s", fx->Opcode, fx->Resource);
+ target->fxqueue.RemoveAllEffectsWithResource(fx_immunity_effect_ref, fx->Resource);
return FX_NOT_APPLIED;
}
@@ -5988,7 +6591,7 @@ int fx_remove_immunity(Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x10c ExploreModifier
int fx_explore_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_explore_modifier (%2d)\n", fx->Opcode );
+ if(0) print("fx_explore_modifier(%2d)", fx->Opcode);
if (fx->Parameter2) {
//gemrb modifier
STAT_SET (IE_EXPLORE, fx->Parameter1);
@@ -6000,17 +6603,39 @@ int fx_explore_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x10d ScreenShake
int fx_screenshake (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
{
- if (0) printf( "fx_screenshake (%2d): Strength: %d\n", fx->Opcode, fx->Parameter1 );
- core->timer->SetScreenShake( fx->Parameter1, fx->Parameter1, fx->Parameter1);
- return FX_APPLIED;
+ if(0) print("fx_screenshake(%2d): Strength: %d", fx->Opcode, fx->Parameter1);
+ unsigned long count;
+
+ if (fx->TimingMode!=FX_PERMANENT) {
+ count = fx->Duration-core->GetGame()->GameTime;
+ } else {
+ count = core->Time.round_size;
+ }
+ int x,y;
+
+ switch(fx->Parameter2) {
+ case 0: default:
+ x=fx->Parameter1;
+ y=fx->Parameter1;
+ break;
+ case 1:
+ x=fx->Parameter1;
+ y=-fx->Parameter1;
+ break;
+ case 2:
+ //gemrb addition
+ x=(short) (fx->Parameter1&0xffff);
+ y=(short) (fx->Parameter1>>16);
+ break;
+ }
+ core->timer->SetScreenShake( x, y, count);
+ return FX_NOT_APPLIED;
}
// 0x10e Cure:CasterHold
-static EffectRef fx_pause_caster_modifier_ref = { "PauseTarget", -1 };
-
int fx_unpause_caster (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_unpause_caster (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_unpause_caster(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
target->fxqueue.RemoveAllEffects(fx_pause_caster_modifier_ref);
return FX_NOT_APPLIED;
}
@@ -6018,7 +6643,7 @@ int fx_unpause_caster (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x10f SummonDisable (bg2)
int fx_summon_disable (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_summon_disable (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_summon_disable(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_SET(IE_SUMMONDISABLE, 1);
STAT_SET(IE_CASTERHOLD, 1);
if (fx->Parameter2==1) {
@@ -6032,13 +6657,12 @@ What happens at a lower level is that the engine recreates the entire stats on s
Since the repeating effects are stored in a list inside those stats, they are being recreated every ai update, if there has been an effect application.
The repeating effect itself internally uses a counter to store how often it has been called. And when this counter equals the period it fires of the effect. When the list is being recreated all those counters are lost.
*/
-static EffectRef fx_apply_effect_repeat_ref = { "ApplyEffectRepeat", -1 };
// 0x110 ApplyEffectRepeat
int fx_apply_effect_repeat (Scriptable* Owner, Actor* target, Effect* fx)
{
ieDword i; //moved here because msvc6 cannot handle it otherwise
- if (0) printf( "fx_apply_effect_repeat (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_apply_effect_repeat(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
Point p(fx->PosX, fx->PosY);
Effect *newfx = core->GetEffect(fx->Resource, fx->Power, p);
@@ -6068,12 +6692,12 @@ int fx_apply_effect_repeat (Scriptable* Owner, Actor* target, Effect* fx)
}
break;
case 3: //once every Param1 second
- if (fx->Parameter1 && (core->GetGame()->GameTime%fx->Parameter1)) {
+ if (fx->Parameter1 && !(core->GetGame()->GameTime%(fx->Parameter1*AI_UPDATE_TIME))) {
core->ApplyEffect(newfx, target, Owner);
}
break;
case 4: //param3 times every Param1 second
- if (fx->Parameter1 && (core->GetGame()->GameTime%fx->Parameter1)) {
+ if (fx->Parameter1 && !(core->GetGame()->GameTime%(fx->Parameter1*AI_UPDATE_TIME))) {
for (i=0;i<fx->Parameter3;i++) {
core->ApplyEffect(newfx, target, Owner);
}
@@ -6090,7 +6714,7 @@ int fx_remove_projectile (Scriptable* /*Owner*/, Actor* target, Effect* fx)
ieDword *projectilelist;
//instant effect
- if (0) printf( "fx_remove_projectile (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_remove_projectile(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (!target) return FX_NOT_APPLIED;
Map *area = target->GetCurrentArea();
@@ -6140,7 +6764,7 @@ int fx_remove_projectile (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x112 TeleportToTarget
int fx_teleport_to_target (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_teleport_to_target (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_teleport_to_target(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (STATE_GET(STATE_DEAD)) {
return FX_NOT_APPLIED;
}
@@ -6152,7 +6776,7 @@ int fx_teleport_to_target (Scriptable* /*Owner*/, Actor* target, Effect* fx)
Targets *tgts = GetAllObjects(map, target, &oC, GA_NO_DEAD);
int rnd = core->Roll(1,tgts->Count(),-1);
Actor *victim = (Actor *) tgts->GetTarget(rnd, ST_ACTOR);
- delete tgts;
+ delete tgts;
if (victim && PersonalDistance(victim, target)>20) {
target->SetPosition( victim->Pos, true, 0 );
target->SetColorMod(0xff, RGBModifier::ADD, 0x50, 0xff, 0xff, 0xff, 0);
@@ -6164,7 +6788,7 @@ int fx_teleport_to_target (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x113 HideInShadowsModifier
int fx_hide_in_shadows_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_hide_in_shadows_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_hide_in_shadows_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_HIDEINSHADOWS );
return FX_APPLIED;
}
@@ -6172,7 +6796,7 @@ int fx_hide_in_shadows_modifier (Scriptable* /*Owner*/, Actor* target, Effect* f
// 0x114 DetectIllusionsModifier
int fx_detect_illusion_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_detect_illusion_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_detect_illusion_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_DETECTILLUSIONS );
return FX_APPLIED;
}
@@ -6180,33 +6804,31 @@ int fx_detect_illusion_modifier (Scriptable* /*Owner*/, Actor* target, Effect* f
// 0x115 SetTrapsModifier
int fx_set_traps_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_traps_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_set_traps_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_SETTRAPS );
return FX_APPLIED;
}
// 0x116 ToHitBonusModifier
int fx_to_hit_bonus_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_to_hit_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_to_hit_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
HandleBonus( target, IE_HITBONUS, fx->Parameter1, fx->TimingMode );
- return FX_APPLIED;
+ return FX_PERMANENT;
}
// 0x117 RenableButton
-static EffectRef fx_disable_button_ref = { "DisableButton", -1 };
-
int fx_renable_button (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
//removes the disable button effect
- if (0) printf( "fx_renable_button (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
- target->fxqueue.RemoveAllEffectsWithParam( fx_disable_button_ref, fx->Parameter2 );
+ if(0) print("fx_renable_button(%2d): Type: %d", fx->Opcode, fx->Parameter2);
+ target->fxqueue.RemoveAllEffectsWithParamAndResource( fx_disable_button_ref, fx->Parameter2, fx->Resource );
return FX_NOT_APPLIED;
}
// 0x118 ForceSurgeModifier
int fx_force_surge_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_force_surge_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_force_surge_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD_VAR( IE_FORCESURGE, MOD_ABSOLUTE );
return FX_APPLIED;
}
@@ -6214,7 +6836,7 @@ int fx_force_surge_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x119 WildSurgeModifier
int fx_wild_surge_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_wild_surge_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_wild_surge_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_SURGEMOD );
return FX_APPLIED;
}
@@ -6222,7 +6844,7 @@ int fx_wild_surge_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x11a ScriptingState
int fx_scripting_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_scripting_state (%2d): Value: %d, Stat: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_scripting_state(%2d): Value: %d, Stat: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//original engine didn't check boundaries, causing crashes
//we allow only positive indices (some extra stats are still addressable)
@@ -6237,7 +6859,7 @@ int fx_scripting_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x11b ApplyEffectCurse
int fx_apply_effect_curse (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_apply_effect_curse (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_apply_effect_curse(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//this effect executes a file effect in place of this effect
//the file effect inherits the target and the timingmode, but gets
@@ -6272,7 +6894,7 @@ int fx_apply_effect_curse (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x11c MeleeHitModifier
int fx_melee_to_hit_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_melee_to_hit_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_melee_to_hit_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_MELEETOHIT );
return FX_APPLIED;
}
@@ -6280,7 +6902,7 @@ int fx_melee_to_hit_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x11d MeleeDamageModifier
int fx_melee_damage_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_melee_damage_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_melee_damage_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_MELEEDAMAGE );
return FX_APPLIED;
}
@@ -6288,7 +6910,7 @@ int fx_melee_damage_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x11e MissileDamageModifier
int fx_missile_damage_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_missile_damage_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_missile_damage_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_MISSILEDAMAGE );
return FX_APPLIED;
}
@@ -6296,7 +6918,7 @@ int fx_missile_damage_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx
// 0x11f NoCircleState
int fx_no_circle_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_missile_damage_modifier (%2d)\n", fx->Opcode);
+ if(0) print("fx_no_circle_state(%2d)", fx->Opcode);
STAT_SET( IE_NOCIRCLE, 1 );
return FX_APPLIED;
}
@@ -6304,7 +6926,7 @@ int fx_no_circle_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x120 FistHitModifier
int fx_fist_to_hit_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_fist_to_hit_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_fist_to_hit_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_FISTHIT );
return FX_APPLIED;
}
@@ -6312,14 +6934,14 @@ int fx_fist_to_hit_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x121 FistDamageModifier
int fx_fist_damage_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_fist_damage_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_fist_damage_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_FISTDAMAGE );
return FX_APPLIED;
}
//0x122 TitleModifier
int fx_title_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_fist_damage_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_fist_damage_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (fx->Parameter2) {
STAT_SET( IE_TITLE2, fx->Parameter1 );
} else {
@@ -6333,7 +6955,7 @@ int fx_title_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//make the bit correspond to it
int fx_disable_overlay_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_disable_overlay_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_disable_overlay_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_SET( IE_DISABLEOVERLAY, fx->Parameter1 );
return FX_APPLIED;
}
@@ -6342,7 +6964,7 @@ int fx_disable_overlay_modifier (Scriptable* /*Owner*/, Actor* target, Effect* f
//3 different games, 3 different methods of flagging this
int fx_no_backstab_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_no_backstab_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_no_backstab_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//bg2
STAT_SET( IE_DISABLEBACKSTAB, fx->Parameter1 );
//how
@@ -6354,7 +6976,7 @@ int fx_no_backstab_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0x125 OffscreenAIModifier
int fx_offscreenai_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_offscreenai_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_offscreenai_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_SET( IE_ENABLEOFFSCREENAI, fx->Parameter1 );
target->Activate();
return FX_APPLIED;
@@ -6362,14 +6984,14 @@ int fx_offscreenai_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0x126 ExistanceDelayModifier
int fx_existance_delay_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_existance_delay_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_existance_delay_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_SET( IE_EXISTANCEDELAY, fx->Parameter1 );
return FX_APPLIED;
}
//0x127 DisableChunk
int fx_disable_chunk_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_disable_chunk_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_disable_chunk_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_SET( IE_DISABLECHUNKING, fx->Parameter1 );
return FX_APPLIED;
}
@@ -6378,7 +7000,7 @@ int fx_disable_chunk_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0x128 Protection:Animation
int fx_protection_from_animation (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_protection_from_animation (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_protection_from_animation(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//remove vvc from actor if active
target->RemoveVVCell(fx->Resource, false);
return FX_APPLIED;
@@ -6388,7 +7010,7 @@ int fx_protection_from_animation (Scriptable* /*Owner*/, Actor* target, Effect*
//0x129 Protection:Turn
int fx_protection_from_turn (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_non_interruptible_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_non_interruptible_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_SET( IE_NOTURNABLE, fx->Parameter1 );
return FX_APPLIED;
}
@@ -6396,21 +7018,38 @@ int fx_protection_from_turn (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//runs a predetermined script in cutscene mode
int fx_cutscene2 (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
{
+ int i;
Game *game;
ieResRef resref;
- if (0) printf( "fx_cutscene2 (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_cutscene2(%2d): Locations: %d Resource: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (core->InCutSceneMode()) return FX_NOT_APPLIED;
game = core->GetGame();
if (!game) return FX_NOT_APPLIED;
- game->ClearPlaneLocations();
- for (int i = 0; i < game->GetPartySize(false); i++) {
- Actor* act = game->GetPC( i, false );
- GAMLocationEntry *gle = game->GetPlaneLocationEntry(i);
- if (act && gle) {
- gle->Pos = act->Pos;
- memcpy(gle->AreaResRef, act->Area, 9);
+ switch(fx->Parameter1) {
+ case 1://simple party locations
+ game->ClearSavedLocations();
+ for (i = 0; i < game->GetPartySize(false); i++) {
+ Actor* act = game->GetPC( i, false );
+ GAMLocationEntry *gle = game->GetSavedLocationEntry(i);
+ if (act && gle) {
+ gle->Pos = act->Pos;
+ memcpy(gle->AreaResRef, act->Area, 9);
+ }
+ }
+ break;
+ case 2: //no store
+ break;
+ default://original plane locations
+ game->ClearPlaneLocations();
+ for (i = 0; i < game->GetPartySize(false); i++) {
+ Actor* act = game->GetPC( i, false );
+ GAMLocationEntry *gle = game->GetPlaneLocationEntry(i);
+ if (act && gle) {
+ gle->Pos = act->Pos;
+ memcpy(gle->AreaResRef, act->Area, 9);
+ }
}
}
@@ -6431,7 +7070,7 @@ int fx_cutscene2 (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
//0x12b ChaosShieldModifier
int fx_chaos_shield_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_chaos_shield_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_chaos_shield_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_ADD( IE_CHAOSSHIELD, fx->Parameter1 );
if (fx->Parameter2) {
target->AddPortraitIcon(PI_CSHIELD); //162
@@ -6443,7 +7082,7 @@ int fx_chaos_shield_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0x12c NPCBump
int fx_npc_bump (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_npc_bump (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_npc_bump(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//unknown effect, but known stat position
STAT_MOD( IE_NPCBUMP );
return FX_APPLIED;
@@ -6451,14 +7090,14 @@ int fx_npc_bump (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0x12d CriticalHitModifier
int fx_critical_hit_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_critical_hit_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_critical_hit_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_CRITICALHITBONUS );
return FX_APPLIED;
}
// 0x12e CanUseAnyItem
int fx_can_use_any_item_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_can_use_any_item_modifier (%2d): Value: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_can_use_any_item_modifier(%2d): Value: %d", fx->Opcode, fx->Parameter2);
STAT_SET( IE_CANUSEANYITEM, fx->Parameter2 );
return FX_APPLIED;
@@ -6467,7 +7106,7 @@ int fx_can_use_any_item_modifier (Scriptable* /*Owner*/, Actor* target, Effect*
// 0x12f AlwaysBackstab
int fx_always_backstab_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_always_backstab_modifier (%2d): Value: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_always_backstab_modifier(%2d): Value: %d", fx->Opcode, fx->Parameter2);
STAT_SET( IE_ALWAYSBACKSTAB, fx->Parameter2 );
return FX_APPLIED;
@@ -6476,7 +7115,7 @@ int fx_always_backstab_modifier (Scriptable* /*Owner*/, Actor* target, Effect* f
// 0x130 MassRaiseDead
int fx_mass_raise_dead (Scriptable* Owner, Actor* /*target*/, Effect* fx)
{
- if (0) printf( "fx_mass_raise_dead (%2d)\n", fx->Opcode );
+ if(0) print("fx_mass_raise_dead(%2d)", fx->Opcode);
Game *game=core->GetGame();
@@ -6492,7 +7131,7 @@ int fx_mass_raise_dead (Scriptable* Owner, Actor* /*target*/, Effect* fx)
// 0x131 OffhandHitModifier
int fx_left_to_hit_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_left_to_hit_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_left_to_hit_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_HITBONUSLEFT );
return FX_APPLIED;
@@ -6501,7 +7140,7 @@ int fx_left_to_hit_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x132 RightHitModifier
int fx_right_to_hit_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_right_to_hit_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_right_to_hit_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_HITBONUSRIGHT );
return FX_APPLIED;
@@ -6510,7 +7149,7 @@ int fx_right_to_hit_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x133 Reveal:Tracks
int fx_reveal_tracks (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_reveal_tracks (%2d): Distance: %d\n", fx->Opcode, fx->Parameter1 );
+ if(0) print("fx_reveal_tracks(%2d): Distance: %d", fx->Opcode, fx->Parameter1);
Map *map = target->GetCurrentArea();
if (!map) return FX_APPLIED;
if (!fx->Parameter2) {
@@ -6531,7 +7170,7 @@ int fx_reveal_tracks (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x134 Protection:Tracking
int fx_protection_from_tracking (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_protection_from_tracking (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_protection_from_tracking(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_NOTRACKING ); //highlight creature???
return FX_APPLIED;
@@ -6549,7 +7188,7 @@ int fx_modify_local_variable (Scriptable* /*Owner*/, Actor* target, Effect* fx)
memmove(poi, fx->Resource4, 8);
fx->IsVariable=1;
}
- if (0) printf( "fx_modify_local_variable (%2d): %s, Mod: %d\n", fx->Opcode, fx->Resource, fx->Parameter2 );
+ if(0) print("fx_modify_local_variable(%2d): %s, Mod: %d", fx->Opcode, fx->Resource, fx->Parameter2);
if (fx->Parameter2) {
ieDword var = 0;
//use resource memory area as variable name
@@ -6564,7 +7203,7 @@ int fx_modify_local_variable (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 0x136 TimelessState
int fx_timeless_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_timeless_modifier (%2d): Mod: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_timeless_modifier(%2d): Mod: %d", fx->Opcode, fx->Parameter2);
STAT_SET(IE_DISABLETIMESTOP, fx->Parameter2);
return FX_APPLIED;
}
@@ -6575,7 +7214,7 @@ int fx_generate_wish (Scriptable* Owner, Actor* target, Effect* fx)
{
ieResRef spl;
- if (0) printf( "fx_generate_wish (%2d): Mod: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_generate_wish(%2d): Mod: %d", fx->Opcode, fx->Parameter2);
if (!fx->Parameter2) {
fx->Parameter2=IE_WIS;
}
@@ -6609,7 +7248,7 @@ int fx_generate_wish (Scriptable* Owner, Actor* target, Effect* fx)
//0x138 //see fx_crash, this effect is not fully enabled in original bg2/tob
int fx_immunity_sequester (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_immunity_sequester (%2d): Mod: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_immunity_sequester(%2d): Mod: %d", fx->Opcode, fx->Parameter2);
//this effect is supposed to provide immunity against sequester (maze/etc?)
STAT_SET(IE_NOSEQUESTER, fx->Parameter2);
return FX_APPLIED;
@@ -6619,8 +7258,9 @@ int fx_immunity_sequester (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0x13a StoneSkin2Modifier
int fx_golem_stoneskin_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_golem_stoneskin_modifier (%2d): Mod: %d\n", fx->Opcode, fx->Parameter1 );
+ if(0) print("fx_golem_stoneskin_modifier(%2d): Mod: %d", fx->Opcode, fx->Parameter1);
if (!fx->Parameter1) {
+ PlayRemoveEffect("EFF_E02",target, fx);
return FX_NOT_APPLIED;
}
//dead actors lose this effect
@@ -6629,14 +7269,14 @@ int fx_golem_stoneskin_modifier (Scriptable* /*Owner*/, Actor* target, Effect* f
}
STAT_SET(IE_STONESKINSGOLEM, fx->Parameter1);
- SetGradient(target, 14);
+ SetGradient(target, fullstone);
return FX_APPLIED;
}
// 0x13b AvatarRemovalModifier (also 0x104 iwd)
int fx_avatar_removal_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_avatar_removal_modifier (%2d): Mod: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_avatar_removal_modifier(%2d): Mod: %d", fx->Opcode, fx->Parameter2);
STAT_SET(IE_AVATARREMOVAL, fx->Parameter2);
return FX_APPLIED;
}
@@ -6644,9 +7284,10 @@ int fx_avatar_removal_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx
// 0x13c MagicalRest (also 0x124 iwd)
int fx_magical_rest (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_magical_rest (%2d)\n", fx->Opcode );
+ if(0) print("fx_magical_rest(%2d)", fx->Opcode);
//instant, full rest
target->Rest(0);
+ target->fxqueue.RemoveAllEffects(fx_fatigue_ref);
target->fxqueue.RemoveAllEffectsWithParam(fx_display_portrait_icon_ref, PI_FATIGUE);
return FX_NOT_APPLIED;
}
@@ -6661,9 +7302,9 @@ int fx_magical_rest (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// 3 fog
int fx_change_weather (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
{
- printf( "fx_change_weather (%2d): P1: %d\n", fx->Opcode, fx->Parameter1 );
+ print("fx_change_weather(%2d): P1: %d", fx->Opcode, fx->Parameter1);
- core->GetGame()->StartRainOrSnow(false, fx->Parameter1 & WB_MASK);
+ core->GetGame()->StartRainOrSnow(false, fx->Parameter1 & WB_TYPEMASK);
return FX_NOT_APPLIED;
}
@@ -6671,7 +7312,7 @@ int fx_change_weather (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
// unknown
int fx_unknown (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
{
- printf( "fx_unknown (%2d): P1: %d P2: %d ResRef: %s\n", fx->Opcode, fx->Parameter1, fx->Parameter2, fx->Resource );
+ print("fx_unknown(%2d): P1: %d P2: %d ResRef: %s", fx->Opcode, fx->Parameter1, fx->Parameter2, fx->Resource);
return FX_NOT_APPLIED;
}
diff --git a/gemrb/plugins/GAMImporter/GAMImporter.cpp b/gemrb/plugins/GAMImporter/GAMImporter.cpp
index b04942b..df08a01 100644
--- a/gemrb/plugins/GAMImporter/GAMImporter.cpp
+++ b/gemrb/plugins/GAMImporter/GAMImporter.cpp
@@ -27,10 +27,15 @@
#include "GameData.h"
#include "Interface.h"
#include "MapMgr.h"
-#include "System/MemoryStream.h"
+#include "PluginMgr.h"
+#include "TableMgr.h"
+#include "Scriptable/Actor.h"
+#include "System/SlicedStream.h"
#include <cassert>
+using namespace GemRB;
+
#define FAMILIAR_FILL_SIZE 324
// if your compiler chokes on this, use -1 or 0xff whichever works for you
#define UNINITIALIZED_CHAR '\xff'
@@ -38,17 +43,14 @@
GAMImporter::GAMImporter(void)
{
str = NULL;
- autoFree = false;
}
GAMImporter::~GAMImporter(void)
{
- if (str && autoFree) {
- delete( str );
- }
+ delete str;
}
-bool GAMImporter::Open(DataStream* stream, bool autoFree)
+bool GAMImporter::Open(DataStream* stream)
{
if (stream == NULL) {
return false;
@@ -57,7 +59,6 @@ bool GAMImporter::Open(DataStream* stream, bool autoFree)
return false;
}
str = stream;
- this->autoFree = autoFree;
char Signature[8];
str->Read( Signature, 8 );
if (strncmp( Signature, "GAMEV0.0", 8 ) == 0) {
@@ -94,7 +95,7 @@ bool GAMImporter::Open(DataStream* stream, bool autoFree)
version=GAM_VER_BG;
}
} else {
- printMessage( "GAMImporter","This file is not a valid GAM File\n", LIGHT_RED );
+ Log(ERROR, "GAMImporter", "This file is not a valid GAM File");
return false;
}
@@ -132,7 +133,7 @@ Game* GAMImporter::LoadGame(Game *newGame, int ver_override)
}
str->ReadDword( &newGame->PartyGold );
//npc count in party???
- str->ReadWord( &newGame->NpcInParty );
+ str->ReadWord( &newGame->NpcInParty ); //in ToB this is named 'nPCAreaViewed'
str->ReadWord( &newGame->WeatherBits );
str->ReadDword( &PCOffset );
str->ReadDword( &PCCount );
@@ -145,14 +146,14 @@ Game* GAMImporter::LoadGame(Game *newGame, int ver_override)
str->ReadDword( &GlobalOffset );
str->ReadDword( &GlobalCount );
str->ReadResRef( newGame->CurrentArea );
- str->ReadDword( &newGame->Unknown48 );//this is still unknown
+ str->ReadDword( &newGame->CurrentLink );//in ToB this is named 'currentLink'
str->ReadDword( &JournalCount );
str->ReadDword( &JournalOffset );
switch (version) {
default:
MazeOffset = 0;
str->ReadDword( &newGame->Reputation );
- str->ReadResRef( newGame->CurrentArea ); // FIXME: see above
+ str->ReadResRef( newGame->CurrentArea ); // FIXME: this is the 'master area'
memcpy(newGame->AnotherArea, newGame->CurrentArea, sizeof(ieResRef) );
str->ReadDword( &newGame->ControlStatus );
str->ReadDword( &newGame->Expansion );
@@ -319,15 +320,14 @@ Game* GAMImporter::LoadGame(Game *newGame, int ver_override)
return newGame;
}
-void SanityCheck(ieWord a,ieWord &b,const char *message)
+static void SanityCheck(ieWord a,ieWord &b,const char *message)
{
if (a==0xffff) {
b=0xffff;
return;
}
if (b==0xffff) {
- printMessage("GAMImporter"," ",LIGHT_RED);
- printf("Invalid Slot Enabler caught: %s!\n", message);
+ Log(ERROR, "GAMImporter", "Invalid Slot Enabler caught: %s!", message);
b=0;
}
}
@@ -393,21 +393,19 @@ Actor* GAMImporter::GetActor(Holder<ActorMgr> aM, bool is_in_party )
//quick innates
//we spare some memory and time by storing them in the same place
//this may be slightly buggy because IWD2 doesn't clear the
- //fields, but QuickSpellClass is set correctly, problem is
- //that GemRB doesn't clear QuickSpellClass
+ //fields, but QuickSpellClass is set correctly
for (i = 0; i < MAX_QSLOTS; i++) {
str->Read( tmp, 8 );
- if ((tmp[0]!=0) && (pcInfo.QuickSpellResRef[0]==0)) {
+ if ((tmp[0]!=0) && (pcInfo.QuickSpellResRef[i][0]==0)) {
memcpy( pcInfo.QuickSpellResRef[i], tmp, 8);
//innates
pcInfo.QuickSpellClass[i]=0xff;
}
}
//recently discovered fields (bard songs)
- //str->Seek( 72, GEM_CURRENT_POS);
for(i = 0; i<MAX_QSLOTS;i++) {
str->Read( tmp, 8 );
- if ((tmp[0]!=0) && (pcInfo.QuickSpellResRef[0]==0)) {
+ if ((tmp[0]!=0) && (pcInfo.QuickSpellResRef[i][0]==0)) {
memcpy( pcInfo.QuickSpellResRef[i], tmp, 8);
//bardsongs
pcInfo.QuickSpellClass[i]=0xfe;
@@ -468,17 +466,11 @@ Actor* GAMImporter::GetActor(Holder<ActorMgr> aM, bool is_in_party )
tmpWord = is_in_party ? (pcInfo.PartyOrder + 1) : 0;
if (pcInfo.OffsetToCRE) {
- str->Seek( pcInfo.OffsetToCRE, GEM_STREAM_START );
- void* Buffer = malloc( pcInfo.CRESize );
- str->Read( Buffer, pcInfo.CRESize );
- //somehow autofree MemoryStream doesn't work on msvc 7.0
- //separate heap for dll's?
- MemoryStream* ms = new MemoryStream( Buffer, pcInfo.CRESize, false );
+ DataStream* ms = SliceStream( str, pcInfo.OffsetToCRE, pcInfo.CRESize );
if (ms) {
- aM->Open( ms, true );
+ aM->Open(ms);
actor = aM->GetActor(tmpWord);
}
- free (Buffer);
//torment has them as 0 or -1
if (pcInfo.Name[0]!=0 && pcInfo.Name[0]!=UNINITIALIZED_CHAR) {
@@ -491,7 +483,7 @@ Actor* GAMImporter::GetActor(Holder<ActorMgr> aM, bool is_in_party )
//another plugin cannot free memory stream from this plugin
//so auto free is a no-no
if (ds) {
- aM->Open( ds, true );
+ aM->Open(ds);
actor = aM->GetActor(pcInfo.PartyOrder);
}
}
@@ -841,7 +833,7 @@ int GAMImporter::PutHeader(DataStream *stream, Game *game)
stream->WriteDword( &GlobalOffset );
stream->WriteDword( &GlobalCount );
stream->WriteResRef( game->CurrentArea );
- stream->WriteDword( &game->Unknown48 );
+ stream->WriteDword( &game->CurrentLink );
stream->WriteDword( &JournalCount );
stream->WriteDword( &JournalOffset );
diff --git a/gemrb/plugins/GAMImporter/GAMImporter.h b/gemrb/plugins/GAMImporter/GAMImporter.h
index fba05f0..f55dee9 100644
--- a/gemrb/plugins/GAMImporter/GAMImporter.h
+++ b/gemrb/plugins/GAMImporter/GAMImporter.h
@@ -25,6 +25,8 @@
#include "ActorMgr.h"
+namespace GemRB {
+
#define GAM_VER_GEMRB 0
#define GAM_VER_BG 10
#define GAM_VER_IWD 11
@@ -36,7 +38,6 @@
class GAMImporter : public SaveGameMgr {
private:
DataStream* str;
- bool autoFree;
int version;
unsigned int PCSize;
ieDword PCOffset, PCCount;
@@ -51,7 +52,7 @@ private:
public:
GAMImporter(void);
~GAMImporter(void);
- bool Open(DataStream* stream, bool autoFree = true);
+ bool Open(DataStream* stream);
Game* LoadGame(Game *newGame, int ver_override = 0);
int GetStoredFileSize(Game *game);
@@ -80,4 +81,6 @@ private:
};
#endif
+}
+
diff --git a/gemrb/plugins/GUIScript/CMakeLists.txt b/gemrb/plugins/GUIScript/CMakeLists.txt
index 54131e9..277efe5 100644
--- a/gemrb/plugins/GUIScript/CMakeLists.txt
+++ b/gemrb/plugins/GUIScript/CMakeLists.txt
@@ -1,5 +1,3 @@
-INCLUDE(FindPythonLibs)
-
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})
ADD_GEMRB_PLUGIN (GUIScript GUIScript.cpp PythonHelpers.cpp)
TARGET_LINK_LIBRARIES(GUIScript ${PYTHON_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS})
diff --git a/gemrb/plugins/GUIScript/GUIScript.cpp b/gemrb/plugins/GUIScript/GUIScript.cpp
index f44184c..b569741 100644
--- a/gemrb/plugins/GUIScript/GUIScript.cpp
+++ b/gemrb/plugins/GUIScript/GUIScript.cpp
@@ -23,6 +23,7 @@
#include "PythonHelpers.h"
#include "Audio.h"
+#include "CharAnimations.h"
#include "ControlAnimation.h"
#include "DataFileMgr.h"
#include "DialogHandler.h"
@@ -41,24 +42,32 @@
#include "ResourceDesc.h"
#include "SaveGameIterator.h"
#include "Spell.h"
+#include "TableMgr.h"
#include "TileMap.h"
#include "Video.h"
#include "WorldMap.h"
#include "GameScript/GSUtils.h" //checkvariable
#include "GUI/Button.h"
+#include "GUI/EventMgr.h"
#include "GUI/GameControl.h"
#include "GUI/Label.h"
#include "GUI/MapControl.h"
+#include "GUI/TextArea.h"
#include "GUI/TextEdit.h"
+#include "GUI/Window.h"
#include "GUI/WorldMapControl.h"
#include "Scriptable/Container.h"
#include "Scriptable/Door.h"
#include "Scriptable/InfoPoint.h"
+#include "System/FileStream.h"
+#include "System/Logger/MessageWindowLogger.h"
#include "System/VFS.h"
#include <cstdio>
-GUIScript *gs = NULL;
+using namespace GemRB;
+
+GUIScript *GemRB::gs = NULL;
//this stuff is missing from Python 2.2
#ifndef PyDoc_VAR
@@ -93,6 +102,9 @@ static int ItemSoundsCount = -1;
//bit used in SetCreatureStat to access some fields
#define EXTRASETTINGS 0x1000
+//maximum distance for passing items between two characters
+#define MAX_DISTANCE 500
+
struct UsedItemType {
ieResRef itemname;
ieVariable username; //death variable
@@ -102,7 +114,7 @@ struct UsedItemType {
typedef char EventNameType[17];
#define IS_DROP 0
-#define IS_GET 1
+#define IS_GET 1
typedef ieResRef ResRefPairs[2];
@@ -151,10 +163,10 @@ inline PyObject* PyString_FromAnimID(const char* AnimID)
*/
inline PyObject* RuntimeError(const char* msg)
{
- printMessage( "GUIScript", "Runtime Error:\n", LIGHT_RED );
+ Log(ERROR, "GUIScript", "Runtime Error:");
PyErr_SetString( PyExc_RuntimeError, msg );
if (QuitOnError) {
- core->Quit();
+ core->ExitGemRB();
}
return NULL;
}
@@ -166,10 +178,10 @@ inline PyObject* RuntimeError(const char* msg)
*/
inline PyObject* AttributeError(const char* doc_string)
{
- printMessage( "GUIScript", "Syntax Error:\n", LIGHT_RED );
+ Log(ERROR, "GUIScript", "Syntax Error:");
PyErr_SetString(PyExc_AttributeError, doc_string);
if (QuitOnError) {
- core->Quit();
+ core->ExitGemRB();
}
return NULL;
}
@@ -192,6 +204,17 @@ inline PyObject* AttributeError(const char* doc_string)
return RuntimeError("Can't find GameControl!"); \
}
+#define GET_ACTOR_GLOBAL() \
+ Actor* actor; \
+ if (globalID > 1000) { \
+ actor = game->GetActorByGlobalID( globalID ); \
+ } else { \
+ actor = game->FindPC( globalID ); \
+ } \
+ if (!actor) { \
+ return RuntimeError( "Actor not found!\n" ); \
+ }
+
inline Control *GetControl( int wi, int ci, int ct)
{
char errorbuffer[256];
@@ -217,24 +240,23 @@ inline Control *GetControl( int wi, int ci, int ct)
}
//sets tooltip with Fx key prepended
-static inline void SetFunctionTooltip(int WindowIndex, int ControlIndex, char *txt, int Function)
+static int SetFunctionTooltip(int WindowIndex, int ControlIndex, char *txt, int Function)
{
if (txt) {
if (txt[0]) {
char *txt2 = (char *) malloc(strlen(txt)+10);
- if (Function) {
- sprintf(txt2,"F%d - %s",Function,txt);
- } else {
- sprintf(txt2,"F%d - %s",ControlIndex+1,txt);
+ if (!Function) {
+ Function = ControlIndex+1;
}
+ sprintf(txt2,"F%d - %s",Function,txt);
core->FreeString(txt);
- core->SetTooltip((ieWord) WindowIndex, (ieWord) ControlIndex, txt2);
+ int ret = core->SetTooltip((ieWord) WindowIndex, (ieWord) ControlIndex, txt2, Function);
free (txt2);
- return;
+ return ret;
}
core->FreeString(txt);
}
- core->SetTooltip((ieWord) WindowIndex, (ieWord) ControlIndex, "");
+ return core->SetTooltip((ieWord) WindowIndex, (ieWord) ControlIndex, "", -1);
}
static void ReadItemSounds()
@@ -283,6 +305,7 @@ static int GetCreatureStrRef(Actor *actor, unsigned int Str)
return actor->StrRefs[Str];
}
+
static inline bool CheckStat(Actor * actor, ieDword stat, ieDword value, int op)
{
int dc = DiffCore(actor->GetBase(stat), value, op);
@@ -309,6 +332,14 @@ static int GetCreatureStat(Actor *actor, unsigned int StatID, int Mod)
static int SetCreatureStat(Actor *actor, unsigned int StatID, int StatValue, bool pcf)
{
+ // special AC handling
+ if (StatID == IE_ARMORCLASS) {
+ actor->AC.SetNatural(StatValue);
+ return 1;
+ } else if (StatID == IE_TOHIT) {
+ actor->ToHit.SetBase(StatValue);
+ return 1;
+ }
//this is a hack, if more PCStats fields are needed, improve it
if (StatID&EXTRASETTINGS) {
PCStatsStruct *ps = actor->PCStats;
@@ -317,6 +348,7 @@ static int SetCreatureStat(Actor *actor, unsigned int StatID, int StatValue, boo
}
StatID&=15;
ps->ExtraSettings[StatID] = StatValue;
+ actor->ApplyExtraSettings();
return 1;
}
@@ -340,7 +372,7 @@ static CREItem *CreateCreItem(const char *ItemResRef, int Charge0, int Charge1,
TmpItem->Usages[1]=(ieWord) Charge1;
TmpItem->Usages[2]=(ieWord) Charge2;
TmpItem->Flags=0;
- if (core->ResolveRandomItem(TmpItem) && gamedata->Exists(TmpItem->ItemResRef, IE_ITM_CLASS_ID)) {
+ if (core->ResolveRandomItem(TmpItem)) {
return TmpItem;
}
/* item couldn't be resolved */
@@ -354,12 +386,12 @@ PyDoc_STRVAR( GemRB_SetInfoTextColor__doc,
static PyObject* GemRB_SetInfoTextColor(PyObject*, PyObject* args)
{
- int r,g,b,a;
+ int r, g, b, a;
if (!PyArg_ParseTuple( args, "iii|i", &r, &g, &b, &a)) {
return AttributeError( GemRB_SetInfoTextColor__doc );
}
- Color c = {r,g,b,a};
+ const Color c = {(ieByte) r,(ieByte) g,(ieByte) b,(ieByte) a};
core->SetInfoTextColor( c );
Py_INCREF( Py_None );
return Py_None;
@@ -421,6 +453,8 @@ static PyObject* GemRB_GetGameString(PyObject*, PyObject* args)
return PyString_FromString( game->LoadMos );
case 1:
return PyString_FromString( game->CurrentArea );
+ case 2:
+ return PyString_FromString( game->TextScreen );
}
}
@@ -496,14 +530,14 @@ static PyObject* GemRB_TextArea_MoveText(PyObject * /*self*/, PyObject* args)
}
PyDoc_STRVAR( GemRB_TextArea_Rewind__doc,
-"RewindTA(Win, Ctrl, Ticks)\n\n"
-"Sets up a TextArea for scrolling. Ticks is the delay between the steps in scrolling.");
+"RewindTA(Win, Ctrl)\n\n"
+"Sets up a TextArea for scrolling.");
static PyObject* GemRB_TextArea_Rewind(PyObject * /*self*/, PyObject* args)
{
- int Win, Ctrl, Ticks;
+ int Win, Ctrl;
- if (!PyArg_ParseTuple( args, "iii", &Win, &Ctrl, &Ticks)) {
+ if (!PyArg_ParseTuple( args, "ii", &Win, &Ctrl)) {
return AttributeError( GemRB_TextArea_Rewind__doc );
}
@@ -512,7 +546,8 @@ static PyObject* GemRB_TextArea_Rewind(PyObject * /*self*/, PyObject* args)
return NULL;
}
- ctrl->SetupScroll(Ticks);
+ core->GetAudioDrv()->Play( NULL, 0, 0, GEM_SND_RELATIVE|GEM_SND_SPEECH);
+ ctrl->SetupScroll();
Py_INCREF( Py_None );
return Py_None;
}
@@ -620,8 +655,8 @@ static PyObject* GemRB_LoadWindowPack(PyObject * /*self*/, PyObject* args)
if ( (width && (width>core->Width)) ||
(height && (height>core->Height)) ) {
- printMessage("GUIScript","Screen is too small!\n",LIGHT_RED);
- printf("This window requires %d x %d resolution.\n",width,height);
+ Log(ERROR, "GUIScript", "Screen is too small! This window requires %d x %d resolution.",
+ width, height);
return RuntimeError("Please change your settings.");
}
Py_INCREF( Py_None );
@@ -804,7 +839,8 @@ PyDoc_STRVAR( GemRB_Window_SetPos__doc,
static PyObject* GemRB_Window_SetPos(PyObject * /*self*/, PyObject* args)
{
- int WindowIndex, X, Y, Flags = WINDOW_TOPLEFT;
+ int WindowIndex, X, Y;
+ int Flags = WINDOW_TOPLEFT;
if (!PyArg_ParseTuple( args, "iii|i", &WindowIndex, &X, &Y, &Flags )) {
return AttributeError( GemRB_Window_SetPos__doc );
@@ -835,10 +871,9 @@ static PyObject* GemRB_Window_SetPos(PyObject * /*self*/, PyObject* args)
// Keep window within screen
// FIXME: keep it within gamecontrol
if (Flags & WINDOW_BOUNDED) {
- // FIXME: grrrr, should be < 0!!!
- if (X > 32767 || X < 0)
+ if ((ieWordSigned) X < 0)
X = 0;
- if (Y > 32767 || Y < 0)
+ if ((ieWordSigned) Y < 0)
Y = 0;
if (X + win->Width >= core->Width)
@@ -855,6 +890,31 @@ static PyObject* GemRB_Window_SetPos(PyObject * /*self*/, PyObject* args)
return Py_None;
}
+PyDoc_STRVAR( GemRB_Window_GetRect__doc,
+"window.GetRect()\n\n"
+"Returns a dict with the window position and size." );
+
+static PyObject* GemRB_Window_GetRect(PyObject * /*self*/, PyObject* args)
+{
+ int WindowIndex;
+
+ if (!PyArg_ParseTuple( args, "i", &WindowIndex)) {
+ return AttributeError( GemRB_Window_GetRect__doc );
+ }
+
+ Window* win = core->GetWindow( WindowIndex );
+ if (win == NULL) {
+ return RuntimeError("Cannot find window!\n");
+ }
+
+ PyObject* dict = PyDict_New();
+ PyDict_SetItemString(dict, "X", PyInt_FromLong( win->XPos ));
+ PyDict_SetItemString(dict, "Y", PyInt_FromLong( win->YPos ));
+ PyDict_SetItemString(dict, "Width", PyInt_FromLong( win->Width ));
+ PyDict_SetItemString(dict, "Height", PyInt_FromLong( win->Height ));
+ return dict;
+}
+
PyDoc_STRVAR( GemRB_LoadTable__doc,
"LoadTable(2DAResRef, [ignore_error=0]) => GTable\n\n"
"Loads a 2DA Table." );
@@ -869,8 +929,13 @@ static PyObject* GemRB_LoadTable(PyObject * /*self*/, PyObject* args)
}
int ind = gamedata->LoadTable( tablename );
- if (!noerror && ind == -1) {
- return RuntimeError("Can't find resource");
+ if (ind == -1) {
+ if (noerror) {
+ Py_INCREF( Py_None );
+ return Py_None;
+ } else {
+ return RuntimeError("Can't find resource");
+ }
}
return gs->ConstructObject("Table", ind);
}
@@ -931,16 +996,12 @@ static PyObject* GemRB_Table_GetValue(PyObject * /*self*/, PyObject* args)
}
if (PyObject_TypeCheck( row, &PyInt_Type ) &&
( !PyObject_TypeCheck( col, &PyInt_Type ) )) {
- printMessage( "GUIScript",
- "Type Error: RowIndex/RowString and ColIndex/ColString must be the same type\n",
- LIGHT_RED );
+ Log(ERROR, "GUIScript", "Type Error: RowIndex/RowString and ColIndex/ColString must be the same type");
return NULL;
}
if (PyObject_TypeCheck( row, &PyString_Type ) &&
( !PyObject_TypeCheck( col, &PyString_Type ) )) {
- printMessage( "GUIScript",
- "Type Error: RowIndex/RowString and ColIndex/ColString must be the same type\n",
- LIGHT_RED );
+ Log(ERROR, "GUIScript", "Type Error: RowIndex/RowString and ColIndex/ColString must be the same type");
return NULL;
}
Holder<TableMgr> tm = gamedata->GetTable( TableIndex );
@@ -986,16 +1047,25 @@ static PyObject* GemRB_Table_FindValue(PyObject * /*self*/, PyObject* args)
int ti, col;
int start = 0;
long Value;
+ char* colname;
if (!PyArg_ParseTuple( args, "iil|i", &ti, &col, &Value, &start )) {
- return AttributeError( GemRB_Table_FindValue__doc );
+ PyErr_Clear(); //clearing the exception
+ col = -1;
+ if (!PyArg_ParseTuple( args, "isl|i", &ti, &colname, &Value, &start )) {
+ return AttributeError( GemRB_Table_FindValue__doc );
+ }
}
Holder<TableMgr> tm = gamedata->GetTable( ti );
if (tm == NULL) {
return RuntimeError("Can't find resource");
}
- return PyInt_FromLong(tm->FindTableValue(col, Value, start));
+ if (col == -1) {
+ return PyInt_FromLong(tm->FindTableValue(colname, Value, start));
+ } else {
+ return PyInt_FromLong(tm->FindTableValue(col, Value, start));
+ }
}
PyDoc_STRVAR( GemRB_Table_GetRowIndex__doc,
@@ -1221,13 +1291,11 @@ static PyObject* GemRB_Window_GetControl(PyObject * /*self*/, PyObject* args)
int ctrlindex = core->GetControl(WindowIndex, ControlID);
if (ctrlindex == -1) {
- return RuntimeError( "Control is not found" );
+ char tmp[40];
+ snprintf(tmp, sizeof(tmp), "Control (ID: %d) was not found!", ControlID);
+ return RuntimeError(tmp);
}
- PyObject* ctrltuple = PyTuple_New(2);
- PyTuple_SET_ITEM(ctrltuple, 0, PyInt_FromLong(WindowIndex));
- PyTuple_SET_ITEM(ctrltuple, 1, PyInt_FromLong(ctrlindex));
-
PyObject* ret = 0;
Control *ctrl = GetControl(WindowIndex, ctrlindex, -1);
if (!ctrl) {
@@ -1256,6 +1324,7 @@ static PyObject* GemRB_Window_GetControl(PyObject * /*self*/, PyObject* args)
default:
break;
}
+ PyObject* ctrltuple = Py_BuildValue("(ii)", WindowIndex, ctrlindex);
ret = gs->ConstructObject(type, ctrltuple);
Py_DECREF(ctrltuple);
@@ -1393,7 +1462,6 @@ static PyObject* GemRB_Control_SetText(PyObject * /*self*/, PyObject* args)
PyObject* wi, * ci, * str;
long WindowIndex, ControlIndex, StrRef;
char* string;
- int ret;
if (!PyArg_UnpackTuple( args, "ref", 3, 3, &wi, &ci, &str )) {
return AttributeError( GemRB_Control_SetText__doc );
@@ -1408,29 +1476,29 @@ static PyObject* GemRB_Control_SetText(PyObject * /*self*/, PyObject* args)
WindowIndex = PyInt_AsLong( wi );
ControlIndex = PyInt_AsLong( ci );
+ Control *ctrl = GetControl(WindowIndex, ControlIndex, -1);
+ if (!ctrl) {
+ return RuntimeError("Invalid Control");
+ }
+
if (PyObject_TypeCheck( str, &PyString_Type )) {
string = PyString_AsString( str );
if (string == NULL) {
return RuntimeError("Null string received");
}
- ret = core->SetText( (ieWord) WindowIndex, (ieWord) ControlIndex, string );
- if (ret == -1) {
- return RuntimeError("Cannot set text");
- }
+ ctrl->SetText(string);
} else {
StrRef = PyInt_AsLong( str );
if (StrRef == -1) {
- ret = core->SetText( (ieWord) WindowIndex, (ieWord) ControlIndex, GEMRB_STRING );
+ ctrl->SetText(GEMRB_STRING);
} else {
char *tmpstr = core->GetString( StrRef );
- ret = core->SetText( (ieWord) WindowIndex, (ieWord) ControlIndex, tmpstr );
+ ctrl->SetText(tmpstr);
core->FreeString( tmpstr );
}
- if (ret == -1) {
- return RuntimeError("Cannot set text");
- }
}
- return PyInt_FromLong( ret );
+ Py_INCREF(Py_None);
+ return Py_None;
}
PyDoc_STRVAR( GemRB_TextArea_Append__doc,
@@ -1467,8 +1535,7 @@ static PyObject* GemRB_TextArea_Append(PyObject * /*self*/, PyObject* args)
}
if (row) {
if (!PyObject_TypeCheck( row, &PyInt_Type )) {
- printMessage( "GUIScript",
- "Syntax Error: AppendText row must be integer\n", LIGHT_RED );
+ Log(ERROR, "GUIScript", "Syntax Error: AppendText row must be integer");
return NULL;
}
Row = PyInt_AsLong( row );
@@ -1479,8 +1546,7 @@ static PyObject* GemRB_TextArea_Append(PyObject * /*self*/, PyObject* args)
if (flag) {
if (!PyObject_TypeCheck( flag, &PyInt_Type )) {
- printMessage( "GUIScript",
- "Syntax Error: GetString flag must be integer\n", LIGHT_RED );
+ Log(ERROR, "GUIScript", "Syntax Error: GetString flag must be integer");
return NULL;
}
Flag = PyInt_AsLong( flag );
@@ -1555,17 +1621,19 @@ static PyObject* GemRB_TextArea_Scroll(PyObject * /*self*/, PyObject* args)
}
PyDoc_STRVAR( GemRB_Control_SetTooltip__doc,
-"SetTooltip(WindowIndex, ControlIndex, String|Strref) => int\n\n"
-"Sets control's tooltip." );
+"SetTooltip(WindowIndex, ControlIndex, String|Strref[, Function]) => int\n\n"
+"Sets control's tooltip. The optional function number will set the function key linkage as well." );
static PyObject* GemRB_Control_SetTooltip(PyObject * /*self*/, PyObject* args)
{
PyObject* wi, * ci, * str;
+ PyObject* function = NULL;
long WindowIndex, ControlIndex, StrRef;
char* string;
int ret;
+ int Function = 0;
- if (!PyArg_UnpackTuple( args, "ref", 3, 3, &wi, &ci, &str )) {
+ if (!PyArg_UnpackTuple( args, "ref", 3, 4, &wi, &ci, &str, &function)) {
return AttributeError( GemRB_Control_SetTooltip__doc );
}
if (!PyObject_TypeCheck( wi, &PyInt_Type ) ||
@@ -1577,12 +1645,22 @@ static PyObject* GemRB_Control_SetTooltip(PyObject * /*self*/, PyObject* args)
WindowIndex = PyInt_AsLong( wi );
ControlIndex = PyInt_AsLong( ci );
+ if (function) {
+ if (!PyObject_TypeCheck(function, &PyInt_Type) ) {
+ return AttributeError( GemRB_Control_SetTooltip__doc );
+ }
+ Function = PyInt_AsLong( function);
+ }
if (PyObject_TypeCheck( str, &PyString_Type )) {
string = PyString_AsString( str );
if (string == NULL) {
return RuntimeError("Null string received");
}
- ret = core->SetTooltip( (ieWord) WindowIndex, (ieWord) ControlIndex, string );
+ if (Function) {
+ ret = SetFunctionTooltip( (ieWord) WindowIndex, (ieWord) ControlIndex, string, Function);
+ } else {
+ ret = core->SetTooltip( (ieWord) WindowIndex, (ieWord) ControlIndex, string );
+ }
if (ret == -1) {
return RuntimeError("Cannot set tooltip");
}
@@ -1592,8 +1670,13 @@ static PyObject* GemRB_Control_SetTooltip(PyObject * /*self*/, PyObject* args)
ret = core->SetTooltip( (ieWord) WindowIndex, (ieWord) ControlIndex, GEMRB_STRING );
} else {
char* str = core->GetString( StrRef );
- ret = core->SetTooltip( (ieWord) WindowIndex, (ieWord) ControlIndex, str );
- core->FreeString( str );
+
+ if (Function) {
+ ret = SetFunctionTooltip( (ieWord) WindowIndex, (ieWord) ControlIndex, str, Function );
+ } else {
+ ret = core->SetTooltip( (ieWord) WindowIndex, (ieWord) ControlIndex, str );
+ core->FreeString( str );
+ }
}
if (ret == -1) {
return RuntimeError("Cannot set tooltip");
@@ -1783,8 +1866,11 @@ static PyObject* GemRB_Control_SetStatus(PyObject * /*self*/, PyObject* args)
}
int ret = core->SetControlStatus( WindowIndex, ControlIndex, status );
- if (ret == -1) {
- return NULL;
+ switch (ret) {
+ case -1:
+ return RuntimeError( "Control is not found." );
+ case -2:
+ return RuntimeError( "Control type is not matching." );
}
Py_INCREF( Py_None );
@@ -1860,6 +1946,29 @@ static PyObject* GemRB_Control_SetVarAssoc(PyObject * /*self*/, PyObject* args)
return Py_None;
}
+PyDoc_STRVAR( GemRB_Window_UpdateVarAssoc__doc,
+"UpdateVarAssoc(WindowIndex)\n\n"
+"Redraw controls in the given Window associated with a variable." );
+
+static PyObject* GemRB_Window_UpdateVarAssoc(PyObject * /*self*/, PyObject* args)
+{
+ int WindowIndex;
+ ieDword Value;
+ char* VarName;
+
+ if (!PyArg_ParseTuple( args, "is", &WindowIndex, &VarName )) {
+ return AttributeError( GemRB_Window_UpdateVarAssoc__doc );
+ }
+
+ Value = 0;
+ core->GetDictionary()->Lookup( VarName, Value );
+ Window* win = core->GetWindow( WindowIndex );
+ win->RedrawControls(VarName, Value);
+
+ Py_INCREF( Py_None );
+ return Py_None;
+}
+
PyDoc_STRVAR( GemRB_Window_Unload__doc,
"UnloadWindow(WindowIndex)\n\n"
"Unloads a previously Loaded Window." );
@@ -2022,7 +2131,8 @@ PyDoc_STRVAR( GemRB_Label_SetTextColor__doc,
static PyObject* GemRB_Label_SetTextColor(PyObject * /*self*/, PyObject* args)
{
- int WindowIndex, ControlIndex, r, g, b;
+ int WindowIndex, ControlIndex;
+ int r, g, b;
if (!PyArg_ParseTuple( args, "iiiii", &WindowIndex, &ControlIndex, &r, &g,
&b )) {
@@ -2034,7 +2144,7 @@ static PyObject* GemRB_Label_SetTextColor(PyObject * /*self*/, PyObject* args)
return NULL;
}
- Color fore = {r,g, b, 0}, back = {0, 0, 0, 0};
+ const Color fore = { (ieByte) r, (ieByte) g, (ieByte) b, 0}, back = {0, 0, 0, 0};
lab->SetColor( fore, back );
Py_INCREF( Py_None );
@@ -2174,9 +2284,9 @@ PyDoc_STRVAR( GemRB_TextEdit_ConvertEdit__doc,
static PyObject* GemRB_TextEdit_ConvertEdit(PyObject * /*self*/, PyObject* args)
{
int WindowIndex, ControlIndex;
- Color fore={255,255,255,0};
- Color init={255,255,255,0};
- Color back={0,0,0,0};
+ const Color fore={255,255,255,0};
+ const Color init={255,255,255,0};
+ const Color back={0,0,0,0};
int ScrollBarID=0;
if (!PyArg_ParseTuple( args, "ii|i", &WindowIndex, &ControlIndex, &ScrollBarID)) {
@@ -2213,6 +2323,42 @@ static PyObject* GemRB_TextEdit_ConvertEdit(PyObject * /*self*/, PyObject* args)
return PyInt_FromLong( ret );
}
+PyDoc_STRVAR( GemRB_TextEdit_SetBackground__doc,
+"SetBackground(WindowIndex, ControlIndex, ResRef)\n\n"
+"Sets the background MOS for a TextEdit control.");
+
+static PyObject* GemRB_TextEdit_SetBackground(PyObject * /*self*/, PyObject* args)
+{
+ int WindowIndex, ControlIndex;
+ char *ResRef;
+
+ if (!PyArg_ParseTuple( args, "iis", &WindowIndex, &ControlIndex,&ResRef) ) {
+ return AttributeError( GemRB_TextEdit_SetBackground__doc );
+ }
+ TextEdit* te = ( TextEdit* ) GetControl(WindowIndex, ControlIndex, IE_GUI_EDIT);
+ if (!te) {
+ return NULL;
+ }
+
+ if (ResRef[0]) {
+ ResourceHolder<ImageMgr> im(ResRef);
+ if (im == NULL) {
+ return RuntimeError("Picture resource not found!\n");
+ }
+
+ Sprite2D* Picture = im->GetSprite2D();
+ if (Picture == NULL) {
+ return RuntimeError("Failed to acquire the picture!\n");
+ }
+ te->SetBackGround(Picture);
+ } else {
+ te->SetBackGround(NULL);
+ }
+
+ Py_INCREF( Py_None );
+ return Py_None;
+}
+
PyDoc_STRVAR( GemRB_ScrollBar_SetSprites__doc,
"SetScrollBarSprites(WindowIndex, ControlIndex, ResRef, Cycle, UpUnpressedFrame, UpPressedFrame, DownUnpressedFrame, DownPressedFrame, TroughFrame, SliderFrame)\n\n"
"Sets a ScrollBar Sprites Images." );
@@ -2343,8 +2489,8 @@ static PyObject* GemRB_Button_SetOverlay(PyObject * /*self*/, PyObject* args)
return NULL;
}
- const Color src = { r1, g1, b1, a1 };
- const Color dest = { r2, g2, b2, a2 };
+ const Color src = { (ieByte) r1, (ieByte) g1, (ieByte) b1, (ieByte) a1 };
+ const Color dest = { (ieByte) r2, (ieByte) g2, (ieByte) b2, (ieByte) a2 };
if (Clipping<0.0) Clipping = 0.0;
else if (Clipping>1.0) Clipping = 1.0;
@@ -2360,7 +2506,8 @@ PyDoc_STRVAR( GemRB_Button_SetBorder__doc,
static PyObject* GemRB_Button_SetBorder(PyObject * /*self*/, PyObject* args)
{
- int WindowIndex, ControlIndex, BorderIndex, dx1, dy1, dx2, dy2, r, g, b, a, enabled = 0, filled = 0;
+ int WindowIndex, ControlIndex, BorderIndex, dx1, dy1, dx2, dy2, enabled = 0, filled = 0;
+ int r, g, b, a;
if (!PyArg_ParseTuple( args, "iiiiiiiiiii|ii", &WindowIndex, &ControlIndex,
&BorderIndex, &dx1, &dy1, &dx2, &dy2, &r, &g, &b, &a, &enabled, &filled)) {
@@ -2372,7 +2519,7 @@ static PyObject* GemRB_Button_SetBorder(PyObject * /*self*/, PyObject* args)
return NULL;
}
- const Color color = { r, g, b, a };
+ const Color color = { (ieByte) r, (ieByte) g, (ieByte) b, (ieByte) a };
btn->SetBorder( BorderIndex, dx1, dy1, dx2, dy2, color, (bool)enabled, (bool)filled );
Py_INCREF( Py_None );
@@ -2428,13 +2575,60 @@ static PyObject* GemRB_Button_SetFont(PyObject * /*self*/, PyObject* args)
return Py_None;
}
+PyDoc_STRVAR( GemRB_Button_SetAnchor__doc,
+"Button.SetAnchor(WindowIndex, ControlIndex, x, y)\n\n"
+"Sets explicit anchor used for drawing button label." );
+
+static PyObject* GemRB_Button_SetAnchor(PyObject * /*self*/, PyObject* args)
+{
+ int WindowIndex, ControlIndex, x, y;
+
+ if (!PyArg_ParseTuple( args, "iiii", &WindowIndex, &ControlIndex, &x, &y)) {
+ return AttributeError( GemRB_Button_SetAnchor__doc );
+ }
+
+ Button* btn = ( Button* ) GetControl(WindowIndex, ControlIndex, IE_GUI_BUTTON);
+ if (!btn) {
+ return NULL;
+ }
+
+ btn->SetAnchor(x, y);
+
+ Py_INCREF( Py_None );
+ return Py_None;
+}
+
+PyDoc_STRVAR( GemRB_Button_SetPushOffset__doc,
+"Button.SetPushOffset(WindowIndex, ControlIndex, x, y)\n\n"
+"Sets pixel offset for drawing pictures and label when the button is pressed." );
+
+static PyObject* GemRB_Button_SetPushOffset(PyObject * /*self*/, PyObject* args)
+{
+ int WindowIndex, ControlIndex, x, y;
+
+ if (!PyArg_ParseTuple( args, "iiii", &WindowIndex, &ControlIndex, &x, &y)) {
+ return AttributeError( GemRB_Button_SetPushOffset__doc );
+ }
+
+ Button* btn = ( Button* ) GetControl(WindowIndex, ControlIndex, IE_GUI_BUTTON);
+ if (!btn) {
+ return NULL;
+ }
+
+ btn->SetPushOffset(x, y);
+
+ Py_INCREF( Py_None );
+ return Py_None;
+}
+
PyDoc_STRVAR( GemRB_Button_SetTextColor__doc,
"SetButtonTextColor(WindowIndex, ControlIndex, red, green, blue[, invert=false])\n\n"
"Sets the Text Color of a Button Control. Invert is used for fonts with swapped background and text colors." );
static PyObject* GemRB_Button_SetTextColor(PyObject * /*self*/, PyObject* args)
{
- int WindowIndex, ControlIndex, r, g, b, swap = 0;
+ int WindowIndex, ControlIndex, swap = 0;
+ int r, g, b;
if (!PyArg_ParseTuple( args, "iiiii|i", &WindowIndex, &ControlIndex, &r, &g, &b, &swap )) {
return AttributeError( GemRB_Button_SetTextColor__doc );
@@ -2445,7 +2639,7 @@ static PyObject* GemRB_Button_SetTextColor(PyObject * /*self*/, PyObject* args)
return NULL;
}
- Color fore = {r,g, b, 0}, back = {0, 0, 0, 0};
+ const Color fore = { (ieByte) r, (ieByte) g, (ieByte) b, 0}, back = {0, 0, 0, 0};
// FIXME: swap is a hack for fonts which apparently have swapped f & B
// colors. Maybe it depends on need_palette?
@@ -2559,7 +2753,6 @@ static PyObject* GemRB_AddNewArea(PyObject * /*self*/, PyObject* args)
int thisarea = wmap->GetEntryCount();
wmap->AddAreaEntry(entry);
- wmap->AreaEntriesCount++;
for (unsigned int j=0;j<total;j++) {
WMPAreaLink *link = new WMPAreaLink();
const char *larea = newlinks->QueryField(j,0);
@@ -2653,6 +2846,32 @@ static PyObject* GemRB_CreateMovement(PyObject * /*self*/, PyObject* args)
return Py_None;
}
+PyDoc_STRVAR( GemRB_UpdateWorldMap__doc,
+"UpdateWorldMap(ResRef, [AreaResRef])\n\n"
+"Reloads the world map from ResRef.\n"
+"If AreaResRef is given only updates if that area is missing." );
+
+static PyObject* GemRB_UpdateWorldMap(PyObject * /*self*/, PyObject* args)
+{
+ char *wmResRef, *areaResRef = NULL;
+ bool update = true;
+
+ if (!PyArg_ParseTuple( args, "s|s", &wmResRef, &areaResRef)) {
+ return AttributeError( GemRB_UpdateWorldMap__doc );
+ }
+
+ if (areaResRef != NULL) {
+ unsigned int i;
+ update = (core->GetWorldMap()->GetArea( areaResRef, i ) == NULL);
+ }
+
+ if (update)
+ core->UpdateWorldMap(wmResRef);
+
+ Py_INCREF( Py_None );
+ return Py_None;
+}
+
PyDoc_STRVAR( GemRB_WorldMap_GetDestinationArea__doc,
"GetDestinationArea(WindowIndex, ControlID[, RndEncounter]) => WorldMap entry\n\n"
"Returns the last area pointed on the worldmap.\n"
@@ -2680,36 +2899,69 @@ static PyObject* GemRB_WorldMap_GetDestinationArea(PyObject * /*self*/, PyObject
PyObject* dict = PyDict_New();
//the area the user clicked on
PyDict_SetItemString(dict, "Target", PyString_FromString (wmc->Area->AreaName) );
+ PyDict_SetItemString(dict, "Destination", PyString_FromString (wmc->Area->AreaName) );
+
+ if (!strnicmp(wmc->Area->AreaName, core->GetGame()->CurrentArea, 8)) {
+ PyDict_SetItemString(dict, "Distance", PyInt_FromLong (-1) );
+ return dict;
+ }
+
bool encounter;
+ int distance;
WMPAreaLink *wal = wm->GetEncounterLink(wmc->Area->AreaName, encounter);
if (!wal) {
PyDict_SetItemString(dict, "Distance", PyInt_FromLong (-1) );
return dict;
}
- PyDict_SetItemString(dict, "Destination", PyString_FromString (wmc->Area->AreaName) );
PyDict_SetItemString(dict, "Entrance", PyString_FromString (wal->DestEntryPoint) );
PyDict_SetItemString(dict, "Direction", PyInt_FromLong (wal->DirectionFlags) );
- //the area the user will fall on
- if (encounter && eval) {
- int i=rand()%5;
+ distance = wm->GetDistance(wmc->Area->AreaName);
- displaymsg->DisplayConstantString(STR_AMBUSH,0xbcefbc);
+ if (eval) {
+ wm->ClearEncounterArea();
- if(wal->EncounterChance>=100) {
- wal->EncounterChance-=100;
- }
- for(int j=0;j<5;j++) {
- if (wal->EncounterAreaResRef[(i+j)%5][0]) {
- PyDict_SetItemString(dict, "Destination", PyString_FromString (wal->EncounterAreaResRef[(i+j)%5]) );
+ //evaluate the area the user will fall on in a random encounter
+ if (encounter) {
+
+ if(wal->EncounterChance>=100) {
+ wal->EncounterChance-=100;
+ }
+
+ //bounty encounter
+ ieResRef tmpresref;
+ WMPAreaEntry *linkdest = wm->GetEntry(wal->AreaIndex);
+
+ CopyResRef(tmpresref, linkdest->AreaResRef);
+ if (core->GetGame()->RandomEncounter(tmpresref)) {
+ displaymsg->DisplayConstantString(STR_AMBUSH, DMC_BG2XPGREEN);
+ PyDict_SetItemString(dict, "Destination", PyString_FromString (tmpresref) );
PyDict_SetItemString(dict, "Entrance", PyString_FromString ("") );
- // do we need to change Direction here?
- break;
+ distance = wm->GetDistance(linkdest->AreaResRef) - (wal->DistanceScale * 4 / 2);
+ wm->SetEncounterArea(tmpresref, wal);
+ } else {
+ //regular random encounter, find a valid encounter area
+ int i=rand()%5;
+
+ for(int j=0;j<5;j++) {
+ const char *area = wal->EncounterAreaResRef[(i+j)%5];
+
+ if (area[0]) {
+ displaymsg->DisplayConstantString(STR_AMBUSH, DMC_BG2XPGREEN);
+ PyDict_SetItemString(dict, "Destination", PyString_FromString (area) );
+ //drop player in the middle of the map
+ PyDict_SetItemString(dict, "Entrance", PyString_FromString ("") );
+ PyDict_SetItemString(dict, "Direction", PyInt_FromLong (ADIRF_CENTER) );
+ //only count half the distance of the final link
+ distance = wm->GetDistance(linkdest->AreaResRef) - (wal->DistanceScale * 4 / 2);
+ wm->SetEncounterArea(area, wal);
+ break;
+ }
+ }
}
}
}
- //the entrance the user will fall on
- PyDict_SetItemString(dict, "Distance", PyInt_FromLong (wm->GetDistance(wmc->Area->AreaName)) );
+ PyDict_SetItemString(dict, "Distance", PyInt_FromLong (distance));
return dict;
}
@@ -2768,7 +3020,8 @@ PyDoc_STRVAR( GemRB_WorldMap_SetTextColor__doc,
static PyObject* GemRB_WorldMap_SetTextColor(PyObject * /*self*/, PyObject* args)
{
- int WindowIndex, ControlIndex, which, r, g, b, a;
+ int WindowIndex, ControlIndex, which;
+ int r, g, b, a;
if (!PyArg_ParseTuple( args, "iiiiiii", &WindowIndex, &ControlIndex, &which, &r, &g, &b, &a )) {
return AttributeError( GemRB_WorldMap_SetTextColor__doc );
@@ -2779,7 +3032,7 @@ static PyObject* GemRB_WorldMap_SetTextColor(PyObject * /*self*/, PyObject* args
return NULL;
}
- Color color = {r, g, b, a};
+ const Color color = { (ieByte) r, (ieByte) g, (ieByte) b, (ieByte) a};
wmap->SetColor( which, color );
Py_INCREF( Py_None );
@@ -2900,6 +3153,31 @@ static PyObject* GemRB_Control_SetPos(PyObject * /*self*/, PyObject* args)
return Py_None;
}
+PyDoc_STRVAR( GemRB_Control_GetRect__doc,
+"control.GetRect()\n\n"
+"Returns a dict with the control position and size." );
+
+static PyObject* GemRB_Control_GetRect(PyObject * /*self*/, PyObject* args)
+{
+ int WindowIndex, ControlIndex;
+
+ if (!PyArg_ParseTuple( args, "ii", &WindowIndex, &ControlIndex)) {
+ return AttributeError( GemRB_Control_GetRect__doc );
+ }
+
+ Control* ctrl = GetControl(WindowIndex, ControlIndex, -1);
+ if (!ctrl) {
+ return NULL;
+ }
+
+ PyObject* dict = PyDict_New();
+ PyDict_SetItemString(dict, "X", PyInt_FromLong( ctrl->XPos ));
+ PyDict_SetItemString(dict, "Y", PyInt_FromLong( ctrl->YPos ));
+ PyDict_SetItemString(dict, "Width", PyInt_FromLong( ctrl->Width ));
+ PyDict_SetItemString(dict, "Height", PyInt_FromLong( ctrl->Height ));
+ return dict;
+}
+
PyDoc_STRVAR( GemRB_Control_SetSize__doc,
"SetControlSize(WindowIndex, ControlIndex, Width, Height)\n\n"
"Resizes a Control." );
@@ -2925,6 +3203,31 @@ static PyObject* GemRB_Control_SetSize(PyObject * /*self*/, PyObject* args)
return Py_None;
}
+PyDoc_STRVAR( GemRB_Label_SetFont__doc,
+"SetLabelFont(WindowIndex, ControlIndex, FontResRef)\n\n"
+"Sets font used for drawing the label." );
+
+static PyObject* GemRB_Label_SetFont(PyObject * /*self*/, PyObject* args)
+{
+ int WindowIndex, ControlIndex;
+ char *FontResRef;
+
+ if (!PyArg_ParseTuple( args, "iis", &WindowIndex, &ControlIndex,
+ &FontResRef)) {
+ return AttributeError( GemRB_Label_SetFont__doc );
+ }
+
+ Label *lbl = (Label *) GetControl(WindowIndex, ControlIndex, IE_GUI_LABEL);
+ if (!lbl) {
+ return NULL;
+ }
+
+ lbl->SetFont( core->GetFont( FontResRef ));
+
+ Py_INCREF( Py_None );
+ return Py_None;
+}
+
PyDoc_STRVAR( GemRB_Label_SetUseRGB__doc,
"SetLabelUseRGB(WindowIndex, ControlIndex, status)\n\n"
"Tells a Label to use the RGB colors with the text." );
@@ -3033,8 +3336,7 @@ static PyObject* GemRB_GameSetScreenFlags(PyObject * /*self*/, PyObject* args)
return AttributeError( GemRB_GameSetScreenFlags__doc );
}
if (Operation < BM_SET || Operation > BM_NAND) {
- printMessage( "GUIScript",
- "Syntax Error: operation must be 0-4\n", LIGHT_RED );
+ Log(ERROR, "GUIScript", "Syntax Error: operation must be 0-4");
return NULL;
}
@@ -3072,7 +3374,7 @@ static PyObject* GemRB_GameControlSetScreenFlags(PyObject * /*self*/, PyObject*
PyDoc_STRVAR( GemRB_GameControlSetTargetMode__doc,
"GameControlSetTargetMode(Mode, Types)\n\n"
-"Sets the targetting mode of the main game screen control (attack, cast spell,...) and type of target (ally, enemy and/or neutral; all by default)" );
+"Sets the targeting mode of the main game screen control (attack, cast spell,...) and type of target (ally, enemy and/or neutral; all by default)" );
static PyObject* GemRB_GameControlSetTargetMode(PyObject * /*self*/, PyObject* args)
{
@@ -3095,7 +3397,7 @@ static PyObject* GemRB_GameControlSetTargetMode(PyObject * /*self*/, PyObject* a
PyDoc_STRVAR( GemRB_GameControlGetTargetMode__doc,
"GameControlGetTargetMode() => Mode\n\n"
-"Returns the targetting mode of the main game screen control (attack, cast spell,...)." );
+"Returns the targeting mode of the main game screen control (attack, cast spell,...)." );
static PyObject* GemRB_GameControlGetTargetMode(PyObject * /*self*/, PyObject* /*args*/)
{
@@ -3104,6 +3406,21 @@ static PyObject* GemRB_GameControlGetTargetMode(PyObject * /*self*/, PyObject* /
return PyInt_FromLong(gc->GetTargetMode());
}
+PyDoc_STRVAR( GemRB_GameControlToggleAlwaysRun__doc,
+"GameControlToggleAlwaysRun()\n\n"
+"Toggles using running instead of walking by default" );
+
+static PyObject* GemRB_GameControlToggleAlwaysRun(PyObject * /*self*/, PyObject* /*args*/)
+{
+
+ GET_GAMECONTROL();
+
+ gc->ToggleAlwaysRun();
+
+ Py_INCREF( Py_None );
+ return Py_None;
+}
+
PyDoc_STRVAR( GemRB_Button_SetFlags__doc,
"SetButtonFlags(WindowIndex, ControlIndex, Flags, Operation)\n\n"
"Sets the Display Flags of a Button." );
@@ -3116,8 +3433,7 @@ static PyObject* GemRB_Button_SetFlags(PyObject * /*self*/, PyObject* args)
return AttributeError( GemRB_Button_SetFlags__doc );
}
if (Operation < BM_SET || Operation > BM_NAND) {
- printMessage( "GUIScript",
- "Syntax Error: operation must be 0-4\n", LIGHT_RED );
+ Log(ERROR, "GUIScript", "Syntax Error: operation must be 0-4");
return NULL;
}
@@ -3127,7 +3443,7 @@ static PyObject* GemRB_Button_SetFlags(PyObject * /*self*/, PyObject* args)
}
if (btn->SetFlags( Flags, Operation ) ) {
- printMessage ("GUIScript", "Flag cannot be set!\n",LIGHT_RED);
+ Log(ERROR, "GUIScript", "Flag cannot be set!");
return NULL;
}
@@ -3148,8 +3464,7 @@ static PyObject* GemRB_Control_TextArea_SetFlags(PyObject * /*self*/, PyObject*
return AttributeError( GemRB_Control_TextArea_SetFlags__doc );
}
if (Operation < BM_SET || Operation > BM_NAND) {
- printMessage( "GUIScript",
- "Syntax Error: operation must be 0-4\n", LIGHT_RED );
+ Log(ERROR, "GUIScript", "Syntax Error: operation must be 0-4");
return NULL;
}
@@ -3159,7 +3474,7 @@ static PyObject* GemRB_Control_TextArea_SetFlags(PyObject * /*self*/, PyObject*
}
if (ta->SetFlags( Flags, Operation )) {
- printMessage ("GUIScript", "Flag cannot be set!\n",LIGHT_RED);
+ Log(ERROR, "GUIScript", "Flag cannot be set!");
return NULL;
}
@@ -3265,7 +3580,7 @@ static PyObject* GemRB_Button_SetPicture(PyObject * /*self*/, PyObject* args)
}
ImageFactory* fact = ( ImageFactory* )
- gamedata->GetFactoryResource( ResRef, IE_BMP_CLASS_ID, IE_NORMAL );
+ gamedata->GetFactoryResource(ResRef, IE_BMP_CLASS_ID, IE_NORMAL, true);
//if the resource doesn't exist, but we have a default resource
//use this resource
@@ -3394,9 +3709,8 @@ static PyObject* GemRB_Button_SetPLT(PyObject * /*self*/, PyObject* args)
gamedata->GetFactoryResource( ResRef,
IE_BAM_CLASS_ID, IE_NORMAL );
if (!af) {
- printMessage("GUISCript","PLT/BAM not found for ref: ",YELLOW);
- printf("%s\n", ResRef);
- textcolor(WHITE);
+ Log(WARNING, "GUISCript", "PLT/BAM not found for ref: %s",
+ ResRef);
if (type == 0)
return NULL;
else {
@@ -3407,13 +3721,13 @@ static PyObject* GemRB_Button_SetPLT(PyObject * /*self*/, PyObject* args)
Picture = af->GetPaperdollImage(col[0]==0xFFFFFFFF?0:col, Picture2,(unsigned int)type);
if (Picture == NULL) {
- printf ("Picture == NULL\n");
+ print("Picture == NULL");
return NULL;
}
} else {
Picture = im->GetSprite2D(type, col);
if (Picture == NULL) {
- printf ("Picture == NULL\n");
+ print("Picture == NULL");
return NULL;
}
}
@@ -3425,7 +3739,7 @@ static PyObject* GemRB_Button_SetPLT(PyObject * /*self*/, PyObject* args)
btn->SetFlags ( IE_GUI_BUTTON_BG1_PAPERDOLL, BM_OR );
btn->StackPicture( Picture2 );
} else if (type == 0) {
- btn->SetFlags ( ~IE_GUI_BUTTON_BG1_PAPERDOLL, BM_AND );
+ btn->SetFlags ( IE_GUI_BUTTON_BG1_PAPERDOLL, BM_NAND );
}
Py_INCREF( Py_None );
@@ -3525,8 +3839,30 @@ static PyObject* GemRB_Control_SetAnimationPalette(PyObject * /*self*/, PyObject
return Py_None;
}
+PyDoc_STRVAR( GemRB_Control_HasAnimation__doc,
+"HasAnimation(WindowIndex, ControlIndex, BAMResRef[, Cycle])\n\n"
+"Checks whether a Control (usually a Button) has a given animation set.");
+
+static PyObject* GemRB_Control_HasAnimation(PyObject * /*self*/, PyObject* args)
+{
+ int wi, ci;
+ char *ResRef;
+ int Cycle = 0;
+
+ if (!PyArg_ParseTuple( args, "iis|i", &wi, &ci, &ResRef, &Cycle )) {
+ return AttributeError( GemRB_Control_HasAnimation__doc );
+ }
+
+ Control* ctl = GetControl(wi, ci, -1);
+ if (ctl && ctl->animation) {
+ return PyBool_FromLong(ctl->animation->SameResource(ResRef, Cycle));
+ }
+
+ return PyBool_FromLong(0);
+}
+
PyDoc_STRVAR( GemRB_Control_SetAnimation__doc,
-"SetAnimation(WindowIndex, ControlIndex, BAMResRef[, Cycle])\n\n"
+"SetAnimation(WindowIndex, ControlIndex, BAMResRef[, Cycle, Blend])\n\n"
"Sets the animation of a Control (usually a Button) from a BAM file. Optionally an animation cycle could be set too.");
static PyObject* GemRB_Control_SetAnimation(PyObject * /*self*/, PyObject* args)
@@ -3534,8 +3870,9 @@ static PyObject* GemRB_Control_SetAnimation(PyObject * /*self*/, PyObject* args)
int wi, ci;
char *ResRef;
int Cycle = 0;
+ int Blend = 0;
- if (!PyArg_ParseTuple( args, "iis|i", &wi, &ci, &ResRef, &Cycle )) {
+ if (!PyArg_ParseTuple( args, "iis|ii", &wi, &ci, &ResRef, &Cycle, &Blend )) {
return AttributeError( GemRB_Control_SetAnimation__doc );
}
@@ -3548,7 +3885,8 @@ static PyObject* GemRB_Control_SetAnimation(PyObject * /*self*/, PyObject* args)
if (ctl->animation) {
//if this control says the resource is the same
//we wanted to set, we don't reset it
- if(ctl->animation->SameResource(ResRef, Cycle)) {
+ //but we must reinitialize it, if it was play once
+ if(ctl->animation->SameResource(ResRef, Cycle) && !(ctl->Flags&IE_GUI_BUTTON_PLAYONCE)) {
Py_INCREF( Py_None );
return Py_None;
}
@@ -3564,32 +3902,56 @@ static PyObject* GemRB_Control_SetAnimation(PyObject * /*self*/, PyObject* args)
ControlAnimation* anim = new ControlAnimation( ctl, ResRef, Cycle );
- anim->UpdateAnimation();
+ if (Blend) {
+ anim->SetBlend(true);
+ }
+ anim->UpdateAnimation(false);
Py_INCREF( Py_None );
return Py_None;
}
+PyDoc_STRVAR( GemRB_ValidTarget__doc,
+"ValidTarget(PartyID, flags)\n\n"
+"Checks if an actor is valid for various purposes, like visible, selectable, dead, etc." );
+
+static PyObject* GemRB_ValidTarget(PyObject * /*self*/, PyObject* args)
+{
+ int globalID, flags;
+
+ if (!PyArg_ParseTuple( args, "ii", &globalID, &flags )) {
+ return AttributeError( GemRB_ValidTarget__doc );
+ }
+
+ GET_GAME();
+ GET_ACTOR_GLOBAL();
+
+ if (actor->ValidTarget(flags, actor)) {
+ Py_INCREF( Py_True );
+ return Py_True;
+ } else {
+ Py_INCREF( Py_False );
+ return Py_False;
+ }
+}
+
+
PyDoc_STRVAR( GemRB_VerbalConstant__doc,
"VerbalConstant(PartyID, str)\n\n"
"Plays a Character's SoundSet entry." );
static PyObject* GemRB_VerbalConstant(PyObject * /*self*/, PyObject* args)
{
- int PartyID, str;
+ int globalID, str;
char Sound[_MAX_PATH];
- if (!PyArg_ParseTuple( args, "ii", &PartyID, &str )) {
+ if (!PyArg_ParseTuple( args, "ii", &globalID, &str )) {
return AttributeError( GemRB_VerbalConstant__doc );
}
GET_GAME();
-
- Actor *actor = game->FindPC(PartyID);
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
if (str<0 || str>=VCONST_COUNT) {
return AttributeError( "SoundSet Entry is too large" );
@@ -3605,8 +3967,9 @@ static PyObject* GemRB_VerbalConstant(PyObject * /*self*/, PyObject* args)
PyDoc_STRVAR( GemRB_PlaySound__doc,
-"PlaySound(SoundResource, xpos, ypos, type)\n\n"
-"Plays a Sound." );
+"PlaySound(SoundResource[, xpos, ypos, type])\n"
+"PlaySound(DefSoundIndex)\n\n"
+"Plays a Sound identified by resource reference or defsound.2da index.\n" );
static PyObject* GemRB_PlaySound(PyObject * /*self*/, PyObject* args)
{
@@ -3614,12 +3977,18 @@ static PyObject* GemRB_PlaySound(PyObject * /*self*/, PyObject* args)
int xpos = 0;
int ypos = 0;
unsigned int flags = 1; //GEM_SND_RELATIVE
+ int index;
- if (!PyArg_ParseTuple( args, "z|iii", &ResRef, &xpos, &ypos, &flags )) {
- return AttributeError( GemRB_PlaySound__doc );
- }
+ if (PyArg_ParseTuple( args, "i", &index) ) {
+ core->PlaySound(index);
+ } else {
+ PyErr_Clear(); //clearing the exception
+ if (!PyArg_ParseTuple( args, "z|iii", &ResRef, &xpos, &ypos, &flags )) {
+ return AttributeError( GemRB_PlaySound__doc );
+ }
- core->GetAudioDrv()->Play( ResRef, xpos, ypos, flags );
+ core->GetAudioDrv()->Play( ResRef, xpos, ypos, flags );
+ }
Py_INCREF( Py_None );
return Py_None;
@@ -3643,10 +4012,7 @@ PyDoc_STRVAR( GemRB_Quit__doc,
static PyObject* GemRB_Quit(PyObject * /*self*/, PyObject * /*args*/)
{
- bool ret = core->Quit();
- if (!ret) {
- return NULL;
- }
+ core->ExitGemRB();
Py_INCREF( Py_None );
return Py_None;
@@ -3729,6 +4095,8 @@ static PyObject* GemRB_SetVar(PyObject * /*self*/, PyObject* args)
core->GetDictionary()->SetAt( Variable, (ieDword) value );
+ //this is a hack to update the settings deeper in the core
+ UpdateActorConfig();
Py_INCREF( Py_None );
return Py_None;
}
@@ -3810,13 +4178,12 @@ static PyObject* GemRB_CheckVar(PyObject * /*self*/, PyObject* args)
}
if (!Sender) {
- printMessage("GUIScript","No Sender!\n", LIGHT_RED);
+ Log(ERROR, "GUIScript", "No Sender!");
return NULL;
}
long value =(long) CheckVariable(Sender, Variable, Context);
- printMessage("GUISCript"," ",YELLOW);
- printf("%s %s=%ld\n",Context, Variable, value);
- textcolor(WHITE);
+ Log(DEBUG, "GUISCript", "%s %s=%ld",
+ Context, Variable, value);
return PyInt_FromLong( value );
}
@@ -3846,7 +4213,7 @@ static PyObject* GemRB_SetGlobal(PyObject * /*self*/, PyObject* args)
Sender = (Scriptable *) game->GetCurrentArea();
}
if (!Sender) {
- printMessage("GUIScript","No Sender!\n", LIGHT_RED);
+ Log(ERROR, "GUIScript", "No Sender!");
return NULL;
}
} // else GLOBAL, area name or KAPUTZ
@@ -3904,16 +4271,35 @@ static PyObject* GemRB_PlayMovie(PyObject * /*self*/, PyObject* args)
return PyInt_FromLong( ind );
}
-PyDoc_STRVAR( GemRB_SaveCharacter__doc,
-"SaveCharacter(PartyID, CharName)\n\n"
-"Exports the character from party.");
-
-static PyObject* GemRB_SaveCharacter(PyObject * /*self*/, PyObject * args)
+PyDoc_STRVAR( GemRB_DumpActor__doc,
+ "DumpActor(globalID)\n\n"
+ "Prints the character's debug dump.");
+static PyObject* GemRB_DumpActor(PyObject * /*self*/, PyObject * args)
{
- int PartyID;
+ int globalID;
+
+ if (!PyArg_ParseTuple( args, "i", &globalID )) {
+ return AttributeError( GemRB_DumpActor__doc );
+ }
+
+ GET_GAME();
+ GET_ACTOR_GLOBAL();
+
+ actor->dump();
+ Py_INCREF( Py_None );
+ return Py_None;
+}
+
+PyDoc_STRVAR( GemRB_SaveCharacter__doc,
+"SaveCharacter(PartyID, CharName)\n\n"
+"Exports the character from party.");
+
+static PyObject* GemRB_SaveCharacter(PyObject * /*self*/, PyObject * args)
+{
+ int globalID;
const char *name;
- if (!PyArg_ParseTuple( args, "is", &PartyID, &name )) {
+ if (!PyArg_ParseTuple( args, "is", &globalID, &name )) {
return AttributeError( GemRB_SaveCharacter__doc );
}
if (!name[0]) {
@@ -3921,14 +4307,21 @@ static PyObject* GemRB_SaveCharacter(PyObject * /*self*/, PyObject * args)
}
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor *actor = game->FindPC(PartyID);
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
return PyInt_FromLong(core->WriteCharacter(name, actor) );
}
+
+PyDoc_STRVAR( GemRB_SaveConfig__doc,
+ "SaveConfig()\n\n"
+ "Exports the game configuration to a file.");
+
+static PyObject* GemRB_SaveConfig(PyObject * /*self*/, PyObject * /*args*/)
+{
+ return PyBool_FromLong(core->SaveConfig());
+}
+
PyDoc_STRVAR( GemRB_SaveGame__doc,
"SaveGame(SlotCount, GameName[,version])\n\n"
"Dumps the save game, if version is given, it will save a specific version.");
@@ -3936,15 +4329,17 @@ PyDoc_STRVAR( GemRB_SaveGame__doc,
static PyObject* GemRB_SaveGame(PyObject * /*self*/, PyObject * args)
{
PyObject *obj;
+ int slot = -1;
int Version = -1;
const char *folder;
if (!PyArg_ParseTuple( args, "Os|i", &obj, &folder, &Version )) {
- return AttributeError( GemRB_SaveGame__doc );
+ PyErr_Clear();
+ if (!PyArg_ParseTuple( args, "i|i", &slot, &Version)) {
+ return AttributeError( GemRB_SaveGame__doc );
+ }
}
- CObject<SaveGame> save(obj);
-
GET_GAME();
SaveGameIterator *sgi = core->GetSaveGameIterator();
@@ -3955,7 +4350,13 @@ static PyObject* GemRB_SaveGame(PyObject * /*self*/, PyObject * args)
if (Version>0) {
game->version = Version;
}
- return PyInt_FromLong(sgi->CreateSaveGame(save, folder) );
+ if (slot == -1) {
+ CObject<SaveGame> save(obj);
+
+ return PyInt_FromLong(sgi->CreateSaveGame(save, folder) );
+ } else {
+ return PyInt_FromLong(sgi->CreateSaveGame(slot, core->MultipleQuickSaves) );
+ }
}
PyDoc_STRVAR( GemRB_GetSaveGames__doc,
@@ -4576,18 +4977,15 @@ PyDoc_STRVAR( GemRB_GetPlayerStates__doc,
static PyObject* GemRB_GetPlayerStates(PyObject * /*self*/, PyObject* args)
{
- int PartyID;
+ int globalID;
- if (!PyArg_ParseTuple( args, "i", &PartyID )) {
+ if (!PyArg_ParseTuple( args, "i", &globalID )) {
return AttributeError( GemRB_GetPlayerStates__doc );
}
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor* MyActor = game->FindPC( PartyID );
- if (!MyActor) {
- return RuntimeError( "Actor not found!\n" );
- }
- return PyString_FromString((const char *) MyActor->GetStateString() );
+ return PyString_FromString((const char *) actor->GetStateString() );
}
PyDoc_STRVAR( GemRB_GetPlayerName__doc,
@@ -4596,23 +4994,20 @@ PyDoc_STRVAR( GemRB_GetPlayerName__doc,
static PyObject* GemRB_GetPlayerName(PyObject * /*self*/, PyObject* args)
{
- int PartyID, Which;
+ int globalID, Which;
Which = 0;
- if (!PyArg_ParseTuple( args, "i|i", &PartyID, &Which )) {
+ if (!PyArg_ParseTuple( args, "i|i", &globalID, &Which )) {
return AttributeError( GemRB_GetPlayerName__doc );
}
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor* MyActor = game->FindPC( PartyID );
- if (!MyActor) {
- return RuntimeError( "Actor not found!\n" );
- }
if (Which == 2) {
- return PyString_FromString( MyActor->GetScriptName() );
+ return PyString_FromString( actor->GetScriptName() );
}
- return PyString_FromString( MyActor->GetName(Which) );
+ return PyString_FromString( actor->GetName(Which) );
}
PyDoc_STRVAR( GemRB_SetPlayerName__doc,
@@ -4622,20 +5017,17 @@ PyDoc_STRVAR( GemRB_SetPlayerName__doc,
static PyObject* GemRB_SetPlayerName(PyObject * /*self*/, PyObject* args)
{
const char *Name=NULL;
- int PlayerSlot, Which;
+ int globalID, Which;
Which = 0;
- if (!PyArg_ParseTuple( args, "is|i", &PlayerSlot, &Name, &Which )) {
+ if (!PyArg_ParseTuple( args, "is|i", &globalID, &Name, &Which )) {
return AttributeError( GemRB_SetPlayerName__doc );
}
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor* MyActor = game->FindPC( PlayerSlot );
- if (!MyActor) {
- return RuntimeError( "Actor not found!\n" );
- }
- MyActor->SetName(Name, Which);
- MyActor->SetMCFlag(MC_EXPORTABLE,BM_OR);
+ actor->SetName(Name, Which);
+ actor->SetMCFlag(MC_EXPORTABLE,BM_OR);
Py_INCREF( Py_None );
return Py_None;
}
@@ -4664,23 +5056,19 @@ PyDoc_STRVAR( GemRB_SetPlayerString__doc,
static PyObject* GemRB_SetPlayerString(PyObject * /*self*/, PyObject* args)
{
- int PlayerSlot, StringSlot, StrRef;
+ int globalID, StringSlot, StrRef;
- if (!PyArg_ParseTuple( args, "iii", &PlayerSlot, &StringSlot, &StrRef )) {
+ if (!PyArg_ParseTuple( args, "iii", &globalID, &StringSlot, &StrRef )) {
return AttributeError( GemRB_SetPlayerString__doc );
}
GET_GAME();
-
- Actor* MyActor = game->FindPC( PlayerSlot );
- if (!MyActor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
if (StringSlot>=VCONST_COUNT) {
return AttributeError( "StringSlot is out of range!\n" );
}
- MyActor->StrRefs[StringSlot]=StrRef;
+ actor->StrRefs[StringSlot]=StrRef;
Py_INCREF( Py_None );
return Py_None;
@@ -4693,18 +5081,15 @@ PyDoc_STRVAR( GemRB_SetPlayerSound__doc,
static PyObject* GemRB_SetPlayerSound(PyObject * /*self*/, PyObject* args)
{
const char *Sound=NULL;
- int PlayerSlot;
+ int globalID;
- if (!PyArg_ParseTuple( args, "is", &PlayerSlot, &Sound )) {
+ if (!PyArg_ParseTuple( args, "is", &globalID, &Sound )) {
return AttributeError( GemRB_SetPlayerSound__doc );
}
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor* MyActor = game->FindPC( PlayerSlot );
- if (!MyActor) {
- return RuntimeError( "Actor not found!\n" );
- }
- MyActor->SetSoundFolder(Sound);
+ actor->SetSoundFolder(Sound);
Py_INCREF( Py_None );
return Py_None;
}
@@ -4716,19 +5101,16 @@ PyDoc_STRVAR( GemRB_GetPlayerSound__doc,
static PyObject* GemRB_GetPlayerSound(PyObject * /*self*/, PyObject* args)
{
char Sound[42];
- int PlayerSlot;
+ int globalID;
int flag = 0;
- if (!PyArg_ParseTuple( args, "i|i", &PlayerSlot, &flag )) {
+ if (!PyArg_ParseTuple( args, "i|i", &globalID, &flag )) {
return AttributeError( GemRB_GetPlayerSound__doc );
}
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor* MyActor = game->FindPC( PlayerSlot );
- if (!MyActor) {
- return RuntimeError( "Actor not found!\n" );
- }
- MyActor->GetSoundFolder(Sound, flag);
+ actor->GetSoundFolder(Sound, flag);
return PyString_FromString(Sound);
}
@@ -4856,7 +5238,7 @@ static PyObject* GemRB_GetPCStats(PyObject * /*self*/, PyObject* args)
return RuntimeError( "Item not found!\n" );
}
- PyDict_SetItemString(dict, "FavouriteWeapon", PyInt_FromLong ((signed) item->GetItemName(false)));
+ PyDict_SetItemString(dict, "FavouriteWeapon", PyInt_FromLong ((signed) item->GetItemName(true)));
gamedata->FreeItem( item, ps->FavouriteWeapons[largest], false );
} else {
@@ -4896,6 +5278,9 @@ static PyObject* GemRB_GameSelectPC(PyObject * /*self*/, PyObject* args)
}
game->SelectActor( actor, (bool) Select, Flags );
+ if (actor && (bool) Select && !(Flags&SELECT_QUIET)) {
+ actor->PlaySelectionSound();
+ }
Py_INCREF( Py_None );
return Py_None;
@@ -5071,21 +5456,18 @@ PyDoc_STRVAR( GemRB_GetPlayerString__doc,
static PyObject* GemRB_GetPlayerString(PyObject * /*self*/, PyObject* args)
{
- int PlayerSlot, Index, StatValue;
+ int globalID, Index, StatValue;
- if (!PyArg_ParseTuple( args, "ii", &PlayerSlot, &Index)) {
+ if (!PyArg_ParseTuple( args, "ii", &globalID, &Index)) {
return AttributeError( GemRB_GetPlayerString__doc );
}
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor* MyActor = game->FindPC( PlayerSlot );
- if (!MyActor) {
- return RuntimeError("Cannot find actor!\n");
- }
if (Index>=VCONST_COUNT) {
- return RuntimeError("String reference too high!\n");
+ return RuntimeError("String reference is too high!\n");
}
- StatValue = GetCreatureStrRef( MyActor, Index );
+ StatValue = GetCreatureStrRef( actor, Index );
return PyInt_FromLong( StatValue );
}
@@ -5095,20 +5477,17 @@ PyDoc_STRVAR( GemRB_GetPlayerStat__doc,
static PyObject* GemRB_GetPlayerStat(PyObject * /*self*/, PyObject* args)
{
- int PlayerSlot, StatID, StatValue, BaseStat;
+ int globalID, StatID, StatValue, BaseStat;
BaseStat = 0;
- if (!PyArg_ParseTuple( args, "ii|i", &PlayerSlot, &StatID, &BaseStat )) {
+ if (!PyArg_ParseTuple( args, "ii|i", &globalID, &StatID, &BaseStat )) {
return AttributeError( GemRB_GetPlayerStat__doc );
}
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor* MyActor = game->FindPC( PlayerSlot );
- if (!MyActor) {
- return RuntimeError("Cannot find actor!\n");
- }
//returning the modified stat if BaseStat was 0 (default)
- StatValue = GetCreatureStat( MyActor, StatID, !BaseStat );
+ StatValue = GetCreatureStat( actor, StatID, !BaseStat );
return PyInt_FromLong( StatValue );
}
@@ -5118,20 +5497,17 @@ PyDoc_STRVAR( GemRB_SetPlayerStat__doc,
static PyObject* GemRB_SetPlayerStat(PyObject * /*self*/, PyObject* args)
{
- int PlayerSlot, StatID, StatValue;
+ int globalID, StatID, StatValue;
int pcf = 1;
- if (!PyArg_ParseTuple( args, "iii|i", &PlayerSlot, &StatID, &StatValue, &pcf )) {
+ if (!PyArg_ParseTuple( args, "iii|i", &globalID, &StatID, &StatValue, &pcf)) {
return AttributeError( GemRB_SetPlayerStat__doc );
}
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor* MyActor = game->FindPC( PlayerSlot );
- if (!MyActor) {
- return RuntimeError("Cannot find actor!\n");
- }
//Setting the creature's base stat
- SetCreatureStat( MyActor, StatID, StatValue, pcf);
+ SetCreatureStat( actor, StatID, StatValue, pcf);
Py_INCREF( Py_None );
return Py_None;
}
@@ -5144,17 +5520,14 @@ PyDoc_STRVAR( GemRB_GetPlayerScript__doc,
static PyObject* GemRB_GetPlayerScript(PyObject * /*self*/, PyObject* args)
{
//class script is the custom slot for player scripts
- int PlayerSlot, Index = SCR_CLASS;
+ int globalID, Index = SCR_CLASS;
- if (!PyArg_ParseTuple( args, "i|i", &PlayerSlot, &Index )) {
+ if (!PyArg_ParseTuple( args, "i|i", &globalID, &Index )) {
return AttributeError( GemRB_GetPlayerScript__doc );
}
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor *actor = game->FindPC(PlayerSlot);
- if (!actor) {
- return RuntimeError("Cannot find actor!\n");
- }
const char *scr = actor->GetScript(Index);
if (scr[0]==0) {
scr="None";
@@ -5170,17 +5543,14 @@ PyDoc_STRVAR( GemRB_SetPlayerScript__doc,
static PyObject* GemRB_SetPlayerScript(PyObject * /*self*/, PyObject* args)
{
const char *ScriptName;
- int PlayerSlot, Index = SCR_CLASS;
+ int globalID, Index = SCR_CLASS;
- if (!PyArg_ParseTuple( args, "is|i", &PlayerSlot, &ScriptName, &Index )) {
+ if (!PyArg_ParseTuple( args, "is|i", &globalID, &ScriptName, &Index )) {
return AttributeError( GemRB_SetPlayerScript__doc );
}
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor *actor = game->FindPC(PlayerSlot);
- if (!actor) {
- return RuntimeError("Cannot find actor!\n");
- }
actor->SetScript(ScriptName, Index, true);
Py_INCREF( Py_None );
return Py_None;
@@ -5192,56 +5562,37 @@ PyDoc_STRVAR( GemRB_FillPlayerInfo__doc,
static PyObject* GemRB_FillPlayerInfo(PyObject * /*self*/, PyObject* args)
{
- int PlayerSlot;
+ int globalID;
const char *Portrait1=NULL, *Portrait2=NULL;
- if (!PyArg_ParseTuple( args, "i|ss", &PlayerSlot, &Portrait1, &Portrait2)) {
+ if (!PyArg_ParseTuple( args, "i|ss", &globalID, &Portrait1, &Portrait2)) {
return AttributeError( GemRB_FillPlayerInfo__doc );
}
// here comes some code to transfer icon/name to the PC sheet
- //
- //
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor* MyActor = game->FindPC( PlayerSlot );
- if (!MyActor) {
- return RuntimeError( "Actor not found!\n" );
- }
if (Portrait1) {
- MyActor->SetPortrait( Portrait1, 1);
+ actor->SetPortrait( Portrait1, 1);
}
if (Portrait2) {
- MyActor->SetPortrait( Portrait2, 2);
+ actor->SetPortrait( Portrait2, 2);
}
- int mastertable = gamedata->LoadTable( "avprefix" );
- Holder<TableMgr> mtm = gamedata->GetTable( mastertable );
- int count = mtm->GetRowCount();
- if (count< 1 || count>8) {
- return RuntimeError("Table is invalid." );
- }
- const char *poi = mtm->QueryField( 0 );
- // the base animation id
- int AnimID = strtoul( poi, NULL, 0 );
- // tables for additive modifiers of the animation id (race, gender, class)
- for (int i = 1; i < count; i++) {
- poi = mtm->QueryField( i );
- int table = gamedata->LoadTable( poi );
- Holder<TableMgr> tm = gamedata->GetTable( table );
- int StatID = atoi( tm->QueryField() );
- StatID = MyActor->GetBase( StatID );
- poi = tm->QueryField( StatID );
- AnimID += strtoul( poi, NULL, 0 );
- gamedata->DelTable( table );
+
+ //set up animation ID
+ switch(actor->UpdateAnimationID(0)) {
+ case -1: return RuntimeError("avprefix table contains no entries." );
+ case -2: return RuntimeError("Couldn't load avprefix table.");
+ case -3: return RuntimeError("Couldn't load an avprefix subtable.");
}
- MyActor->SetBase(IE_ANIMATION_ID, AnimID);
- //setting PST's starting stance to 18
- poi = mtm->QueryField( 0, 1 );
- if (*poi != '*') {
- MyActor->SetStance( atoi( poi ) );
+
+ actor->SetOver( false );
+ actor->InitButtons(actor->GetStat(IE_CLASS), true); //force re-init of actor's buttons
+
+ //what about multiplayer?
+ if ((globalID == 1) && core->HasFeature(GF_HAS_DPLAYER) ) {
+ actor->SetScript("DPLAYER3", SCR_DEFAULT, false);
}
- gamedata->DelTable( mastertable );
- MyActor->SetOver( false );
- MyActor->InitButtons(MyActor->GetStat(IE_CLASS), true); //force re-init of actor's buttons
Py_INCREF( Py_None );
return Py_None;
}
@@ -5266,8 +5617,8 @@ PyObject *SetSpellIcon(int wi, int ci, const ieResRef SpellResRef, int type, int
Spell* spell = gamedata->GetSpell( SpellResRef, 1 );
if (spell == NULL) {
btn->SetPicture( NULL );
- printMessage( "GUIScript", " ", LIGHT_RED);
- printf("Spell not found :%.8s", SpellResRef );
+ Log(ERROR, "GUIScript", "Spell not found :%.8s",
+ SpellResRef);
//no incref here!
return Py_None;
}
@@ -5333,9 +5684,9 @@ static Sprite2D* GetUsedWeaponIcon(Item *item, int which)
ieh = item->GetWeaponHeader(true);
}
if (ieh) {
- return gamedata->GetBAMSprite(ieh->UseIcon, -1, which);
+ return gamedata->GetBAMSprite(ieh->UseIcon, -1, which, true);
}
- return gamedata->GetBAMSprite(item->ItemIcon, -1, which);
+ return gamedata->GetBAMSprite(item->ItemIcon, -1, which, true);
}
static void SetItemText(int wi, int ci, int charges, bool oneisnone)
@@ -5371,7 +5722,7 @@ PyObject *SetItemIcon(int wi, int ci, const char *ItemResRef, int Which, int too
//no incref here!
return Py_None;
}
- Item* item = gamedata->GetItem(ItemResRef);
+ Item* item = gamedata->GetItem(ItemResRef, true);
if (item == NULL) {
btn->SetPicture(NULL);
//no incref here!
@@ -5384,12 +5735,12 @@ PyObject *SetItemIcon(int wi, int ci, const char *ItemResRef, int Which, int too
int i;
switch (Which) {
case 0: case 1:
- Picture = gamedata->GetBAMSprite(item->ItemIcon, -1, Which);
+ Picture = gamedata->GetBAMSprite(item->ItemIcon, -1, Which, true);
break;
case 2:
btn->SetPicture( NULL ); // also calls ClearPictureList
for (i=0;i<4;i++) {
- Picture = gamedata->GetBAMSprite(item->DescriptionIcon, -1, i);
+ Picture = gamedata->GetBAMSprite(item->DescriptionIcon, -1, i, true);
if (Picture)
btn->StackPicture(Picture);
}
@@ -5402,10 +5753,10 @@ PyObject *SetItemIcon(int wi, int ci, const char *ItemResRef, int Which, int too
Picture = GetUsedWeaponIcon(item, Which-4);
if (Item2ResRef) {
btn->SetPicture( NULL ); // also calls ClearPictureList
- Item* item2 = gamedata->GetItem(Item2ResRef);
+ Item* item2 = gamedata->GetItem(Item2ResRef, true);
if (item2) {
Sprite2D* Picture2;
- Picture2 = gamedata->GetBAMSprite(item2->ItemIcon, -1, Which-4);
+ Picture2 = gamedata->GetBAMSprite(item2->ItemIcon, -1, Which-4, true);
if (Picture2) btn->StackPicture(Picture2);
gamedata->FreeItem( item2, Item2ResRef, false );
}
@@ -5416,7 +5767,7 @@ PyObject *SetItemIcon(int wi, int ci, const char *ItemResRef, int Which, int too
default:
ITMExtHeader *eh = item->GetExtHeader(Which-6);
if (eh) {
- Picture = gamedata->GetBAMSprite(eh->UseIcon, -1, 0);
+ Picture = gamedata->GetBAMSprite(eh->UseIcon, -1, 0, true);
}
else {
Picture = NULL;
@@ -5485,9 +5836,7 @@ PyDoc_STRVAR( GemRB_LeaveStore__doc,
static PyObject* GemRB_LeaveStore(PyObject * /*self*/, PyObject* /*args*/)
{
- if (core->CloseCurrentStore() ) {
- return RuntimeError("Cannot save store!");
- }
+ core->CloseCurrentStore();
core->ResetEventFlag(EF_OPENSTORE);
core->SetEventFlag(EF_PORTRAIT);
Py_INCREF( Py_None );
@@ -5533,6 +5882,9 @@ static PyObject* GemRB_GetContainer(PyObject * /*self*/, PyObject* args)
Container *container = NULL;
if (autoselect) { //autoselect works only with piles
Map *map = actor->GetCurrentArea();
+ if (!map) {
+ return RuntimeError("No current area!");
+ }
//GetContainer should create an empty container
container = map->GetPile(actor->Pos);
} else {
@@ -5555,22 +5907,22 @@ PyDoc_STRVAR( GemRB_GetContainerItem__doc,
static PyObject* GemRB_GetContainerItem(PyObject * /*self*/, PyObject* args)
{
- int PartyID;
+ int globalID;
int index;
- if (!PyArg_ParseTuple( args, "ii", &PartyID, &index )) {
+ if (!PyArg_ParseTuple( args, "ii", &globalID, &index )) {
return AttributeError( GemRB_GetContainerItem__doc );
}
Container *container;
- if (PartyID) {
+ if (globalID) {
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor *actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
Map *map = actor->GetCurrentArea();
+ if (!map) {
+ return RuntimeError("No current area!");
+ }
container = map->TMap->GetContainer(actor->Pos, IE_CONTAINER_PILE);
} else {
container = core->GetCurrentContainer();
@@ -5592,7 +5944,12 @@ static PyObject* GemRB_GetContainerItem(PyObject * /*self*/, PyObject* args)
PyDict_SetItemString(dict, "Usages2", PyInt_FromLong (ci->Usages[2]));
PyDict_SetItemString(dict, "Flags", PyInt_FromLong (ci->Flags));
- Item *item = gamedata->GetItem( ci->ItemResRef );
+ Item *item = gamedata->GetItem(ci->ItemResRef, true);
+ if (!item) {
+ Log(MESSAGE, "GUIScript", "Cannot find container (%s) item %s!", container->GetScriptName(), ci->ItemResRef);
+ Py_INCREF( Py_None );
+ return Py_None;
+ }
bool identified = ci->Flags & IE_INV_ITEM_IDENTIFIED;
PyDict_SetItemString(dict, "ItemName", PyInt_FromLong( (signed) item->GetItemName( identified )) );
@@ -5611,30 +5968,38 @@ PyDoc_STRVAR( GemRB_ChangeContainerItem__doc,
static PyObject* GemRB_ChangeContainerItem(PyObject * /*self*/, PyObject* args)
{
- int PartyID, Slot;
+ int globalID, Slot;
int action;
- if (!PyArg_ParseTuple( args, "iii", &PartyID, &Slot, &action)) {
+ if (!PyArg_ParseTuple( args, "iii", &globalID, &Slot, &action)) {
return AttributeError( GemRB_ChangeContainerItem__doc );
}
GET_GAME();
- Actor* actor;
Container *container;
- if (PartyID) {
- actor = game->FindPC( PartyID );
+ Actor *actor = NULL;
+
+ if (globalID) {
+ if (globalID > 1000) {
+ actor = game->GetActorByGlobalID( globalID );
+ } else {
+ actor = game->FindPC( globalID );
+ }
if (!actor) {
return RuntimeError( "Actor not found!\n" );
}
Map *map = actor->GetCurrentArea();
+ if (!map) {
+ return RuntimeError("No current area!");
+ }
container = map->TMap->GetContainer(actor->Pos, IE_CONTAINER_PILE);
} else {
actor = core->GetFirstSelectedPC(false);
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
container = core->GetCurrentContainer();
}
+ if (!actor) {
+ return RuntimeError( "Actor not found!\n" );
+ }
if (!container) {
return RuntimeError("No current container!");
}
@@ -5649,17 +6014,28 @@ static PyObject* GemRB_ChangeContainerItem(PyObject * /*self*/, PyObject* args)
return RuntimeError("Invalid Container slot!");
}
- res = core->CanMoveItem(container->inventory.GetSlotItem(Slot) );
+ si = container->inventory.GetSlotItem(Slot);
+ res = core->CanMoveItem(si);
if (!res) { //cannot move
- printMessage("GUIScript","Cannot move item, it is undroppable!\n", GREEN);
+ Log(MESSAGE, "GUIScript", "Cannot move item, it is undroppable!");
Py_INCREF( Py_None );
return Py_None;
}
+ // check for full inventory up front to prevent unnecessary shuffling of container
+ // items; note that shuffling will still occur when picking up stacked items where
+ // not the entire stack fits
+ if (res == -1) { // not gold
+ if (actor->inventory.FindCandidateSlot(SLOT_INVENTORY, 0, si->ItemResRef) == -1) {
+ Py_INCREF( Py_None );
+ return Py_None;
+ }
+ }
+
//this will update the container
si = container->RemoveItem(Slot,0);
if (!si) {
- printMessage("GUIScript","Cannot move item, there is something weird!\n", YELLOW);
+ Log(WARNING, "GUIScript", "Cannot move item, there is something weird!");
Py_INCREF( Py_None );
return Py_None;
}
@@ -5684,14 +6060,14 @@ static PyObject* GemRB_ChangeContainerItem(PyObject * /*self*/, PyObject* args)
} else { //put stuff in container, simple!
res = core->CanMoveItem(actor->inventory.GetSlotItem(core->QuerySlot(Slot) ) );
if (!res) { //cannot move
- printMessage("GUIScript","Cannot move item, it is undroppable!\n", GREEN);
+ Log(MESSAGE, "GUIScript","Cannot move item, it is undroppable!");
Py_INCREF( Py_None );
return Py_None;
}
si = actor->inventory.RemoveItem(core->QuerySlot(Slot));
if (!si) {
- printMessage("GUIScript","Cannot move item, there is something weird!\n", YELLOW);
+ Log(WARNING, "GUIScript", "Cannot move item, there is something weird!");
Py_INCREF( Py_None );
return Py_None;
}
@@ -5718,6 +6094,8 @@ static PyObject* GemRB_ChangeContainerItem(PyObject * /*self*/, PyObject* args)
core->GetAudioDrv()->Play(Sound);
}
+ //keep weight up to date
+ actor->CalculateSpeed(false);
Py_INCREF( Py_None );
return Py_None;
}
@@ -5822,18 +6200,14 @@ PyDoc_STRVAR( GemRB_IsValidStoreItem__doc,
static PyObject* GemRB_IsValidStoreItem(PyObject * /*self*/, PyObject* args)
{
- int PartyID, Slot, ret;
+ int globalID, Slot, ret;
int type = 0;
- if (!PyArg_ParseTuple( args, "ii|i", &PartyID, &Slot, &type)) {
+ if (!PyArg_ParseTuple( args, "ii|i", &globalID, &Slot, &type)) {
return AttributeError( GemRB_IsValidStoreItem__doc );
}
GET_GAME();
-
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
Store *store = core->GetCurrentStore();
if (!store) {
@@ -5844,7 +6218,7 @@ static PyObject* GemRB_IsValidStoreItem(PyObject * /*self*/, PyObject* args)
ieDword Flags;
if (type) {
- STOItem* si = store->GetItem( Slot );
+ STOItem* si = store->GetItem( Slot, true );
if (!si) {
return PyInt_FromLong(0);
}
@@ -5858,10 +6232,10 @@ static PyObject* GemRB_IsValidStoreItem(PyObject * /*self*/, PyObject* args)
ItemResRef = si->ItemResRef;
Flags = si->Flags;
}
- Item *item = gamedata->GetItem( ItemResRef );
+ Item *item = gamedata->GetItem(ItemResRef, true);
if (!item) {
- printMessage("GUIScript", " ", LIGHT_RED);
- printf("Invalid resource reference: %s\n", ItemResRef);
+ Log(ERROR, "GUIScript", "Invalid resource reference: %s",
+ ItemResRef);
return PyInt_FromLong(0);
}
@@ -5907,7 +6281,7 @@ static PyObject* GemRB_FindStoreItem(PyObject * /*self*/, PyObject* args)
if (Slot == -1) {
return PyInt_FromLong(0);
}
- STOItem* si = store->GetItem( Slot );
+ STOItem* si = store->GetItem( Slot, true );
if (!si) {
// shouldn't be possible, item vanished
return PyInt_FromLong(0);
@@ -5938,7 +6312,7 @@ static PyObject* GemRB_SetPurchasedAmount(PyObject * /*self*/, PyObject* args)
if (!store) {
return RuntimeError("No current store!");
}
- STOItem* si = store->GetItem( Slot );
+ STOItem* si = store->GetItem( Slot, true );
if (!si) {
return RuntimeError("Store item not found!");
}
@@ -5966,19 +6340,15 @@ PyDoc_STRVAR( GemRB_ChangeStoreItem__doc,
static PyObject* GemRB_ChangeStoreItem(PyObject * /*self*/, PyObject* args)
{
- int PartyID, Slot;
+ int globalID, Slot;
int action;
int res = ASI_FAILED;
- if (!PyArg_ParseTuple( args, "iii", &PartyID, &Slot, &action)) {
+ if (!PyArg_ParseTuple( args, "iii", &globalID, &Slot, &action)) {
return AttributeError( GemRB_ChangeStoreItem__doc );
}
GET_GAME();
-
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
Store *store = core->GetCurrentStore();
if (!store) {
@@ -5988,7 +6358,7 @@ static PyObject* GemRB_ChangeStoreItem(PyObject * /*self*/, PyObject* args)
case IE_STORE_STEAL:
case IE_STORE_BUY:
{
- STOItem* si = store->GetItem( Slot );
+ STOItem* si = store->GetItem( Slot, true );
if (!si) {
return RuntimeError("Store item not found!");
}
@@ -6010,6 +6380,8 @@ static PyObject* GemRB_ChangeStoreItem(PyObject * /*self*/, PyObject* args)
} else {
store->RemoveItem( Slot );
}
+ //keep encumbrance labels up to date
+ actor->CalculateSpeed(false);
res = ASI_SUCCESS;
break;
}
@@ -6025,7 +6397,7 @@ static PyObject* GemRB_ChangeStoreItem(PyObject * /*self*/, PyObject* args)
}
case IE_STORE_SELECT|IE_STORE_BUY:
{
- STOItem* si = store->GetItem( Slot );
+ STOItem* si = store->GetItem( Slot, true );
if (!si) {
return RuntimeError("Store item not found!");
}
@@ -6055,7 +6427,7 @@ static PyObject* GemRB_ChangeStoreItem(PyObject * /*self*/, PyObject* args)
{
//store/bag is at full capacity
if (store->Capacity && (store->Capacity <= store->GetRealStockSize()) ) {
- printMessage("GUIScript", "Store is full.\n", GREEN);
+ Log(MESSAGE, "GUIScript", "Store is full.");
res = ASI_FAILED;
break;
}
@@ -6069,10 +6441,10 @@ static PyObject* GemRB_ChangeStoreItem(PyObject * /*self*/, PyObject* args)
if (!si->Expired && (si->Flags& IE_INV_ITEM_RESELLABLE)) {
si->Flags &= ~IE_INV_ITEM_SELECTED;
store->AddItem( si );
- STOItem *s = store->GetItem(store->FindItem(si->ItemResRef, true));
- s->AmountInStock++;
}
delete si;
+ //keep encumbrance labels up to date
+ actor->CalculateSpeed(false);
res = ASI_SUCCESS;
break;
}
@@ -6096,14 +6468,14 @@ static PyObject* GemRB_GetStoreItem(PyObject * /*self*/, PyObject* args)
return RuntimeError("No current store!");
}
if (index>=(int) store->GetRealStockSize()) {
- printMessage("GUIScript","Item is not available???",YELLOW);
+ Log(WARNING, "GUIScript", "Item is not available???");
Py_INCREF( Py_None );
return Py_None;
}
PyObject* dict = PyDict_New();
- STOItem *si=store->GetItem( index );
+ STOItem *si=store->GetItem( index, true );
if (!si) {
- printMessage("GUIScript","Item is not available???",YELLOW);
+ Log(WARNING, "GUIScript", "Item is not available???");
Py_INCREF( Py_None );
return Py_None;
}
@@ -6114,19 +6486,15 @@ static PyObject* GemRB_GetStoreItem(PyObject * /*self*/, PyObject* args)
PyDict_SetItemString(dict, "Flags", PyInt_FromLong (si->Flags));
PyDict_SetItemString(dict, "Purchased", PyInt_FromLong (si->PurchasedAmount) );
- int amount;
if (si->InfiniteSupply==-1) {
PyDict_SetItemString(dict, "Amount", PyInt_FromLong( -1 ) );
- amount = 100;
} else {
- amount = si->AmountInStock;
- PyDict_SetItemString(dict, "Amount", PyInt_FromLong( amount ) );
+ PyDict_SetItemString(dict, "Amount", PyInt_FromLong( si->AmountInStock ) );
}
- Item *item = gamedata->GetItem( si->ItemResRef );
-
+ Item *item = gamedata->GetItem(si->ItemResRef, true);
if (!item) {
- printMessage("GUIScript","Item is not available???",YELLOW);
+ Log(WARNING, "GUIScript", "Item is not available???");
Py_INCREF( Py_None );
return Py_None;
}
@@ -6139,9 +6507,8 @@ static PyObject* GemRB_GetStoreItem(PyObject * /*self*/, PyObject* args)
//calculate depreciation too
//store->DepreciationRate, mount
- if (item->StackAmount>1) {
- price *= si->Usages[0];
- }
+ price *= si->Usages[0];
+
//is this correct?
if (price<1) {
price = 1;
@@ -6313,7 +6680,7 @@ static PyObject* GemRB_ExecuteString(PyObject * /*self*/, PyObject* args)
if (pc) {
GameScript::ExecuteString( pc, String );
} else {
- printMessage("GUIScript","Player not found!\n", YELLOW);
+ Log(WARNING, "GUIScript", "Player not found!");
}
} else {
GameScript::ExecuteString( game->GetCurrentArea( ), String );
@@ -6336,9 +6703,9 @@ static PyObject* GemRB_EvaluateString(PyObject * /*self*/, PyObject* args)
GET_GAME();
if (GameScript::EvaluateString( game->GetCurrentArea( ), String )) {
- printf( "%s returned True\n", String );
+ print("%s returned True", String);
} else {
- printf( "%s returned False\n", String );
+ print("%s returned False", String);
}
Py_INCREF( Py_None );
return Py_None;
@@ -6368,6 +6735,28 @@ static PyObject* GemRB_UpdateAmbientsVolume(PyObject * /*self*/, PyObject* /*arg
return Py_None;
}
+PyDoc_STRVAR( GemRB_MessageWindowDebug__doc,
+ "MessageWindowDebug(log_level)\n\n"
+ "Enable/Disable debug messages of log_level in the MessageWindow." );
+
+static PyObject* GemRB_MessageWindowDebug(PyObject * /*self*/, PyObject* args)
+{
+ int logLevel;
+ if (!PyArg_ParseTuple( args, "i", &logLevel )) {
+ return AttributeError( GemRB_MessageWindowDebug__doc );
+ }
+
+ if (logLevel == -1) {
+ RemoveLogger(getMessageWindowLogger());
+ } else {
+ // convert it to the internal representation
+ getMessageWindowLogger(true)->SetLogLevel((log_level)logLevel);
+ }
+
+ Py_INCREF( Py_None );
+ return Py_None;
+}
+
PyDoc_STRVAR( GemRB_GetCurrentArea__doc,
"GetCurrentArea()=>resref\n\n"
"Returns current area's ResRef." );
@@ -6406,7 +6795,7 @@ static PyObject* GemRB_MoveToArea(PyObject * /*self*/, PyObject* args)
if (map1) {
map1->RemoveActor( actor );
}
- map2->AddActor( actor );
+ map2->AddActor( actor, true );
}
Py_INCREF( Py_None );
@@ -6419,17 +6808,13 @@ PyDoc_STRVAR( GemRB_GetMemorizableSpellsCount__doc,
static PyObject* GemRB_GetMemorizableSpellsCount(PyObject* /*self*/, PyObject* args)
{
- int PartyID, SpellType, Level, Bonus=1;
+ int globalID, SpellType, Level, Bonus=1;
- if (!PyArg_ParseTuple( args, "iii|i", &PartyID, &SpellType, &Level, &Bonus )) {
+ if (!PyArg_ParseTuple( args, "iii|i", &globalID, &SpellType, &Level, &Bonus )) {
return AttributeError( GemRB_GetMemorizableSpellsCount__doc );
}
GET_GAME();
-
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
//this isn't in the actor's spellbook, handles Wisdom
return PyInt_FromLong(actor->spellbook.GetMemorizableSpellsCount( (ieSpellType) SpellType, Level, (bool) Bonus ) );
@@ -6441,17 +6826,13 @@ PyDoc_STRVAR( GemRB_SetMemorizableSpellsCount__doc,
static PyObject* GemRB_SetMemorizableSpellsCount(PyObject* /*self*/, PyObject* args)
{
- int PartyID, Value, SpellType, Level;
+ int globalID, Value, SpellType, Level;
- if (!PyArg_ParseTuple( args, "iiii", &PartyID, &Value, &SpellType, &Level)) {
+ if (!PyArg_ParseTuple( args, "iiii", &globalID, &Value, &SpellType, &Level)) {
return AttributeError( GemRB_SetMemorizableSpellsCount__doc );
}
GET_GAME();
-
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
//the bonus increased value (with wisdom too) is handled by the core
actor->spellbook.SetMemorizableSpellsCount( Value, (ieSpellType) SpellType, Level, 0 );
@@ -6460,22 +6841,47 @@ static PyObject* GemRB_SetMemorizableSpellsCount(PyObject* /*self*/, PyObject* a
return Py_None;
}
+PyDoc_STRVAR( GemRB_CountSpells__doc,
+"CountSpells(PartyID, SpellName, SpellType, Flag)=>int\n\n"
+"Returns number of memorized spells of given name and type in PC's spellbook.\n"
+"If flag is set then spent spells are also count.");
+
+static PyObject* GemRB_CountSpells(PyObject * /*self*/, PyObject* args)
+{
+ int globalID, SpellType = -1;
+ char *SpellResRef;
+ int Flag = 0;
+
+ if (!PyArg_ParseTuple( args, "is|ii", &globalID, &SpellResRef, &SpellType, &Flag)) {
+ return AttributeError( GemRB_CountSpells__doc );
+ }
+ GET_GAME();
+ GET_ACTOR_GLOBAL();
+
+ return PyInt_FromLong(actor->spellbook.CountSpells( SpellResRef, SpellType, Flag) );
+}
+
PyDoc_STRVAR( GemRB_GetKnownSpellsCount__doc,
"GetKnownSpellsCount(PartyID, SpellType, Level)=>int\n\n"
-"Returns number of known spells of given type and level in PC's spellbook." );
+"Returns number of known spells of given type and level in PC's spellbook."
+"If level isn't given, it will return the number of all spells of the given type.");
static PyObject* GemRB_GetKnownSpellsCount(PyObject * /*self*/, PyObject* args)
{
- int PartyID, SpellType, Level;
+ int globalID, SpellType, Level = -1;
- if (!PyArg_ParseTuple( args, "iii", &PartyID, &SpellType, &Level )) {
+ if (!PyArg_ParseTuple( args, "ii|i", &globalID, &SpellType, &Level)) {
return AttributeError( GemRB_GetKnownSpellsCount__doc );
}
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
+ if (Level<0) {
+ int tmp = 0;
+ for(int i=0;i<9;i++) {
+ tmp += actor->spellbook.GetKnownSpellsCount( SpellType, i );
+ }
+ return PyInt_FromLong(tmp);
}
return PyInt_FromLong(actor->spellbook.GetKnownSpellsCount( SpellType, Level ) );
@@ -6483,21 +6889,17 @@ static PyObject* GemRB_GetKnownSpellsCount(PyObject * /*self*/, PyObject* args)
PyDoc_STRVAR( GemRB_GetKnownSpell__doc,
"GetKnownSpell(PartyID, SpellType, Level, Index)=>dict\n\n"
-"Returns dict with specified known spell from PC's spellbook." );
+"Returns dict with specified known spell from PC's spellbook.");
static PyObject* GemRB_GetKnownSpell(PyObject * /*self*/, PyObject* args)
{
- int PartyID, SpellType, Level, Index;
+ int globalID, SpellType, Level, Index;
- if (!PyArg_ParseTuple( args, "iiii", &PartyID, &SpellType, &Level, &Index )) {
+ if (!PyArg_ParseTuple( args, "iiii", &globalID, &SpellType, &Level, &Index)) {
return AttributeError( GemRB_GetKnownSpell__doc );
}
GET_GAME();
-
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
CREKnownSpell* ks = actor->spellbook.GetKnownSpell( SpellType, Level, Index );
if (! ks) {
@@ -6513,55 +6915,45 @@ static PyObject* GemRB_GetKnownSpell(PyObject * /*self*/, PyObject* args)
PyDoc_STRVAR( GemRB_GetMemorizedSpellsCount__doc,
-"GetMemorizedSpellsCount(PartyID, SpellType[, Level, global])=>int\n\n"
+"GetMemorizedSpellsCount(PartyID, SpellType, Level, castable)=>int\n\n"
"Returns number of spells of given type and level in PartyID's memory. "
-"If level is omitted then it returns the number of distinct spells memorised.\n"
-"If global is set, the actor will be looked up by its global ID instead of party slot.");
+"If level is omitted then it returns the number of distinct spells memorised.\n");
static PyObject* GemRB_GetMemorizedSpellsCount(PyObject * /*self*/, PyObject* args)
{
- int PartyID, SpellType, Level = -1;
- int global = 0;
+ int globalID, SpellType, Level = -1;
+ int castable;
- if (!PyArg_ParseTuple( args, "ii|ii", &PartyID, &SpellType, &Level, &global )) {
+ if (!PyArg_ParseTuple( args, "iiii", &globalID, &SpellType, &Level, &castable)) {
return AttributeError( GemRB_GetMemorizedSpellsCount__doc );
}
GET_GAME();
-
- Actor* actor;
- if (global) {
- actor = game->GetActorByGlobalID( PartyID );
- } else {
- actor = game->FindPC( PartyID );
- }
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
if (Level<0) {
- return PyInt_FromLong( actor->spellbook.GetSpellInfoSize( SpellType ) );
+ if (castable) {
+ return PyInt_FromLong( actor->spellbook.GetSpellInfoSize( SpellType ) );
+ } else {
+ return PyInt_FromLong( actor->spellbook.GetMemorizedSpellsCount( SpellType, false ) );
+ }
} else {
- return PyInt_FromLong( actor->spellbook.GetMemorizedSpellsCount( SpellType, Level ) );
+ return PyInt_FromLong( actor->spellbook.GetMemorizedSpellsCount( SpellType, Level, castable ) );
}
}
PyDoc_STRVAR( GemRB_GetMemorizedSpell__doc,
"GetMemorizedSpell(PartyID, SpellType, Level, Index)=>dict\n\n"
-"Returns dict with specified memorized spell from PC's spellbook." );
+"Returns dict with specified memorized spell from PC's spellbook.");
static PyObject* GemRB_GetMemorizedSpell(PyObject * /*self*/, PyObject* args)
{
- int PartyID, SpellType, Level, Index;
+ int globalID, SpellType, Level, Index;
- if (!PyArg_ParseTuple( args, "iiii", &PartyID, &SpellType, &Level, &Index )) {
+ if (!PyArg_ParseTuple( args, "iiii", &globalID, &SpellType, &Level, &Index)) {
return AttributeError( GemRB_GetMemorizedSpell__doc );
}
GET_GAME();
-
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
CREMemorizedSpell* ms = actor->spellbook.GetMemorizedSpell( SpellType, Level, Index );
if (! ms) {
@@ -6571,7 +6963,6 @@ static PyObject* GemRB_GetMemorizedSpell(PyObject * /*self*/, PyObject* args)
PyObject* dict = PyDict_New();
PyDict_SetItemString(dict, "SpellResRef", PyString_FromResRef (ms->SpellResRef));
PyDict_SetItemString(dict, "Flags", PyInt_FromLong (ms->Flags));
-
return dict;
}
@@ -6601,39 +6992,114 @@ static PyObject* GemRB_GetSpell(PyObject * /*self*/, PyObject* args)
}
PyObject* dict = PyDict_New();
+ PyDict_SetItemString(dict, "SpellType", PyInt_FromLong (spell->SpellType));
PyDict_SetItemString(dict, "SpellName", PyInt_FromLong ((signed) spell->SpellName));
PyDict_SetItemString(dict, "SpellDesc", PyInt_FromLong ((signed) spell->SpellDesc));
PyDict_SetItemString(dict, "SpellbookIcon", PyString_FromResRef (spell->SpellbookIcon));
PyDict_SetItemString(dict, "SpellExclusion", PyInt_FromLong (spell->ExclusionSchool)); //this will list school exclusions and alignment
PyDict_SetItemString(dict, "SpellDivine", PyInt_FromLong (spell->PriestType)); //this will tell apart a priest spell from a druid spell
PyDict_SetItemString(dict, "SpellSchool", PyInt_FromLong (spell->PrimaryType));
- PyDict_SetItemString(dict, "SpellType", PyInt_FromLong (spell->SecondaryType));
+ PyDict_SetItemString(dict, "SpellSecondary", PyInt_FromLong (spell->SecondaryType));
PyDict_SetItemString(dict, "SpellLevel", PyInt_FromLong (spell->SpellLevel));
+ PyDict_SetItemString(dict, "Completion", PyString_FromResRef (spell->CompletionSound));
PyDict_SetItemString(dict, "SpellTargetType", PyInt_FromLong (spell->GetExtHeader(0)->Target));
+ PyDict_SetItemString(dict, "NonHostile", PyInt_FromLong (!(spell->Flags&SF_HOSTILE) && !spell->ContainsDamageOpcode()));
+ PyDict_SetItemString(dict, "SpellResRef", PyString_FromResRef (spell->Name));
gamedata->FreeSpell( spell, ResRef, false );
return dict;
}
+PyDoc_STRVAR( GemRB_CheckSpecialSpell__doc,
+"CheckSpecialSpell(GlobalID, SpellResRef)=>int\n\n"
+"Checks if the specified spell is special. Returns 0 for normal ones." );
+
+static PyObject* GemRB_CheckSpecialSpell(PyObject * /*self*/, PyObject* args)
+{
+ int globalID;
+ const char *SpellResRef;
+
+ if (!PyArg_ParseTuple( args, "is", &globalID, &SpellResRef)) {
+ return AttributeError( GemRB_CheckSpecialSpell__doc );
+ }
+ GET_GAME();
+
+ Actor* actor = game->GetActorByGlobalID( globalID );
+ if (!actor) {
+ return RuntimeError( "Actor not found!\n" );
+ }
+
+ int ret = core->CheckSpecialSpell( SpellResRef, actor );
+ return PyInt_FromLong( ret );
+}
+
+PyDoc_STRVAR( GemRB_GetSpelldataIndex__doc,
+"GetSpelldataIndex(globalID, spellResRef, type)=>int\n\n"
+"Returns the index of the spell in the spellbook's spellinfo structure."
+);
+
+static PyObject* GemRB_GetSpelldataIndex(PyObject * /*self*/, PyObject* args)
+{
+ unsigned int globalID;
+ const char *spellResRef;
+ int type;
+
+ if (!PyArg_ParseTuple( args, "isi", &globalID, &spellResRef, &type)) {
+ return AttributeError( GemRB_GetSpelldataIndex__doc );
+ }
+
+ GET_GAME();
+ GET_ACTOR_GLOBAL();
+
+ SpellExtHeader spelldata;
+ int ret = actor->spellbook.FindSpellInfo(&spelldata, spellResRef, type);
+ return PyInt_FromLong( ret-1 );
+}
+
+PyDoc_STRVAR( GemRB_GetSpelldata__doc,
+"GetSpelldata(globalID[, type])=>tuple\n\n"
+"Returns a tuple containing resrefs of the spells in the spellbook's spellinfo structure."
+);
+
+static PyObject* GemRB_GetSpelldata(PyObject * /*self*/, PyObject* args)
+{
+ unsigned int globalID;
+ int type = 255;
+
+ if (!PyArg_ParseTuple( args, "i|i", &globalID, &type)) {
+ return AttributeError( GemRB_GetSpelldata__doc );
+ }
+
+ GET_GAME();
+ GET_ACTOR_GLOBAL();
+
+ SpellExtHeader spelldata;
+ int i = 0;
+ int count = actor->spellbook.GetSpellInfoSize(type);
+ PyObject* spell_list = PyTuple_New(count);
+ for (i=0; i < count; i++) {
+ actor->spellbook.GetSpellInfo(&spelldata, type, i, 1);
+ PyTuple_SetItem(spell_list, i, PyString_FromResRef(spelldata.spellname) );
+ }
+ return spell_list;
+}
+
+
PyDoc_STRVAR( GemRB_LearnSpell__doc,
"LearnSpell(PartyID, SpellResRef[, Flags])=>int\n\n"
"Learns specified spell. Returns 0 on success." );
static PyObject* GemRB_LearnSpell(PyObject * /*self*/, PyObject* args)
{
- int PartyID;
+ int globalID;
const char *Spell;
int Flags=0;
- if (!PyArg_ParseTuple( args, "is|i", &PartyID, &Spell, &Flags )) {
+ if (!PyArg_ParseTuple( args, "is|i", &globalID, &Spell, &Flags )) {
return AttributeError( GemRB_LearnSpell__doc );
}
GET_GAME();
-
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
int ret = actor->LearnSpell( Spell, Flags ); // returns 0 on success
if (!ret) core->SetEventFlag( EF_ACTION );
@@ -6648,18 +7114,14 @@ static EffectRef work_ref;
static PyObject* GemRB_DispelEffect(PyObject * /*self*/, PyObject* args)
{
- int PartyID, Parameter2;
+ int globalID, Parameter2;
const char *EffectName;
- if (!PyArg_ParseTuple( args, "isi", &PartyID, &EffectName, &Parameter2 )) {
+ if (!PyArg_ParseTuple( args, "isi", &globalID, &EffectName, &Parameter2 )) {
return AttributeError( GemRB_DispelEffect__doc );
}
GET_GAME();
-
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
work_ref.Name=EffectName;
work_ref.opcode=-1;
@@ -6676,18 +7138,14 @@ PyDoc_STRVAR( GemRB_RemoveEffects__doc,
static PyObject* GemRB_RemoveEffects(PyObject * /*self*/, PyObject* args)
{
- int PartyID;
+ int globalID;
const char * SpellResRef;
- if (!PyArg_ParseTuple( args, "is", &PartyID, &SpellResRef )) {
+ if (!PyArg_ParseTuple( args, "is", &globalID, &SpellResRef )) {
return AttributeError( GemRB_RemoveEffects__doc );
}
GET_GAME();
-
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
actor->fxqueue.RemoveAllEffects(SpellResRef);
@@ -6701,18 +7159,24 @@ PyDoc_STRVAR( GemRB_RemoveSpell__doc,
static PyObject* GemRB_RemoveSpell(PyObject * /*self*/, PyObject* args)
{
- int PartyID, SpellType, Level, Index;
+ int globalID, SpellType, Level, Index;
+ const char *SpellResRef;
- if (!PyArg_ParseTuple( args, "iiii", &PartyID, &SpellType, &Level, &Index )) {
- return AttributeError( GemRB_RemoveSpell__doc );
- }
GET_GAME();
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
+ if (PyArg_ParseTuple( args, "is", &globalID, &SpellResRef) ) {
+ GET_ACTOR_GLOBAL();
+ int ret = actor->spellbook.KnowSpell(SpellResRef);
+ actor->spellbook.RemoveSpell(SpellResRef);
+ return PyInt_FromLong(ret);
+ }
+ PyErr_Clear(); //clear the type exception from above
+
+ if (!PyArg_ParseTuple( args, "iiii", &globalID, &SpellType, &Level, &Index )) {
+ return AttributeError( GemRB_RemoveSpell__doc );
}
+ GET_ACTOR_GLOBAL();
CREKnownSpell* ks = actor->spellbook.GetKnownSpell( SpellType, Level, Index );
if (! ks) {
return RuntimeError( "Spell not known!" );
@@ -6727,18 +7191,14 @@ PyDoc_STRVAR( GemRB_RemoveItem__doc,
static PyObject* GemRB_RemoveItem(PyObject * /*self*/, PyObject* args)
{
- int PartyID, Slot;
+ int globalID, Slot;
int Count = 0;
- if (!PyArg_ParseTuple( args, "ii|i", &PartyID, &Slot, &Count )) {
+ if (!PyArg_ParseTuple( args, "ii|i", &globalID, &Slot, &Count )) {
return AttributeError( GemRB_RemoveItem__doc );
}
GET_GAME();
-
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
int ok;
@@ -6755,93 +7215,85 @@ static PyObject* GemRB_RemoveItem(PyObject * /*self*/, PyObject* args)
}
PyDoc_STRVAR( GemRB_MemorizeSpell__doc,
-"MemorizeSpell(PartyID, SpellType, Level, Index)=>bool\n\n"
+"MemorizeSpell(PartyID, SpellType, Level, Index[, enabled])=>bool\n\n"
"Memorizes specified known spell. Returns 1 on success." );
static PyObject* GemRB_MemorizeSpell(PyObject * /*self*/, PyObject* args)
{
- int PartyID, SpellType, Level, Index;
+ int globalID, SpellType, Level, Index, enabled=0;
- if (!PyArg_ParseTuple( args, "iiii", &PartyID, &SpellType, &Level, &Index )) {
+ if (!PyArg_ParseTuple( args, "iiii|i", &globalID, &SpellType, &Level, &Index, &enabled )) {
return AttributeError( GemRB_MemorizeSpell__doc );
}
GET_GAME();
-
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
CREKnownSpell* ks = actor->spellbook.GetKnownSpell( SpellType, Level, Index );
if (! ks) {
return RuntimeError( "Spell not found!" );
}
- bool enabled = false;
- if (SpellType == IE_SPELL_TYPE_INNATE) enabled = true;
+ // auto-refresh innates (memorisation defaults to depleted)
+ if (core->HasFeature(GF_HAS_SPELLLIST)) {
+ if (SpellType == IE_IWD2_SPELL_INNATE) enabled = 1;
+ } else {
+ if (SpellType == IE_SPELL_TYPE_INNATE) enabled = 1;
+ }
return PyInt_FromLong( actor->spellbook.MemorizeSpell( ks, enabled ) );
}
PyDoc_STRVAR( GemRB_UnmemorizeSpell__doc,
-"UnmemorizeSpell(PartyID, SpellType, Level, Index)=>bool\n\n"
-"Unmemorizes specified known spell. Returns 1 on success." );
+"UnmemorizeSpell(PartyID, SpellType, Level, Index[, onlydepleted])=>bool\n\n"
+"Unmemorizes specified known spell. Returns 1 on success.\n"
+"If onlydepleted is set, it will only remove an already depleted spell (with the same resref as the provided spell)." );
static PyObject* GemRB_UnmemorizeSpell(PyObject * /*self*/, PyObject* args)
{
- int PartyID, SpellType, Level, Index;
+ int globalID, SpellType, Level, Index, onlydepleted=0;
- if (!PyArg_ParseTuple( args, "iiii", &PartyID, &SpellType, &Level, &Index )) {
+ if (!PyArg_ParseTuple( args, "iiii|i", &globalID, &SpellType, &Level, &Index, &onlydepleted )) {
return AttributeError( GemRB_UnmemorizeSpell__doc );
}
GET_GAME();
-
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
CREMemorizedSpell* ms = actor->spellbook.GetMemorizedSpell( SpellType, Level, Index );
if (! ms) {
return RuntimeError( "Spell not found!\n" );
}
-
- return PyInt_FromLong( actor->spellbook.UnmemorizeSpell( ms ) );
+ if (onlydepleted)
+ return PyInt_FromLong(actor->spellbook.UnmemorizeSpell(ms->SpellResRef, false, onlydepleted));
+ else
+ return PyInt_FromLong(actor->spellbook.UnmemorizeSpell(ms));
}
PyDoc_STRVAR( GemRB_GetSlotItem__doc,
-"GetSlotItem(PartyID, slot[, global])=>dict\n\n"
-"Returns dict with specified slot item from PC's inventory or the dragged item if PartyID is 0.\n"
-"If global is set, the actor will be looked up by its global ID instead of party slot.");
+"GetSlotItem(globalID, slot[, translated])=>dict\n\n"
+"Returns dict with specified slot item from PC's inventory or the dragged item if globalID is 0.\n\n"
+"If translated is nonzero, the slot will not be looked up again.\n");
static PyObject* GemRB_GetSlotItem(PyObject * /*self*/, PyObject* args)
{
- int PartyID, Slot;
- int global = 0;
+ int globalID, Slot;
+ int translated = 0; // inventory slots are numbered differently in CRE and need to be remapped
- if (!PyArg_ParseTuple( args, "ii|i", &PartyID, &Slot, &global)) {
+ if (!PyArg_ParseTuple( args, "ii|i", &globalID, &Slot, &translated)) {
return AttributeError( GemRB_GetSlotItem__doc );
}
CREItem *si;
int header = -1;
- if (PartyID==0) {
+ if (globalID==0) {
si = core->GetDraggedItem();
} else {
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor* actor;
- if (global) {
- actor = game->GetActorByGlobalID( PartyID );
- } else {
- actor = game->FindPC( PartyID );
- }
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
+ if (!translated) {
+ Slot = core->QuerySlot(Slot);
}
-
- Slot = core->QuerySlot(Slot);
header = actor->PCStats->GetHeaderForSlot(Slot);
si = actor->inventory.GetSlotItem( Slot );
@@ -6867,17 +7319,14 @@ PyDoc_STRVAR( GemRB_ChangeItemFlag__doc,
static PyObject* GemRB_ChangeItemFlag(PyObject * /*self*/, PyObject* args)
{
- int PartyID, Slot, Flags, Mode;
+ int globalID, Slot, Flags, Mode;
- if (!PyArg_ParseTuple( args, "iiii", &PartyID, &Slot, &Flags, &Mode)) {
+ if (!PyArg_ParseTuple( args, "iiii", &globalID, &Slot, &Flags, &Mode)) {
return AttributeError( GemRB_ChangeItemFlag__doc );
}
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor *actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
if (actor->inventory.ChangeItemFlag(core->QuerySlot(Slot), Flags, Mode)) {
return PyInt_FromLong(1);
}
@@ -6891,25 +7340,30 @@ PyDoc_STRVAR( GemRB_CanUseItemType__doc,
static PyObject* GemRB_CanUseItemType(PyObject * /*self*/, PyObject* args)
{
- int SlotType, PartyID, Equipped;
+ int SlotType, globalID, Equipped;
const char *ItemName;
- PartyID = 0;
- if (!PyArg_ParseTuple( args, "is|ii", &SlotType, &ItemName, &PartyID, &Equipped)) {
+ globalID = 0;
+ if (!PyArg_ParseTuple( args, "is|ii", &SlotType, &ItemName, &globalID, &Equipped)) {
return AttributeError( GemRB_CanUseItemType__doc );
}
if (!ItemName[0]) {
return PyInt_FromLong(0);
}
- Item *item = gamedata->GetItem(ItemName);
+ Item *item = gamedata->GetItem(ItemName, true);
if (!item) {
+ Log(MESSAGE, "GUIScript", "Cannot find item %s to check!", ItemName);
return PyInt_FromLong(0);
}
- Actor* actor = 0;
- if (PartyID) {
+ Actor* actor = NULL;
+ if (globalID) {
GET_GAME();
- actor = game->FindPC( PartyID );
+ if (globalID > 1000) {
+ actor = game->GetActorByGlobalID( globalID );
+ } else {
+ actor = game->FindPC( globalID );
+ }
if (!actor) {
return RuntimeError( "Actor not found!\n" );
}
@@ -6931,19 +7385,15 @@ PyDoc_STRVAR( GemRB_GetSlots__doc,
static PyObject* GemRB_GetSlots(PyObject * /*self*/, PyObject* args)
{
- int SlotType, Count, MaxCount, PartyID;
+ int SlotType, Count, MaxCount, globalID;
int flag = 1;
- if (!PyArg_ParseTuple( args, "ii|i", &PartyID, &SlotType, &flag)) {
+ if (!PyArg_ParseTuple( args, "ii|i", &globalID, &SlotType, &flag)) {
return AttributeError( GemRB_GetSlots__doc );
}
GET_GAME();
-
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
MaxCount = core->SlotTypes;
int i;
@@ -7006,8 +7456,9 @@ static PyObject* GemRB_GetItem(PyObject * /*self*/, PyObject* args)
actor = game->FindPC( PartyID );
}
- Item* item = gamedata->GetItem(ResRef);
+ Item* item = gamedata->GetItem(ResRef, true);
if (item == NULL) {
+ Log(MESSAGE, "GUIScript", "Cannot get item %s!", ResRef);
Py_INCREF( Py_None );
return Py_None;
}
@@ -7020,7 +7471,7 @@ static PyObject* GemRB_GetItem(PyObject * /*self*/, PyObject* args)
PyDict_SetItemString(dict, "ItemIcon", PyString_FromResRef (item->ItemIcon));
PyDict_SetItemString(dict, "DescIcon", PyString_FromResRef (item->DescriptionIcon));
PyDict_SetItemString(dict, "BrokenItem", PyString_FromResRef (item->ReplacementItem));
- PyDict_SetItemString(dict, "StackAmount", PyInt_FromLong (item->StackAmount));
+ PyDict_SetItemString(dict, "MaxStackAmount", PyInt_FromLong (item->MaxStackAmount));
PyDict_SetItemString(dict, "Dialog", PyString_FromResRef (item->Dialog));
PyDict_SetItemString(dict, "DialogName", PyInt_FromLong ((signed)item->DialogName));
PyDict_SetItemString(dict, "Price", PyInt_FromLong (item->Price));
@@ -7028,6 +7479,7 @@ static PyObject* GemRB_GetItem(PyObject * /*self*/, PyObject* args)
PyDict_SetItemString(dict, "AnimationType", PyString_FromAnimID(item->AnimationType));
PyDict_SetItemString(dict, "Exclusion", PyInt_FromLong(item->ItemExcl));
PyDict_SetItemString(dict, "LoreToID", PyInt_FromLong(item->LoreToID));
+ PyDict_SetItemString(dict, "MaxCharge", PyInt_FromLong(0) );
int ehc = item->ExtHeaderCount;
@@ -7035,6 +7487,8 @@ static PyObject* GemRB_GetItem(PyObject * /*self*/, PyObject* args)
for(int i=0;i<ehc;i++) {
int tip = core->GetItemTooltip(ResRef, i, 1);
PyTuple_SetItem(tooltiptuple, i, PyInt_FromLong(tip));
+ ITMExtHeader *eh = item->ext_headers+i;
+ PyDict_SetItemString(dict, "MaxCharge", PyInt_FromLong(eh->Charges) );
}
PyDict_SetItemString(dict, "Tooltips", tooltiptuple);
@@ -7135,7 +7589,7 @@ int CheckRemoveItem(Actor *actor, CREItem *si, int action)
break;
}
- displaymsg->DisplayString(UsedItems[i].value,0xffffff, IE_STR_SOUND);
+ displaymsg->DisplayString(UsedItems[i].value, DMC_WHITE, IE_STR_SOUND);
return 1;
}
return 0;
@@ -7160,7 +7614,11 @@ CREItem *TryToUnequip(Actor *actor, unsigned int Slot, unsigned int Count)
///fixme: make difference between cursed/unmovable
if (! actor->inventory.UnEquipItem( Slot, false )) {
// Item is currently undroppable/cursed
- displaymsg->DisplayConstantString(STR_CANT_DROP_ITEM,0xffffff);
+ if (si->Flags&IE_INV_ITEM_CURSED) {
+ displaymsg->DisplayConstantString(STR_CURSED, DMC_WHITE);
+ } else {
+ displaymsg->DisplayConstantString(STR_CANT_DROP_ITEM, DMC_WHITE);
+ }
return NULL;
}
si = actor->inventory.RemoveItem( Slot, Count );
@@ -7168,16 +7626,16 @@ CREItem *TryToUnequip(Actor *actor, unsigned int Slot, unsigned int Count)
}
PyDoc_STRVAR( GemRB_DragItem__doc,
-"DragItem(PartyID, Slot, ResRef, [Count=0, Type])\n\n"
-"Start dragging specified item, if Slot is negative, drag the PartyID portrait instead." );
+"DragItem(globalID, Slot, ResRef, [Count=0, Type])\n\n"
+"Start dragging specified item, if Slot is negative, drag the globalID party portrait instead." );
static PyObject* GemRB_DragItem(PyObject * /*self*/, PyObject* args)
{
ieResRef Sound;
- int PartyID, Slot, Count = 0, Type = 0;
+ int globalID, Slot, Count = 0, Type = 0;
const char *ResRef;
- if (!PyArg_ParseTuple( args, "iis|ii", &PartyID, &Slot, &ResRef, &Count, &Type)) {
+ if (!PyArg_ParseTuple( args, "iis|ii", &globalID, &Slot, &ResRef, &Count, &Type)) {
return AttributeError( GemRB_DragItem__doc );
}
@@ -7190,16 +7648,21 @@ static PyObject* GemRB_DragItem(PyObject * /*self*/, PyObject* args)
}
GET_GAME();
+ Actor* actor;
+ if (globalID > 1000) {
+ actor = game->GetActorByGlobalID( globalID );
+ } else {
+ actor = game->FindPC( globalID );
+ }
- Actor* actor = game->FindPC( PartyID );
//allow -1,-1
- if (!actor && ( PartyID || ResRef[0]) ) {
+ if (!actor && ( globalID || ResRef[0]) ) {
return RuntimeError( "Actor not found!\n" );
}
//dragging a portrait
if (!ResRef[0]) {
- core->SetDraggedPortrait(PartyID, Slot);
+ core->SetDraggedPortrait(globalID, Slot);
Py_INCREF( Py_None );
return Py_None;
}
@@ -7210,14 +7673,19 @@ static PyObject* GemRB_DragItem(PyObject * /*self*/, PyObject* args)
CREItem* si;
if (Type) {
Map *map = actor->GetCurrentArea();
+ if (!map) {
+ return RuntimeError("No current area!");
+ }
Container *cc = map->GetPile(actor->Pos);
if (!cc) {
- return RuntimeError( "No current container" );
+ return RuntimeError( "No current container!" );
}
si = cc->RemoveItem(Slot, Count);
} else {
si = TryToUnequip( actor, core->QuerySlot(Slot), Count );
actor->RefreshEffects(NULL);
+ // make sure the encumbrance labels stay correct
+ actor->CalculateSpeed(false);
actor->ReinitQuickSlots();
core->SetEventFlag(EF_SELECTION);
}
@@ -7265,9 +7733,9 @@ PyDoc_STRVAR( GemRB_DropDraggedItem__doc,
static PyObject* GemRB_DropDraggedItem(PyObject * /*self*/, PyObject* args)
{
ieResRef Sound;
- int PartyID, Slot;
+ int globalID, Slot;
- if (!PyArg_ParseTuple( args, "ii", &PartyID, &Slot)) {
+ if (!PyArg_ParseTuple( args, "ii", &globalID, &Slot)) {
return AttributeError( GemRB_DropDraggedItem__doc );
}
@@ -7278,19 +7746,18 @@ static PyObject* GemRB_DropDraggedItem(PyObject * /*self*/, PyObject* args)
}
GET_GAME();
-
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
int res;
if (Slot==-2) {
Map *map = actor->GetCurrentArea();
+ if (!map) {
+ return RuntimeError("No current area!");
+ }
Container *cc = map->GetPile(actor->Pos);
if (!cc) {
- return RuntimeError( "No current container" );
+ return RuntimeError( "No current container!" );
}
CREItem *si = core->GetDraggedItem();
res = cc->AddItem(si);
@@ -7330,6 +7797,16 @@ static PyObject* GemRB_DropDraggedItem(PyObject * /*self*/, PyObject* args)
Slottype = core->QuerySlotType( Slot );
Effect = core->QuerySlotEffects( Slot );
}
+
+ // too far away?
+ Actor *current = game->FindPC(game->GetSelectedPCSingle());
+ if (current && current != actor &&
+ (actor->GetCurrentArea() != current->GetCurrentArea() ||
+ SquaredPersonalDistance(actor, current) > MAX_DISTANCE * MAX_DISTANCE)) {
+ displaymsg->DisplayConstantString(STR_TOOFARAWAY, DMC_WHITE);
+ return PyInt_FromLong( 0 );
+ }
+
CREItem * slotitem = core->GetDraggedItem();
Item *item = gamedata->GetItem( slotitem->ItemResRef );
if (!item) {
@@ -7339,18 +7816,26 @@ static PyObject* GemRB_DropDraggedItem(PyObject * /*self*/, PyObject* args)
// can't equip item because of similar already equipped
if (Effect) {
if (item->ItemExcl & actor->inventory.GetEquipExclusion(Slot)) {
- displaymsg->DisplayConstantString(STR_ITEMEXCL, 0xf0f0f0);
+ displaymsg->DisplayConstantString(STR_ITEMEXCL, DMC_WHITE);
//freeing the item before returning
gamedata->FreeItem( item, slotitem->ItemResRef, false );
return PyInt_FromLong( 0 );
}
}
+ if ((Slottype!=-1) && (Slottype & SLOT_WEAPON)) {
+ CREItem *item = actor->inventory.GetUsedWeapon(false, Effect); //recycled variable
+ if (item && (item->Flags & IE_INV_ITEM_CURSED)) {
+ displaymsg->DisplayConstantString(STR_CURSED, DMC_WHITE);
+ return PyInt_FromLong( 0 );
+ }
+ }
+
// can't equip item because it is not identified
if ( (Slottype == SLOT_ITEM) && !(slotitem->Flags&IE_INV_ITEM_IDENTIFIED)) {
ITMExtHeader *eh = item->GetExtHeader(0);
if (eh && eh->IDReq) {
- displaymsg->DisplayConstantString(STR_ITEMID, 0xf0f0f0);
+ displaymsg->DisplayConstantString(STR_ITEMID, DMC_WHITE);
gamedata->FreeItem( item, slotitem->ItemResRef, false );
return PyInt_FromLong( 0 );
}
@@ -7382,18 +7867,11 @@ static PyObject* GemRB_DropDraggedItem(PyObject * /*self*/, PyObject* args)
if (res) {
//release it only when fully placed
if (res==ASI_SUCCESS) {
+ // make sure the encumbrance labels stay correct
+ actor->CalculateSpeed(false);
core->ReleaseDraggedItem ();
- } else {
- // res == ASI_PARTIAL
- // swap the items, so the existing one ends up being filled;
- // the items are the same, so we just need to adjust the usage count
- int usages = slotitem->Usages[0];
- CREItem *itm = actor->inventory.GetSlotItem(Slot);
- if (itm) {
- slotitem->Usages[0] = itm->Usages[0];
- itm->Usages[0] = usages;
- }
}
+ // res == ASI_PARTIAL
//EquipItem (in AddSlotItem) already called RefreshEffects
actor->ReinitQuickSlots();
//couldn't place item there, try swapping (only if slot is explicit)
@@ -7401,7 +7879,7 @@ static PyObject* GemRB_DropDraggedItem(PyObject * /*self*/, PyObject* args)
//swapping won't cure this
res = actor->inventory.WhyCantEquip(Slot, slotitem->Flags&IE_INV_ITEM_TWOHANDED);
if (res) {
- displaymsg->DisplayConstantString(res,0xffffff);
+ displaymsg->DisplayConstantString(res, DMC_WHITE);
return PyInt_FromLong( 0 );
}
CREItem *tmp = TryToUnequip(actor, Slot, 0 );
@@ -7415,12 +7893,17 @@ static PyObject* GemRB_DropDraggedItem(PyObject * /*self*/, PyObject* args)
res = ASI_SWAPPED;
//EquipItem (in AddSlotItem) already called RefreshEffects
actor->RefreshEffects(NULL);
+ // make sure the encumbrance labels stay correct
+ actor->CalculateSpeed(false);
actor->ReinitQuickSlots();
core->SetEventFlag(EF_SELECTION);
} else {
res = ASI_FAILED;
}
+ } else {
+ displaymsg->DisplayConstantString(STR_INVFULL, DMC_WHITE);
}
+
if (Sound[0]) {
core->GetAudioDrv()->Play(Sound);
}
@@ -7466,20 +7949,16 @@ PyDoc_STRVAR( GemRB_CreateItem__doc,
static PyObject* GemRB_CreateItem(PyObject * /*self*/, PyObject* args)
{
- int PartyID;
+ int globalID;
int SlotID=-1;
int Charge0=1,Charge1=0,Charge2=0;
const char *ItemResRef;
- if (!PyArg_ParseTuple( args, "is|iiii", &PartyID, &ItemResRef, &SlotID, &Charge0, &Charge1, &Charge2)) {
+ if (!PyArg_ParseTuple( args, "is|iiii", &globalID, &ItemResRef, &SlotID, &Charge0, &Charge1, &Charge2)) {
return AttributeError( GemRB_CreateItem__doc );
}
GET_GAME();
-
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
if (SlotID==-1) {
//This is already a slot ID we need later
@@ -7510,6 +7989,26 @@ static PyObject* GemRB_CreateItem(PyObject * /*self*/, PyObject* args)
return Py_None;
}
+PyDoc_STRVAR( GemRB_GetAvatarsValue__doc,
+"GetAvatarsValue(globalID, column)\n\n"
+"Returns an entry from the avatars.2da table, accounting for animation ID ranges.");
+// NOTE: currently it can only lookup the animation prefixes!
+static PyObject* GemRB_GetAvatarsValue(PyObject * /*self*/, PyObject* args)
+{
+ int globalID, col;
+
+ if (!PyArg_ParseTuple(args, "ii", &globalID, &col)) {
+ return AttributeError( GemRB_GetAvatarsValue__doc );
+ }
+ GET_GAME();
+ GET_ACTOR_GLOBAL();
+
+ ieResRef prefix;
+ strnuprcpy(prefix, actor->GetAnims()->GetArmourLevel(col), sizeof(ieResRef)-1);
+
+ return PyString_FromResRef(prefix);
+}
+
PyDoc_STRVAR( GemRB_SetMapAnimation__doc,
"SetMapAnimation(X, Y, BAMresref[, flags, cycle, height])\n\n"
"Creates an area animation.");
@@ -7527,7 +8026,7 @@ static PyObject* GemRB_SetMapAnimation(PyObject * /*self*/, PyObject* args)
memset(&anim,0,sizeof(anim));
if (!PyArg_ParseTuple( args, "iis|iii", &x, &y, &ResRef, &Flags, &Cycle, &Height)) {
- return AttributeError( GemRB_CreateItem__doc );
+ return AttributeError( GemRB_SetMapAnimation__doc );
}
GET_GAME();
@@ -7600,7 +8099,7 @@ static PyObject* GemRB_SetMapDoor(PyObject * /*self*/, PyObject* args)
GET_GAME();
GET_MAP();
-
+
Door *door = map->TMap->GetDoor(DoorName);
if (!door) {
return RuntimeError( "No such door!" );
@@ -7667,7 +8166,6 @@ static PyObject* GemRB_SetMapRegion(PyObject * /*self*/, PyObject* args)
}
GET_GAME();
-
GET_MAP();
InfoPoint *ip = map->TMap->GetInfoPoint(Name);
@@ -7692,25 +8190,21 @@ PyDoc_STRVAR( GemRB_CreateCreature__doc,
static PyObject* GemRB_CreateCreature(PyObject * /*self*/, PyObject* args)
{
- int PartyID;
+ int globalID;
const char *CreResRef;
int PosX = -1, PosY = -1;
- if (!PyArg_ParseTuple( args, "is|ii", &PartyID, &CreResRef, &PosX, &PosY)) {
+ if (!PyArg_ParseTuple( args, "is|ii", &globalID, &CreResRef, &PosX, &PosY)) {
return AttributeError( GemRB_CreateCreature__doc );
}
GET_GAME();
-
GET_MAP();
if (PosX!=-1 && PosY!=-1) {
map->SpawnCreature(Point(PosX, PosY), CreResRef, 0);
} else {
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
map->SpawnCreature(actor->Pos, CreResRef, 10);
}
Py_INCREF( Py_None );
@@ -7785,40 +8279,39 @@ static PyObject* GemRB_GetRumour(PyObject * /*self*/, PyObject* args)
}
PyDoc_STRVAR( GemRB_GamePause__doc,
-"GamePause(Pause, Quiet)\n\n"
-"Pause or unpause the game or just toggle the pause.");
+"GamePause(Pause, Quiet)==> pause state\n\n"
+"Pause or unpause the game or just toggle the pause state.");
static PyObject* GemRB_GamePause(PyObject * /*self*/, PyObject* args)
{
int pause, quiet;
+ int ret;
if (!PyArg_ParseTuple( args, "ii", &pause, &quiet)) {
return AttributeError( GemRB_GamePause__doc );
}
- GameControl *gc = core->GetGameControl();
- if (gc) {
- //this will trigger when pause is not 0 or 1
- if ((unsigned int) pause > 1) {
- pause = ~gc->GetDialogueFlags()&DF_FREEZE_SCRIPTS;
- }
+ GET_GAMECONTROL();
- if (pause) {
- gc->SetDialogueFlags(DF_FREEZE_SCRIPTS, BM_OR);
- } else {
- gc->SetDialogueFlags(DF_FREEZE_SCRIPTS, BM_NAND);
- }
- if (!quiet) {
- if (gc->GetDialogueFlags()&DF_FREEZE_SCRIPTS) {
- displaymsg->DisplayConstantString(STR_PAUSED,0xff0000);
- } else {
- displaymsg->DisplayConstantString(STR_UNPAUSED,0xff0000);
- }
- }
+ //this will trigger when pause is not 0 or 1
+ switch(pause)
+ {
+ case 2:
+ ret = core->TogglePause();
+ break;
+ case 0:
+ case 1:
+ core->SetPause((PauseSetting)pause, quiet);
+ default:
+ ret = gc->GetDialogueFlags()&DF_FREEZE_SCRIPTS;
+ }
+ if (ret) {
+ Py_INCREF( Py_True );
+ return Py_True;
+ } else {
+ Py_INCREF( Py_False );
+ return Py_False;
}
-
- Py_INCREF( Py_None );
- return Py_None;
}
PyDoc_STRVAR( GemRB_CheckFeatCondition__doc,
@@ -7892,7 +8385,7 @@ static PyObject* GemRB_CheckFeatCondition(PyObject * /*self*/, PyObject* args)
PyTuple_SetItem( param, i-2, PyInt_FromLong( v[i] ) );
}
- PyObject *pValue = gs->CallbackFunction(fname, param);
+ PyObject *pValue = gs->RunFunction(NULL, fname, param);
/* we created this parameter, now we don't need it*/
Py_DECREF( param );
@@ -7905,21 +8398,25 @@ static PyObject* GemRB_CheckFeatCondition(PyObject * /*self*/, PyObject* args)
bool ret = true;
- if (v[1] || v[2])
+ if (v[1] || v[2]) {
ret = CheckStat(actor, v[1], v[2], v[9]);
+ }
- if (v[3] || v[4])
+ if (v[3] || v[4]) {
ret |= CheckStat(actor, v[3], v[4], v[10]);
+ }
if (!ret)
goto endofquest;
- if (v[5] || v[6])
+ if (v[5] || v[6]) {
// no | because the formula is (a|b) & (c|d)
ret = CheckStat(actor, v[5], v[6], v[11]);
+ }
- if (v[7] || v[8])
+ if (v[7] || v[8]) {
ret |= CheckStat(actor, v[7], v[8], v[12]);
+ }
endofquest:
if (ret) {
@@ -7931,6 +8428,58 @@ endofquest:
}
}
+PyDoc_STRVAR( GemRB_HasFeat__doc,
+"HasFeat(Slot, feat)\n\n"
+"Returns the number of times this feat was taken if the player in Slot has the passed feat id (from ie_feats.py)." );
+
+static PyObject* GemRB_HasFeat(PyObject * /*self*/, PyObject* args)
+{
+ int globalID, featindex;
+
+ if (!PyArg_ParseTuple( args, "ii", &globalID, &featindex )) {
+ return AttributeError( GemRB_HasFeat__doc );
+ }
+ GET_GAME();
+ GET_ACTOR_GLOBAL();
+ return PyInt_FromLong(actor->GetFeat(featindex));
+}
+
+PyDoc_STRVAR( GemRB_SetFeat__doc,
+"SetFeat(Slot, feat)\n\n"
+"Sets a feat value, handles both the boolean and the numeric fields." );
+
+static PyObject* GemRB_SetFeat(PyObject * /*self*/, PyObject* args)
+{
+ int globalID, featindex, value;
+
+ if (!PyArg_ParseTuple( args, "iii", &globalID, &featindex, &value )) {
+ return AttributeError( GemRB_SetFeat__doc );
+ }
+ GET_GAME();
+ GET_ACTOR_GLOBAL();
+ actor->SetFeatValue(featindex, value);
+ Py_INCREF( Py_None );
+ return Py_None;
+}
+
+PyDoc_STRVAR( GemRB_GetMaxEncumbrance__doc,
+"GetMaxEncumbrance(pc) => int\n\n"
+"Returns the maximum weight the PC may carry before becoming encumbered.");
+
+static PyObject* GemRB_GetMaxEncumbrance(PyObject * /*self*/, PyObject* args)
+{
+ int globalID;
+
+ if (!PyArg_ParseTuple( args, "i", &globalID )) {
+ return AttributeError( GemRB_GetMaxEncumbrance__doc );
+ }
+
+ GET_GAME();
+ GET_ACTOR_GLOBAL();
+
+ return PyInt_FromLong( actor->GetMaxEncumbrance() );
+}
+
PyDoc_STRVAR( GemRB_GetAbilityBonus__doc,
"GetAbilityBonus(stat, column, value[, ex])\n\n"
"Returns an ability bonus value based on various .2da files.");
@@ -7988,17 +8537,13 @@ PyDoc_STRVAR( GemRB_LeaveParty__doc,
static PyObject* GemRB_LeaveParty(PyObject * /*self*/, PyObject* args)
{
- int PlayerSlot, initDialog = 0;
+ int globalID, initDialog = 0;
- if (!PyArg_ParseTuple( args, "i|i", &PlayerSlot, &initDialog )) {
+ if (!PyArg_ParseTuple( args, "i|i", &globalID, &initDialog )) {
return AttributeError( GemRB_LeaveParty__doc );
}
GET_GAME();
-
- Actor *actor = game->FindPC(PlayerSlot);
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
if (initDialog) {
if (initDialog == 2)
@@ -8080,6 +8625,7 @@ static PyObject* SetActionIcon(int WindowIndex, int ControlIndex, PyObject *dict
btn->SetImage( IE_GUI_BUTTON_DISABLED, 0 );
btn->SetFlags( IE_GUI_BUTTON_NO_IMAGE, BM_SET );
btn->SetEvent( IE_GUI_BUTTON_ON_PRESS, NULL );
+ btn->SetEvent( IE_GUI_BUTTON_ON_RIGHT_PRESS, NULL );
core->SetTooltip( (ieWord) WindowIndex, (ieWord) ControlIndex, "" );
//no incref
return Py_None;
@@ -8089,7 +8635,6 @@ static PyObject* SetActionIcon(int WindowIndex, int ControlIndex, PyObject *dict
ReadActionButtons();
}
-
//FIXME: this is a hardcoded resource (pst has no such one)
AnimationFactory* bam = ( AnimationFactory* )
gamedata->GetFactoryResource( GUIResRef[Index],
@@ -8117,9 +8662,13 @@ static PyObject* SetActionIcon(int WindowIndex, int ControlIndex, PyObject *dict
btn->SetEvent( IE_GUI_BUTTON_ON_RIGHT_PRESS, new PythonCallback(func2) );
//cannot make this const, because it will be freed
- char *txt = core->GetString( GUITooltip[Index] );
+ char *txt = NULL;
+ if (GUITooltip[Index] != (ieDword) -1) {
+ txt = core->GetString( GUITooltip[Index] );
+ }
//will free txt
SetFunctionTooltip(WindowIndex, ControlIndex, txt, Function);
+
//no incref
return Py_None;
}
@@ -8164,35 +8713,24 @@ static PyObject* GemRB_HasResource(PyObject * /*self*/, PyObject* args)
}
PyDoc_STRVAR( GemRB_Window_SetupEquipmentIcons__doc,
-"SetupEquipmentIcons(WindowIndex, dict, slot[, Start, Offset, global])\n\n"
+"SetupEquipmentIcons(WindowIndex, dict, slot[, Start, Offset])\n\n"
"Automagically sets up the controls of the equipment list window for a PC indexed by globalID.\n"
"Start is the beginning of the visible part of the item list.\n"
-"Offset is the ID of the first usable button.\n"
-"If global is set, the actor will be looked up by its global ID instead of party slot.");
+"Offset is the ID of the first usable button.\n");
static PyObject* GemRB_Window_SetupEquipmentIcons(PyObject * /*self*/, PyObject* args)
{
- int wi, slot;
+ int wi, globalID;
int Start = 0;
int Offset = 0; //control offset (iwd2 has the action buttons starting at 6)
- int global = 0;
PyObject *dict;
- if (!PyArg_ParseTuple( args, "iOi|iii", &wi, &dict, &slot, &Start, &Offset, &global )) {
+ if (!PyArg_ParseTuple( args, "iOi|ii", &wi, &dict, &globalID, &Start, &Offset)) {
return AttributeError( GemRB_Window_SetupEquipmentIcons__doc );
}
GET_GAME();
-
- Actor* actor;
- if (global) {
- actor = game->GetActorByGlobalID( slot );
- } else {
- actor = game->FindPC( slot );
- }
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
//-2 because of the left/right scroll icons
if (!ItemArray) {
@@ -8200,7 +8738,7 @@ static PyObject* GemRB_Window_SetupEquipmentIcons(PyObject * /*self*/, PyObject*
}
bool more = actor->inventory.GetEquipmentInfo(ItemArray, Start, GUIBT_COUNT-(Start?1:0));
int i;
- if (Start) {
+ if (Start||more) {
PyObject *ret = SetActionIcon(wi,core->GetControl(wi, Offset),dict, ACT_LEFT,0);
if (!ret) {
return RuntimeError("Cannot set action button!\n");
@@ -8226,7 +8764,11 @@ static PyObject* GemRB_Window_SetupEquipmentIcons(PyObject * /*self*/, PyObject*
Sprite2D *Picture = NULL;
if (item->UseIcon[0]) {
- Picture = gamedata->GetBAMSprite(item->UseIcon, 1, 0);
+ Picture = gamedata->GetBAMSprite(item->UseIcon, 1, 0, true);
+ // try cycle 0 if cycle 1 doesn't exist
+ // (needed for e.g. sppr707b which is used by Daystar's Sunray)
+ if (!Picture)
+ Picture = gamedata->GetBAMSprite(item->UseIcon, 0, 0, true);
}
if (!Picture) {
@@ -8275,160 +8817,18 @@ static PyObject* GemRB_Window_SetupEquipmentIcons(PyObject * /*self*/, PyObject*
return Py_None;
}
-PyDoc_STRVAR( GemRB_Window_SetupSpellIcons__doc,
-"SetupSpellIcons(WindowIndex, dict, slot, type[, Start, Offset, global])\n\n"
-"Automagically sets up the controls of the spell or innate list window for a PC indexed by slot.\n"
-"Start is the beginning of the visible part of the spell list.\n"
-"Offset is the ID of the first usable button.\n"
-"If global is set, the actor will be looked up by its global ID instead of party slot.");
-
-static PyObject* GemRB_Window_SetupSpellIcons(PyObject * /*self*/, PyObject* args)
-{
- int wi, slot, Type;
- int Start = 0;
- int Offset = 0;
- int global = 0;
- PyObject *dict;
-
- if (!PyArg_ParseTuple( args, "iOii|iii", &wi, &dict, &slot, &Type, &Start, &Offset, &global )) {
- return AttributeError( GemRB_Window_SetupSpellIcons__doc );
- }
-
- GET_GAME();
-
- Actor* actor;
- if (global) {
- actor = game->GetActorByGlobalID( slot );
- } else {
- actor = game->FindPC( slot );
- }
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
-
- //-2 because of the left/right scroll icons
- if (!SpellArray) {
- SpellArray = (SpellExtHeader *) malloc((GUIBT_COUNT) * sizeof (SpellExtHeader) );
- }
- int more = actor->spellbook.GetSpellInfo(SpellArray, Type, Start, GUIBT_COUNT-(Start?1:0));
- int i;
- if (Start) {
- more |= 2;
- }
- if (more) {
- int ci = core->GetControl(wi, Offset);
- PyObject *ret = SetActionIcon(wi, ci, dict, ACT_LEFT, 0);
- if (!ret) {
- return RuntimeError("Cannot set action button!\n");
- }
- Button * btn = (Button *) GetControl(wi, ci, IE_GUI_BUTTON);
- if (Start) {
- btn->SetState(IE_GUI_BUTTON_UNPRESSED);
- } else {
- btn->SetState(IE_GUI_BUTTON_DISABLED);
- }
- }
-
- //FIXME: this is a hardcoded resource (pst has no such one)
- AnimationFactory* bam = ( AnimationFactory* )
- gamedata->GetFactoryResource( "guibtbut",
- IE_BAM_CLASS_ID, IE_NORMAL );
- if (!bam) {
- return RuntimeError("guibtbut BAM not found");
- }
-
- // disable all spells if fx_disable_spellcasting was run with the same type
- // but only if there are any spells of that type to disable
- int disabled_spellcasting = actor->GetStat(IE_CASTING);
-
- for (i=0;i<GUIBT_COUNT-(more?2:0);i++) {
- SpellExtHeader *spell = SpellArray+i;
-
- int ci = core->GetControl(wi, i+Offset+(more?1:0) );
- Button* btn = (Button *) GetControl( wi, ci, IE_GUI_BUTTON );
- strcpy(btn->VarName,"Spell");
- btn->Value = i+Start;
-
- // disable spells that should be cast from the inventory
- // Identify is misclassified and has Target 3 (Dead char)
-
- ieDword spelltype = ResolveSpellNumber(spell->spellname)/1000;
- if (core->CheckSpecialSpell(spell->spellname, actor) || (disabled_spellcasting&(1<<spelltype)) ) {
- btn->SetState(IE_GUI_BUTTON_DISABLED);
- btn->EnableBorder(1, IE_GUI_BUTTON_DISABLED);
- PyObject *Function = PyDict_GetItemString(dict, "UpdateActionsWindow");
- btn->SetEvent(IE_GUI_BUTTON_ON_PRESS, new PythonCallback(Function)); //noop
- } else {
- btn->SetState(IE_GUI_BUTTON_UNPRESSED);
- PyObject *Function = PyDict_GetItemString(dict, "SpellPressed");
- btn->SetEvent(IE_GUI_BUTTON_ON_PRESS, new PythonCallback(Function));
- }
- Sprite2D *Picture = NULL;
-
- if (spell->MemorisedIcon[0]) {
- Picture = gamedata->GetBAMSprite(spell->MemorisedIcon, 0, 0);
- }
-
- if (!Picture) {
- btn->SetState(IE_GUI_BUTTON_DISABLED);
- btn->SetFlags(IE_GUI_BUTTON_NO_IMAGE, BM_SET);
- btn->SetTooltip(NULL);
- } else {
- SetButtonCycle(bam, btn, 0, IE_GUI_BUTTON_UNPRESSED);
- SetButtonCycle(bam, btn, 1, IE_GUI_BUTTON_PRESSED);
- SetButtonCycle(bam, btn, 2, IE_GUI_BUTTON_SELECTED);
- SetButtonCycle(bam, btn, 3, IE_GUI_BUTTON_DISABLED);
- btn->SetPicture( Picture );
- btn->SetFlags(IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_ALIGN_BOTTOM|IE_GUI_BUTTON_ALIGN_RIGHT, BM_SET);
- //cannot make this const, because it will be freed
- char *tmp = core->GetString(spell->strref,0);
- btn->SetTooltip(tmp);
- core->FreeString(tmp);
- char usagestr[10];
-
- if (spell->count>0) {
- sprintf(usagestr,"%d", spell->count);
- btn->SetText( usagestr );
- btn->SetState(IE_GUI_BUTTON_UNPRESSED);
- } else {
- btn->SetState(IE_GUI_BUTTON_DISABLED);
- }
- }
- }
-
- if (more) {
- int ci = core->GetControl(wi, i+Offset+1);
- PyObject *ret = SetActionIcon(wi, ci, dict, ACT_RIGHT, i+1);
- if (!ret) {
- return RuntimeError("Cannot set action button!\n");
- }
- Button* btn = (Button *) GetControl( wi, ci, IE_GUI_BUTTON );
- if (more&1) {
- btn->SetState(IE_GUI_BUTTON_UNPRESSED);
- } else {
- btn->SetState(IE_GUI_BUTTON_DISABLED);
- btn->SetFlags(IE_GUI_BUTTON_NO_IMAGE, BM_SET);
- btn->SetTooltip(NULL);
- }
- }
-
- Py_INCREF( Py_None );
- return Py_None;
-}
-
PyDoc_STRVAR( GemRB_Window_SetupControls__doc,
-"SetupControls(WindowIndex, dict, slot[, Start, global])\n\n"
-"Automagically sets up the controls of the action window for a PC indexed by slot.\n"
-"If global is set, the actor will be looked up by its global ID instead of party slot.");
+"SetupControls(WindowIndex, dict, slot[, Startl])\n\n"
+"Automagically sets up the controls of the action window for a PC indexed by slot.\n");
static PyObject* GemRB_Window_SetupControls(PyObject * /*self*/, PyObject* args)
{
- int wi, slot;
+ int wi, globalID;
int Start = 0;
- int global = 0;
PyObject *dict;
+ PyObject *Tuple = NULL;
- if (!PyArg_ParseTuple( args, "iOi|ii", &wi, &dict, &slot, &Start, &global )) {
+ if (!PyArg_ParseTuple( args, "iOi|iO", &wi, &dict, &globalID, &Start, &Tuple)) {
return AttributeError( GemRB_Window_SetupControls__doc );
}
@@ -8438,11 +8838,11 @@ static PyObject* GemRB_Window_SetupControls(PyObject * /*self*/, PyObject* args)
Actor* actor = NULL;
- if (slot) {
- if (global) {
- actor = game->GetActorByGlobalID( slot );
+ if (globalID) {
+ if (globalID > 1000) {
+ actor = game->GetActorByGlobalID( globalID );
} else {
- actor = game->FindPC( slot );
+ actor = game->FindPC( globalID );
}
} else {
if (game->selected.size()==1) {
@@ -8455,7 +8855,23 @@ static PyObject* GemRB_Window_SetupControls(PyObject * /*self*/, PyObject* args)
}
ActionButtonRow myrow;
- actor->GetActionButtonRow(myrow);
+ if (Tuple) {
+ if (!PyObject_TypeCheck( Tuple, &PyTuple_Type )) {
+ return AttributeError( GemRB_Window_SetupControls__doc );
+ }
+ if (PyTuple_Size(Tuple)!=GUIBT_COUNT) {
+ return AttributeError( GemRB_Window_SetupControls__doc );
+ }
+ for(int i=0;i<GUIBT_COUNT;i++) {
+ PyObject *x = PyTuple_GetItem(Tuple, i);
+ if (!PyObject_TypeCheck( x, &PyInt_Type )) {
+ return AttributeError( GemRB_Window_SetupControls__doc );
+ }
+ myrow[i] = PyInt_AsLong(x);
+ }
+ } else {
+ actor->GetActionButtonRow(myrow);
+ }
bool fistdrawn = true;
ieDword magicweapon = actor->inventory.GetMagicSlot();
if (!actor->inventory.HasItemInSlot("",magicweapon) ) {
@@ -8468,14 +8884,16 @@ static PyObject* GemRB_Window_SetupControls(PyObject * /*self*/, PyObject* args)
for (int i=0;i<GUIBT_COUNT;i++) {
int ci = core->GetControl(wi, i+Start);
if (ci<0) {
- printf("Couldn't find button #%d on Window #%d\n", i+Start, wi);
+ print("Couldn't find button #%d on Window #%d", i+Start, wi);
return RuntimeError ("No such control!\n");
}
int action = myrow[i];
if (action==100) {
action = -1;
} else {
- action&=31;
+ if (action < ACT_IWDQSPELL) {
+ action %= 100;
+ }
}
Button * btn = (Button *) GetControl(wi,ci,IE_GUI_BUTTON);
if (!btn) {
@@ -8485,17 +8903,25 @@ static PyObject* GemRB_Window_SetupControls(PyObject * /*self*/, PyObject* args)
SetItemText(wi, ci, 0, false);
PyObject *ret = SetActionIcon(wi,ci,dict, action,i+1);
+ if (action!=-1) {
+ // reset it to the first one, so we can handle them more easily below
+ if ( (action>=ACT_IWDQSPELL) && (action<=ACT_IWDQSPELL+9) ) action = ACT_IWDQSPELL;
+ else if ( (action>=ACT_IWDQITEM) && (action<=ACT_IWDQITEM+9) ) action = ACT_IWDQITEM;
+ else if ( (action>=ACT_IWDQSPEC) && (action<=ACT_IWDQSPEC+9) ) action = ACT_IWDQSPEC;
+ else if ( (action>=ACT_IWDQSONG) && (action<=ACT_IWDQSONG+9) ) action = ACT_IWDQSONG;
+ }
+
int state = IE_GUI_BUTTON_UNPRESSED;
ieDword modalstate = actor->ModalState;
int type;
switch (action) {
case ACT_INNATE:
if (actor->spellbook.IsIWDSpellBook()) {
- type = IE_IWD2_SPELL_INNATE;
+ type = (1<<IE_IWD2_SPELL_INNATE) | (1<<IE_IWD2_SPELL_SHAPE);
} else {
- type = IE_SPELL_TYPE_INNATE;
+ type = 1<<IE_SPELL_TYPE_INNATE;
}
- if (!actor->spellbook.GetMemorizedSpellsCount(type)) {
+ if (!actor->spellbook.GetSpellInfoSize(type)) {
state = IE_GUI_BUTTON_DISABLED;
}
break;
@@ -8507,10 +8933,31 @@ static PyObject* GemRB_Window_SetupControls(PyObject * /*self*/, PyObject* args)
type = (1<<IE_SPELL_TYPE_INNATE)-1;
}
//returns true if there are ANY spells to cast
+ if (!actor->spellbook.GetSpellInfoSize(type) || !actor->GetAnyActiveCasterLevel()) {
+ state = IE_GUI_BUTTON_DISABLED;
+ }
+ break;
+ case ACT_BARD:
+ case ACT_CLERIC:
+ case ACT_DRUID:
+ case ACT_PALADIN:
+ case ACT_RANGER:
+ case ACT_SORCERER:
+ case ACT_WIZARD:
+ case ACT_DOMAIN:
+ if (actor->spellbook.IsIWDSpellBook()) {
+ type = 1<<(action-ACT_BARD);
+ } else {
+ //only cleric or wizard switch exists in the bg engine
+ if (action==ACT_WIZARD) type = 1<<IE_SPELL_TYPE_WIZARD;
+ else type = 1<<IE_SPELL_TYPE_PRIEST;
+ }
+ //returns true if there is ANY shape
if (!actor->spellbook.GetSpellInfoSize(type)) {
state = IE_GUI_BUTTON_DISABLED;
}
break;
+ case ACT_WILDSHAPE:
case ACT_SHAPE:
if (actor->spellbook.IsIWDSpellBook()) {
type = 1<<IE_IWD2_SPELL_SHAPE;
@@ -8550,15 +8997,33 @@ static PyObject* GemRB_Window_SetupControls(PyObject * /*self*/, PyObject* args)
}
break;
case ACT_STEALTH:
- if (modalstate==MS_STEALTH) {
- state = IE_GUI_BUTTON_SELECTED;
+ //don't use level control for this, iwd2 allows everyone to sneak
+ if ((actor->GetStat(IE_STEALTH)+actor->GetStat(IE_HIDEINSHADOWS) )<=0 ) {
+ state = IE_GUI_BUTTON_DISABLED;
+ } else {
+ if (modalstate==MS_STEALTH) {
+ state = IE_GUI_BUTTON_SELECTED;
+ }
}
break;
case ACT_SEARCH:
+ //in IWD2 everyone can try to search, in bg2 only thieves get the icon
+ //so there is no problem, if you absolutely want to disable this button
+ //check the search skill
if (modalstate==MS_DETECTTRAPS) {
state = IE_GUI_BUTTON_SELECTED;
}
break;
+ case ACT_THIEVING:
+ if ((actor->GetStat(IE_LOCKPICKING)+actor->GetStat(IE_PICKPOCKET) )<=0 ) {
+ state = IE_GUI_BUTTON_DISABLED;
+ }
+ break;
+ case ACT_TAMING:
+ if (actor->GetStat(IE_ANIMALS)<=0 ) {
+ state = IE_GUI_BUTTON_DISABLED;
+ }
+ break;
case ACT_WEAPON1:
case ACT_WEAPON2:
case ACT_WEAPON3:
@@ -8600,7 +9065,7 @@ static PyObject* GemRB_Window_SetupControls(PyObject * /*self*/, PyObject* args)
if (gc->GetTargetMode() == TARGET_MODE_ATTACK) {
state = IE_GUI_BUTTON_SELECTED;
} else {
- state = IE_GUI_BUTTON_THIRD;
+ state = IE_GUI_BUTTON_FAKEDISABLED;
}
} else {
btn->EnableBorder(0, false);
@@ -8608,19 +9073,54 @@ static PyObject* GemRB_Window_SetupControls(PyObject * /*self*/, PyObject* args)
}
}
}
- break;
+ break;
+ case ACT_IWDQSPELL:
+ SetButtonBAM(wi, ci, "stonspel",0,0,-1);
+ if (actor->version==22 && i>3) {
+ tmp = i-3;
+ } else {
+ tmp = 0;
+ }
+ goto jump_label2;
+ case ACT_IWDQSONG:
+ SetButtonBAM(wi, ci, "stonsong",0,0,-1);
+ if (actor->version==22 && i>3) {
+ tmp = i-3;
+ } else {
+ tmp = 0;
+ }
+ goto jump_label2;
+ case ACT_IWDQSPEC:
+ SetButtonBAM(wi, ci, "stonspec",0,0,-1);
+ if (actor->version==22 && i>3) {
+ tmp = i-3;
+ } else {
+ tmp = 0;
+ }
+ goto jump_label2;
case ACT_QSPELL1:
case ACT_QSPELL2:
case ACT_QSPELL3:
- //fixme iwd2 has 9
- {
SetButtonBAM(wi, ci, "stonspel",0,0,-1);
- ieResRef *poi = &actor->PCStats->QuickSpells[action-ACT_QSPELL1];
+ tmp = action-ACT_QSPELL1;
+jump_label2:
+ {
+ ieResRef *poi = &actor->PCStats->QuickSpells[tmp];
if ((*poi)[0]) {
SetSpellIcon(wi, ci, *poi, 1, 1, i+1);
+ int mem = actor->spellbook.GetMemorizedSpellsCount(*poi, -1, true);
+ if (!mem) {
+ state = IE_GUI_BUTTON_DISABLED;
+ }
+ SetItemText(wi, ci, mem, true);
}
}
- break;
+ break;
+ case ACT_IWDQITEM:
+ if (i>3) {
+ tmp = (i+1)%3;
+ goto jump_label;
+ }
case ACT_QSLOT1:
tmp=0;
goto jump_label;
@@ -8654,6 +9154,14 @@ jump_label:
SetItemIcon(wi, ci, item->ItemResRef,header+6,(item->Flags&IE_INV_ITEM_IDENTIFIED)?2:1, i+1, NULL);
SetItemText(wi, ci, usages, false);
}
+ } else {
+ if (action == ACT_IWDQITEM) {
+ action = -1; // so it gets marked as disabled below
+ }
+ }
+ } else {
+ if (action == ACT_IWDQITEM) {
+ action = -1; // so it gets marked as disabled below
}
}
}
@@ -8669,6 +9177,7 @@ jump_label:
}
btn->SetState(state);
//you have to set this overlay up
+ //FIXME: is this really state==IE_GUI_BUTTON_DISABLED ??? That means active border for a disabled button
btn->EnableBorder(1, state==IE_GUI_BUTTON_DISABLED);
}
Py_INCREF( Py_None );
@@ -8676,39 +9185,29 @@ jump_label:
}
PyDoc_STRVAR( GemRB_ClearActions__doc,
-"ClearActions(slot[, global])\n\n"
-"Stops an action for a PC indexed by slot or if global is set, by global ID." );
+"ClearActions(slot)\n\n"
+"Stops an action for a PC indexed by slot or by global ID." );
static PyObject* GemRB_ClearActions(PyObject * /*self*/, PyObject* args)
{
- int slot;
- int global = 0;
+ int globalID;
- if (!PyArg_ParseTuple( args, "i|i", &slot, &global )) {
+ if (!PyArg_ParseTuple( args, "i", &globalID)) {
return AttributeError( GemRB_ClearActions__doc );
}
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor* actor;
- if (global) {
- actor = game->GetActorByGlobalID( slot );
- } else {
- actor = game->FindPC( slot );
- }
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
if (actor->GetInternalFlag()&IF_NOINT) {
- printMessage( "GuiScript","Cannot break action!\n", GREEN);
+ Log(MESSAGE, "GuiScript","Cannot break action!");
Py_INCREF( Py_None );
return Py_None;
}
if (!(actor->GetNextStep()) && !actor->ModalState && !actor->LastTarget) {
- printMessage( "GuiScript","No breakable action!\n", GREEN);
+ Log(MESSAGE, "GuiScript","No breakable action!");
Py_INCREF( Py_None );
return Py_None;
}
- game->OutAttack(actor->GetGlobalID()); //stop attacking
actor->ClearPath(); //stop walking
actor->ClearActions(); //stop pending action involved walking
actor->SetModal(MS_NONE);//stop modal actions
@@ -8735,34 +9234,59 @@ static PyObject* GemRB_SetDefaultActions(PyObject * /*self*/, PyObject* args)
return Py_None;
}
+
+PyDoc_STRVAR( GemRB_SetupQuickSpell__doc,
+"SetupQuickSpell(PartyID, spellslot, spellindex, type)=>int\n\n"
+"Set up a quick spell slot of a PC.\n\n"
+"It also returns the target type of the selected spell.");
+
+static PyObject* GemRB_SetupQuickSpell(PyObject * /*self*/, PyObject* args)
+{
+ SpellExtHeader spelldata;
+ int globalID, which, slot, type;
+
+ if (!PyArg_ParseTuple( args, "iiii", &globalID, &slot, &which, &type)) {
+ return AttributeError( GemRB_SetupQuickSpell__doc );
+ }
+
+ GET_GAME();
+ GET_ACTOR_GLOBAL();
+
+ if (!actor->PCStats) {
+ //no quick slots for this actor, is this an error?
+ //return RuntimeError( "Actor has no quickslots!\n" );
+ Py_INCREF( Py_None );
+ return Py_None;
+ }
+
+ actor->spellbook.GetSpellInfo(&spelldata, type, which, 1);
+ if (!spelldata.spellname[0]) {
+ return RuntimeError( "Invalid parameter! Spell not found!\n" );
+ }
+
+ memcpy(actor->PCStats->QuickSpells[slot], spelldata.spellname, sizeof(ieResRef) );
+ actor->PCStats->QuickSpellClass[slot] = type;
+
+ return PyInt_FromLong( spelldata.Target );
+}
+
PyDoc_STRVAR( GemRB_SetupQuickSlot__doc,
-"SetupQuickSlot(PartyID, quickslot, inventoryslot[, headerindex, global])\n\n"
+"SetupQuickSlot(PartyID, quickslot, inventoryslot[, headerindex])\n\n"
"Set up a quick slot or weapon slot of a PC to use a weapon ability.\n\n"
"If the inventoryslot number is -1, only the header index will be changed. "
"If the quick slot is 0, then the inventory slot will be used to find which "
-"headerindex should be set. The default value for headerindex is 0.\n"
-"If global is set, the actor will be looked up by its global ID instead of party slot.");
+"headerindex should be set. The default value for headerindex is 0.\n");
static PyObject* GemRB_SetupQuickSlot(PyObject * /*self*/, PyObject* args)
{
- int PartyID, which, slot, headerindex = 0;
- int global = 0;
+ int globalID, which, slot, headerindex = 0;
- if (!PyArg_ParseTuple( args, "iii|ii", &PartyID, &which, &slot, &headerindex, &global )) {
+ if (!PyArg_ParseTuple( args, "iii|i", &globalID, &which, &slot, &headerindex)) {
return AttributeError( GemRB_SetupQuickSlot__doc );
}
GET_GAME();
-
- Actor* actor;
- if (global) {
- actor = game->GetActorByGlobalID( PartyID );
- } else {
- actor = game->FindPC( PartyID );
- }
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
slot = core->QuerySlot(slot);
actor->SetupQuickSlot(which, slot, headerindex);
@@ -8771,70 +9295,54 @@ static PyObject* GemRB_SetupQuickSlot(PyObject * /*self*/, PyObject* args)
}
PyDoc_STRVAR( GemRB_SetEquippedQuickSlot__doc,
-"SetEquippedQuickSlot(PartyID, QWeaponSlot[, ability, global])->int\n\n"
-"Sets the named weapon/item slot as equipped weapon slot, optionally sets the used ability."
-"Returns strref number of failure (0 success, -1 silent failure).\n"
-"If global is set, the actor will be looked up by its global ID instead of party slot.");
+"SetEquippedQuickSlot(PartyID, QWeaponSlot[, ability])\n\n"
+"Sets the named weapon/item slot as equipped weapon slot, optionally sets the used ability.\n");
static PyObject* GemRB_SetEquippedQuickSlot(PyObject * /*self*/, PyObject* args)
{
+ int ret;
int slot;
- int PartyID;
+ int dummy;
+ int globalID;
int ability = -1;
- int global = 0;
- if (!PyArg_ParseTuple( args, "ii|ii", &PartyID, &slot, &ability, &global)) {
+ if (!PyArg_ParseTuple( args, "ii|i", &globalID, &slot, &ability)) {
return AttributeError( GemRB_SetEquippedQuickSlot__doc );
}
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor* actor;
- if (global) {
- actor = game->GetActorByGlobalID( PartyID );
+ CREItem *item = actor->inventory.GetUsedWeapon(false, dummy);
+ if (item && (item->Flags & IE_INV_ITEM_CURSED)) {
+ displaymsg->DisplayConstantString(STR_CURSED, DMC_WHITE);
} else {
- actor = game->FindPC( PartyID );
- }
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
+ ret = actor->SetEquippedQuickSlot(slot, ability);
+ if (ret) {
+ displaymsg->DisplayConstantString(ret, DMC_WHITE);
+ }
}
-
- int ret = actor->SetEquippedQuickSlot(slot, ability);
- return PyInt_FromLong( ret );
+ Py_INCREF( Py_None );
+ return Py_None;
}
PyDoc_STRVAR( GemRB_GetEquippedQuickSlot__doc,
-"GetEquippedQuickSlot(PartyID[, NoTrans, global]) => Slot\n\n"
-"Returns the inventory slot (translation) or quick weapon index (no translation) of the equipped weapon.\n"
-"If global is set, the actor will be looked up by its global ID instead of party slot.");
+"GetEquippedQuickSlot(PartyID[, NoTrans]) => Slot\n\n"
+"Returns the inventory slot (translation) or quick weapon index (no translation) of the equipped weapon.\n");
static PyObject* GemRB_GetEquippedQuickSlot(PyObject * /*self*/, PyObject* args)
{
- int PartyID;
+ int globalID;
int NoTrans = 0;
- int global = 0;
- if (!PyArg_ParseTuple( args, "i|ii", &PartyID, &NoTrans, &global)) {
+ if (!PyArg_ParseTuple( args, "i|i", &globalID, &NoTrans)) {
return AttributeError( GemRB_GetEquippedQuickSlot__doc );
}
GET_GAME();
-
- Actor* actor;
- if (global) {
- actor = game->GetActorByGlobalID( PartyID );
- } else {
- actor = game->FindPC( PartyID );
- }
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
int ret = actor->inventory.GetEquippedSlot();
- /*int effect = core->QuerySlotEffects(ret);
- if (effect == SLOT_EFFECT_MISSILE) {
- ret = actor->inventory.FindRangedWeapon();
- }*/
if (actor->PCStats) {
for(int i=0;i<4;i++) {
if (ret == actor->PCStats->QuickWeaponSlots[i]) {
@@ -8845,30 +9353,24 @@ static PyObject* GemRB_GetEquippedQuickSlot(PyObject * /*self*/, PyObject* args)
break;
}
}
- } /*else {
- ret-=actor->inventory.GetWeaponSlot();
- }*/
+ }
return PyInt_FromLong( core->FindSlot(ret) );
}
PyDoc_STRVAR( GemRB_GetEquippedAmmunition__doc,
-"GetEquippedAmmunition(PartyID) => QSlot\n\n"
+"GetEquippedAmmunition(globalID) => QSlot\n\n"
"Returns the equipped ammunition slot, if any; -1 if none." );
static PyObject* GemRB_GetEquippedAmmunition(PyObject * /*self*/, PyObject* args)
{
- int PartyID;
+ int globalID;
- if (!PyArg_ParseTuple( args, "i", &PartyID)) {
+ if (!PyArg_ParseTuple( args, "i", &globalID)) {
return AttributeError( GemRB_GetEquippedQuickSlot__doc );
}
GET_GAME();
-
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
int ret = actor->inventory.GetEquippedSlot();
int effect = core->QuerySlotEffects(ret);
@@ -8880,32 +9382,22 @@ static PyObject* GemRB_GetEquippedAmmunition(PyObject * /*self*/, PyObject* args
}
PyDoc_STRVAR( GemRB_SetModalState__doc,
-"SetModalState(slot, state[, global, spell])\n\n"
+"SetModalState(slot, state[, spell])\n\n"
"Sets the modal state of the actor.\n"
-"If 'spell' is not given, it will set a default spell resource associated with the state.\n"
-"If global is set, the actor will be looked up by its global ID instead of party slot.");
+"If 'spell' is not given, it will set a default spell resource associated with the state.\n");
static PyObject* GemRB_SetModalState(PyObject * /*self*/, PyObject* args)
{
- int slot;
+ int globalID;
int state;
- int global = 0;
const char *spell=NULL;
- if (!PyArg_ParseTuple( args, "ii|is", &slot, &state, &global, &spell )) {
+ if (!PyArg_ParseTuple( args, "ii|s", &globalID, &state, &spell )) {
return AttributeError( GemRB_SetModalState__doc );
}
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor* actor;
- if (global) {
- actor = game->GetActorByGlobalID( slot );
- } else {
- actor = game->FindPC( slot );
- }
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
actor->SetModal( (ieDword) state, 0);
actor->SetModalSpell(state, spell);
@@ -8914,34 +9406,23 @@ static PyObject* GemRB_SetModalState(PyObject * /*self*/, PyObject* args)
}
PyDoc_STRVAR( GemRB_SpellCast__doc,
-"SpellCast(slot, type, spell[, global])\n\n"
+"SpellCast(slot, type, spell)\n\n"
"Makes the actor try to cast a spell. Type is the spell type like 3 for normal spells and 4 for innates.\n"
"If type is -1, then the castable spell list will be deleted and no spell will be cast.\n"
-"Spell is the index of the spell in the memorised spell list.\n"
-"If global is set, the actor will be looked up by its global ID instead of party slot.\n");
+"Spell is the index of the spell in the memorised spell list.\n");
static PyObject* GemRB_SpellCast(PyObject * /*self*/, PyObject* args)
{
- unsigned int slot;
+ unsigned int globalID;
int type;
unsigned int spell;
- int global = 0;
- if (!PyArg_ParseTuple( args, "iii|i", &slot, &type, &spell, &global )) {
+ if (!PyArg_ParseTuple( args, "iii", &globalID, &type, &spell)) {
return AttributeError( GemRB_SpellCast__doc );
}
GET_GAME();
-
- Actor* actor;
- if (global) {
- actor = game->GetActorByGlobalID( slot );
- } else {
- actor = game->FindPC( slot );
- }
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
//don't cast anything, just reinit the spell list
if (type==-1) {
@@ -8951,17 +9432,35 @@ static PyObject* GemRB_SpellCast(PyObject * /*self*/, PyObject* args)
}
SpellExtHeader spelldata; // = SpellArray[spell];
- actor->spellbook.GetSpellInfo(&spelldata, type, spell, 1);
- printf("Cast spell: %s\n", spelldata.spellname);
- printf("Slot: %d\n", spelldata.slot);
- printf("Type: %d\n", spelldata.type);
+ if (type==-2) {
+ //resolve quick spell slot
+ if (!actor->PCStats) {
+ //no quick slots for this actor, is this an error?
+ //return RuntimeError( "Actor has no quickslots!\n" );
+ Py_INCREF( Py_None );
+ return Py_None;
+ }
+ actor->spellbook.FindSpellInfo(&spelldata, actor->PCStats->QuickSpells[spell], actor->PCStats->QuickSpellClass[spell]);
+ } else {
+ ieDword ActionLevel = 0;
+ core->GetDictionary()->Lookup("ActionLevel", ActionLevel);
+ if (ActionLevel == 5) {
+ // get the right spell, since the lookup below only checks the memorized list
+ actor->spellbook.SetCustomSpellInfo(NULL, NULL, type);
+ }
+ actor->spellbook.GetSpellInfo(&spelldata, type, spell, 1);
+ }
+
+ print("Cast spell: %s", spelldata.spellname);
+ print("Slot: %d", spelldata.slot);
+ print("Type: %d", spelldata.type);
//cannot make this const, because it will be freed
char *tmp = core->GetString(spelldata.strref);
- printf("Spellname: %s\n", tmp);
+ print("Spellname: %s", tmp);
core->FreeString(tmp);
- printf("Target: %d\n", spelldata.Target);
- printf("Range: %d\n", spelldata.Range);
+ print("Target: %d", spelldata.Target);
+ print("Range: %d", spelldata.Range);
if(! (1<<spelldata.type) & type) {
return RuntimeError( "Wrong type of spell!");
}
@@ -8993,7 +9492,7 @@ static PyObject* GemRB_SpellCast(PyObject * /*self*/, PyObject* args)
//bring up inventory in the end???
//break;
default:
- printf("Unhandled target type: %d\n", spelldata.Target);
+ print("Unhandled target type: %d", spelldata.Target);
break;
}
Py_INCREF( Py_None );
@@ -9006,22 +9505,18 @@ PyDoc_STRVAR( GemRB_ApplySpell__doc,
static PyObject* GemRB_ApplySpell(PyObject * /*self*/, PyObject* args)
{
- int PartyID, casterID = 0;
+ int globalID, casterID = 0;
const char *spell;
- if (!PyArg_ParseTuple( args, "is|i", &PartyID, &spell, &casterID )) {
+ if (!PyArg_ParseTuple( args, "is|i", &globalID, &spell, &casterID )) {
return AttributeError( GemRB_ApplySpell__doc );
}
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Map *map = game->GetCurrentArea();
-
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
Actor *caster = NULL;
+ Map *map = game->GetCurrentArea();
if (map) caster = map->GetActorByGlobalID(casterID);
if (!caster) caster = game->GetActorByGlobalID(casterID);
if (!caster) caster = actor;
@@ -9033,38 +9528,28 @@ static PyObject* GemRB_ApplySpell(PyObject * /*self*/, PyObject* args)
}
PyDoc_STRVAR( GemRB_UseItem__doc,
-"UseItem(actor, slot, header[,forcetarget,global])\n\n"
+"UseItem(actor, slot, header[,forcetarget])\n\n"
"Makes the actor try to use an item. "
"If slot is -1, then header is the index of the item functionality in the use item list. "
"If slot is -2, then header is the quickslot index. "
-"If slot is non-negative, then header is the header of the item in the 'slot'.\n"
-"If global is set, the actor will be looked up by its global ID instead of party slot.");
+"If slot is non-negative, then header is the header of the item in the 'slot'.\n");
static PyObject* GemRB_UseItem(PyObject * /*self*/, PyObject* args)
{
- int PartyID;
+ int globalID;
int slot;
int header;
int forcetarget=-1; //some crappy scrolls don't target self correctly!
- int global = 0;
- if (!PyArg_ParseTuple( args, "iii|ii", &PartyID, &slot, &header, &forcetarget, &global )) {
+ if (!PyArg_ParseTuple( args, "iii|i", &globalID, &slot, &header, &forcetarget)) {
return AttributeError( GemRB_UseItem__doc );
}
GET_GAME();
GET_GAMECONTROL();
+ GET_ACTOR_GLOBAL();
- Actor* actor;
- if (global) {
- actor = game->GetActorByGlobalID( PartyID );
- } else {
- actor = game->FindPC( PartyID );
- }
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
ItemExtHeader itemdata;
int flags = 0;
@@ -9077,7 +9562,7 @@ static PyObject* GemRB_UseItem(PyObject * /*self*/, PyObject* args)
//quickslot
actor->GetItemSlotInfo(&itemdata, header, -1);
if (!itemdata.Charges) {
- printMessage("GUIScript","QuickItem has no charges.\n", WHITE);
+ Log(MESSAGE, "GUIScript", "QuickItem has no charges.");
Py_INCREF( Py_None );
return Py_None;
}
@@ -9095,18 +9580,18 @@ static PyObject* GemRB_UseItem(PyObject * /*self*/, PyObject* args)
//is there any better check for a non existent item?
if (!itemdata.itemname[0]) {
- printMessage("GUIScript","Empty slot used?\n", YELLOW);
+ Log(WARNING, "GUIScript", "Empty slot used?");
Py_INCREF( Py_None );
return Py_None;
}
/// remove this after projectile is done
- printf("Use item: %s\n", itemdata.itemname);
- printf("Extended header: %d\n", itemdata.headerindex);
- printf("Attacktype: %d\n",itemdata.AttackType);
- printf("Range: %d\n",itemdata.Range);
- printf("Target: %d\n",forcetarget);
- printf("Projectile: %d\n", itemdata.ProjectileAnimation);
+ print("Use item: %s", itemdata.itemname);
+ print("Extended header: %d", itemdata.headerindex);
+ print("Attacktype: %d", itemdata.AttackType);
+ print("Range: %d", itemdata.Range);
+ print("Target: %d", forcetarget);
+ print("Projectile: %d", itemdata.ProjectileAnimation);
//
switch (forcetarget) {
case TARGET_SELF:
@@ -9127,7 +9612,7 @@ static PyObject* GemRB_UseItem(PyObject * /*self*/, PyObject* args)
gc->SetupItemUse(itemdata.slot, itemdata.headerindex, actor, 0, itemdata.TargetNumber);
break;
default:
- printMessage("GUIScript", "Unhandled target type!", LIGHT_RED );
+ Log(ERROR, "GUIScript", "Unhandled target type!");
break;
}
Py_INCREF( Py_None );
@@ -9203,7 +9688,7 @@ static PyObject* GemRB_SetFullScreen(PyObject * /*self*/, PyObject* args)
if (!PyArg_ParseTuple( args, "i", &fullscreen )) {
return AttributeError( GemRB_SetFullScreen__doc );
}
- core->GetVideoDriver()->ToggleFullscreenMode(fullscreen);
+ core->GetVideoDriver()->SetFullscreenMode(fullscreen);
Py_INCREF( Py_None );
return Py_None;
}
@@ -9222,7 +9707,24 @@ static PyObject* GemRB_RestParty(PyObject * /*self*/, PyObject* args)
}
GET_GAME();
- game->RestParty(noareacheck, dream, hp);
+ return PyInt_FromLong(game->RestParty(noareacheck, dream, hp));
+}
+
+PyDoc_STRVAR( GemRB_ChargeSpells__doc,
+"ChargeSpells(globalID|pc)\n\n"
+"Recharges the actor's spells.");
+static PyObject* GemRB_ChargeSpells(PyObject * /*self*/, PyObject* args)
+{
+ int globalID;
+
+ if (!PyArg_ParseTuple( args, "i", &globalID)) {
+ return AttributeError( GemRB_ChargeSpells__doc );
+ }
+ GET_GAME();
+ GET_ACTOR_GLOBAL();
+
+ actor->spellbook.ChargeAllSpells();
+
Py_INCREF( Py_None );
return Py_None;
}
@@ -9234,9 +9736,9 @@ PyDoc_STRVAR( GemRB_HasSpecialItem__doc,
//itemtype 1 - identify
static PyObject* GemRB_HasSpecialItem(PyObject * /*self*/, PyObject* args)
{
- int PartyID, itemtype, useup;
+ int globalID, itemtype, useup;
- if (!PyArg_ParseTuple( args, "iii", &PartyID, &itemtype, &useup)) {
+ if (!PyArg_ParseTuple( args, "iii", &globalID, &itemtype, &useup)) {
return AttributeError( GemRB_HasSpecialItem__doc );
}
if (SpecialItemsCount==-1) {
@@ -9244,11 +9746,8 @@ static PyObject* GemRB_HasSpecialItem(PyObject * /*self*/, PyObject* args)
}
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
int i = SpecialItemsCount;
int slot = -1;
while(i--) {
@@ -9279,20 +9778,19 @@ PyDoc_STRVAR( GemRB_HasSpecialSpell__doc,
"Checks if a team member has a spell, optionally uses it.");
//itemtype 1 - identify
+// 2 - can use in silence
+// 4 - cannot use in wildsurge
static PyObject* GemRB_HasSpecialSpell(PyObject * /*self*/, PyObject* args)
{
- int PartyID, itemtype, useup;
+ int globalID, itemtype, useup;
- if (!PyArg_ParseTuple( args, "iii", &PartyID, &itemtype, &useup)) {
+ if (!PyArg_ParseTuple( args, "iii", &globalID, &itemtype, &useup)) {
return AttributeError( GemRB_HasSpecialSpell__doc );
}
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
int i = core->GetSpecialSpellsCount();
if (i == -1) {
return RuntimeError( "Game has no splspec.2da table!" );
@@ -9323,7 +9821,8 @@ PyDoc_STRVAR( GemRB_ApplyEffect__doc,
static PyObject* GemRB_ApplyEffect(PyObject * /*self*/, PyObject* args)
{
- int PartyID;
+ int timing = FX_DURATION_INSTANT_PERMANENT_AFTER_BONUSES;
+ int globalID;
const char *opcodename;
int param1, param2;
const char *resref1 = NULL;
@@ -9331,18 +9830,15 @@ static PyObject* GemRB_ApplyEffect(PyObject * /*self*/, PyObject* args)
const char *resref3 = NULL;
const char *source = NULL;
- if (!PyArg_ParseTuple( args, "isii|ssss", &PartyID, &opcodename, ¶m1, ¶m2, &resref1, &resref2, &resref3, &source)) {
+ if (!PyArg_ParseTuple( args, "isii|ssssi", &globalID, &opcodename, ¶m1, ¶m2, &resref1, &resref2, &resref3, &source, &timing)) {
return AttributeError( GemRB_ApplyEffect__doc );
}
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
work_ref.Name=opcodename;
work_ref.opcode=-1;
- Effect *fx = EffectQueue::CreateEffect(work_ref, param1, param2, FX_DURATION_INSTANT_PERMANENT_AFTER_BONUSES);
+ Effect *fx = EffectQueue::CreateEffect(work_ref, param1, param2, timing);
if (!fx) {
//invalid effect name didn't resolve to opcode
return RuntimeError( "Invalid effect name!\n" );
@@ -9380,20 +9876,17 @@ PyDoc_STRVAR( GemRB_CountEffects__doc,
static PyObject* GemRB_CountEffects(PyObject * /*self*/, PyObject* args)
{
- int PartyID;
+ int globalID;
const char *opcodename;
int param1, param2;
const char *resref = NULL;
- if (!PyArg_ParseTuple( args, "isii|s", &PartyID, &opcodename, ¶m1, ¶m2, &resref)) {
+ if (!PyArg_ParseTuple( args, "isii|s", &globalID, &opcodename, ¶m1, ¶m2, &resref)) {
return AttributeError( GemRB_CountEffects__doc );
}
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
work_ref.Name=opcodename;
work_ref.opcode=-1;
ieDword ret = actor->fxqueue.CountEffects(work_ref, param1, param2, resref);
@@ -9407,19 +9900,16 @@ PyDoc_STRVAR( GemRB_ModifyEffect__doc,
static PyObject* GemRB_ModifyEffect(PyObject * /*self*/, PyObject* args)
{
- int PartyID;
+ int globalID;
const char *opcodename;
int px, py;
- if (!PyArg_ParseTuple( args, "isii", &PartyID, &opcodename, &px, &py)) {
+ if (!PyArg_ParseTuple( args, "isii", &globalID, &opcodename, &px, &py)) {
return AttributeError( GemRB_ModifyEffect__doc );
}
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
work_ref.Name=opcodename;
work_ref.opcode=-1;
actor->fxqueue.ModifyEffectPoint(work_ref, px, py);
@@ -9445,13 +9935,13 @@ static PyObject* GemRB_StealFailed(PyObject * /*self*/, PyObject* /*args*/)
Actor* owner = map->GetActorByGlobalID( store->GetOwnerID() );
if (!owner) owner = game->GetActorByGlobalID( store->GetOwnerID() );
if (!owner) {
- printMessage("GUIScript", "No owner found!", YELLOW );
+ Log(WARNING, "GUIScript", "No owner found!");
Py_INCREF( Py_None );
return Py_None;
}
Actor* attacker = game->FindPC((int) game->GetSelectedPCSingle() );
if (!attacker) {
- printMessage("GUIScript", "No thief found!", YELLOW );
+ Log(WARNING, "GUIScript", "No thief found!");
Py_INCREF( Py_None );
return Py_None;
}
@@ -9463,8 +9953,11 @@ static PyObject* GemRB_StealFailed(PyObject * /*self*/, PyObject* /*args*/)
}
//not sure if this is ok
- //owner->LastAttacker = attacker->GetID();
- owner->LastDisarmFailed = attacker->GetGlobalID();
+ //owner->LastDisarmFailed = attacker->GetGlobalID();
+ if (core->HasFeature(GF_STEAL_IS_ATTACK)) {
+ owner->AttackedBy(attacker);
+ }
+ owner->AddTrigger(TriggerEntry(trigger_stealfailed, attacker->GetGlobalID()));
Py_INCREF( Py_None );
return Py_None;
}
@@ -9517,18 +10010,15 @@ PyDoc_STRVAR( GemRB_DisplayString__doc,
static PyObject* GemRB_DisplayString(PyObject * /*self*/, PyObject* args)
{
int strref, color;
- int PartyID = 0;
+ int globalID = 0;
- if (!PyArg_ParseTuple( args, "ii|i", &strref, &color, &PartyID)) {
+ if (!PyArg_ParseTuple( args, "ii|i", &strref, &color, &globalID)) {
return AttributeError( GemRB_DisplayString__doc );
}
- if (PartyID) {
+ if (globalID) {
GET_GAME();
+ GET_ACTOR_GLOBAL();
- Actor *actor = game->FindPC(PartyID);
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
displaymsg->DisplayStringName(strref, (unsigned int) color, actor, IE_STR_SOUND);
} else {
displaymsg->DisplayString(strref, (unsigned int) color, IE_STR_SOUND);
@@ -9543,58 +10033,176 @@ PyDoc_STRVAR( GemRB_GetCombatDetails__doc,
static PyObject* GemRB_GetCombatDetails(PyObject * /*self*/, PyObject* args)
{
- int PartyID;
+ int globalID;
int leftorright;
- if (!PyArg_ParseTuple( args, "ii", &PartyID, &leftorright)) {
+ if (!PyArg_ParseTuple( args, "ii", &globalID, &leftorright)) {
return AttributeError( GemRB_GetCombatDetails__doc );
}
GET_GAME();
-
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
leftorright = leftorright&1;
WeaponInfo wi;
- ITMExtHeader *header = NULL;
- ITMExtHeader *hittingheader = NULL;
+ ITMExtHeader *header = NULL; // contains the weapon header
+ ITMExtHeader *hittingheader = NULL; // same header, except for ranged weapons it is the ammo header
int tohit=20;
- ieDword Flags=0;
- int DamageBonus=0, CriticalBonus=0;
- int speed, style=0;
+ int DamageBonus=0;
+ int CriticalBonus=0;
+ int speed=0;
+ int style=0;
PyObject* dict = PyDict_New();
- if (!actor->GetCombatDetails(tohit, leftorright, wi, header, hittingheader, Flags, DamageBonus, speed, CriticalBonus, style, NULL)) {
+ if (!actor->GetCombatDetails(tohit, leftorright, wi, header, hittingheader, DamageBonus, speed, CriticalBonus, style, NULL)) {
//TODO: handle error, so tohit will still be set correctly?
}
- PyDict_SetItemString(dict, "ToHit", PyInt_FromLong (tohit));
- PyDict_SetItemString(dict, "Flags", PyInt_FromLong (Flags));
+ PyDict_SetItemString(dict, "Slot", PyInt_FromLong (wi.slot));
+ PyDict_SetItemString(dict, "Flags", PyInt_FromLong (wi.wflags));
+ PyDict_SetItemString(dict, "Enchantment", PyInt_FromLong (wi.enchantment));
+ PyDict_SetItemString(dict, "Range", PyInt_FromLong (wi.range));
+ PyDict_SetItemString(dict, "Proficiency", PyInt_FromLong (wi.prof));
PyDict_SetItemString(dict, "DamageBonus", PyInt_FromLong (DamageBonus));
PyDict_SetItemString(dict, "Speed", PyInt_FromLong (speed));
PyDict_SetItemString(dict, "CriticalBonus", PyInt_FromLong (CriticalBonus));
PyDict_SetItemString(dict, "Style", PyInt_FromLong (style));
+ PyDict_SetItemString(dict, "APR", PyInt_FromLong (actor->GetNumberOfAttacks() ));
+ PyDict_SetItemString(dict, "CriticalMultiplier", PyInt_FromLong (wi.critmulti));
+ PyDict_SetItemString(dict, "CriticalRange", PyInt_FromLong (wi.critrange));
+ PyDict_SetItemString(dict, "ProfDmgBon", PyInt_FromLong (wi.profdmgbon));
+ PyDict_SetItemString(dict, "LauncherDmgBon", PyInt_FromLong (wi.launcherdmgbon));
+ PyDict_SetItemString(dict, "WeaponStrBonus", PyInt_FromLong (actor->WeaponDamageBonus(wi)));
+ if (hittingheader) {
+ PyDict_SetItemString(dict, "HitHeaderNumDice", PyInt_FromLong (hittingheader->DiceThrown));
+ PyDict_SetItemString(dict, "HitHeaderDiceSides", PyInt_FromLong (hittingheader->DiceSides));
+ PyDict_SetItemString(dict, "HitHeaderDiceBonus", PyInt_FromLong (hittingheader->DamageBonus));
+ } else {
+ return RuntimeError("Serious problem in GetCombatDetails: could not find the hitting header!");
+ }
+
+// actor->AC.dump();
+ actor->ToHit.dump();
+ PyObject *ac = PyDict_New();
+ PyDict_SetItemString(ac, "Total", PyInt_FromLong (actor->AC.GetTotal()));
+ PyDict_SetItemString(ac, "Natural", PyInt_FromLong (actor->AC.GetNatural()));
+ PyDict_SetItemString(ac, "Armor", PyInt_FromLong (actor->AC.GetArmorBonus()));
+ PyDict_SetItemString(ac, "Shield", PyInt_FromLong (actor->AC.GetShieldBonus()));
+ PyDict_SetItemString(ac, "Deflection", PyInt_FromLong (actor->AC.GetDeflectionBonus()));
+ PyDict_SetItemString(ac, "Generic", PyInt_FromLong (actor->AC.GetGenericBonus()));
+ PyDict_SetItemString(ac, "Dexterity", PyInt_FromLong (actor->AC.GetDexterityBonus()));
+ PyDict_SetItemString(ac, "Wisdom", PyInt_FromLong (actor->AC.GetWisdomBonus()));
+ PyDict_SetItemString(dict, "AC", ac);
+
+ PyObject *tohits = PyDict_New();
+ PyDict_SetItemString(tohits, "Total", PyInt_FromLong (actor->ToHit.GetTotal()));
+ PyDict_SetItemString(tohits, "Base", PyInt_FromLong (actor->ToHit.GetBase()));
+ PyDict_SetItemString(tohits, "Armor", PyInt_FromLong (actor->ToHit.GetArmorBonus()));
+ PyDict_SetItemString(tohits, "Shield", PyInt_FromLong (actor->ToHit.GetShieldBonus()));
+ PyDict_SetItemString(tohits, "Proficiency", PyInt_FromLong (actor->ToHit.GetProficiencyBonus()));
+ PyDict_SetItemString(tohits, "Generic", PyInt_FromLong (actor->ToHit.GetGenericBonus()));
+ PyDict_SetItemString(tohits, "Ability", PyInt_FromLong (actor->ToHit.GetAbilityBonus()));
+ PyDict_SetItemString(tohits, "Weapon", PyInt_FromLong (actor->ToHit.GetWeaponBonus()));
+ PyDict_SetItemString(dict, "ToHitStats", tohits);
+
+ const CREItem *wield;
+ // wi.slot has the launcher, so look up the ammo
+ //FIXME: remove the need to look it up again
+ if (hittingheader && (hittingheader->AttackType&ITEM_AT_PROJECTILE)) {
+ wield = actor->inventory.GetSlotItem(actor->inventory.GetEquippedSlot());
+ header = hittingheader;
+ } else {
+ wield = actor->inventory.GetUsedWeapon(leftorright, wi.slot);
+ }
+ if (!wield) {
+ return 0;
+ }
+ Item *item = gamedata->GetItem(wield->ItemResRef, true);
+ if (!item) {
+ Log(WARNING, "Actor", "Missing or invalid weapon item: %s!", wield->ItemResRef);
+ return dict;
+ }
+
+ // create a tuple with all the 100% probable damage opcodes' stats
+ std::vector<DMGOpcodeInfo> damage_opcodes = item->GetDamageOpcodesDetails(header) ;
+ PyObject *alldos = PyTuple_New(damage_opcodes.size());
+ unsigned int i;
+ for (i = 0; i < damage_opcodes.size(); i++) {
+ PyObject *dos = PyDict_New();
+ PyDict_SetItemString(dos, "TypeName", PyString_FromString (damage_opcodes[i].TypeName));
+ PyDict_SetItemString(dos, "NumDice", PyInt_FromLong (damage_opcodes[i].DiceThrown));
+ PyDict_SetItemString(dos, "DiceSides", PyInt_FromLong (damage_opcodes[i].DiceSides));
+ PyDict_SetItemString(dos, "DiceBonus", PyInt_FromLong (damage_opcodes[i].DiceBonus));
+ PyDict_SetItemString(dos, "Chance", PyInt_FromLong (damage_opcodes[i].Chance));
+ PyTuple_SetItem(alldos, i, dos);
+ }
+ PyDict_SetItemString(dict, "DamageOpcodes", alldos);
+
return dict;
}
+PyDoc_STRVAR( GemRB_GetDamageReduction__doc,
+ "GetDamageReduction(pc, enchantment[, missile])\n\n"
+ "returns the damage reduction for the specified enchantment level and type.");
+static PyObject* GemRB_GetDamageReduction(PyObject * /*self*/, PyObject* args)
+{
+ int globalID;
+ unsigned int enchantment = 0;
+ int missile = 0;
+
+ if (!PyArg_ParseTuple( args, "ii|i", &globalID, &enchantment, &missile)) {
+ return AttributeError( GemRB_GetDamageReduction__doc );
+ }
+ GET_GAME();
+ GET_ACTOR_GLOBAL();
+
+ int total = 0;
+ if (missile) {
+ total = actor->GetDamageReduction(IE_RESISTMISSILE, enchantment);
+ } else {
+ total = actor->GetDamageReduction(IE_RESISTCRUSHING, enchantment);
+ }
+
+ return PyInt_FromLong(total);
+}
+
+PyDoc_STRVAR( GemRB_GetSpellFailure__doc,
+ "GetSpellFailure(pc[, cleric])\n\n"
+ "returns the (arcane unless cleric is set) spell failure in percent.");
+static PyObject* GemRB_GetSpellFailure(PyObject * /*self*/, PyObject* args)
+{
+ int globalID;
+ int cleric = 0;
+
+ if (!PyArg_ParseTuple( args, "i|i", &globalID, &cleric)) {
+ return AttributeError( GemRB_GetSpellFailure__doc );
+ }
+ GET_GAME();
+ GET_ACTOR_GLOBAL();
+
+ PyObject *failure = PyDict_New();
+ // true means arcane, so reverse the passed argument
+ PyDict_SetItemString(failure, "Total", PyInt_FromLong (actor->GetSpellFailure(!cleric)));
+ // set also the shield and armor penalty - we can't reuse the ones for to-hit boni, since they also considered armor proficiency
+ int am = 0, sm = 0;
+ actor->GetArmorFailure(am, sm);
+ PyDict_SetItemString(failure, "Armor", PyInt_FromLong (am));
+ PyDict_SetItemString(failure, "Shield", PyInt_FromLong (sm));
+
+ return failure;
+}
+
PyDoc_STRVAR( GemRB_IsDualWielding__doc,
"IsDualWielding(pc)\n\n"
"1 if the pc is dual wielding; 0 otherwise.");
static PyObject* GemRB_IsDualWielding(PyObject * /*self*/, PyObject* args)
{
- int PartyID;
+ int globalID;
- if (!PyArg_ParseTuple( args, "i", &PartyID)) {
+ if (!PyArg_ParseTuple( args, "i", &globalID)) {
return AttributeError( GemRB_IsDualWielding__doc );
}
GET_GAME();
-
- Actor* actor = game->FindPC( PartyID );
- if (!actor) {
- return RuntimeError( "Actor not found!\n" );
- }
+ GET_ACTOR_GLOBAL();
int dualwield = actor->IsDualWielding();
return PyInt_FromLong( dualwield );
@@ -9633,19 +10241,20 @@ PyDoc_STRVAR( GemRB_GetSpellCastOn__doc,
static PyObject* GemRB_GetSpellCastOn(PyObject* /*self*/, PyObject* args)
{
- int PartyID;
+ int globalID;
ieResRef splname;
- if (!PyArg_ParseTuple( args, "i", &PartyID )) {
+ if (!PyArg_ParseTuple( args, "i", &globalID )) {
return AttributeError( GemRB_GetSpellCastOn__doc );
}
GET_GAME();
-
- Actor* actor = game->FindPC( PartyID );
+ GET_ACTOR_GLOBAL();
+/*
+ Actor* actor = game->FindPC( globalID );
if (!actor) {
return RuntimeError( "Actor not found!\n" );
}
-
+*/
ResolveSpellName(splname, actor->LastSpellOnMe);
return PyString_FromString(splname);
}
@@ -9699,12 +10308,12 @@ static PyObject* GemRB_SetupMaze(PyObject* /*self*/, PyObject* args)
GET_GAME();
- maze_header *h = (maze_header *) (game->AllocateMazeData()+MAZE_ENTRY_COUNT*MAZE_ENTRY_SIZE);
+ maze_header *h = reinterpret_cast<maze_header *> (game->AllocateMazeData()+MAZE_ENTRY_COUNT*MAZE_ENTRY_SIZE);
memset(h, 0, MAZE_HEADER_SIZE);
h->maze_sizex = xsize;
h->maze_sizey = ysize;
for(int i=0;i<MAZE_ENTRY_COUNT;i++) {
- maze_entry *m = (maze_entry *) (game->mazedata+i*MAZE_ENTRY_SIZE);
+ maze_entry *m = reinterpret_cast<maze_entry *> (game->mazedata+i*MAZE_ENTRY_SIZE);
memset(m, 0, MAZE_ENTRY_SIZE);
bool used = (i/MAZE_MAX_DIM<ysize) && (i%MAZE_MAX_DIM<xsize);
m->valid = used;
@@ -9740,7 +10349,7 @@ static PyObject* GemRB_SetMazeEntry(PyObject* /*self*/, PyObject* args)
return RuntimeError( "No maze set up!" );
}
- maze_entry *m = (maze_entry *) (game->mazedata+entry*MAZE_ENTRY_SIZE);
+ maze_entry *m = reinterpret_cast<maze_entry *> (game->mazedata+entry*MAZE_ENTRY_SIZE);
maze_entry *m2;
switch(index) {
case ME_OVERRIDE:
@@ -9764,28 +10373,28 @@ static PyObject* GemRB_SetMazeEntry(PyObject* /*self*/, PyObject* args)
m->walls |= value;
if (value & WALL_SOUTH) {
if (entry%MAZE_MAX_DIM!=MAZE_MAX_DIM-1) {
- m2 = (maze_entry *) (game->mazedata+(entry+1)*MAZE_ENTRY_SIZE);
+ m2 = reinterpret_cast<maze_entry *> (game->mazedata+(entry+1)*MAZE_ENTRY_SIZE);
m2->walls|=WALL_NORTH;
}
}
if (value & WALL_NORTH) {
if (entry%MAZE_MAX_DIM) {
- m2 = (maze_entry *) (game->mazedata+(entry-1)*MAZE_ENTRY_SIZE);
+ m2 = reinterpret_cast<maze_entry *> (game->mazedata+(entry-1)*MAZE_ENTRY_SIZE);
m2->walls|=WALL_SOUTH;
}
}
if (value & WALL_EAST) {
if (entry+MAZE_MAX_DIM<MAZE_ENTRY_COUNT) {
- m2 = (maze_entry *) (game->mazedata+(entry+MAZE_MAX_DIM)*MAZE_ENTRY_SIZE);
+ m2 = reinterpret_cast<maze_entry *> (game->mazedata+(entry+MAZE_MAX_DIM)*MAZE_ENTRY_SIZE);
m2->walls|=WALL_WEST;
}
}
if (value & WALL_WEST) {
if (entry>=MAZE_MAX_DIM) {
- m2 = (maze_entry *) (game->mazedata+(entry-MAZE_MAX_DIM)*MAZE_ENTRY_SIZE);
+ m2 = reinterpret_cast<maze_entry *> (game->mazedata+(entry-MAZE_MAX_DIM)*MAZE_ENTRY_SIZE);
m2->walls|=WALL_EAST;
}
}
@@ -9820,7 +10429,7 @@ static PyObject* GemRB_SetMazeData(PyObject* /*self*/, PyObject* args)
return RuntimeError( "No maze set up!" );
}
- maze_header *h = (maze_header *) (game->mazedata+MAZE_ENTRY_COUNT*MAZE_ENTRY_SIZE);
+ maze_header *h = reinterpret_cast<maze_header *> (game->mazedata+MAZE_ENTRY_COUNT*MAZE_ENTRY_SIZE);
switch(entry) {
case MH_POS1X:
h->pos1x = value;
@@ -9880,7 +10489,7 @@ static PyObject* GemRB_GetMazeHeader(PyObject* /*self*/, PyObject* /*args*/)
}
PyObject* dict = PyDict_New();
- maze_header *h = (maze_header *) (game->mazedata+MAZE_ENTRY_COUNT*MAZE_ENTRY_SIZE);
+ maze_header *h = reinterpret_cast<maze_header *> (game->mazedata+MAZE_ENTRY_COUNT*MAZE_ENTRY_SIZE);
PyDict_SetItemString(dict, "MazeX", PyInt_FromLong (h->maze_sizex));
PyDict_SetItemString(dict, "MazeY", PyInt_FromLong (h->maze_sizey));
PyDict_SetItemString(dict, "Pos1X", PyInt_FromLong (h->pos1x));
@@ -9919,7 +10528,7 @@ static PyObject* GemRB_GetMazeEntry(PyObject* /*self*/, PyObject* args)
}
PyObject* dict = PyDict_New();
- maze_entry *m = (maze_entry *) (game->mazedata+entry*MAZE_ENTRY_SIZE);
+ maze_entry *m = reinterpret_cast<maze_entry *> (game->mazedata+entry*MAZE_ENTRY_SIZE);
PyDict_SetItemString(dict, "Override", PyInt_FromLong (m->override));
PyDict_SetItemString(dict, "Accessible", PyInt_FromLong (m->accessible));
PyDict_SetItemString(dict, "Valid", PyInt_FromLong (m->valid));
@@ -9963,6 +10572,42 @@ static PyObject* GemRB_AddGameTypeHint(PyObject* /*self*/, PyObject* args)
}
+PyDoc_STRVAR( GemRB_GetAreaInfo__doc,
+"GetAreaInfo()=>mapping\n\n"
+"Returns important values about the current area.\n");
+
+static PyObject* GemRB_GetAreaInfo(PyObject* /*self*/, PyObject* /*args*/)
+{
+ GET_GAME();
+ GET_GAMECONTROL();
+
+ PyObject* info = PyDict_New();
+ PyDict_SetItemString(info, "CurrentArea", PyString_FromResRef( game->CurrentArea ) );
+ PyDict_SetItemString(info, "PositionX", PyInt_FromLong (gc->lastMouseX));
+ PyDict_SetItemString(info, "PositionY", PyInt_FromLong (gc->lastMouseY));
+
+ return info;
+}
+
+PyDoc_STRVAR( GemRB_Log__doc,
+"GemRB.Log(log_level, owner, message)\n\n"
+"Log a message to GemRB's logging system.\n");
+
+static PyObject* GemRB_Log(PyObject* /*self*/, PyObject* args)
+{
+ log_level level;
+ char* owner;
+ char* message;
+
+ if (!PyArg_ParseTuple(args, "iss", &level, &owner, &message)) {
+ return NULL;
+ }
+
+ Log(level, owner, "%s", message);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
static PyMethodDef GemRBMethods[] = {
METHOD(ActOnPC, METH_VARARGS),
METHOD(AddGameTypeHint, METH_VARARGS),
@@ -9973,10 +10618,13 @@ static PyMethodDef GemRBMethods[] = {
METHOD(ChangeContainerItem, METH_VARARGS),
METHOD(ChangeItemFlag, METH_VARARGS),
METHOD(ChangeStoreItem, METH_VARARGS),
+ METHOD(ChargeSpells, METH_VARARGS),
METHOD(CheckFeatCondition, METH_VARARGS),
+ METHOD(CheckSpecialSpell, METH_VARARGS),
METHOD(CheckVar, METH_VARARGS),
METHOD(ClearActions, METH_VARARGS),
METHOD(CountEffects, METH_VARARGS),
+ METHOD(CountSpells, METH_VARARGS),
METHOD(CreateCreature, METH_VARARGS),
METHOD(CreateItem, METH_VARARGS),
METHOD(CreateMovement, METH_VARARGS),
@@ -9989,6 +10637,7 @@ static PyMethodDef GemRBMethods[] = {
METHOD(DragItem, METH_VARARGS),
METHOD(DrawWindows, METH_NOARGS),
METHOD(DropDraggedItem, METH_VARARGS),
+ METHOD(DumpActor, METH_VARARGS),
METHOD(EnableCheatKeys, METH_VARARGS),
METHOD(EndCutSceneMode, METH_NOARGS),
METHOD(EnterGame, METH_NOARGS),
@@ -9999,6 +10648,7 @@ static PyMethodDef GemRBMethods[] = {
METHOD(FillPlayerInfo, METH_VARARGS),
METHOD(FindStoreItem, METH_VARARGS),
METHOD(GameControlGetTargetMode, METH_NOARGS),
+ METHOD(GameControlToggleAlwaysRun, METH_NOARGS),
METHOD(GameControlSetLastActor, METH_VARARGS),
METHOD(GameControlSetScreenFlags, METH_VARARGS),
METHOD(GameControlSetTargetMode, METH_VARARGS),
@@ -10021,11 +10671,14 @@ static PyMethodDef GemRBMethods[] = {
METHOD(GameSetPartySize, METH_VARARGS),
METHOD(GameSetProtagonistMode, METH_VARARGS),
METHOD(GameSetScreenFlags, METH_VARARGS),
+ METHOD(GetAreaInfo, METH_NOARGS),
+ METHOD(GetAvatarsValue, METH_VARARGS),
METHOD(GetAbilityBonus, METH_VARARGS),
METHOD(GetCombatDetails, METH_VARARGS),
METHOD(GetContainer, METH_VARARGS),
METHOD(GetContainerItem, METH_VARARGS),
METHOD(GetCurrentArea, METH_NOARGS),
+ METHOD(GetDamageReduction, METH_VARARGS),
METHOD(GetEquippedAmmunition, METH_VARARGS),
METHOD(GetEquippedQuickSlot, METH_VARARGS),
METHOD(GetGamePortraitPreview, METH_VARARGS),
@@ -10042,11 +10695,13 @@ static PyMethodDef GemRBMethods[] = {
METHOD(GetJournalSize, METH_VARARGS),
METHOD(GetKnownSpell, METH_VARARGS),
METHOD(GetKnownSpellsCount, METH_VARARGS),
+ METHOD(GetMaxEncumbrance, METH_VARARGS),
METHOD(GetMazeEntry, METH_VARARGS),
METHOD(GetMazeHeader, METH_NOARGS),
METHOD(GetMemorizableSpellsCount, METH_VARARGS),
METHOD(GetMemorizedSpell, METH_VARARGS),
METHOD(GetMemorizedSpellsCount, METH_VARARGS),
+ METHOD(MessageWindowDebug, METH_VARARGS),
METHOD(GetMessageWindowSize, METH_NOARGS),
METHOD(GetPartySize, METH_NOARGS),
METHOD(GetPCStats, METH_VARARGS),
@@ -10062,6 +10717,7 @@ static PyMethodDef GemRBMethods[] = {
METHOD(GetSelectedSize, METH_NOARGS),
METHOD(GetSelectedActors, METH_NOARGS),
METHOD(GetString, METH_VARARGS),
+ METHOD(GetSpellFailure, METH_VARARGS),
METHOD(GetSpellCastOn, METH_VARARGS),
METHOD(GetSlotType, METH_VARARGS),
METHOD(GetStore, METH_VARARGS),
@@ -10069,12 +10725,15 @@ static PyMethodDef GemRBMethods[] = {
METHOD(GetStoreCure, METH_VARARGS),
METHOD(GetStoreItem, METH_VARARGS),
METHOD(GetSpell, METH_VARARGS),
+ METHOD(GetSpelldata, METH_VARARGS),
+ METHOD(GetSpelldataIndex, METH_VARARGS),
METHOD(GetSlotItem, METH_VARARGS),
METHOD(GetSlots, METH_VARARGS),
METHOD(GetSystemVariable, METH_VARARGS),
METHOD(GetToken, METH_VARARGS),
METHOD(GetVar, METH_VARARGS),
METHOD(HardEndPL, METH_NOARGS),
+ METHOD(HasFeat, METH_VARARGS),
METHOD(HasResource, METH_VARARGS),
METHOD(HasSpecialItem, METH_VARARGS),
METHOD(HasSpecialSpell, METH_VARARGS),
@@ -10094,6 +10753,7 @@ static PyMethodDef GemRBMethods[] = {
METHOD(LoadWindowPack, METH_VARARGS),
METHOD(LoadWindow, METH_VARARGS),
METHOD(LoadWindowFrame, METH_VARARGS),
+ METHOD(Log, METH_VARARGS),
METHOD(MemorizeSpell, METH_VARARGS),
METHOD(ModifyEffect, METH_VARARGS),
METHOD(MoveToArea, METH_VARARGS),
@@ -10109,8 +10769,10 @@ static PyMethodDef GemRBMethods[] = {
METHOD(Roll, METH_VARARGS),
METHOD(SaveCharacter, METH_VARARGS),
METHOD(SaveGame, METH_VARARGS),
+ METHOD(SaveConfig, METH_NOARGS),
METHOD(SetDefaultActions, METH_VARARGS),
METHOD(SetEquippedQuickSlot, METH_VARARGS),
+ METHOD(SetFeat, METH_VARARGS),
METHOD(SetFullScreen, METH_VARARGS),
METHOD(SetGamma, METH_VARARGS),
METHOD(SetGlobal, METH_VARARGS),
@@ -10141,6 +10803,7 @@ static PyMethodDef GemRBMethods[] = {
METHOD(SetTooltipDelay, METH_VARARGS),
METHOD(SetupMaze, METH_VARARGS),
METHOD(SetupQuickSlot, METH_VARARGS),
+ METHOD(SetupQuickSpell, METH_VARARGS),
METHOD(SetVar, METH_VARARGS),
METHOD(SoftEndPL, METH_NOARGS),
METHOD(SpellCast, METH_VARARGS),
@@ -10151,7 +10814,9 @@ static PyMethodDef GemRBMethods[] = {
METHOD(UnmemorizeSpell, METH_VARARGS),
METHOD(UpdateAmbientsVolume, METH_NOARGS),
METHOD(UpdateMusicVolume, METH_NOARGS),
+ METHOD(UpdateWorldMap, METH_VARARGS),
METHOD(UseItem, METH_VARARGS),
+ METHOD(ValidTarget, METH_VARARGS),
METHOD(VerbalConstant, METH_VARARGS),
// terminating entry
{NULL, NULL, 0, NULL}
@@ -10165,6 +10830,8 @@ static PyMethodDef GemRBInternalMethods[] = {
METHOD(Button_SetBorder, METH_VARARGS),
METHOD(Button_SetFlags, METH_VARARGS),
METHOD(Button_SetFont, METH_VARARGS),
+ METHOD(Button_SetAnchor, METH_VARARGS),
+ METHOD(Button_SetPushOffset, METH_VARARGS),
METHOD(Button_SetItemIcon, METH_VARARGS),
METHOD(Button_SetMOS, METH_VARARGS),
METHOD(Button_SetOverlay, METH_VARARGS),
@@ -10177,6 +10844,8 @@ static PyMethodDef GemRBInternalMethods[] = {
METHOD(Button_SetState, METH_VARARGS),
METHOD(Button_SetTextColor, METH_VARARGS),
METHOD(Control_AttachScrollBar, METH_VARARGS),
+ METHOD(Control_GetRect, METH_VARARGS),
+ METHOD(Control_HasAnimation, METH_VARARGS),
METHOD(Control_QueryText, METH_VARARGS),
METHOD(Control_SetAnimation, METH_VARARGS),
METHOD(Control_SetAnimationPalette, METH_VARARGS),
@@ -10188,6 +10857,7 @@ static PyMethodDef GemRBInternalMethods[] = {
METHOD(Control_SetTooltip, METH_VARARGS),
METHOD(Control_SetVarAssoc, METH_VARARGS),
METHOD(Control_TextArea_SetFlags, METH_VARARGS),
+ METHOD(Label_SetFont, METH_VARARGS),
METHOD(Label_SetTextColor, METH_VARARGS),
METHOD(Label_SetUseRGB, METH_VARARGS),
METHOD(SaveGame_GetDate, METH_VARARGS),
@@ -10220,6 +10890,7 @@ static PyMethodDef GemRBInternalMethods[] = {
METHOD(TextArea_SelectText, METH_VARARGS),
METHOD(TextArea_SetHistory, METH_VARARGS),
METHOD(TextEdit_ConvertEdit, METH_VARARGS),
+ METHOD(TextEdit_SetBackground, METH_VARARGS),
METHOD(TextEdit_SetBufferLength, METH_VARARGS),
METHOD(Window_CreateButton, METH_VARARGS),
METHOD(Window_CreateLabel, METH_VARARGS),
@@ -10229,6 +10900,7 @@ static PyMethodDef GemRBInternalMethods[] = {
METHOD(Window_CreateWorldMapControl, METH_VARARGS),
METHOD(Window_DeleteControl, METH_VARARGS),
METHOD(Window_GetControl, METH_VARARGS),
+ METHOD(Window_GetRect, METH_VARARGS),
METHOD(Window_HasControl, METH_VARARGS),
METHOD(Window_Invalidate, METH_VARARGS),
METHOD(Window_SetFrame, METH_VARARGS),
@@ -10238,9 +10910,9 @@ static PyMethodDef GemRBInternalMethods[] = {
METHOD(Window_SetVisible, METH_VARARGS),
METHOD(Window_SetupControls, METH_VARARGS),
METHOD(Window_SetupEquipmentIcons, METH_VARARGS),
- METHOD(Window_SetupSpellIcons, METH_VARARGS),
METHOD(Window_ShowModal, METH_VARARGS),
METHOD(Window_Unload, METH_VARARGS),
+ METHOD(Window_UpdateVarAssoc, METH_VARARGS),
METHOD(WorldMap_AdjustScrolling, METH_VARARGS),
METHOD(WorldMap_GetDestinationArea, METH_VARARGS),
METHOD(WorldMap_SetTextColor, METH_VARARGS),
@@ -10350,7 +11022,7 @@ bool GUIScript::Init(void)
sprintf( string, "import sys" );
if (PyRun_SimpleString( string ) == -1) {
- printMessage( "GUIScript", string, RED );
+ Log(ERROR, "GUIScript", "Error running: %s", string);
return false;
}
@@ -10367,20 +11039,20 @@ bool GUIScript::Init(void)
// Add generic script path early, so GameType detection works
sprintf( string, "sys.path.append(\"%s\")", QuotePath( quoted, path ));
if (PyRun_SimpleString( string ) == -1) {
- printMessage( "GUIScript", string, RED );
+ Log(ERROR, "GUIScript", "Error running: %s", string);
return false;
}
sprintf( string, "import GemRB\n");
if (PyRun_SimpleString( "import GemRB" ) == -1) {
- printMessage( "GUIScript", string, RED );
+ Log(ERROR, "GUIScript", "Error running: %s", string);
return false;
}
// FIXME: better would be to add GemRB.GetGamePath() or some such
sprintf( string, "GemRB.GamePath = \"%s\"", QuotePath( quoted, core->GamePath ));
if (PyRun_SimpleString( string ) == -1) {
- printMessage( "GUIScript", string, RED );
+ Log(ERROR, "GUIScript", "Error running: %s", string);
return false;
}
@@ -10397,15 +11069,15 @@ bool GUIScript::Init(void)
}
// GameType-specific import path must have a higher priority than
- // the generic one, so insert it before it
+ // the generic one, so insert it before it
sprintf( string, "sys.path.insert(-1, \"%s\")", QuotePath( quoted, path2 ));
if (PyRun_SimpleString( string ) == -1) {
- printMessage( "GUIScript", string, RED );
+ Log(ERROR, "GUIScript", "Error running: %s", string );
return false;
}
sprintf( string, "GemRB.GameType = \"%s\"", core->GameType);
if (PyRun_SimpleString( string ) == -1) {
- printMessage( "GUIScript", string, RED );
+ Log(ERROR, "GUIScript", "Error running: %s", string );
return false;
}
@@ -10417,20 +11089,17 @@ bool GUIScript::Init(void)
#endif
if (PyRun_SimpleString( "from GUIDefines import *" ) == -1) {
- printMessage( "GUIScript", " ", RED );
- printf("Check if %s/GUIDefines.py exists! ", path);
+ Log(ERROR, "GUIScript", "Check if %s/GUIDefines.py exists!", path);
return false;
}
if (PyRun_SimpleString( "from GUIClasses import *" ) == -1) {
- printMessage( "GUIScript", " ", RED );
- printf("Check if %s/GUIClasses.py exists! ", path);
+ Log(ERROR, "GUIScript", "Check if %s/GUIClasses.py exists!", path);
return false;
}
if (PyRun_SimpleString( "from GemRB import *" ) == -1) {
- printMessage( "GUIScript", " ", RED );
- printf("builtin GemRB module failed to load!!! ");
+ Log(ERROR, "GUIScript", "builtin GemRB module failed to load!!!");
return false;
}
@@ -10455,7 +11124,7 @@ bool GUIScript::Init(void)
bool GUIScript::Autodetect(void)
{
- printMessage( "GUIScript", "Detecting GameType: ", WHITE);
+ Log(MESSAGE, "GUIScript", "Detecting GameType.");
char path[_MAX_PATH];
PathJoin( path, core->GUIScriptsPath, "GUIScripts", NULL );
@@ -10470,7 +11139,7 @@ bool GUIScript::Autodetect(void)
const char *dirent = iter.GetName();
char module[_MAX_PATH];
- //printf("DE: %s\n", dirent);
+ //print("DE: %s", dirent);
if (iter.IsDirectory() && dirent[0] != '.') {
// NOTE: these methods subtly differ in sys.path content, need for __init__.py files ...
// Method1:
@@ -10484,12 +11153,12 @@ bool GUIScript::Autodetect(void)
} while (++iter);
if (gametype_hint[0]) {
- printStatus(gametype_hint, GREEN);
+ Log(MESSAGE, "GUIScript", "Detected GameType: %s", gametype_hint);
strcpy(core->GameType, gametype_hint);
return true;
}
else {
- printStatus("ERROR", LIGHT_RED);
+ Log(ERROR, "GUIScript", "Failed to detect game type.");
return false;
}
}
@@ -10499,8 +11168,7 @@ bool GUIScript::LoadScript(const char* filename)
if (!Py_IsInitialized()) {
return false;
}
- printMessage( "GUIScript", "Loading Script ", WHITE );
- printf( "%s...", filename );
+ Log(MESSAGE, "GUIScript", "Loading Script %s.", filename);
char path[_MAX_PATH];
strcpy( path, filename );
@@ -10508,7 +11176,7 @@ bool GUIScript::LoadScript(const char* filename)
PyObject *pName = PyString_FromString( filename );
/* Error checking of pName left out */
if (pName == NULL) {
- printStatus( "ERROR", LIGHT_RED );
+ Log(ERROR, "GUIScript", "Failed to create filename for script \"%s\".", filename);
return false;
}
@@ -10526,91 +11194,90 @@ bool GUIScript::LoadScript(const char* filename)
/* pDict is a borrowed reference */
} else {
PyErr_Print();
- printStatus( "ERROR", LIGHT_RED );
+ Log(ERROR, "GUIScript", "Failed to load script \"%s\".", filename);
return false;
}
- printStatus( "OK", LIGHT_GREEN );
return true;
}
-/* Similar to RunFunction, but with parameters, and doesn't necessarily fails */
-PyObject *GUIScript::CallbackFunction(const char* fname, PyObject* pArgs)
+/* Similar to RunFunction, but with parameters, and doesn't necessarily fail */
+PyObject *GUIScript::RunFunction(const char* moduleName, const char* functionName, PyObject* pArgs, bool report_error)
{
if (!Py_IsInitialized()) {
return NULL;
}
- if (pDict == NULL) {
- return NULL;
- }
- PyObject *pFunc = PyDict_GetItemString( pDict, (char *) fname );
- /* pFunc: Borrowed reference */
- if (( !pFunc ) || ( !PyCallable_Check( pFunc ) )) {
- printMessage("GUIScript", " ", LIGHT_RED);
- printf("%s is not callable!\n", fname);
- return NULL;
- }
- PyObject *pValue = PyObject_CallObject( pFunc, pArgs );
- if (pValue == NULL) {
- if (PyErr_Occurred()) {
- PyErr_Print();
- }
- }
- return pValue;
-}
-
-bool GUIScript::RunFunction(const char *ModuleName, const char* FunctionName, bool error, int intparam)
-{
- if (!Py_IsInitialized()) {
- return false;
- }
PyObject *module;
- if (ModuleName) {
- module = PyImport_ImportModule(const_cast<char*> (ModuleName) );
+ if (moduleName) {
+ module = PyImport_ImportModule(const_cast<char*>(moduleName));
} else {
module = pModule;
Py_XINCREF(module);
}
if (module == NULL) {
PyErr_Print();
- return false;
+ return NULL;
}
PyObject *dict = PyModule_GetDict(module);
- PyObject *pFunc = PyDict_GetItemString( dict, const_cast<char*>(FunctionName) );
+ PyObject *pFunc = PyDict_GetItemString(dict, const_cast<char*>(functionName));
/* pFunc: Borrowed reference */
- if (( !pFunc ) || ( !PyCallable_Check( pFunc ) )) {
- if (error) {
- printMessage( "GUIScript", "Missing function:", LIGHT_RED );
- printf("%s\n", FunctionName);
+ if (!pFunc || !PyCallable_Check(pFunc)) {
+ if (report_error) {
+ Log(ERROR, "GUIScript", "Missing function: %s from %s", functionName, moduleName);
}
Py_DECREF(module);
- return false;
+ return NULL;
+ }
+ PyObject *pValue = PyObject_CallObject( pFunc, pArgs );
+ if (pValue == NULL) {
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ }
}
+ Py_DECREF(module);
+ return pValue;
+}
+
+bool GUIScript::RunFunction(const char *moduleName, const char* functionName, bool report_error, int intparam)
+{
PyObject *pArgs;
if (intparam == -1) {
pArgs = NULL;
} else {
pArgs = Py_BuildValue("(i)", intparam);
}
- PyObject *pValue = PyObject_CallObject( pFunc, pArgs );
- Py_XDECREF( pArgs );
+ PyObject *pValue = RunFunction(moduleName, functionName, pArgs, report_error);
+ Py_XDECREF(pArgs);
if (pValue == NULL) {
if (PyErr_Occurred()) {
PyErr_Print();
}
- Py_DECREF(module);
return false;
}
- Py_DECREF( pValue );
- Py_DECREF(module);
+ Py_DECREF(pValue);
+ return true;
+}
+
+bool GUIScript::RunFunction(const char *moduleName, const char* functionName, bool report_error, Point param)
+{
+ PyObject *pArgs = Py_BuildValue("(ii)", param.x, param.y);
+ PyObject *pValue = RunFunction(moduleName, functionName, pArgs, report_error);
+ Py_XDECREF(pArgs);
+ if (pValue == NULL) {
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ }
+ return false;
+ }
+ Py_DECREF(pValue);
return true;
}
void GUIScript::ExecFile(const char* file)
{
FileStream fs;
- if (!fs.Open(file, true))
+ if (!fs.Open(file))
return;
int len = fs.Remains();
@@ -10678,3 +11345,4 @@ PyObject* GUIScript::ConstructObject(const char* type, PyObject* pArgs)
GEMRB_PLUGIN(0x1B01BE6B, "GUI Script Engine (Python)")
PLUGIN_CLASS(IE_GUI_SCRIPT_CLASS_ID, GUIScript)
END_PLUGIN()
+
diff --git a/gemrb/plugins/GUIScript/GUIScript.h b/gemrb/plugins/GUIScript/GUIScript.h
index 05d8bfd..ab6d86b 100644
--- a/gemrb/plugins/GUIScript/GUIScript.h
+++ b/gemrb/plugins/GUIScript/GUIScript.h
@@ -33,6 +33,8 @@
#include "ScriptEngine.h"
+namespace GemRB {
+
#define SV_BPP 0
#define SV_WIDTH 1
#define SV_HEIGHT 2
@@ -52,17 +54,20 @@ public:
/** Load Script */
bool LoadScript(const char* filename);
/** Run Function */
- bool RunFunction(const char *module, const char* fname, bool error=true, int intparam=-1);
+ bool RunFunction(const char *module, const char* fname, bool report_error=true, int intparam=-1);
+ bool RunFunction(const char *module, const char* fname, bool report_error, Point param);
/** Exec a single File */
void ExecFile(const char* file);
/** Exec a single String */
void ExecString(const char* string);
/** lets hope this one can be here without screwing up the general interface */
- PyObject *CallbackFunction(const char* fname, PyObject* pArgs);
+ PyObject *RunFunction(const char* moduleName, const char* fname, PyObject* pArgs, bool report_error = true);
PyObject* ConstructObject(const char* classname, int arg);
PyObject* ConstructObject(const char* classname, PyObject* pArgs);
};
extern GUIScript *gs;
+}
+
#endif
diff --git a/gemrb/plugins/GUIScript/PythonHelpers.cpp b/gemrb/plugins/GUIScript/PythonHelpers.cpp
index f1c27a3..9384cec 100644
--- a/gemrb/plugins/GUIScript/PythonHelpers.cpp
+++ b/gemrb/plugins/GUIScript/PythonHelpers.cpp
@@ -20,6 +20,8 @@
#include "PythonHelpers.h"
+using namespace GemRB;
+
static bool CallPython(PyObject *Function, PyObject *args = NULL)
{
if (!Function) {
diff --git a/gemrb/plugins/GUIScript/PythonHelpers.h b/gemrb/plugins/GUIScript/PythonHelpers.h
index 85fbe21..f7164d4 100644
--- a/gemrb/plugins/GUIScript/PythonHelpers.h
+++ b/gemrb/plugins/GUIScript/PythonHelpers.h
@@ -28,6 +28,8 @@
#include "Holder.h"
#include "Interface.h"
+namespace GemRB {
+
struct PythonCallback : public Callback {
public:
PythonCallback(PyObject *Function);
@@ -69,7 +71,7 @@ public:
else
PyErr_Clear();
if (!PyCObject_Check(obj) || PyCObject_GetDesc(obj) != const_cast<TypeID*>(&T::ID)) {
- printMessage("GUIScript","Bad CObject extracted.\n",LIGHT_RED);
+ Log(ERROR, "GUIScript", "Bad CObject extracted.");
Py_XDECREF(id);
return;
}
@@ -90,7 +92,7 @@ private:
static void PyRelease(void *obj, void *desc)
{
if (desc != const_cast<TypeID*>(&T::ID)) {
- printMessage("GUIScript","Bad CObject deleted.\n",LIGHT_RED);
+ Log(ERROR, "GUIScript", "Bad CObject deleted.");
return;
}
static_cast<T*>(obj)->release();
@@ -109,4 +111,6 @@ PyObject* MakePyList(const Container &source)
return list;
}
+}
+
#endif
diff --git a/gemrb/plugins/IDSImporter/IDSImporter.cpp b/gemrb/plugins/IDSImporter/IDSImporter.cpp
index 254582b..6a5c0e3 100644
--- a/gemrb/plugins/IDSImporter/IDSImporter.cpp
+++ b/gemrb/plugins/IDSImporter/IDSImporter.cpp
@@ -27,33 +27,24 @@
#include <cstring>
+using namespace GemRB;
+
IDSImporter::IDSImporter(void)
{
- str = NULL;
- autoFree = false;
}
IDSImporter::~IDSImporter(void)
{
- if (str && autoFree) {
- delete( str );
- }
-
for (unsigned int i = 0; i < ptrs.size(); i++) {
free( ptrs[i] );
}
}
-bool IDSImporter::Open(DataStream* stream, bool autoFree)
+bool IDSImporter::Open(DataStream* str)
{
- if (stream == NULL) {
- return false;
- }
- if (str) {
+ if (str == NULL) {
return false;
}
- str = stream;
- this->autoFree = autoFree;
str->CheckEncrypted();
char tmp[11];
@@ -89,6 +80,7 @@ bool IDSImporter::Open(DataStream* stream, bool autoFree)
}
}
+ delete str;
return true;
}
diff --git a/gemrb/plugins/IDSImporter/IDSImporter.h b/gemrb/plugins/IDSImporter/IDSImporter.h
index d91daf2..f27101e 100644
--- a/gemrb/plugins/IDSImporter/IDSImporter.h
+++ b/gemrb/plugins/IDSImporter/IDSImporter.h
@@ -23,6 +23,10 @@
#include "SymbolMgr.h"
+#include <vector>
+
+namespace GemRB {
+
struct Pair {
int val;
char* str;
@@ -30,16 +34,13 @@ struct Pair {
class IDSImporter : public SymbolMgr {
private:
- DataStream* str;
- bool autoFree;
-
std::vector< Pair> pairs;
std::vector< char*> ptrs;
public:
IDSImporter(void);
~IDSImporter(void);
- bool Open(DataStream* stream, bool autoFree = true);
+ bool Open(DataStream* stream);
int GetValue(const char* txt) const;
char* GetValue(int val) const;
char* GetStringIndex(unsigned int Index) const;
@@ -50,4 +51,6 @@ public:
};
#endif
+}
+
diff --git a/gemrb/plugins/IDSImporter/IDSImporterDefs.h b/gemrb/plugins/IDSImporter/IDSImporterDefs.h
index 68e4af8..837053f 100644
--- a/gemrb/plugins/IDSImporter/IDSImporterDefs.h
+++ b/gemrb/plugins/IDSImporter/IDSImporterDefs.h
@@ -18,6 +18,8 @@
*
*/
+namespace GemRB {
+
#define MAX_LINES 400
#define MAX_VALUE_LENGTH 20
#define MAX_TEXT_LENGTH 60 // maximum text length in case IDS file doesn't specify
@@ -30,8 +32,4 @@
#define HEADER_RECORD 4
#define HEADER_ERROR -1
-// need to transfer this to a header file in the includes dir:
-//#define IDS_VALUE_NOT_LOCATED -65535 // GetValue returns this if text is not found in arrays ... this needs to be a unique number that does not exist in the value[] array
-
-// need to transfer this to a header file in the includes dir too:
-//#define GEM_ENCRYPTION_KEY "\x88\xa8\x8f\xba\x8a\xd3\xb9\xf5\xed\xb1\xcf\xea\xaa\xe4\xb5\xfb\xeb\x82\xf9\x90\xca\xc9\xb5\xe7\xdc\x8e\xb7\xac\xee\xf7\xe0\xca\x8e\xea\xca\x80\xce\xc5\xad\xb7\xc4\xd0\x84\x93\xd5\xf0\xeb\xc8\xb4\x9d\xcc\xaf\xa5\x95\xba\x99\x87\xd2\x9d\xe3\x91\xba\x90\xca"
+}
diff --git a/gemrb/plugins/INIImporter/INIImporter.cpp b/gemrb/plugins/INIImporter/INIImporter.cpp
index e2b252a..25f3dc8 100644
--- a/gemrb/plugins/INIImporter/INIImporter.cpp
+++ b/gemrb/plugins/INIImporter/INIImporter.cpp
@@ -24,31 +24,23 @@
#include "Interface.h"
+using namespace GemRB;
+
INIImporter::INIImporter(void)
{
- str = NULL;
- autoFree = false;
}
INIImporter::~INIImporter(void)
{
- if (str && autoFree) {
- delete( str );
- }
for (unsigned int i = 0; i < tags.size(); i++)
delete( tags[i] );
}
-bool INIImporter::Open(DataStream* stream, bool autoFree)
+bool INIImporter::Open(DataStream* str)
{
- if (stream == NULL) {
+ if (str == NULL) {
return false;
}
- if (str && this->autoFree) {
- delete( str );
- }
- str = stream;
- this->autoFree = autoFree;
int cnt = 0;
char* strbuf = ( char* ) malloc( 4097 );
INITag* lastTag = NULL;
@@ -79,12 +71,13 @@ bool INIImporter::Open(DataStream* stream, bool autoFree)
if (lastTag == NULL)
continue;
if (lastTag->AddLine( strbuf )) {
- printMessage("INIImporter","", LIGHT_RED);
- printf("Bad Line in file: %s, Section: [%s], Entry: '%s'\n", stream->filename, lastTag->GetTagName(), strbuf);
+ Log(ERROR, "INIImporter", "Bad Line in file: %s, Section: [%s], Entry: '%s'",
+ str->filename, lastTag->GetTagName(), strbuf);
}
} while (true);
free( strbuf );
+ delete str;
return true;
}
diff --git a/gemrb/plugins/INIImporter/INIImporter.h b/gemrb/plugins/INIImporter/INIImporter.h
index 46c0320..9651653 100644
--- a/gemrb/plugins/INIImporter/INIImporter.h
+++ b/gemrb/plugins/INIImporter/INIImporter.h
@@ -26,6 +26,9 @@
#include "globals.h"
#include <cstring>
+#include <vector>
+
+namespace GemRB {
struct INIPair {
char* Name, * Value;
@@ -180,14 +183,12 @@ public:
class INIImporter : public DataFileMgr {
private:
- DataStream* str;
- bool autoFree;
std::vector< INITag*> tags;
public:
INIImporter(void);
~INIImporter(void);
- bool Open(DataStream* stream, bool autoFree = true);
+ bool Open(DataStream* stream);
int GetTagsCount() const
{
return ( int ) tags.size();
@@ -209,4 +210,6 @@ public:
const bool Default) const;
};
+}
+
#endif
diff --git a/gemrb/plugins/ITMImporter/ITMImporter.cpp b/gemrb/plugins/ITMImporter/ITMImporter.cpp
index 742528a..b107b08 100644
--- a/gemrb/plugins/ITMImporter/ITMImporter.cpp
+++ b/gemrb/plugins/ITMImporter/ITMImporter.cpp
@@ -24,31 +24,71 @@
#include "EffectMgr.h"
#include "Interface.h"
+#include "PluginMgr.h"
+#include "TableMgr.h" //needed for autotable
+
+using namespace GemRB;
+
+int *profs = NULL;
+int profcount = -1;
+
+//cannot call this at the time of initialization because the tablemanager isn't alive yet
+static void Initializer()
+{
+ if (profs) {
+ free(profs);
+ profs = NULL;
+ }
+ profcount = 0;
+ AutoTable tm("proftype");
+ if (!tm) {
+ Log(ERROR, "ITMImporter", "Cannot find proftype.2da.");
+ return;
+ }
+ profcount = tm->GetRowCount();
+ profs = (int *) calloc( profcount, sizeof(int) );
+ for (int i = 0; i < profcount; i++) {
+ profs[i] = atoi(tm->QueryField( i, 0 ) );
+ }
+}
+
+static void ReleaseMemoryITM()
+{
+ free(profs);
+ profs = NULL;
+ profcount = -1;
+}
+
+static int GetProficiency(ieDword ItemType)
+{
+ if (profcount<0) {
+ Initializer();
+ }
+
+ if (ItemType>=(ieDword) profcount) {
+ return 0;
+ }
+ return profs[ItemType];
+}
ITMImporter::ITMImporter(void)
{
str = NULL;
- autoFree = false;
}
ITMImporter::~ITMImporter(void)
{
- if (autoFree) {
- delete str;
- }
+ delete str;
str = NULL;
}
-bool ITMImporter::Open(DataStream* stream, bool autoFree)
+bool ITMImporter::Open(DataStream* stream)
{
if (stream == NULL) {
return false;
}
- if (this->autoFree) {
- delete str;
- }
+ delete str;
str = stream;
- this->autoFree = autoFree;
char Signature[8];
str->Read( Signature, 8 );
if (strncmp( Signature, "ITM V1 ", 8 ) == 0) {
@@ -58,7 +98,7 @@ bool ITMImporter::Open(DataStream* stream, bool autoFree)
} else if (strncmp( Signature, "ITM V2.0", 8 ) == 0) {
version = 20;
} else {
- printf( "[ITMImporter]: This file is not a valid ITM File\n" );
+ print("[ITMImporter]: This file is not a valid ITM File");
return false;
}
@@ -100,10 +140,22 @@ Item* ITMImporter::GetItem(Item *s)
s->KitUsability=(k1<<24) | (k2<<16) | (k3<<8) | k4; //bg2/iwd2 specific
str->Read( &s->MinConstitution, 1 );
str->Read( &s->WeaProf, 1 ); //bg2 specific
+
+ //hack for non bg2 weapon proficiencies
+ if (!s->WeaProf) {
+ s->WeaProf = GetProficiency(s->ItemType);
+ }
+
str->Read( &s->MinCharisma, 1 );
str->Read( &s->unknown3, 1 );
str->ReadDword( &s->Price );
- str->ReadWord( &s->StackAmount );
+ str->ReadWord( &s->MaxStackAmount );
+
+ //hack for non stacked items, so MaxStackAmount could be used as a boolean
+ if (s->MaxStackAmount==1) {
+ s->MaxStackAmount = 0;
+ }
+
str->ReadResRef( s->ItemIcon );
str->ReadWord( &s->LoreToID );
str->ReadResRef( s->GroundIcon );
@@ -162,12 +214,16 @@ Item* ITMImporter::GetItem(Item *s)
if (!core->IsAvailable( IE_BAM_CLASS_ID )) {
- printf( "[ITMImporter]: No BAM Importer Available.\n" );
+ print("[ITMImporter]: No BAM Importer Available.");
return NULL;
}
return s;
}
+//unfortunately, i couldn't avoid this hack, unless adding another array
+#define IT_DAGGER 0x10
+#define IT_SHORTSWORD 0x13
+
void ITMImporter::GetExtHeader(Item *s, ITMExtHeader* eh)
{
ieByte tmpByte;
@@ -198,6 +254,10 @@ void ITMImporter::GetExtHeader(Item *s, ITMExtHeader* eh)
str->ReadWord( &eh->Charges );
str->ReadWord( &eh->ChargeDepletion );
str->ReadDword( &eh->RechargeFlags );
+
+ //hack for default weapon finesse
+ if (s->ItemType==IT_DAGGER || s->ItemType==IT_SHORTSWORD) eh->RechargeFlags^=IE_ITEM_USEDEXTERITY;
+
str->ReadWord( &eh->ProjectileAnimation );
//for some odd reasons 0 and 1 are the same
if (eh->ProjectileAnimation) {
@@ -252,4 +312,5 @@ void ITMImporter::GetFeature(Effect *fx)
GEMRB_PLUGIN(0xD913A54, "ITM File Importer")
PLUGIN_CLASS(IE_ITM_CLASS_ID, ITMImporter)
+PLUGIN_CLEANUP(ReleaseMemoryITM)
END_PLUGIN()
diff --git a/gemrb/plugins/ITMImporter/ITMImporter.h b/gemrb/plugins/ITMImporter/ITMImporter.h
index c188a5c..adc7946 100644
--- a/gemrb/plugins/ITMImporter/ITMImporter.h
+++ b/gemrb/plugins/ITMImporter/ITMImporter.h
@@ -27,6 +27,8 @@
#include "Item.h"
+namespace GemRB {
+
#define ITM_VER_BG 10
#define ITM_VER_PST 11
#define ITM_VER_IWD2 20
@@ -34,13 +36,12 @@
class ITMImporter : public ItemMgr {
private:
DataStream* str;
- bool autoFree;
int version;
public:
ITMImporter(void);
~ITMImporter(void);
- bool Open(DataStream* stream, bool autoFree = true);
+ bool Open(DataStream* stream);
Item* GetItem(Item *s);
private:
void GetExtHeader(Item *s, ITMExtHeader* eh);
@@ -48,4 +49,6 @@ private:
};
+}
+
#endif
diff --git a/gemrb/plugins/IWDOpcodes/IWDOpcodes.cpp b/gemrb/plugins/IWDOpcodes/IWDOpcodes.cpp
index e55f636..07de3e6 100644
--- a/gemrb/plugins/IWDOpcodes/IWDOpcodes.cpp
+++ b/gemrb/plugins/IWDOpcodes/IWDOpcodes.cpp
@@ -35,6 +35,8 @@
#include "Scriptable/Actor.h"
#include "GameScript/GSUtils.h" //needs for displaystringcore
+using namespace GemRB;
+
static const ieResRef SevenEyes[7]={"spin126","spin127","spin128","spin129","spin130","spin131","spin132"};
static bool enhanced_effects = false;
@@ -49,6 +51,7 @@ static Trigger *Enemy = NULL;
#define PI_NAUSEA 43
#define PI_HOPELESSNESS 44
#define PI_STONESKIN 46
+#define PI_TENSER 55
#define PI_RIGHTEOUS 67
#define PI_ELEMENTS 76
#define PI_FAITHARMOR 84
@@ -79,8 +82,19 @@ static Trigger *Enemy = NULL;
#define PI_TORTOISE 125
#define PI_BLINK 130
+
+#define PI_DAYBLINDNESS 137
+#define PI_HEROIC 138
+
#define PI_EMPTYBODY 145
+//These settings are saved in the V2.2 chr struct in IWD2
+#define ES_EXPERTISE 3
+#define ES_POWERATTACK 4
+#define ES_ARTERIAL 5
+#define ES_HAMSTRING 6
+#define ES_RAPIDSHOT 7
+
static int fx_ac_vs_damage_type_modifier_iwd2 (Scriptable* Owner, Actor* target, Effect* fx);//0
static int fx_damage_bonus_modifier (Scriptable* Owner, Actor* target, Effect* fx);//49
static int fx_draw_upon_holy_might (Scriptable* Owner, Actor* target, Effect* fx);//84 (iwd2)
@@ -136,7 +150,6 @@ static int fx_soul_eater (Scriptable* Owner, Actor* target, Effect* fx);//115
static int fx_shroud_of_flame (Scriptable* Owner, Actor* target, Effect* fx);//116
static int fx_shroud_of_flame2 (Scriptable* Owner, Actor* target, Effect* fx);//116
static int fx_animal_rage (Scriptable* Owner, Actor* target, Effect* fx);//117
-static int fx_turn_undead (Scriptable* Owner, Actor* target, Effect* fx);//118
static int fx_turn_undead2 (Scriptable* Owner, Actor* target, Effect* fx);//118
static int fx_vitriolic_sphere (Scriptable* Owner, Actor* target, Effect* fx);//119
static int fx_suppress_hp (Scriptable* Owner, Actor* target, Effect* fx);//11a
@@ -158,6 +171,17 @@ static int fx_jackalwere_gaze (Scriptable* Owner, Actor* target, Effect* fx); //
//0x129 HideInShadows (same as bg2)
static int fx_use_magic_device_modifier (Scriptable* Owner, Actor* target, Effect* fx);//12a
+//iwd2 related, gemrb specific effects (IE. unhardcoded hacks)
+static int fx_animal_empathy_modifier (Scriptable* Owner, Actor* target, Effect* fx);//12b
+static int fx_bluff_modifier (Scriptable* Owner, Actor* target, Effect* fx);//12c
+static int fx_concentration_modifier (Scriptable* Owner, Actor* target, Effect* fx);//12d
+static int fx_diplomacy_modifier (Scriptable* Owner, Actor* target, Effect* fx);//12e
+static int fx_intimidate_modifier (Scriptable* Owner, Actor* target, Effect* fx);//12f
+static int fx_search_modifier (Scriptable* Owner, Actor* target, Effect* fx);//130
+static int fx_spellcraft_modifier (Scriptable* Owner, Actor* target, Effect* fx);//131
+//0x132 CriticalHitModifier (same as bg2, needed for improved criticals)
+static int fx_turnlevel_modifier (Scriptable* Owner, Actor* target, Effect* fx); //133
+
//iwd related, gemrb specific effects (IE. unhardcoded hacks)
static int fx_alter_animation (Scriptable* Owner, Actor *target, Effect* fx); //399
@@ -191,7 +215,7 @@ static int fx_protection_from_elements (Scriptable* Owner, Actor* target, Effect
static int fx_aegis (Scriptable* Owner, Actor* target, Effect* fx); //426
static int fx_executioner_eyes (Scriptable* Owner, Actor* target, Effect* fx); //427
//428 DeathMagic (same as 0xd)
-//429
+static int fx_effects_on_struck (Scriptable* Owner, Actor* target, Effect *fx);//429 (similar to 0xe8)
static int fx_projectile_use_effect_list (Scriptable* Owner, Actor* target, Effect* fx); //430
static int fx_energy_drain (Scriptable* Owner, Actor* target, Effect* fx); //431
static int fx_tortoise_shell (Scriptable* Owner, Actor* target, Effect* fx); //432
@@ -204,10 +228,10 @@ static int fx_heroic_inspiration (Scriptable* Owner, Actor* target, Effect* fx);
//static int fx_prevent_ai_slowdown (Scriptable* Owner, Actor* target, Effect* fx); //439
static int fx_barbarian_rage (Scriptable* Owner, Actor* target, Effect* fx); //440
//441 MovementRateModifier4
-//442 unknown
+static int fx_cleave (Scriptable* Owner, Actor* target, Effect* fx); //442
static int fx_missile_damage_reduction (Scriptable* Owner, Actor* target, Effect* fx); //443
static int fx_tenser_transformation (Scriptable* Owner, Actor* target, Effect* fx); //444
-//static int fx_445 (Scriptable* Owner, Actor* target, Effect* fx); //445 unused
+static int fx_slippery_mind (Scriptable* Owner, Actor* target, Effect* fx); //445
static int fx_smite_evil (Scriptable* Owner, Actor* target, Effect* fx); //446
static int fx_restoration (Scriptable* Owner, Actor* target, Effect* fx); //447
static int fx_alicorn_lance (Scriptable* Owner, Actor* target, Effect* fx); //448
@@ -224,12 +248,11 @@ static int fx_rapid_shot (Scriptable* Owner, Actor* target, Effect* fx); //457
//No need to make these ordered, they will be ordered by EffectQueue
static EffectDesc effectnames[] = {
{ "ACVsDamageTypeModifierIWD2", fx_ac_vs_damage_type_modifier_iwd2, 0, -1 }, //0
- { "DamageBonusModifier", fx_damage_bonus_modifier, 0, -1 }, //49
+ { "DamageBonusModifier2", fx_damage_bonus_modifier, 0, -1 }, //49
{ "DrawUponHolyMight", fx_draw_upon_holy_might, 0, -1 },//84 (iwd2)
- { "RetreatFrom", fx_turn_undead, 0, -1 },//6e
{ "IronSkins", fx_ironskins, 0, -1 }, //da (iwd2)
{ "Color:FadeRGB", fx_fade_rgb, 0, -1 }, //e8
- { "IWDVisualSpellHit", fx_iwd_visual_spell_hit, 0, -1 }, //e9
+ { "IWDVisualSpellHit", fx_iwd_visual_spell_hit, EFFECT_NO_ACTOR, -1 }, //e9
{ "ColdDamage", fx_cold_damage, EFFECT_DICED, -1 }, //ea
{ "ChillTouch", fx_chill_touch, 0, -1 }, //ec (how)
{ "ChillTouchPanic", fx_chill_touch_panic, 0, -1 }, //ec (iwd2)
@@ -272,7 +295,6 @@ static EffectDesc effectnames[] = {
{ "ShroudOfFlame", fx_shroud_of_flame, 0, -1 },//116
{ "ShroudOfFlame2", fx_shroud_of_flame2, 0, -1 },//116
{ "AnimalRage", fx_animal_rage, 0, -1 }, //117 - berserk?
- { "TurnUndead", fx_turn_undead, 0, -1 }, //118 how
{ "TurnUndead2", fx_turn_undead2, 0, -1 }, //118 iwd2
{ "VitriolicSphere", fx_vitriolic_sphere, EFFECT_DICED, -1 }, //119
{ "SuppressHP", fx_suppress_hp, 0, -1 }, //11a -- some stat???
@@ -287,6 +309,15 @@ static EffectDesc effectnames[] = {
{ "HarpyWail", fx_harpy_wail, 0, -1 }, //126
{ "JackalWereGaze", fx_jackalwere_gaze, 0, -1 }, //127
{ "UseMagicDeviceModifier", fx_use_magic_device_modifier, 0, -1 }, //12a
+ //unhardcoded hacks for IWD2
+ { "AnimalEmpathyModifier", fx_animal_empathy_modifier, 0, -1 },//12b
+ { "BluffModifier", fx_bluff_modifier, 0, -1 },//12c
+ { "ConcentrationModifier", fx_concentration_modifier, 0, -1 },//12d
+ { "DiplomacyModifier", fx_diplomacy_modifier, 0, -1 },//12e
+ { "IntimidateModifier", fx_intimidate_modifier, 0, -1 },//12f
+ { "SearchModifier", fx_search_modifier, 0, -1 },//130
+ { "SpellcraftModifier", fx_spellcraft_modifier, 0, -1 },//131
+ { "TurnLevelModifier", fx_turnlevel_modifier, 0, -1 },//133
//unhardcoded hacks for IWD
{ "AlterAnimation", fx_alter_animation, EFFECT_NO_ACTOR, -1 }, //399
//iwd2 effects
@@ -316,6 +347,7 @@ static EffectDesc effectnames[] = {
{ "ControlUndead2", fx_control_undead, 0, -1 }, //425
{ "Aegis", fx_aegis, 0, -1 }, //426
{ "ExecutionerEyes", fx_executioner_eyes, 0, -1 }, //427
+ { "EffectsOnStruck", fx_effects_on_struck, 0, -1 }, //429
{ "ProjectileUseEffectList", fx_projectile_use_effect_list, 0, -1 }, //430
{ "EnergyDrain", fx_energy_drain, 0, -1 }, //431
{ "TortoiseShell", fx_tortoise_shell, 0, -1 }, //432
@@ -327,8 +359,10 @@ static EffectDesc effectnames[] = {
{ "HeroicInspiration", fx_heroic_inspiration, 0, -1 },//438
//{ "PreventAISlowDown", fx_prevent_ai_slowdown, 0, -1 }, //439 same as bg2
{ "BarbarianRage", fx_barbarian_rage, 0, -1 }, //440
+ { "Cleave", fx_cleave, 0, -1 }, //442
{ "MissileDamageReduction", fx_missile_damage_reduction, 0, -1 }, //443
{ "TensersTransformation", fx_tenser_transformation, 0, -1 }, //444
+ { "SlipperyMind", fx_slippery_mind, 0, -1 }, //445
{ "SmiteEvil", fx_smite_evil, 0, -1 }, //446
{ "Restoration", fx_restoration, 0, -1 }, //447
{ "AlicornLance", fx_alicorn_lance, 0, -1 }, //448
@@ -344,6 +378,31 @@ static EffectDesc effectnames[] = {
{ NULL, NULL, 0, 0 },
};
+//effect refs used in this module
+static EffectRef fx_charm_ref = { "Charm", -1 }; //5
+static EffectRef fx_cha_ref = { "CharismaModifier", -1 }; //0x6
+static EffectRef fx_con_ref = { "ConstitutionModifier", -1 }; //0xa
+static EffectRef fx_damage_opcode_ref = { "Damage", -1 }; //0xc
+static EffectRef fx_death_ref = { "Death", -1 }; //0xd
+static EffectRef fx_dex_ref = { "DexterityModifier", -1 }; //0xf
+static EffectRef fx_int_ref = { "IntelligenceModifier", -1 }; //0x13
+static EffectRef fx_poison_ref = { "Poison", -1 }; //0x19
+static EffectRef fx_unconscious_state_ref = { "State:Helpless", -1 }; //0x27
+static EffectRef fx_str_ref = { "StrengthModifier", -1 }; //0x2c
+static EffectRef fx_wis_ref = { "WisdomModifier", -1 }; //0x31
+static EffectRef fx_state_blind_ref = { "State:Blind", -1 }; //0x4a
+static EffectRef fx_disease_ref = { "State:Diseased", -1 }; //0x4e
+static EffectRef fx_confusion_ref = { "State:Confused", -1 }; //0x80
+static EffectRef fx_bless_ref = { "BlessNonCumulative", -1 }; //0x82
+static EffectRef fx_fear_ref = { "State:Panic", -1 }; //0xa1
+static EffectRef fx_hold_creature_ref = { "State:Hold", -1 }; //0xaf
+static EffectRef fx_resist_spell_ref = { "Protection:Spell2", -1 }; //0xce (IWD2)
+static EffectRef fx_iwd_visual_spell_hit_ref = { "IWDVisualSpellHit", -1 }; //0xe9
+static EffectRef fx_umberhulk_gaze_ref = { "UmberHulkGaze", -1 }; //0x100
+static EffectRef fx_protection_from_evil_ref = { "ProtectionFromEvil", -1 }; //401
+static EffectRef fx_wound_ref = { "BleedingWounds", -1 }; //416
+
+
struct IWDIDSEntry {
ieDword value;
ieWord stat;
@@ -414,8 +473,8 @@ static void ReadSpellProtTable(const ieResRef tablename)
return;
}
for( int i=0;i<spellrescnt;i++) {
- ieDword tmp = core->TranslateStat(tab->QueryField(i,0) );
- spellres[i].stat = (ieWord) tmp;
+ ieDword stat = core->TranslateStat(tab->QueryField(i,0) );
+ spellres[i].stat = (ieWord) stat;
spellres[i].value = (ieDword) strtol(tab->QueryField(i,1),NULL,0 );
spellres[i].relation = (ieWord) strtol(tab->QueryField(i,2),NULL,0 );
@@ -448,6 +507,7 @@ static int check_iwd_targeting(Scriptable* Owner, Actor* target, ieDword value,
ieDword idx = spellres[type].stat;
ieDword val = spellres[type].value;
+ ieDword rel = spellres[type].relation;
//if IDS value is 'anything' then the supplied value is in Parameter1
if (val==0xffffffff) {
val = value;
@@ -456,16 +516,19 @@ static int check_iwd_targeting(Scriptable* Owner, Actor* target, ieDword value,
case STI_INVALID:
return 0;
case STI_EA:
- return DiffCore(EARelation(Owner, target), val, spellres[type].relation);
+ return DiffCore(EARelation(Owner, target), val, rel);
case STI_DAYTIME:
- return (core->GetGame()->GameTime%7200/3600) != val;
+ {
+ ieDword timeofday = core->GetGame()->GameTime%7200/3600;
+ return timeofday>= val && timeofday<= rel;
+ }
case STI_AREATYPE:
- return DiffCore((ieDword) target->GetCurrentArea()->AreaType, val, spellres[type].relation);
+ return DiffCore((ieDword) target->GetCurrentArea()->AreaType, val, rel);
case STI_MORAL_ALIGNMENT:
if(Owner && Owner->Type==ST_ACTOR) {
- return DiffCore( ((Actor *) Owner)->GetStat(IE_ALIGNMENT)&AL_GE_MASK,STAT_GET(IE_ALIGNMENT)&AL_GE_MASK, spellres[type].relation);
+ return DiffCore( ((Actor *) Owner)->GetStat(IE_ALIGNMENT)&AL_GE_MASK,STAT_GET(IE_ALIGNMENT)&AL_GE_MASK, rel);
} else {
- return DiffCore(AL_TRUE_NEUTRAL,STAT_GET(IE_ALIGNMENT)&AL_GE_MASK, spellres[type].relation);
+ return DiffCore(AL_TRUE_NEUTRAL,STAT_GET(IE_ALIGNMENT)&AL_GE_MASK, rel);
}
case STI_TWO_ROWS:
//used in checks where any of two matches are ok (golem or undead etc)
@@ -488,7 +551,7 @@ static int check_iwd_targeting(Scriptable* Owner, Actor* target, ieDword value,
}
return 1;
case STI_CIRCLESIZE:
- return DiffCore((ieDword) target->GetAnims()->GetCircleSize(), val, spellres[type].relation);
+ return DiffCore((ieDword) target->GetAnims()->GetCircleSize(), val, rel);
case STI_EVASION:
if (target->GetThiefLevel() < 7 ) {
return 0;
@@ -499,17 +562,27 @@ static int check_iwd_targeting(Scriptable* Owner, Actor* target, ieDword value,
}
return 0;
default:
- return DiffCore(STAT_GET(idx), val, spellres[type].relation);
+ {
+ //subraces are not stand alone stats, actually, this hack should affect the CheckStat action too
+ ieDword stat = STAT_GET(idx);
+ if (idx==IE_SUBRACE) {
+ stat |= STAT_GET(IE_RACE)<<16;
+ }
+ return DiffCore(stat, val, rel);
+ }
}
}
//iwd got a hardcoded 'fireshield' system
//this effect applies damage on ALL nearby actors, except the center
-static EffectRef fx_damage_opcode_ref = { "Damage", -1 };
+//also in IWD2, a dragon with this aura
+//would probably not hurt anyone, because it is not using personaldistance
+//but a short range area projectile
static void ApplyDamageNearby(Scriptable* Owner, Actor* target, Effect *fx, ieDword damagetype)
{
- Effect *newfx = EffectQueue::CreateEffect(fx_damage_opcode_ref, fx->Parameter1, damagetype,FX_DURATION_INSTANT_PERMANENT);
+ Effect *newfx = EffectQueue::CreateEffect(fx_damage_opcode_ref, fx->Parameter1, damagetype<<16, FX_DURATION_INSTANT_PERMANENT);
+ newfx->Target = FX_TARGET_PRESET;
newfx->Power = fx->Power;
newfx->DiceThrown = fx->DiceThrown;
newfx->DiceSides = fx->DiceSides;
@@ -519,6 +592,7 @@ static void ApplyDamageNearby(Scriptable* Owner, Actor* target, Effect *fx, ieDw
int i = area->GetActorCount(true);
while(i--) {
Actor *victim = area->GetActor(i,true);
+ //not sure if this is needed
if (target==victim) continue;
if (PersonalDistance(target, victim)<20) {
//this function deletes newfx (not anymore)
@@ -549,11 +623,10 @@ static inline void HandleBonus(Actor *target, int stat, int mod, int mode)
}
// fx_ac_vs_damage_type_modifier_iwd2
+// the major difference from bg2 are the different type values and more AC types
int fx_ac_vs_damage_type_modifier_iwd2 (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_ac_vs_damage_type_modifier_iwd2 (%2d): AC Modif: %d ; Type: %d ; MinLevel: %d ; MaxLevel: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2, (int) fx->DiceSides, (int) fx->DiceThrown );
- //check level was pulled outside as a common functionality
- //CHECK_LEVEL();
+ if(0) print("fx_ac_vs_damage_type_modifier_iwd2(%2d): AC Modif: %d ; Type: %d ; MinLevel: %d ; MaxLevel: %d", fx->Opcode, fx->Parameter1, fx->Parameter2,(int) fx->DiceSides,(int) fx->DiceThrown);
// it is a bitmask
int type = fx->Parameter2;
@@ -562,33 +635,27 @@ int fx_ac_vs_damage_type_modifier_iwd2 (Scriptable* /*Owner*/, Actor* target, Ef
switch(type)
{
case 0: //generic
- HandleBonus(target, IE_ARMORCLASS, fx->Parameter1, fx->TimingMode);
+ target->AC.HandleFxBonus(fx->Parameter1, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
break;
case 1: //armor
- if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
- if (BASE_GET( IE_ARMORCLASS) > fx->Parameter1) {
- BASE_SET( IE_ARMORCLASS, fx->Parameter1 );
- }
- } else {
- if (STAT_GET( IE_ARMORCLASS) > fx->Parameter1) {
- STAT_SET( IE_ARMORCLASS, fx->Parameter1 );
- }
- }
- return FX_INSERT;
+ target->AC.SetArmorBonus(fx->Parameter1, 0);
+ break;
case 2: //deflection
+ target->AC.SetDeflectionBonus(fx->Parameter1, 0);
break;
case 3: //shield
+ target->AC.SetShieldBonus(fx->Parameter1, 0);
break;
- case 4:
+ case 4: // crushing
HandleBonus(target, IE_ACCRUSHINGMOD, fx->Parameter1, fx->TimingMode);
break;
- case 5:
+ case 5: // piercing
HandleBonus(target, IE_ACPIERCINGMOD, fx->Parameter1, fx->TimingMode);
break;
- case 6:
+ case 6: // slashing
HandleBonus(target, IE_ACSLASHINGMOD, fx->Parameter1, fx->TimingMode);
break;
- case 7:
+ case 7: // missile
HandleBonus(target, IE_ACMISSILEMOD, fx->Parameter1, fx->TimingMode);
break;
}
@@ -601,7 +668,7 @@ int fx_ac_vs_damage_type_modifier_iwd2 (Scriptable* /*Owner*/, Actor* target, Ef
// only the special type of 0 means a flat bonus
int fx_damage_bonus_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_damage_bonus_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_damage_bonus_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
switch (fx->Parameter2) {
case 0:
@@ -631,7 +698,7 @@ int fx_damage_bonus_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
// in bg2 the effect is called: HolyNonCumulative
int fx_draw_upon_holy_might (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_draw_upon_holy_might (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_draw_upon_holy_might(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (target->SetSpellState( SS_HOLYMIGHT)) return FX_NOT_APPLIED;
STAT_ADD( IE_STR, fx->Parameter1);
@@ -642,6 +709,7 @@ int fx_draw_upon_holy_might (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0xda IronSkins (iwd2)
//This is about damage reduction, not full stoneskin like in bg2
+//this effect has no level check in original, but I think, it is a bug
int fx_ironskins (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
ieDword tmp;
@@ -676,7 +744,7 @@ int fx_ironskins (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0xe8 Colour:FadeRGB
int fx_fade_rgb (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_fade_rgb (%2d): RGB:%x\n", fx->Opcode, fx->Parameter1 );
+ if(0) print("fx_fade_rgb(%2d): RGB:%x", fx->Opcode, fx->Parameter1);
int speed = (fx->Parameter2 >> 16) & 0xFF;
target->SetColorMod(0xff, RGBModifier::ADD, speed,
@@ -689,7 +757,7 @@ int fx_fade_rgb (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0xe9 IWDVisualSpellHit
int fx_iwd_visual_spell_hit (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_iwd_visual_spell_hit (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_iwd_visual_spell_hit(%2d): Type: %d", fx->Opcode, fx->Parameter2);
if (!Owner) {
return FX_NOT_APPLIED;
}
@@ -713,8 +781,8 @@ int fx_iwd_visual_spell_hit (Scriptable* Owner, Actor* target, Effect* fx)
//0xea ColdDamage (how)
int fx_cold_damage (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cold_damage (%2d): Damage %d\n", fx->Opcode, fx->Parameter1 );
- target->Damage(fx->Parameter1, DAMAGE_COLD, Owner);
+ if(0) print("fx_cold_damage(%2d): Damage %d", fx->Opcode, fx->Parameter1);
+ target->Damage(fx->Parameter1, DAMAGE_COLD, Owner, fx->IsVariable, fx->SavingThrowType);
return FX_NOT_APPLIED;
}
@@ -725,8 +793,8 @@ int fx_cold_damage (Scriptable* Owner, Actor* target, Effect* fx)
//it is the usual iwd/how style hack
int fx_chill_touch (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_chill_touch (%2d)\n", fx->Opcode);
- target->Damage(fx->Parameter1, DAMAGE_COLD, Owner);
+ if(0) print("fx_chill_touch(%2d)", fx->Opcode);
+ target->Damage(fx->Parameter1, DAMAGE_COLD, Owner, fx->IsVariable, fx->SavingThrowType);
if (STAT_GET(IE_GENERAL)==GEN_UNDEAD) {
target->Panic(Owner, PANIC_RUNAWAY);
}
@@ -737,7 +805,7 @@ int fx_chill_touch (Scriptable* Owner, Actor* target, Effect* fx)
//the undead check is made by IDS targeting as it should be
int fx_chill_touch_panic (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_chill_touch_panic (%2d)\n", fx->Opcode);
+ if(0) print("fx_chill_touch_panic(%2d)", fx->Opcode);
ieDword state;
if (fx->Parameter2) {
@@ -760,15 +828,15 @@ int fx_chill_touch_panic (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0xed CrushingDamage (how)
int fx_crushing_damage (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_crushing_damage (%2d): Damage %d\n", fx->Opcode, fx->Parameter1 );
- target->Damage(fx->Parameter1, DAMAGE_CRUSHING, Owner);
+ if(0) print("fx_crushing_damage(%2d): Damage %d", fx->Opcode, fx->Parameter1);
+ target->Damage(fx->Parameter1, DAMAGE_CRUSHING, Owner, fx->IsVariable, fx->SavingThrowType);
return FX_NOT_APPLIED;
}
//0xee SaveBonus
int fx_save_bonus (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_save_bonus (%2d): Bonus %d Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_save_bonus(%2d): Bonus %d Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_SAVEVSDEATH );
STAT_MOD( IE_SAVEVSWANDS );
STAT_MOD( IE_SAVEVSPOLY );
@@ -779,15 +847,14 @@ int fx_save_bonus (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0xef SlowPoison
//gemrb extension: can slow bleeding wounds (like bandage)
-static EffectRef fx_poison_ref = { "Poison", -1 };
-static EffectRef fx_wound_ref = { "BleedingWounds", -1 };
int fx_slow_poison (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
ieDword my_opcode;
+
if (fx->Parameter2) my_opcode = EffectQueue::ResolveEffect(fx_wound_ref);
else my_opcode = EffectQueue::ResolveEffect(fx_poison_ref);
- if (0) printf( "fx_slow_poison (%2d): Damage %d\n", fx->Opcode, fx->Parameter1 );
+ if(0) print("fx_slow_poison(%2d): Damage %d", fx->Opcode, fx->Parameter1);
std::list< Effect* >::const_iterator f=target->fxqueue.GetFirstEffect();
Effect *poison;
//this is intentionally an assignment
@@ -827,7 +894,7 @@ ieResRef iwd_monster_2da[IWD_MSC]={"MSUMMO1","MSUMMO2","MSUMMO3","MSUMMO4",
//0xf0 IWDMonsterSummoning
int fx_iwd_monster_summoning (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_iwd_monster_summoning (%2d): ResRef:%s Anim:%s Type: %d\n", fx->Opcode, fx->Resource, fx->Resource2, fx->Parameter2 );
+ if(0) print("fx_iwd_monster_summoning(%2d): ResRef:%s Anim:%s Type: %d", fx->Opcode, fx->Resource, fx->Resource2, fx->Parameter2);
//check the summoning limit?
@@ -836,7 +903,7 @@ int fx_iwd_monster_summoning (Scriptable* Owner, Actor* target, Effect* fx)
ieResRef areahit;
if (fx->Parameter2>=IWD_MSC) {
- fx->Parameter2=0;
+ fx->Parameter2 = 0;
}
core->GetResRefFrom2DA(iwd_monster_2da[fx->Parameter2], monster, hit, areahit);
@@ -851,7 +918,7 @@ int fx_iwd_monster_summoning (Scriptable* Owner, Actor* target, Effect* fx)
//0xf1 VampiricTouch
int fx_vampiric_touch (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_vampiric_touch (%2d): ResRef:%s Type: %d\n", fx->Opcode, fx->Resource, fx->Parameter2 );
+ if(0) print("fx_vampiric_touch(%2d): ResRef:%s Type: %d", fx->Opcode, fx->Resource, fx->Parameter2);
if (Owner->Type!=ST_ACTOR) {
return FX_NOT_APPLIED;
}
@@ -871,7 +938,7 @@ int fx_vampiric_touch (Scriptable* Owner, Actor* target, Effect* fx)
default:
return FX_NOT_APPLIED;
}
- int damage = donor->Damage(fx->Parameter1, fx->Parameter2, owner);
+ int damage = donor->Damage(fx->Parameter1, fx->Parameter2, owner, fx->IsVariable, fx->SavingThrowType);
receiver->SetBase( IE_HITPOINTS, BASE_GET( IE_HITPOINTS ) + ( damage ) );
return FX_NOT_APPLIED;
}
@@ -882,7 +949,7 @@ ieResRef animate_dead_2da[IWD_AD]={"ADEAD","ADEADL"};
//0xf3 AnimateDead
int fx_animate_dead (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_animate_dead (%2d): ResRef:%s Type: %d\n", fx->Opcode, fx->Resource, fx->Parameter2 );
+ if(0) print("fx_animate_dead(%2d): ResRef:%s Type: %d", fx->Opcode, fx->Resource, fx->Parameter2);
//check the summoning limit?
if (!target) {
return FX_NOT_APPLIED;
@@ -897,7 +964,7 @@ int fx_animate_dead (Scriptable* Owner, Actor* target, Effect* fx)
ieResRef areahit;
if (fx->Parameter2>=IWD_AD) {
- fx->Parameter2=0;
+ fx->Parameter2 = 0;
}
core->GetResRefFrom2DA(animate_dead_2da[fx->Parameter2], monster, hit, areahit);
@@ -911,7 +978,7 @@ int fx_animate_dead (Scriptable* Owner, Actor* target, Effect* fx)
//f4 Prayer
int fx_prayer (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_prayer (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_prayer(%2d): Type: %d", fx->Opcode, fx->Parameter2);
ieDword value;
if (fx->Parameter2)
@@ -927,7 +994,7 @@ int fx_prayer (Scriptable* /*Owner*/, Actor* target, Effect* fx)
value = 1;
}
- STAT_ADD( IE_TOHIT, value);
+ target->ToHit.HandleFxBonus(value, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
STAT_ADD( IE_SAVEFORTITUDE, value);
STAT_ADD( IE_SAVEREFLEX, value);
STAT_ADD( IE_SAVEWILL, value);
@@ -939,10 +1006,10 @@ int fx_prayer (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0xf5
int fx_curse (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_curse (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_curse(%2d): Type: %d", fx->Opcode, fx->Parameter2);
if (target->SetSpellState(SS_BADPRAYER)) return FX_NOT_APPLIED;
EXTSTATE_SET(EXTSTATE_PRAYER_BAD);
- STAT_ADD( IE_TOHIT, -1);
+ target->ToHit.HandleFxBonus(-1, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
STAT_ADD( IE_SAVEFORTITUDE, -1);
STAT_ADD( IE_SAVEREFLEX, -1);
STAT_ADD( IE_SAVEWILL, -1);
@@ -959,14 +1026,14 @@ ieResRef summon_monster_2da[IWD_SM2]={"SLIZARD","STROLLS","SSHADOW","ISTALKE",
int fx_summon_monster2 (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_summon_monster2 (%2d): ResRef:%s Type: %d\n", fx->Opcode, fx->Resource, fx->Parameter2 );
+ if(0) print("fx_summon_monster2(%2d): ResRef:%s Type: %d", fx->Opcode, fx->Resource, fx->Parameter2);
ieResRef monster;
ieResRef hit;
ieResRef areahit;
if (fx->Parameter2>=IWD_SM2) {
- fx->Parameter2=0;
+ fx->Parameter2 = 0;
}
core->GetResRefFrom2DA(summon_monster_2da[fx->Parameter2], monster, hit, areahit);
@@ -981,7 +1048,7 @@ int fx_summon_monster2 (Scriptable* Owner, Actor* target, Effect* fx)
//0xf7 BurningBlood (iwd)
int fx_burning_blood (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_burning_blood (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_burning_blood(%2d): Type: %d", fx->Opcode, fx->Parameter2);
//if the target is dead, this effect ceases to exist
if (STATE_GET(STATE_DEAD|STATE_PETRIFIED|STATE_FROZEN) ) {
@@ -996,14 +1063,14 @@ int fx_burning_blood (Scriptable* Owner, Actor* target, Effect* fx)
damage = DAMAGE_COLD;
}
- target->Damage(fx->Parameter1, damage, Owner);
+ target->Damage(fx->Parameter1, damage, Owner, fx->IsVariable, fx->SavingThrowType);
STAT_SET(IE_CHECKFORBERSERK,1);
return FX_NOT_APPLIED;
}
//0xf7 BurningBlood2 (how, iwd2)
int fx_burning_blood2 (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_burning_blood2 (%2d): Count: %d Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_burning_blood2(%2d): Count: %d Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//if the target is dead, this effect ceases to exist
if (STATE_GET(STATE_DEAD|STATE_PETRIFIED|STATE_FROZEN) ) {
@@ -1027,7 +1094,7 @@ int fx_burning_blood2 (Scriptable* Owner, Actor* target, Effect* fx)
}
//this effect doesn't use Parameter1 to modify damage, it is a counter instead
- target->Damage(DICE_ROLL(0), damage, Owner);
+ target->Damage(DICE_ROLL(0), damage, Owner, fx->IsVariable, fx->SavingThrowType);
STAT_SET(IE_CHECKFORBERSERK,1);
return FX_APPLIED;
}
@@ -1039,14 +1106,14 @@ ieResRef summon_shadow_monster_2da[IWD_SM2]={"SMONSTE","DSMONST","SHADES" };
int fx_summon_shadow_monster (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_summon_shadow_monster (%2d): ResRef:%s Type: %d\n", fx->Opcode, fx->Resource, fx->Parameter2 );
+ if(0) print("fx_summon_shadow_monster(%2d): ResRef:%s Type: %d", fx->Opcode, fx->Resource, fx->Parameter2);
ieResRef monster;
ieResRef hit;
ieResRef areahit;
if (fx->Parameter2>=IWD_SSM) {
- fx->Parameter2=0;
+ fx->Parameter2 = 0;
}
core->GetResRefFrom2DA(summon_shadow_monster_2da[fx->Parameter2], monster, hit, areahit);
@@ -1060,7 +1127,7 @@ int fx_summon_shadow_monster (Scriptable* Owner, Actor* target, Effect* fx)
//0xf9 Recitation
int fx_recitation (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_recitation (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_recitation(%2d): Type: %d", fx->Opcode, fx->Parameter2);
ieDword value;
if (fx->Parameter2)
@@ -1076,7 +1143,7 @@ int fx_recitation (Scriptable* /*Owner*/, Actor* target, Effect* fx)
value = 2;
}
- STAT_ADD( IE_TOHIT, value);
+ target->ToHit.HandleFxBonus(value, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
STAT_ADD( IE_SAVEFORTITUDE, value);
STAT_ADD( IE_SAVEREFLEX, value);
STAT_ADD( IE_SAVEWILL, value);
@@ -1088,10 +1155,10 @@ int fx_recitation (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0xfa RecitationBad
int fx_recitation_bad (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_recitation (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_recitation(%2d): Type: %d", fx->Opcode, fx->Parameter2);
if (target->SetSpellState(SS_BADRECIT)) return FX_NOT_APPLIED;
EXTSTATE_SET(EXTSTATE_REC_BAD);
- STAT_ADD( IE_TOHIT, -2);
+ target->ToHit.HandleFxBonus(-2, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
STAT_ADD( IE_SAVEFORTITUDE, -2);
STAT_ADD( IE_SAVEREFLEX, -2);
STAT_ADD( IE_SAVEWILL, -2);
@@ -1102,15 +1169,14 @@ int fx_recitation_bad (Scriptable* /*Owner*/, Actor* target, Effect* fx)
}
//0xfb LichTouch (how)
//0xfb State:Hold4 (iwd2)
-static EffectRef fx_hold_creature_ref = { "State:Hold", -1 };
int fx_lich_touch (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_lich_touch (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_lich_touch(%2d): Type: %d", fx->Opcode, fx->Parameter2);
if (STAT_GET(IE_GENERAL)==GEN_UNDEAD) {
return FX_NOT_APPLIED;
}
- target->Damage(DICE_ROLL(0), DAMAGE_COLD, Owner);
+ target->Damage(DICE_ROLL(0), DAMAGE_COLD, Owner, fx->IsVariable, fx->SavingThrowType );
///convert to hold creature
///shall we check for immunity vs. #175?
///if yes, then probably it is easier to apply the hold effect instead of converting to it
@@ -1123,7 +1189,6 @@ int fx_lich_touch (Scriptable* Owner, Actor* target, Effect* fx)
}
//0xfc BlindingOrb (how)
-static EffectRef fx_state_blind_ref = { "State:Blind", -1 };
int fx_blinding_orb (Scriptable* Owner, Actor* target, Effect* fx)
{
@@ -1136,10 +1201,10 @@ int fx_blinding_orb (Scriptable* Owner, Actor* target, Effect* fx)
//check saving throw
bool st = target->GetSavingThrow(0,0); //spell
if (st) {
- target->Damage(damage/2, DAMAGE_FIRE, Owner);
+ target->Damage(damage/2, DAMAGE_FIRE, Owner, fx->IsVariable, fx->SavingThrowType);
return FX_NOT_APPLIED;
}
- target->Damage(damage, DAMAGE_FIRE, Owner);
+ target->Damage(damage, DAMAGE_FIRE, Owner, fx->IsVariable, fx->SavingThrowType);
//convert effect to a blind effect.
fx->Opcode = EffectQueue::ResolveEffect(fx_state_blind_ref);
@@ -1153,7 +1218,7 @@ int fx_blinding_orb (Scriptable* Owner, Actor* target, Effect* fx)
//0xfe RemoveEffects
int fx_remove_effects (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_remove_effects (%2d): ResRef:%s Type: %d\n", fx->Opcode, fx->Resource, fx->Parameter2 );
+ if(0) print("fx_remove_effects(%2d): ResRef:%s Type: %d", fx->Opcode, fx->Resource, fx->Parameter2);
switch(fx->Parameter2) {
case 1:
@@ -1163,7 +1228,7 @@ int fx_remove_effects (Scriptable* /*Owner*/, Actor* target, Effect* fx)
target->fxqueue.RemoveAllEffects(fx->Resource, FX_DURATION_INSTANT_LIMITED);
break;
default:
- target->fxqueue.RemoveAllEffects(fx->Resource);
+ target->fxqueue.RemoveAllEffects(fx->Resource);
}
return FX_NOT_APPLIED;
}
@@ -1171,9 +1236,11 @@ int fx_remove_effects (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0xff SalamanderAura
int fx_salamander_aura (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_salamander_aura (%2d): ResRef:%s Type: %d\n", fx->Opcode, fx->Resource, fx->Parameter2 );
+ if(0) print("fx_salamander_aura(%2d): ResRef:%s Type: %d", fx->Opcode, fx->Resource, fx->Parameter2);
//inflicts damage calculated by dice values+parameter1
- //creates damage opcode on everyone around. fx->Parameter2 - 0 fire, 1 - ice
+ //creates damage opcode on everyone around. fx->Parameter2 - 0 fire, 1 - ice,
+ //Param2 = 2/3 are gemrb specific, i couldn't resist
+ //doesn't affect targets with 100% resistance, but could affect self
//if the target is dead, this effect ceases to exist
if (STATE_GET(STATE_DEAD|STATE_PETRIFIED|STATE_FROZEN) ) {
@@ -1182,37 +1249,65 @@ int fx_salamander_aura (Scriptable* Owner, Actor* target, Effect* fx)
//timing
ieDword time = core->GetGame()->GameTime;
- if ((fx->Parameter4==time) || (time%6) ) {
+ if ((fx->Parameter4==time) || (time%core->Time.round_size) ) {
return FX_APPLIED;
}
fx->Parameter4=time;
- ieDword damage = DAMAGE_FIRE;
-
- if (fx->Parameter2==1) {
+ ieDword damage, mystat;
+ switch(fx->Parameter2) {
+ case 0:default:
+ damage = DAMAGE_FIRE;
+ mystat = IE_RESISTFIRE;
+ break;
+ case 1:
damage = DAMAGE_COLD;
+ mystat = IE_RESISTCOLD;
+ break;
+ case 2:
+ damage = DAMAGE_ELECTRICITY;
+ mystat = IE_RESISTELECTRICITY;
+ break;
+ case 3:
+ damage = DAMAGE_ACID;
+ mystat = IE_RESISTACID;
+ break;
}
- ApplyDamageNearby(Owner, target, fx, damage);
+ Effect *newfx = EffectQueue::CreateEffect(fx_damage_opcode_ref, fx->Parameter1, damage<<16, FX_DURATION_INSTANT_PERMANENT);
+ newfx->Target = FX_TARGET_PRESET;
+ newfx->Power = fx->Power;
+ newfx->DiceThrown = fx->DiceThrown;
+ newfx->DiceSides = fx->DiceSides;
+ memcpy(newfx->Resource, fx->Resource,sizeof(newfx->Resource) );
+
+ Map *area = target->GetCurrentArea();
+ int i = area->GetActorCount(true);
+ while(i--) {
+ Actor *victim = area->GetActor(i,true);
+ if (PersonalDistance(target, victim)>20) continue;
+ if (victim->GetSafeStat(mystat)>=100) continue;
+ //apply the damage opcode
+ core->ApplyEffect(newfx, victim, Owner);
+ }
+ delete newfx;
return FX_APPLIED;
}
//0x100 UmberHulkGaze (causes confusion)
//it is a specially hacked effect to ignore certain races
//from the confusion effect
-static EffectRef fx_confusion_ref = { "State:Confused", -1 };
-static EffectRef fx_immunity_resource_ref = { "Protection:Spell", -1 };
int fx_umberhulk_gaze (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_umberhulk_gaze (%2d): Duration: %d\n", fx->Opcode, fx->Parameter1);
+ if(0) print("fx_umberhulk_gaze(%2d): Duration: %d", fx->Opcode, fx->Parameter1);
//if the target is dead, this effect ceases to exist
if (STATE_GET(STATE_DEAD|STATE_PETRIFIED|STATE_FROZEN) ) {
return FX_NOT_APPLIED;
}
fx->TimingMode=FX_DURATION_AFTER_EXPIRES;
- fx->Duration=core->GetGame()->GameTime+7*15;
+ fx->Duration=core->GetGame()->GameTime+7*AI_UPDATE_TIME;
//build effects to apply
Effect * newfx1, *newfx2;
@@ -1221,7 +1316,7 @@ int fx_umberhulk_gaze (Scriptable* Owner, Actor* target, Effect* fx)
newfx1->TimingMode = FX_DURATION_INSTANT_LIMITED;
newfx1->Duration = fx->Parameter1;
- newfx2 = EffectQueue::CreateEffectCopy(fx, fx_immunity_resource_ref, 0, 0);
+ newfx2 = EffectQueue::CreateEffectCopy(fx, fx_resist_spell_ref, 0, 0);
newfx2->TimingMode = FX_DURATION_INSTANT_LIMITED;
newfx2->Duration = fx->Parameter1;
memcpy(newfx2->Resource, fx->Source, sizeof(newfx2->Resource) );
@@ -1261,18 +1356,17 @@ int fx_umberhulk_gaze (Scriptable* Owner, Actor* target, Effect* fx)
}
//0x101 ZombieLordAura (causes Panic) unused in all games
-static EffectRef fx_fear_ref = { "State:Panic", -1 };
int fx_zombielord_aura (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_zombie_lord_aura (%2d): Duration: %d\n", fx->Opcode, fx->Parameter1);
+ if(0) print("fx_zombie_lord_aura(%2d): Duration: %d", fx->Opcode, fx->Parameter1);
//if the target is dead, this effect ceases to exist
if (STATE_GET(STATE_DEAD|STATE_PETRIFIED|STATE_FROZEN) ) {
return FX_NOT_APPLIED;
}
fx->TimingMode=FX_DURATION_AFTER_EXPIRES;
- fx->Duration=core->GetGame()->GameTime+7*15;
+ fx->Duration=core->GetGame()->GameTime+7*AI_UPDATE_TIME;
//build effects to apply
Effect * newfx1, *newfx2;
@@ -1281,7 +1375,7 @@ int fx_zombielord_aura (Scriptable* Owner, Actor* target, Effect* fx)
newfx1->TimingMode = FX_DURATION_INSTANT_LIMITED;
newfx1->Duration = fx->Parameter1;
- newfx2 = EffectQueue::CreateEffectCopy(fx, fx_immunity_resource_ref, 0, 0);
+ newfx2 = EffectQueue::CreateEffectCopy(fx, fx_resist_spell_ref, 0, 0);
newfx2->TimingMode = FX_DURATION_INSTANT_LIMITED;
newfx2->Duration = fx->Parameter1;
memcpy(newfx2->Resource, fx->Source, sizeof(newfx2->Resource) );
@@ -1321,7 +1415,7 @@ static int eamods[]={EAM_DEFAULT,EAM_SOURCEALLY,EAM_SOURCEENEMY};
int fx_summon_creature2 (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_summon_creature2 (%2d): ResRef:%s Anim:%s Type: %d\n", fx->Opcode, fx->Resource, fx->Resource2, fx->Parameter2 );
+ if(0) print("fx_summon_creature2(%2d): ResRef:%s Anim:%s Type: %d", fx->Opcode, fx->Resource, fx->Resource2, fx->Parameter2);
if (!target) {
return FX_NOT_APPLIED;
@@ -1360,7 +1454,7 @@ int fx_avatar_removal (Scriptable* /*Owner*/, Actor* target, Effect* /*fx*/)
int fx_summon_pomab (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_summon_pomab (%2d): ResRef:%s Anim:%s Type: %d\n", fx->Opcode, fx->Resource, fx->Resource2, fx->Parameter2 );
+ if(0) print("fx_summon_pomab(%2d): ResRef:%s Anim:%s Type: %d", fx->Opcode, fx->Resource, fx->Resource2, fx->Parameter2);
if (!target) {
return FX_NOT_APPLIED;
@@ -1399,11 +1493,22 @@ int fx_summon_pomab (Scriptable* Owner, Actor* target, Effect* fx)
return FX_NOT_APPLIED;
}
-//0x107 ControlUndead (like charm?)
+//This is the IWD2 charm effect
+//0x107 ControlUndead (like charm)
//425 ControlUndead2
int fx_control_undead (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_control_undead (%2d): General: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_control_undead(%2d): General: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+ //blood rage berserking gives immunity to charm (in iwd2)
+ if (target->HasSpellState(SS_BLOODRAGE)) {
+ return FX_NOT_APPLIED;
+ }
+
+ //protection from evil gives immunity to charm (in iwd2)
+ if (target->HasSpellState(SS_PROTFROMEVIL)) {
+ return FX_NOT_APPLIED;
+ }
+
if (fx->Parameter1 && (STAT_GET(IE_GENERAL)!=fx->Parameter1)) {
return FX_NOT_APPLIED;
}
@@ -1421,23 +1526,26 @@ int fx_control_undead (Scriptable* Owner, Actor* target, Effect* fx)
}
switch (fx->Parameter2) {
case 0: //charmed (target neutral after charm)
- displaymsg->DisplayConstantStringName(STR_CHARMED, 0xf0f0f0, target);
+ displaymsg->DisplayConstantStringName(STR_CHARMED, DMC_WHITE, target);
break;
case 1: //charmed (target hostile after charm)
- displaymsg->DisplayConstantStringName(STR_CHARMED, 0xf0f0f0, target);
+ displaymsg->DisplayConstantStringName(STR_CHARMED, DMC_WHITE, target);
target->SetBase(IE_EA, EA_ENEMY);
break;
case 2: //controlled by cleric
- displaymsg->DisplayConstantStringName(STR_CONTROLLED, 0xf0f0f0, target);
+ displaymsg->DisplayConstantStringName(STR_CONTROLLED, DMC_WHITE, target);
+ target->SetSpellState(SS_DOMINATION);
break;
case 3: //controlled by cleric (hostile after charm)
- displaymsg->DisplayConstantStringName(STR_CONTROLLED, 0xf0f0f0, target);
+ displaymsg->DisplayConstantStringName(STR_CONTROLLED, DMC_WHITE, target);
target->SetBase(IE_EA, EA_ENEMY);
+ target->SetSpellState(SS_DOMINATION);
break;
case 4: //turn undead
- displaymsg->DisplayConstantStringName(STR_CONTROLLED, 0xf0f0f0, target);
+ displaymsg->DisplayConstantStringName(STR_CONTROLLED, DMC_WHITE, target);
target->SetBase(IE_EA, EA_ENEMY);
target->SetStat(IE_MORALE, 0, 0);
+ target->SetSpellState(SS_DOMINATION);
break;
}
}
@@ -1451,7 +1559,7 @@ int fx_control_undead (Scriptable* Owner, Actor* target, Effect* fx)
//0x108 StaticCharge
int fx_static_charge(Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_static_charge (%2d): Count: %d \n", fx->Opcode, fx->Parameter1 );
+ if(0) print("fx_static_charge(%2d): Count: %d ", fx->Opcode, fx->Parameter1);
//if the target is dead, this effect ceases to exist
if (STATE_GET(STATE_DEAD|STATE_PETRIFIED|STATE_FROZEN) ) {
@@ -1462,11 +1570,15 @@ int fx_static_charge(Scriptable* Owner, Actor* target, Effect* fx)
if (fx->Parameter1<=1) {
ret = FX_NOT_APPLIED;
+ // prevent an underflow
+ if (fx->Parameter1 == 0) {
+ return ret;
+ }
}
//timing
fx->TimingMode=FX_DURATION_DELAY_PERMANENT;
- fx->Duration=core->GetGame()->GameTime+70*15;
+ fx->Duration=core->GetGame()->GameTime+70*AI_UPDATE_TIME;
fx->Parameter1--;
//iwd2 style
@@ -1476,18 +1588,15 @@ int fx_static_charge(Scriptable* Owner, Actor* target, Effect* fx)
}
//how style
- target->Damage(DICE_ROLL(0), DAMAGE_ELECTRICITY, Owner);
+ target->Damage(DICE_ROLL(0), DAMAGE_ELECTRICITY, Owner, fx->IsVariable, fx->SavingThrowType);
return ret;
}
//0x109 CloakOfFear (HoW/IWD2)
//if the resource is not specified, it will work like in HoW
-
-static EffectRef fx_umberhulk_gaze_ref = { "UmberHulkGaze", -1 };
-
int fx_cloak_of_fear(Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_cloak_of_fear (%2d): Count: %d \n", fx->Opcode, fx->Parameter1 );
+ if(0) print("fx_cloak_of_fear(%2d): Count: %d ", fx->Opcode, fx->Parameter1);
//if the target is dead, this effect ceases to exist
if (STATE_GET(STATE_DEAD|STATE_PETRIFIED|STATE_FROZEN) ) {
@@ -1500,7 +1609,7 @@ int fx_cloak_of_fear(Scriptable* Owner, Actor* target, Effect* fx)
//timing (set up next fire)
fx->TimingMode=FX_DURATION_DELAY_PERMANENT;
- fx->Duration=core->GetGame()->GameTime+3*15;
+ fx->Duration=core->GetGame()->GameTime+3*AI_UPDATE_TIME;
fx->Parameter1--;
//iwd2 style
@@ -1535,7 +1644,7 @@ int fx_cloak_of_fear(Scriptable* Owner, Actor* target, Effect* fx)
//0x10c EyeOfTheMind
int fx_eye_of_the_mind (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_eye_of_the_mind (%2d)\n", fx->Opcode );
+ if(0) print("fx_eye_of_the_mind(%2d)", fx->Opcode);
if (target->SetSpellState( SS_EYEMIND)) return FX_APPLIED;
EXTSTATE_SET(EXTSTATE_EYE_MIND);
@@ -1547,7 +1656,7 @@ int fx_eye_of_the_mind (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0x10d EyeOfTheSword
int fx_eye_of_the_sword (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_eye_of_the_sword (%2d)\n", fx->Opcode );
+ if(0) print("fx_eye_of_the_sword(%2d)", fx->Opcode);
if (target->SetSpellState( SS_EYESWORD)) return FX_APPLIED;
EXTSTATE_SET(EXTSTATE_EYE_SWORD);
@@ -1560,7 +1669,7 @@ int fx_eye_of_the_sword (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0x10e EyeOfTheMage
int fx_eye_of_the_mage (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_eye_of_the_mage (%2d)\n", fx->Opcode );
+ if(0) print("fx_eye_of_the_mage(%2d)", fx->Opcode);
if (target->SetSpellState( SS_EYEMAGE)) return FX_APPLIED;
EXTSTATE_SET(EXTSTATE_EYE_MAGE);
@@ -1573,7 +1682,7 @@ int fx_eye_of_the_mage (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0x10f EyeOfVenom
int fx_eye_of_venom (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_eye_of_venom (%2d)\n", fx->Opcode );
+ if(0) print("fx_eye_of_venom(%2d)", fx->Opcode);
if (target->SetSpellState( SS_EYEVENOM)) return FX_APPLIED;
EXTSTATE_SET(EXTSTATE_EYE_VENOM);
@@ -1586,7 +1695,7 @@ int fx_eye_of_venom (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0x110 EyeOfTheSpirit
int fx_eye_of_the_spirit (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_eye_of_the_spirit (%2d)\n", fx->Opcode );
+ if(0) print("fx_eye_of_the_spirit(%2d)", fx->Opcode);
if (target->SetSpellState( SS_EYESPIRIT)) return FX_APPLIED;
EXTSTATE_SET(EXTSTATE_EYE_SPIRIT);
@@ -1599,7 +1708,7 @@ int fx_eye_of_the_spirit (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0x111 EyeOfFortitude
int fx_eye_of_fortitude (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_eye_of_fortitude (%2d)\n", fx->Opcode );
+ if(0) print("fx_eye_of_fortitude(%2d)", fx->Opcode);
if (target->SetSpellState( SS_EYEFORTITUDE)) return FX_APPLIED;
EXTSTATE_SET(EXTSTATE_EYE_FORT);
@@ -1612,7 +1721,7 @@ int fx_eye_of_fortitude (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0x112 EyeOfStone
int fx_eye_of_stone (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_eye_of_stone (%2d)\n", fx->Opcode );
+ if(0) print("fx_eye_of_stone(%2d)", fx->Opcode);
if (target->SetSpellState( SS_EYESTONE)) return FX_APPLIED;
EXTSTATE_SET(EXTSTATE_EYE_STONE);
@@ -1626,7 +1735,7 @@ int fx_eye_of_stone (Scriptable* /*Owner*/, Actor* target, Effect* fx)
int fx_remove_seven_eyes (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_remove_seven_eyes (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_remove_seven_eyes(%2d): Type: %d", fx->Opcode, fx->Parameter2);
target->spellbook.RemoveSpell(SevenEyes[EYE_MIND]);
target->spellbook.RemoveSpell(SevenEyes[EYE_SWORD]);
target->spellbook.RemoveSpell(SevenEyes[EYE_MAGE]);
@@ -1640,7 +1749,7 @@ int fx_remove_seven_eyes (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0x114 RemoveEffect
int fx_remove_effect (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_remove_effect (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_remove_effect(%2d): Type: %d", fx->Opcode, fx->Parameter2);
if (fx->Resource[0])
{
target->fxqueue.RemoveAllEffectsWithResource(fx->Parameter2, fx->Resource);
@@ -1652,14 +1761,10 @@ int fx_remove_effect (Scriptable* /*Owner*/, Actor* target, Effect* fx)
return FX_NOT_APPLIED;
}
-static EffectRef fx_str_ref = { "StrengthModifier", -1 };
-static EffectRef fx_con_ref = { "ConstitutionModifier", -1 };
-static EffectRef fx_dex_ref = { "DexterityModifier", -1 };
-
//0x115 SoulEater
int fx_soul_eater (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_soul_eater (%2d): Damage %d\n", fx->Opcode, fx->Parameter1 );
+ if(0) print("fx_soul_eater(%2d): Damage %d", fx->Opcode, fx->Parameter1);
// Soul Eater has no effect on undead, constructs, and elemental creatures,
// but this is handled in the spells via fx_resist_spell_and_message
int damage = fx->Parameter1;
@@ -1668,7 +1773,7 @@ int fx_soul_eater (Scriptable* Owner, Actor* target, Effect* fx)
damage = core->Roll(3, 8, 0);
}
- target->Damage(damage, DAMAGE_SOULEATER, Owner);
+ target->Damage(damage, DAMAGE_SOULEATER, Owner, fx->IsVariable, fx->SavingThrowType);
//the state is not set soon enough!
//if (STATE_GET(STATE_DEAD) ) {
if (target->GetInternalFlag() & IF_REALLYDIED) {
@@ -1703,7 +1808,7 @@ int fx_soul_eater (Scriptable* Owner, Actor* target, Effect* fx)
//FIXME: maybe it is cheaper to port effsof1/2 to how than having an alternate effect
int fx_shroud_of_flame (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_shroud_of_flame (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_shroud_of_flame(%2d): Type: %d", fx->Opcode, fx->Parameter2);
//if the target is dead, this effect ceases to exist
if (STATE_GET(STATE_DEAD|STATE_PETRIFIED|STATE_FROZEN) ) {
@@ -1732,14 +1837,14 @@ int fx_shroud_of_flame (Scriptable* Owner, Actor* target, Effect* fx)
//inflicts damage calculated by dice values+parameter1
//creates damage opcode on everyone around. fx->Parameter2 - 0 fire, 1 - ice
- ieDword damage = DAMAGE_FIRE;
+ ieDword damagetype = DAMAGE_FIRE;
if (fx->Parameter2==1) {
- damage = DAMAGE_COLD;
+ damagetype = DAMAGE_COLD;
}
- target->Damage(fx->Parameter1, damage, Owner);
- ApplyDamageNearby(Owner, target, fx, damage);
+ target->Damage(fx->Parameter1, damagetype, Owner, fx->IsVariable, fx->SavingThrowType);
+ ApplyDamageNearby(Owner, target, fx, damagetype);
return FX_APPLIED;
}
@@ -1749,7 +1854,7 @@ static ieResRef resref_sof2={"effsof2"};
//0x116 ShroudOfFlame (iwd2)
int fx_shroud_of_flame2 (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_shroud_of_flame2 (%2d)\n", fx->Opcode );
+ if(0) print("fx_shroud_of_flame2(%2d)", fx->Opcode);
//if the target is dead, this effect ceases to exist
if (STATE_GET(STATE_DEAD|STATE_PETRIFIED|STATE_FROZEN) ) {
@@ -1789,7 +1894,7 @@ int fx_shroud_of_flame2 (Scriptable* Owner, Actor* target, Effect* fx)
//0x117 AnimalRage
int fx_animal_rage (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_animal_rage (%2d): Mode: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_animal_rage(%2d): Mode: %d", fx->Opcode, fx->Parameter2);
//param2==1 sets only the spell state
if (fx->Parameter2) {
@@ -1833,7 +1938,7 @@ int fx_animal_rage (Scriptable* /*Owner*/, Actor* target, Effect* fx)
}
//see the nearest enemy
if (SeeCore(target, Enemy, false)) {
- target->SetTarget(target->GetCurrentArea()->GetActorByGlobalID(target->LastSeen));
+ target->FaceTarget(target->GetCurrentArea()->GetActorByGlobalID(target->LastSeen));
//this is highly unsure
//fx->Parameter1=1;
}
@@ -1841,44 +1946,29 @@ int fx_animal_rage (Scriptable* /*Owner*/, Actor* target, Effect* fx)
return FX_APPLIED;
}
-//0x118 TurnUndead how
-int fx_turn_undead (Scriptable* Owner, Actor* target, Effect* fx)
-{
- if (0) printf( "fx_turn_undead (%2d): Level %d\n", fx->Opcode, fx->Parameter1 );
- if (fx->Parameter1) {
- target->Turn(Owner, fx->Parameter1);
- } else {
- if (Owner->Type!=ST_ACTOR) {
- return FX_NOT_APPLIED;
- }
- target->Turn(Owner, ((Actor *) Owner)->GetStat(IE_TURNUNDEADLEVEL));
- }
- return FX_APPLIED;
-}
-
//0x118 TurnUndead2 iwd2
int fx_turn_undead2 (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_turn_undead2 (%2d): Level: %d Type %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_turn_undead2(%2d): Level: %d Type %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
switch (fx->Parameter2)
{
case 0: //command
- target->LastTurner = Owner->GetGlobalID();
+ target->AddTrigger(TriggerEntry(trigger_turnedby, Owner->GetGlobalID()));
target->Panic(Owner, PANIC_RUNAWAY);
break;
case 1://rebuke
+ target->AddTrigger(TriggerEntry(trigger_turnedby, Owner->GetGlobalID()));
if (target->SetSpellState(SS_REBUKED)) {
//display string rebuked
}
- STAT_SUB(IE_ARMORCLASS,4);
- target->LastTurner = Owner->GetGlobalID();
+ target->AC.HandleFxBonus(-4, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
break;
case 2://destroy
- target->LastTurner = Owner->GetGlobalID();
+ target->AddTrigger(TriggerEntry(trigger_turnedby, Owner->GetGlobalID()));
target->Die(Owner);
break;
case 3://panic
- target->LastTurner = Owner->GetGlobalID();
+ target->AddTrigger(TriggerEntry(trigger_turnedby, Owner->GetGlobalID()));
target->Panic(Owner, PANIC_RUNAWAY);
break;
default://depends on caster
@@ -1898,25 +1988,25 @@ int fx_turn_undead2 (Scriptable* Owner, Actor* target, Effect* fx)
//0x119 VitriolicSphere
int fx_vitriolic_sphere (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_vitriolic_sphere (%2d): Damage %d\n", fx->Opcode, fx->Parameter1 );
+ if(0) print("fx_vitriolic_sphere(%2d): Damage %d", fx->Opcode, fx->Parameter1);
//timing
if (core->GetGame()->GameTime%6) {
return FX_APPLIED;
}
- target->Damage(fx->Parameter1, DAMAGE_ACID, Owner);
+ target->Damage(fx->Parameter1, DAMAGE_ACID, Owner, fx->IsVariable, fx->SavingThrowType);
fx->DiceThrown-=2;
if ((signed) fx->DiceThrown<1) {
return FX_NOT_APPLIED;
}
//also damage people nearby?
-// ApplyDamageNearby(Owner, target, fx, DAMAGE_ACID);
+ ApplyDamageNearby(Owner, target, fx, DAMAGE_ACID);
return FX_APPLIED;
}
//0x11a SuppressHP
int fx_suppress_hp (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_suppress_hp (%2d)\n", fx->Opcode);
+ if(0) print("fx_suppress_hp(%2d)", fx->Opcode);
if (target->SetSpellState( SS_NOHPINFO)) return FX_APPLIED;
EXTSTATE_SET(EXTSTATE_NO_HP);
return FX_APPLIED;
@@ -1925,7 +2015,7 @@ int fx_suppress_hp (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0x11b FloatText
int fx_floattext (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_floattext (%2d): StrRef:%d Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_floattext(%2d): StrRef:%d Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
switch (fx->Parameter2)
{
case 1:
@@ -1964,12 +2054,10 @@ int fx_floattext (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0x11c MaceOfDisruption
//death with chance based on race and level
-static EffectRef fx_death_ref = { "Death", -1 };
-static EffectRef fx_iwd_visual_spell_hit_ref = { "IWDVisualSpellHit", -1 };
int fx_mace_of_disruption (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_mace_of_disruption (%2d): ResRef:%s Anim:%s Type: %d\n", fx->Opcode, fx->Resource, fx->Resource2, fx->Parameter2 );
+ if(0) print("fx_mace_of_disruption(%2d): ResRef:%s Anim:%s Type: %d", fx->Opcode, fx->Resource, fx->Resource2, fx->Parameter2);
ieDword race = STAT_GET(IE_RACE);
//golem / outer planar gets hit
int chance = 0;
@@ -2031,13 +2119,17 @@ int fx_mace_of_disruption (Scriptable* Owner, Actor* target, Effect* fx)
//0x120 State:Set
int fx_set_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_state (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_set_state(%2d): Type: %d", fx->Opcode, fx->Parameter2);
//in IWD2 we have 176 states (original had 256)
target->SetSpellState(fx->Parameter2);
//in HoW this sets only the 10 last bits of extstate (until it runs out of bits)
if (fx->Parameter2<11) {
EXTSTATE_SET(0x40000<<fx->Parameter2);
}
+ //maximized attacks active
+ if (fx->Parameter2==SS_KAI) {
+ target->Modified[IE_DAMAGELUCK]=255;
+ }
return FX_APPLIED;
}
@@ -2047,13 +2139,13 @@ int fx_set_state (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//ToB has an effect which actually runs a hardcoded cutscene
int fx_cutscene (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
{
- if (0) printf( "fx_cutscene (%2d)\n", fx->Opcode );
+ if(0) print("fx_cutscene(%2d)", fx->Opcode);
Game *game = core->GetGame();
game->locals->SetAt("GEM_ACTIVE", 1);
return FX_NOT_APPLIED;
}
-//0xce (same place as in bg2, but different)
+//0xce (same place as in bg2, but different targeting)
int fx_resist_spell (Scriptable* Owner, Actor* target, Effect *fx)
{
//check iwd ids targeting
@@ -2069,8 +2161,6 @@ int fx_resist_spell (Scriptable* Owner, Actor* target, Effect *fx)
return FX_ABORT;
}
-static EffectRef fx_resist_spell_ref = { "Protection:Spell2", -1 };
-
//0x122 Protection:Spell3 ??? IWD ids targeting
// this is a variant of resist spell, used in iwd2
int fx_resist_spell_and_message (Scriptable* Owner, Actor* target, Effect *fx)
@@ -2092,16 +2182,20 @@ int fx_resist_spell_and_message (Scriptable* Owner, Actor* target, Effect *fx)
int spellname = -1;
if(gamedata->Exists(fx->Resource, IE_ITM_CLASS_ID) ) {
- spellname = gamedata->GetItem(fx->Resource)->ItemName;
+ Item *poi = gamedata->GetItem(fx->Resource);
+ spellname = poi->ItemName;
+ gamedata->FreeItem(poi, fx->Resource, 0);
} else if (gamedata->Exists(fx->Resource, IE_SPL_CLASS_ID) ) {
- spellname = gamedata->GetSpell(fx->Resource, true)->SpellName;
+ Spell *poi = gamedata->GetSpell(fx->Resource, true);
+ spellname = poi->SpellName;
+ gamedata->FreeSpell(poi, fx->Resource, 0);
}
if (spellname>=0) {
char *tmpstr = core->GetString(spellname, 0);
core->GetTokenDictionary()->SetAtCopy("RESOURCE", tmpstr);
core->FreeString(tmpstr);
- displaymsg->DisplayConstantStringName(STR_RES_RESISTED, 0xf0f0f0, target);
+ displaymsg->DisplayConstantStringName(STR_RES_RESISTED, DMC_WHITE, target);
}
//this has effect only on first apply, it will stop applying the spell
return FX_ABORT;
@@ -2113,7 +2207,7 @@ int fx_resist_spell_and_message (Scriptable* Owner, Actor* target, Effect *fx)
//otherwise: nothing
int fx_rod_of_smithing (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_rod_of_smithing (%2d): ResRef:%s Anim:%s Type: %d\n", fx->Opcode, fx->Resource, fx->Resource2, fx->Parameter2 );
+ if(0) print("fx_rod_of_smithing(%2d): ResRef:%s Anim:%s Type: %d", fx->Opcode, fx->Resource, fx->Resource2, fx->Parameter2);
int damage = 0;
int five_percent = core->Roll(1,100,0)<5;
@@ -2152,7 +2246,7 @@ int fx_rod_of_smithing (Scriptable* Owner, Actor* target, Effect* fx)
//TODO: range, affected actors
int fx_beholder_dispel_magic (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_beholder_dispel_magic (%2d): Spell: %s\n", fx->Opcode, fx->Resource );
+ if(0) print("fx_beholder_dispel_magic(%2d): Spell: %s", fx->Opcode, fx->Resource);
if (!fx->Resource[0]) {
strcpy(fx->Resource,"SPIN164");
}
@@ -2180,7 +2274,7 @@ int fx_beholder_dispel_magic (Scriptable* Owner, Actor* target, Effect* fx)
//TODO: range, affected actors, sound effect
int fx_harpy_wail (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_harpy_wail (%2d): Spell: %s\n", fx->Opcode, fx->Resource );
+ if(0) print("fx_harpy_wail(%2d): Spell: %s", fx->Opcode, fx->Resource);
if (!fx->Resource[0]) {
strcpy(fx->Resource,"SPIN166");
}
@@ -2212,7 +2306,7 @@ int fx_harpy_wail (Scriptable* Owner, Actor* target, Effect* fx)
//TODO: range, affected actors
int fx_jackalwere_gaze (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_jackalwere_gaze (%2d): Spell: %s\n", fx->Opcode, fx->Resource );
+ if(0) print("fx_jackalwere_gaze(%2d): Spell: %s", fx->Opcode, fx->Resource);
if (!fx->Resource[0]) {
strcpy(fx->Resource,"SPIN179");
}
@@ -2241,7 +2335,7 @@ int fx_jackalwere_gaze (Scriptable* Owner, Actor* target, Effect* fx)
//0x12a UseMagicDevice
int fx_use_magic_device_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_use_magic_device_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_use_magic_device_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
STAT_MOD( IE_MAGICDEVICE );
return FX_APPLIED;
}
@@ -2261,9 +2355,10 @@ int fx_use_magic_device_modifier (Scriptable* /*Owner*/, Actor* target, Effect*
//Create alternate cycles for the altered area object
//Create a spell hit animation (optionally)
//Create the effect which will contain the spell hit projectile and the cycle change command
+//0x18f AlterAnimation
int fx_alter_animation (Scriptable* Owner, Actor* /*target*/, Effect* fx)
{
- if (0) printf( "fx_alter_animation (%2d)\n", fx->Opcode);
+ if(0) print("fx_alter_animation(%2d) Parameter: %d Projectile: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
Map *map = Owner->GetCurrentArea();
if (!map) {
return FX_NOT_APPLIED;
@@ -2286,6 +2381,9 @@ int fx_alter_animation (Scriptable* Owner, Actor* /*target*/, Effect* fx)
case BM_SET:
an->sequence=value;
break;
+ case BM_AND:
+ an->sequence&=value;
+ break;
case BM_OR:
an->sequence|=value;
break;
@@ -2296,19 +2394,85 @@ int fx_alter_animation (Scriptable* Owner, Actor* /*target*/, Effect* fx)
an->sequence^=value;
break;
}
- an->frame=0;
+ an->frame = 0;
an->InitAnimation();
}
}
return FX_NOT_APPLIED;
}
+//0x12b AnimalEmpathy (gemrb extension for iwd2)
+int fx_animal_empathy_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
+{
+ if(0) print("fx_animal_empathy_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+ STAT_MOD( IE_ANIMALS );
+ return FX_APPLIED;
+}
+
+//0x12c Bluff (gemrb extension for iwd2)
+int fx_bluff_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
+{
+ if(0) print("fx_bluff_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+ STAT_MOD( IE_BLUFF );
+ return FX_APPLIED;
+}
+
+//0x12d Concentration (gemrb extension for iwd2)
+int fx_concentration_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
+{
+ if(0) print("fx_concentration_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+ STAT_MOD( IE_CONCENTRATION );
+ return FX_APPLIED;
+}
+
+//0x12e Diplomacy (gemrb extension for iwd2)
+int fx_diplomacy_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
+{
+ if(0) print("fx_diplomacy_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+ STAT_MOD( IE_DIPLOMACY );
+ return FX_APPLIED;
+}
+
+//0x12f Intimidate (gemrb extension for iwd2)
+int fx_intimidate_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
+{
+ if(0) print("fx_intimidate_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+ STAT_MOD( IE_INTIMIDATE );
+ return FX_APPLIED;
+}
+
+//0x130 Search (gemrb extension for iwd2)
+int fx_search_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
+{
+ if(0) print("fx_search_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+ STAT_MOD( IE_SEARCH );
+ return FX_APPLIED;
+}
+
+//0x131 Spellcraft (gemrb extension for iwd2)
+int fx_spellcraft_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
+{
+ if(0) print("fx_spellcraft_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+ STAT_MOD( IE_SPELLCRAFT );
+ return FX_APPLIED;
+}
+
+//0x132 DamageLuck (gemrb extension for iwd2, implemented in base opcodes)
+
+//0x133 TurnLevel (gemrb extension for iwd2)
+int fx_turnlevel_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx)
+{
+ if(0) print("fx_turnlevel_modifier(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+ STAT_MOD( IE_TURNUNDEADLEVEL );
+ return FX_APPLIED;
+}
+
//IWD2 effects
//400 Hopelessness
int fx_hopelessness (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_hopelessness (%2d)\n", fx->Opcode);
+ if(0) print("fx_hopelessness(%2d)", fx->Opcode);
if (target->HasSpellState(SS_BLOODRAGE)) {
return FX_NOT_APPLIED;
@@ -2323,7 +2487,7 @@ int fx_hopelessness (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//401 ProtectionFromEvil
int fx_protection_from_evil (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_protection_from_evil (%2d)\n", fx->Opcode);
+ if(0) print("fx_protection_from_evil(%2d)", fx->Opcode);
//
if (target->SetSpellState( SS_PROTFROMEVIL)) return FX_APPLIED;
target->AddPortraitIcon(PI_PROTFROMEVIL);
@@ -2352,7 +2516,7 @@ int fx_add_effects_list (Scriptable* Owner, Actor* target, Effect* fx)
//403 ArmorOfFaith
static int fx_armor_of_faith (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_armor_of_faith (%2d) Amount: %d\n", fx->Opcode, fx->Parameter1);
+ if(0) print("fx_armor_of_faith(%2d) Amount: %d", fx->Opcode, fx->Parameter1);
if (target->SetSpellState( SS_ARMOROFFAITH)) return FX_APPLIED;
if (!fx->Parameter1) {
fx->Parameter1=1;
@@ -2362,7 +2526,7 @@ static int fx_armor_of_faith (Scriptable* /*Owner*/, Actor* target, Effect* fx)
STAT_ADD(IE_RESISTCOLD,fx->Parameter1 );
STAT_ADD(IE_RESISTELECTRICITY,fx->Parameter1 );
STAT_ADD(IE_RESISTACID,fx->Parameter1 );
- STAT_ADD(IE_RESISTMAGIC,fx->Parameter1 );
+ STAT_ADD(IE_MAGICDAMAGERESISTANCE,fx->Parameter1 );
STAT_ADD(IE_RESISTSLASHING,fx->Parameter1 );
STAT_ADD(IE_RESISTCRUSHING,fx->Parameter1 );
STAT_ADD(IE_RESISTPIERCING,fx->Parameter1 );
@@ -2374,11 +2538,10 @@ static int fx_armor_of_faith (Scriptable* /*Owner*/, Actor* target, Effect* fx)
}
//404 Nausea
-static EffectRef fx_unconscious_state_ref = { "State:Helpless", -1 };
int fx_nausea (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_nausea (%2d)\n", fx->Opcode);
+ if(0) print("fx_nausea(%2d)", fx->Opcode);
//FIXME: i'm not sure if this part is there
//create the sleep effect only once?
if (!fx->Parameter3 && Owner) {
@@ -2401,7 +2564,7 @@ int fx_nausea (Scriptable* Owner, Actor* target, Effect* fx)
//minimum stats in 3rd ed are 1, so this effect won't kill the target
int fx_enfeeblement (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_enfeeblement (%2d)\n", fx->Opcode);
+ if(0) print("fx_enfeeblement(%2d)", fx->Opcode);
if (target->SetSpellState( SS_ENFEEBLED)) return FX_APPLIED;
target->AddPortraitIcon(PI_ENFEEBLEMENT);
STAT_ADD(IE_STR, -15);
@@ -2411,7 +2574,7 @@ int fx_enfeeblement (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//406 FireShield
int fx_fireshield (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_fireshield (%2d) Type: %d\n", fx->Opcode, fx->Parameter2);
+ if(0) print("fx_fireshield(%2d) Type: %d", fx->Opcode, fx->Parameter2);
if (fx->Parameter2) {
if (target->SetSpellState( SS_ICESHIELD)) return FX_APPLIED;
target->AddPortraitIcon(PI_ICESHIELD);
@@ -2426,7 +2589,7 @@ int fx_fireshield (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//407 DeathWard
int fx_death_ward (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_death_ward (%2d)\n", fx->Opcode);
+ if(0) print("fx_death_ward(%2d)", fx->Opcode);
if (target->SetSpellState( SS_DEATHWARD)) return FX_APPLIED;
target->AddPortraitIcon(PI_DEATHWARD); // is it ok?
@@ -2436,20 +2599,21 @@ int fx_death_ward (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//408 HolyPower
int fx_holy_power (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_holy_power (%2d)\n", fx->Opcode);
+ if(0) print("fx_holy_power(%2d)", fx->Opcode);
if (target->SetSpellState( SS_HOLYPOWER)) return FX_APPLIED;
if (enhanced_effects) {
target->AddPortraitIcon(PI_HOLYPOWER);
target->SetColorMod(0xff, RGBModifier::ADD, 20, 0x80, 0x80, 0x80);
}
+ STAT_ADD(IE_DAMAGEBONUS, 4);
return FX_APPLIED;
}
//409 RighteousWrath
int fx_righteous_wrath (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_righteous_wrath (%2d) Type: %d\n", fx->Opcode, fx->Parameter2);
+ if(0) print("fx_righteous_wrath(%2d) Type: %d", fx->Opcode, fx->Parameter2);
if (fx->Parameter2)
{
if (target->SetSpellState( SS_RIGHTEOUS2)) return FX_APPLIED;
@@ -2489,14 +2653,23 @@ int fx_summon_enemy (Scriptable* Owner, Actor* target, Effect* fx)
//412 Control2
-static EffectRef fx_protection_from_evil_ref = { "ProtectionFromEvil", -1 };
-
int fx_control (Scriptable* Owner, Actor* target, Effect* fx)
{
//prot from evil deflects it
if (target->fxqueue.HasEffect(fx_protection_from_evil_ref)) return FX_NOT_APPLIED;
- if (0) printf( "fx_control (%2d)\n", fx->Opcode);
+ //check for slippery mind feat success
+ Game *game = core->GetGame();
+ if (fx->FirstApply && target->HasFeat(FEAT_SLIPPERY_MIND)) {
+ fx->Parameter3 = 1;
+ fx->Parameter4 = game->GameTime+core->Time.round_size;
+ }
+
+ if (fx->Parameter3 && fx->Parameter4<game->GameTime) {
+ fx->Parameter3 = 0;
+ if (target->GetSavingThrow(IE_SAVEVSSPELL,0) ) return FX_NOT_APPLIED;
+ }
+ if(0) print("fx_control(%2d)", fx->Opcode);
bool enemyally = true;
if (Owner->Type==ST_ACTOR) {
enemyally = ((Actor *) Owner)->GetStat(IE_EA)>EA_GOODCUTOFF; //or evilcutoff?
@@ -2505,14 +2678,13 @@ int fx_control (Scriptable* Owner, Actor* target, Effect* fx)
switch(fx->Parameter2)
{
case 0:
- displaymsg->DisplayConstantStringName(STR_CHARMED, 0xf0f0f0, target);
+ displaymsg->DisplayConstantStringName(STR_CHARMED, DMC_WHITE, target);
break;
case 1:
- displaymsg->DisplayConstantStringName(STR_DIRECHARMED, 0xf0f0f0, target)
-;
+ displaymsg->DisplayConstantStringName(STR_DIRECHARMED, DMC_WHITE, target);
break;
default:
- displaymsg->DisplayConstantStringName(STR_CONTROLLED, 0xf0f0f0, target);
+ displaymsg->DisplayConstantStringName(STR_CONTROLLED, DMC_WHITE, target);
break;
}
@@ -2526,8 +2698,7 @@ int fx_control (Scriptable* Owner, Actor* target, Effect* fx)
//i put them there because the first bit is sanctuary
int fx_visual_effect_iwd2 (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- //
- if (0) printf( "fx_visual_effect_iwd2 (%2d) Type: %d\n", fx->Opcode, fx->Parameter2);
+ if(0) print("fx_visual_effect_iwd2(%2d) Type: %d", fx->Opcode, fx->Parameter2);
unsigned int type = fx->Parameter2;
if (type<32) {
switch(type) {
@@ -2548,10 +2719,22 @@ int fx_visual_effect_iwd2 (Scriptable* /*Owner*/, Actor* target, Effect* fx)
break;
case OV_SEVENEYES:
target->SetOverlay(OV_SEVENEYES2);
- // some more
+ break;
+ case OV_LATH1:
+ target->SetOverlay(OV_LATH2);
+ break;
+ case OV_GLATH1:
+ target->SetOverlay(OV_GLATH2);
+ break;
+ case OV_FIRESHIELD1:
+ target->SetOverlay(OV_FIRESHIELD2);
+ break;
+ case OV_ICESHIELD1:
+ target->SetOverlay(OV_ICESHIELD2);
+ break;
}
+ //the sanctuary stat is handled in SetOverlay
target->SetOverlay(type);
- //STAT_BIT_OR(IE_SANCTUARY, 1<<type);
return FX_APPLIED;
}
return FX_NOT_APPLIED;
@@ -2560,7 +2743,7 @@ int fx_visual_effect_iwd2 (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//414 ResilientSphere
int fx_resilient_sphere (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_resilient_sphere (%2d)\n", fx->Opcode);
+ if(0) print("fx_resilient_sphere(%2d)", fx->Opcode);
target->SetSpellState(SS_HELD|SS_RESILIENT);
STATE_SET(STATE_HELPLESS);
if (enhanced_effects) {
@@ -2573,7 +2756,7 @@ int fx_resilient_sphere (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//415 Barkskin
int fx_barkskin (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_barkskin (%2d)\n", fx->Opcode);
+ if(0) print("fx_barkskin(%2d)", fx->Opcode);
if (target->SetSpellState( SS_BARKSKIN)) return FX_APPLIED;
int bonus;
@@ -2586,7 +2769,8 @@ int fx_barkskin (Scriptable* /*Owner*/, Actor* target, Effect* fx)
} else {
bonus=3;
}
- STAT_ADD(IE_ARMORCLASS,bonus);
+ target->AC.HandleFxBonus(bonus, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
+
if (enhanced_effects) {
target->AddPortraitIcon(PI_BARKSKIN);
target->SetGradient(2);
@@ -2597,7 +2781,7 @@ int fx_barkskin (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//416 BleedingWounds
int fx_bleeding_wounds (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_bleeding_wounds (%2d): Damage: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_bleeding_wounds(%2d): Damage: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//also this effect is executed every update
ieDword damage;
@@ -2627,7 +2811,7 @@ seconds:
break;
}
//percent
- target->Damage(damage, DAMAGE_POISON, Owner);
+ target->Damage(damage, DAMAGE_POISON, Owner, fx->IsVariable, fx->SavingThrowType);
target->AddPortraitIcon(PI_BLEEDING);
return FX_APPLIED;
}
@@ -2639,7 +2823,7 @@ seconds:
int fx_area_effect (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_area_effect (%2d) Radius: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2);
+ if(0) print("fx_area_effect(%2d) Radius: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
//this effect ceases to affect dead targets (probably on frozen and stoned too)
Game *game = core->GetGame();
@@ -2683,7 +2867,7 @@ int fx_area_effect (Scriptable* Owner, Actor* target, Effect* fx)
//bit 1 repeat or only once
if (fx->Parameter2&AE_REPEAT) {
- return FX_APPLIED;
+ return FX_APPLIED;
}
return FX_NOT_APPLIED;
}
@@ -2691,7 +2875,7 @@ int fx_area_effect (Scriptable* Owner, Actor* target, Effect* fx)
//418 FreeAction2
int fx_free_action_iwd2 (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_free_action_iwd2 (%2d)\n", fx->Opcode);
+ if(0) print("fx_free_action_iwd2(%2d)", fx->Opcode);
if (target->SetSpellState( SS_FREEACTION)) return FX_APPLIED;
// immunity to the following effects, coded in the effects:
@@ -2712,7 +2896,7 @@ int fx_free_action_iwd2 (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//same as the sleep effect, but different icon
int fx_unconsciousness (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_unconsciousness (%2d): Type: %d\n", fx->Opcode, fx->Parameter2);
+ if(0) print("fx_unconsciousness(%2d): Type: %d", fx->Opcode, fx->Parameter2);
STATE_SET(STATE_HELPLESS|STATE_SLEEP);
if (fx->Parameter2) {
target->SetSpellState(SS_NOAWAKE);
@@ -2729,7 +2913,7 @@ int fx_unconsciousness (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//421 EntropyShield
int fx_entropy_shield (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_entropy_shield (%2d)\n", fx->Opcode);
+ if(0) print("fx_entropy_shield(%2d)", fx->Opcode);
if (target->SetSpellState( SS_ENTROPY)) return FX_APPLIED;
if (!fx->Resource[0]) {
strnuprcpy(fx->Resource, "entropy", sizeof(ieResRef)-1);
@@ -2754,7 +2938,7 @@ int fx_entropy_shield (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//422 StormShell
int fx_storm_shell (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_storm_shell (%2d)\n", fx->Opcode);
+ if(0) print("fx_storm_shell(%2d)", fx->Opcode);
if (target->SetSpellState(SS_STORMSHELL)) return FX_APPLIED;
STAT_ADD(IE_RESISTFIRE, 15);
STAT_ADD(IE_RESISTCOLD, 15);
@@ -2769,7 +2953,7 @@ int fx_storm_shell (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//423 ProtectionFromElements
int fx_protection_from_elements (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_protection_from_elements (%2d)\n", fx->Opcode);
+ if(0) print("fx_protection_from_elements(%2d)", fx->Opcode);
if (target->SetSpellState( SS_ELEMPROT)) return FX_APPLIED;
target->AddPortraitIcon(PI_ELEMPROT);
STAT_ADD(IE_RESISTFIRE, 15);
@@ -2793,7 +2977,7 @@ int fx_aegis (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
ieDword tmp;
- if (0) printf( "fx_aegis (%2d)\n", fx->Opcode);
+ if(0) print("fx_aegis(%2d)", fx->Opcode);
//gives immunity against:
//0xda stoneskin
//0x9a entangle
@@ -2844,11 +3028,11 @@ int fx_aegis (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//427 ExecutionerEyes
int fx_executioner_eyes (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_executioner_eyes (%2d)\n", fx->Opcode);
+ if(0) print("fx_executioner_eyes(%2d)", fx->Opcode);
if (target->SetSpellState( SS_EXECUTIONER)) return FX_APPLIED;
STAT_ADD(IE_CRITICALHITBONUS, 4);
- STAT_ADD(IE_TOHIT, 4);
+ target->ToHit.HandleFxBonus(4, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
if (enhanced_effects) {
target->AddPortraitIcon(PI_EXECUTIONER);
@@ -2859,12 +3043,31 @@ int fx_executioner_eyes (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//428 Death3 (also a death effect)
-//429 WhenStruckUseEffectList
+//429 EffectsOnStruck (a much simpler version of CastSpellOnCondition)
+int fx_effects_on_struck (Scriptable* Owner, Actor* target, Effect* fx)
+{
+ Map *map = target->GetCurrentArea();
+ if (!map) return FX_APPLIED;
+
+ Actor *actor = map->GetActorByGlobalID(target->LastHitter);
+ if (!actor) {
+ return FX_APPLIED;
+ }
+
+ const TriggerEntry *entry = target->GetMatchingTrigger(trigger_hitby, TEF_PROCESSED_EFFECTS);
+ if (entry!=NULL) {
+ ieDword dist = GetSpellDistance(fx->Resource, target);
+ if (!dist) return FX_APPLIED;
+ if (PersonalDistance(target, actor) > dist) return FX_APPLIED;
+ core->ApplySpell(fx->Resource, actor, Owner, fx->Power);
+ }
+ return FX_APPLIED;
+}
//430 ProjectileUseEffectList
int fx_projectile_use_effect_list (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_projectile_use_effect_list (%2d) Type: %d Spell:%s\n", fx->Opcode, fx->Parameter2, fx->Resource);
+ if(0) print("fx_projectile_use_effect_list(%2d) Type: %d Spell:%s", fx->Opcode, fx->Parameter2, fx->Resource);
if (!Owner) {
return FX_NOT_APPLIED;
@@ -2897,7 +3100,7 @@ int fx_projectile_use_effect_list (Scriptable* Owner, Actor* target, Effect* fx)
int fx_energy_drain (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_energy_drain (%2d) Type: %d\n", fx->Opcode, fx->Parameter1);
+ if(0) print("fx_energy_drain(%2d) Type: %d", fx->Opcode, fx->Parameter1);
if (!fx->Parameter1) {
return FX_NOT_APPLIED;
}
@@ -2922,19 +3125,25 @@ int fx_energy_drain (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//432 TortoiseShell
int fx_tortoise_shell (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_tortoise_shell (%2d) Type: %d\n", fx->Opcode, fx->Parameter2);
+ if(0) print("fx_tortoise_shell(%2d) Hits: %d", fx->Opcode, fx->Parameter1);
+ if (!fx->Parameter1) {
+ return FX_NOT_APPLIED;
+ }
+
if (target->SetSpellState( SS_TORTOISE)) return FX_NOT_APPLIED;
if (enhanced_effects) {
target->AddPortraitIcon(PI_TORTOISE);
target->SetOverlay(OV_TORTOISE);
}
+ target->SetSpellState(SS_HELD);
+ STATE_SET(STATE_HELPLESS);
return FX_APPLIED;
}
//433 Blink
int fx_blink (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_blink (%2d) Type: %d\n", fx->Opcode, fx->Parameter2);
+ if(0) print("fx_blink(%2d) Type: %d", fx->Opcode, fx->Parameter2);
if (target->SetSpellState( SS_BLINK)) return FX_APPLIED;
@@ -2942,7 +3151,7 @@ int fx_blink (Scriptable* /*Owner*/, Actor* target, Effect* fx)
ieDword Trans = fx->Parameter4;
if (fx->Parameter3) {
if (Trans>=240) {
- fx->Parameter3=0;
+ fx->Parameter3 = 0;
} else {
Trans+=16;
}
@@ -2968,7 +3177,7 @@ int fx_blink (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//434 PersistentUseEffectList
int fx_persistent_use_effect_list (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_persistent_use_effect_list (%2d) Interval: %d Resource: %.8s\n", fx->Opcode, fx->Parameter1, fx->Resource);
+ if(0) print("fx_persistent_use_effect_list(%2d) Interval: %d Resource: %.8s", fx->Opcode, fx->Parameter1, fx->Resource);
if (fx->Parameter3) {
fx->Parameter3--;
} else {
@@ -2979,36 +3188,69 @@ int fx_persistent_use_effect_list (Scriptable* Owner, Actor* target, Effect* fx)
}
//435 DayBlindness
+//for this effect to work, apply it repeatedly on targets
int fx_day_blindness (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_day_blindness (%2d) Amount: %d\n", fx->Opcode, fx->Parameter2);
- if (target->SetSpellState(SS_DAYBLINDNESS)) return FX_NOT_APPLIED;
+ if(0) print("fx_day_blindness(%2d) Amount: %d", fx->Opcode, fx->Parameter2);
+ Map *map = target->GetCurrentArea();
+ if (!map) {
+ return FX_NOT_APPLIED;
+ }
+
+ //extended night IS needed, even though IWD2's extended night isn't the same as in BG2 (no separate tileset)
+ if ((map->AreaType&(AT_OUTDOOR|AT_DAYNIGHT|AT_EXTENDED_NIGHT)) == AT_EXTENDED_NIGHT) {
+ return FX_NOT_APPLIED;
+ }
+ //drop the effect when day came
+ if (!core->GetGame()->IsDay()) {
+ return FX_NOT_APPLIED;
+ }
+
+ //don't let it work twice
+ if (target->SetSpellState(SS_DAYBLINDNESS)) {
+ return FX_NOT_APPLIED;
+ }
+
// medium hack (better than original)
// the original used explicit race/subrace values
ieDword penalty;
- if (check_iwd_targeting(Owner, target, 0, 82)) penalty = 2; //dark elf
+ //the original engine let the effect stay on non affected races, doing the same so the spell state sticks
+ if (check_iwd_targeting(Owner, target, 0, 82)) penalty = 1; //dark elf
else if (check_iwd_targeting(Owner, target, 0, 84)) penalty = 2; //duergar
- else penalty = 0;
+ else return FX_APPLIED;
- STAT_ADD(IE_SAVEFORTITUDE, penalty);
- STAT_ADD(IE_SAVEREFLEX, penalty);
- STAT_ADD(IE_SAVEWILL, penalty);
+ target->AddPortraitIcon(PI_DAYBLINDNESS);
+
+ //saving throw penalty (bigger is better in iwd2)
+ STAT_SUB(IE_SAVEFORTITUDE, penalty);
+ STAT_SUB(IE_SAVEREFLEX, penalty);
+ STAT_SUB(IE_SAVEWILL, penalty);
//for compatibility reasons
- STAT_ADD(IE_SAVEVSBREATH, penalty);
- STAT_ADD(IE_SAVEVSSPELL, penalty);
+ STAT_SUB(IE_SAVEVSBREATH, penalty);
+ STAT_SUB(IE_SAVEVSSPELL, penalty);
+ //bigger is better in iwd2
+ target->ToHit.HandleFxBonus(-penalty, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
- //TODO: implement the rest
+ //decrease all skills by 1
+ for(int i=0;i<32;i++) {
+ int stat = target->GetSkillStat(i);
+ if (stat<0) break;
+ STAT_SUB(stat, 1);
+ }
return FX_APPLIED;
}
//436 DamageReduction
int fx_damage_reduction (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_damage_reduction (%2d) Amount: %d\n", fx->Opcode, fx->Parameter2);
- STAT_SET(IE_RESISTSLASHING, fx->Parameter2*5);
- STAT_SET(IE_RESISTCRUSHING, fx->Parameter2*5);
- STAT_SET(IE_RESISTPIERCING, fx->Parameter2*5);
+ if(0) print("fx_damage_reduction(%2d) Hits: %d Strength: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
+
+ // most of the uses have damage coresponding to this formula (eg. 5/+1, 15/+3)
+ if (!fx->Parameter1) fx->Parameter1 = 5*fx->Parameter2;
+ STAT_ADD(IE_RESISTSLASHING, fx->Parameter1);
+ STAT_ADD(IE_RESISTCRUSHING, fx->Parameter1);
+ STAT_ADD(IE_RESISTPIERCING, fx->Parameter1);
return FX_APPLIED;
}
@@ -3016,14 +3258,24 @@ int fx_damage_reduction (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//modifies character animations to look like clerics of same gender/race
int fx_disguise (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_disguise (%2d) Amount: %d\n", fx->Opcode, fx->Parameter2);
+ if(0) print("fx_disguise(%2d) Amount: %d", fx->Opcode, fx->Parameter2);
+ if (fx->Parameter1) {
+ //
+ if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
+ BASE_SET(IE_ANIMATION_ID, fx->Parameter1);
+ } else {
+ STAT_SET(IE_ANIMATION_ID, fx->Parameter1);
+ }
+ return FX_PERMANENT;
+ }
+
ieDword anim = BASE_GET(IE_ANIMATION_ID);
- if (anim>=0x6000 || anim<=0x6fff) {
+ if (anim>=0x6000 && anim<=0x6fff) {
STAT_SET(IE_ANIMATION_ID, anim&0x600f);
return FX_APPLIED;
}
- if (anim>=0x5000 || anim<=0x5fff) {
+ if (anim>=0x5000 && anim<=0x5fff) {
STAT_SET(IE_ANIMATION_ID, anim&0x500f);
return FX_APPLIED;
}
@@ -3034,8 +3286,14 @@ int fx_disguise (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//438 HeroicInspiration
int fx_heroic_inspiration (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_heroic_inspiration (%2d)\n", fx->Opcode);
+ if(0) print("fx_heroic_inspiration(%2d)", fx->Opcode);
+ if (target->GetSafeStat(IE_HITPOINTS)*2>=target->GetSafeStat(IE_MAXHITPOINTS)) return FX_APPLIED;
+
+ target->AddPortraitIcon(PI_HEROIC);
+ //+1 bab and damage
+ STAT_ADD( IE_DAMAGEBONUS, 1);
+ STAT_ADD( IE_HITBONUS, 1);
//+1 to all saves
STAT_ADD( IE_SAVEFORTITUDE, 1);
STAT_ADD( IE_SAVEREFLEX, 1);
@@ -3052,57 +3310,107 @@ int fx_heroic_inspiration (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//440 BarbarianRage
int fx_barbarian_rage (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
{
- if (0) printf( "fx_barbarian_rage (%2d) Amount:%d\n", fx->Opcode, fx->Parameter1);
+ if(0) print("fx_barbarian_rage(%2d) Amount:%d", fx->Opcode, fx->Parameter1);
//TODO: implement this
return FX_APPLIED;
}
//441 MovementRateModifier4 (same as others)
-//442 Unknown (needs research)
+//442 Cleave
+int fx_cleave (Scriptable* /*Owner*/, Actor* target, Effect* fx)
+{
+ if(0) print("fx_cleave(%2d) Amount:%d", fx->Opcode, fx->Parameter1);
+ //just remain dormant after first apply for the remaining duration (possibly disabling more cleaves)
+ if (!fx->FirstApply) return FX_APPLIED;
+ Map *map = target->GetCurrentArea();
+ if (!map) return FX_NOT_APPLIED;
+
+ //reset attackcount to a previous number and hack the current opponent to another enemy nearby
+ //SeeCore returns the closest living enemy
+ //FIXME:the previous opponent must be dead by now, or this code won't work
+ if (SeeCore(target, Enemy, false) ) {
+ Actor *enemy = map->GetActorByGlobalID(target->LastSeen);
+ //50 is more like our current weapon range
+ if (enemy && (PersonalDistance(enemy, target)<50) && target->LastSeen!=target->LastTarget) {
+ displaymsg->DisplayConstantStringNameValue(STR_CLEAVE, DMC_WHITE, target, fx->Parameter1);
+ target->attackcount=fx->Parameter1;
+ target->FaceTarget(enemy);
+ target->LastTarget=target->LastSeen;
+ //linger around for more
+ return FX_APPLIED;
+ }
+ }
+ //no opponent found, nothing to do
+ return FX_NOT_APPLIED;
+}
//443 MissileDamageReduction
int fx_missile_damage_reduction (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_missile_damage_reduction (%2d) Amount:%d\n", fx->Opcode, fx->Parameter1);
- STAT_SET(IE_RESISTMISSILE, fx->Parameter1);
- //TODO: didn't set the pluses
+ if(0) print("fx_missile_damage_reduction(%2d) Amount:%d", fx->Opcode, fx->Parameter1);
+ // most of the uses have damage coresponding to this formula (eg. 5/+1, 15/+3)
+ if (!fx->Parameter1) fx->Parameter1 = 5*fx->Parameter2;
+ STAT_ADD(IE_RESISTMISSILE, fx->Parameter1);
return FX_APPLIED;
}
//444 TensersTransformation
int fx_tenser_transformation (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_tenser_transformation (%2d)\n", fx->Opcode);
+ if(0) print("fx_tenser_transformation(%2d)", fx->Opcode);
if (target->SetSpellState( SS_TENSER)) return FX_APPLIED;
- STAT_SUB(IE_ARMORCLASS, 2);
+
+ if (fx->FirstApply) {
+ fx->Parameter3=core->Roll(fx->CasterLevel, 6, 0);
+ fx->Parameter4=core->Roll(2,4,0);
+ fx->Parameter5=core->Roll(2,4,0);
+ BASE_ADD(IE_HITPOINTS, fx->Parameter3); // FIXME: permanent
+ }
+
+ target->AC.HandleFxBonus(4, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
+ // FIXME: should actually increase the base, so extra attacks can be gained
+ // but then the effect would be permanent and Actor::GetNumberOfAttacks doesn't handle effects yet
+ target->ToHit.HandleFxBonus(fx->CasterLevel/2, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
+ STAT_ADD(IE_SAVEFORTITUDE, 5);
+ STAT_ADD(IE_MAXHITPOINTS, fx->Parameter3);
+ STAT_ADD(IE_STR, fx->Parameter4);
+ STAT_ADD(IE_CON, fx->Parameter5);
if (enhanced_effects) {
+ target->AddPortraitIcon(PI_TENSER);
target->SetGradient(0x3e);
}
+
return FX_APPLIED;
}
-//445 Unknown (empty function in iwd2)
+//445 SlipperyMind (the original removed charm when the effect itself was about to be removed)
+
+int fx_slippery_mind (Scriptable* /*Owner*/, Actor* target, Effect* fx)
+{
+ if(0) print("fx_slippery_mind(%2d)", fx->Opcode);
+ target->fxqueue.RemoveAllEffects(fx_charm_ref);
+ return FX_NOT_APPLIED;
+}
//446 SmiteEvil
int fx_smite_evil (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_smite_evil (%2d)\n", fx->Opcode);
+ if(0) print("fx_smite_evil(%2d)", fx->Opcode);
target->SetSpellState(SS_SMITEEVIL);
+ int chrmod = target->GetAbilityBonus(IE_CHR);
+ if (chrmod > 0) {
+ target->ToHit.HandleFxBonus(chrmod, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
+ }
+ STAT_ADD(IE_DAMAGEBONUS, target->GetPaladinLevel());
return FX_NOT_APPLIED;
}
//447 Restoration
-
-static EffectRef fx_disease_ref = { "Disease", -1 };
-static EffectRef fx_int_ref = { "IntelligenceModifier", -1 };
-static EffectRef fx_wis_ref = { "WisdomModifier", -1 };
-static EffectRef fx_cha_ref = { "CharismaModifier", -1 };
-
int fx_restoration (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_restoration (%2d)\n", fx->Opcode);
+ if(0) print("fx_restoration(%2d)", fx->Opcode);
target->fxqueue.RemoveAllEffectsWithParam(fx_disease_ref, 4);
target->fxqueue.RemoveAllEffectsWithParam(fx_disease_ref, 5);
target->fxqueue.RemoveAllEffectsWithParam(fx_disease_ref, 6);
@@ -3125,10 +3433,10 @@ int fx_restoration (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//448 AlicornLance
int fx_alicorn_lance (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_alicorn_lance (%2d)\n", fx->Opcode);
+ if(0) print("fx_alicorn_lance(%2d)", fx->Opcode);
if (target->SetSpellState( SS_ALICORNLANCE)) return FX_APPLIED;
////target->AddPortraitIcon(PI_ALICORN); //no portrait icon
- STAT_SUB(IE_ARMORCLASS, 2);
+ target->AC.HandleFxBonus(-2, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
//color glow
if (enhanced_effects) {
target->SetColorMod(0xff, RGBModifier::ADD, 1, 0xb9, 0xb9, 0xb9);
@@ -3184,7 +3492,7 @@ Actor *GetRandomEnemySeen(Map *map, Actor *origin)
int fx_call_lightning (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_call_lightning (%2d)\n", fx->Opcode);
+ if(0) print("fx_call_lightning(%2d)", fx->Opcode);
//this effect ceases to affect dead targets (probably on frozen and stoned too)
if (STATE_GET(STATE_DEAD)) {
@@ -3201,13 +3509,13 @@ int fx_call_lightning (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//timing
fx->TimingMode=FX_DURATION_DELAY_PERMANENT;
- fx->Duration=core->GetGame()->GameTime+70*15;
+ fx->Duration=core->GetGame()->GameTime+70*AI_UPDATE_TIME;
fx->Parameter1--;
//calculate victim (an opponent of target)
Actor *victim = GetRandomEnemySeen(map, target);
if (!victim) {
- displaymsg->DisplayConstantStringName(STR_LIGHTNING_DISS, 0xf0f0f0, target);
+ displaymsg->DisplayConstantStringName(STR_LIGHTNING_DISS, DMC_WHITE, target);
return ret;
}
@@ -3218,14 +3526,14 @@ int fx_call_lightning (Scriptable* /*Owner*/, Actor* target, Effect* fx)
}
//how style
- victim->Damage(DICE_ROLL(0), DAMAGE_ELECTRICITY, target);
+ victim->Damage(DICE_ROLL(0), DAMAGE_ELECTRICITY, target, fx->IsVariable, fx->SavingThrowType);
return ret;
}
//450 GlobeInvulnerability
int fx_globe_invulnerability (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_globe_invulnerability (%2d)\n", fx->Opcode);
+ if(0) print("fx_globe_invulnerability(%2d)", fx->Opcode);
int state;
int icon;
int value;
@@ -3253,21 +3561,49 @@ int fx_globe_invulnerability (Scriptable* /*Owner*/, Actor* target, Effect* fx)
}
//451 LowerResistance
+//the original effect has two unwanted quirks
+//1. strength is always caster level * 2
+//2. non cumulative, which causes stronger effects canceled out
int fx_lower_resistance (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_lower_resistance (%2d)\n", fx->Opcode);
- if (target->SetSpellState( SS_LOWERRESIST)) return FX_APPLIED;
+ if(0) print("fx_lower_resistance(%2d)", fx->Opcode);
+ int modifier;
- STAT_SUB(IE_RESISTMAGIC, 15);
+ switch(fx->Parameter2) {
+ case 0: default:
+ //original IWD2 style
+ if (target->SetSpellState( SS_LOWERRESIST)) return FX_APPLIED;
+ modifier = fx->CasterLevel * 2;
+ if (modifier>50) modifier = 50;
+ break;
+ case 1:
+ //like IWD2, but stronger effects are not canceled out
+ target->SetSpellState( SS_LOWERRESIST);
+ modifier = fx->CasterLevel * 2;
+ if (modifier>50) modifier = 50;
+ break;
+ case 2:
+ //GemRB style, non cumulative
+ if (target->SetSpellState( SS_LOWERRESIST)) return FX_APPLIED;
+ modifier = fx->Parameter1;
+ break;
+ case 3:
+ //GemRB style, cumulative
+ target->SetSpellState( SS_LOWERRESIST);
+ modifier = fx->Parameter1;
+ break;
+ }
+ //FIXME: the original never goes below zero, but i think it is prone to bugs that way
+ //it is easier to handle this by simply not printing negative values
+ STAT_SUB(IE_RESISTMAGIC, modifier);
return FX_APPLIED;
}
//452 Bane
-static EffectRef fx_bless_ref = { "Bless", -1 };
int fx_bane (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_bane (%2d)\n", fx->Opcode);
+ if(0) print("fx_bane(%2d)", fx->Opcode);
if (target->SetSpellState( SS_BANE)) return FX_NOT_APPLIED;
//do this once
@@ -3277,110 +3613,154 @@ int fx_bane (Scriptable* /*Owner*/, Actor* target, Effect* fx)
target->AddPortraitIcon(PI_BANE);
target->SetColorMod(0xff, RGBModifier::ADD, 20, 0, 0, 0x80);
}
- STAT_ADD( IE_TOHIT, -fx->Parameter1);
+ target->ToHit.HandleFxBonus(-fx->Parameter1, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
STAT_ADD( IE_MORALEBREAK, -fx->Parameter1);
return FX_APPLIED;
}
//453 PowerAttack
-static EffectRef fx_expertise_ref = { "Expertise", -1 };
-
int fx_power_attack (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_power_attack (%2d)\n", fx->Opcode);
+ if(0) print("fx_power_attack(%2d)", fx->Opcode);
- if (fx->FirstApply) {
- if (target->HasSpellState(SS_EXPERTISE)) {
- //stopped using feat: Expertise
- target->fxqueue.RemoveAllEffects(fx_expertise_ref);
- }
- }
- unsigned int x;
- x = target->GetFeat(FEAT_POWER_ATTACK);
- if (x>5) x=5;
- for(unsigned int i = 0;i<5;i++) {
- if (i<x) {
- target->SetSpellState( SS_POWERATTACK);
- } else {
- //FIXME: doubt we need UnSetSpellState
- //target->UnSetSpellState(SS_POWERATTACK+x);
+ if (!target->HasFeat(FEAT_POWER_ATTACK)) return FX_NOT_APPLIED;
+ if (!target->PCStats) return FX_NOT_APPLIED;
+
+ ieDword x=target->PCStats->ExtraSettings[ES_POWERATTACK];
+ if (x) {
+ if (target->SetSpellState(SS_POWERATTACK+x)) return FX_NOT_APPLIED;
+ if (fx->FirstApply) {
+ //disable mutually exclusive feats
+ target->PCStats->ExtraSettings[ES_EXPERTISE] = 0;
+
+ //set new modal feat
+ displaymsg->DisplayConstantStringNameString(STR_USING_FEAT, DMC_WHITE, STR_POWERATTACK, target);
}
}
- return FX_APPLIED;
+
+ displaymsg->DisplayConstantStringNameString(STR_STOPPED_FEAT, DMC_WHITE, STR_POWERATTACK, target);
+ return FX_NOT_APPLIED;
}
//454 Expertise
-static EffectRef fx_powerattack_ref = { "PowerAttack", -1 };
-
int fx_expertise (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
//expertise feat:
//convert positive base attack bonus into AC (dodge bonus)
//up to feat_expertise count (player's choice)
- if (0) printf( "fx_expertise (%2d)\n", fx->Opcode);
- if (fx->FirstApply) {
- if (target->HasSpellState(SS_POWERATTACK)) {
- target->fxqueue.RemoveAllEffects(fx_powerattack_ref);
- }
- }
- unsigned int x;
+ if(0) print("fx_expertise(%2d)", fx->Opcode);
- x = target->GetFeat(FEAT_EXPERTISE);
- if (x>5) x=5;
- for(unsigned int i = 0;i<5;i++) {
- if (i<x) {
- target->SetSpellState(SS_EXPERTISE+x);
- } else {
- //FIXME: doubt we need UnSetSpellState
- //target->UnSetSpellState(SS_EXPERTISE+x);
+ if (!target->HasFeat(FEAT_EXPERTISE)) return FX_NOT_APPLIED;
+ if (!target->PCStats) return FX_NOT_APPLIED;
+
+ ieDword x=target->PCStats->ExtraSettings[ES_EXPERTISE];
+ if (x) {
+ if (target->SetSpellState(SS_EXPERTISE+x)) return FX_NOT_APPLIED;
+ if (fx->FirstApply) {
+ //disable mutually exclusive feats
+ target->PCStats->ExtraSettings[ES_POWERATTACK] = 0;
+
+ //set new modal feat
+ displaymsg->DisplayConstantStringNameString(STR_USING_FEAT, DMC_WHITE, STR_EXPERTISE, target);
}
}
- return FX_APPLIED;
+
+ displaymsg->DisplayConstantStringNameString(STR_STOPPED_FEAT, DMC_WHITE, STR_EXPERTISE, target);
+ return FX_NOT_APPLIED;
}
//455 ArterialStrike
-static EffectRef fx_hamstring_ref = { "HamString", -1 };
-
+//apply arterial strike spell on backstab, this is by default the same as in iwd2
int fx_arterial_strike (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_arterial_strike (%2d)\n", fx->Opcode);
- if (fx->FirstApply) {
- if (target->HasSpellState(SS_HAMSTRING)) {
- target->fxqueue.RemoveAllEffects(fx_hamstring_ref);
+ if(0) print("fx_arterial_strike(%2d)", fx->Opcode);
+ //arterial strike doesn't work for npcs?
+ if (!target->HasFeat(FEAT_ARTERIAL_STRIKE)) return FX_NOT_APPLIED;
+ if (!target->PCStats) return FX_NOT_APPLIED;
+
+ if (target->PCStats->ExtraSettings[ES_ARTERIAL]) {
+ if (target->SetSpellState( SS_ARTERIAL)) return FX_NOT_APPLIED; //don't apply it twice
+
+ if (fx->FirstApply) {
+ if (!fx->Resource[0]) {
+ strnuprcpy(fx->Resource, "artstr", sizeof(ieResRef)-1);
+ }
+ //disable mutually exclusive feats
+ target->PCStats->ExtraSettings[ES_HAMSTRING] = 0;
+
+ //set new modal feat
+ displaymsg->DisplayConstantStringNameString(STR_USING_FEAT, DMC_WHITE, STR_ARTERIAL, target);
+ }
+ if (target->BackstabResRef[0]=='*') {
+ memcpy(target->BackstabResRef, fx->Resource, sizeof(ieResRef));
}
- }
- if (target->SetSpellState( SS_ARTERIAL)) {
- //TODO:display using feat arterial strike
return FX_APPLIED;
}
- return FX_APPLIED;
+
+ //stop arterial
+ displaymsg->DisplayConstantStringNameString(STR_STOPPED_FEAT, DMC_WHITE, STR_ARTERIAL, target);
+ return FX_NOT_APPLIED;
}
//456 HamString
-static EffectRef fx_arterialstrike_ref = { "ArterialStrike", -1 };
-
+//apply hamstring spell on backstab, this is by default the same as in iwd2
int fx_hamstring (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_hamstring (%2d)\n", fx->Opcode);
- if (fx->FirstApply) {
- if (target->HasSpellState(SS_ARTERIAL)) {
- target->fxqueue.RemoveAllEffects(fx_arterialstrike_ref);
+ if(0) print("fx_hamstring(%2d)", fx->Opcode);
+ //hamstring doesn't work for npcs?
+ if (!target->HasFeat(FEAT_HAMSTRING)) return FX_NOT_APPLIED;
+ if (!target->PCStats) return FX_NOT_APPLIED;
+
+ if (target->PCStats->ExtraSettings[ES_HAMSTRING]) {
+ if (target->SetSpellState( SS_HAMSTRING)) return FX_NOT_APPLIED; //don't apply it twice
+
+ if (fx->FirstApply) {
+ if (!fx->Resource[0]) {
+ strnuprcpy(fx->Resource, "hamstr", sizeof(ieResRef)-1);
+ }
+ //disable mutually exclusive feats
+ target->PCStats->ExtraSettings[ES_ARTERIAL] = 0;
+
+ //set new modal feat
+ displaymsg->DisplayConstantStringNameString(STR_USING_FEAT, DMC_WHITE, STR_HAMSTRING, target);
+ }
+ if (target->BackstabResRef[0]=='*') {
+ memcpy(target->BackstabResRef, fx->Resource, sizeof(ieResRef));
}
- }
- if (target->SetSpellState( SS_HAMSTRING)) {
- //TODO:display using feat hamstring
return FX_APPLIED;
}
- return FX_APPLIED;
+
+ //stop hamstring
+ displaymsg->DisplayConstantStringNameString(STR_STOPPED_FEAT, DMC_WHITE, STR_HAMSTRING, target);
+ return FX_NOT_APPLIED;
}
//457 RapidShot
int fx_rapid_shot (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_rapid_shot (%2d)\n", fx->Opcode);
- if (target->SetSpellState( SS_RAPIDSHOT)) return FX_APPLIED;
- //TODO:
- return FX_APPLIED;
+ if(0) print("fx_rapid_shot(%2d)", fx->Opcode);
+ //rapid shot doesn't work for npcs?
+ if (!target->HasFeat(FEAT_RAPID_SHOT)) return FX_NOT_APPLIED;
+ if (!target->PCStats) return FX_NOT_APPLIED;
+
+ if (target->PCStats->ExtraSettings[ES_RAPIDSHOT]) {
+ if (target->SetSpellState( SS_RAPIDSHOT)) return FX_NOT_APPLIED; //don't apply it twice
+
+ target->ToHit.HandleFxBonus(-2, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
+ if (fx->FirstApply) {
+ //disable mutually exclusive feats
+ //none i know of
+
+ //set new modal feat
+ displaymsg->DisplayConstantStringNameString(STR_USING_FEAT, DMC_WHITE, STR_RAPIDSHOT, target);
+ }
+
+ return FX_APPLIED;
+ }
+
+ //stop rapidshot
+ displaymsg->DisplayConstantStringNameString(STR_STOPPED_FEAT, DMC_WHITE, STR_RAPIDSHOT, target);
+ return FX_NOT_APPLIED;
}
#include "plugindef.h"
@@ -3389,4 +3769,3 @@ GEMRB_PLUGIN(0x4F172B2, "Effect opcodes for the icewind branch of the games")
PLUGIN_INITIALIZER(RegisterIWDOpcodes)
PLUGIN_CLEANUP(Cleanup)
END_PLUGIN()
-
diff --git a/gemrb/plugins/KEYImporter/CMakeLists.txt b/gemrb/plugins/KEYImporter/CMakeLists.txt
index de14082..3404514 100644
--- a/gemrb/plugins/KEYImporter/CMakeLists.txt
+++ b/gemrb/plugins/KEYImporter/CMakeLists.txt
@@ -1 +1 @@
-ADD_GEMRB_PLUGIN (KEYImporter KEYImporter.cpp Dictionary.cpp)
+ADD_GEMRB_PLUGIN (KEYImporter KEYImporter.cpp)
diff --git a/gemrb/plugins/KEYImporter/Dictionary.cpp b/gemrb/plugins/KEYImporter/Dictionary.cpp
deleted file mode 100644
index 73be141..0000000
--- a/gemrb/plugins/KEYImporter/Dictionary.cpp
+++ /dev/null
@@ -1,226 +0,0 @@
-/* GemRB - Infinity Engine Emulator
- * Copyright (C) 2003 The GemRB Project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- *
- */
-
-#include "Dictionary.h"
-
-#include "globals.h"
-#include "win32def.h"
-
-#include <ctype.h>
-
-/////////////////////////////////////////////////////////////////////////////
-// inlines
-
-inline unsigned int Dictionary::MyHashKey(const char* key, unsigned int type) const
-{
- unsigned int nHash = type;
- for (int i = 0; i < KEYSIZE && key[i]; i++) {
- nHash = ( nHash << 5 ) + nHash + tolower( key[i] );
- }
- return nHash;
-}
-inline int Dictionary::GetCount() const
-{
- return m_nCount;
-}
-inline bool Dictionary::IsEmpty() const
-{
- return m_nCount == 0;
-}
-/////////////////////////////////////////////////////////////////////////////
-// out of lines
-Dictionary::Dictionary(int nBlockSize, int nHashTableSize)
-{
- assert( nBlockSize > 0 );
- assert( nHashTableSize > 16 );
-
- m_pHashTable = NULL;
- m_nHashTableSize = nHashTableSize; // default size
- m_nCount = 0;
- m_pFreeList = NULL;
- m_pBlocks = NULL;
- m_nBlockSize = nBlockSize;
-}
-
-void Dictionary::InitHashTable(unsigned int nHashSize, bool bAllocNow)
- //Used to force allocation of a hash table or to override the default
- //hash table size of (which is fairly small)
-{
- assert( m_nCount == 0 );
- assert( nHashSize > 16 );
-
- if (m_pHashTable != NULL) {
- // free hash table
- free( m_pHashTable);
- m_pHashTable = NULL;
- }
-
- if (bAllocNow) {
- m_pHashTable = (Dictionary::MyAssoc **) malloc( sizeof( MyAssoc * ) * nHashSize );
- memset( m_pHashTable, 0, sizeof( MyAssoc * ) * nHashSize );
- }
- m_nHashTableSize = nHashSize;
-}
-
-void Dictionary::RemoveAll()
-{
- //removed the part about freeing values/keys
- //because the complete value/key pair is stored in the
- //node which is freed in the memblocks
-
- // free hash table
- free( m_pHashTable );
- m_pHashTable = NULL;
-
- m_nCount = 0;
- m_pFreeList = NULL;
-
- // free memory blocks
- MemBlock* p = m_pBlocks;
- while (p != NULL) {
- MemBlock* pNext = p->pNext;
- free( p );
- p = pNext;
- }
-
- m_pBlocks = NULL;
-}
-
-Dictionary::~Dictionary()
-{
- RemoveAll();
-}
-
-Dictionary::MyAssoc* Dictionary::NewAssoc()
-{
- if (m_pFreeList == NULL) {
- // add another block
- Dictionary::MemBlock* newBlock = ( Dictionary::MemBlock* ) malloc(m_nBlockSize * sizeof( Dictionary::MyAssoc ) + sizeof( Dictionary::MemBlock ));
- assert( newBlock != NULL ); // we must have something
-
- newBlock->pNext = m_pBlocks;
- m_pBlocks = newBlock;
-
- // chain them into free list
- Dictionary::MyAssoc* pAssoc = ( Dictionary::MyAssoc* )
- ( newBlock + 1 );
- for (int i = 0; i < m_nBlockSize; i++) {
- pAssoc->pNext = m_pFreeList;
- m_pFreeList = pAssoc++;
- }
- }
-
- Dictionary::MyAssoc* pAssoc = m_pFreeList;
- m_pFreeList = m_pFreeList->pNext;
- m_nCount++;
- assert( m_nCount > 0 ); // make sure we don't overflow
-#ifdef _DEBUG
- pAssoc->key[0] = 0;
- pAssoc->value = 0xcccccccc;
-#endif
- return pAssoc;
-}
-
-void Dictionary::FreeAssoc(Dictionary::MyAssoc* pAssoc)
-{
- pAssoc->pNext = m_pFreeList;
- m_pFreeList = pAssoc;
- m_nCount--;
- assert( m_nCount >= 0 ); // make sure we don't underflow
-
- // if no more elements, cleanup completely
- if (m_nCount == 0) {
- RemoveAll();
- }
-}
-
-Dictionary::MyAssoc* Dictionary::GetAssocAt(const ieResRef key,
- unsigned int type, unsigned int& nHash) const
- // find association (or return NULL)
-{
- nHash = MyHashKey( key, type ) % m_nHashTableSize;
-
- if (m_pHashTable == NULL) {
- return NULL;
- }
-
- // see if it exists
- MyAssoc* pAssoc;
- for (pAssoc = m_pHashTable[nHash];
- pAssoc != NULL;
- pAssoc = pAssoc->pNext) {
- if (type == pAssoc->type) {
- if (!strnicmp( pAssoc->key, key, KEYSIZE )) {
- return pAssoc;
- }
- }
- }
- return NULL;
-}
-
-bool Dictionary::Lookup(const ieResRef key, unsigned int type,
- unsigned int& rValue) const
-{
- unsigned int nHash;
-
- MyAssoc* pAssoc = GetAssocAt( key, type, nHash );
- if (pAssoc == NULL) {
- return false;
- } // not in map
-
- rValue = pAssoc->value;
- return true;
-}
-
-void Dictionary::RemoveAt(const ieResRef key, unsigned int type)
-{
- unsigned int nHash;
- MyAssoc* pAssoc = GetAssocAt( key, type, nHash );
-
- if (pAssoc != NULL) {
- FreeAssoc(pAssoc);
- }
-}
-
-void Dictionary::SetAt(const ieResRef key, unsigned int type, unsigned int value)
-{
- int i;
- unsigned int nHash;
- MyAssoc* pAssoc=GetAssocAt( key, type, nHash );
-
- if (pAssoc == NULL) {
- if (m_pHashTable == NULL)
- InitHashTable( m_nHashTableSize );
-
- // it doesn't exist, add a new Association
- pAssoc = NewAssoc();
- // put into hash table
- pAssoc->pNext = m_pHashTable[nHash];
- m_pHashTable[nHash] = pAssoc;
- }
- for(i=0;i<KEYSIZE && key[i];i++) {
- pAssoc->key[i]=tolower(key[i]);
- }
- for(;i<KEYSIZE;i++) {
- pAssoc->key[i]=0;
- }
- pAssoc->type = type;
- pAssoc->value = value;
-}
diff --git a/gemrb/plugins/KEYImporter/Dictionary.h b/gemrb/plugins/KEYImporter/Dictionary.h
deleted file mode 100644
index ce8aee3..0000000
--- a/gemrb/plugins/KEYImporter/Dictionary.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* GemRB - Infinity Engine Emulator
- * Copyright (C) 2003 |Avenger|
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- *
- */
-
-#if !defined(DICTIONARY_H)
-#define DICTIONARY_H
-
-#include "SClassID.h"
-#include "win32def.h"
-
-#include <cstring>
-
-/////////////////////////////////////////////////////////////////////////////
-// Dictionary<unsigned long, VALUE>
-
-#define KEYSIZE 8
-
-class Dictionary //: public CObject
-{
-protected:
- // Association
- struct MyAssoc {
- MyAssoc* pNext;
- char key[KEYSIZE]; //not ieResRef!
- SClass_ID type;
- unsigned int value;
- };
- struct MemBlock {
- MemBlock* pNext;
- };
-
-public:
- // Construction
- Dictionary(int nBlockSize = 10, int nHashTableSize = 32769);
-
- // Attributes
- // number of elements
- int GetCount() const;
- bool IsEmpty() const;
-
- // Lookup
- bool Lookup(const ieResRef key, unsigned int type, unsigned int& rValue) const;
-
- // Operations
- void SetAt(const ieResRef key, unsigned int type, unsigned int newValue);
- void RemoveAt(const ieResRef key, unsigned int type);
- void RemoveAll();
- void InitHashTable(unsigned int hashSize, bool bAllocNow = true);
-
- // Implementation
-protected:
- MyAssoc** m_pHashTable;
- unsigned int m_nHashTableSize;
- int m_nCount;
- MyAssoc* m_pFreeList;
- MemBlock* m_pBlocks;
- int m_nBlockSize;
-
- MyAssoc* NewAssoc();
- void FreeAssoc(MyAssoc*);
- MyAssoc* GetAssocAt(const ieResRef, unsigned int, unsigned int&) const;
- unsigned int MyHashKey(const ieResRef, unsigned int) const;
-
-public:
- ~Dictionary();
-};
-
-#endif // !defined(DICTIONARY_H)
diff --git a/gemrb/plugins/KEYImporter/KEYImporter.cpp b/gemrb/plugins/KEYImporter/KEYImporter.cpp
index a444a49..e0e36bf 100644
--- a/gemrb/plugins/KEYImporter/KEYImporter.cpp
+++ b/gemrb/plugins/KEYImporter/KEYImporter.cpp
@@ -23,11 +23,13 @@
#include "win32def.h"
#include "globals.h"
-#include "ArchiveImporter.h"
+#include "IndexedArchive.h"
#include "Interface.h"
#include "ResourceDesc.h"
#include "System/FileStream.h"
+using namespace GemRB;
+
KEYImporter::KEYImporter(void)
{
description = NULL;
@@ -90,37 +92,15 @@ static void FindBIF(BIFEntry *entry)
return;
}
- if (core->GameOnCD) {
- int mask = 1<<2;
- for(int cd = 1; cd<=MAX_CD; cd++) {
- if ((entry->BIFLocator & mask) != 0) {
- entry->cd = cd;
- break;
- }
- mask += mask;
- }
-
- if (!entry->cd) {
- printStatus( "ERROR", LIGHT_RED );
- printf( "Cannot find %s... Resource unavailable.\n",
- entry->name );
- entry->found = false;
- return;
- }
- entry->found = PathExists(entry, core->CD[entry->cd-1]);
- return;
- }
-
for (int i = 0; i < MAX_CD; i++) {
if (PathExists(entry, core->CD[i]) ) {
entry->found = true;
+ entry->cd = i;
return;
}
}
- printMessage( "KEYImporter", " ", WHITE );
- printf( "Cannot find %s...", entry->name );
- printStatus( "ERROR", LIGHT_RED );
+ Log(ERROR, "KEYImporter", "Cannot find %s...", entry->name);
}
bool KEYImporter::Open(const char *resfile, const char *desc)
@@ -128,51 +108,44 @@ bool KEYImporter::Open(const char *resfile, const char *desc)
free(description);
description = strdup(desc);
if (!core->IsAvailable( IE_BIF_CLASS_ID )) {
- printf( "[ERROR]\nAn Archive Plug-in is not Available\n" );
+ Log(ERROR, "KEYImporter", "An Archive Plug-in is not Available");
return false;
}
unsigned int i;
// NOTE: Interface::Init has already resolved resfile.
- printMessage( "KEYImporter", "Opening ", WHITE );
- printf( "%s...", resfile );
- FileStream* f = new FileStream();
- if (!f->Open( resfile )) {
+ Log(MESSAGE, "KEYImporter", "Opening %s...", resfile);
+ FileStream* f = FileStream::OpenFile(resfile);
+ if (!f) {
// Check for backslashes (false escape characters)
// this check probably belongs elsewhere (e.g. ResolveFilePath)
if (strstr( resfile, "\\ " )) {
- printf("%s", "\nEscaped space(s) detected in path!. Do not escape spaces in your GamePath! " );
+ Log(MESSAGE, "KEYImporter", "Escaped space(s) detected in path!. Do not escape spaces in your GamePath!");
}
- printStatus( "ERROR", LIGHT_RED );
- printMessage( "KEYImporter", "Cannot open Chitin.key\n", LIGHT_RED );
- textcolor( WHITE );
- delete( f );
+ Log(ERROR, "KEYImporter", "Cannot open Chitin.key");
+ Log(ERROR, "KeyImporter", "This means you set the GamePath config variable incorrectly.");
+ Log(ERROR, "KeyImporter", "It must point to the directory that holds a readable Chitin.key");
return false;
}
- printStatus( "OK", LIGHT_GREEN );
- printMessage( "KEYImporter", "Checking file type...", WHITE );
+ Log(MESSAGE, "KEYImporter", "Checking file type...");
char Signature[8];
f->Read( Signature, 8 );
if (strncmp( Signature, "KEY V1 ", 8 ) != 0) {
- printStatus( "ERROR", LIGHT_RED );
- printMessage( "KEYImporter", "File has an Invalid Signature.\n",
- LIGHT_RED );
- textcolor( WHITE );
+ Log(ERROR, "KEYImporter", "File has an Invalid Signature.");
delete( f );
return false;
}
- printStatus( "OK", LIGHT_GREEN );
- printMessage( "KEYImporter", "Reading Resources...\n", WHITE );
+ Log(MESSAGE, "KEYImporter", "Reading Resources...");
ieDword BifCount, ResCount, BifOffset, ResOffset;
f->ReadDword( &BifCount );
f->ReadDword( &ResCount );
f->ReadDword( &BifOffset );
f->ReadDword( &ResOffset );
- printMessage( "KEYImporter", " ", WHITE );
- printf( "BIF Files Count: %d (Starting at %d Bytes)\n", BifCount,
- BifOffset );
- printMessage( "KEYImporter", " ", WHITE );
- printf( "RES Count: %d (Starting at %d Bytes)\n", ResCount, ResOffset );
+ Log(MESSAGE, "KEYImporter", "BIF Files Count: %d (Starting at %d Bytes)",
+ BifCount, BifOffset );
+ Log(MESSAGE, "KEYImporter", "RES Count: %d (Starting at %d Bytes)",
+ ResCount, ResOffset);
f->Seek( BifOffset, GEM_STREAM_START );
+
ieDword BifLen, ASCIIZOffset;
ieWord ASCIIZLen;
for (i = 0; i < BifCount; i++) {
@@ -190,36 +163,36 @@ bool KEYImporter::Open(const char *resfile, const char *desc)
if (be.name[p] == '\\' || be.name[p] == ':')
be.name[p] = PathDelimiter;
}
- if (be.name[0] == PathDelimiter) {
- // totl has '\data\zcMHar.bif' in the key file, and the CaseSensitive
- // code breaks with that extra slash, so simple fix: remove it
- ASCIIZLen--;
- for (int p = 0; p < ASCIIZLen; p++)
- be.name[p] = be.name[p + 1];
- // (if you change this, try moving to ar9700 for testing)
- }
FindBIF(&be);
biffiles.push_back( be );
}
f->Seek( ResOffset, GEM_STREAM_START );
- resources.InitHashTable( ResCount < 17 ? 17 : ResCount );
+
+ MapKey key;
+ ieDword ResLocator;
+
+ // limit to 32k buckets
+ // only ~1% of the bg2 entries are of bucket lenght >4
+ resources.init(ResCount > 32 * 1024 ? 32 * 1024 : ResCount, ResCount);
+
for (i = 0; i < ResCount; i++) {
- RESEntry re;
- f->ReadResRef( re.ResRef );
- f->ReadWord( &re.Type );
- f->ReadDword( &re.ResLocator );
- resources.SetAt( re.ResRef, re.Type, re.ResLocator );
+ f->ReadResRef(key.ref);
+ f->ReadWord(&key.type);
+ f->ReadDword(&ResLocator);
+
+ // seems to be always the last entry?
+ if (key.ref[0] != 0)
+ resources.set(key, ResLocator);
}
- printMessage( "KEYImporter", "Resources Loaded...", WHITE );
- printStatus( "OK", LIGHT_GREEN );
+
+ Log(MESSAGE, "KEYImporter", "Resources Loaded...");
delete( f );
return true;
}
bool KEYImporter::HasResource(const char* resname, SClass_ID type)
{
- unsigned int ResLocator;
- return resources.Lookup( resname, type, ResLocator );
+ return resources.has(resname, type);
}
bool KEYImporter::HasResource(const char* resname, const ResourceDesc &type)
@@ -227,47 +200,37 @@ bool KEYImporter::HasResource(const char* resname, const ResourceDesc &type)
return HasResource(resname, type.GetKeyType());
}
-static void FindBIFOnCD(BIFEntry *entry)
+DataStream* KEYImporter::GetStream(const char *resname, ieWord type)
{
- if (file_exists(entry->path)) {
- entry->found = true;
- return;
- }
+ if (type == 0)
+ return NULL;
- core->WaitForDisc(entry->cd, entry->name);
+ const ieDword *ResLocator = resources.get(resname, type);
+ if (!ResLocator)
+ return 0;
- entry->found = PathExists(entry, core->CD[entry->cd-1]);
-}
+ unsigned int bifnum = ( *ResLocator & 0xFFF00000 ) >> 20;
-DataStream* KEYImporter::GetStream(const char *resname, ieWord type)
-{
- unsigned int ResLocator;
+ if (!biffiles[bifnum].found) {
+ print("Cannot find %s... Resource unavailable.",
+ biffiles[bifnum].name );
+ return NULL;
+ }
- if (type == 0)
+ PluginHolder<IndexedArchive> ai(IE_BIF_CLASS_ID);
+ if (ai->OpenArchive( biffiles[bifnum].path ) == GEM_ERROR) {
+ print("Cannot open archive %s", biffiles[bifnum].path);
return NULL;
- if (resources.Lookup( resname, type, ResLocator )) {
- int bifnum = ( ResLocator & 0xFFF00000 ) >> 20;
-
- if (core->GameOnCD && (biffiles[bifnum].cd != 0))
- FindBIFOnCD(&biffiles[bifnum]);
- if (!biffiles[bifnum].found) {
- printf( "Cannot find %s... Resource unavailable.\n",
- biffiles[bifnum].name );
- return NULL;
- }
+ }
- PluginHolder<ArchiveImporter> ai(IE_BIF_CLASS_ID);
- if (ai->OpenArchive( biffiles[bifnum].path ) == GEM_ERROR) {
- printf("Cannot open archive %s\n", biffiles[bifnum].path );
- return NULL;
- }
- DataStream* ret = ai->GetStream( ResLocator, type );
- if (ret) {
- strnlwrcpy( ret->filename, resname, 8 );
- strcat( ret->filename, core->TypeExt( type ) );
- return ret;
- }
+ DataStream* ret = ai->GetStream( *ResLocator, type );
+ if (ret) {
+ strnlwrcpy( ret->filename, resname, 8 );
+ strcat( ret->filename, "." );
+ strcat( ret->filename, core->TypeExt( type ) );
+ return ret;
}
+
return NULL;
}
diff --git a/gemrb/plugins/KEYImporter/KEYImporter.h b/gemrb/plugins/KEYImporter/KEYImporter.h
index 4ea85f9..f6399df 100644
--- a/gemrb/plugins/KEYImporter/KEYImporter.h
+++ b/gemrb/plugins/KEYImporter/KEYImporter.h
@@ -23,20 +23,19 @@
#include "ResourceSource.h"
-#include "Dictionary.h"
+#include "IndexedArchive.h"
+#include "PluginMgr.h"
+
+#include "StringMap.h"
#include <vector>
+namespace GemRB {
+
class DataStream;
class Resource;
class ResourceDesc;
-struct RESEntry {
- ieResRef ResRef;
- ieWord Type;
- ieDword ResLocator;
-};
-
struct BIFEntry {
char* name;
ieWord BIFLocator;
@@ -45,11 +44,93 @@ struct BIFEntry {
bool found;
};
+struct KEYCache {
+ KEYCache() { bifnum = 0xffffffff; }
+
+ unsigned int bifnum;
+ PluginHolder<IndexedArchive> plugin;
+};
+
+// the key for this specific hashmap
+struct MapKey {
+ ieResRef ref;
+ ieWord type;
+
+ MapKey()
+ {
+ }
+};
+
+// hash template for the above key for this hashmap
+template<>
+struct HashKey<MapKey> {
+ // hash without MapKey construction
+ static inline unsigned int hash(const ieResRef ref, SClass_ID type)
+ {
+ unsigned int h = type;
+ const char *c = ref;
+
+ for (unsigned int i = 0; *c && i < sizeof(ieResRef); ++i)
+ h = (h << 5) + h + tolower(*c++);
+
+ return h;
+ }
+
+ static inline unsigned int hash(const MapKey &key)
+ {
+ return hash(key.ref, key.type);
+ }
+
+ // equal check without MapKey construction
+ static inline bool equals(const MapKey &a, const ieResRef ref, SClass_ID type)
+ {
+ if (a.type != type)
+ return false;
+
+ return stricmp(a.ref, ref) == 0;
+ }
+
+ static inline bool equals(const MapKey &a, const MapKey &b)
+ {
+ return equals(a, b.ref, b.type);
+ }
+
+ static inline void copy(MapKey &a, const MapKey &b)
+ {
+ a.type = b.type;
+ strncpy(a.ref, b.ref, sizeof(ieResRef));
+ }
+};
+
+// FIXME: The captialization of KEYMap is important, since there is also a KeyMap defined in core.
+class KEYMap : public HashMap<MapKey, ieDword> {
+public:
+ // lookup without MapKey construction
+ const ieDword *get(const ieResRef ref, SClass_ID type) const
+ {
+ if (!isInitialized())
+ return NULL;
+
+ incAccesses();
+
+ for (Entry *e = getBucketByHash(HashKey<MapKey>::hash(ref, type)); e; e = e->next)
+ if (HashKey<MapKey>::equals(e->key, ref, type))
+ return &e->value;
+
+ return NULL;
+ }
+
+ // lookup without MapKey construction
+ bool has(const ieResRef ref, SClass_ID type) const
+ {
+ return get(ref, type) != NULL;
+ }
+};
class KEYImporter : public ResourceSource {
private:
std::vector< BIFEntry> biffiles;
- Dictionary resources;
+ KEYMap resources;
/** Gets the stream assoicated to a RESKey */
DataStream *GetStream(const char *resname, ieWord type);
@@ -65,4 +146,6 @@ public:
DataStream* GetResource(const char* resname, const ResourceDesc &type);
};
+}
+
#endif
diff --git a/gemrb/plugins/KEYImporter/Makefile.am b/gemrb/plugins/KEYImporter/Makefile.am
index 28a935b..505f4cb 100644
--- a/gemrb/plugins/KEYImporter/Makefile.am
+++ b/gemrb/plugins/KEYImporter/Makefile.am
@@ -1,3 +1,3 @@
plugin_LTLIBRARIES = KEYImporter.la
KEYImporter_la_LDFLAGS = -module -avoid-version -shared
-KEYImporter_la_SOURCES = Dictionary.cpp Dictionary.h KEYImporter.cpp KEYImporter.h
+KEYImporter_la_SOURCES = KEYImporter.cpp KEYImporter.h
diff --git a/gemrb/plugins/MOSImporter/MOSImporter.cpp b/gemrb/plugins/MOSImporter/MOSImporter.cpp
index 660e1f9..6cfbe98 100644
--- a/gemrb/plugins/MOSImporter/MOSImporter.cpp
+++ b/gemrb/plugins/MOSImporter/MOSImporter.cpp
@@ -23,22 +23,22 @@
#include "RGBAColor.h"
#include "win32def.h"
-#include "Compressor.h"
+#include "FileCache.h"
#include "Interface.h"
#include "Video.h"
-#include "System/CachedFileStream.h"
-#include "System/FileStream.h"
-static ieDword red_mask = 0xff000000;
-static ieDword green_mask = 0x00ff0000;
-static ieDword blue_mask = 0x0000ff00;
+using namespace GemRB;
+
+static ieDword red_mask = 0x00ff0000;
+static ieDword green_mask = 0x0000ff00;
+static ieDword blue_mask = 0x000000ff;
MOSImporter::MOSImporter(void)
{
if (DataStream::IsEndianSwitch()) {
- red_mask = 0x000000ff;
- green_mask = 0x0000ff00;
- blue_mask = 0x00ff0000;
+ red_mask = 0x0000ff00;
+ green_mask = 0x00ff0000;
+ blue_mask = 0xff000000;
}
}
@@ -52,36 +52,13 @@ bool MOSImporter::Open(DataStream* stream)
char Signature[8];
str->Read( Signature, 8 );
if (strncmp( Signature, "MOSCV1 ", 8 ) == 0) {
- char cpath[_MAX_PATH];
- strcpy( cpath, core->CachePath );
- strcat( cpath, stream->filename );
- FILE* exist_in_cache = fopen( cpath, "rb" );
- if (exist_in_cache) {
- //File was previously cached, using local copy
- delete( str );
- fclose( exist_in_cache );
- FileStream* s = new FileStream();
- s->Open( cpath );
- str = s;
- str->Read( Signature, 8 );
- } else {
- //No file found in Cache, Decompressing and storing for further use
- str->Seek( 4, GEM_CURRENT_POS );
-
- if (!core->IsAvailable( PLUGIN_COMPRESSION_ZLIB )) {
- printf( "No Compression Manager Available.\nCannot Load Compressed Mos File.\n" );
- return false;
- }
- FILE* newfile = fopen( cpath, "wb" );
- PluginHolder<Compressor> comp(PLUGIN_COMPRESSION_ZLIB);
- comp->Decompress( newfile, str );
- fclose( newfile );
- delete( str );
- FileStream* s = new FileStream();
- s->Open( cpath );
- str = s;
- str->Read( Signature, 8 );
- }
+ str->Seek( 4, GEM_CURRENT_POS );
+ DataStream* cached = CacheCompressedStream(stream, stream->filename);
+ delete str;
+ if (!cached)
+ return false;
+ str = cached;
+ str->Read( Signature, 8 );
}
if (strncmp( Signature, "MOS V1 ", 8 ) != 0) {
return false;
@@ -127,14 +104,14 @@ Sprite2D* MOSImporter::GetSprite2D()
( 4 * x * 64 );
for (int h = 0; h < bh; h++) {
for (int w = 0; w < bw; w++) {
- *startpixel = RevCol[*bp].a;
- startpixel++;
*startpixel = RevCol[*bp].b;
startpixel++;
*startpixel = RevCol[*bp].g;
startpixel++;
*startpixel = RevCol[*bp].r;
startpixel++;
+ *startpixel = RevCol[*bp].a;
+ startpixel++;
bp++;
}
startpixel = startpixel + ( Width * 4 ) - ( 4 * bw );
@@ -151,5 +128,5 @@ Sprite2D* MOSImporter::GetSprite2D()
#include "plugindef.h"
GEMRB_PLUGIN(0x167B73E, "MOS File Importer")
-PLUGIN_IE_RESOURCE(MOSImporter, ".mos", (ieWord)IE_MOS_CLASS_ID)
+PLUGIN_IE_RESOURCE(MOSImporter, "mos", (ieWord)IE_MOS_CLASS_ID)
END_PLUGIN()
diff --git a/gemrb/plugins/MOSImporter/MOSImporter.h b/gemrb/plugins/MOSImporter/MOSImporter.h
index b38e0ad..be834a2 100644
--- a/gemrb/plugins/MOSImporter/MOSImporter.h
+++ b/gemrb/plugins/MOSImporter/MOSImporter.h
@@ -23,6 +23,8 @@
#include "ImageMgr.h"
+namespace GemRB {
+
class MOSImporter : public ImageMgr {
private:
ieWord Width, Height, Cols, Rows;
@@ -36,4 +38,6 @@ public:
int GetHeight() { return (int) Height; }
};
+}
+
#endif
diff --git a/gemrb/plugins/MUSImporter/MUSImporter.cpp b/gemrb/plugins/MUSImporter/MUSImporter.cpp
index 1bb6b1c..8556a6e 100644
--- a/gemrb/plugins/MUSImporter/MUSImporter.cpp
+++ b/gemrb/plugins/MUSImporter/MUSImporter.cpp
@@ -27,6 +27,8 @@
#include "Interface.h"
#include "SoundMgr.h"
+using namespace GemRB;
+
static char musicsubfolder[6] = "music";
MUSImporter::MUSImporter()
@@ -74,13 +76,11 @@ bool MUSImporter::OpenPlaylist(const char* name)
}
char path[_MAX_PATH];
PathJoin(path, core->GamePath, musicsubfolder, name, NULL);
- printMessage("MUSImporter", "", WHITE);
- printf( "Loading %s...", path );
- if (!str->Open( path, true )) {
- printStatus("NOT FOUND", LIGHT_RED );
+ Log(MESSAGE, "MUSImporter", "Loading %s...", path);
+ if (!str->Open(path)) {
+ Log(ERROR, "MUSImporter", "Didn't find playlist '%s'.", path);
return false;
}
- printStatus("FOUND", LIGHT_GREEN );
int c = str->ReadLine( PLName, 32 );
while (c > 0) {
if (( PLName[c - 1] == ' ' ) || ( PLName[c - 1] == '\t' ))
@@ -193,7 +193,7 @@ void MUSImporter::Start()
} else {
PLnext = PLpos + 1;
if ((unsigned int) PLnext >= playlist.size())
- PLnext = -1;
+ PLnext = 0;
}
PlayMusic( PLpos );
core->GetAudioDrv()->Play();
@@ -318,7 +318,7 @@ void MUSImporter::PlayMusic(char* name)
} else {
core->GetAudioDrv()->Stop();
}
- printf( "Playing: %s\n", FName );
+ print("Playing: %s", FName);
}
bool MUSImporter::CurrentPlayList(const char* name) {
diff --git a/gemrb/plugins/MUSImporter/MUSImporter.h b/gemrb/plugins/MUSImporter/MUSImporter.h
index 1448b46..7f05945 100644
--- a/gemrb/plugins/MUSImporter/MUSImporter.h
+++ b/gemrb/plugins/MUSImporter/MUSImporter.h
@@ -28,6 +28,8 @@
#include <cstdio>
+namespace GemRB {
+
/**MUS PlayList Importer
*@author GemRB Development Team
*/
@@ -76,4 +78,6 @@ public:
bool CurrentPlayList(const char* name);
};
+}
+
#endif
diff --git a/gemrb/plugins/MVEPlayer/MVEPlayer.cpp b/gemrb/plugins/MVEPlayer/MVEPlayer.cpp
index 6ff83ca..e2449ec 100644
--- a/gemrb/plugins/MVEPlayer/MVEPlayer.cpp
+++ b/gemrb/plugins/MVEPlayer/MVEPlayer.cpp
@@ -32,6 +32,8 @@
#include <cassert>
#include <cstdio>
+using namespace GemRB;
+
static const char MVESignature[] = "Interplay MVE File\x1A";
static const int MVE_SIGNATURE_LEN = 19;
@@ -104,7 +106,7 @@ int MVEPlay::doPlay()
player.video_init(w, h);
if (!player.start_playback()) {
- printf("Failed to decode movie!\n");
+ print("Failed to decode movie!");
return 1;
}
@@ -115,6 +117,7 @@ int MVEPlay::doPlay()
}
video->DrawMovieSubtitle(0);
+ video->DestroyMovieScreen();
return 0;
}
@@ -183,5 +186,5 @@ void MVEPlay::queueBuffer(int stream, unsigned short bits,
#include "plugindef.h"
GEMRB_PLUGIN(0x218963DC, "MVE Video Player")
-PLUGIN_IE_RESOURCE(MVEPlay, ".mve", (ieWord)IE_MVE_CLASS_ID)
+PLUGIN_IE_RESOURCE(MVEPlay, "mve", (ieWord)IE_MVE_CLASS_ID)
END_PLUGIN()
diff --git a/gemrb/plugins/MVEPlayer/MVEPlayer.h b/gemrb/plugins/MVEPlayer/MVEPlayer.h
index 1a56438..bbc531d 100644
--- a/gemrb/plugins/MVEPlayer/MVEPlayer.h
+++ b/gemrb/plugins/MVEPlayer/MVEPlayer.h
@@ -28,6 +28,8 @@
#include "Interface.h"
+namespace GemRB {
+
class MVEPlay : public MoviePlayer {
friend class MVEPlayer;
private:
@@ -54,4 +56,6 @@ public:
int Play();
};
+}
+
#endif
diff --git a/gemrb/plugins/MVEPlayer/gstmvedemux.h b/gemrb/plugins/MVEPlayer/gstmvedemux.h
index c8908c2..c28145b 100644
--- a/gemrb/plugins/MVEPlayer/gstmvedemux.h
+++ b/gemrb/plugins/MVEPlayer/gstmvedemux.h
@@ -25,9 +25,11 @@
#include "win32def.h"
#include "globals.h"
+using namespace GemRB;
+
#define G_UNLIKELY(x) (x)
-#define GST_WARNING printf
-#define GST_ERROR printf
+#define GST_WARNING print
+#define GST_ERROR print
/* Define GET function for unaligned memory */
#define _GST_GET(__data, __idx, __size, __shift) \
diff --git a/gemrb/plugins/MVEPlayer/mve_player.cpp b/gemrb/plugins/MVEPlayer/mve_player.cpp
index b8edf7d..3cc520b 100644
--- a/gemrb/plugins/MVEPlayer/mve_player.cpp
+++ b/gemrb/plugins/MVEPlayer/mve_player.cpp
@@ -25,15 +25,15 @@
* Jens Granseuer <jensgr at gmx.net>
*/
-#if defined(__HAIKU__)
-#include <unistd.h>
-#endif
-
#include "mve_player.h"
#include "MVEPlayer.h"
#include "gstmvedemux.h"
#include "mve.h"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
/* mvevideodec8.cpp */
extern int ipvideo_decode_frame8 (const GstMveDemuxStream * s,
const unsigned char *data, unsigned short len);
@@ -44,6 +44,8 @@ extern int ipvideo_decode_frame16 (const GstMveDemuxStream * s,
extern void ipaudio_uncompress (short *buffer,
unsigned short buf_len, const unsigned char *data, unsigned char channels);
+namespace GemRB {
+
/*
* constructor: doesn't really do anything
*/
@@ -80,7 +82,7 @@ MVEPlayer::~MVEPlayer() {
if (audio_stream != -1) host->freeAudioStream(audio_stream);
if (video_skippedframes)
- printf("Warning: Had to drop %d video frame(s).\n", video_skippedframes);
+ print("Warning: Had to drop %d video frame(s).", video_skippedframes);
}
/*
@@ -103,7 +105,7 @@ bool MVEPlayer::start_playback() {
* The first two chunks contain audio and video initialisation, hopefully.
*/
if (!process_chunk() || !process_chunk()) {
- printf("Error: Failed to read initial movie chunks.\n");
+ print("Error: Failed to read initial movie chunks.");
return false;
}
@@ -147,7 +149,7 @@ bool MVEPlayer::request_data(unsigned int len) {
bool MVEPlayer::verify_header() {
if (!request_data(MVE_PREAMBLE_SIZE)) return false;
if (memcmp(buffer, MVE_PREAMBLE, MVE_PREAMBLE_SIZE) != 0) {
- printf("Error: MVE preamble didn't match\n");
+ print("Error: MVE preamble didn't match");
return false;
}
return true;
@@ -173,7 +175,7 @@ bool MVEPlayer::process_chunk() {
}
if (chunk_offset != chunk_size) {
- printf("Error: Decoded past the end of an MVE chunk\n");
+ print("Error: Decoded past the end of an MVE chunk");
return false;
}
@@ -228,7 +230,7 @@ bool MVEPlayer::process_segment(unsigned short len, unsigned char type, unsigned
/* ignore these */
break;
default:
- printf("Warning: Skipping unknown segment type 0x%02x", type);
+ Log(WARNING, "MVEPlayer", "Skipping unknown segment type 0x%02x", type);
}
return true;
@@ -297,8 +299,10 @@ void MVEPlayer::segment_create_timer() {
void MVEPlayer::segment_video_init(unsigned char version) {
unsigned short width = GST_READ_UINT16_LE(buffer) << 3;
unsigned short height = GST_READ_UINT16_LE(buffer + 2) << 3;
+/* count is unused
unsigned short count = 1;
if (version > 0) count = GST_READ_UINT16_LE(buffer + 4);
+*/
unsigned short temp = 0;
if (version > 1) temp = GST_READ_UINT16_LE(buffer + 6);
truecolour = !!temp;
@@ -339,7 +343,9 @@ void MVEPlayer::segment_video_palette() {
host->setPalette((unsigned char *)palette - (3 * palette_start), palette_start, palette_count);
}
+//appears to be unused
void MVEPlayer::segment_video_compressedpalette() {
+#if 0
char *data = buffer;
unsigned int i, j;
@@ -360,6 +366,7 @@ void MVEPlayer::segment_video_compressedpalette() {
}
}
}
+#endif
}
void MVEPlayer::segment_video_codemap(unsigned short size) {
@@ -419,7 +426,7 @@ void MVEPlayer::segment_audio_init(unsigned char version) {
audio_stream = host->setAudioStream();
if (audio_stream == -1) {
- printf("Error: MVE player couldn't open audio. Will play silently.\n");
+ print("Error: MVE player couldn't open audio. Will play silently.");
playsound = false;
return;
}
@@ -442,7 +449,7 @@ void MVEPlayer::segment_audio_init(unsigned char version) {
if (audio_buffer) free(audio_buffer);
audio_buffer = (short *)malloc(min_buffer_len);
-/* printf("Movie audio: Sample rate %d, %d channels, %d bit, requested buffer size 0x%02x, %s\n",
+/* print("Movie audio: Sample rate %d, %d channels, %d bit, requested buffer size 0x%02x, %s",
audio_sample_rate, audio_num_channels, audio_sample_size, min_buffer_len, audio_compressed ? "compressed" : "uncompressed");*/
}
@@ -471,3 +478,4 @@ void MVEPlayer::segment_audio_data(bool silent) {
}
}
+}
diff --git a/gemrb/plugins/MVEPlayer/mve_player.h b/gemrb/plugins/MVEPlayer/mve_player.h
index 77e1fb7..ffb0317 100644
--- a/gemrb/plugins/MVEPlayer/mve_player.h
+++ b/gemrb/plugins/MVEPlayer/mve_player.h
@@ -21,6 +21,10 @@
#ifndef MVE_PLAYER_H
#define MVE_PLAYER_H
+struct _GstMveDemuxStream;
+
+namespace GemRB {
+
class MVEPlayer {
protected:
class MVEPlay *host;
@@ -36,7 +40,7 @@ protected:
long timer_last_usec;
unsigned int frame_wait;
- struct _GstMveDemuxStream *video_data;
+ _GstMveDemuxStream *video_data;
unsigned short video_width;
unsigned short video_height;
unsigned short *video_back_buf;
@@ -90,4 +94,6 @@ public:
bool is_truecolour() { return truecolour; }
};
+}
+
#endif
diff --git a/gemrb/plugins/Makefile.am b/gemrb/plugins/Makefile.am
index b5a7361..c2d9ae3 100644
--- a/gemrb/plugins/Makefile.am
+++ b/gemrb/plugins/Makefile.am
@@ -30,11 +30,13 @@ SUBDIRS = \
PNGImporter \
PROImporter \
PSTOpcodes \
+ SAVImporter \
SDLVideo \
SPLImporter \
STOImporter \
TISImporter \
TLKImporter \
+ TTFImporter
WAVReader \
WEDImporter \
WMPImporter \
diff --git a/gemrb/plugins/NullSound/NullSound.cpp b/gemrb/plugins/NullSound/NullSound.cpp
index ee700e5..c0de29b 100644
--- a/gemrb/plugins/NullSound/NullSound.cpp
+++ b/gemrb/plugins/NullSound/NullSound.cpp
@@ -25,6 +25,8 @@
#include "AmbientMgr.h"
#include "SoundMgr.h"
+using namespace GemRB;
+
NullSound::NullSound(void)
{
XPos = 0;
@@ -82,11 +84,6 @@ bool NullSound::CanPlay()
return false;
}
-bool NullSound::IsSpeaking()
-{
- return false;
-}
-
void NullSound::UpdateListenerPos(int x, int y)
{
XPos = x;
diff --git a/gemrb/plugins/NullSound/NullSound.h b/gemrb/plugins/NullSound/NullSound.h
index 2261c56..96c5b2c 100644
--- a/gemrb/plugins/NullSound/NullSound.h
+++ b/gemrb/plugins/NullSound/NullSound.h
@@ -23,6 +23,8 @@
#include "Audio.h"
+namespace GemRB {
+
class NullSound : public Audio {
public:
NullSound(void);
@@ -35,7 +37,6 @@ public:
bool Pause();
bool Resume();
bool CanPlay();
- bool IsSpeaking();
void ResetMusics();
void UpdateListenerPos(int XPos, int YPos);
void GetListenerPos(int& XPos, int& YPos);
@@ -52,4 +53,6 @@ private:
int XPos, YPos;
};
+}
+
#endif
diff --git a/gemrb/plugins/NullSource/CMakeLists.txt b/gemrb/plugins/NullSource/CMakeLists.txt
new file mode 100644
index 0000000..19fdeb2
--- /dev/null
+++ b/gemrb/plugins/NullSource/CMakeLists.txt
@@ -0,0 +1 @@
+ADD_GEMRB_PLUGIN (NullSource NullSource.cpp )
diff --git a/gemrb/plugins/NullSource/NullSource.cpp b/gemrb/plugins/NullSource/NullSource.cpp
new file mode 100644
index 0000000..29b76da
--- /dev/null
+++ b/gemrb/plugins/NullSource/NullSource.cpp
@@ -0,0 +1,71 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "NullSource.h"
+
+#include "globals.h"
+#include "win32def.h"
+
+#include "Interface.h"
+#include "ResourceDesc.h"
+#include "System/FileStream.h"
+
+using namespace GemRB;
+
+NullSource::NullSource(void)
+{
+ description = NULL;
+}
+
+NullSource::~NullSource(void)
+{
+ free(description);
+}
+
+bool NullSource::Open(const char *, const char *desc)
+{
+ free(description);
+ description = strdup(desc);
+ return true;
+}
+
+bool NullSource::HasResource(const char*, SClass_ID)
+{
+ return false;
+}
+
+bool NullSource::HasResource(const char*, const ResourceDesc&)
+{
+ return false;
+}
+
+DataStream* NullSource::GetResource(const char*, SClass_ID)
+{
+ return NULL;
+}
+
+DataStream* NullSource::GetResource(const char*, const ResourceDesc&)
+{
+ return NULL;
+}
+
+#include "plugindef.h"
+
+GEMRB_PLUGIN(0xFA42E34A, "Null Resource Source")
+PLUGIN_CLASS(PLUGIN_RESOURCE_NULL, NullSource)
+END_PLUGIN()
diff --git a/gemrb/plugins/NullSource/NullSource.h b/gemrb/plugins/NullSource/NullSource.h
new file mode 100644
index 0000000..a48d2bb
--- /dev/null
+++ b/gemrb/plugins/NullSource/NullSource.h
@@ -0,0 +1,41 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef NULLSOURCE_H
+#define NULLSOURCE_H
+
+#include "ResourceSource.h"
+
+namespace GemRB {
+
+class NullSource : public ResourceSource {
+public:
+ NullSource(void);
+ virtual ~NullSource(void);
+ virtual bool Open(const char *filename, const char *description);
+ virtual bool HasResource(const char* resname, SClass_ID type);
+ virtual bool HasResource(const char* resname, const ResourceDesc &type);
+ virtual DataStream* GetResource(const char* resname, SClass_ID type);
+ virtual DataStream* GetResource(const char* resname, const ResourceDesc &type);
+};
+
+}
+
+#endif
diff --git a/gemrb/plugins/OGGReader/OGGReader.cpp b/gemrb/plugins/OGGReader/OGGReader.cpp
index 762ccfe..a290d89 100644
--- a/gemrb/plugins/OGGReader/OGGReader.cpp
+++ b/gemrb/plugins/OGGReader/OGGReader.cpp
@@ -18,6 +18,8 @@
#include "OGGReader.h"
+using namespace GemRB;
+
static size_t ovfd_read(void *ptr, size_t size, size_t nmemb, void *datasource)
{
DataStream *vb = (DataStream *) datasource;
@@ -84,7 +86,7 @@ bool OGGReader::Open(DataStream* stream)
res=ov_open_callbacks(str, &OggStream, NULL, 0, cbstruct);
if(res<0) {
- printMessage("Sound","Couldn't initialize vorbis!\n", LIGHT_RED);
+ Log(ERROR, "Sound", "Couldn't initialize vorbis!");
return false;
}
info = ov_info(&OggStream, -1);
@@ -124,5 +126,5 @@ int OGGReader::read_samples(short* buffer, int count)
#include "plugindef.h"
GEMRB_PLUGIN(0x18C310C3, "OGG File Importer")
-PLUGIN_RESOURCE(OGGReader, ".ogg")
+PLUGIN_RESOURCE(OGGReader, "ogg")
END_PLUGIN()
diff --git a/gemrb/plugins/OGGReader/OGGReader.h b/gemrb/plugins/OGGReader/OGGReader.h
index 159f8d7..b3beff8 100644
--- a/gemrb/plugins/OGGReader/OGGReader.h
+++ b/gemrb/plugins/OGGReader/OGGReader.h
@@ -30,6 +30,8 @@
#endif
#include <vorbis/vorbisfile.h>
+namespace GemRB {
+
class OGGReader : public SoundMgr {
private:
OggVorbis_File OggStream;
@@ -52,4 +54,6 @@ public:
int read_samples(short* buffer, int count);
};
+}
+
#endif
diff --git a/gemrb/plugins/OpenALAudio/AmbientMgrAL.cpp b/gemrb/plugins/OpenALAudio/AmbientMgrAL.cpp
index c5c6c53..c73309b 100644
--- a/gemrb/plugins/OpenALAudio/AmbientMgrAL.cpp
+++ b/gemrb/plugins/OpenALAudio/AmbientMgrAL.cpp
@@ -33,6 +33,8 @@
#include <SDL.h>
+using namespace GemRB;
+
// TODO: remove last dependencies on OpenAL, and then rename and move it?
// legal nop if already reset
@@ -65,7 +67,12 @@ void AmbientMgrAL::setAmbients(const std::vector<Ambient *> &a)
}
core->GetAudioDrv()->UpdateVolume( GEM_SND_VOL_AMBIENTS );
+#if SDL_VERSION_ATLEAST(1, 3, 0)
+ /* as of changeset 3a041d215edc SDL_CreateThread has a 'name' parameter */
+ player = SDL_CreateThread(&play, "AmbientMgrAL", (void *) this);
+#else
player = SDL_CreateThread(&play, (void *) this);
+#endif
}
void AmbientMgrAL::activate(const std::string &name)
@@ -157,6 +164,16 @@ unsigned int AmbientMgrAL::tick(unsigned int ticks)
return delay;
}
+void AmbientMgrAL::UpdateVolume(unsigned short volume)
+{
+ SDL_mutexP( mutex );
+ for (std::vector<AmbientSource *>::iterator it = ambientSources.begin(); it != ambientSources.end(); ++it) {
+ (*it) -> SetVolume( volume );
+ }
+ SDL_mutexV( mutex );
+}
+
+
AmbientMgrAL::AmbientSource::AmbientSource(const Ambient *a)
: stream(-1), ambient(a), lastticks(0), enqueued(0), loaded(false)
{
@@ -201,6 +218,7 @@ unsigned int AmbientMgrAL::AmbientSource::tick(unsigned int ticks, Point listene
if (stream >= 0) {
// release the stream without immediately stopping it
core->GetAudioDrv()->ReleaseStream(stream, false);
+ stream = -1;
}
return UINT_MAX;
}
@@ -222,6 +240,7 @@ unsigned int AmbientMgrAL::AmbientSource::tick(unsigned int ticks, Point listene
if (delay > 500) {
// release stream if we're inactive for a while
core->GetAudioDrv()->ReleaseStream(stream);
+ stream = -1;
}
return delay;
}
@@ -231,7 +250,11 @@ unsigned int AmbientMgrAL::AmbientSource::tick(unsigned int ticks, Point listene
if (stream < 0) {
// we need to allocate a stream
- stream = core->GetAudioDrv()->SetupNewStream(ambient->getOrigin().x, ambient->getOrigin().y, ambient->getHeight(), ambient->getGain(), (ambient->getFlags() & IE_AMBI_POINT), true);
+ unsigned int v = 100;
+
+ core->GetDictionary()->Lookup("Volume Ambients", v);
+ v *= ambient->getGain();
+ stream = core->GetAudioDrv()->SetupNewStream(ambient->getOrigin().x, ambient->getOrigin().y, ambient->getHeight(), v/100, (ambient->getFlags() & IE_AMBI_POINT), true);
if (stream == -1) {
// no streams available...
@@ -269,7 +292,7 @@ int AmbientMgrAL::AmbientSource::enqueue()
if (soundrefs.empty()) return -1;
if (stream < 0) return -1;
int index = rand() % soundrefs.size();
- //printf("Playing ambient %p, %s, %d/%ld on stream %d\n", (void*)this, soundrefs[index], index, soundrefs.size(), stream);
+ //print("Playing ambient %p, %s, %d/%ld on stream %d",(void*)this, soundrefs[index], index, soundrefs.size(), stream);
return core->GetAudioDrv()->QueueAmbient(stream, soundrefs[index]);
}
@@ -289,15 +312,6 @@ void AmbientMgrAL::AmbientSource::hardStop()
}
}
-void AmbientMgrAL::UpdateVolume(unsigned short volume)
-{
- SDL_mutexP( mutex );
- for (std::vector<AmbientSource *>::iterator it = ambientSources.begin(); it != ambientSources.end(); ++it) {
- (*it) -> SetVolume( volume );
- }
- SDL_mutexV( mutex );
-}
-
/* sets the overall volume (in percent)
* the final volume is affected by the specific ambient gain
*/
diff --git a/gemrb/plugins/OpenALAudio/AmbientMgrAL.h b/gemrb/plugins/OpenALAudio/AmbientMgrAL.h
index e276e67..96d7c67 100644
--- a/gemrb/plugins/OpenALAudio/AmbientMgrAL.h
+++ b/gemrb/plugins/OpenALAudio/AmbientMgrAL.h
@@ -41,6 +41,8 @@
#include <alc.h>
#endif
+namespace GemRB {
+
class Ambient;
class AmbientMgrAL : public AmbientMgr {
@@ -86,4 +88,6 @@ private:
SDL_cond *cond;
};
+}
+
#endif /* AMBIENTMGRAL_H */
diff --git a/gemrb/plugins/OpenALAudio/OpenALAudio.cpp b/gemrb/plugins/OpenALAudio/OpenALAudio.cpp
index cfd28ea..1150b79 100644
--- a/gemrb/plugins/OpenALAudio/OpenALAudio.cpp
+++ b/gemrb/plugins/OpenALAudio/OpenALAudio.cpp
@@ -25,24 +25,24 @@
#include <cassert>
#include <cstdio>
-bool checkALError(const char* msg, const char* status) {
+using namespace GemRB;
+
+bool checkALError(const char* msg, log_level level) {
int error = alGetError();
if (error != AL_NO_ERROR) {
- printMessage("OpenAL", msg, WHITE );
- printf (": 0x%x ", error);
- printStatus(status, YELLOW);
+ Log(level, "OpenAL", "%s: 0x%x - %s", msg, error, alGetString(error));
return true;
}
return false;
}
-void showALCError(const char* msg, const char* status, ALCdevice *device) {
+void showALCError(const char* msg, log_level level, ALCdevice *device) {
int error = alcGetError(device);
- printMessage("OpenAL", msg, WHITE );
if (error != AL_NO_ERROR) {
- printf (": 0x%x ", error);
+ Log(level, "OpenAL", "%s: 0x%x", msg, error);
+ } else {
+ Log(level, "OpenAL", "%s", msg);
}
- printStatus(status, YELLOW);
}
void OpenALSoundHandle::SetPos(int XPos, int YPos) {
@@ -53,6 +53,7 @@ void OpenALSoundHandle::SetPos(int XPos, int YPos) {
};
alSourcefv(parent->Source, AL_POSITION, SourcePos);
+ checkALError("Unable to set source position", WARNING);
}
bool OpenALSoundHandle::Playing() {
@@ -72,23 +73,34 @@ void OpenALSoundHandle::StopLooping() {
if (!parent) return;
alSourcei(parent->Source, AL_LOOPING, 0);
+ checkALError("Unable to stop audio loop", WARNING);
}
void AudioStream::ClearProcessedBuffers()
{
ALint processed = 0;
alGetSourcei( Source, AL_BUFFERS_PROCESSED, &processed );
-
- checkALError("Failed to get processed buffers", "WARNING");
+ checkALError("Failed to get processed buffers", WARNING);
if (processed > 0) {
ALuint * b = new ALuint[processed];
alSourceUnqueueBuffers( Source, processed, b );
- checkALError("Failed to unqueue buffers", "WARNING");
+ checkALError("Failed to unqueue buffers", WARNING);
if (delete_buffers) {
+#ifdef __APPLE__ // mac os x and iOS
+ /* FIXME: hackish
+ somebody with more knowledge than me could perhapps figure out
+ why Apple's implementation of alSourceUnqueueBuffers seems to delay (threading thing?)
+ and possible how better to deal with this.
+ */
+ do{
+ alDeleteBuffers(processed, b);
+ }while(alGetError() != AL_NO_ERROR);
+#else
alDeleteBuffers(processed, b);
- checkALError("Failed to delete buffers", "WARNING");
+ checkALError("Failed to delete buffers", WARNING);
+#endif
}
delete[] b;
@@ -100,16 +112,19 @@ void AudioStream::ClearIfStopped()
{
if (free || locked) return;
- if (!alIsSource(Source)) return;
+ if (!Source || !alIsSource(Source)) {
+ checkALError("No AL Context", WARNING);
+ return;
+ }
ALint state;
alGetSourcei( Source, AL_SOURCE_STATE, &state );
- if (!checkALError("Failed to check source state", "WARNING") &&
+ if (!checkALError("Failed to check source state", WARNING) &&
state == AL_STOPPED)
{
ClearProcessedBuffers();
alDeleteSources( 1, &Source );
- checkALError("Failed to delete source", "WARNING");
+ checkALError("Failed to delete source", WARNING);
Source = 0;
Buffer = 0;
free = true;
@@ -122,10 +137,10 @@ void AudioStream::ClearIfStopped()
void AudioStream::ForceClear()
{
- if (!alIsSource(Source)) return;
+ if (!Source || !alIsSource(Source)) return;
alSourceStop(Source);
- checkALError("Failed to stop source", "WARNING");
+ checkALError("Failed to stop source", WARNING);
ClearProcessedBuffers();
ClearIfStopped();
}
@@ -141,26 +156,47 @@ OpenALAudioDriver::OpenALAudioDriver(void)
ambim = NULL;
}
+void OpenALAudioDriver::PrintDeviceList ()
+{
+ char *deviceList;
+
+ if (alcIsExtensionPresent(NULL, (ALchar*)"ALC_ENUMERATION_EXT") == AL_TRUE) { // try out enumeration extension
+ Log(MESSAGE, "OpenAL", "Usable audio output devices:");
+ deviceList = (char *)alcGetString(NULL, ALC_DEVICE_SPECIFIER);
+
+ while(deviceList && *deviceList) {
+ Log(MESSAGE,"OpenAL", "Devices: %s", deviceList);
+ deviceList+=strlen(deviceList)+1;
+ }
+ return;
+ }
+ Log(MESSAGE, "OpenAL", "No device enumeration present.");
+}
+
bool OpenALAudioDriver::Init(void)
{
+ Log(MESSAGE, "OpenAL", "Initializing OpenAL driver:\nAL Version:%s\nAL Renderer:%s\nAL Vendor:%s",
+ alGetString(AL_VERSION), alGetString(AL_RENDERER), alGetString(AL_VENDOR));
+
ALCdevice *device;
ALCcontext *context;
device = alcOpenDevice (NULL);
if (device == NULL) {
- showALCError("Failed to open device", "ERROR", device);
+ showALCError("Failed to open device", ERROR, device);
+ PrintDeviceList();
return false;
}
context = alcCreateContext (device, NULL);
if (context == NULL) {
- showALCError("Failed to create context", "ERROR", device);
+ showALCError("Failed to create context", ERROR, device);
alcCloseDevice (device);
return false;
}
if (!alcMakeContextCurrent (context)) {
- showALCError("Failed to select context", "ERROR", device);
+ showALCError("Failed to select context", ERROR, device);
alcDestroyContext (context);
alcCloseDevice (device);
return false;
@@ -171,14 +207,16 @@ bool OpenALAudioDriver::Init(void)
int sources = CountAvailableSources(MAX_STREAMS+1);
num_streams = sources - 1;
- char buf[255];
- sprintf(buf, "Allocated %d streams.%s", num_streams,
- (num_streams < MAX_STREAMS ? " (Fewer than desired.)" : "" ) );
-
- printMessage( "OpenAL", buf, WHITE );
+ Log(MESSAGE, "OpenAL", "Allocated %d streams.%s",
+ num_streams, (num_streams < MAX_STREAMS ? " (Fewer than desired.)" : "" ));
stayAlive = true;
+#if SDL_VERSION_ATLEAST(1, 3, 0)
+ /* as of changeset 3a041d215edc SDL_CreateThread has a 'name' parameter */
+ musicThread = SDL_CreateThread( MusicManager, "OpenALAudio", this );
+#else
musicThread = SDL_CreateThread( MusicManager, this );
+#endif
ambim = new AmbientMgrAL;
speech.free = true;
@@ -203,7 +241,7 @@ int OpenALAudioDriver::CountAvailableSources(int limit)
// (Might not be strictly necessary...)
i -= 2;
- checkALError("Error while auto-detecting number of sources", "WARNING");
+ checkALError("Error while auto-detecting number of sources", WARNING);
// Return number of succesfully allocated sources
return i;
@@ -216,6 +254,12 @@ OpenALAudioDriver::~OpenALAudioDriver(void)
return;
}
+ stayAlive = false;
+// AmigaOS4 can't kill threads and would just wait forever
+#ifndef __amigaos4__
+ SDL_WaitThread(musicThread, NULL);
+#endif
+
for(int i =0; i<num_streams; i++) {
streams[i].ForceClear();
}
@@ -233,9 +277,6 @@ OpenALAudioDriver::~OpenALAudioDriver(void)
alcCloseDevice (device);
}
alutContext = NULL;
- SDL_mutexP(musicMutex);
- SDL_KillThread(musicThread);
- SDL_mutexV(musicMutex);
SDL_DestroyMutex(musicMutex);
musicMutex = NULL;
@@ -264,13 +305,14 @@ ALuint OpenALAudioDriver::loadSound(const char *ResRef, unsigned int &time_lengt
//no cache entry...
alGenBuffers(1, &Buffer);
- if (checkALError("Unable to create sound buffer", "ERROR")) {
+ if (checkALError("Unable to create sound buffer", ERROR)) {
return 0;
}
ResourceHolder<SoundMgr> acm(ResRef);
if (!acm) {
alDeleteBuffers( 1, &Buffer );
+ checkALError("Unable to delete buffer!", ERROR);
return 0;
}
int cnt = acm->get_length();
@@ -287,9 +329,9 @@ ALuint OpenALAudioDriver::loadSound(const char *ResRef, unsigned int &time_lengt
alBufferData( Buffer, GetFormatEnum( riff_chans, 16 ), memory, cnt1, samplerate );
free(memory);
- if (checkALError("Unable to fill buffer", "ERROR")) {
+ if (checkALError("Unable to fill buffer", ERROR)) {
alDeleteBuffers( 1, &Buffer );
- checkALError("Error deleting buffer", "WARNING");
+ checkALError("Error deleting buffer", WARNING);
return 0;
}
@@ -298,7 +340,7 @@ ALuint OpenALAudioDriver::loadSound(const char *ResRef, unsigned int &time_lengt
e->Length = ((cnt / riff_chans) * 1000) / samplerate;
buffercache.SetAt(ResRef, (void*)e);
- //printf("LoadSound: added %s to cache: %d. Cache size now %d\n", ResRef, e->Buffer, buffercache.GetCount());
+ //print("LoadSound: added %s to cache: %d. Cache size now %d", ResRef, e->Buffer, buffercache.GetCount());
if (buffercache.GetCount() > BUFFER_CACHE_SIZE) {
evictBuffer();
@@ -312,10 +354,10 @@ Holder<SoundHandle> OpenALAudioDriver::Play(const char* ResRef, int XPos, int YP
unsigned int time_length;
if(ResRef == NULL) {
- if((flags & GEM_SND_SPEECH) && alIsSource(speech.Source)) {
+ if((flags & GEM_SND_SPEECH) && (speech.Source && alIsSource(speech.Source))) {
//So we want him to be quiet...
alSourceStop( speech.Source );
- checkALError("Unable to stop speech", "WARNING");
+ checkALError("Unable to stop speech", WARNING);
speech.ClearProcessedBuffers();
}
return Holder<SoundHandle>();
@@ -330,7 +372,6 @@ Holder<SoundHandle> OpenALAudioDriver::Play(const char* ResRef, int XPos, int YP
*length = time_length;
}
- ALuint Source;
ALfloat SourcePos[] = {
(float) XPos, (float) YPos, 0.0f
};
@@ -339,99 +380,76 @@ Holder<SoundHandle> OpenALAudioDriver::Play(const char* ResRef, int XPos, int YP
};
ieDword volume = 100;
+ ALint loop = (flags & GEM_SND_LOOPING ? 1 : 0);
+
+ AudioStream* stream = NULL;
if (flags & GEM_SND_SPEECH) {
- //speech has a single channel, if a new speech started
- //we stop the previous one
- if(!speech.free && alIsSource(speech.Source)) {
- alSourceStop( speech.Source );
- checkALError("Unable to stop speech", "WARNING");
- speech.ClearProcessedBuffers();
+ stream = &speech;
+
+ if (!(flags & GEM_SND_QUEUE)) {
+ //speech has a single channel, if a new speech started
+ //we stop the previous one
+
+ if(!speech.free && (speech.Source && alIsSource(speech.Source))) {
+ alSourceStop( speech.Source );
+ checkALError("Unable to stop speech", WARNING);
+ speech.ClearProcessedBuffers();
+ }
}
- if(!alIsSource(speech.Source)) {
- alGenSources( 1, &speech.Source );
- if (checkALError("Error creating source for speech", "ERROR")) {
- return Holder<SoundHandle>();
+
+ core->GetDictionary()->Lookup( "Volume Voices", volume );
+
+ loop = 0; // Speech ignores GEM_SND_LOOPING
+ } else {
+ // do we want to be able to queue sfx too? not so far. How would we?
+ for (int i = 0; i < num_streams; i++) {
+ streams[i].ClearIfStopped();
+ if (streams[i].free) {
+ stream = &streams[i];
+ break;
}
}
- alSourcef( speech.Source, AL_PITCH, 1.0f );
- alSourcefv( speech.Source, AL_VELOCITY, SourceVel );
- alSourcei( speech.Source, AL_LOOPING, 0 );
- alSourcef( speech.Source, AL_REFERENCE_DISTANCE, REFERENCE_DISTANCE );
- checkALError("Unable to set speech parameters", "WARNING");
- speech.free = false;
- printf("speech.free: %d source:%d\n", speech.free,speech.Source);
+ core->GetDictionary()->Lookup( "Volume SFX", volume );
- core->GetDictionary()->Lookup( "Volume Voices", volume );
- alSourcef( speech.Source, AL_GAIN, 0.01f * volume );
- alSourcei( speech.Source, AL_SOURCE_RELATIVE, flags & GEM_SND_RELATIVE );
- alSourcefv( speech.Source, AL_POSITION, SourcePos );
- assert(!speech.delete_buffers);
- alSourcei( speech.Source, AL_BUFFER, Buffer );
- checkALError("Unable to set speech parameters", "WARNING");
- speech.Buffer = Buffer;
- alSourcePlay( speech.Source );
- if (checkALError("Unable to play speech", "ERROR")) {
+ if (stream == NULL) {
+ // Failed to assign new sound.
+ // The buffercache will handle deleting Buffer.
return Holder<SoundHandle>();
}
- speech.handle = new OpenALSoundHandle(&speech);
- return speech.handle.get();
}
- int stream = -1;
- for (int i = 0; i < num_streams; i++) {
- streams[i].ClearIfStopped();
- if (streams[i].free) {
- stream = i;
- break;
- }
- }
+ assert(stream);
+ ALuint Source = stream->Source;
- if (stream == -1) {
- // Failed to assign new sound.
- // The buffercache will handle deleting Buffer.
- return Holder<SoundHandle>();
- }
-
- // not speech
- alGenSources( 1, &Source );
- if (checkALError("Unable to create source", "ERROR")) {
- return Holder<SoundHandle>();
+ if(!Source || !alIsSource(Source)) {
+ alGenSources( 1, &Source );
+ if (checkALError("Error creating source", ERROR)) {
+ return Holder<SoundHandle>();
+ }
}
alSourcef( Source, AL_PITCH, 1.0f );
alSourcefv( Source, AL_VELOCITY, SourceVel );
- alSourcei( Source, AL_LOOPING, (flags & GEM_SND_LOOPING ? 1 : 0) );
+ alSourcei( Source, AL_LOOPING, loop);
alSourcef( Source, AL_REFERENCE_DISTANCE, REFERENCE_DISTANCE );
- core->GetDictionary()->Lookup( "Volume SFX", volume );
alSourcef( Source, AL_GAIN, 0.01f * volume );
alSourcei( Source, AL_SOURCE_RELATIVE, flags & GEM_SND_RELATIVE );
alSourcefv( Source, AL_POSITION, SourcePos );
- assert(!streams[stream].delete_buffers);
- alSourcei( Source, AL_BUFFER, Buffer );
+ checkALError("Unable to set audio parameters", WARNING);
- if (checkALError("Unable to set sound parameters", "ERROR")) {
- return Holder<SoundHandle>();
- }
+ assert(!stream->delete_buffers);
- streams[stream].Buffer = Buffer;
- streams[stream].Source = Source;
- streams[stream].free = false;
- alSourcePlay( Source );
+ stream->Source = Source;
+ stream->free = false;
- if (checkALError("Unable to play sound", "ERROR")) {
+ if (QueueALBuffer(Source, Buffer) != GEM_OK) {
return Holder<SoundHandle>();
}
- streams[stream].handle = new OpenALSoundHandle(&streams[stream]);
- return streams[stream].handle.get();
-}
-
-bool OpenALAudioDriver::IsSpeaking()
-{
- speech.ClearIfStopped();
- return !speech.free;
+ stream->handle = new OpenALSoundHandle(stream);
+ return stream->handle.get();
}
void OpenALAudioDriver::UpdateVolume(unsigned int flags)
@@ -441,7 +459,7 @@ void OpenALAudioDriver::UpdateVolume(unsigned int flags)
if (flags & GEM_SND_VOL_MUSIC) {
SDL_mutexP( musicMutex );
core->GetDictionary()->Lookup("Volume Music", volume);
- if (alIsSource(MusicSource))
+ if (MusicSource && alIsSource(MusicSource))
alSourcef(MusicSource, AL_GAIN, volume * 0.01f);
SDL_mutexV(musicMutex);
}
@@ -461,16 +479,16 @@ void OpenALAudioDriver::ResetMusics()
{
MusicPlaying = false;
SDL_mutexP( musicMutex );
- if (alIsSource(MusicSource)) {
+ if (MusicSource && alIsSource(MusicSource)) {
alSourceStop(MusicSource);
- checkALError("Unable to stop music source", "WARNING");
+ checkALError("Unable to stop music source", WARNING);
alDeleteSources(1, &MusicSource );
- checkALError("Unable to delete music source", "WARNING");
+ checkALError("Unable to delete music source", WARNING);
MusicSource = 0;
for (int i=0; i<MUSICBUFFERS; i++) {
if (alIsBuffer(MusicBuffer[i])) {
alDeleteBuffers(1, MusicBuffer+i);
- checkALError("Unable to delete music buffer", "WARNING");
+ checkALError("Unable to delete music buffer", WARNING);
}
}
}
@@ -492,15 +510,15 @@ bool OpenALAudioDriver::Play()
bool OpenALAudioDriver::Stop()
{
SDL_mutexP( musicMutex );
- if (!alIsSource( MusicSource )) {
+ if (!MusicSource || !alIsSource( MusicSource )) {
SDL_mutexV( musicMutex );
return false;
}
alSourceStop( MusicSource );
- checkALError("Unable to stop music source", "WARNING");
+ checkALError("Unable to stop music source", WARNING);
MusicPlaying = false;
alDeleteSources( 1, &MusicSource );
- checkALError("Unable to delete music source", "WARNING");
+ checkALError("Unable to delete music source", WARNING);
MusicSource = 0;
SDL_mutexV( musicMutex );
return true;
@@ -509,33 +527,37 @@ bool OpenALAudioDriver::Stop()
bool OpenALAudioDriver::Pause()
{
SDL_mutexP( musicMutex );
- if (!alIsSource( MusicSource )) {
+ if (!MusicSource || !alIsSource( MusicSource )) {
SDL_mutexV( musicMutex );
return false;
}
alSourcePause(MusicSource);
- checkALError("Unable to pause music source", "WARNING");
+ checkALError("Unable to pause music source", WARNING);
MusicPlaying = false;
SDL_mutexV( musicMutex );
((AmbientMgrAL*) ambim)->deactivate();
#ifdef ANDROID
+#if SDL_COMPILEDVERSION < SDL_VERSIONNUM(1,3,0)
al_android_pause_playback(); //call AudioTrack.pause() from JNI
#endif
+#endif
return true;
}
bool OpenALAudioDriver::Resume()
{
#ifdef ANDROID
+#if SDL_COMPILEDVERSION < SDL_VERSIONNUM(1,3,0)
al_android_resume_playback(); //call AudioTrack.play() from JNI
#endif
+#endif
SDL_mutexP( musicMutex );
- if (!alIsSource( MusicSource )) {
+ if (!MusicSource || !alIsSource( MusicSource )) {
SDL_mutexV( musicMutex );
return false;
}
alSourcePlay(MusicSource);
- checkALError("Unable to resume music source", "WARNING");
+ checkALError("Unable to resume music source", WARNING);
MusicPlaying = true;
SDL_mutexV( musicMutex );
((AmbientMgrAL*) ambim)->activate();
@@ -554,14 +576,14 @@ int OpenALAudioDriver::CreateStream(Holder<SoundMgr> newMusic)
if (MusicBuffer[0] == 0) {
alGenBuffers( MUSICBUFFERS, MusicBuffer );
- if (checkALError("Unable to create music buffers", "ERROR")) {
+ if (checkALError("Unable to create music buffers", ERROR)) {
return -1;
}
}
if (MusicSource == 0) {
alGenSources( 1, &MusicSource );
- if (checkALError("Unable to create music source", "ERROR")) {
+ if (checkALError("Unable to create music source", ERROR)) {
return -1;
}
@@ -580,7 +602,7 @@ int OpenALAudioDriver::CreateStream(Holder<SoundMgr> newMusic)
alSourcefv( MusicSource, AL_POSITION, SourcePos );
alSourcefv( MusicSource, AL_VELOCITY, SourceVel );
alSourcei( MusicSource, AL_LOOPING, 0 );
- checkALError("Unable to set music parameters", "WARNING");
+ checkALError("Unable to set music parameters", WARNING);
}
return 0;
@@ -589,13 +611,14 @@ int OpenALAudioDriver::CreateStream(Holder<SoundMgr> newMusic)
void OpenALAudioDriver::UpdateListenerPos(int XPos, int YPos )
{
alListener3f( AL_POSITION, (float) XPos, (float) YPos, 0.0f );
+ checkALError("Unable to update listener position.", WARNING);
}
void OpenALAudioDriver::GetListenerPos(int &XPos, int &YPos )
{
ALfloat listen[3];
alGetListenerfv( AL_POSITION, listen );
- if (checkALError("Unable to get listener pos", "ERROR")) return;
+ if (checkALError("Unable to get listener pos", ERROR)) return;
XPos = (int) listen[0];
YPos = (int) listen[1];
}
@@ -612,9 +635,8 @@ bool OpenALAudioDriver::ReleaseStream(int stream, bool HardStop)
ALuint Source = streams[stream].Source;
alSourceStop(Source);
- checkALError("Unable to stop source", "WARNING");
+ checkALError("Unable to stop source", WARNING);
streams[stream].ClearIfStopped();
-
return true;
}
@@ -631,11 +653,14 @@ int OpenALAudioDriver::SetupNewStream( ieWord x, ieWord y, ieWord z,
break;
}
}
- if (stream == -1) return -1;
+ if (stream == -1) {
+ Log(ERROR, "OpenAL", "No available audio streams out of %d", num_streams);
+ return -1;
+ }
ALuint source;
alGenSources(1, &source);
- if (checkALError("Unable to create new source", "ERROR")) {
+ if (checkALError("Unable to create new source", ERROR)) {
return -1;
}
@@ -646,7 +671,7 @@ int OpenALAudioDriver::SetupNewStream( ieWord x, ieWord y, ieWord z,
alSourcei( source, AL_REFERENCE_DISTANCE, REFERENCE_DISTANCE );
alSourcei( source, AL_ROLLOFF_FACTOR, point ? 1 : 0 );
alSourcei( source, AL_LOOPING, 0 );
- checkALError("Unable to set stream parameters", "WARNING");
+ checkALError("Unable to set stream parameters", WARNING);
streams[stream].Buffer = 0;
streams[stream].Source = source;
@@ -678,20 +703,8 @@ int OpenALAudioDriver::QueueAmbient(int stream, const char* sound)
assert(!streams[stream].delete_buffers);
- alSourceQueueBuffers(source, 1, &Buffer);
- if (checkALError("Unable to queue ambient buffer","ERROR")) {
- return -1;
- }
-
- // play
- ALint state;
- alGetSourcei( source, AL_SOURCE_STATE, &state );
- if (!checkALError("Unable to query ambient source state", "ERROR") &&
- state != AL_PLAYING)
- { // play on playing source would rewind it
- alSourcePlay( source );
- if (checkALError("Unable to play ambient source", "ERROR"))
- return -1;
+ if (QueueALBuffer(source, Buffer) != GEM_OK) {
+ return GEM_ERROR;
}
return time_length;
@@ -704,7 +717,7 @@ void OpenALAudioDriver::SetAmbientStreamVolume(int stream, int volume)
ALuint source = streams[stream].Source;
alSourcef( source, AL_GAIN, 0.01f * volume );
- checkALError("Unable to set ambient volume", "WARNING");
+ checkALError("Unable to set ambient volume", WARNING);
}
bool OpenALAudioDriver::evictBuffer()
@@ -729,7 +742,7 @@ bool OpenALAudioDriver::evictBuffer()
delete e;
buffercache.Remove(k);
- //printf("Removed buffer %s from ACMImp cache\n", k);
+ //print("Removed buffer %s from ACMImp cache", k);
break;
}
++n;
@@ -787,38 +800,52 @@ int OpenALAudioDriver::MusicManager(void* arg)
if (driver->MusicPlaying) {
ALint state;
alGetSourcei( driver->MusicSource, AL_SOURCE_STATE, &state );
- if (checkALError("Unable to query music source state", "ERROR")) {
+ if (checkALError("Unable to query music source state", ERROR)) {
driver->MusicPlaying = false;
return -1;
}
switch (state) {
default:
- printMessage("OpenAL", "WARNING: Unhandled Music state", WHITE );
- printStatus("ERROR", YELLOW);
+ Log(ERROR, "OpenAL", "Unhandled Music state '%d'.", state);
+ //no break
+ case AL_PAUSED:
driver->MusicPlaying = false;
return -1;
case AL_INITIAL:
{
- printMessage("OPENAL", "Music in INITIAL State. AutoStarting\n", WHITE );
+ Log(MESSAGE, "OPENAL", "Music in INITIAL State. AutoStarting");
+ // ensure that MusicSource has no buffers attached by passing "NULL" buffer
+ alSourcei(driver->MusicSource, AL_BUFFER, 0);
+ checkALError("Unable to detach buffers from music source.", WARNING);
for (int i = 0; i < MUSICBUFFERS; i++) {
driver->MusicReader->read_samples( driver->music_memory, ACM_BUFFERSIZE >> 1 );
alBufferData( driver->MusicBuffer[i], AL_FORMAT_STEREO16,
driver->music_memory, ACM_BUFFERSIZE,
driver->MusicReader->get_samplerate() );
}
+ checkALError("Unable to buffer data.", ERROR);
+ // FIXME: determine if we should error out if any data fails to buffer
alSourceQueueBuffers( driver->MusicSource, MUSICBUFFERS, driver->MusicBuffer );
- if (alIsSource( driver->MusicSource )) {
- alSourcePlay( driver->MusicSource );
- checkALError("Error playing music source", "ERROR");
+ if (!checkALError("Unable to queue buffer.", ERROR)) {
+ if (driver->MusicSource && alIsSource( driver->MusicSource )) {
+ alSourcePlay( driver->MusicSource );
+ if (!checkALError("Error playing music source", ERROR)) {
+ // no errors happened
+ bFinished = AL_FALSE;
+ break;
+ }
+ }
}
- bFinished = AL_FALSE;
+ // if all had gone well we would have broken out
+ driver->MusicPlaying = false;
+ return -1;
}
break;
case AL_STOPPED:
- printMessage("OpenAL", "WARNING: Buffer Underrun. AutoRestarting Stream Playback\n", WHITE );
- if (alIsSource( driver->MusicSource )) {
+ Log(MESSAGE, "OpenAL", "WARNING: Buffer Underrun. AutoRestarting Stream Playback");
+ if (driver->MusicSource && alIsSource( driver->MusicSource )) {
alSourcePlay( driver->MusicSource );
- checkALError("Error playing music source", "ERROR");
+ checkALError("Error playing music source", ERROR);
}
break;
case AL_PLAYING:
@@ -826,7 +853,7 @@ int OpenALAudioDriver::MusicManager(void* arg)
}
ALint processed;
alGetSourcei( driver->MusicSource, AL_BUFFERS_PROCESSED, &processed );
- if (checkALError("Unable to query music source state", "ERROR")) {
+ if (checkALError("Unable to query music source state", ERROR)) {
driver->MusicPlaying = false;
return -1;
}
@@ -835,7 +862,7 @@ int OpenALAudioDriver::MusicManager(void* arg)
while (processed) {
ALuint BufferID;
alSourceUnqueueBuffers( driver->MusicSource, 1, &BufferID );
- if (checkALError("Unable to unqueue music buffers", "ERROR")) {
+ if (checkALError("Unable to unqueue music buffers", ERROR)) {
driver->MusicPlaying = false;
return -1;
}
@@ -846,26 +873,26 @@ int OpenALAudioDriver::MusicManager(void* arg)
if (size != 0)
bFinished = AL_TRUE;
if (bFinished) {
- printMessage("OpenAL", "Playing Next Music\n", WHITE );
+ Log(MESSAGE, "OpenAL", "Playing Next Music");
core->GetMusicMgr()->PlayNext();
if (driver->MusicPlaying) {
- printMessage( "OpenAL", "Queuing New Music\n", WHITE );
+ Log(MESSAGE, "OpenAL", "Queuing New Music");
driver->MusicReader->read_samples( ( driver->music_memory + cnt ), size >> 1 );
bFinished = AL_FALSE;
} else {
- printMessage( "OpenAL", "No Other Music to play\n", WHITE );
+ Log(MESSAGE, "OpenAL", "No Other Music to play");
memset( driver->music_memory + cnt, 0, size );
driver->MusicPlaying = false;
break;
}
}
alBufferData( BufferID, AL_FORMAT_STEREO16, driver->music_memory, ACM_BUFFERSIZE, driver->MusicReader->get_samplerate() );
- if (checkALError("Unable to buffer music data", "ERROR")) {
+ if (checkALError("Unable to buffer music data", ERROR)) {
driver->MusicPlaying = false;
return -1;
}
alSourceQueueBuffers( driver->MusicSource, 1, &BufferID );
- if (checkALError("Unable to queue music buffers", "ERROR")) {
+ if (checkALError("Unable to queue music buffers", ERROR)) {
driver->MusicPlaying = false;
return -1;
}
@@ -886,35 +913,60 @@ void OpenALAudioDriver::QueueBuffer(int stream, unsigned short bits,
ALuint Buffer;
alGenBuffers(1, &Buffer);
- if (checkALError("Unable to create buffer", "ERROR")) {
+ if (checkALError("Unable to create buffer", ERROR)) {
return;
}
alBufferData(Buffer, GetFormatEnum(channels, bits), memory, size, samplerate);
- if (checkALError("Unable to buffer data", "ERROR")) {
+ if (checkALError("Unable to buffer data", ERROR)) {
return;
}
streams[stream].delete_buffers = true;
streams[stream].ClearProcessedBuffers();
- alSourceQueueBuffers(streams[stream].Source, 1, &Buffer );
- if (checkALError("Unable to queue buffer", "ERROR")) {
- return;
+ QueueALBuffer(streams[stream].Source, Buffer);
+}
+
+// !!!!!!!!!!!!!!!
+// Private Methods
+// !!!!!!!!!!!!!!!
+
+int OpenALAudioDriver::QueueALBuffer(ALuint source, ALuint buffer)
+{
+#ifdef _DEBUG
+ ALint frequency, bits, channels;
+ alGetBufferi(buffer, AL_FREQUENCY, &frequency);
+ alGetBufferi(buffer, AL_BITS, &bits);
+ alGetBufferi(buffer, AL_CHANNELS, &channels);
+ checkALError("Error querying buffer properties.", WARNING);
+ Log(DEBUG, "OpenAL", "Attempting to buffer audio source:%d\nFrequency:%d\nBits:%d\nChannels:%d",
+ source, frequency, bits, channels);
+#endif
+ ALint type;
+ alGetSourcei(source, AL_SOURCE_TYPE, &type);
+ if (type == AL_STATIC || checkALError("Cannot get AL source type.", ERROR)) {
+ Log(ERROR, "OpenAL", "Cannot queue a buffer to a static source.");
+ return GEM_ERROR;
+ }
+ alSourceQueueBuffers(source, 1, &buffer);
+ if (checkALError("Unable to queue buffer", ERROR)) {
+ return GEM_ERROR;
}
ALenum state;
- alGetSourcei(streams[stream].Source, AL_SOURCE_STATE, &state);
- if (checkALError("Unable to query source state", "ERROR")) {
- return;
+ alGetSourcei(source, AL_SOURCE_STATE, &state);
+ if (checkALError("Unable to query source state", ERROR)) {
+ return GEM_ERROR;
}
+ // queueing always implies playing for us
if (state != AL_PLAYING ) {
- alSourcePlay(streams[stream].Source);
- checkALError("Unable to play source", "ERROR");
+ alSourcePlay(source);
+ checkALError("Unable to play source", ERROR);
+ return GEM_ERROR;
}
-
- return;
+ return GEM_OK;
}
#include "plugindef.h"
diff --git a/gemrb/plugins/OpenALAudio/OpenALAudio.h b/gemrb/plugins/OpenALAudio/OpenALAudio.h
index 085bd0d..37dfed3 100644
--- a/gemrb/plugins/OpenALAudio/OpenALAudio.h
+++ b/gemrb/plugins/OpenALAudio/OpenALAudio.h
@@ -49,7 +49,8 @@
#include <alc.h>
#endif
-#ifdef ANDROID
+#if ANDROID && SDL_COMPILEDVERSION < SDL_VERSIONNUM(1,3,0)
+// Pely's build only
#include <AL/android.h>
#endif
@@ -60,6 +61,8 @@
#define REFERENCE_DISTANCE 50
#define ACM_BUFFERSIZE 8192
+namespace GemRB {
+
class OpenALSoundHandle : public SoundHandle {
protected:
struct AudioStream *parent;
@@ -101,10 +104,10 @@ class OpenALAudioDriver : public Audio {
public:
OpenALAudioDriver(void);
~OpenALAudioDriver(void);
+ void PrintDeviceList();
bool Init(void);
Holder<SoundHandle> Play(const char* ResRef, int XPos, int YPos,
unsigned int flags = 0, unsigned int *length = 0);
- bool IsSpeaking();
void UpdateVolume(unsigned int flags);
bool CanPlay();
void ResetMusics();
@@ -122,7 +125,10 @@ public:
void SetAmbientStreamVolume(int stream, int volume);
void QueueBuffer(int stream, unsigned short bits,
int channels, short* memory,
- int size, int samplerate) ;
+ int size, int samplerate);
+private:
+ int QueueALBuffer(ALuint source, ALuint buffer);
+
private:
ALCcontext *alutContext;
ALuint MusicSource;
@@ -145,4 +151,6 @@ private:
SDL_Thread* musicThread;
};
+}
+
#endif // OPENALAUDIO_H_INCLUDED
diff --git a/gemrb/plugins/OpenALAudio/StackLock.cpp b/gemrb/plugins/OpenALAudio/StackLock.cpp
index b1db38f..dc7001f 100644
--- a/gemrb/plugins/OpenALAudio/StackLock.cpp
+++ b/gemrb/plugins/OpenALAudio/StackLock.cpp
@@ -22,11 +22,14 @@
#include <cstdio>
+using namespace GemRB;
+
// adapted from ScummVM's mutex.cpp
StackLock::StackLock(SDL_mutex* mutex, const char *mutexName)
: _mutex(mutex), _mutexName(mutexName) {
lock();
+ (void)_mutexName; // NOOP to silence clang
}
StackLock::~StackLock() {
diff --git a/gemrb/plugins/OpenALAudio/StackLock.h b/gemrb/plugins/OpenALAudio/StackLock.h
index f8a881f..49f0747 100644
--- a/gemrb/plugins/OpenALAudio/StackLock.h
+++ b/gemrb/plugins/OpenALAudio/StackLock.h
@@ -20,6 +20,8 @@
#include "SDL_mutex.h"
+namespace GemRB {
+
// Copied from ScummVM, mutex.h
/**
@@ -35,4 +37,6 @@ public:
StackLock(SDL_mutex* mutex, const char *mutexName = NULL);
~StackLock();
};
+}
+
diff --git a/gemrb/plugins/PLTImporter/PLTImporter.cpp b/gemrb/plugins/PLTImporter/PLTImporter.cpp
index c7ec0da..57c2617 100644
--- a/gemrb/plugins/PLTImporter/PLTImporter.cpp
+++ b/gemrb/plugins/PLTImporter/PLTImporter.cpp
@@ -26,19 +26,21 @@
#include "Interface.h"
#include "Video.h"
+using namespace GemRB;
+
static int pperm[8]={3,6,0,5,4,1,2,7};
-static ieDword red_mask = 0xff000000;
-static ieDword green_mask = 0x00ff0000;
-static ieDword blue_mask = 0x0000ff00;
+static ieDword red_mask = 0x00ff0000;
+static ieDword green_mask = 0x0000ff00;
+static ieDword blue_mask = 0x000000ff;
PLTImporter::PLTImporter(void)
{
pixels = NULL;
if (DataStream::IsEndianSwitch()) {
- red_mask = 0x000000ff;
- green_mask = 0x0000ff00;
- blue_mask = 0x00ff0000;
+ red_mask = 0x0000ff00;
+ green_mask = 0x00ff0000;
+ blue_mask = 0xff000000;
}
}
@@ -49,16 +51,18 @@ PLTImporter::~PLTImporter(void)
}
}
-bool PLTImporter::Open(DataStream* stream)
+bool PLTImporter::Open(DataStream* str)
{
- str = stream;
+ if (!str) {
+ return false;
+ }
char Signature[8];
unsigned short unknown[4];
str->Read( Signature, 8 );
if (strncmp( Signature, "PLT V1 ", 8 ) != 0) {
- printf( "[PLTImporter]: Not a valid PLT File.\n" );
+ print("[PLTImporter]: Not a valid PLT File.");
return false;
}
@@ -68,7 +72,7 @@ bool PLTImporter::Open(DataStream* stream)
pixels = malloc( Width * Height * 2 );
str->Read( pixels, Width * Height * 2 );
-
+ delete str;
return true;
}
@@ -80,19 +84,19 @@ Sprite2D* PLTImporter::GetSprite2D(unsigned int type, ieDword paletteIndex[8])
}
unsigned char * p = ( unsigned char * ) malloc( Width * Height * 4 );
unsigned char * dest = p;
- unsigned char * src = ( unsigned char * ) pixels;
+ unsigned char * src = NULL;
for (int y = Height - 1; y >= 0; y--) {
src = ( unsigned char * ) pixels + ( y * Width * 2 );
for (unsigned int x = 0; x < Width; x++) {
unsigned char intensity = *src++;
unsigned char palindex = *src++;
+ *dest++ = Palettes[palindex][intensity].b;
+ *dest++ = Palettes[palindex][intensity].g;
+ *dest++ = Palettes[palindex][intensity].r;
if (intensity == 0xff)
*dest++ = 0x00;
else
*dest++ = 0xff;
- *dest++ = Palettes[palindex][intensity].b;
- *dest++ = Palettes[palindex][intensity].g;
- *dest++ = Palettes[palindex][intensity].r;
}
}
Sprite2D* spr = core->GetVideoDriver()->CreateSprite( Width, Height, 32,
@@ -106,5 +110,5 @@ Sprite2D* PLTImporter::GetSprite2D(unsigned int type, ieDword paletteIndex[8])
#include "plugindef.h"
GEMRB_PLUGIN(0x8D0C64F, "PLT File Importer")
-PLUGIN_IE_RESOURCE(PLTImporter, ".plt", (ieWord)IE_PLT_CLASS_ID)
+PLUGIN_IE_RESOURCE(PLTImporter, "plt", (ieWord)IE_PLT_CLASS_ID)
END_PLUGIN()
diff --git a/gemrb/plugins/PLTImporter/PLTImporter.h b/gemrb/plugins/PLTImporter/PLTImporter.h
index 870baec..52315b6 100644
--- a/gemrb/plugins/PLTImporter/PLTImporter.h
+++ b/gemrb/plugins/PLTImporter/PLTImporter.h
@@ -23,6 +23,8 @@
#include "PalettedImageMgr.h"
+namespace GemRB {
+
class PLTImporter : public PalettedImageMgr {
private:
ieDword Width, Height;
@@ -34,4 +36,6 @@ public:
Sprite2D* GetSprite2D(unsigned int type, ieDword col[8]);
};
+}
+
#endif
diff --git a/gemrb/plugins/PNGImporter/PNGImporter.cpp b/gemrb/plugins/PNGImporter/PNGImporter.cpp
index 30afe74..2925323 100644
--- a/gemrb/plugins/PNGImporter/PNGImporter.cpp
+++ b/gemrb/plugins/PNGImporter/PNGImporter.cpp
@@ -30,6 +30,8 @@
// CHECKME: how should we include png.h ? (And how should we check for it?)
#include <png.h>
+using namespace GemRB;
+
static void DataStream_png_read_data(png_structp png_ptr,
png_bytep data, png_size_t length)
{
@@ -38,7 +40,7 @@ static void DataStream_png_read_data(png_structp png_ptr,
str->Read(data, length);
}
-struct PNGInternal {
+struct GemRB::PNGInternal {
png_structp png_ptr;
png_infop info_ptr;
png_infop end_info;
@@ -213,5 +215,5 @@ void PNGImporter::GetPalette(int colors, Color* pal)
#include "plugindef.h"
GEMRB_PLUGIN(0x11C3EB12, "PNG File Importer")
-PLUGIN_IE_RESOURCE(PNGImporter, ".png", (ieWord)IE_PNG_CLASS_ID)
+PLUGIN_IE_RESOURCE(PNGImporter, "png", (ieWord)IE_PNG_CLASS_ID)
END_PLUGIN()
diff --git a/gemrb/plugins/PNGImporter/PNGImporter.h b/gemrb/plugins/PNGImporter/PNGImporter.h
index 4aabd66..732c353 100644
--- a/gemrb/plugins/PNGImporter/PNGImporter.h
+++ b/gemrb/plugins/PNGImporter/PNGImporter.h
@@ -23,6 +23,8 @@
#include "ImageMgr.h"
+namespace GemRB {
+
struct PNGInternal;
class PNGImporter : public ImageMgr {
@@ -42,4 +44,6 @@ public:
int GetHeight() { return (int) Height; }
};
+}
+
#endif
diff --git a/gemrb/plugins/PROImporter/PROImporter.cpp b/gemrb/plugins/PROImporter/PROImporter.cpp
index 013cc75..9ffa695 100644
--- a/gemrb/plugins/PROImporter/PROImporter.cpp
+++ b/gemrb/plugins/PROImporter/PROImporter.cpp
@@ -25,36 +25,32 @@
#include "EffectMgr.h"
#include "Interface.h"
+using namespace GemRB;
+
PROImporter::PROImporter(void)
{
str = NULL;
- autoFree = false;
}
PROImporter::~PROImporter(void)
{
- if (autoFree) {
- delete str;
- }
+ delete str;
str = NULL;
}
-bool PROImporter::Open(DataStream* stream, bool autoFree)
+bool PROImporter::Open(DataStream* stream)
{
if (stream == NULL) {
return false;
}
- if (this->autoFree) {
- delete str;
- }
+ delete str;
str = stream;
- this->autoFree = autoFree;
char Signature[8];
str->Read( Signature, 8 );
if (strncmp( Signature, "PRO V1.0", 8 ) == 0) {
version = 10;
} else {
- printf( "[PROImporter]: This file is not a valid PRO File\n" );
+ print("[PROImporter]: This file is not a valid PRO File");
return false;
}
diff --git a/gemrb/plugins/PROImporter/PROImporter.h b/gemrb/plugins/PROImporter/PROImporter.h
index d6c7b91..6bed73e 100644
--- a/gemrb/plugins/PROImporter/PROImporter.h
+++ b/gemrb/plugins/PROImporter/PROImporter.h
@@ -27,21 +27,24 @@
#include "Projectile.h"
+namespace GemRB {
+
class PROImporter : public ProjectileMgr {
private:
DataStream* str;
- bool autoFree;
int version;
public:
PROImporter(void);
~PROImporter(void);
- bool Open(DataStream* stream, bool autoFree = true);
+ bool Open(DataStream* stream);
Projectile* GetProjectile(Projectile *s);
private:
void GetAreaExtension(ProjectileExtension *s);
};
+}
+
#endif
diff --git a/gemrb/plugins/PSTOpcodes/PSTOpcodes.cpp b/gemrb/plugins/PSTOpcodes/PSTOpcodes.cpp
index 477894e..65e2931 100644
--- a/gemrb/plugins/PSTOpcodes/PSTOpcodes.cpp
+++ b/gemrb/plugins/PSTOpcodes/PSTOpcodes.cpp
@@ -24,11 +24,16 @@
#include "EffectQueue.h"
#include "Game.h"
#include "GameData.h"
+#include "GlobalTimer.h"
#include "Interface.h"
+#include "Map.h"
+#include "TableMgr.h"
#include "TileMap.h"
#include "Video.h" //for tints
#include "Scriptable/Actor.h"
+using namespace GemRB;
+
int fx_retreat_from (Scriptable* Owner, Actor* target, Effect* fx);//6e
int fx_set_status (Scriptable* Owner, Actor* target, Effect* fx);//ba
int fx_play_bam_blended (Scriptable* Owner, Actor* target, Effect* fx);//bb
@@ -94,7 +99,7 @@ void RegisterTormentOpcodes()
//retreat_from (works only in PST) - forces target to run away/walk away from Owner
int fx_retreat_from (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_retreat_from (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_retreat_from(%2d): Mod: %d, Type: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
if (!Owner) {
return FX_NOT_APPLIED;
@@ -125,7 +130,7 @@ int fx_retreat_from (Scriptable* Owner, Actor* target, Effect* fx)
//0xba fx_set_status
int fx_set_status (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_set_status (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_set_status(%2d): Par2: %d", fx->Opcode, fx->Parameter2);
if (fx->Parameter1) {
if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
BASE_STATE_SET (fx->Parameter2);
@@ -149,7 +154,7 @@ int fx_play_bam_blended (Scriptable* Owner, Actor* target, Effect* fx)
{
bool playonce;
- if (0) printf( "fx_play_bam_blended (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_play_bam_blended(%2d): Par2: %d", fx->Opcode, fx->Parameter2);
if (!Owner)
Owner = target;
if (!Owner)
@@ -179,17 +184,17 @@ int fx_play_bam_blended (Scriptable* Owner, Actor* target, Effect* fx)
rgb.type=RGBModifier::TINT;
sca->AlterPalette(rgb);
}
- if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
- playonce=true;
- } else {
+ if ((fx->TimingMode==FX_DURATION_INSTANT_LIMITED) && (fx->Parameter2&1) ) {
playonce=false;
+ } else {
+ playonce=true;
}
if (playonce) {
- sca->PlayOnce();
+ sca->PlayOnce();
} else {
if (fx->Parameter2&1) {
//four cycles, duration is in millisecond
- sca->SetDefaultDuration(sca->GetSequenceDuration(AI_UPDATE_TIME));
+ sca->SetDefaultDuration(sca->GetSequenceDuration(AI_UPDATE_TIME));
} else {
sca->SetDefaultDuration(fx->Duration-core->GetGame()->Ticks);
}
@@ -226,7 +231,7 @@ int fx_play_bam_not_blended (Scriptable* Owner, Actor* target, Effect* fx)
bool playonce;
bool doublehint;
- if (0) printf( "fx_play_bam_not_blended (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_play_bam_not_blended(%2d): Par2: %d", fx->Opcode, fx->Parameter2);
if (!Owner)
Owner = target;
if (!Owner)
@@ -332,7 +337,7 @@ int fx_play_bam_not_blended (Scriptable* Owner, Actor* target, Effect* fx)
//0xc0 fx_transfer_hp
int fx_transfer_hp (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_transfer_hp (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_transfer_hp(%2d): Par2: %d", fx->Opcode, fx->Parameter2);
if (Owner->Type!=ST_ACTOR) {
return FX_NOT_APPLIED;
}
@@ -372,7 +377,7 @@ int fx_transfer_hp (Scriptable* Owner, Actor* target, Effect* fx)
damage=(signed) fx->Parameter1;
}
if (damage) {
- damage = donor->Damage(damage, fx->Parameter2, owner);
+ damage = donor->Damage(damage, fx->Parameter2, owner, fx->IsVariable, fx->SavingThrowType);
receiver->NewBase( IE_HITPOINTS, damage, MOD_ADDITIVE );
}
return FX_NOT_APPLIED;
@@ -383,7 +388,7 @@ int fx_transfer_hp (Scriptable* Owner, Actor* target, Effect* fx)
//0xc2 fx_flash_screen
int fx_flash_screen (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
{
- if (0) printf( "fx_flash_screen (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_flash_screen(%2d): Par2: %d", fx->Opcode, fx->Parameter2);
core->GetVideoDriver()->SetFadeColor(((unsigned char *) &fx->Parameter1)[0],((unsigned char *) &fx->Parameter1)[1],((unsigned char *) &fx->Parameter1)[2]);
//this needs to be at least 2 for any effect
core->timer->SetFadeFromColor(2);
@@ -394,7 +399,7 @@ int fx_flash_screen (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
//FIXME: implement bit4 which would mean duration
int fx_tint_screen (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
{
- if (0) printf( "fx_tint_screen (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_tint_screen(%2d): Par2: %d", fx->Opcode, fx->Parameter2);
int fromTime = fx->DiceSides;
int toTime = fx->DiceSides;
switch(fx->Parameter2&6) {
@@ -410,7 +415,7 @@ int fx_tint_screen (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
//it is a mystery, why they needed to make this effect
int fx_special_effect (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_special_effect (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_special_effect(%2d): Par2: %d", fx->Opcode, fx->Parameter2);
//param2 determines the effect's behaviour
//0 - adder's kiss projectile (0xcd)
// adds play bam and damage opcodes to the projectile
@@ -430,8 +435,19 @@ int fx_special_effect (Scriptable* Owner, Actor* target, Effect* fx)
strnuprcpy(fx->Resource,"rdead",8);
break;
}
- Owner->CastSpell(fx->Resource, target, false);
- Owner->CastSpellEnd(fx->CasterLevel);
+
+ ieResRef OldSpellResRef;
+
+ memcpy(OldSpellResRef, Owner->SpellResRef, sizeof(OldSpellResRef));
+ Owner->SetSpellResRef(fx->Resource);
+ //cast spell on target
+ //flags: deplete, instant, no interrupt
+ Owner->CastSpell(target, false, true, true);
+ //actually finish casting (if this is not good enough, use an action???)
+ //flag: instant - no casting animation
+ Owner->CastSpellEnd(fx->CasterLevel, 1);
+ Owner->SetSpellResRef(OldSpellResRef);
+
return FX_NOT_APPLIED;
}
//0xc5 fx_multiple_vvc
@@ -439,7 +455,7 @@ int fx_special_effect (Scriptable* Owner, Actor* target, Effect* fx)
//it plays multiple vvc's with a given delay and duration
int fx_multiple_vvc (Scriptable* Owner, Actor* /*target*/, Effect* fx)
{
- if (0) printf( "fx_multiple_vvc (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_multiple_vvc(%2d): Par2: %d", fx->Opcode, fx->Parameter2);
Map *area = Owner->GetCurrentArea();
if (!area)
@@ -458,7 +474,7 @@ int fx_multiple_vvc (Scriptable* Owner, Actor* /*target*/, Effect* fx)
offset.y=atoi(tab->QueryField(rows,1));
delay = atoi(tab->QueryField(rows,3));
duration = atoi(tab->QueryField(rows,4));
- ScriptedAnimation *sca = gamedata->GetScriptedAnimation(tab->QueryField(rows,2), true);
+ ScriptedAnimation *sca = gamedata->GetScriptedAnimation(tab->QueryField(rows,2), true);
if (!sca) continue;
sca->SetBlend();
sca->SetDelay(AI_UPDATE_TIME*delay);
@@ -474,7 +490,7 @@ int fx_multiple_vvc (Scriptable* Owner, Actor* /*target*/, Effect* fx)
//GemRB specific, to support BMP area background changes (desert hell projectile)
int fx_change_background (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
{
- if (0) printf( "fx_change_background (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_change_background(%2d): Par2: %d", fx->Opcode, fx->Parameter2);
Map *map = core->GetGame()->GetCurrentArea();
if (map) {
map->SetBackground(fx->Resource, fx->Duration);
@@ -484,12 +500,336 @@ int fx_change_background (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
//0xc7-c8 fx_unknown
//0xc9 fx_overlay
-int fx_overlay (Scriptable* /*Owner*/, Actor* target, Effect* fx)
+static EffectRef fx_armor_ref = { "ACVsDamageTypeModifier", -1 };
+static EffectRef fx_breath_ref = { "SaveVsBreathModifier", -1 };
+static EffectRef fx_death_ref = { "SaveVsDeathModifier", -1 };
+static EffectRef fx_poly_ref = { "SaveVsPolyModifier", -1 };
+static EffectRef fx_spell_ref = { "SaveVsSpellsModifier", -1 };
+static EffectRef fx_wands_ref = { "SaveVsWandsModifier", -1 };
+static EffectRef fx_damage_opcode_ref = { "Damage", -1 };
+static EffectRef fx_colorchange_ref = { "Color:SetRGBGlobal", -1 };
+static EffectRef fx_colorpulse_ref = { "Color:PulseRGBGlobal", -1 };
+static EffectRef fx_single_color_pulse_ref = { "Color:BriefRGB", -1 };
+static EffectRef fx_resistfire_ref = { "FireResistanceModifier", -1 };
+static EffectRef fx_resistmfire_ref = { "MagicalFireResistanceModifier", -1 };
+static EffectRef fx_protection_ref = { "Protection:SpellLevel", -1 };
+static EffectRef fx_magicdamage_ref = { "MagicDamageResistanceModifier", -1 };
+static EffectRef fx_dispel_ref = { "DispelEffects", -1 };
+static EffectRef fx_miscast_ref = { "MiscastMagicModifier", -1 };
+static EffectRef fx_set_state_ref = { "SetStatus", -1 };
+
+static inline int DamageLastHitter(Effect *fx, Actor *target, int param1, int param2)
+{
+ if (fx->Parameter3) {
+ Map *map = target->GetCurrentArea();
+ Actor *actor = map->GetActorByGlobalID(target->LastHitter);
+ if (actor && PersonalDistance(target, actor)<30 ) {
+ const TriggerEntry *entry = target->GetMatchingTrigger(trigger_hitby, TEF_PROCESSED_EFFECTS);
+ if (entry) {
+ Effect *newfx = EffectQueue::CreateEffect( fx_damage_opcode_ref, param1, param2<<16, FX_DURATION_INSTANT_PERMANENT);
+ newfx->Target = FX_TARGET_PRESET;
+ newfx->Power = fx->Power;
+ memcpy(newfx->Source, fx->Source, sizeof(newfx->Source) );
+ core->ApplyEffect(newfx, actor, target);
+ if (fx->Parameter3!=0xffffffff) {
+ fx->Parameter3--;
+ }
+ }
+ }
+ }
+
+ if (!fx->Parameter3) {
+ return FX_NOT_APPLIED;
+ }
+ return FX_APPLIED;
+}
+
+static inline void ConvertTiming(Effect *fx, int Duration)
{
- if (0) printf( "fx_overlay (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 );
- target->AddAnimation(fx->Resource,-1,0,true);
+ fx->Duration = Duration;
+ fx->TimingMode = FX_DURATION_INSTANT_LIMITED;
+ ieDword GameTime = core->GetGame()->GameTime;
+ PrepareDuration(fx);
+}
+
+int fx_overlay (Scriptable* Owner, Actor* target, Effect* fx)
+{
+ if(0) print("fx_overlay(%2d): Par2: %d", fx->Opcode, fx->Parameter2);
+ if (!target) {
+ return FX_NOT_APPLIED;
+ }
+ int terminate = FX_APPLIED;
+ bool playonce = false;
+ ieDword tint = 0;
+ Effect *newfx;
+
//special effects based on fx_param2
- return FX_NOT_APPLIED;
+ if (fx->FirstApply) {
+ switch(fx->Parameter2) {
+ case 0: //cloak of warding
+ ConvertTiming (fx, 5 * fx->CasterLevel);
+ fx->Parameter3 = core->Roll(3,4,fx->CasterLevel);
+ break;
+ case 1: //shield
+ ConvertTiming(fx, 25 * fx->CasterLevel);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_armor_ref, 3, 16);
+ core->ApplyEffect(newfx, target, Owner);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_breath_ref, 1, 0);
+ core->ApplyEffect(newfx, target, Owner);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_death_ref, 1, 0);
+ core->ApplyEffect(newfx, target, Owner);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_poly_ref, 1, 0);
+ core->ApplyEffect(newfx, target, Owner);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_spell_ref, 1, 0);
+ core->ApplyEffect(newfx, target, Owner);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_wands_ref, 1, 0);
+ core->ApplyEffect(newfx, target, Owner);
+ break;
+ case 2: //black barbed shield
+ ConvertTiming (fx, core->Roll(10,3,0));
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_armor_ref, 2, 0);
+ core->ApplyEffect(newfx, target, Owner);
+ fx->Parameter3=0xffffffff;
+ break;
+ case 3: //pain mirror
+ fx->Parameter3 = 1;
+ ConvertTiming (fx, 5 * fx->CasterLevel);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_colorpulse_ref, 0xFAFF7000, 0x30000C);
+ core->ApplyEffect(newfx, target, Owner);
+ break;
+ case 4: //guardian mantle
+ ConvertTiming (fx, 50 + 5 * fx->CasterLevel);
+ break;
+ case 5: //shroud of shadows
+
+ break;
+ case 6: //duplication
+ core->GetAudioDrv()->Play("magic02", target->Pos.x, target->Pos.y);
+ break;
+ case 7: //armor
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_colorchange_ref, 0x825A2800, -1);
+ core->ApplyEffect(newfx, target, Owner);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_armor_ref, 6, 16);
+ core->ApplyEffect(newfx, target, Owner);
+ break;
+ case 8: //antimagic shell
+ {
+ int i;
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_dispel_ref, 100, 0);
+ newfx->Power = 10;
+ core->ApplyEffect(newfx, target, Owner);
+
+ for (i=0;i<2;i++) {
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_miscast_ref, 100, i);
+ core->ApplyEffect(newfx, target, Owner);
+ }
+
+ for (i=1;i<10;i++) {
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_protection_ref, i, 0);
+ core->ApplyEffect(newfx, target, Owner);
+ }
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_magicdamage_ref, 100, 0);
+ core->ApplyEffect(newfx, target, Owner);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_set_state_ref, 1, STATE_ANTIMAGIC);
+ core->ApplyEffect(newfx, target, Owner);
+ }
+ break;
+ case 9: case 10: //unused
+ default:
+ break;
+ case 11: //flame walk
+ ConvertTiming (fx, 10 * fx->CasterLevel);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_single_color_pulse_ref, 0xFF00, 0x400040);
+ core->ApplyEffect(newfx, target, Owner);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_colorchange_ref, 0x64FA00, 0x50005);
+ //wtf is this
+ newfx->IsVariable = 0x23;
+ core->ApplyEffect(newfx, target, Owner);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_resistfire_ref, 50, 1);
+ core->ApplyEffect(newfx, target, Owner);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_resistmfire_ref, 50, 1);
+ core->ApplyEffect(newfx, target, Owner);
+ break;
+ case 12: //protection from evil
+ ConvertTiming (fx, 10 * fx->CasterLevel);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_armor_ref, 2, 0);
+ core->ApplyEffect(newfx, target, Owner);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_breath_ref, 2, 0);
+ core->ApplyEffect(newfx, target, Owner);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_death_ref, 2, 0);
+ core->ApplyEffect(newfx, target, Owner);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_poly_ref, 2, 0);
+ core->ApplyEffect(newfx, target, Owner);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_spell_ref, 2, 0);
+ core->ApplyEffect(newfx, target, Owner);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_wands_ref, 2, 0);
+ core->ApplyEffect(newfx, target, Owner);
+ //terminate = FX_NOT_APPLIED;
+ break;
+ case 13: //conflagration
+ ConvertTiming (fx, 50);
+ playonce = true;
+ break;
+ case 14: //infernal shield
+ tint = 0x5EC2FE;
+ ConvertTiming (fx, 5 * fx->CasterLevel);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_resistfire_ref, 150, 1);
+ core->ApplyEffect(newfx, target, Owner);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_resistmfire_ref, 150, 1);
+ core->ApplyEffect(newfx, target, Owner);
+ break;
+ case 15: //submerge the will
+ tint = 0x538D90;
+ ConvertTiming (fx, 12 * fx->CasterLevel);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_armor_ref, 2, 16);
+ core->ApplyEffect(newfx, target, Owner);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_breath_ref, 1, 0);
+ core->ApplyEffect(newfx, target, Owner);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_death_ref, 1, 0);
+ core->ApplyEffect(newfx, target, Owner);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_poly_ref, 1, 0);
+ core->ApplyEffect(newfx, target, Owner);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_spell_ref, 1, 0);
+ core->ApplyEffect(newfx, target, Owner);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_wands_ref, 1, 0);
+ core->ApplyEffect(newfx, target, Owner);
+ break;
+ case 16: //balance in all things
+ tint = 0x615AB4;
+ fx->Parameter3 = fx->CasterLevel/4;
+ ConvertTiming (fx, 5 * fx->CasterLevel);
+
+ newfx = EffectQueue::CreateEffectCopy(fx, fx_colorpulse_ref, 0x615AB400, 0x30000C);
+ core->ApplyEffect(newfx, target, Owner);
+ playonce = true;
+ break;
+ }
+
+ if (!target->HasVVCCell(fx->Resource)) {
+ ScriptedAnimation *sca = gamedata->GetScriptedAnimation(fx->Resource, true);
+ if (sca) {
+ if (tint) {
+ RGBModifier rgb;
+
+ rgb.speed=-1;
+ rgb.phase=0;
+ rgb.rgb.r=tint;
+ rgb.rgb.g=tint >> 8;
+ rgb.rgb.b=tint >> 16;
+ rgb.rgb.a=tint >> 24;
+ rgb.type=RGBModifier::TINT;
+
+ sca->AlterPalette(rgb);
+ }
+ sca->SetBlend();
+ if (playonce) {
+ sca->PlayOnce();
+ } else {
+ sca->SetDefaultDuration(fx->Duration-core->GetGame()->Ticks);
+ }
+ sca->SetBlend();
+ sca->SetEffectOwned(true);
+ ScriptedAnimation *twin = sca->DetachTwin();
+ if (twin) {
+ target->AddVVCell(twin);
+ }
+ target->AddVVCell(sca);
+ }
+ }
+ }
+
+ ScriptedAnimation *vvc = target->GetVVCCell(&target->vvcOverlays, fx->Resource);
+ if (vvc) {
+ vvc->active = true;
+ vvc = target->GetVVCCell(&target->vvcShields, fx->Resource);
+ if (vvc) {
+ vvc->active = true;
+ }
+ } else {
+ return FX_NOT_APPLIED;
+ }
+
+ switch(fx->Parameter2) {
+ case 0: //cloak of warding
+ if (fx->Parameter3<=0) {
+ return FX_NOT_APPLIED;
+ }
+ //flag for removal trigger
+ target->Modified[IE_STONESKINS]=1;
+ break;
+ case 2: //black barbed shield (damage opponents)
+ if (target->LastHitter) {
+ terminate = DamageLastHitter(fx, target, core->Roll(2, 6, 0),0x100000 );
+ }
+ break;
+ case 3: case 16: //pain mirror or balance in all things
+ if (target->LastHitter) {
+ //well, someone took LastDamage out
+ //terminate = DamageLastHitter(fx, target, target->LastDamage, target->LastDamageType);
+ }
+ break;
+ case 4:
+ //this is not the original position, but the immunity stat was already used for things like this
+ //as an added benefit, HasImmunityEffects also works with the pst spell
+ STAT_BIT_OR( IE_IMMUNITY, IMM_GUARDIAN);
+ break;
+ case 5:
+ break;
+ case 6:
+ STATE_SET(STATE_EE_DUPL);
+ break;
+ case 7:
+ break;
+ case 8: //antimagic shell
+ if (!target->HasVVCCell("S061GLWB") ) {
+ ScriptedAnimation *sca = gamedata->GetScriptedAnimation("S061GLWB", false);
+ if (sca) {
+ sca->SetDefaultDuration(fx->Duration-core->GetGame()->Ticks);
+ target->AddVVCell(sca);
+ }
+ }
+ break;
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ break;
+ default:;
+ }
+ //PST doesn't keep these effects applied, but we do, because we don't have
+ //separate stats for these effects.
+ //We just use Parameter3 for the stats where needed
+ return terminate;
}
//0xca fx_unknown
@@ -499,7 +839,7 @@ int fx_overlay (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//but i would rather use the IWD2 method
int fx_bless (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_curse (%2d): Par1: %d\n", fx->Opcode, fx->Parameter1 );
+ if(0) print("fx_curse(%2d): Par1: %d", fx->Opcode, fx->Parameter1);
//this bit is the same as the invisibility bit in other games
//it should be considered what if we replace the pst invis bit
//with this one (losing binary compatibility, gaining easier
@@ -510,7 +850,7 @@ int fx_bless (Scriptable* /*Owner*/, Actor* target, Effect* fx)
target->SetColorMod(255, RGBModifier::ADD, 0x18, 0xc8, 0xc8, 0xc8);
STATE_SET( STATE_BLESS );
- STAT_SUB( IE_TOHIT, fx->Parameter1);
+ target->ToHit.HandleFxBonus(-fx->Parameter1, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
STAT_SUB( IE_SAVEVSDEATH, fx->Parameter1);
STAT_SUB( IE_SAVEVSWANDS, fx->Parameter1);
STAT_SUB( IE_SAVEVSPOLY, fx->Parameter1);
@@ -522,7 +862,7 @@ int fx_bless (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0xcb fx_curse
int fx_curse (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_curse (%2d): Par1: %d\n", fx->Opcode, fx->Parameter1 );
+ if(0) print("fx_curse(%2d): Par1: %d", fx->Opcode, fx->Parameter1);
//this bit is the same as the invisibility bit in other games
//it should be considered what if we replace the pst invis bit
//with this one (losing binary compatibility, gaining easier
@@ -530,7 +870,7 @@ int fx_curse (Scriptable* /*Owner*/, Actor* target, Effect* fx)
if (STATE_GET (STATE_PST_CURSE) ) //curse is non cumulative
return FX_NOT_APPLIED;
STATE_SET( STATE_PST_CURSE );
- STAT_SUB( IE_TOHIT, fx->Parameter1);
+ target->ToHit.HandleFxBonus(-fx->Parameter1, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
STAT_SUB( IE_SAVEVSDEATH, fx->Parameter1);
STAT_SUB( IE_SAVEVSWANDS, fx->Parameter1);
STAT_SUB( IE_SAVEVSPOLY, fx->Parameter1);
@@ -545,7 +885,7 @@ static EffectRef fx_bless_ref = { "Bless", -1 };
int fx_prayer (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_prayer (%2d): Par1: %d\n", fx->Opcode, fx->Parameter1 );
+ if(0) print("fx_prayer(%2d): Par1: %d", fx->Opcode, fx->Parameter1);
int ea = target->GetStat(IE_EA);
int type;
if (ea>EA_EVILCUTOFF) type = 1;
@@ -556,7 +896,7 @@ int fx_prayer (Scriptable* Owner, Actor* target, Effect* fx)
int i = map->GetActorCount(true);
Effect *newfx = EffectQueue::CreateEffect(type?fx_curse_ref:fx_bless_ref, fx->Parameter1, fx->Parameter2, FX_DURATION_INSTANT_LIMITED);
memcpy(newfx, fx->Source,sizeof(ieResRef));
- newfx->Duration=60;
+ newfx->Duration = 60;
while(i--) {
Actor *tar=map->GetActor(i,true);
ea = tar->GetStat(IE_EA);
@@ -576,7 +916,7 @@ int fx_prayer (Scriptable* Owner, Actor* target, Effect* fx)
//0xcd fx_move_view
int fx_move_view (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
{
- if (0) printf( "fx_move_view (%2d): Speed: %d\n", fx->Opcode, fx->Parameter1 );
+ if(0) print("fx_move_view(%2d): Speed: %d", fx->Opcode, fx->Parameter1);
Map *map = core->GetGame()->GetCurrentArea();
if (map) {
core->timer->SetMoveViewPort( fx->PosX, fx->PosY, fx->Parameter1, true);
@@ -587,7 +927,7 @@ int fx_move_view (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
//0xce fx_embalm
int fx_embalm (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_embalm (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_embalm(%2d): Par2: %d", fx->Opcode, fx->Parameter2);
if (STATE_GET (STATE_EMBALM) ) //embalm is non cumulative
return FX_NOT_APPLIED;
STATE_SET( STATE_EMBALM );
@@ -601,16 +941,16 @@ int fx_embalm (Scriptable* /*Owner*/, Actor* target, Effect* fx)
}
STAT_ADD( IE_MAXHITPOINTS, fx->Parameter1);
if (fx->Parameter2) {
- STAT_ADD( IE_ARMORCLASS,2 );
+ target->AC.HandleFxBonus(2, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
} else {
- STAT_ADD( IE_ARMORCLASS,1 );
+ target->AC.HandleFxBonus(1, fx->TimingMode==FX_DURATION_INSTANT_PERMANENT);
}
return FX_APPLIED;
}
//0xcf fx_stop_all_action
int fx_stop_all_action (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
{
- if (0) printf( "fx_stop_all_action (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 );
+ if(0) print("fx_stop_all_action(%2d): Par2: %d", fx->Opcode, fx->Parameter2);
if (fx->Parameter2) {
core->GetGame()->TimeStop(NULL, 0xffffffff);
} else {
@@ -625,7 +965,7 @@ int fx_iron_fist (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
ieDword p1,p2;
- if (0) printf( "fx_iron_fist (%2d): Par1: %d Par2: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_iron_fist(%2d): Par1: %d Par2: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
switch (fx->Parameter2)
{
case 0: p1 = 3; p2 = 6; break;
@@ -641,16 +981,14 @@ int fx_iron_fist (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//0xd1 fx_hostile_image
int fx_hostile_image (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
{
- if (0) printf( "fx_hostile_image (%2d): Par1: %d Par2: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_hostile_image(%2d): Par1: %d Par2: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
return FX_NOT_APPLIED;
}
//0xd2 fx_detect_evil
-static EffectRef fx_single_color_pulse_ref = { "Color:BriefRGB", -1 };
-
int fx_detect_evil (Scriptable* Owner, Actor* target, Effect* fx)
{
- if (0) printf( "fx_detect_evil (%2d): Par1: %d Par2: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
+ if(0) print("fx_detect_evil(%2d): Par1: %d Par2: %d", fx->Opcode, fx->Parameter1, fx->Parameter2);
ieDword type = fx->Parameter2;
//default is alignment/evil/speed 30/range 10
if (!type) type = 0x08031e0a;
@@ -677,7 +1015,7 @@ int fx_detect_evil (Scriptable* Owner, Actor* target, Effect* fx)
//0xd3 fx_jumble_curse
int fx_jumble_curse (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf( "fx_jumble_curse (%2d)\n", fx->Opcode );
+ if(0) print("fx_jumble_curse(%2d)", fx->Opcode);
if (STATE_GET( STATE_DEAD) ) {
return FX_NOT_APPLIED;
@@ -709,7 +1047,7 @@ int fx_jumble_curse (Scriptable* /*Owner*/, Actor* target, Effect* fx)
//In GemRB it is used in a custom spell
int fx_speak_with_dead (Scriptable* /*Owner*/, Actor* target, Effect* fx)
{
- if (0) printf("fx_speak_with_dead (%2d)\n", fx->Opcode );
+ if(0) print("fx_speak_with_dead(%2d)", fx->Opcode);
if (!STATE_GET( STATE_DEAD) ) {
return FX_NOT_APPLIED;
}
diff --git a/gemrb/plugins/SAVImporter/CMakeLists.txt b/gemrb/plugins/SAVImporter/CMakeLists.txt
new file mode 100644
index 0000000..e99bef0
--- /dev/null
+++ b/gemrb/plugins/SAVImporter/CMakeLists.txt
@@ -0,0 +1 @@
+ADD_GEMRB_PLUGIN (SAVImporter SAVImporter.cpp)
diff --git a/gemrb/plugins/SAVImporter/Makefile.am b/gemrb/plugins/SAVImporter/Makefile.am
new file mode 100644
index 0000000..825d8d9
--- /dev/null
+++ b/gemrb/plugins/SAVImporter/Makefile.am
@@ -0,0 +1,3 @@
+plugin_LTLIBRARIES = SAVImporter.la
+SAVImporter_la_LDFLAGS = -module -avoid-version -shared
+SAVImporter_la_SOURCES = SAVImporter.cpp SAVImporter.h
diff --git a/gemrb/plugins/SAVImporter/SAVImporter.cpp b/gemrb/plugins/SAVImporter/SAVImporter.cpp
new file mode 100644
index 0000000..5d8af22
--- /dev/null
+++ b/gemrb/plugins/SAVImporter/SAVImporter.cpp
@@ -0,0 +1,124 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "SAVImporter.h"
+
+#include "win32def.h"
+
+#include "Compressor.h"
+#include "FileCache.h"
+#include "Interface.h"
+#include "PluginMgr.h"
+
+using namespace GemRB;
+
+SAVImporter::SAVImporter()
+{
+}
+
+SAVImporter::~SAVImporter()
+{
+}
+
+int SAVImporter::DecompressSaveGame(DataStream *compressed)
+{
+ char Signature[8];
+ compressed->Read( Signature, 8 );
+ if (strncmp( Signature, "SAV V1.0", 8 ) ) {
+ return GEM_ERROR;
+ }
+ int All = compressed->Remains();
+ int Current;
+ int percent, last_percent = 20;
+ if (!All) return GEM_ERROR;
+ do {
+ ieDword fnlen, complen, declen;
+ compressed->ReadDword( &fnlen );
+ if (!fnlen) {
+ Log(ERROR, "SAVImporter", "Corrupt Save Detected");
+ return GEM_ERROR;
+ }
+ char* fname = ( char* ) malloc( fnlen );
+ compressed->Read( fname, fnlen );
+ strlwr(fname);
+ compressed->ReadDword( &declen );
+ compressed->ReadDword( &complen );
+ print("Decompressing %s", fname);
+ DataStream* cached = CacheCompressedStream(compressed, fname, complen, true);
+ free( fname );
+ if (!cached)
+ return GEM_ERROR;
+ delete cached;
+ Current = compressed->Remains();
+ //starting at 20% going up to 70%
+ percent = (20 + (All - Current) * 50 / All);
+ if (percent - last_percent > 5) {
+ core->LoadProgress(percent);
+ last_percent = percent;
+ }
+ }
+ while(Current);
+ return GEM_OK;
+}
+
+//this one can create .sav files only
+int SAVImporter::CreateArchive(DataStream *compressed)
+{
+ if (!compressed) {
+ return GEM_ERROR;
+ }
+ char Signature[8];
+
+ memcpy(Signature,"SAV V1.0",8);
+ compressed->Write(Signature, 8);
+
+ return GEM_OK;
+}
+
+int SAVImporter::AddToSaveGame(DataStream *str, DataStream *uncompressed)
+{
+ ieDword fnlen, declen, complen;
+
+ fnlen = strlen(uncompressed->filename)+1;
+ declen = uncompressed->Size();
+ str->WriteDword( &fnlen);
+ str->Write( uncompressed->filename, fnlen);
+ str->WriteDword( &declen);
+ //baaah, we dump output right in the stream, we get the compressed length
+ //only after the compressed data was written
+ complen = 0xcdcdcdcd; //placeholder
+ unsigned long Pos = str->GetPos(); //storing the stream position
+ str->WriteDword( &complen);
+
+ PluginHolder<Compressor> comp(PLUGIN_COMPRESSION_ZLIB);
+ comp->Compress( str, uncompressed );
+
+ //writing compressed length (calculated)
+ unsigned long Pos2 = str->GetPos();
+ complen = Pos2-Pos-sizeof(ieDword); //calculating the compressed stream size
+ str->Seek(Pos, GEM_STREAM_START); //going back to the placeholder
+ str->WriteDword( &complen); //updating size
+ str->Seek(Pos2, GEM_STREAM_START);//resuming work
+ return GEM_OK;
+}
+
+#include "plugindef.h"
+
+GEMRB_PLUGIN(0xCDF132C, "SAV File Importer")
+PLUGIN_CLASS(IE_SAV_CLASS_ID, SAVImporter)
+END_PLUGIN()
diff --git a/gemrb/plugins/SAVImporter/SAVImporter.h b/gemrb/plugins/SAVImporter/SAVImporter.h
new file mode 100644
index 0000000..9426896
--- /dev/null
+++ b/gemrb/plugins/SAVImporter/SAVImporter.h
@@ -0,0 +1,43 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef SAVIMPORTER_H
+#define SAVIMPORTER_H
+
+#include "ArchiveImporter.h"
+
+#include "globals.h"
+
+#include "System/DataStream.h"
+
+namespace GemRB {
+
+class SAVImporter : public ArchiveImporter {
+public:
+ SAVImporter(void);
+ ~SAVImporter(void);
+ int DecompressSaveGame(DataStream *compressed);
+ int AddToSaveGame(DataStream *str, DataStream *uncompressed);
+ int CreateArchive(DataStream *compressed);
+};
+
+}
+
+#endif
diff --git a/gemrb/plugins/SDLAudio/SDLAudio.cpp b/gemrb/plugins/SDLAudio/SDLAudio.cpp
index d307552..d42f43a 100644
--- a/gemrb/plugins/SDLAudio/SDLAudio.cpp
+++ b/gemrb/plugins/SDLAudio/SDLAudio.cpp
@@ -31,6 +31,8 @@
#include <SDL.h>
#include <SDL_mixer.h>
+using namespace GemRB;
+
SDLAudio::SDLAudio(void)
{
XPos = 0;
@@ -63,7 +65,7 @@ bool SDLAudio::Init(void)
if (Mix_OpenAudio(22050, MIX_DEFAULT_FORMAT, 2, 8192) < 0) {
return false;
}
- Mix_QuerySpec(&audio_rate, &audio_format, &audio_channels);
+ Mix_QuerySpec(&audio_rate, (Uint16 *)&audio_format, &audio_channels);
channel_data.resize(Mix_AllocateChannels(-1));
for (unsigned int i = 0; i < channel_data.size(); i++) {
@@ -91,14 +93,14 @@ void SDLAudio::music_callback(void *udata, unsigned short *stream, int len) {
break;
// TODO: this shouldn't be in the callback (see also the openal thread)
- printMessage("SDLAudio", "Playing Next Music\n", WHITE );
+ Log(MESSAGE, "SDLAudio", "Playing Next Music");
core->GetMusicMgr()->PlayNext();
stream = stream + cnt;
len = len - (cnt * 2);
if (!driver->MusicPlaying) {
- printMessage( "SDLAudio", "No Other Music to play\n", WHITE );
+ Log(MESSAGE, "SDLAudio", "No Other Music to play");
memset(stream, 0, len);
Mix_HookMusic(NULL, NULL);
break;
@@ -138,7 +140,7 @@ Holder<SoundHandle> SDLAudio::Play(const char* ResRef, int XPos, int YPos, unsig
// TODO: move this loading code somewhere central
ResourceHolder<SoundMgr> acm(ResRef);
if (!acm) {
- printf("failed acm load\n");
+ print("failed acm load");
return Holder<SoundHandle>();
}
int cnt = acm->get_length();
@@ -170,7 +172,7 @@ Holder<SoundHandle> SDLAudio::Play(const char* ResRef, int XPos, int YPos, unsig
// make SDL_mixer chunk
Mix_Chunk *chunk = Mix_QuickLoad_RAW(cvt.buf, cvt.len*cvt.len_ratio);
if (!chunk) {
- printf("error loading chunk\n");
+ print("error loading chunk");
return Holder<SoundHandle>();
}
@@ -183,7 +185,7 @@ Holder<SoundHandle> SDLAudio::Play(const char* ResRef, int XPos, int YPos, unsig
channel = Mix_PlayChannel(channel, chunk, 0);
if (channel < 0) {
SDL_mutexV(OurMutex);
- printf("error playing channel\n");
+ print("error playing channel");
return Holder<SoundHandle>();
}
@@ -197,7 +199,7 @@ Holder<SoundHandle> SDLAudio::Play(const char* ResRef, int XPos, int YPos, unsig
int SDLAudio::CreateStream(Holder<SoundMgr> newMusic)
{
- printf("SDLAudio setting new music\n");
+ print("SDLAudio setting new music");
MusicReader = newMusic;
// TODO
@@ -232,11 +234,6 @@ bool SDLAudio::CanPlay()
return true;
}
-bool SDLAudio::IsSpeaking()
-{
- return Mix_Playing(0);
-}
-
void SDLAudio::UpdateListenerPos(int x, int y)
{
// TODO
@@ -295,7 +292,7 @@ int SDLAudio::SetupNewStream(ieWord x, ieWord y, ieWord z,
(void)gain;
(void)point;
- printf("SDLAudio allocating stream\n");
+ print("SDLAudio allocating stream");
// TODO: buggy
MusicPlaying = false;
@@ -316,7 +313,7 @@ bool SDLAudio::ReleaseStream(int stream, bool HardStop)
return false;
}
- printf("SDLAudio releasing stream\n");
+ print("SDLAudio releasing stream");
(void)HardStop;
@@ -359,8 +356,8 @@ void SDLAudio::QueueBuffer(int stream, unsigned short bits,
SDL_AudioCVT cvt;
if (SDL_BuildAudioCVT(&cvt, (bits == 8 ? AUDIO_S8 : AUDIO_S16SYS), channels, samplerate,
audio_format, audio_channels, audio_rate) == 0) {
- printMessage("SDLAudio", "Couldn't convert video stream!\n", RED );
- printf("trying to convert %d bits, %d channels, %d rate\n", bits, channels, samplerate);
+ Log(ERROR, "SDLAudio", "Couldn't convert video stream! trying to convert %d bits, %d channels, %d rate",
+ bits, channels, samplerate);
return;
}
cvt.buf = (Uint8*)malloc(size*cvt.len_mult);
diff --git a/gemrb/plugins/SDLAudio/SDLAudio.h b/gemrb/plugins/SDLAudio/SDLAudio.h
index 4bdbbaf..b15b0df 100644
--- a/gemrb/plugins/SDLAudio/SDLAudio.h
+++ b/gemrb/plugins/SDLAudio/SDLAudio.h
@@ -25,6 +25,10 @@
#include <vector>
+struct SDL_mutex;
+
+namespace GemRB {
+
struct BufferedData {
char *buf;
unsigned int size;
@@ -42,7 +46,6 @@ public:
bool Pause() { return true; } /*not implemented*/
bool Resume() { return true; } /*not implemented*/
bool CanPlay();
- bool IsSpeaking();
void ResetMusics();
void UpdateListenerPos(int XPos, int YPos);
void GetListenerPos(int& XPos, int& YPos);
@@ -75,7 +78,9 @@ private:
unsigned short audio_format;
int audio_channels;
- struct SDL_mutex* OurMutex;
+ SDL_mutex* OurMutex;
};
+}
+
#endif
diff --git a/gemrb/plugins/SDLVideo/CMakeLists.txt b/gemrb/plugins/SDLVideo/CMakeLists.txt
index 5bff68b..44e63b5 100644
--- a/gemrb/plugins/SDLVideo/CMakeLists.txt
+++ b/gemrb/plugins/SDLVideo/CMakeLists.txt
@@ -1,4 +1,4 @@
INCLUDE_DIRECTORIES( ${SDL_INCLUDE_DIR} )
-ADD_GEMRB_PLUGIN (SDLVideo SDLVideo.cpp)
-TARGET_LINK_LIBRARIES( SDLVideo ${SDL_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} )
+ADD_GEMRB_PLUGIN (SDLVideo COCOA SDLVideo.cpp SDL12Video.cpp)
+TARGET_LINK_LIBRARIES( SDLVideo ${SDL_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${COCOA_LIBRARY_PATH})
diff --git a/gemrb/plugins/SDLVideo/CocoaWrapper.m b/gemrb/plugins/SDLVideo/CocoaWrapper.m
new file mode 100644
index 0000000..bb21b3e
--- /dev/null
+++ b/gemrb/plugins/SDLVideo/CocoaWrapper.m
@@ -0,0 +1,47 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003-2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+#import <SDL.h>
+#import "CocoaWrapper.h"
+
+// SDL 1.3 has its own App Delegate, but curently all it does is what this delegate category is doing
+// SDL is nice enough to check if a delegate exists prior to assigning its own.
+
+/*
+Mac OS X wrapper
+*/
+
+ at interface CocoaWrapper (SDLTerminate)
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
+ at end
+
+ at implementation CocoaWrapper (SDLTerminate)
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *) __unused sender
+{
+ NSLog(@"Received terminate request. Dispatching SDL_QUIT event...");
+ SDL_Event event;
+ event.type = SDL_QUIT;
+ if (SDL_PushEvent(&event) == 0) {
+ // we deny the application request to terminate.
+ // this way we can let GemRB handle quit event so we can save before exit etc.
+ return NSTerminateCancel;
+ }
+ return NSTerminateNow;
+}
+ at end
diff --git a/gemrb/plugins/SDLVideo/Makefile.am b/gemrb/plugins/SDLVideo/Makefile.am
index 0f5cde2..4ca60ba 100644
--- a/gemrb/plugins/SDLVideo/Makefile.am
+++ b/gemrb/plugins/SDLVideo/Makefile.am
@@ -2,4 +2,4 @@ plugin_LTLIBRARIES = SDLVideo.la
INCLUDES = $(SDL_CFLAGS)
SDLVideo_la_LDFLAGS = -module -avoid-version -shared
SDLVideo_la_LIBADD = @SDL_LIBS@
-SDLVideo_la_SOURCES = SDLVideo.cpp SDLVideo.h SDLVideoDriver.inl TileRenderer.inl
+SDLVideo_la_SOURCES = SDLVideo.cpp SDLVideo.h SpriteRenderer.inl TileRenderer.inl
diff --git a/gemrb/plugins/SDLVideo/SDL12Video.cpp b/gemrb/plugins/SDLVideo/SDL12Video.cpp
new file mode 100644
index 0000000..d41a36c
--- /dev/null
+++ b/gemrb/plugins/SDLVideo/SDL12Video.cpp
@@ -0,0 +1,343 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003-2012 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "SDL12Video.h"
+
+#include "Game.h"
+#include "Interface.h"
+
+using namespace GemRB;
+
+SDL12VideoDriver::SDL12VideoDriver(void)
+{
+ overlay = NULL;
+}
+
+SDL12VideoDriver::~SDL12VideoDriver(void)
+{
+ DestroyMovieScreen();
+}
+
+int SDL12VideoDriver::Init(void)
+{
+ int ret = SDLVideoDriver::Init();
+ if (ret==GEM_OK) {
+ SDL_EnableUNICODE( 1 );
+ SDL_EnableKeyRepeat( 500, 50 );
+ }
+ return ret;
+}
+
+int SDL12VideoDriver::CreateDisplay(int w, int h, int b, bool fs, const char* title)
+{
+ bpp=b;
+ fullscreen=fs;
+ Log(MESSAGE, "SDL 1.2 Driver", "Creating display");
+ ieDword flags = SDL_SWSURFACE;
+ if (fullscreen) {
+ flags |= SDL_FULLSCREEN;
+ }
+ Log(MESSAGE, "SDL 1.2 Driver", "SDL_SetVideoMode...");
+ disp = SDL_SetVideoMode( w, h, bpp, flags );
+ SDL_WM_SetCaption( title, 0 );
+ if (disp == NULL) {
+ Log(ERROR, "SDL 1.2 Driver", "%s", SDL_GetError());
+ return GEM_ERROR;
+ }
+ Log(MESSAGE, "SDL 1.2 Driver", "Checking for HardWare Acceleration...");
+ const SDL_VideoInfo* vi = SDL_GetVideoInfo();
+ if (!vi) {
+ Log(WARNING, "SDL 1.2 Driver", "No Hardware Acceleration available.");
+ }
+
+ width = disp->w;
+ height = disp->h;
+ Viewport.w = width;
+ Viewport.h = height;
+ Log(MESSAGE, "SDL 1.2 Driver", "Creating Main Surface...");
+ SDL_Surface* tmp = SDL_CreateRGBSurface( SDL_SWSURFACE, width, height,
+ bpp, 0, 0, 0, 0 );
+ Log(MESSAGE, "SDL 1.2 Driver", "Creating Back Buffer...");
+ backBuf = SDL_DisplayFormat( tmp );
+ Log(MESSAGE, "SDL 1.2 Driver", "Creating Extra Buffer...");
+ extra = SDL_DisplayFormat( tmp );
+ SDL_LockSurface( extra );
+ long val = SDL_MapRGBA( extra->format, fadeColor.r, fadeColor.g, fadeColor.b, 0 );
+ SDL_FillRect( extra, NULL, val );
+ SDL_UnlockSurface( extra );
+ SDL_FreeSurface( tmp );
+
+ return GEM_OK;
+}
+
+void SDL12VideoDriver::InitMovieScreen(int &w, int &h, bool yuv)
+{
+ if (yuv) {
+ if (overlay) {
+ SDL_FreeYUVOverlay(overlay);
+ }
+ // BIKPlayer outputs PIX_FMT_YUV420P which is YV12
+ overlay = SDL_CreateYUVOverlay(w, h, SDL_YV12_OVERLAY, disp);
+ }
+ if (SDL_LockSurface( disp ) == 0) {
+ memset( disp->pixels, 0,
+ disp->w * disp->h * disp->format->BytesPerPixel );
+ SDL_UnlockSurface( disp );
+ SDL_Flip( disp );
+ w = disp->w;
+ h = disp->h;
+ } else {
+ print("Couldn't lock surface: %s\n", SDL_GetError());
+ }
+ //setting the subtitle region to the bottom 1/4th of the screen
+ subtitleregion.w = w;
+ subtitleregion.h = h/4;
+ subtitleregion.x = 0;
+ subtitleregion.y = h-h/4;
+
+ //same for SDL
+ subtitleregion_sdl.w = w;
+ subtitleregion_sdl.h = h/4;
+ subtitleregion_sdl.x = 0;
+ subtitleregion_sdl.y = h-h/4;
+}
+
+void SDL12VideoDriver::DestroyMovieScreen()
+{
+ if (overlay) SDL_FreeYUVOverlay(overlay);
+}
+
+void SDL12VideoDriver::showFrame(unsigned char* buf, unsigned int bufw,
+ unsigned int bufh, unsigned int sx, unsigned int sy, unsigned int w,
+ unsigned int h, unsigned int dstx, unsigned int dsty,
+ int g_truecolor, unsigned char *pal, ieDword titleref)
+{
+ int i;
+ SDL_Surface* sprite;
+ SDL_Rect srcRect, destRect;
+
+ assert( bufw == w && bufh == h );
+
+ if (g_truecolor) {
+ sprite = SDL_CreateRGBSurfaceFrom( buf, bufw, bufh, 16, 2 * bufw,
+ 0x7C00, 0x03E0, 0x001F, 0 );
+ } else {
+ sprite = SDL_CreateRGBSurfaceFrom( buf, bufw, bufh, 8, bufw, 0, 0, 0, 0 );
+ for (i = 0; i < 256; i++) {
+ sprite->format->palette->colors[i].r = ( *pal++ ) << 2;
+ sprite->format->palette->colors[i].g = ( *pal++ ) << 2;
+ sprite->format->palette->colors[i].b = ( *pal++ ) << 2;
+ sprite->format->palette->colors[i].unused = 0;
+ }
+ }
+
+ srcRect.x = sx;
+ srcRect.y = sy;
+ srcRect.w = w;
+ srcRect.h = h;
+ destRect.x = dstx;
+ destRect.y = dsty;
+ destRect.w = w;
+ destRect.h = h;
+
+ SDL_FillRect(disp, &subtitleregion_sdl, 0);
+ SDL_BlitSurface( sprite, &srcRect, disp, &destRect );
+ if (titleref>0)
+ DrawMovieSubtitle( titleref );
+ SDL_Flip( disp );
+ SDL_FreeSurface( sprite );
+}
+
+// sets brightness and contrast
+// FIXME:SetGammaRamp doesn't seem to work
+// WARNING: SDL 1.2.13 crashes in SetGamma on Windows (it was fixed in SDL's #3533 Revision)
+void SDL12VideoDriver::SetGamma(int brightness, int /*contrast*/)
+{
+ SDL_SetGamma(0.8+brightness/50.0,0.8+brightness/50.0,0.8+brightness/50.0);
+}
+
+bool SDL12VideoDriver::SetFullscreenMode(bool set)
+{
+ if (fullscreen != set) {
+ fullscreen=set;
+ // FIXME: SDL_WM_ToggleFullScreen only works on X11. use SDL_SetVideoMode()
+ SDL_WM_ToggleFullScreen( disp );
+ //readjust mouse to original position
+ MoveMouse(CursorPos.x, CursorPos.y);
+ //synchronise internal variable
+ core->GetDictionary()->SetAt( "Full Screen", (ieDword) fullscreen );
+ return true;
+ }
+ return false;
+}
+
+int SDL12VideoDriver::SwapBuffers(void)
+{
+ int ret = SDLVideoDriver::SwapBuffers();
+
+ SDL_BlitSurface( backBuf, NULL, disp, NULL );
+ if (fadeColor.a) {
+ SDL_SetAlpha( extra, SDL_SRCALPHA, fadeColor.a );
+ SDL_Rect src = {
+ 0, 0, (Uint16)Viewport.w, (Uint16)Viewport.h
+ };
+ SDL_Rect dst = {
+ xCorr, yCorr, 0, 0
+ };
+ SDL_BlitSurface( extra, &src, disp, &dst );
+ }
+
+ if (Cursor[CursorIndex] && !(MouseFlags & (MOUSE_DISABLED | MOUSE_HIDDEN))) {
+ SDL_Surface* temp = backBuf;
+ backBuf = disp; // FIXME: UGLY HACK!
+ if (MouseFlags&MOUSE_GRAYED) {
+ //used for greyscale blitting, fadeColor is unused
+ BlitGameSprite(Cursor[CursorIndex], CursorPos.x, CursorPos.y, BLIT_GREY, fadeColor, NULL, NULL, NULL, true);
+ } else {
+ BlitSprite(Cursor[CursorIndex], CursorPos.x, CursorPos.y, true);
+ }
+ backBuf = temp;
+ }
+ if (!(MouseFlags & MOUSE_NO_TOOLTIPS)) {
+ //handle tooltips
+ unsigned int delay = core->TooltipDelay;
+ // The multiplication by 10 is there since the last, disabling slider position is the eleventh
+ if (!core->ConsolePopped && (delay<TOOLTIP_DELAY_FACTOR*10) ) {
+ unsigned long time = GetTickCount();
+ /** Display tooltip if mouse is idle */
+ if (( time - lastMouseMoveTime ) > delay) {
+ if (EvntManager)
+ EvntManager->MouseIdle( time - lastMouseMoveTime );
+ }
+
+ /** This causes the tooltip to be rendered directly to display */
+ SDL_Surface* tmp = backBuf;
+ backBuf = disp; // FIXME: UGLY HACK!
+ core->DrawTooltip();
+ backBuf = tmp;
+ }
+ }
+ SDL_Flip( disp );
+ return ret;
+}
+
+bool SDL12VideoDriver::ToggleGrabInput()
+{
+ if (SDL_GRAB_OFF == SDL_WM_GrabInput( SDL_GRAB_QUERY )) {
+ SDL_WM_GrabInput( SDL_GRAB_ON );
+ return true;
+ }
+ else {
+ SDL_WM_GrabInput( SDL_GRAB_OFF );
+ MoveMouse(CursorPos.x, CursorPos.y);
+ return false;
+ }
+}
+
+/* no idea how elaborate this should be*/
+void SDL12VideoDriver::MoveMouse(unsigned int x, unsigned int y)
+{
+ SDL_WarpMouse(x,y);
+}
+
+void SDL12VideoDriver::showYUVFrame(unsigned char** buf, unsigned int *strides,
+ unsigned int /*bufw*/, unsigned int bufh,
+ unsigned int w, unsigned int h,
+ unsigned int dstx, unsigned int dsty,
+ ieDword titleref) {
+ assert( /* bufw == w && */ bufh == h );
+
+ SDL_Rect destRect;
+
+ SDL_LockYUVOverlay(overlay);
+ for (unsigned int plane = 0; plane < 3; plane++) {
+ unsigned char *data = buf[plane];
+ unsigned int size = overlay->pitches[plane];
+ if (strides[plane] < size) {
+ size = strides[plane];
+ }
+ unsigned int srcoffset = 0, destoffset = 0;
+ for (unsigned int i = 0; i < ((plane == 0) ? bufh : (bufh / 2)); i++) {
+ memcpy(overlay->pixels[plane] + destoffset,
+ data + srcoffset, size);
+ srcoffset += strides[plane];
+ destoffset += overlay->pitches[plane];
+ }
+ }
+ SDL_UnlockYUVOverlay(overlay);
+ destRect.x = dstx;
+ destRect.y = dsty;
+ destRect.w = w;
+ destRect.h = h;
+ SDL_FillRect(disp, &subtitleregion_sdl, 0);
+ SDL_DisplayYUVOverlay(overlay, &destRect);
+ if (titleref>0)
+ DrawMovieSubtitle( titleref );
+}
+
+int SDL12VideoDriver::ProcessEvent(const SDL_Event & event)
+{
+ switch (event.type) {
+ case SDL_ACTIVEEVENT:
+ if (core->ConsolePopped) {
+ break;
+ }
+ if (event.active.state == SDL_APPMOUSEFOCUS) {
+ if (!event.active.gain)
+ EvntManager->OnSpecialKeyPress( GEM_MOUSEOUT );
+ }
+ break;
+ default:
+ return SDLVideoDriver::ProcessEvent(event);
+ }
+ return GEM_OK;
+}
+
+void SDL12VideoDriver::ShowSoftKeyboard()
+{
+ if(core->UseSoftKeyboard){
+ Log(WARNING, "SDL 1.2 Driver", "SDL 1.2 doesn't support a software keyboard");
+ }
+}
+
+void SDL12VideoDriver::HideSoftKeyboard()
+{
+ if(core->UseSoftKeyboard){
+ Log(WARNING, "SDL 1.2 Driver", "SDL 1.2 doesn't support a software keyboard");
+ }
+}
+
+// Private methods
+
+bool SDL12VideoDriver::SetSurfacePalette(SDL_Surface* surface, SDL_Color* colors, int ncolors)
+{
+ return (bool)SDL_SetPalette( surface, SDL_LOGPAL, colors, 0, ncolors );
+}
+
+bool SDL12VideoDriver::SetSurfaceAlpha(SDL_Surface* surface, unsigned short alpha)
+{
+ return (SDL_SetAlpha( surface, SDL_SRCALPHA | SDL_RLEACCEL, alpha ) == 0);
+}
+
+#include "plugindef.h"
+
+GEMRB_PLUGIN(0xDBAAB50, "SDL Video Driver")
+PLUGIN_DRIVER(SDL12VideoDriver, "sdl")
+END_PLUGIN()
diff --git a/gemrb/plugins/SDLVideo/SDL12Video.h b/gemrb/plugins/SDLVideo/SDL12Video.h
new file mode 100644
index 0000000..49c8209
--- /dev/null
+++ b/gemrb/plugins/SDLVideo/SDL12Video.h
@@ -0,0 +1,67 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2012 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef SDL12VIDEODRIVER_H
+#define SDL12VIDEODRIVER_H
+
+#include "SDLVideo.h"
+
+namespace GemRB {
+
+class SDL12VideoDriver : public SDLVideoDriver {
+private:
+ /* yuv overlay for bink movie */
+ SDL_Overlay *overlay;
+public:
+ SDL12VideoDriver(void);
+ ~SDL12VideoDriver(void);
+
+ int Init(void);
+ int CreateDisplay(int w, int h, int b, bool fs, const char* title);
+ int SwapBuffers(void);
+
+ void InitMovieScreen(int &w, int &h, bool yuv);
+ virtual void DestroyMovieScreen();
+ void showFrame(unsigned char* buf, unsigned int bufw,
+ unsigned int bufh, unsigned int sx, unsigned int sy, unsigned int w,
+ unsigned int h, unsigned int dstx, unsigned int dsty,
+ int g_truecolor, unsigned char *pal, ieDword titleref);
+ void showYUVFrame(unsigned char** buf, unsigned int *strides,
+ unsigned int bufw, unsigned int bufh,
+ unsigned int w, unsigned int h,
+ unsigned int dstx, unsigned int dsty,
+ ieDword titleref);
+ bool SetFullscreenMode(bool set);
+ void MoveMouse(unsigned int x, unsigned int y);
+
+ bool ToggleGrabInput();
+ void ShowSoftKeyboard();
+ void HideSoftKeyboard();
+ void SetGamma(int brightness, int contrast);
+private:
+ bool SetSurfacePalette(SDL_Surface* surface, SDL_Color* colors, int ncolors);
+ bool SetSurfaceAlpha(SDL_Surface* surface, unsigned short alpha);
+
+ int ProcessEvent(const SDL_Event & event);
+};
+
+}
+
+#endif
diff --git a/gemrb/plugins/SDLVideo/SDL20Video.cpp b/gemrb/plugins/SDLVideo/SDL20Video.cpp
new file mode 100644
index 0000000..90d56ac
--- /dev/null
+++ b/gemrb/plugins/SDLVideo/SDL20Video.cpp
@@ -0,0 +1,707 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2003-2012 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "SDL20Video.h"
+
+#include "Interface.h"
+#include "GUI/Console.h"
+#include "GUI/GameControl.h" // for TargetMode (contextual information for touch inputs)
+
+using namespace GemRB;
+
+//touch gestures
+#define MIN_GESTURE_DELTA_PIXELS 5
+#define TOUCH_RC_NUM_TICKS 500
+
+SDL20VideoDriver::SDL20VideoDriver(void)
+{
+ assert( core->NumFingScroll > 1 && core->NumFingKboard > 1 && core->NumFingInfo > 1);
+ assert( core->NumFingScroll < 5 && core->NumFingKboard < 5 && core->NumFingInfo < 5);
+ assert( core->NumFingScroll != core->NumFingKboard );
+
+ renderer = NULL;
+ window = NULL;
+ screenTexture = NULL;
+
+ // touch input
+ ClearFirstTouch();
+}
+
+SDL20VideoDriver::~SDL20VideoDriver(void)
+{
+ // no need to call DestroyMovieScreen()
+ SDL_DestroyTexture(screenTexture);
+ SDL_DestroyRenderer(renderer);
+ SDL_DestroyWindow(window);
+}
+
+int SDL20VideoDriver::CreateDisplay(int w, int h, int bpp, bool fs, const char* title)
+{
+ fullscreen=fs;
+ width = w, height = h;
+
+ Log(MESSAGE, "SDL 2 Driver", "Creating display");
+ Uint32 winFlags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL;
+#if TARGET_OS_IPHONE || ANDROID
+ // this allows the user to flip the device upsidedown if they wish and have the game rotate.
+ // it also for some unknown reason is required for retina displays
+ winFlags |= SDL_WINDOW_RESIZABLE;
+ // this hint is set in the wrapper for iPad at a higher priority. set it here for iPhone
+ // don't know if Android makes use of this.
+ SDL_SetHintWithPriority(SDL_HINT_ORIENTATIONS, "LandscapeRight LandscapeLeft", SDL_HINT_DEFAULT);
+#endif
+ if (fullscreen) {
+ winFlags |= SDL_WINDOW_FULLSCREEN;
+ //This is needed to remove the status bar on Android/iOS.
+ //since we are in fullscreen this has no effect outside Android/iOS
+ winFlags |= SDL_WINDOW_BORDERLESS;
+ }
+ window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, winFlags);
+ if (window == NULL) {
+ Log(ERROR, "SDL 2 Driver", "couldnt create window:%s", SDL_GetError());
+ return GEM_ERROR;
+ }
+
+ renderer = SDL_CreateRenderer(window, -1, 0);
+
+ if (renderer == NULL) {
+ Log(ERROR, "SDL 2 Driver", "couldnt create renderer:%s", SDL_GetError());
+ return GEM_ERROR;
+ }
+
+ // we set logical size so that platforms where the window can be a diffrent size then requested
+ // function properly. eg iPhone and Android the requested size may be 640x480,
+ // but the window will always be the size of the screen
+ SDL_RenderSetLogicalSize(renderer, width, height);
+
+ Viewport.w = width;
+ Viewport.h = height;
+
+ SDL_RendererInfo info;
+ SDL_GetRendererInfo(renderer, &info);
+
+ Uint32 format = SDL_PIXELFORMAT_ABGR8888;
+ // TODO: SDL forces SDL_PIXELFORMAT_ABGR8888 on OpenGLES2
+ // if we want to use this driver with other renderers we need to do some
+ // selection such as the commented out code below
+/*
+ for (Uint32 i=0; i<info.num_texture_formats; i++) {
+ // TODO: probably could be more educated about selecting the best format.
+ switch (bpp) {
+ case 16:
+ if (SDL_PIXELTYPE(info.texture_formats[i]) == SDL_PIXELTYPE_PACKED16) {
+ format = info.texture_formats[i];
+ goto doneFormat;
+ }
+ continue;
+ case 32:
+ default:
+ if (SDL_PIXELTYPE(info.texture_formats[i]) == SDL_PIXELTYPE_PACKED32) {
+ format = info.texture_formats[i];
+ goto doneFormat;
+ }
+ continue;
+ }
+ }
+
+doneFormat:
+ if (format == SDL_PIXELFORMAT_UNKNOWN) {
+ format = SDL_GetWindowPixelFormat(window);
+ // bpp will be set by SDL_PixelFormatEnumToMasks
+ }
+*/
+ screenTexture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STREAMING, width, height);
+
+ int access;
+ SDL_QueryTexture(screenTexture,
+ &format,
+ &access,
+ &width,
+ &height);
+
+ Uint32 r, g, b, a;
+ SDL_PixelFormatEnumToMasks(format, &bpp, &r, &g, &b, &a);
+
+ Log(MESSAGE, "SDL 2 Driver", "Creating Main Surface: w=%d h=%d fmt=%s",
+ width, height, SDL_GetPixelFormatName(format));
+ backBuf = SDL_CreateRGBSurface( 0, width, height,
+ bpp, r, g, b, a );
+ this->bpp = bpp;
+
+ if (!backBuf) {
+ Log(ERROR, "SDL 2 Video", "Unable to create backbuffer of %s format: %s",
+ SDL_GetPixelFormatName(format), SDL_GetError());
+ return GEM_ERROR;
+ }
+ disp = backBuf;
+
+ return GEM_OK;
+}
+
+void SDL20VideoDriver::InitMovieScreen(int &w, int &h, bool yuv)
+{
+ SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
+ SDL_RenderClear(renderer);
+
+ if (screenTexture) SDL_DestroyTexture(screenTexture);
+ if (yuv) {
+ screenTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, w, h);
+ } else {
+ screenTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, width, height);
+ }
+ if (!screenTexture) {
+ Log(ERROR, "SDL 2 Driver", "Unable to create texture for video playback: %s", SDL_GetError());
+ }
+ w = width;
+ h = height;
+ //setting the subtitle region to the bottom 1/4th of the screen
+ subtitleregion.w = w;
+ subtitleregion.h = h/4;
+ subtitleregion.x = 0;
+ subtitleregion.y = h-h/4;
+ //same for SDL
+ subtitleregion_sdl.w = w;
+ subtitleregion_sdl.h = h/4;
+ subtitleregion_sdl.x = 0;
+ subtitleregion_sdl.y = h-h/4;
+}
+
+void SDL20VideoDriver::DestroyMovieScreen()
+{
+ if (screenTexture) SDL_DestroyTexture(screenTexture);
+ // recreate the texture for gameplay
+ Uint32 format = SDL_GetWindowPixelFormat(window);
+ screenTexture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STREAMING, width, height);
+}
+
+void SDL20VideoDriver::showFrame(unsigned char* buf, unsigned int bufw,
+ unsigned int bufh, unsigned int sx, unsigned int sy, unsigned int w,
+ unsigned int h, unsigned int dstx, unsigned int dsty,
+ int g_truecolor, unsigned char *pal, ieDword titleref)
+{
+ assert( bufw == w && bufh == h );
+
+ SDL_Rect srcRect = {sx, sy, w, h};
+ SDL_Rect destRect = {dstx, dsty, w, h};
+
+ Uint32 *dst;
+ unsigned int row, col;
+ void *pixels;
+ int pitch;
+ SDL_Color color = {0, 0, 0, 0};
+
+ if(SDL_LockTexture(screenTexture, NULL, &pixels, &pitch) != GEM_OK) {
+ Log(ERROR, "SDL 2 driver", "Unable to lock video player: %s", SDL_GetError());
+ return;
+ }
+ if (g_truecolor) {
+ Uint16 *src = (Uint16*)buf;
+ for (row = 0; row < bufh; ++row) {
+ dst = (Uint32*)((Uint8*)pixels + row * pitch);
+ for (col = 0; col < bufw; ++col) {
+ color.r = ((*src & 0x7C00) >> 7) | ((*src & 0x7C00) >> 12);
+ color.g = ((*src & 0x03E0) >> 2) | ((*src & 0x03E0) >> 8);
+ color.b = ((*src & 0x001F) << 3) | ((*src & 0x001F) >> 2);
+ // video player texture is of ARGB format. buf is RGB555
+ *dst++ = (0xFF000000|(color.r << 16)|(color.g << 8)|(color.b));
+ src++;
+ }
+ }
+ } else {
+ Uint8 *src = buf;
+ SDL_Palette* palette;
+ palette = SDL_AllocPalette(256);
+ for (int i = 0; i < 256; i++) {
+ palette->colors[i].r = ( *pal++ ) << 2;
+ palette->colors[i].g = ( *pal++ ) << 2;
+ palette->colors[i].b = ( *pal++ ) << 2;
+ }
+ for (row = 0; row < bufh; ++row) {
+ dst = (Uint32*)((Uint8*)pixels + row * pitch);
+ for (col = 0; col < bufw; ++col) {
+ color = palette->colors[*src++];
+ // video player texture is of ARGB format
+ *dst++ = (0xFF000000|(color.r << 16)|(color.g << 8)|(color.b));
+ }
+ }
+ SDL_FreePalette(palette);
+ }
+ SDL_UnlockTexture(screenTexture);
+
+ SDL_RenderFillRect(renderer, &subtitleregion_sdl);
+ SDL_RenderCopy(renderer, screenTexture, &srcRect, &destRect);
+
+ if (titleref>0)
+ DrawMovieSubtitle( titleref );
+
+ SDL_RenderPresent(renderer);
+}
+
+void SDL20VideoDriver::showYUVFrame(unsigned char** buf, unsigned int *strides,
+ unsigned int /*bufw*/, unsigned int bufh,
+ unsigned int w, unsigned int h,
+ unsigned int dstx, unsigned int dsty,
+ ieDword /*titleref*/)
+{
+ SDL_Rect destRect;
+ destRect.x = dstx;
+ destRect.y = dsty;
+ destRect.w = w;
+ destRect.h = h;
+
+ Uint8 *pixels;
+ int pitch;
+
+ if(SDL_LockTexture(screenTexture, NULL, (void**)&pixels, &pitch) != GEM_OK) {
+ Log(ERROR, "SDL 2 driver", "Unable to lock video player: %s", SDL_GetError());
+ return;
+ }
+ pitch = w;
+ if((unsigned int)pitch == strides[0]) {
+ int size = pitch * bufh;
+ memcpy(pixels, buf[0], size);
+ memcpy(pixels + size, buf[2], size / 4);
+ memcpy(pixels + size * 5 / 4, buf[1], size / 4);
+ } else {
+ unsigned char *Y,*U,*V,*iY,*iU,*iV;
+ unsigned int i;
+ Y = pixels;
+ V = pixels + pitch * h;
+ U = pixels + pitch * h * 5 / 4;
+
+ iY = buf[0];
+ iU = buf[1];
+ iV = buf[2];
+
+ for (i = 0; i < (h/2); i++) {
+ memcpy(Y,iY,pitch);
+ iY += strides[0];
+ Y += pitch;
+
+ memcpy(Y,iY,pitch);
+ memcpy(U,iU,pitch / 2);
+ memcpy(V,iV,pitch / 2);
+
+ Y += pitch;
+ U += pitch / 2;
+ V += pitch / 2;
+ iY += strides[0];
+ iU += strides[1];
+ iV += strides[2];
+ }
+ }
+
+ SDL_UnlockTexture(screenTexture);
+ SDL_RenderCopy(renderer, screenTexture, NULL, &destRect);
+ SDL_RenderPresent(renderer);
+}
+
+int SDL20VideoDriver::SwapBuffers(void)
+{
+ int ret = SDLVideoDriver::SwapBuffers();
+
+ void *pixels;
+ int pitch;
+
+ if(SDL_LockTexture(screenTexture, NULL, &pixels, &pitch) != GEM_OK) {
+ Log(ERROR, "SDL 2 driver", "Unable to lock screen texture: %s", SDL_GetError());
+ return GEM_ERROR;
+ }
+
+ assert(pitch == backBuf->pitch);
+ memcpy(pixels, backBuf->pixels, pitch * height);
+/*
+ if (fadeColor.a) {
+ SDL_Rect dst = {
+ xCorr, yCorr, Viewport.w, Viewport.h
+ };
+ SDL_SetRenderDrawColor(renderer, fadeColor.r, fadeColor.g, fadeColor.b, fadeColor.a);
+ SDL_RenderFillRect(renderer, &dst);
+ }
+*/
+ SDL_UnlockTexture(screenTexture);
+ SDL_RenderCopy(renderer, screenTexture, NULL, NULL);
+ SDL_RenderPresent( renderer );
+ return ret;
+}
+
+int SDL20VideoDriver::PollEvents()
+{
+ if (firstFingerDownTime
+ && GetTickCount() - firstFingerDownTime >= TOUCH_RC_NUM_TICKS) {
+ // enough time has passed to transform firstTouch into a right click event
+ int x = firstFingerDown.x;
+ int y = firstFingerDown.y;
+ ProcessFirstTouch(GEM_MB_MENU);
+ EvntManager->MouseUp( x, y, GEM_MB_MENU, GetModState(SDL_GetModState()));
+ ignoreNextFingerUp = true;
+ }
+
+ return SDLVideoDriver::PollEvents();
+}
+
+void SDL20VideoDriver::ClearFirstTouch()
+{
+ firstFingerDown = SDL_TouchFingerEvent();
+ firstFingerDown.fingerId = -1;
+ ignoreNextFingerUp = false;
+ firstFingerDownTime = 0;
+}
+
+bool SDL20VideoDriver::ProcessFirstTouch( int mouseButton )
+{
+ if (!(MouseFlags & MOUSE_DISABLED) && firstFingerDown.fingerId >= 0) {
+ lastMouseDownTime = EvntManager->GetRKDelay();
+ if (lastMouseDownTime != (unsigned long) ~0) {
+ lastMouseDownTime += lastMouseDownTime + lastTime;
+ }
+
+ // do an actual mouse move first! this is important for things such as ground piles to work!
+ // also ensure any referencing of the cursor is accurate
+ MouseMovement(firstFingerDown.x, firstFingerDown.y);
+
+ if (CursorIndex != VID_CUR_DRAG)
+ CursorIndex = VID_CUR_DOWN;
+
+ // no need to scale these coordinates. they were scaled previously for us.
+ EvntManager->MouseDown( firstFingerDown.x, firstFingerDown.y,
+ mouseButton, GetModState(SDL_GetModState()) );
+
+ ClearFirstTouch();
+ return true;
+ }
+ return false;
+}
+
+int SDL20VideoDriver::ProcessEvent(const SDL_Event & event)
+{
+ Control* focusCtrl = NULL; //used for contextual touch events.
+ static int numFingers = 0;
+ static bool continuingGesture = false; // resets when numFingers changes
+
+ // beware that this may be removed before all events it created are processed!
+ SDL_Finger* finger0 = SDL_GetTouchFinger(event.tfinger.touchId, 0);
+
+ if (finger0) {
+ numFingers = SDL_GetNumTouchFingers(event.tfinger.touchId);
+ focusCtrl = EvntManager->GetMouseFocusedControl();
+ }
+
+ bool ConsolePopped = core->ConsolePopped;
+
+ switch (event.type) {
+ // For swipes only. gestures requireing pinch or rotate need to use SDL_MULTIGESTURE or SDL_DOLLARGESTURE
+ case SDL_FINGERMOTION:
+ ignoreNextFingerUp = true;
+
+ if (numFingers == core->NumFingScroll
+ || (numFingers != core->NumFingKboard && (focusCtrl && focusCtrl->ControlType == IE_GUI_TEXTAREA))) {
+ //any # of fingers != NumFingKBoard will scroll a text area
+ if (focusCtrl && focusCtrl->ControlType == IE_GUI_TEXTAREA) {
+ // if we are scrolling a text area we dont want the keyboard in the way
+ HideSoftKeyboard();
+ } else if (!focusCtrl) {
+ // ensure the control we touched becomes focused before attempting to scroll it.
+ // we cannot safely call ProcessFirstTouch anymore because now we process mouse events
+ // this can result in a selection box being created
+
+ EvntManager->MouseDown(ScaleCoordinateHorizontal(event.tfinger.x),
+ ScaleCoordinateVertical(event.tfinger.y),
+ GEM_MB_ACTION, 0);
+ }
+ // invert the coordinates such that dragging down scrolls up etc.
+ int scrollX = (event.tfinger.dx * width) * -1;
+ int scrollY = (event.tfinger.dy * height) * -1;
+
+ EvntManager->MouseWheelScroll( scrollX, scrollY );
+ } else if (numFingers == core->NumFingKboard && !continuingGesture) {
+ int delta = (int)(event.tfinger.dy * height) * -1;
+ if (delta >= MIN_GESTURE_DELTA_PIXELS){
+ // if the keyboard is already up interpret this gesture as console pop
+ if( SDL_IsScreenKeyboardShown(window) && !ConsolePopped ) core->PopupConsole();
+ else ShowSoftKeyboard();
+ } else if (delta <= -MIN_GESTURE_DELTA_PIXELS) {
+ HideSoftKeyboard();
+ }
+ } else if (numFingers == 1) { //click and drag
+ ProcessFirstTouch(GEM_MB_ACTION);
+ ignoreNextFingerUp = false;
+ // standard mouse movement
+ MouseMovement(ScaleCoordinateHorizontal(event.tfinger.x),
+ ScaleCoordinateVertical(event.tfinger.y));
+ }
+ // we set this on finger motion because simple up/down are not part of gestures
+ continuingGesture = true;
+ break;
+ case SDL_FINGERDOWN:
+ if (!finger0) numFingers++;
+ continuingGesture = false;
+ if (numFingers == 1
+ // this test is for when multiple fingers begin the first touch
+ // commented out because we dont care right now, but if we need it i want it documented
+ //|| (numFingers > 1 && firstFingerDown.fingerId < 0)
+ ) {
+ // do not send a mouseDown event. we delay firstTouch until we know more about the context.
+ firstFingerDown = event.tfinger;
+ firstFingerDownTime = GetTickCount();
+ // ensure we get the coords for the actual first finger
+ if (finger0) {
+ firstFingerDown.x = ScaleCoordinateHorizontal(finger0->x);
+ firstFingerDown.y = ScaleCoordinateVertical(finger0->y);
+ } else {
+ // rare case where the touch has
+ // been removed before processing
+ firstFingerDown.x = ScaleCoordinateHorizontal(event.tfinger.x);
+ firstFingerDown.y = ScaleCoordinateVertical(event.tfinger.y);
+ }
+ } else {
+ if (EvntManager && numFingers == core->NumFingInfo) {
+ ProcessFirstTouch(GEM_MB_ACTION);
+ EvntManager->OnSpecialKeyPress( GEM_TAB );
+ EvntManager->OnSpecialKeyPress( GEM_ALT );
+ }
+ if ((numFingers == core->NumFingScroll || numFingers == core->NumFingKboard)
+ && focusCtrl && focusCtrl->ControlType == IE_GUI_GAMECONTROL) {
+ // scrolling cancels previous action
+ ((GameControl*)focusCtrl)->ClearMouseState();
+ }
+ }
+ break;
+ case SDL_FINGERUP:
+ {
+ if (numFingers) numFingers--;
+ continuingGesture = false;
+ // we need to get mouseButton before calling ProcessFirstTouch
+ int mouseButton = (firstFingerDown.fingerId >= 0) ? GEM_MB_ACTION : GEM_MB_MENU;
+ ProcessFirstTouch(mouseButton);
+ if (numFingers == 0) { // this event was the last finger that was in contact
+ if (!ignoreNextFingerUp) {
+ if (CursorIndex != VID_CUR_DRAG)
+ CursorIndex = VID_CUR_UP;
+ // move cursor to ensure any referencing of the cursor is accurate
+ CursorPos.x = event.button.x;
+ CursorPos.y = event.button.y;
+
+ EvntManager->MouseUp(ScaleCoordinateHorizontal(event.tfinger.x),
+ ScaleCoordinateVertical(event.tfinger.y),
+ mouseButton, GetModState(SDL_GetModState()) );
+ }
+ }
+ if (numFingers != core->NumFingInfo) {
+ // FIXME: this is "releasing" the ALT key even when it hadn't been previously "pushed"
+ // this isn't causing a problem currently
+ EvntManager->KeyRelease( GEM_ALT, 0 );
+ }
+ }
+ break;
+ case SDL_MULTIGESTURE:// use this for pinch or rotate gestures. see also SDL_DOLLARGESTURE
+ // purposely ignore processing first touch here. I think users ould find it annoying
+ // to attempt a gesture and accidently command a party movement etc
+ if (firstFingerDown.fingerId >= 0 && numFingers == 2
+ && focusCtrl && focusCtrl->ControlType == IE_GUI_GAMECONTROL) {
+ /* formation rotation gesture:
+ first touch with a single finger to obtain the pivot
+ then touch and drag with a second finger (while maintaining contact with first)
+ to move the application point
+ */
+ GameControl* gc = core->GetGameControl();
+ if (gc && gc->GetTargetMode() == TARGET_MODE_NONE) {
+ ProcessFirstTouch(GEM_MB_MENU);
+ SDL_Finger* secondFinger = SDL_GetTouchFinger(event.tfinger.touchId, 1);
+ gc->OnMouseOver(secondFinger->x + Viewport.x, secondFinger->y + Viewport.y);
+ }
+ } else {
+ ProcessFirstTouch(GEM_MB_ACTION);
+ }
+ break;
+ case SDL_MOUSEWHEEL:
+ /*
+ TODO: need a preference for inverting these
+ */
+ short scrollX;
+ scrollX= event.wheel.x * -1;
+ short scrollY;
+ scrollY= event.wheel.y * -1;
+ EvntManager->MouseWheelScroll( scrollX, scrollY );
+ break;
+ /* not user input events */
+ case SDL_TEXTINPUT:
+ for (size_t i=0; i < strlen(event.text.text); i++) {
+ if (core->ConsolePopped)
+ core->console->OnKeyPress( event.text.text[i], GetModState(event.key.keysym.mod));
+ else
+ EvntManager->KeyPress( event.text.text[i], GetModState(event.key.keysym.mod));
+ }
+ break;
+ /* not user input events */
+ case SDL_WINDOWEVENT://SDL 1.2
+ switch (event.window.event) {
+ case SDL_WINDOWEVENT_MINIMIZED://SDL 1.3
+ // We pause the game and audio when the window is minimized.
+ // on iOS/Android this happens when leaving the application or when play is interrupted (ex phone call)
+ // if win/mac/linux has a problem with this behavior we can work something out.
+ core->GetAudioDrv()->Pause();//this is for ANDROID mostly
+ core->SetPause(PAUSE_ON);
+ break;
+ case SDL_WINDOWEVENT_RESTORED: //SDL 1.3
+ /*
+ reset all input variables as if no events have happened yet
+ restoring from "minimized state" should be a clean slate.
+ */
+ ClearFirstTouch();
+ GameControl* gc = core->GetGameControl();
+ if (gc) {
+ gc->ClearMouseState();
+ }
+ // should we reset the lastMouseTime vars?
+#if TARGET_OS_IPHONE
+ // FIXME:
+ // sleep for a short while to avoid some unknown Apple threading issue with OpenAL threads being suspended
+ // even using Apple examples of how to properly suspend an OpenAL context and resume on iOS are falling flat
+ // it could be this bug affects only the simulator.
+ sleep(1);
+#endif
+ core->GetAudioDrv()->Resume();//this is for ANDROID mostly
+ break;
+ /*
+ case SDL_WINDOWEVENT_RESIZED: //SDL 1.2
+ // this event exists in SDL 1.2, but this handler is only getting compiled under 1.3+
+ Log(WARNING, "SDL 2 Driver", "Window resized so your window surface is now invalid.");
+ break;
+ */
+ }
+ break;
+ // conditionally handle mouse events
+ // discard them if they are produced by touch events
+ // do NOT discard mouse wheel events
+ case SDL_MOUSEMOTION:
+ if (event.motion.which == SDL_TOUCH_MOUSEID) {
+ break;
+ }
+ case SDL_MOUSEBUTTONDOWN:
+ case SDL_MOUSEBUTTONUP:
+ if (event.button.which == SDL_TOUCH_MOUSEID) {
+ break;
+ }
+ default:
+ return SDLVideoDriver::ProcessEvent(event);
+ }
+ return GEM_OK;
+}
+
+/*
+ This method is intended for devices with no physical keyboard or with an optional soft keyboard (iOS/Android)
+ */
+void SDL20VideoDriver::HideSoftKeyboard()
+{
+ if(core->UseSoftKeyboard){
+ SDL_StopTextInput();
+ if(core->ConsolePopped) core->PopupConsole();
+ }
+}
+
+/*
+ This method is intended for devices with no physical keyboard or with an optional soft keyboard (iOS/Android)
+ */
+void SDL20VideoDriver::ShowSoftKeyboard()
+{
+ if(core->UseSoftKeyboard){
+ SDL_StartTextInput();
+ }
+}
+
+/* no idea how elaborate this should be*/
+void SDL20VideoDriver::MoveMouse(unsigned int x, unsigned int y)
+{
+ SDL_WarpMouseInWindow(window, x, y);
+}
+
+void SDL20VideoDriver::SetGamma(int brightness, int /*contrast*/)
+{
+ SDL_SetWindowBrightness(window, (float)(brightness/40.0));
+}
+
+bool SDL20VideoDriver::SetFullscreenMode(bool set)
+{
+ if (SDL_SetWindowFullscreen(window, (SDL_bool)set) == GEM_OK) {
+ fullscreen = set;
+ return true;
+ }
+ return false;
+}
+
+bool SDL20VideoDriver::ToggleGrabInput()
+{
+ bool isGrabbed = SDL_GetWindowGrab(window);
+ SDL_SetWindowGrab(window, (SDL_bool)!isGrabbed);
+ return (isGrabbed != SDL_GetWindowGrab(window));
+}
+
+// Private methods
+
+bool SDL20VideoDriver::SetSurfacePalette(SDL_Surface* surface, SDL_Color* colors, int ncolors)
+{
+ return (SDL_SetPaletteColors((surface)->format->palette, colors, 0, ncolors) == 0);
+}
+
+bool SDL20VideoDriver::SetSurfaceAlpha(SDL_Surface* surface, unsigned short alpha)
+{
+ return (SDL_SetSurfaceAlphaMod(surface, alpha) == 0);
+}
+
+float SDL20VideoDriver::ScaleCoordinateHorizontal(float x)
+{
+ float scaleX;
+ SDL_RenderGetScale(renderer, &scaleX, NULL);
+
+ int winW, winH;
+ float xoffset = 0.0;
+ SDL_GetWindowSize(window, &winW, &winH);
+ float winWf = winW, winHf = winH;
+ // only need to scale if they do not have the same ratio
+ if ((winWf / winHf) != ((float)width / height)) {
+ xoffset = ((winWf - (width * scaleX)) / 2) / winWf;
+ return ((x - xoffset) * (winWf / scaleX));
+ }
+ return x * width;
+}
+
+float SDL20VideoDriver::ScaleCoordinateVertical(float y)
+{
+ float scaleY;
+ SDL_RenderGetScale(renderer, NULL, &scaleY);
+
+ int winW, winH;
+ float yoffset = 0.0;
+ SDL_GetWindowSize(window, &winW, &winH);
+ float winWf = winW, winHf = winH;
+ // only need to scale if they do not have the same ratio
+ if ((winWf / winHf) != ((float)width / height)) {
+ yoffset = ((winHf - (height * scaleY)) / 2) / winHf;
+ return ((y - yoffset) * (winHf / scaleY));
+ }
+ return y * height;
+}
+
+#include "plugindef.h"
+
+GEMRB_PLUGIN(0xDBAAB50, "SDL Video Driver")
+PLUGIN_DRIVER(SDL20VideoDriver, "sdl")
+END_PLUGIN()
diff --git a/gemrb/plugins/SDLVideo/SDL20Video.h b/gemrb/plugins/SDLVideo/SDL20Video.h
new file mode 100644
index 0000000..0cf41bc
--- /dev/null
+++ b/gemrb/plugins/SDLVideo/SDL20Video.h
@@ -0,0 +1,87 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2012 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef SDL20VideoDRIVER_H
+#define SDL20VideoDRIVER_H
+
+#include "SDLVideo.h"
+
+namespace GemRB {
+
+class SDL20VideoDriver : public SDLVideoDriver {
+private:
+ SDL_Texture* screenTexture;
+ SDL_Window* window;
+ SDL_Renderer* renderer;
+
+ // touch input vars
+ bool ignoreNextFingerUp;
+ SDL_TouchFingerEvent firstFingerDown;
+ unsigned long firstFingerDownTime;
+public:
+ SDL20VideoDriver(void);
+ ~SDL20VideoDriver(void);
+
+ int CreateDisplay(int w, int h, int b, bool fs, const char* title);
+ int SwapBuffers(void);
+ int PollEvents();
+
+ void InitMovieScreen(int &w, int &h, bool yuv);
+ virtual void DestroyMovieScreen();
+
+ void showFrame(unsigned char* buf, unsigned int bufw,
+ unsigned int bufh, unsigned int sx, unsigned int sy, unsigned int w,
+ unsigned int h, unsigned int dstx, unsigned int dsty,
+ int g_truecolor, unsigned char *pal, ieDword titleref);
+ void showYUVFrame(unsigned char** buf, unsigned int *strides,
+ unsigned int bufw, unsigned int bufh,
+ unsigned int w, unsigned int h,
+ unsigned int dstx, unsigned int dsty,
+ ieDword titleref);
+
+ bool SetFullscreenMode(bool set);
+ void SetGamma(int brightness, int contrast);
+ bool ToggleGrabInput();
+ void ShowSoftKeyboard();
+ void HideSoftKeyboard();
+ void MoveMouse(unsigned int x, unsigned int y);
+private:
+ bool SetSurfacePalette(SDL_Surface* surface, SDL_Color* colors, int ncolors);
+ bool SetSurfaceAlpha(SDL_Surface* surface, unsigned short alpha);
+
+ int ProcessEvent(const SDL_Event & event);
+ // the first finger touch of a gesture is delayed until another touch event or until
+ // enough time passes for it to become a right click
+ bool ProcessFirstTouch( int mouseButton );
+ void ClearFirstTouch();
+
+ // temporary methods to scale input coordinates from the renderer to the backbuf
+ // once we have a real SDL2 render pipeline in place we shouldnt require this.
+ // this should only apply to devices where the window size cannot be guaranteed
+ // to match the render size (iOS, Android)
+
+ // TODO: probably need to apply this to mouse input
+ float ScaleCoordinateHorizontal(float x);
+ float ScaleCoordinateVertical(float y);
+};
+
+}
+
+#endif
diff --git a/gemrb/plugins/SDLVideo/SDLVideo.cpp b/gemrb/plugins/SDLVideo/SDLVideo.cpp
index be87bcf..7fd5df8 100644
--- a/gemrb/plugins/SDLVideo/SDLVideo.cpp
+++ b/gemrb/plugins/SDLVideo/SDLVideo.cpp
@@ -20,39 +20,49 @@
#include "SDLVideo.h"
+#include "Sprite2D.h"
+
#include "TileRenderer.inl"
+#include "SpriteRenderer.inl"
#include "AnimationFactory.h"
-#include "Audio.h"
#include "Game.h" // for GetGlobalTint
#include "GameData.h"
#include "Interface.h"
#include "Palette.h"
+#include "Polygon.h"
#include "SpriteCover.h"
+
+#include "GUI/Button.h"
#include "GUI/Console.h"
+#include "GUI/Window.h"
#include <cmath>
#include <cassert>
#include <cstdio>
+using namespace GemRB;
+
+#if SDL_VERSION_ATLEAST(1,3,0)
+#define SDL_SRCCOLORKEY SDL_TRUE
+#define SDL_SRCALPHA 0
+#define SDLK_SCROLLOCK SDLK_SCROLLLOCK
+#define SDLK_KP2 SDLK_KP_2
+#define SDLK_KP4 SDLK_KP_4
+#define SDLK_KP6 SDLK_KP_6
+#define SDLK_KP8 SDLK_KP_8
+#endif
+
SDLVideoDriver::SDLVideoDriver(void)
{
- CursorIndex = 0;
- Cursor[0] = NULL;
- Cursor[1] = NULL;
- Cursor[2] = NULL;
- CursorPos.x = 0;
- CursorPos.y = 0;
- DisableMouse = 0;
xCorr = 0;
yCorr = 0;
lastTime = 0;
- GetTime( lastMouseTime );
backBuf=NULL;
extra=NULL;
+ lastMouseDownTime = lastMouseMoveTime = GetTickCount();
subtitlestrref = 0;
subtitletext = NULL;
- overlay = NULL;
}
SDLVideoDriver::~SDLVideoDriver(void)
@@ -61,120 +71,34 @@ SDLVideoDriver::~SDLVideoDriver(void)
if(backBuf) SDL_FreeSurface( backBuf );
if(extra) SDL_FreeSurface( extra );
- if (overlay) SDL_FreeYUVOverlay(overlay);
SDL_Quit();
// This sprite needs to have been freed earlier, because
// all AnimationFactories and Sprites have already been
// destructed before the video driver is freed.
- assert(Cursor[2] == NULL);
+ assert(Cursor[VID_CUR_DRAG] == NULL);
}
int SDLVideoDriver::Init(void)
{
- //printf("[SDLVideoDriver]: Init...");
+ //print("[SDLVideoDriver]: Init...");
if (SDL_InitSubSystem( SDL_INIT_VIDEO ) == -1) {
- //printf("[ERROR]\n");
+ //print("[ERROR]");
return GEM_ERROR;
}
- //printf("[OK]\n");
- SDL_EnableUNICODE( 1 );
- SDL_EnableKeyRepeat( 500, 50 );
+ //print("[OK]\n");
SDL_ShowCursor( SDL_DISABLE );
- fadeColor.a=0; //fadePercent
- fadeColor.r=0;
- fadeColor.b=0;
- fadeColor.g=0;
return GEM_OK;
}
-int SDLVideoDriver::CreateDisplay(int w, int h, int b, bool fs)
-{
- bpp=b;
- fullscreen=fs;
- printMessage( "SDLVideo", "Creating display\n", WHITE );
- ieDword flags = SDL_SWSURFACE;
- if (fullscreen) {
- flags |= SDL_FULLSCREEN;
- }
- printMessage( "SDLVideo", "SDL_SetVideoMode...", WHITE );
- disp = SDL_SetVideoMode( w, h, bpp, flags );
- if (disp == NULL) {
- printStatus( "ERROR", LIGHT_RED );
- return GEM_ERROR;
- }
- printStatus( "OK", LIGHT_GREEN );
- printMessage( "SDLVideo", "Checking for HardWare Acceleration...", WHITE );
- const SDL_VideoInfo* vi = SDL_GetVideoInfo();
- if (!vi) {
- printStatus( "ERROR", LIGHT_RED );
- }
- printStatus( "OK", LIGHT_GREEN );
- Viewport.x = Viewport.y = 0;
- width = disp->w;
- height = disp->h;
- Viewport.w = width;
- Viewport.h = height;
- printMessage( "SDLVideo", "Creating Main Surface...", WHITE );
- SDL_Surface* tmp = SDL_CreateRGBSurface( SDL_SWSURFACE, width, height,
- bpp, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff );
- printStatus( "OK", LIGHT_GREEN );
- printMessage( "SDLVideo", "Creating Back Buffer...", WHITE );
- backBuf = SDL_DisplayFormat( tmp );
- printStatus( "OK", LIGHT_GREEN );
- printMessage( "SDLVideo", "Creating Extra Buffer...", WHITE );
- extra = SDL_DisplayFormat( tmp );
- printStatus( "OK", LIGHT_GREEN );
- SDL_LockSurface( extra );
- long val = SDL_MapRGBA( extra->format, fadeColor.r, fadeColor.g, fadeColor.b, 0 );
- SDL_FillRect( extra, NULL, val );
- SDL_UnlockSurface( extra );
- SDL_FreeSurface( tmp );
- printMessage( "SDLVideo", "CreateDisplay...", WHITE );
- printStatus( "OK", LIGHT_GREEN );
- return GEM_OK;
-}
-
-void SDLVideoDriver::SetDisplayTitle(char* title, char* icon)
-{
- SDL_WM_SetCaption( title, icon );
-}
-
-bool SDLVideoDriver::ToggleFullscreenMode(int set_reset)
-{
- if (set_reset==-1) {
- set_reset=!fullscreen;
- }
- if (fullscreen != set_reset) {
- fullscreen=set_reset;
- SDL_WM_ToggleFullScreen( disp );
- //readjust mouse to original position
- MoveMouse(CursorPos.x, CursorPos.y);
- //synchronise internal variable
- core->GetDictionary()->SetAt( "Full Screen", (ieDword) fullscreen );
- return true;
- }
- return false;
-}
-
-inline int GetModState(int modstate)
-{
- int value = 0;
- if (modstate&KMOD_SHIFT) value |= GEM_MOD_SHIFT;
- if (modstate&KMOD_CTRL) value |= GEM_MOD_CTRL;
- if (modstate&KMOD_ALT) value |= GEM_MOD_ALT;
- return value;
-}
-
int SDLVideoDriver::SwapBuffers(void)
{
- int ret = GEM_OK;
unsigned long time;
- GetTime( time );
- if (( time - lastTime ) < 17) {
- SDL_Delay( 17 - (time - lastTime) );
- GetTime( time );
+ time = GetTickCount();
+ if (( time - lastTime ) < 33) {
+ SDL_Delay( 33 - (time - lastTime) );
+ time = GetTickCount();
}
lastTime = time;
@@ -184,77 +108,54 @@ int SDLVideoDriver::SwapBuffers(void)
core->DrawConsole();
}
- ret = PollEvents();
+ return PollEvents();
+}
- SDL_BlitSurface( backBuf, NULL, disp, NULL );
- if (fadeColor.a) {
- SDL_SetAlpha( extra, SDL_SRCALPHA, fadeColor.a );
- SDL_Rect src = {
- 0, 0, Viewport.w, Viewport.h
- };
- SDL_Rect dst = {
- xCorr, yCorr, 0, 0
- };
- SDL_BlitSurface( extra, &src, disp, &dst );
- }
+int SDLVideoDriver::PollEvents()
+{
+ int ret = GEM_OK;
+ SDL_Event currentEvent;
- if (Cursor[CursorIndex] && !(DisableMouse&MOUSE_DISABLED)) {
- SDL_Surface* temp = backBuf;
- backBuf = disp; // FIXME: UGLY HACK!
- if (DisableMouse&MOUSE_GRAYED) {
- //used for greyscale blitting, fadeColor is unused
- BlitGameSprite(Cursor[CursorIndex], CursorPos.x, CursorPos.y, BLIT_GREY, fadeColor, NULL, NULL, NULL, true);
- } else {
- BlitSprite(Cursor[CursorIndex], CursorPos.x, CursorPos.y, true);
- }
- backBuf = temp;
+ while (ret != GEM_ERROR && SDL_PollEvent(¤tEvent)) {
+ ret = ProcessEvent(currentEvent);
}
- //handle tooltips
- unsigned int delay = core->TooltipDelay;
- // The multiplication by 10 is there since the last, disabling slider position is the eleventh
- if (!ConsolePopped && (delay<TOOLTIP_DELAY_FACTOR*10) ) {
- GetTime( time );
- /** Display tooltip if mouse is idle */
- if (( time - lastMouseTime ) > delay) {
- if (Evnt)
- Evnt->MouseIdle( time - lastMouseTime );
+ if (ret == GEM_OK && !(MouseFlags & (MOUSE_DISABLED | MOUSE_GRAYED))
+ && lastTime>lastMouseDownTime
+ && SDL_GetMouseState(NULL, NULL)==SDL_BUTTON(SDL_BUTTON_LEFT))
+ {
+ // get our internal mouse coordinates instead of system coordinates
+ // this is important for SDL2 (Android, iOS currently)
+ int x, y;
+ GetMousePos(x, y);
+ lastMouseDownTime=lastTime + EvntManager->GetRKDelay();
+ if (!core->ConsolePopped) {
+ EvntManager->MouseUp( x, y, GEM_MB_ACTION, GetModState(SDL_GetModState()) );
+ Control* ctl = EvntManager->GetMouseFocusedControl();
+ if (ctl && ctl->ControlType == IE_GUI_BUTTON)
+ // these are repeat events so the control should stay pressed
+ ((Button*)ctl)->SetState(IE_GUI_BUTTON_PRESSED);
}
-
- /** This causes the tooltip to be rendered directly to display */
- SDL_Surface* tmp = backBuf;
- backBuf = disp; // FIXME: UGLY HACK!
- core->DrawTooltip();
- backBuf = tmp;
- }
-
- SDL_Flip( disp );
-
+ }
return ret;
}
-int SDLVideoDriver::PollEvents() {
- static bool lastevent = false; /* last event was a mousedown */
- static unsigned long lastmousetime = 0;
-
- int ret = GEM_OK;
+int SDLVideoDriver::ProcessEvent(const SDL_Event & event)
+{
+ if (!EvntManager)
+ return GEM_ERROR;
- bool ConsolePopped = core->ConsolePopped;
- unsigned long time = lastTime;
unsigned char key = 0;
- int x,y;
+ int modstate = GetModState(event.key.keysym.mod);
- while ( SDL_PollEvent(&event) ) {
- int modstate = GetModState(event.key.keysym.mod);
-
- /* Loop until there are no events left on the queue */
- switch (event.type) {
- /* Process the appropriate event type */
+ /* Loop until there are no events left on the queue */
+ switch (event.type) {
+ /* Process the appropriate event type */
case SDL_QUIT:
- /* Handle a QUIT event */
- ret = GEM_ERROR;
+ /* Quit event originated from outside GemRB so ask the user if we should exit */
+ core->AskAndExit();
+ return GEM_OK;
break;
-
case SDL_KEYUP:
switch(event.key.keysym.sym) {
case SDLK_LALT:
@@ -265,20 +166,23 @@ int SDLVideoDriver::PollEvents() {
key = GEM_GRAB;
break;
case SDLK_f:
+ // FIXME: this is a poor place to handle this
+ // cant do it in GameControl because it only exists while in a game
+ // could move to event manager, but that seems on par with doing it here
if (modstate & GEM_MOD_CTRL) {
- ToggleFullscreenMode(-1);
+ ToggleFullscreenMode();
+ break;
}
- break;
+ // fallthrough
default:
if (event.key.keysym.sym<256) {
key=(unsigned char) event.key.keysym.sym;
}
break;
}
- if (!ConsolePopped && Evnt && ( key != 0 ))
- Evnt->KeyRelease( key, modstate );
+ if (!core->ConsolePopped && ( key != 0 ))
+ EvntManager->KeyRelease( key, modstate );
break;
-
case SDL_KEYDOWN:
if ((event.key.keysym.sym == SDLK_SPACE) && modstate & GEM_MOD_CTRL) {
core->PopupConsole();
@@ -287,134 +191,118 @@ int SDLVideoDriver::PollEvents() {
key = (unsigned char) event.key.keysym.unicode;
if (key < 32 || key == 127) {
switch (event.key.keysym.sym) {
- case SDLK_ESCAPE:
- key = GEM_ESCAPE;
- break;
- case SDLK_END:
- key = GEM_END;
- break;
- case SDLK_HOME:
- key = GEM_HOME;
- break;
- case SDLK_UP:
- key = GEM_UP;
- break;
- case SDLK_DOWN:
- key = GEM_DOWN;
- break;
- case SDLK_LEFT:
- key = GEM_LEFT;
- break;
- case SDLK_RIGHT:
- key = GEM_RIGHT;
- break;
- case SDLK_BACKSPACE:
- key = GEM_BACKSP;
- break;
- case SDLK_DELETE:
- key = GEM_DELETE;
- break;
- case SDLK_RETURN:
- case SDLK_KP_ENTER:
- key = GEM_RETURN;
- break;
- case SDLK_LALT:
- case SDLK_RALT:
- key = GEM_ALT;
- break;
- case SDLK_TAB:
- key = GEM_TAB;
- break;
- case SDLK_PAGEUP:
- key = GEM_PGUP;
- break;
- case SDLK_PAGEDOWN:
- key = GEM_PGDOWN;
- break;
- case SDLK_SCROLLOCK:
- key = GEM_GRAB;
- break;
- default:
- break;
+ case SDLK_ESCAPE:
+ key = GEM_ESCAPE;
+ break;
+ case SDLK_END:
+ key = GEM_END;
+ break;
+ case SDLK_HOME:
+ key = GEM_HOME;
+ break;
+ case SDLK_UP:
+ case SDLK_KP8:
+ key = GEM_UP;
+ break;
+ case SDLK_DOWN:
+ case SDLK_KP2:
+ key = GEM_DOWN;
+ break;
+ case SDLK_LEFT:
+ case SDLK_KP4:
+ key = GEM_LEFT;
+ break;
+ case SDLK_RIGHT:
+ case SDLK_KP6:
+ key = GEM_RIGHT;
+ break;
+ case SDLK_DELETE:
+#if TARGET_OS_IPHONE < 1
+ //iOS currently doesnt have a backspace so we use delete.
+ //This change should be future proof in the event apple changes the delete key to a backspace.
+ key = GEM_DELETE;
+ break;
+#endif
+ case SDLK_BACKSPACE:
+ key = GEM_BACKSP;
+ break;
+ case SDLK_RETURN:
+ case SDLK_KP_ENTER:
+ key = GEM_RETURN;
+ break;
+ case SDLK_LALT:
+ case SDLK_RALT:
+ key = GEM_ALT;
+ break;
+ case SDLK_TAB:
+ key = GEM_TAB;
+ break;
+ case SDLK_PAGEUP:
+ key = GEM_PGUP;
+ break;
+ case SDLK_PAGEDOWN:
+ key = GEM_PGDOWN;
+ break;
+ case SDLK_SCROLLOCK:
+ key = GEM_GRAB;
+ break;
+ case SDLK_F1:
+ case SDLK_F2:
+ case SDLK_F3:
+ case SDLK_F4:
+ case SDLK_F5:
+ case SDLK_F6:
+ case SDLK_F7:
+ case SDLK_F8:
+ case SDLK_F9:
+ case SDLK_F10:
+ case SDLK_F11:
+ case SDLK_F12:
+ //assuming they come sequentially,
+ //also, there is no need to ever produce more than 12
+ key = GEM_FUNCTION1+event.key.keysym.sym-SDLK_F1;
+ break;
+ default:
+ break;
}
- if (ConsolePopped)
+ if (core->ConsolePopped)
core->console->OnSpecialKeyPress( key );
- else if (Evnt)
- Evnt->OnSpecialKeyPress( key );
+ else
+ EvntManager->OnSpecialKeyPress( key );
} else if (( key != 0 )) {
- if (ConsolePopped)
+ if (core->ConsolePopped)
core->console->OnKeyPress( key, modstate);
- else if (Evnt)
- Evnt->KeyPress( key, modstate);
+ else
+ EvntManager->KeyPress( key, modstate);
}
break;
case SDL_MOUSEMOTION:
- lastevent = false;
MouseMovement(event.motion.x, event.motion.y);
break;
case SDL_MOUSEBUTTONDOWN:
- if ((DisableMouse & MOUSE_DISABLED) || !Evnt)
+ if (MouseFlags & MOUSE_DISABLED)
break;
- lastevent = true;
- lastmousetime=Evnt->GetRKDelay();
- if (lastmousetime != (unsigned long) ~0) {
- lastmousetime += lastmousetime+time;
+ lastMouseDownTime=EvntManager->GetRKDelay();
+ if (lastMouseDownTime != (unsigned long) ~0) {
+ lastMouseDownTime += lastMouseDownTime+lastTime;
}
- if (CursorIndex != 2)
- CursorIndex = 1;
+ if (CursorIndex != VID_CUR_DRAG)
+ CursorIndex = VID_CUR_DOWN;
CursorPos.x = event.button.x; // - mouseAdjustX[CursorIndex];
CursorPos.y = event.button.y; // - mouseAdjustY[CursorIndex];
- if (!ConsolePopped)
- Evnt->MouseDown( event.button.x, event.button.y, 1 << ( event.button.button - 1 ), GetModState(SDL_GetModState()) );
-
+ if (!core->ConsolePopped)
+ EvntManager->MouseDown( event.button.x, event.button.y, 1 << ( event.button.button - 1 ), GetModState(SDL_GetModState()) );
break;
-
case SDL_MOUSEBUTTONUP:
- lastevent = false;
- if ((DisableMouse & MOUSE_DISABLED) || !Evnt)
- break;
- if (CursorIndex != 2)
- CursorIndex = 0;
+ if (CursorIndex != VID_CUR_DRAG)
+ CursorIndex = VID_CUR_UP;
CursorPos.x = event.button.x;
CursorPos.y = event.button.y;
- if (!ConsolePopped)
- Evnt->MouseUp( event.button.x, event.button.y, 1 << ( event.button.button - 1 ), GetModState(SDL_GetModState()) );
-
- break;
- case SDL_ACTIVEEVENT:
- if (ConsolePopped) {
- break;
- }
-
- if (event.active.state == SDL_APPMOUSEFOCUS) {
- if (Evnt && !event.active.gain)
- Evnt->OnSpecialKeyPress( GEM_MOUSEOUT );
- }
+ if (!core->ConsolePopped)
+ EvntManager->MouseUp( event.button.x, event.button.y, 1 << ( event.button.button - 1 ), GetModState(SDL_GetModState()) );
break;
-
- }
- }
-
- if (Evnt && !DisableMouse && lastevent && time>lastmousetime && SDL_GetMouseState(&x,&y)==SDL_BUTTON(1)) {
- lastmousetime=time+Evnt->GetRKDelay();
- if (!ConsolePopped)
- Evnt->MouseUp( x, y, 1 << ( 0 ), GetModState(SDL_GetModState()) );
- }
-
- return ret;
-}
-
-bool SDLVideoDriver::ToggleGrabInput()
-{
- if (SDL_GRAB_OFF == SDL_WM_GrabInput( SDL_GRAB_QUERY )) {
- SDL_WM_GrabInput( SDL_GRAB_ON );
- return true;
- }
- else {
- SDL_WM_GrabInput( SDL_GRAB_OFF );
- MoveMouse(CursorPos.x, CursorPos.y);
- return false;
}
+ return GEM_OK;
}
void SDLVideoDriver::InitSpriteCover(SpriteCover* sc, int flags)
@@ -430,15 +318,14 @@ void SDLVideoDriver::InitSpriteCover(SpriteCover* sc, int flags)
void SDLVideoDriver::DestroySpriteCover(SpriteCover* sc)
{
delete[] sc->pixels;
- sc->pixels = 0;
+ sc->pixels = NULL;
}
// flags: 0 - never dither (full cover)
// 1 - dither if polygon wants it
// 2 - always dither
-void SDLVideoDriver::AddPolygonToSpriteCover(SpriteCover* sc,
- Wall_Polygon* poly)
+void SDLVideoDriver::AddPolygonToSpriteCover(SpriteCover* sc, Wall_Polygon* poly)
{
// possible TODO: change the cover to use a set of intervals per line?
@@ -450,7 +337,7 @@ void SDLVideoDriver::AddPolygonToSpriteCover(SpriteCover* sc,
std::list<Trapezoid>::iterator iter;
for (iter = poly->trapezoids.begin(); iter != poly->trapezoids.end();
- ++iter)
+ ++iter)
{
int y_top = iter->y1 - yoff; // inclusive
int y_bot = iter->y2 - yoff; // exclusive
@@ -510,53 +397,38 @@ void SDLVideoDriver::AddPolygonToSpriteCover(SpriteCover* sc,
Sprite2D* SDLVideoDriver::CreateSprite(int w, int h, int bpp, ieDword rMask,
ieDword gMask, ieDword bMask, ieDword aMask, void* pixels, bool cK, int index)
{
- Sprite2D* spr = new Sprite2D();
- void* p = SDL_CreateRGBSurfaceFrom( pixels, w, h, bpp, w*( bpp / 8 ),
+ SDL_Surface* p = SDL_CreateRGBSurfaceFrom( pixels, w, h, bpp, w*( bpp / 8 ),
rMask, gMask, bMask, aMask );
- spr->vptr = p;
- spr->pixels = pixels;
if (cK) {
SDL_SetColorKey( ( SDL_Surface * ) p, SDL_SRCCOLORKEY | SDL_RLEACCEL,
index );
}
- spr->Width = w;
- spr->Height = h;
- spr->Bpp = bpp;
- return spr;
+ return new Sprite2D(w, h, bpp, p, pixels);
}
Sprite2D* SDLVideoDriver::CreateSprite8(int w, int h, int bpp, void* pixels,
void* palette, bool cK, int index)
{
- Sprite2D* spr = new Sprite2D();
- void* p = SDL_CreateRGBSurfaceFrom( pixels, w, h, 8, w, 0, 0, 0, 0 );
+ SDL_Surface* p = SDL_CreateRGBSurfaceFrom( pixels, w, h, 8, w, 0, 0, 0, 0 );
int colorcount;
if (bpp == 8) {
colorcount = 256;
} else {
colorcount = 16;
}
- SDL_SetPalette( ( SDL_Surface * ) p, SDL_LOGPAL, ( SDL_Color * ) palette, 0, colorcount );
- spr->vptr = p;
- spr->pixels = pixels;
+ SetSurfacePalette( ( SDL_Surface * ) p, ( SDL_Color * ) palette, colorcount );
if (cK) {
SDL_SetColorKey( ( SDL_Surface * ) p, SDL_SRCCOLORKEY, index );
}
- spr->Width = w;
- spr->Height = h;
- spr->Bpp = bpp;
- return spr;
+ return new Sprite2D(w, h, bpp, p, pixels);
}
Sprite2D* SDLVideoDriver::CreateSpriteBAM8(int w, int h, bool rle,
- const unsigned char* pixeldata,
- AnimationFactory* datasrc,
- Palette* palette, int transindex)
+ const unsigned char* pixeldata,
+ AnimationFactory* datasrc,
+ Palette* palette, int transindex)
{
- Sprite2D* spr = new Sprite2D();
- spr->BAM = true;
Sprite2D_BAM_Internal* data = new Sprite2D_BAM_Internal;
- spr->vptr = data;
palette->IncRef();
data->pal = palette;
@@ -567,11 +439,8 @@ Sprite2D* SDLVideoDriver::CreateSpriteBAM8(int w, int h, bool rle,
data->source = datasrc;
datasrc->IncDataRefCount();
- spr->pixels = (const void*)pixeldata;
- spr->Width = w;
- spr->Height = h;
- spr->Bpp = 8; // FIXME!!!!
-
+ Sprite2D* spr = new Sprite2D(w, h, 8 /* FIXME!!!! */, data, pixeldata);
+ spr->BAM = true;
return spr;
}
@@ -605,7 +474,7 @@ void SDLVideoDriver::FreeSprite(Sprite2D*& spr)
Sprite2D* SDLVideoDriver::DuplicateSprite(const Sprite2D* sprite)
{
if (!sprite) return NULL;
- Sprite2D* dest = 0;
+ Sprite2D* dest = NULL;
if (!sprite->BAM) {
SDL_Surface* tmp = ( SDL_Surface* ) sprite->vptr;
@@ -614,7 +483,7 @@ Sprite2D* SDLVideoDriver::DuplicateSprite(const Sprite2D* sprite)
SDL_LockSurface( tmp );
memcpy(newpixels, sprite->pixels, sprite->Width*sprite->Height);
dest = CreateSprite8(sprite->Width, sprite->Height, 8,
- newpixels, tmp->format->palette->colors, true, 0);
+ newpixels, tmp->format->palette->colors, true, 0);
SDL_UnlockSurface( tmp );
} else {
Sprite2D_BAM_Internal* data = (Sprite2D_BAM_Internal*) sprite->vptr;
@@ -633,193 +502,10 @@ Sprite2D* SDLVideoDriver::DuplicateSprite(const Sprite2D* sprite)
return dest;
}
-
-void SDLVideoDriver::BlitSpriteRegion(const Sprite2D* spr, const Region& size, int x,
- int y, bool anchor, const Region* clip)
-{
- if (!spr->vptr) return;
-
- if (!spr->BAM) {
- //TODO: Add the destination surface and rect to the Blit Pipeline
- SDL_Rect drect;
- SDL_Rect t = {
- size.x, size.y, size.w, size.h
- };
- Region c;
- if (clip) {
- c = *clip;
- } else {
- c.x = 0;
- c.y = 0;
- c.w = backBuf->w;
- c.h = backBuf->h;
- }
- if (anchor) {
- drect.x = x;
- drect.y = y;
- } else {
- drect.x = x - Viewport.x;
- drect.y = y - Viewport.y;
- if (clip) {
- c.x -= Viewport.x;
- c.y -= Viewport.y;
- }
- }
- if (clip) {
- if (drect.x + size.w <= c.x)
- return;
- if (drect.x >= c.x + c.w)
- return;
-
- if (drect.y + size.h <= c.y)
- return;
- if (drect.y >= c.y + c.h)
- return;
-
- if (drect.x < c.x) {
- t.x += c.x - drect.x;
- t.w -= c.x - drect.x;
- drect.x = c.x;
- }
- if (drect.x + t.w > c.x + c.w) {
- t.w = c.x + c.w - drect.x;
- }
-
- if (drect.y < c.y) {
- t.y += c.y - drect.y;
- t.h -= c.y - drect.y;
- drect.y = c.y;
- }
- if (drect.y + t.h > c.y + c.h) {
- t.h = c.y + c.h - drect.y;
- }
- }
- SDL_BlitSurface( ( SDL_Surface * ) spr->vptr, &t, backBuf, &drect );
- } else {
- Sprite2D_BAM_Internal* data = (Sprite2D_BAM_Internal*)spr->vptr;
-
- const Uint8* rle = (const Uint8*)spr->pixels;
- int tx, ty;
- if (anchor) {
- tx = x - spr->XPos;
- ty = y - spr->YPos;
- } else {
- tx = x - spr->XPos - Viewport.x;
- ty = y - spr->YPos - Viewport.y;
- }
- if (tx > backBuf->w) return;
- if (tx+spr->Width <= 0) return;
-
- SDL_LockSurface(backBuf);
-
- int clipx, clipy, clipw, cliph;
- if (clip) {
- clipx = clip->x;
- clipy = clip->y;
- clipw = clip->w;
- cliph = clip->h;
- } else {
- clipx = 0;
- clipy = 0;
- clipw = backBuf->w;
- cliph = backBuf->h;
- }
-
- SDL_Rect cliprect;
- SDL_GetClipRect(backBuf, &cliprect);
- if (cliprect.x > clipx) {
- clipw -= (cliprect.x - clipx);
- clipx = cliprect.x;
- }
- if (cliprect.y > clipy) {
- cliph -= (cliprect.y - clipy);
- clipy = cliprect.y;
- }
- if (clipx+clipw > cliprect.x+cliprect.w) {
- clipw = cliprect.x+cliprect.w-clipx;
- }
- if (clipy+cliph > cliprect.y+cliprect.h) {
- cliph = cliprect.y+cliprect.h-clipy;
- }
-
- if (clipx < tx+size.x) {
- clipw -= (tx+size.x - clipx);
- clipx = tx+size.x;
- }
- if (clipy < ty+size.y) {
- cliph -= (ty+size.y - clipy);
- clipy = ty+size.y;
- }
- if (clipx+clipw > tx+size.x+size.w) {
- clipw = tx+size.x+size.w-clipx;
- }
- if (clipy+cliph > ty+size.y+size.h) {
- cliph = ty+size.y+size.h-clipy;
- }
-
-#define ALREADYCLIPPED
-#define SPECIALPIXEL
-#define FLIP
-#define HFLIP_CONDITIONAL data->flip_hor
-#define VFLIP_CONDITIONAL data->flip_ver
-#define RLE data->RLE
-#define PAL data->pal
-#define SRCDATA rle
-#define USE_PALETTE
-#undef COVER
-#undef TINT
-
- if (backBuf->format->BytesPerPixel == 4) {
-
-#undef BPP16
- if (data->pal->alpha) {
-
-#define PALETTE_ALPHA
-#include "SDLVideoDriver.inl"
-
- } else {
-
-#undef PALETTE_ALPHA
-#include "SDLVideoDriver.inl"
-
- }
-
- } else {
-
-#define BPP16
- if (data->pal->alpha) {
-
-#define PALETTE_ALPHA
-#include "SDLVideoDriver.inl"
-
- } else {
-
-#undef PALETTE_ALPHA
-#include "SDLVideoDriver.inl"
-
- }
-
- }
-
-#undef BPP16
-#undef ALREADYCLIPPED
-#undef SPECIALPIXEL
-#undef FLIP
-#undef HFLIP_CONDITIONAL
-#undef VFLIP_CONDITIONAL
-#undef RLE
-#undef PAL
-#undef SRCDATA
-#undef USE_PALETTE
-
- SDL_UnlockSurface(backBuf);
- }
-}
-
-void SDLVideoDriver::BlitTile(const Sprite2D* spr, const Sprite2D* mask, int x, int y, const Region* clip, bool trans)
+void SDLVideoDriver::BlitTile(const Sprite2D* spr, const Sprite2D* mask, int x, int y, const Region* clip, unsigned int flags)
{
if (spr->BAM) {
- printMessage( "SDLVideo", "Tile blit not supported for this sprite\n", LIGHT_RED );
+ Log(ERROR, "SDLVideo", "Tile blit not supported for this sprite");
return;
}
@@ -858,15 +544,19 @@ void SDLVideoDriver::BlitTile(const Sprite2D* spr, const Sprite2D* mask, int x,
const Uint8* data = (Uint8*) (( SDL_Surface * ) spr->vptr)->pixels;
const SDL_Color* pal = (( SDL_Surface * ) spr->vptr)->format->palette->colors;
- const Uint8* mask_data = 0;
- Uint8 ck = 0;
+ const Uint8* mask_data = NULL;
+ Uint32 ck = 0;
if (mask) {
mask_data = (Uint8*) (( SDL_Surface * ) mask->vptr)->pixels;
+#if SDL_VERSION_ATLEAST(1,3,0)
+ SDL_GetColorKey(( SDL_Surface * ) mask->vptr, &ck);
+#else
ck = (( SDL_Surface * ) mask->vptr)->format->colorkey;
+#endif
}
bool tint = false;
- Color tintcol = {0,0,0,0};
+ Color tintcol = {255,255,255,0};
if (core->GetGame()) {
const Color* totint = core->GetGame()->GetGlobalTint();
@@ -882,27 +572,58 @@ void SDLVideoDriver::BlitTile(const Sprite2D* spr, const Sprite2D* mask, int x,
else \
BlitTile_internal<Uint16>(backBuf, x, y, rx, ry, w, h, data, pal, mask_data, ck, T, B); \
+ if (flags & TILE_GREY) {
- if (trans) {
- TRBlender_HalfTrans B(backBuf->format);
+ if (flags & TILE_HALFTRANS) {
+ TRBlender_HalfTrans B(backBuf->format);
- if (tint) {
- TRTinter_Tint T(tintcol);
+ TRTinter_Grey T(tintcol);
DO_BLIT
} else {
- TRTinter_NoTint T;
+ TRBlender_Opaque B(backBuf->format);
+
+ TRTinter_Grey T(tintcol);
DO_BLIT
}
- } else {
- TRBlender_Opaque B(backBuf->format);
- if (tint) {
- TRTinter_Tint T(tintcol);
+ } else if (flags & TILE_SEPIA) {
+
+ if (flags & TILE_HALFTRANS) {
+ TRBlender_HalfTrans B(backBuf->format);
+
+ TRTinter_Sepia T(tintcol);
DO_BLIT
} else {
- TRTinter_NoTint T;
+ TRBlender_Opaque B(backBuf->format);
+
+ TRTinter_Sepia T(tintcol);
DO_BLIT
}
+
+ } else {
+
+ if (flags & TILE_HALFTRANS) {
+ TRBlender_HalfTrans B(backBuf->format);
+
+ if (tint) {
+ TRTinter_Tint T(tintcol);
+ DO_BLIT
+ } else {
+ TRTinter_NoTint T;
+ DO_BLIT
+ }
+ } else {
+ TRBlender_Opaque B(backBuf->format);
+
+ if (tint) {
+ TRTinter_Tint T(tintcol);
+ DO_BLIT
+ } else {
+ TRTinter_NoTint T;
+ DO_BLIT
+ }
+ }
+
}
#undef DO_BLIT
@@ -911,22 +632,24 @@ void SDLVideoDriver::BlitTile(const Sprite2D* spr, const Sprite2D* mask, int x,
void SDLVideoDriver::BlitSprite(const Sprite2D* spr, int x, int y, bool anchor,
- const Region* clip)
+ const Region* clip, Palette* palette)
{
if (!spr->vptr) return;
+ int tx = x - spr->XPos;
+ int ty = y - spr->YPos;
+ if (!anchor) {
+ tx -= Viewport.x;
+ ty -= Viewport.y;
+ }
+
if (!spr->BAM) {
//TODO: Add the destination surface and rect to the Blit Pipeline
SDL_Rect drect;
SDL_Rect t;
SDL_Rect* srect = NULL;
- if (anchor) {
- drect.x = x - spr->XPos;
- drect.y = y - spr->YPos;
- } else {
- drect.x = x - spr->XPos - Viewport.x;
- drect.y = y - spr->YPos - Viewport.y;
- }
+ drect.x = tx;
+ drect.y = ty;
if (clip) {
if (drect.x + spr->Width <= clip->x)
@@ -939,6 +662,7 @@ void SDLVideoDriver::BlitSprite(const Sprite2D* spr, int x, int y, bool anchor,
if (drect.y >= clip->y + clip->h)
return;
+ // determine srect/drect to clip to 'clip'
t.x = 0;
t.w = spr->Width;
if (drect.x < clip->x) {
@@ -963,79 +687,44 @@ void SDLVideoDriver::BlitSprite(const Sprite2D* spr, int x, int y, bool anchor,
srect = &t;
}
- SDL_BlitSurface( ( SDL_Surface * ) spr->vptr, srect, backBuf, &drect );
- } else {
- Sprite2D_BAM_Internal* data = (Sprite2D_BAM_Internal*)spr->vptr;
-
- const Uint8* rle = (const Uint8*)spr->pixels;
- int tx, ty;
- if (anchor) {
- tx = x - spr->XPos;
- ty = y - spr->YPos;
+ if (palette) {
+ Palette* tmpPal = spr->GetPalette();
+ SetSurfacePalette(( SDL_Surface * )spr->vptr, (SDL_Color*)palette->col, 256);
+ SDL_BlitSurface( ( SDL_Surface * ) spr->vptr, srect, backBuf, &drect );
+ SetSurfacePalette(( SDL_Surface * )spr->vptr, (SDL_Color*)tmpPal->col, 256);
+ tmpPal->Release();
} else {
- tx = x - spr->XPos - Viewport.x;
- ty = y - spr->YPos - Viewport.y;
+ SDL_BlitSurface( ( SDL_Surface * ) spr->vptr, srect, backBuf, &drect );
}
- if (tx > backBuf->w) return;
- if (tx+spr->Width <= 0) return;
-
- SDL_LockSurface(backBuf);
-
-#define SPECIALPIXEL
-#undef BPP16
-#define FLIP
-#define HFLIP_CONDITIONAL data->flip_hor
-#define VFLIP_CONDITIONAL data->flip_ver
-#define RLE data->RLE
-#define PAL data->pal
-#define SRCDATA rle
-#define USE_PALETTE
-#undef COVER
-#undef TINT
+ } else {
+ Sprite2D_BAM_Internal* data = (Sprite2D_BAM_Internal*)spr->vptr;
- if (backBuf->format->BytesPerPixel == 4) {
+ const Uint8* srcdata = (const Uint8*)spr->pixels;
-#undef BPP16
- if (data->pal->alpha) {
+ Region finalclip = computeClipRect(backBuf, clip, tx, ty, spr->Width, spr->Height);
-#define PALETTE_ALPHA
-#include "SDLVideoDriver.inl"
+ if (finalclip.w <= 0 || finalclip.h <= 0)
+ return;
- } else {
+ SDL_LockSurface(backBuf);
-#undef PALETTE_ALPHA
-#include "SDLVideoDriver.inl"
+ Palette* pal = (palette) ? palette : data->pal;
+ SRShadow_Regular shadow;
- }
+ if (pal->alpha) {
+ SRTinter_NoTint<true> tinter;
+ SRBlender_Alpha blender;
+ BlitSpritePAL_dispatch(false, data->flip_hor,
+ backBuf, srcdata, pal->col, tx, ty, spr->Width, spr->Height, data->flip_ver, finalclip, (Uint8)data->transindex, 0, spr, 0, shadow, tinter, blender);
} else {
+ SRTinter_NoTint<false> tinter;
+ SRBlender_NoAlpha blender;
-#define BPP16
- if (data->pal->alpha) {
-
-#define PALETTE_ALPHA
-#include "SDLVideoDriver.inl"
-
- } else {
-
-#undef PALETTE_ALPHA
-#include "SDLVideoDriver.inl"
-
- }
-
+ BlitSpritePAL_dispatch(false, data->flip_hor,
+ backBuf, srcdata, pal->col, tx, ty, spr->Width, spr->Height, data->flip_ver, finalclip, (Uint8)data->transindex, 0, spr, 0, shadow, tinter, blender);
}
-#undef BPP16
-#undef FLIP
-#undef HFLIP_CONDITIONAL
-#undef VFLIP_CONDITIONAL
-#undef RLE
-#undef PAL
-#undef SPECIALPIXEL
-#undef PALETTE_ALPHA
-#undef SRCDATA
-#undef USE_PALETTE
-
SDL_UnlockSurface(backBuf);
}
}
@@ -1046,16 +735,17 @@ void SDLVideoDriver::BlitGameSprite(const Sprite2D* spr, int x, int y,
SpriteCover* cover, Palette *palette,
const Region* clip, bool anchor)
{
+ assert(spr);
if (!spr->vptr) return;
// WARNING: this pointer is only valid with BAM sprites
- Sprite2D_BAM_Internal* data = 0;
+ Sprite2D_BAM_Internal* data = NULL;
if (!spr->BAM) {
SDL_Surface* surf = ( SDL_Surface * ) spr->vptr;
- if (surf->format->BytesPerPixel != 4) {
+ if (surf->format->BytesPerPixel != 4 && surf->format->BytesPerPixel != 1) {
// TODO...
- printMessage( "SDLVideo", "BlitGameSprite not supported for this sprite\n", LIGHT_RED );
+ Log(ERROR, "SDLVideo", "BlitGameSprite not supported for this sprite");
BlitSprite(spr, x, y, false, clip);
return;
}
@@ -1083,16 +773,17 @@ void SDLVideoDriver::BlitGameSprite(const Sprite2D* spr, int x, int y,
// implicit flags:
- const unsigned int blit_COVERED = 0x20000000U;
const unsigned int blit_TINTALPHA = 0x40000000U;
const unsigned int blit_PALETTEALPHA = 0x80000000U;
- if (cover) flags |= blit_COVERED;
+ // NB: blit_TINTALPHA isn't directly used or checked, but its presence
+ // affects the special case checks below
if ((flags & BLIT_TINTED) && tint.a != 255) flags |= blit_TINTALPHA;
+
if (spr->BAM && palette->alpha) flags |= blit_PALETTEALPHA;
// flag combinations which are often used:
- // (ignoring MIRRORX/Y since those are handled conditionally)
+ // (ignoring MIRRORX/Y since those are always resp. never handled by templ.)
// most game sprites:
// covered, BLIT_TINTED
@@ -1111,17 +802,19 @@ void SDLVideoDriver::BlitGameSprite(const Sprite2D* spr, int x, int y,
// other combinations use general case
- const Uint8* rle = (const Uint8*)spr->pixels;
- //int tx = x - spr->XPos - Viewport.x;
- //int ty = y - spr->YPos - Viewport.y;
+ const Uint8* srcdata = (const Uint8*)spr->pixels;
int tx = x - spr->XPos;
int ty = y - spr->YPos;
if (!anchor) {
- tx-=Viewport.x;
- ty-=Viewport.y;
+ tx -= Viewport.x;
+ ty -= Viewport.y;
}
- if (tx > backBuf->w) return;
- if (tx+spr->Width <= 0) return;
+
+ Region finalclip = computeClipRect(backBuf, clip, tx, ty, spr->Width, spr->Height);
+
+ if (finalclip.w <= 0 || finalclip.h <= 0)
+ return;
+
SDL_LockSurface(backBuf);
bool hflip = spr->BAM ? data->flip_hor : false;
@@ -1129,296 +822,99 @@ void SDLVideoDriver::BlitGameSprite(const Sprite2D* spr, int x, int y,
if (flags & BLIT_MIRRORX) hflip = !hflip;
if (flags & BLIT_MIRRORY) vflip = !vflip;
- Uint32 shadowcol32 = 0, mask32;
- Uint16 shadowcol16 = 0, mask16;
-
- if (flags & BLIT_TRANSSHADOW) {
- shadowcol32 = SDL_MapRGBA(backBuf->format, palette->col[1].r/2,
- palette->col[1].g/2, palette->col[1].b/2, 0);
- shadowcol16 = (Uint16)shadowcol32;
- }
-
- mask32 = (backBuf->format->Rmask >> 1) & backBuf->format->Rmask;
- mask32 |= (backBuf->format->Gmask >> 1) & backBuf->format->Gmask;
- mask32 |= (backBuf->format->Bmask >> 1) & backBuf->format->Bmask;
- mask16 = (Uint16)mask32;
-
+ // remove already handled flags and incompatible combinations
unsigned int remflags = flags & ~(BLIT_MIRRORX | BLIT_MIRRORY);
if (remflags & BLIT_NOSHADOW) remflags &= ~BLIT_TRANSSHADOW;
+ if (remflags & BLIT_GREY) remflags &= ~BLIT_SEPIA;
-#define FLIP
-#define HFLIP_CONDITIONAL hflip
-#define VFLIP_CONDITIONAL vflip
-#define RLE data->RLE
-#define PAL palette
-#define COVERX (cover->XPos - spr->XPos)
-#define COVERY (cover->YPos - spr->YPos)
-#define USE_PALETTE
-#define SRCDATA rle
-#undef TINT_ALPHA
-#undef PALETTE_ALPHA
+ if (spr->BAM && remflags == BLIT_TINTED) {
- if (spr->BAM && remflags == (blit_COVERED | BLIT_TINTED)) {
+ SRShadow_Regular shadow;
+ SRTinter_Tint<false, false> tinter(tint);
+ SRBlender_NoAlpha blender;
-#define COVER
-#define SPECIALPIXEL
-#define TINT
+ BlitSpritePAL_dispatch(cover, hflip, backBuf, srcdata, palette->col, tx, ty, spr->Width, spr->Height, vflip, finalclip, (Uint8)data->transindex, cover, spr, remflags, shadow, tinter, blender);
- if (backBuf->format->BytesPerPixel == 4) {
-#undef BPP16
-#include "SDLVideoDriver.inl"
- } else {
-#define BPP16
-#include "SDLVideoDriver.inl"
- }
-
-#undef COVER
-#undef TINT
-#undef SPECIALPIXEL
-
- } else if (spr->BAM && remflags == (blit_COVERED | BLIT_TINTED | BLIT_TRANSSHADOW)) {
-
-#define COVER
-#define TINT
-
- if (backBuf->format->BytesPerPixel == 4) {
-#undef BPP16
-#define SPECIALPIXEL if (p == 1) { *pix = ((*pix >> 1)&mask32) + shadowcol32; } else
-#include "SDLVideoDriver.inl"
-#undef SPECIALPIXEL
- } else {
-#define BPP16
-#define SPECIALPIXEL if (p == 1) { *pix = ((*pix >> 1)&mask16) + shadowcol16; } else
-#include "SDLVideoDriver.inl"
-#undef SPECIALPIXEL
- }
-
-#undef COVER
-#undef TINT
-
- } else if (spr->BAM && remflags == (blit_COVERED | BLIT_TINTED | BLIT_NOSHADOW)) {
-
-#define COVER
-#define TINT
-#define SPECIALPIXEL if (p != 1)
-
- if (backBuf->format->BytesPerPixel == 4) {
-#undef BPP16
-#include "SDLVideoDriver.inl"
- } else {
-#define BPP16
-#include "SDLVideoDriver.inl"
- }
-
-#undef SPECIALPIXEL
-#undef COVER
-#undef TINT
+ } else if (spr->BAM && remflags == (BLIT_TINTED | BLIT_TRANSSHADOW)) {
+ SRShadow_HalfTrans shadow(backBuf->format, palette->col[1]);
+ SRTinter_Tint<false, false> tinter(tint);
+ SRBlender_NoAlpha blender;
- } else if (spr->BAM && remflags == BLIT_TINTED) {
+ BlitSpritePAL_dispatch(cover, hflip, backBuf, srcdata, palette->col, tx, ty, spr->Width, spr->Height, vflip, finalclip, (Uint8)data->transindex, cover, spr, remflags, shadow, tinter, blender);
-#define SPECIALPIXEL
-#define TINT
+ } else if (spr->BAM && remflags == (BLIT_TINTED | BLIT_NOSHADOW)) {
- if (backBuf->format->BytesPerPixel == 4) {
-#undef BPP16
-#include "SDLVideoDriver.inl"
- } else {
-#define BPP16
-#include "SDLVideoDriver.inl"
- }
+ SRShadow_None shadow;
+ SRTinter_Tint<false, false> tinter(tint);
+ SRBlender_NoAlpha blender;
-#undef TINT
-#undef SPECIALPIXEL
+ BlitSpritePAL_dispatch(cover, hflip, backBuf, srcdata, palette->col, tx, ty, spr->Width, spr->Height, vflip, finalclip, (Uint8)data->transindex, cover, spr, remflags, shadow, tinter, blender);
} else if (spr->BAM && remflags == BLIT_HALFTRANS) {
-#define HALFALPHA
-#define SPECIALPIXEL
-
- if (backBuf->format->BytesPerPixel == 4) {
-#undef BPP16
-#include "SDLVideoDriver.inl"
- } else {
-#define BPP16
-#include "SDLVideoDriver.inl"
- }
-
-#undef HALFALPHA
-#undef SPECIALPIXEL
-
- } else if (spr->BAM && remflags == (blit_COVERED | BLIT_HALFTRANS)) {
-
-#define HALFALPHA
-#define COVER
-#define SPECIALPIXEL
-
- if (backBuf->format->BytesPerPixel == 4) {
-#undef BPP16
-#include "SDLVideoDriver.inl"
- } else {
-#define BPP16
-#include "SDLVideoDriver.inl"
- }
-
-#undef HALFALPHA
-#undef COVER
-#undef SPECIALPIXEL
+ SRShadow_HalfTrans shadow(backBuf->format, palette->col[1]);
+ SRTinter_NoTint<false> tinter;
+ SRBlender_NoAlpha blender;
- } else if (spr->BAM && remflags == blit_COVERED) {
-
-#define COVER
-#define SPECIALPIXEL
-
- if (backBuf->format->BytesPerPixel == 4) {
-#undef BPP16
-#include "SDLVideoDriver.inl"
- } else {
-#define BPP16
-#include "SDLVideoDriver.inl"
- }
+ BlitSpritePAL_dispatch(cover, hflip, backBuf, srcdata, palette->col, tx, ty, spr->Width, spr->Height, vflip, finalclip, (Uint8)data->transindex, cover, spr, remflags, shadow, tinter, blender);
-#undef COVER
-#undef SPECIALPIXEL
+ } else if (spr->BAM && remflags == 0) {
- }/* else if (remflags == 0) {
+ SRShadow_Regular shadow;
+ SRTinter_NoTint<false> tinter;
+ SRBlender_NoAlpha blender;
-#define SPECIALPIXEL
- if (backBuf->format->BytesPerPixel == 4) {
-#undef BPP16
-#include "SDLVideoDriver.inl"
- } else {
-#define BPP16
-#include "SDLVideoDriver.inl"
- }
-#undef SPECIALPIXEL
+ BlitSpritePAL_dispatch(cover, hflip, backBuf, srcdata, palette->col, tx, ty, spr->Width, spr->Height, vflip, finalclip, (Uint8)data->transindex, cover, spr, remflags, shadow, tinter, blender);
-}*/ else if (spr->BAM) {
+ } else if (spr->BAM) {
// handling the following effects with conditionals:
// halftrans
// noshadow
// transshadow
- // grey
- // red
+ // grey (TODO)
+ // sepia (TODO)
// glow (not yet)
// blended (not yet)
+ // vflip
- // handling the following effects by repeated inclusion:
+ // handling the following effects by repeated calls:
// palettealpha
// tinted
// covered
-
-// printf("Unoptimized blit: %04X\n", flags);
-
-#define SPECIALPIXEL int ia=0; if ((remflags & BLIT_HALFTRANS) || (p == 1 && (remflags & BLIT_TRANSSHADOW))) ia = 1; if (p == 1 && (remflags & BLIT_NOSHADOW)) { } else
-
-#define CUSTOMBLENDING
-#define ALPHAADJUST(a) ((a)>>ia)
-#define CUSTOMBLEND(r,g,b) do { if (remflags & BLIT_GREY) { unsigned int t = (r)+(g)+(b); t /= 3; (r)=t; (g)=t; (b)=t; } if (remflags & BLIT_RED) { (g) /= 2; (b) /= 2; } } while(0)
-
-#define TINT_ALPHA
+ // hflip
if (!(remflags & BLIT_TINTED)) tint.a = 255;
+ SRShadow_Flags shadow; // for halftrans, noshadow, transshadow
+ SRBlender_Alpha blender;
if (remflags & blit_PALETTEALPHA) {
-#define PALETTE_ALPHA
- if (remflags & blit_COVERED) {
-#define COVER
- if (remflags & BLIT_TINTED) {
-#define TINT
- if (backBuf->format->BytesPerPixel == 4) {
-#undef BPP16
-#include "SDLVideoDriver.inl"
- } else {
-#define BPP16
-#include "SDLVideoDriver.inl"
- }
-#undef TINT
- } else {
- if (backBuf->format->BytesPerPixel == 4) {
-#undef BPP16
-#include "SDLVideoDriver.inl"
- } else {
-#define BPP16
-#include "SDLVideoDriver.inl"
- }
- }
-#undef COVER
+ if (remflags & BLIT_TINTED) {
+ SRTinter_Flags<true> tinter(tint);
+
+ BlitSpritePAL_dispatch(cover, hflip,
+ backBuf, srcdata, palette->col, tx, ty, spr->Width, spr->Height, vflip, finalclip, (Uint8)data->transindex, cover, spr, remflags, shadow, tinter, blender);
} else {
- if (remflags & BLIT_TINTED) {
-#define TINT
- if (backBuf->format->BytesPerPixel == 4) {
-#undef BPP16
-#include "SDLVideoDriver.inl"
- } else {
-#define BPP16
-#include "SDLVideoDriver.inl"
- }
-#undef TINT
- } else {
- if (backBuf->format->BytesPerPixel == 4) {
-#undef BPP16
-#include "SDLVideoDriver.inl"
- } else {
-#define BPP16
-#include "SDLVideoDriver.inl"
- }
- }
+ SRTinter_FlagsNoTint<true> tinter;
+
+ BlitSpritePAL_dispatch(cover, hflip,
+ backBuf, srcdata, palette->col, tx, ty, spr->Width, spr->Height, vflip, finalclip, (Uint8)data->transindex, cover, spr, remflags, shadow, tinter, blender);
}
-#undef PALETTE_ALPHA
} else {
- if (remflags & blit_COVERED) {
-#define COVER
- if (remflags & BLIT_TINTED) {
-#define TINT
- if (backBuf->format->BytesPerPixel == 4) {
-#undef BPP16
-#include "SDLVideoDriver.inl"
- } else {
-#define BPP16
-#include "SDLVideoDriver.inl"
- }
-#undef TINT
- } else {
- if (backBuf->format->BytesPerPixel == 4) {
-#undef BPP16
-#include "SDLVideoDriver.inl"
- } else {
-#define BPP16
-#include "SDLVideoDriver.inl"
- }
- }
-#undef COVER
+ if (remflags & BLIT_TINTED) {
+ SRTinter_Flags<false> tinter(tint);
+
+ BlitSpritePAL_dispatch(cover, hflip,
+ backBuf, srcdata, palette->col, tx, ty, spr->Width, spr->Height, vflip, finalclip, (Uint8)data->transindex, cover, spr, remflags, shadow, tinter, blender);
} else {
- if (remflags & BLIT_TINTED) {
-#define TINT
- if (backBuf->format->BytesPerPixel == 4) {
-#undef BPP16
-#include "SDLVideoDriver.inl"
- } else {
-#define BPP16
-#include "SDLVideoDriver.inl"
- }
-#undef TINT
- } else {
- if (backBuf->format->BytesPerPixel == 4) {
-#undef BPP16
-#include "SDLVideoDriver.inl"
- } else {
-#define BPP16
-#include "SDLVideoDriver.inl"
- }
- }
+ SRTinter_FlagsNoTint<false> tinter;
+
+ BlitSpritePAL_dispatch(cover, hflip,
+ backBuf, srcdata, palette->col, tx, ty, spr->Width, spr->Height, vflip, finalclip, (Uint8)data->transindex, cover, spr, remflags, shadow, tinter, blender);
}
- }
-#undef SPECIALPIXEL
-#undef CUSTOMBLENDING
-#undef USE_PALETTE
-#undef ALPHAADJUST
-#undef CUSTOMBLEND
-#undef TINT_ALPHA
+ }
} else {
// non-BAM Blitting
@@ -1426,148 +922,98 @@ void SDLVideoDriver::BlitGameSprite(const Sprite2D* spr, int x, int y,
// handling the following effects with conditionals:
// halftrans
// grey
- // red
+ // sepia
// glow (not yet)
// blended (not yet)
+ // yflip
// handling the following effects by repeated inclusion:
// tinted
// covered
+ // xflip
// not handling the following effects at all:
- // noshadow (impossible with 32bpp)
- // transshadow (impossible with 32bpp)
- // palettealpha (always set)
+ // noshadow
+ // transshadow
+ // palettealpha
-// printf("Unoptimized blit: %04X\n", flags);
+// print("Unoptimized blit: %04X", flags);
-#define SPECIALPIXEL int ia=0; if ((remflags & BLIT_HALFTRANS)) ia = 1; if (p == 1 && (remflags & BLIT_NOSHADOW)) { } else
+ if (remflags & BLIT_HALFTRANS) {
+ // handle halftrans with 50% alpha tinting
+ if (!(remflags & BLIT_TINTED)) {
+ tint.r = tint.g = tint.b = tint.a = 255;
+ remflags |= BLIT_TINTED;
+ }
+ tint.a >>= 1;
+
+ }
-#define PALETTE_ALPHA
-#define CUSTOMBLENDING
-#define ALPHAADJUST(a) ((a)>>ia)
-#define CUSTOMBLEND(r,g,b) do { if (remflags & BLIT_GREY) { unsigned int t = (r)+(g)+(b); t /= 3; (r)=t; (g)=t; (b)=t; } if (remflags & BLIT_RED) { (g) /= 2; (b) /= 2; } } while(0)
+ const Color *col = 0;
-#undef SRCDATA
-#define SRCDATA ((const Uint32*)spr->pixels)
+ SDL_Surface* surf = ( SDL_Surface * ) spr->vptr;
+ if (surf->format->BytesPerPixel == 1) {
-#define TINT_ALPHA
+ if (remflags & BLIT_TINTED)
+ tint.a = 255;
- if (!(remflags & BLIT_TINTED)) tint.a = 255;
+ // NB: GemRB::Color has exactly the same layout as SDL_Color
+ if (!palette)
+ col = reinterpret_cast<const Color*>(surf->format->palette->colors);
+ else
+ col = palette->col;
- if (remflags & blit_COVERED) {
-#define COVER
+ const Uint8 *data = (const Uint8*)spr->pixels;
+
+ SRBlender_Alpha blender;
+ SRShadow_NOP shadow;
if (remflags & BLIT_TINTED) {
-#define TINT
- if (backBuf->format->BytesPerPixel == 4) {
-#undef BPP16
-#include "SDLVideoDriver.inl"
- } else {
-#define BPP16
-#include "SDLVideoDriver.inl"
- }
-#undef TINT
+ SRTinter_Flags<false> tinter(tint);
+
+ BlitSpritePAL_dispatch(cover, hflip,
+ backBuf, data, col, tx, ty, spr->Width, spr->Height, vflip, finalclip, -1, cover, spr, remflags, shadow, tinter, blender);
} else {
- if (backBuf->format->BytesPerPixel == 4) {
-#undef BPP16
-#include "SDLVideoDriver.inl"
- } else {
-#define BPP16
-#include "SDLVideoDriver.inl"
- }
+ SRTinter_FlagsNoTint<false> tinter;
+
+ BlitSpritePAL_dispatch(cover, hflip,
+ backBuf, data, col, tx, ty, spr->Width, spr->Height, vflip, finalclip, -1, cover, spr, remflags, shadow, tinter, blender);
}
-#undef COVER
+
} else {
+
+ const Uint32 *data = (const Uint32*)spr->pixels;
+
+ SRBlender_Alpha blender;
if (remflags & BLIT_TINTED) {
-#define TINT
- if (backBuf->format->BytesPerPixel == 4) {
-#undef BPP16
-#include "SDLVideoDriver.inl"
- } else {
-#define BPP16
-#include "SDLVideoDriver.inl"
- }
-#undef TINT
+ SRTinter_Flags<true> tinter(tint);
+
+ BlitSpriteRGB_dispatch(cover, hflip,
+ backBuf, data, tx, ty, spr->Width, spr->Height, vflip, finalclip, cover, spr, remflags, tinter, blender);
} else {
- if (backBuf->format->BytesPerPixel == 4) {
-#undef BPP16
-#include "SDLVideoDriver.inl"
- } else {
-#define BPP16
-#include "SDLVideoDriver.inl"
- }
+ SRTinter_FlagsNoTint<true> tinter;
+
+ BlitSpriteRGB_dispatch(cover, hflip,
+ backBuf, data, tx, ty, spr->Width, spr->Height, vflip, finalclip, cover, spr, remflags, tinter, blender);
}
- }
-#undef SPECIALPIXEL
-#undef CUSTOMBLENDING
-#undef ALPHAADJUST
-#undef CUSTOMBLEND
-#undef TINT_ALPHA
-#undef PALETTE_ALPHA
+ }
}
-#undef FLIP
-#undef HFLIP_CONDITIONAL
-#undef VFLIP_CONDITIONAL
-#undef RLE
-#undef PAL
-#undef COVERX
-#undef COVERY
-#undef SRCDATA
-
SDL_UnlockSurface(backBuf);
}
-
-
-
-
-void SDLVideoDriver::SetCursor(Sprite2D* up, Sprite2D* down)
-{
- if (up) {
- Cursor[0] = up;
- } else {
- Cursor[0] = NULL;
- }
- if (down) {
- Cursor[1] = down;
- } else {
- Cursor[1] = NULL;
- }
- return;
-}
-
-// Drag cursor is shown instead of all other cursors
-void SDLVideoDriver::SetDragCursor(Sprite2D* drag)
-{
- FreeSprite(Cursor[2]);
- if (drag) {
- Cursor[2] = drag;
- CursorIndex = 2;
- } else {
- CursorIndex = 0;
- Cursor[2] = NULL;
- }
-}
-
Sprite2D* SDLVideoDriver::GetScreenshot( Region r )
{
- int Width = r.w ? r.w : disp->w;
- int Height = r.h ? r.h : disp->h;
- SDL_Rect src = {r.x, r.y, r.w, r.h};
+ unsigned int Width = r.w ? r.w : disp->w;
+ unsigned int Height = r.h ? r.h : disp->h;
+ SDL_Rect src = {(Sint16)r.x, (Sint16)r.y, (Uint16)r.w, (Uint16)r.h};
-
- SDL_Surface* surf = SDL_CreateRGBSurface( SDL_SWSURFACE, Width, Height, 24,
- 0xFF0000, 0x00FF00, 0x0000FF, 0x000000 );
- SDL_BlitSurface( backBuf, (r.w && r.h) ? &src : NULL, surf, NULL);
void* pixels = malloc( Width * Height * 3 );
- memcpy( pixels, surf->pixels, Width * Height * 3 );
- //freeing up temporary surface as we copied its pixels
Sprite2D* screenshot = CreateSprite( Width, Height, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000, pixels, false, 0 );
- SDL_FreeSurface(surf);
+ SDL_BlitSurface( backBuf, (r.w && r.h) ? &src : NULL, (SDL_Surface*)screenshot->vptr, NULL);
+
return screenshot;
}
@@ -1575,7 +1021,7 @@ Sprite2D* SDLVideoDriver::GetScreenshot( Region r )
void SDLVideoDriver::SetPalette(void *data, Palette* pal)
{
SDL_Surface* sur = ( SDL_Surface* ) data;
- SDL_SetPalette( sur, SDL_LOGPAL, ( SDL_Color * ) pal->col, 0, 256 );
+ SetSurfacePalette(sur, ( SDL_Color * ) pal->col, 256);
}
void SDLVideoDriver::ConvertToVideoFormat(Sprite2D* sprite)
@@ -1586,7 +1032,7 @@ void SDLVideoDriver::ConvertToVideoFormat(Sprite2D* sprite)
{
return;
}
- SDL_Surface* ns = SDL_DisplayFormatAlpha( ss );
+ SDL_Surface* ns = SDL_ConvertSurface( ss, disp->format, 0);
if (ns == NULL) {
return;
}
@@ -1601,7 +1047,7 @@ void SDLVideoDriver::ConvertToVideoFormat(Sprite2D* sprite)
void SDLVideoDriver::DrawRect(const Region& rgn, const Color& color, bool fill, bool clipped)
{
SDL_Rect drect = {
- rgn.x, rgn.y, rgn.w, rgn.h
+ (Sint16)rgn.x, (Sint16)rgn.y, (Uint16)rgn.w, (Uint16)rgn.h
};
if (fill) {
if ( SDL_ALPHA_TRANSPARENT == color.a ) {
@@ -1615,8 +1061,8 @@ void SDLVideoDriver::DrawRect(const Region& rgn, const Color& color, bool fill,
c.r = color.r;
c.b = color.b;
c.g = color.g;
- SDL_SetPalette( rectsurf, SDL_LOGPAL, &c, 0, 1 );
- SDL_SetAlpha( rectsurf, SDL_SRCALPHA | SDL_RLEACCEL, color.a );
+ SetSurfacePalette( rectsurf, &c, 1 );
+ SetSurfaceAlpha(rectsurf, color.a);
SDL_BlitSurface( rectsurf, NULL, backBuf, &drect );
SDL_FreeSurface( rectsurf );
}
@@ -1632,13 +1078,13 @@ void SDLVideoDriver::DrawRect(const Region& rgn, const Color& color, bool fill,
void SDLVideoDriver::DrawRectSprite(const Region& rgn, const Color& color, const Sprite2D* sprite)
{
if (sprite->BAM) {
- printMessage( "SDLVideo", "DrawRectSprite not supported for this sprite\n", LIGHT_RED );
+ Log(ERROR, "SDLVideo", "DrawRectSprite not supported for this sprite");
return;
}
SDL_Surface* surf = ( SDL_Surface* ) sprite->vptr;
SDL_Rect drect = {
- rgn.x, rgn.y, rgn.w, rgn.h
+ (Sint16)rgn.x, (Sint16)rgn.y, (Uint16)rgn.w, (Uint16)rgn.h
};
if ( SDL_ALPHA_TRANSPARENT == color.a ) {
return;
@@ -1651,14 +1097,14 @@ void SDLVideoDriver::DrawRectSprite(const Region& rgn, const Color& color, const
c.r = color.r;
c.b = color.b;
c.g = color.g;
- SDL_SetPalette( rectsurf, SDL_LOGPAL, &c, 0, 1 );
- SDL_SetAlpha( rectsurf, SDL_SRCALPHA | SDL_RLEACCEL, color.a );
+ SetSurfacePalette( rectsurf, &c, 1 );
+ SetSurfaceAlpha(rectsurf, color.a);
SDL_BlitSurface( rectsurf, NULL, surf, &drect );
SDL_FreeSurface( rectsurf );
}
}
-inline void ReadPixel(long &val, unsigned char *pixels, int BytesPerPixel) {
+inline void ReadPixel(long &val, Pixel* pixels , int BytesPerPixel) {
if (BytesPerPixel == 1) {
val = *pixels;
} else if (BytesPerPixel == 2) {
@@ -1674,7 +1120,7 @@ inline void ReadPixel(long &val, unsigned char *pixels, int BytesPerPixel) {
}
}
-inline void WritePixel(const long val, unsigned char *pixels, int BytesPerPixel) {
+inline void WritePixel(const long val, Pixel* pixels, int BytesPerPixel) {
if (BytesPerPixel == 1) {
*pixels = (unsigned char)val;
} else if (BytesPerPixel == 2) {
@@ -1696,7 +1142,7 @@ inline void WritePixel(const long val, unsigned char *pixels, int BytesPerPixel)
void SDLVideoDriver::SetPixel(short x, short y, const Color& color, bool clipped)
{
- //printf("x: %d; y: %d; XC: %d; YC: %d, VX: %d, VY: %d, VW: %d, VH: %d\n", x, y, xCorr, yCorr, Viewport.x, Viewport.y, Viewport.w, Viewport.h);
+ //print("x: %d; y: %d; XC: %d; YC: %d, VX: %d, VY: %d, VW: %d, VH: %d", x, y, xCorr, yCorr, Viewport.x, Viewport.y, Viewport.w, Viewport.h);
if (clipped) {
x += xCorr;
y += yCorr;
@@ -2107,7 +1553,7 @@ void SDLVideoDriver::DrawPolyline(Gem_Polygon* poly, const Color& color, bool fi
SDL_LockSurface(backBuf);
std::list<Trapezoid>::iterator iter;
for (iter = poly->trapezoids.begin(); iter != poly->trapezoids.end();
- ++iter)
+ ++iter)
{
int y_top = iter->y1 - Viewport.y; // inclusive
int y_bot = iter->y2 - Viewport.y; // exclusive
@@ -2123,7 +1569,7 @@ void SDLVideoDriver::DrawPolyline(Gem_Polygon* poly, const Color& color, bool fi
Point& c = poly->points[redge];
Point& d = poly->points[(redge+1)%(poly->count)];
- Uint8* line = (Uint8*)(backBuf->pixels) + (y_top+yCorr)*backBuf->pitch;
+ Pixel* line = (Pixel*)(backBuf->pixels) + (y_top+yCorr)*backBuf->pitch;
for (int y = y_top; y < y_bot; ++y) {
int py = y + Viewport.y;
@@ -2176,17 +1622,6 @@ void SDLVideoDriver::DrawPolyline(Gem_Polygon* poly, const Color& color, bool fi
return;
}
-/** Send a Quit Signal to the Event Queue */
-bool SDLVideoDriver::Quit()
-{
- SDL_Event evnt;
- evnt.type = SDL_QUIT;
- if (SDL_PushEvent( &evnt ) == -1) {
- return false;
- }
- return true;
-}
-
Palette* SDLVideoDriver::GetPalette(void *vptr)
{
SDL_Surface* s = ( SDL_Surface* ) vptr;
@@ -2211,11 +1646,9 @@ Sprite2D *SDLVideoDriver::MirrorSpriteVertical(const Sprite2D* sprite, bool Mirr
if (!sprite || !sprite->vptr)
return NULL;
- Sprite2D* dest = 0;
-
+ Sprite2D* dest = DuplicateSprite(sprite);
if (!sprite->BAM) {
- dest = DuplicateSprite(sprite);
for (int x = 0; x < dest->Width; x++) {
unsigned char * dst = ( unsigned char * ) dest->pixels + x;
unsigned char * src = dst + ( dest->Height - 1 ) * dest->Width;
@@ -2228,12 +1661,11 @@ Sprite2D *SDLVideoDriver::MirrorSpriteVertical(const Sprite2D* sprite, bool Mirr
}
}
} else {
- dest = DuplicateSprite(sprite);
Sprite2D_BAM_Internal* destdata = (Sprite2D_BAM_Internal*)dest->vptr;
destdata->flip_ver = !destdata->flip_ver;
}
- dest->XPos = dest->XPos;
+ dest->XPos = sprite->XPos;
if (MirrorAnchor)
dest->YPos = sprite->Height - sprite->YPos;
else
@@ -2249,10 +1681,9 @@ Sprite2D *SDLVideoDriver::MirrorSpriteHorizontal(const Sprite2D* sprite, bool Mi
if (!sprite || !sprite->vptr)
return NULL;
- Sprite2D* dest = 0;
+ Sprite2D* dest = DuplicateSprite(sprite);
if (!sprite->BAM) {
- dest = DuplicateSprite(sprite);
for (int y = 0; y < dest->Height; y++) {
unsigned char * dst = (unsigned char *) dest->pixels + ( y * dest->Width );
unsigned char * src = dst + dest->Width - 1;
@@ -2263,7 +1694,6 @@ Sprite2D *SDLVideoDriver::MirrorSpriteHorizontal(const Sprite2D* sprite, bool Mi
}
}
} else {
- dest = DuplicateSprite(sprite);
Sprite2D_BAM_Internal* destdata = (Sprite2D_BAM_Internal*)dest->vptr;
destdata->flip_hor = !destdata->flip_hor;
}
@@ -2333,19 +1763,13 @@ void SDLVideoDriver::GetMousePos(int &x, int &y)
void SDLVideoDriver::MouseMovement(int x, int y)
{
- GetTime( lastMouseTime );
- if (DisableMouse&MOUSE_DISABLED)
+ lastMouseMoveTime = GetTickCount();
+ if (MouseFlags&MOUSE_DISABLED)
return;
CursorPos.x = x; // - mouseAdjustX[CursorIndex];
CursorPos.y = y; // - mouseAdjustY[CursorIndex];
- if (Evnt)
- Evnt->MouseMove(x, y);
-}
-
-/* no idea how elaborate this should be*/
-void SDLVideoDriver::MoveMouse(unsigned int x, unsigned int y)
-{
- SDL_WarpMouse(x,y);
+ if (EvntManager)
+ EvntManager->MouseMove(x, y);
}
void SDLVideoDriver::ClickMouse(unsigned int button)
@@ -2358,127 +1782,19 @@ void SDLVideoDriver::ClickMouse(unsigned int button)
}
}
-void SDLVideoDriver::MouseClickEvent(Uint8 type, Uint8 button)
-{
- SDL_Event *event = new SDL_Event();
- event->type = type;
- event->button.type = type;
- event->button.button = button;
- event->button.state = (type==SDL_MOUSEBUTTONDOWN)?SDL_PRESSED:SDL_RELEASED;
- event->button.x = CursorPos.x;
- event->button.y = CursorPos.y;
- SDL_PushEvent(event);
-}
-
-void SDLVideoDriver::InitMovieScreen(int &w, int &h, bool yuv)
-{
- if (yuv) {
- if (overlay) {
- SDL_FreeYUVOverlay(overlay);
- }
- // BIKPlayer outputs PIX_FMT_YUV420P which is YV12
- overlay = SDL_CreateYUVOverlay(w, h, SDL_YV12_OVERLAY, disp);
- }
- SDL_LockSurface( disp );
- memset( disp->pixels, 0,
- disp->w * disp->h * disp->format->BytesPerPixel );
- SDL_UnlockSurface( disp );
- SDL_Flip( disp );
- w = disp->w;
- h = disp->h;
- //setting the subtitle region to the bottom 1/4th of the screen
- subtitleregion.w = w;
- subtitleregion.h = h/4;
- subtitleregion.x = 0;
- subtitleregion.y = h-h/4;
-
- //same for SDL
- subtitleregion_sdl.w = w;
- subtitleregion_sdl.h = h/4;
- subtitleregion_sdl.x = 0;
- subtitleregion_sdl.y = h-h/4;
-}
-
-void SDLVideoDriver::showFrame(unsigned char* buf, unsigned int bufw,
- unsigned int bufh, unsigned int sx, unsigned int sy, unsigned int w,
- unsigned int h, unsigned int dstx, unsigned int dsty,
- int g_truecolor, unsigned char *pal, ieDword titleref)
+void SDLVideoDriver::MouseClickEvent(SDL_EventType type, Uint8 button)
{
- int i;
- SDL_Surface* sprite;
- SDL_Rect srcRect, destRect;
-
- assert( bufw == w && bufh == h );
-
- if (g_truecolor) {
- sprite = SDL_CreateRGBSurfaceFrom( buf, bufw, bufh, 16, 2 * bufw,
- 0x7C00, 0x03E0, 0x001F, 0 );
- } else {
- sprite = SDL_CreateRGBSurfaceFrom( buf, bufw, bufh, 8, bufw, 0x7C00,
- 0x03E0, 0x001F, 0 );
-
- for (i = 0; i < 256; i++) {
- sprite->format->palette->colors[i].r = ( *pal++ ) << 2;
- sprite->format->palette->colors[i].g = ( *pal++ ) << 2;
- sprite->format->palette->colors[i].b = ( *pal++ ) << 2;
- sprite->format->palette->colors[i].unused = 0;
- }
- }
-
- srcRect.x = sx;
- srcRect.y = sy;
- srcRect.w = w;
- srcRect.h = h;
- destRect.x = dstx;
- destRect.y = dsty;
- destRect.w = w;
- destRect.h = h;
-
- SDL_FillRect(disp, &subtitleregion_sdl, 0);
- SDL_BlitSurface( sprite, &srcRect, disp, &destRect );
- if (titleref>0)
- DrawMovieSubtitle( titleref );
- SDL_Flip( disp );
- SDL_FreeSurface( sprite );
+ SDL_Event evtClick = SDL_Event();
+
+ evtClick.type = type;
+ evtClick.button.type = type;
+ evtClick.button.button = button;
+ evtClick.button.state = (type==SDL_MOUSEBUTTONDOWN)?SDL_PRESSED:SDL_RELEASED;
+ evtClick.button.x = CursorPos.x;
+ evtClick.button.y = CursorPos.y;
+ SDL_PushEvent(&evtClick);
}
-void SDLVideoDriver::showYUVFrame(unsigned char** buf, unsigned int *strides,
- unsigned int /*bufw*/, unsigned int bufh,
- unsigned int w, unsigned int h,
- unsigned int dstx, unsigned int dsty,
- ieDword titleref) {
- SDL_Rect destRect;
-
- assert( /* bufw == w && */ bufh == h );
-
- SDL_LockYUVOverlay(overlay);
- for (unsigned int plane = 0; plane < 3; plane++) {
- unsigned char *data = buf[plane];
- unsigned int size = overlay->pitches[plane];
- if (strides[plane] < size) {
- size = strides[plane];
- }
- unsigned int srcoffset = 0, destoffset = 0;
- for (unsigned int i = 0; i < ((plane == 0) ? bufh : (bufh / 2)); i++) {
- memcpy(overlay->pixels[plane] + destoffset,
- data + srcoffset, size);
- srcoffset += strides[plane];
- destoffset += overlay->pitches[plane];
- }
- }
- SDL_UnlockYUVOverlay(overlay);
- destRect.x = dstx;
- destRect.y = dsty;
- destRect.w = w;
- destRect.h = h;
- SDL_FillRect(disp, &subtitleregion_sdl, 0);
- SDL_DisplayYUVOverlay(overlay, &destRect);
- if (titleref>0)
- DrawMovieSubtitle( titleref );
- //Maybe we don't need this?
- //SDL_Flip( disp );
-}
-
int SDLVideoDriver::PollMovieEvents()
{
SDL_Event event;
@@ -2494,7 +1810,7 @@ int SDLVideoDriver::PollMovieEvents()
case SDLK_q:
return 1;
case SDLK_f:
- ToggleFullscreenMode(-1);
+ ToggleFullscreenMode();
break;
default:
break;
@@ -2508,12 +1824,6 @@ int SDLVideoDriver::PollMovieEvents()
return 0;
}
-void SDLVideoDriver::SetMovieFont(Font *stfont, Palette *pal)
-{
- subtitlefont = stfont;
- subtitlepal = pal;
-}
-
void SDLVideoDriver::DrawMovieSubtitle(ieDword strRef)
{
if (strRef!=subtitlestrref) {
@@ -2527,23 +1837,10 @@ void SDLVideoDriver::DrawMovieSubtitle(ieDword strRef)
// FIXME: ugly hack!
SDL_Surface* temp = backBuf;
backBuf = disp;
-
+
//FYI: that 0 is pitch black
//SDL_FillRect(disp, &subtitleregion_sdl, 0);
subtitlefont->Print(subtitleregion, (unsigned char *) subtitletext, subtitlepal, IE_FONT_ALIGN_LEFT|IE_FONT_ALIGN_BOTTOM, true);
backBuf = temp;
}
}
-// sets brightness and contrast
-// FIXME:SetGammaRamp doesn't seem to work
-// WARNING: SDL 1.2.13 crashes in SetGamma on Windows (it was fixed in SDL's #3533 Revision)
-void SDLVideoDriver::SetGamma(int brightness, int /*contrast*/)
-{
- SDL_SetGamma(0.8+brightness/50.0,0.8+brightness/50.0,0.8+brightness/50.0);
-}
-
-#include "plugindef.h"
-
-GEMRB_PLUGIN(0xDBAAB50, "SDL Video Driver")
-PLUGIN_DRIVER(SDLVideoDriver, "sdl")
-END_PLUGIN()
diff --git a/gemrb/plugins/SDLVideo/SDLVideo.h b/gemrb/plugins/SDLVideo/SDLVideo.h
index e24ad9f..66e88de 100644
--- a/gemrb/plugins/SDLVideo/SDLVideo.h
+++ b/gemrb/plugins/SDLVideo/SDLVideo.h
@@ -23,54 +23,67 @@
#include "Video.h"
+#include "GUI/EventMgr.h"
#include "win32def.h"
+#include <vector>
#include <SDL.h>
+typedef unsigned char
+#ifdef __GNUC__
+ __attribute__((aligned(4)))
+#endif
+ Pixel;
+
+namespace GemRB {
+
+inline int GetModState(int modstate)
+{
+ int value = 0;
+ if (modstate&KMOD_SHIFT) value |= GEM_MOD_SHIFT;
+ if (modstate&KMOD_CTRL) value |= GEM_MOD_CTRL;
+ if (modstate&KMOD_ALT) value |= GEM_MOD_ALT;
+ return value;
+}
+
class SDLVideoDriver : public Video {
-private:
+protected:
SDL_Surface* disp;
SDL_Surface* backBuf;
SDL_Surface* extra;
std::vector< Region> upd;//Regions of the Screen to Update in the next SwapBuffer operation.
- Sprite2D* Cursor[3];
- SDL_Rect CursorPos;
- unsigned short CursorIndex;
- Color fadeColor;
unsigned long lastTime;
- unsigned long lastMouseTime;
- SDL_Event event; /* Event structure */
- //subtitle specific variables
- Font *subtitlefont;
- Palette *subtitlepal;
- Region subtitleregion;
+ unsigned long lastMouseMoveTime;
+ unsigned long lastMouseDownTime;
+
SDL_Rect subtitleregion_sdl; //we probably have the same stuff, twice
char *subtitletext;
ieDword subtitlestrref;
- /* yuv overlay for bink movie */
- SDL_Overlay *overlay;
public:
SDLVideoDriver(void);
- ~SDLVideoDriver(void);
+ virtual ~SDLVideoDriver(void);
int Init(void);
- int CreateDisplay(int width, int height, int bpp, bool fullscreen);
- void SetDisplayTitle(char* title, char* icon);
- bool ToggleFullscreenMode(int set_reset=-1);
- int SwapBuffers(void);
- int PollEvents();
- bool ToggleGrabInput();
+ virtual int PollEvents();
+
+ virtual int CreateDisplay(int width, int height, int bpp, bool fullscreen, const char* title)=0;
+ virtual bool SetFullscreenMode(bool set)=0;
+ virtual int SwapBuffers(void);
+
+ virtual bool ToggleGrabInput()=0;
short GetWidth() { return ( disp ? disp->w : 0 ); }
short GetHeight() { return ( disp ? disp->h : 0 ); }
+ virtual void ShowSoftKeyboard()=0;
+ virtual void HideSoftKeyboard()=0;
+
void InitSpriteCover(SpriteCover* sc, int flags);
void AddPolygonToSpriteCover(SpriteCover* sc, Wall_Polygon* poly);
void DestroySpriteCover(SpriteCover* sc);
void GetMousePos(int &x, int &y);
void MouseMovement(int x, int y);
- void MoveMouse(unsigned int x, unsigned int y);
void ClickMouse(unsigned int button);
- void MouseClickEvent(Uint8 type, Uint8 button);
+ void MouseClickEvent(SDL_EventType type, Uint8 button);
Sprite2D* CreateSprite(int w, int h, int bpp, ieDword rMask,
ieDword gMask, ieDword bMask, ieDword aMask, void* pixels,
bool cK = false, int index = 0);
@@ -82,11 +95,9 @@ public:
bool SupportsBAMSprites() { return true; }
void FreeSprite(Sprite2D* &spr);
Sprite2D* DuplicateSprite(const Sprite2D* spr);
- void BlitTile(const Sprite2D* spr, const Sprite2D* mask, int x, int y, const Region* clip, bool trans);
+ void BlitTile(const Sprite2D* spr, const Sprite2D* mask, int x, int y, const Region* clip, unsigned int flags);
void BlitSprite(const Sprite2D* spr, int x, int y, bool anchor = false,
- const Region* clip = NULL);
- void BlitSpriteRegion(const Sprite2D* spr, const Region& size, int x, int y,
- bool anchor = true, const Region* clip = NULL);
+ const Region* clip = NULL, Palette* palette = NULL);
void BlitGameSprite(const Sprite2D* spr, int x, int y,
unsigned int flags, Color tint,
SpriteCover* cover, Palette *palette = NULL,
@@ -115,13 +126,11 @@ public:
const Color& color, bool clipped = true);
/** This function Draws a Polygon on the Screen */
void DrawPolyline(Gem_Polygon* poly, const Color& color, bool fill = false);
- inline void DrawHLine(short x1, short y, short x2, const Color& color, bool clipped = false);
- inline void DrawVLine(short x, short y1, short y2, const Color& color, bool clipped = false);
- inline void DrawLine(short x1, short y1, short x2, short y2, const Color& color, bool clipped = false);
+ void DrawHLine(short x1, short y, short x2, const Color& color, bool clipped = false);
+ void DrawVLine(short x, short y1, short y2, const Color& color, bool clipped = false);
+ void DrawLine(short x1, short y1, short x2, short y2, const Color& color, bool clipped = false);
/** Blits a Sprite filling the Region */
void BlitTiled(Region rgn, const Sprite2D* img, bool anchor = false);
- /** Send a Quit Signal to the Event Queue */
- bool Quit();
/** Get the Palette of a surface */
Palette* GetPalette(void *vptr);
/** Flips sprite vertically */
@@ -148,26 +157,33 @@ public:
void SetFadeColor(int r, int g, int b);
void SetFadePercent(int percent);
- void InitMovieScreen(int &w, int &h, bool yuv=false);
- void SetMovieFont(Font *stfont, Palette *pal);
- void showFrame(unsigned char* buf, unsigned int bufw,
- unsigned int bufh, unsigned int sx, unsigned int sy, unsigned int w,
- unsigned int h, unsigned int dstx, unsigned int dsty, int truecolor,
- unsigned char *palette, ieDword strRef);
+
+ virtual void InitMovieScreen(int &w, int &h, bool yuv=false)=0;
+ virtual void DestroyMovieScreen() = 0;
+ virtual void showFrame(unsigned char* buf, unsigned int bufw,
+ unsigned int bufh, unsigned int sx, unsigned int sy, unsigned int w,
+ unsigned int h, unsigned int dstx, unsigned int dsty, int truecolor,
+ unsigned char *palette, ieDword strRef)=0;
void showYUVFrame(unsigned char** buf, unsigned int *strides,
- unsigned int bufw, unsigned int bufh,
- unsigned int w, unsigned int h,
- unsigned int dstx, unsigned int dsty,
- ieDword titleref);
+ unsigned int bufw, unsigned int bufh,
+ unsigned int w, unsigned int h,
+ unsigned int dstx, unsigned int dsty,
+ ieDword titleref)=0;
int PollMovieEvents();
-private:
+protected:
void DrawMovieSubtitle(ieDword strRef);
+ virtual bool SetSurfacePalette(SDL_Surface* surface, SDL_Color* colors, int ncolors)=0;
+ virtual bool SetSurfaceAlpha(SDL_Surface* surface, unsigned short alpha)=0;
+ /* used to process the SDL events dequeued by PollEvents or an arbitraty event from another source.*/
+ virtual int ProcessEvent(const SDL_Event & event);
public:
long GetPixel(void *data, unsigned short x, unsigned short y);
- void SetGamma(int brightness, int contrast);
+ void SetGamma(int brightness, int contrast)=0;
void SetMouseScrollSpeed(int speed);
};
+}
+
#endif
diff --git a/gemrb/plugins/SDLVideo/SDLVideoDriver.inl b/gemrb/plugins/SDLVideo/SDLVideoDriver.inl
deleted file mode 100644
index 4020ae8..0000000
--- a/gemrb/plugins/SDLVideo/SDLVideoDriver.inl
+++ /dev/null
@@ -1,539 +0,0 @@
-/* GemRB - Infinity Engine Emulator
- * Copyright (C) 2005-2006 The GemRB Project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- *
- */
-
-// Input macros:
-//
-// SRCDATA
-// pointer to the pixel data
-// RLE
-// is the sprite RLE-encoded?
-
-// USE_PALETTE
-// does the sprite use a palette? (If defined, define PAL too)
-// PAL
-// the palette
-// PALETTE_ALPHA
-// use the alpha values from the palette
-
-// BPP16
-// output surface is 16bpp instead of the default 32bpp
-
-// ALREADYCLIPPED
-// the variables clipx, clipy, clipw, cliph have already been set
-// FLIP
-// enable code for flipping sprite H/V, through the following two macros:
-// HFLIP_CONDITIONAL
-// boolean expression for when to flip the sprite horizontally
-// VFLIP_CONDITIONAL
-// boolean expression for when to flip the sprite vertically
-
-// COVER
-// apply wallcovers (The wallcover data is taken from the 'cover' variable)
-
-// TINT
-// enable tinting (The colour to tint with is taken from the 'tint' variable)
-// TINT_ALPHA
-// use the alpha component of the tint
-
-// SPECIALPIXEL
-// special code to be inserted right before rendering a pixel
-
-// CUSTOMBLENDING
-// if defined, use CUSTOMBLEND and ALPHAADJUST to pre-process source colour
-// CUSTOMBLEND(r,g,b)
-// called on colour right before blending with output pixel (post-tinting)
-// APLHAADJUST(a)
-// called on colour right before blending with output pixel (post-tinting)
-
-// HALFALPHA
-// draw sprite 50% transparent.
-// Cannot be used together with TINT_ALPHA, PALETTE_ALPHA or CUSTOMBLENDING
-
-// HIGHLIGHTCOVER
-// (debugging) make covered pixels white instead of black
-
-
-//#define HIGHLIGHTCOVER
-
-#define TARGET backBuf
-#define WIDTH spr->Width
-#define HEIGHT spr->Height
-
-
-// XNEG(x) is -x when flipping horizontally, x otherwise
-// YNEG(y) is -y when flipping vertically, y otherwise
-#ifdef FLIP
- #define XNEG(x) (((x)+xneg)^xneg)
- #define YNEG(y) (((y)+yneg)^yneg)
-#else
- #define XNEG(x) (x)
- #define YNEG(y) (y)
-#endif
-
-
-// Output 16/32 bpp
-#ifdef BPP16
- #define PTYPE Uint16
- #define PITCHMULT 2
- #define MASK mask16
-#else
- #define PITCHMULT 4
- #define PTYPE Uint32
- #define MASK mask32
-#endif
-
-// Input indexed/32 bpp
-#ifdef USE_PALETTE
- #define RVALUE(p) (col[(p)].r)
- #define GVALUE(p) (col[(p)].g)
- #define BVALUE(p) (col[(p)].b)
- #define AVALUE(p) (col[(p)].a)
- #define ISTRANSPARENT(p) (p == (Uint8)data->transindex)
- #define SRCTYPE Uint8
-#else
- // TODO: These shifts will need fixing if we ever use this functionality
- // for sprites not created by SDLVideoDriver::CreateLight
- #define RVALUE(p) (p & 0xff)
- #define GVALUE(p) ((p >> 8) & 0xff)
- #define BVALUE(p) ((p >> 16) & 0xff)
- #define AVALUE(p) (p >> 24)
- #define ISTRANSPARENT(p) (AVALUE(p) == 0)
- #define SRCTYPE Uint32
-#endif
-
-// Make ALPHAADJUST, CUSTOMBLEND nops if not doing CUSTOMBLENDING
-#ifndef CUSTOMBLENDING
- #define ALPHAADJUST(a) a
- #define CUSTOMBLEND(r,g,b)
-#endif
-
-
-// Define ALPHA, ALPHAVALUE macros appropriately for palette/tint alpha settings
-#ifdef PALETTE_ALPHA
- #define ALPHA
- #ifdef TINT_ALPHA
- #define ALPHAVALUE(p) (ALPHAADJUST(((AVALUE(p)) * tint.a)>>8))
- #else
- #define ALPHAVALUE(p) (ALPHAADJUST(AVALUE(p)))
- #endif
-#else
- #ifdef TINT_ALPHA
- #define ALPHA
- #define ALPHAVALUE(p) (ALPHAADJUST(tint.a))
- #else
- #undef ALPHA
- #define ALPHAVALUE(p) (ALPHAADJUST(255))
- #endif
-#endif
-
-#ifdef COVER
-assert(cover);
-#endif
-
-// TODO: preconvert palette to surface-specific color values, where possible
-
-
-// Define BLENDPIXEL macro for blending of source and dest pixels
-
-#ifdef ALPHA
- #ifdef TINT
- // alpha, tinted
- #define BLENDPIXEL(target,cr,cg,cb,ca,curval) do { \
- if ((ca) != 0) { \
- dR = ((tint.r*(cr)) >> 8); \
- dG = ((tint.g*(cg)) >> 8); \
- dB = ((tint.b*(cb)) >> 8); \
- CUSTOMBLEND(dR,dG,dB); \
- dR = 1 + (ca)*dR \
- + ((((curval)>>rshift)<<rloss)&0xFF)*(255-(ca)); \
- dR = (dR + (dR >> 8)) >> 8; \
- dG = 1 + (ca)*dG \
- + ((((curval)>>gshift)<<gloss)&0xFF)*(255-(ca)); \
- dG = (dG + (dG >> 8)) >> 8; \
- dB = 1 + (ca)*dB \
- + ((((curval)>>bshift)<<bloss)&0xFF)*(255-(ca)); \
- dB = (dB + (dB >> 8)) >> 8; \
- target = (PTYPE) ( ((dR) >> rloss) << rshift \
- | ((dG) >> gloss) << gshift \
- | ((dB) >> bloss) << bshift); \
- } \
- } while (0)
- #else
- // alpha, untinted
- #define BLENDPIXEL(target,cr,cg,cb,ca,curval) do { \
- if ((ca) != 0) { \
- dR = (cr); \
- dG = (cg); \
- dB = (cb); \
- CUSTOMBLEND(dR,dG,dB); \
- dR = 1 + (ca)*dR \
- + ((((curval)>>rshift)<<rloss)&0xFF)*(255-(ca)); \
- dR = (dR + (dR >> 8)) >> 8; \
- dG = 1 + (ca)*dG \
- + ((((curval)>>gshift)<<gloss)&0xFF)*(255-(ca)); \
- dG = (dG + (dG >> 8)) >> 8; \
- dB = 1 + (ca)*dB \
- + ((((curval)>>bshift)<<bloss)&0xFF)*(255-(ca)); \
- dB = (dB + (dB >> 8)) >> 8; \
- target = (PTYPE) ( ((dR) >> rloss) << rshift \
- | ((dG) >> gloss) << gshift \
- | ((dB) >> bloss) << bshift); \
- } \
- } while (0)
- #endif
-
-#else
-
- #ifdef HALFALPHA
-
- #ifdef TINT
- // 50% transparent, tinted
- #define BLENDPIXEL(target,cr,cg,cb,ca,curval) \
- target = ((curval >> 1)&MASK) + \
- ((((PTYPE)( ((tint.r*(cr)) >> (rloss+8)) << rshift \
- | ((tint.g*(cg)) >> (gloss+8)) << gshift \
- | ((tint.b*(cb)) >> (bloss+8)) << bshift)) >> 1)\
- &MASK)
-
- #else
- // 50% transparent, untinted
- #define BLENDPIXEL(target,cr,cg,cb,ca,curval) \
- target = ((curval >> 1)&MASK) + \
- ((((PTYPE)( ((cr) >> rloss) << rshift \
- | ((cg) >> gloss) << gshift \
- | ((cb) >> bloss) << bshift)) >> 1)&MASK)
-
- #endif
-
- #else
-
- #ifdef CUSTOMBLENDING
-
- #ifdef TINT
- // no alpha, tinted (custom blending)
- #define BLENDPIXEL(target,cr,cg,cb,ca,curval) do { \
- dR = ((tint.r*(cr)) >> 8); \
- dG = ((tint.g*(cg)) >> 8); \
- dB = ((tint.b*(cb)) >> 8); \
- CUSTOMBLEND(dR,dG,dB); \
- target = (PTYPE) ( ((dR) >> rloss) << rshift \
- | ((dG) >> gloss) << gshift \
- | ((dB) >> bloss) << bshift); \
- } while(0)
- #else
- // no alpha, untinted (custom blending)
- #define BLENDPIXEL(target,cr,cg,cb,ca,curval) do { \
- dR = (cr); \
- dG = (cg); \
- dB = (cb); \
- CUSTOMBLEND(dR,dG,dB); \
- target = (PTYPE) ( ((dR) >> rloss) << rshift \
- | ((dG) >> gloss) << gshift \
- | ((dB) >> bloss) << bshift); \
- } while(0)
- #endif
-
- #else
- #ifdef TINT
- // no alpha, tinted
- #define BLENDPIXEL(target,cr,cg,cb,ca,curval) \
- target = (PTYPE)( ((tint.r*(cr)) >> (rloss+8)) << rshift \
- | ((tint.g*(cg)) >> (gloss+8)) << gshift \
- | ((tint.b*(cb)) >> (bloss+8)) << bshift)
- #else
- // no alpha, untinted
- #define BLENDPIXEL(target,cr,cg,cb,ca,curval) \
- target = (PTYPE)( ((cr) >> rloss) << rshift \
- | ((cg) >> gloss) << gshift \
- | ((cb) >> bloss) << bshift)
- #endif
- #endif
- #endif
-#endif
-
-
-// Main rendering code
-
-do {
-#ifdef FLIP
- const int xneg = (HFLIP_CONDITIONAL)?-1:0;
- const int yneg = (VFLIP_CONDITIONAL)?-1:0;
-#else
- const int xneg = 0;
- const int yneg = 0;
-#endif
-
- const int rloss = (TARGET)->format->Rloss;
- const int gloss = (TARGET)->format->Gloss;
- const int bloss = (TARGET)->format->Bloss;
- const int rshift = (TARGET)->format->Rshift;
- const int gshift = (TARGET)->format->Gshift;
- const int bshift = (TARGET)->format->Bshift;
-#ifdef USE_PALETTE
- const Color* const col = (PAL)->col;
-#endif
- const SRCTYPE* srcdata = (SRCDATA);
-
-#if (defined(ALPHA) || defined(CUSTOMBLENDING))
- unsigned int dR;
- unsigned int dG;
- unsigned int dB;
-#endif
-
-#ifndef ALREADYCLIPPED
- int clipx, clipy, clipw, cliph;
- if (clip) {
- clipx = clip->x;
- clipy = clip->y;
- clipw = clip->w;
- cliph = clip->h;
- } else {
- clipx = 0;
- clipy = 0;
- clipw = (TARGET)->w;
- cliph = (TARGET)->h;
- }
- SDL_Rect cliprect;
- SDL_GetClipRect((TARGET), &cliprect);
- if (cliprect.x > clipx) {
- clipw -= (cliprect.x - clipx);
- clipx = cliprect.x;
- }
- if (cliprect.y > clipy) {
- cliph -= (cliprect.y - clipy);
- clipy = cliprect.y;
- }
- if (clipx+clipw > cliprect.x+cliprect.w) {
- clipw = cliprect.x+cliprect.w-clipx;
- }
- if (clipy+cliph > cliprect.y+cliprect.h) {
- cliph = cliprect.y+cliprect.h-clipy;
- }
-#endif
-
-#ifdef USE_PALETTE
- if (RLE) {
-#else
- if (false) {
-#endif
-
- PTYPE* line = (PTYPE*)(TARGET)->pixels +
- (ty - yneg*((HEIGHT)-1))*(TARGET)->pitch/(PITCHMULT);
- PTYPE* end = line + YNEG(HEIGHT)*(TARGET)->pitch/(PITCHMULT);
- PTYPE* clipstartline = (PTYPE*)(TARGET)->pixels
- + clipy*((TARGET)->pitch)/PITCHMULT;
- PTYPE* clipendline = clipstartline + cliph*((TARGET)->pitch)/PITCHMULT;
-#ifdef COVER
- Uint8* coverline = (Uint8*)cover->pixels + ((COVERY) - yneg*((HEIGHT)-1))*cover->Width;
-#endif
-
- if (yneg) {
- if (end < clipstartline)
- end = clipstartline - ((TARGET)->pitch)/PITCHMULT;
- } else {
- if (end > clipendline)
- end = clipendline;
- }
-
- int translength = 0;
- for (; YNEG((int)(end - line)) > 0; line += YNEG((TARGET)->pitch/(PITCHMULT)))
- {
- PTYPE* pix = line + tx + translength - xneg*((WIDTH)-1);
- PTYPE* endpix = line + tx - xneg*((WIDTH)-1) + XNEG(WIDTH);
- PTYPE* clipstartpix = line + clipx;
- PTYPE* clipendpix = clipstartpix + clipw;
-#ifdef COVER
- Uint8* coverpix = coverline + (COVERX) + translength - xneg*((WIDTH)-1);
-#endif
- if (yneg) {
- if (line >= clipendline) clipstartpix = clipendpix;
- } else {
- if (line < clipstartline) clipstartpix = clipendpix;
- }
- while (XNEG((int)(endpix - pix)) > 0)
- {
- Uint8 p = *srcdata++;
- if (ISTRANSPARENT(p)) {
- int count = XNEG((*srcdata++) + 1);
- pix += count;
-#ifdef COVER
- coverpix += count;
-#endif
- } else {
- if (pix >= clipstartpix && pix < clipendpix) {
-#ifdef COVER
- if (!*coverpix)
-#endif
- {
- SPECIALPIXEL {
- BLENDPIXEL(*pix, (RVALUE(p)), (GVALUE(p)), (BVALUE(p)), (ALPHAVALUE(p)), *pix);
- }
- }
-#if defined(COVER) && defined(HIGHLIGHTCOVER)
- else {
- BLENDPIXEL(*pix, 255, 255, 255, 255, *pix);
- }
-#endif
- }
- pix += XNEG(1);
-#ifdef COVER
- coverpix += XNEG(1);
-#endif
- }
- }
- translength = pix - endpix;
-#ifdef COVER
- coverline += YNEG(cover->Width);
-#endif
- }
- } else {
-#ifdef COVER
- Uint8* coverline = (Uint8*)cover->pixels + ((COVERY) - yneg*((HEIGHT)-1))*cover->Width;
-#endif
- int starty, endy;
-
- if (!yneg) {
- starty = ty;
- if (clipy > starty) starty = clipy;
- endy = ty + (HEIGHT);
- if (clipy+cliph < endy) endy = clipy+cliph;
-
- if (starty >= endy) break;
-
- // skip clipped lines at start
- srcdata += (starty - ty) * (WIDTH);
-#ifdef COVER
- coverline += (starty - ty) * cover->Width;
-#endif
- } else {
- starty = ty + (HEIGHT) - 1;
- if (clipy+cliph <= starty) starty = clipy+cliph-1;
- endy = ty - 1;
- if (clipy-1 > endy) endy = clipy-1;
-
- if (starty <= endy) break;
-
- // skip clipped lines at start
- srcdata += (ty + (HEIGHT) - 1 - starty) * (WIDTH);
-#ifdef COVER
- coverline -= (ty + (HEIGHT) - 1 - starty) * cover->Width;
-#endif
- }
-
- int startx, endx;
- int prelineskip = 0;
- int postlineskip = 0;
-
- if (!xneg) {
- startx = tx;
- if (clipx > startx) startx = clipx;
- endx = tx + (WIDTH);
- if (clipx+clipw < endx) endx = clipx+cliph;
-
- if (startx >= endx) break;
-
- prelineskip = startx - tx;
- postlineskip = tx + (WIDTH) - endx;
- } else {
- startx = tx + (WIDTH) - 1;
- if (clipx+clipw <= startx) startx = clipx+clipw-1;
- endx = tx - 1;
- if (clipx-1 > endx) endx = clipx-1;
-
- if (startx <= endx) break;
-
- prelineskip = (tx + (WIDTH) - 1) - startx;
- postlineskip = endx - (tx-1);
- }
-
-
- PTYPE* line = (PTYPE*)(TARGET)->pixels +
- starty*(TARGET)->pitch/(PITCHMULT);
- PTYPE* endline = (PTYPE*)(TARGET)->pixels +
- endy*(TARGET)->pitch/(PITCHMULT);
-
- while (line != endline) {
- PTYPE* pix = line + startx;
- PTYPE* endpix = line + endx;
-#ifdef COVER
- Uint8* coverpix = coverline + (COVERX) + XNEG(prelineskip) - xneg*((WIDTH)-1);
-#endif
- srcdata += prelineskip;
-
- while (pix != endpix)
- {
- SRCTYPE p = *srcdata++;
- if (!(ISTRANSPARENT(p))) {
-#ifdef COVER
- if (!*coverpix)
-#endif
- {
- SPECIALPIXEL {
- BLENDPIXEL(*pix, (RVALUE(p)), (GVALUE(p)), (BVALUE(p)), ( (ALPHAVALUE(p))), *pix);
- }
- }
-#if defined(COVER) && defined(HIGHLIGHTCOVER)
- else {
- BLENDPIXEL(*pix, 255, 255, 255, 255, *pix);
- }
-#endif
- }
- pix += XNEG(1);
-#ifdef COVER
- coverpix += XNEG(1);
-#endif
- }
-
- srcdata += postlineskip;
-
- line += YNEG((TARGET)->pitch/(PITCHMULT));
-#ifdef COVER
- coverline += YNEG(cover->Width);
-#endif
- }
- }
-
-} while(0);
-
-
-
-#undef XNEG
-#undef YNEG
-#undef PITCHMULT
-#undef PTYPE
-#undef BLENDPIXEL
-#undef TARGET
-#undef WIDTH
-#undef HEIGHT
-#undef ALPHA
-#undef ALPHAVALUE
-#undef HIGHLIGHTCOVER
-#undef MASK
-#undef RVALUE
-#undef GVALUE
-#undef BVALUE
-#undef AVALUE
-#undef ISTRANSPARENT
-#undef SRCTYPE
-
-#ifndef CUSTOMBLENDING
-#undef ALPHAADJUST
-#undef CUSTOMBLEND
-#endif
diff --git a/gemrb/plugins/SDLVideo/SpriteRenderer.inl b/gemrb/plugins/SDLVideo/SpriteRenderer.inl
new file mode 100644
index 0000000..b479595
--- /dev/null
+++ b/gemrb/plugins/SDLVideo/SpriteRenderer.inl
@@ -0,0 +1,912 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2012 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+// For debugging:
+//#define HIGHLIGHTCOVER
+
+
+
+// For pixel formats:
+// We hardcode a single pixel format per bit depth.
+
+#if TARGET_OS_IPHONE || (ANDROID && SDL_VERSION_ATLEAST(1,3,0))
+// NOTE: TARGET_OS_IPHONE must go before TARGET_OS_MAC
+// I don't know if its just the simulator, but TARGET_OS_MAC is set on iOS
+
+const unsigned int RLOSS16 = 3;
+const unsigned int GLOSS16 = 2;
+const unsigned int BLOSS16 = 3;
+const unsigned int RSHIFT16 = 11;
+const unsigned int GSHIFT16 = 5;
+const unsigned int BSHIFT16 = 0;
+
+const unsigned int RSHIFT32 = 0;
+const unsigned int GSHIFT32 = 8;
+const unsigned int BSHIFT32 = 16;
+
+#elif TARGET_OS_MAC
+
+const unsigned int RLOSS16 = 3;
+const unsigned int GLOSS16 = 2;
+const unsigned int BLOSS16 = 3;
+const unsigned int RSHIFT16 = 11;
+const unsigned int GSHIFT16 = 5;
+const unsigned int BSHIFT16 = 0;
+
+const unsigned int RSHIFT32 = 8;
+const unsigned int GSHIFT32 = 16;
+const unsigned int BSHIFT32 = 24;
+
+#else
+
+const unsigned int RLOSS16 = 3;
+const unsigned int GLOSS16 = 2;
+const unsigned int BLOSS16 = 3;
+const unsigned int RSHIFT16 = 11;
+const unsigned int GSHIFT16 = 5;
+const unsigned int BSHIFT16 = 0;
+
+const unsigned int RSHIFT32 = 16;
+const unsigned int GSHIFT32 = 8;
+const unsigned int BSHIFT32 = 0;
+
+#endif
+
+const Uint16 halfmask16 = ((0xFFU >> (RLOSS16+1)) << RSHIFT16) | ((0xFFU >> (GLOSS16+1)) << GSHIFT16) | ((0xFFU >> (BLOSS16+1)) << BSHIFT16);
+const Uint32 halfmask32 = ((0xFFU >> 1) << RSHIFT32) | ((0xFFU >> 1) << GSHIFT32) | ((0xFFU >> 1) << BSHIFT32);
+
+static Region computeClipRect(SDL_Surface* target, const Region* clip,
+ int tx, int ty, int width, int height)
+{
+ Region r;
+ if (clip) {
+ r = *clip;
+ } else {
+ r.x = 0;
+ r.y = 0;
+ r.w = target->w;
+ r.h = target->h;
+ }
+
+ // Intersect with SDL clipping rect
+ SDL_Rect cliprect;
+ SDL_GetClipRect(target, &cliprect);
+ if (cliprect.x > r.x) {
+ r.w -= (cliprect.x - r.x);
+ r.x = cliprect.x;
+ }
+ if (cliprect.y > r.y) {
+ r.h -= (cliprect.y - r.y);
+ r.y = cliprect.y;
+ }
+ if (r.x+r.w > cliprect.x+cliprect.w) {
+ r.w = cliprect.x+cliprect.w-r.x;
+ }
+ if (r.y+r.h > cliprect.y+cliprect.h) {
+ r.h = cliprect.y+cliprect.h-r.y;
+ }
+
+ // Intersect with actual sprite target rectangle
+ if (r.x < tx) {
+ r.w -= (tx - r.x);
+ r.x = tx;
+ }
+ if (r.y < ty) {
+ r.h -= (ty - r.y);
+ r.y = ty;
+ }
+ if (r.x+r.w > tx+width)
+ r.w = tx+width-r.x;
+ if (r.y+r.h > ty+height)
+ r.h = ty+height-r.y;
+
+ return r;
+}
+
+
+struct SRShadow_NOP {
+ template<typename PTYPE>
+ bool operator()(PTYPE&, Uint8, int&, unsigned int) const { return false; }
+};
+
+struct SRShadow_None {
+ template<typename PTYPE>
+ bool operator()(PTYPE&, Uint8 p, int&, unsigned int) const { return (p == 1); }
+};
+
+struct SRShadow_HalfTrans {
+ SRShadow_HalfTrans(const SDL_PixelFormat* format, const Color& col)
+ {
+ shadowcol = (Uint32)SDL_MapRGBA(format, col.r/2, col.g/2, col.b/2, 0);
+ mask = (0x7F >> format->Rloss) << format->Rshift
+ | (0x7F >> format->Gloss) << format->Gshift
+ | (0x7F >> format->Bloss) << format->Bshift;
+ }
+
+ template<typename PTYPE>
+ bool operator()(PTYPE& pix, Uint8 p, int&, unsigned int) const
+ {
+ if (p == 1) {
+ pix = ((pix >> 1)&mask) + shadowcol;
+ return true;
+ }
+ return false;
+ }
+
+ Uint32 mask;
+ Uint32 shadowcol;
+};
+
+struct SRShadow_Regular {
+ template<typename PTYPE>
+ bool operator()(PTYPE&, Uint8, int&, unsigned int) const { return false; }
+};
+
+// Conditionally handle halftrans,noshadow,transshadow
+struct SRShadow_Flags {
+ template<typename PTYPE>
+ bool operator()(PTYPE&, Uint8 p, int& a, unsigned int flags) const {
+ if ((flags & BLIT_HALFTRANS) || ((p == 1) && (flags & BLIT_TRANSSHADOW)))
+ a = 1;
+ if (p == 1 && (flags & BLIT_NOSHADOW))
+ return true;
+ return false;
+ }
+};
+
+
+template<bool PALALPHA>
+struct SRTinter_NoTint {
+ void operator()(Uint8&, Uint8&, Uint8&, Uint8& a, unsigned int) const {
+ if (!PALALPHA) a = 255;
+ }
+};
+
+template<bool PALALPHA, bool TINTALPHA>
+struct SRTinter_Tint {
+ SRTinter_Tint(const Color& t) : tint(t) { }
+
+ void operator()(Uint8& r, Uint8& g, Uint8& b, Uint8& a, unsigned int) const {
+ r = (tint.r * r) >> 8;
+ g = (tint.g * g) >> 8;
+ b = (tint.b * b) >> 8;
+ if (TINTALPHA && PALALPHA) a = (tint.a * a) >> 8;
+ //if (!TINTALPHA && PALALPHA) a = a;
+ if (TINTALPHA && !PALALPHA) a = tint.a;
+ if (!TINTALPHA && !PALALPHA) a = 255;
+ }
+ Color tint;
+};
+
+// Always tint, and conditionally handle grey, red
+template<bool PALALPHA>
+struct SRTinter_Flags {
+ SRTinter_Flags(const Color& t) : tint(t) { }
+
+ void operator()(Uint8& r, Uint8& g, Uint8& b, Uint8& a, unsigned int flags) const {
+ if (flags & BLIT_GREY) {
+ r = (tint.r * r) >> 10;
+ g = (tint.g * g) >> 10;
+ b = (tint.b * b) >> 10;
+ Uint8 avg = r + g + b;
+ r = g = b = avg;
+ } else if (flags & BLIT_SEPIA) {
+ r = (tint.r * r) >> 10;
+ g = (tint.g * g) >> 10;
+ b = (tint.b * b) >> 10;
+ Uint8 avg = r + g + b;
+ r = avg + 21; // can't overflow, since a is at most 189
+ g = avg;
+ b = avg < 32 ? 0 : avg - 32;
+ } else {
+ r = (tint.r * r) >> 8;
+ g = (tint.g * g) >> 8;
+ b = (tint.b * b) >> 8;
+ }
+
+ if (!PALALPHA)
+ a = tint.a;
+ else
+ a = (tint.a * a) >> 8;
+ }
+
+ Color tint;
+};
+
+// Don't tint, but conditionally handle grey, sepia
+template<bool PALALPHA>
+struct SRTinter_FlagsNoTint {
+ SRTinter_FlagsNoTint() { }
+
+ void operator()(Uint8& r, Uint8& g, Uint8& b, Uint8& a, unsigned int flags) const {
+ if (flags & BLIT_GREY) {
+ r >>= 2;
+ g >>= 2;
+ b >>= 2;
+ Uint8 avg = r + g + b;
+ r = g = b = avg;
+ } else if (flags & BLIT_SEPIA) {
+ r >>= 2;
+ g >>= 2;
+ b >>= 2;
+ Uint8 avg = r + g + b;
+ r = avg + 21; // can't overflow, since a is at most 189
+ g = avg;
+ b = avg < 32 ? 0 : avg - 32;
+ }
+
+ if (!PALALPHA) a = 255;
+ }
+};
+
+
+struct SRBlender_NoAlpha { };
+struct SRBlender_HalfAlpha { };
+struct SRBlender_Alpha { };
+
+struct SRFormat_Hard { };
+struct SRFormat_Soft { };
+
+template<typename PTYPE, typename BLENDER, typename PIXELFORMAT>
+struct SRBlender {
+ void operator()(PTYPE& /*pix*/, Uint8 /*r*/, Uint8 /*g*/, Uint8 /*b*/, Uint8 /*a*/) const { assert(false); }
+};
+
+
+
+// 16 bpp, 565
+template<>
+struct SRBlender<Uint16, SRBlender_NoAlpha, SRFormat_Hard> {
+ void operator()(Uint16& pix, Uint8 r, Uint8 g, Uint8 b, Uint8) const {
+ pix = ((r >> RLOSS16) << RSHIFT16) |
+ ((g >> GLOSS16) << GSHIFT16) |
+ ((b >> BLOSS16) << BSHIFT16);
+ }
+};
+
+template<>
+struct SRBlender<Uint16, SRBlender_HalfAlpha, SRFormat_Hard> {
+ void operator()(Uint16& pix, Uint8 r, Uint8 g, Uint8 b, Uint8) const {
+ pix = ((pix >> 1) & halfmask16) +
+ ((((r >> (RLOSS16+1)) << RSHIFT16) | ((g >> (GLOSS16+1)) << GSHIFT16) | ((b >> (BLOSS16+1)) << BSHIFT16)) & halfmask16);
+ }
+};
+
+template<>
+struct SRBlender<Uint16, SRBlender_Alpha, SRFormat_Hard> {
+ void operator()(Uint16& pix, Uint8 r, Uint8 g, Uint8 b, Uint8 a) const {
+ unsigned int dr = 1 + a*(r >> RLOSS16) + (255-a)*((pix >> RSHIFT16) & ((1 << (8-RLOSS16))-1));
+ unsigned int dg = 1 + a*(g >> GLOSS16) + (255-a)*((pix >> GSHIFT16) & ((1 << (8-GLOSS16))-1));
+ unsigned int db = 1 + a*(b >> BLOSS16) + (255-a)*((pix >> BSHIFT16) & ((1 << (8-BLOSS16))-1));
+
+ r = (dr + (dr>>8)) >> 8;
+ g = (dg + (dg>>8)) >> 8;
+ b = (db + (db>>8)) >> 8;
+ pix = (r << RSHIFT16) |
+ (g << GSHIFT16) |
+ (b << BSHIFT16);
+ }
+};
+
+// 32 bpp, 888
+template<>
+struct SRBlender<Uint32, SRBlender_NoAlpha, SRFormat_Hard> {
+ void operator()(Uint32& pix, Uint8 r, Uint8 g, Uint8 b, Uint8) const {
+ pix = (r << RSHIFT32) |
+ (g << GSHIFT32) |
+ (b << BSHIFT32);
+ }
+};
+
+template<>
+struct SRBlender<Uint32, SRBlender_HalfAlpha, SRFormat_Hard> {
+ void operator()(Uint32& pix, Uint8 r, Uint8 g, Uint8 b, Uint8) const {
+ pix = ((pix >> 1) & halfmask32) +
+ ((((r << RSHIFT32) | (g << GSHIFT32) | (b << BSHIFT32)) >> 1) & halfmask32);
+ }
+};
+
+
+template<>
+struct SRBlender<Uint32, SRBlender_Alpha, SRFormat_Hard> {
+ void operator()(Uint32& pix, Uint8 r, Uint8 g, Uint8 b, Uint8 a) const {
+ unsigned int dr = 1 + a*r + (255-a)*((pix >> RSHIFT32) & 0xFF);
+ unsigned int dg = 1 + a*g + (255-a)*((pix >> GSHIFT32) & 0xFF);
+ unsigned int db = 1 + a*b + (255-a)*((pix >> BSHIFT32) & 0xFF);
+ r = (dr + (dr>>8)) >> 8;
+ g = (dg + (dg>>8)) >> 8;
+ b = (db + (db>>8)) >> 8;
+ pix = (r << RSHIFT32) |
+ (g << GSHIFT32) |
+ (b << BSHIFT32);
+ }
+};
+
+
+// MSVC6 requires all template arguments to a function to be reflected in the
+// argument list. We wrap them in the type of a dummy argument.
+template <bool b>
+class MSVCHack {};
+
+// RLE, palette
+template<typename PTYPE, bool COVER, bool XFLIP, typename Shadow, typename Tinter, typename Blender>
+static void BlitSpriteRLE_internal(SDL_Surface* target,
+ const Uint8* srcdata, const Color* col,
+ int tx, int ty,
+ int width, int height,
+ bool yflip,
+ Region clip,
+ Uint8 transindex,
+ const SpriteCover* cover,
+ const Sprite2D* spr, unsigned int flags,
+ const Shadow& shadow, const Tinter& tint, const Blender& blend, PTYPE /*dummy*/ = 0, MSVCHack<COVER>* /*dummy*/ = 0, MSVCHack<XFLIP>* /*dummy*/ = 0)
+{
+ if (COVER)
+ assert(cover);
+ assert(spr);
+
+ int pitch = target->pitch / target->format->BytesPerPixel;
+ int coverx, covery;
+ if (COVER) {
+ coverx = cover->XPos - spr->XPos;
+ covery = cover->YPos - spr->YPos;
+ }
+
+ // We assume the clipping rectangle is the exact rectangle in which we will
+ // paint. This means clip rect <= sprite rect <= cover rect
+
+ assert(clip.w > 0 && clip.h > 0);
+ assert(clip.x >= tx);
+ assert(clip.y >= ty);
+ assert(clip.x + clip.w <= tx + spr->Width);
+ assert(clip.y + clip.h <= ty + spr->Height);
+
+ if (COVER) {
+ assert(tx >= tx - coverx);
+ assert(ty >= ty - coverx);
+ assert(tx + spr->Width <= tx - coverx + cover->Width);
+ assert(ty + spr->Height <= ty - covery + cover->Height);
+ }
+
+
+ // Clipping strategy:
+ // Because we can't jump to the right spot in the RLE data,
+ // we have to process the full sprite.
+ // We fast-forward through the bits outside of the clipping rectangle.
+
+ // This is done line-by-line.
+ // To avoid having to fast-forward, blit, fast-forward for each line,
+ // we consider the end of each line to be directly behind the clipping
+ // rectangle, so that we only do a single fast-forward loop followed by a
+ // blit loop.
+
+
+ PTYPE *clipstartpix, *clipendpix;
+ PTYPE *clipstartline;
+
+ if (!yflip) {
+ clipstartline = (PTYPE*)target->pixels + clip.y*pitch;
+ } else {
+ clipstartline = (PTYPE*)target->pixels + (clip.y + clip.h - 1)*pitch;
+ }
+
+
+ PTYPE *line, *end, *pix;
+ Uint8 *coverline, *coverpix;
+ if (!yflip) {
+ line = (PTYPE*)target->pixels + ty*pitch;
+ end = (PTYPE*)target->pixels + (clip.y + clip.h)*pitch;
+ if (COVER)
+ coverline = (Uint8*)cover->pixels + covery*cover->Width;
+ } else {
+ line = (PTYPE*)target->pixels + (ty + height-1)*pitch;
+ end = (PTYPE*)target->pixels + (clip.y-1)*pitch;
+ if (COVER)
+ coverline = (Uint8*)cover->pixels + (covery+height-1)*cover->Width;
+ }
+ if (!XFLIP) {
+ pix = line + tx;
+ clipstartpix = line + clip.x;
+ clipendpix = clipstartpix + clip.w;
+ if (COVER)
+ coverpix = coverline + coverx;
+ } else {
+ pix = line + tx + width - 1;
+ clipstartpix = line + clip.x + clip.w - 1;
+ clipendpix = clipstartpix - clip.w;
+ if (COVER)
+ coverpix = coverline + coverx + width - 1;
+ }
+
+ // clipstartpix is the first pixel to draw
+ // clipendpix is one past the last pixel to draw (in either x direction)
+
+ const int yfactor = yflip ? -1 : 1;
+ const int xfactor = XFLIP ? -1 : 1;
+
+ while (line != end) {
+
+ // Fast-forward through the RLE data until we reach clipstartpix
+
+ if (!XFLIP) {
+ while (pix < clipstartpix) {
+ Uint8 p = *srcdata++;
+ int count;
+ if (p == transindex)
+ count = (*srcdata++) + 1;
+ else
+ count = 1;
+ pix += count;
+ if (COVER)
+ coverpix += count;
+ }
+ } else {
+ while (pix > clipstartpix) {
+ Uint8 p = *srcdata++;
+ int count;
+ if (p == transindex)
+ count = (*srcdata++) + 1;
+ else
+ count = 1;
+ pix -= count;
+ if (COVER)
+ coverpix -= count;
+ }
+ }
+
+ // Blit a line, if it's not vertically clipped
+
+ if ((!yflip && pix >= clipstartline) || (yflip && pix < clipstartline+pitch))
+ {
+ while ( (!XFLIP && pix < clipendpix) || (XFLIP && pix > clipendpix) )
+ {
+ Uint8 p = *srcdata++;
+ if (p == transindex) {
+ int count = (int)(*srcdata++) + 1;
+ if (!XFLIP) {
+ pix += count;
+ if (COVER)
+ coverpix += count;
+ } else {
+ pix -= count;
+ if (COVER)
+ coverpix -= count;
+ }
+ } else {
+ if (!COVER || !*coverpix) {
+ int extra_alpha = 0;
+ if (!shadow(*pix, p, extra_alpha, flags)) {
+ Uint8 r = col[p].r;
+ Uint8 g = col[p].g;
+ Uint8 b = col[p].b;
+ Uint8 a = col[p].a;
+ tint(r, g, b, a, flags);
+ blend(*pix, r, g, b, a >> extra_alpha);
+ }
+ }
+#ifdef HIGHLIGHTCOVER
+ else if (COVER) {
+ blend(*pix, 255, 255, 255, 255);
+ }
+#endif
+
+ if (!XFLIP) {
+ pix++;
+ if (COVER) coverpix++;
+ } else {
+ pix--;
+ if (COVER) coverpix--;
+ }
+ }
+ }
+ }
+
+ // We pretend we ended the sprite line here, and move all
+ // pointers to the next line
+
+ line += yfactor * pitch;
+ pix += yfactor * pitch - xfactor * width;
+ if (COVER)
+ coverpix += yfactor * cover->Width - xfactor * width;
+ clipstartpix += yfactor * pitch;
+ clipendpix += yfactor * pitch;
+ }
+
+}
+
+// non-RLE, palette
+template<typename PTYPE, bool COVER, bool XFLIP, typename Shadow, typename Tinter, typename Blender>
+static void BlitSprite_internal(SDL_Surface* target,
+ const Uint8* srcdata, const Color* col,
+ int tx, int ty,
+ int width, int /*height*/,
+ bool yflip,
+ Region clip,
+ int transindex,
+ const SpriteCover* cover,
+ const Sprite2D* spr, unsigned int flags,
+ const Shadow& shadow, const Tinter& tint, const Blender& blend, PTYPE /*dummy*/ = 0, MSVCHack<COVER>* /*dummy*/ = 0, MSVCHack<XFLIP>* /*dummy*/ = 0)
+{
+ if (COVER)
+ assert(cover);
+ assert(spr);
+
+ int pitch = target->pitch / target->format->BytesPerPixel;
+ int coverx, covery;
+ if (COVER) {
+ coverx = cover->XPos - spr->XPos;
+ covery = cover->YPos - spr->YPos;
+ }
+
+ // We assume the clipping rectangle is the exact rectangle in which we will
+ // paint. This means clip rect <= sprite rect <= cover rect
+
+ assert(clip.w > 0 && clip.h > 0);
+ assert(clip.x >= tx);
+ assert(clip.y >= ty);
+ assert(clip.x + clip.w <= tx + spr->Width);
+ assert(clip.y + clip.h <= ty + spr->Height);
+
+ if (COVER) {
+ assert(tx >= tx - coverx);
+ assert(ty >= ty - coverx);
+ assert(tx + spr->Width <= tx - coverx + cover->Width);
+ assert(ty + spr->Height <= ty - covery + cover->Height);
+ }
+
+
+ PTYPE *line, *end;
+ Uint8 *coverpix;
+
+ if (!yflip) {
+ line = (PTYPE*)target->pixels + clip.y*pitch;
+ end = line + clip.h*pitch;
+ srcdata += (clip.y - ty)*spr->Width;
+ if (COVER)
+ coverpix = (Uint8*)cover->pixels + (clip.y - ty + covery)*cover->Width;
+ } else {
+ line = (PTYPE*)target->pixels + (clip.y + clip.h - 1)*pitch;
+ end = line - clip.h*pitch;
+ srcdata += (ty + spr->Height - (clip.y + clip.h))*spr->Width;
+ if (COVER)
+ coverpix = (Uint8*)cover->pixels + (clip.y - ty + clip.h + covery - 1)*cover->Width;
+ }
+
+ PTYPE *pix, *endpix;
+ if (!XFLIP) {
+ pix = line + clip.x;
+ endpix = pix + clip.w;
+ srcdata += clip.x - tx;
+ if (COVER)
+ coverpix += clip.x - tx + coverx;
+ } else {
+ pix = line + clip.x + clip.w - 1;
+ endpix = pix - clip.w;
+ srcdata += tx + spr->Width - (clip.x + clip.w);
+ if (COVER)
+ coverpix += clip.x - tx + clip.w + coverx - 1;
+ }
+
+ const int yfactor = yflip ? -1 : 1;
+ const int xfactor = XFLIP ? -1 : 1;
+
+ while (line != end) {
+ do {
+ Uint8 p = *srcdata++;
+ if ((int)p != transindex) {
+ if (!COVER || !*coverpix) {
+ int extra_alpha = 0;
+ if (!shadow(*pix, p, extra_alpha, flags)) {
+ Uint8 r = col[p].r;
+ Uint8 g = col[p].g;
+ Uint8 b = col[p].b;
+ Uint8 a = col[p].a;
+ tint(r, g, b, a, flags);
+ blend(*pix, r, g, b, a >> extra_alpha);
+ }
+ }
+#ifdef HIGHLIGHTCOVER
+ else if (COVER) {
+ blend(*pix, 255, 255, 255, 255);
+ }
+#endif
+ }
+ if (!XFLIP) {
+ pix++;
+ if (COVER) coverpix++;
+ } else {
+ pix--;
+ if (COVER) coverpix--;
+ }
+ } while (pix != endpix);
+
+ // advance all pointers to the next line
+ pix += yfactor * pitch - xfactor * clip.w;
+ endpix += yfactor * pitch;
+ line += yfactor * pitch;
+ srcdata += (width - clip.w);
+ if (COVER)
+ coverpix += yfactor * cover->Width - xfactor * clip.w;
+ }
+
+}
+
+// non-RLE, 32 bit RGB
+template<typename PTYPE, bool COVER, bool XFLIP, typename Tinter, typename Blender>
+static void BlitSpriteRGB_internal(SDL_Surface* target,
+ const Uint32* srcdata,
+ int tx, int ty,
+ int width, int /*height*/,
+ bool yflip,
+ Region clip,
+ const SpriteCover* cover,
+ const Sprite2D* spr, unsigned int flags,
+ const Tinter& tint, const Blender& blend, PTYPE /*dummy*/ = 0, MSVCHack<COVER>* /*dummy*/ = 0, MSVCHack<XFLIP>* /*dummy*/ = 0)
+{
+ if (COVER)
+ assert(cover);
+ assert(spr);
+
+ int pitch = target->pitch / target->format->BytesPerPixel;
+ int coverx, covery;
+ if (COVER) {
+ coverx = cover->XPos - spr->XPos;
+ covery = cover->YPos - spr->YPos;
+ }
+
+ // We assume the clipping rectangle is the exact rectangle in which we will
+ // paint. This means clip rect <= sprite rect <= cover rect
+
+ assert(clip.w > 0 && clip.h > 0);
+ assert(clip.x >= tx);
+ assert(clip.y >= ty);
+ assert(clip.x + clip.w <= tx + spr->Width);
+ assert(clip.y + clip.h <= ty + spr->Height);
+
+ if (COVER) {
+ assert(tx >= tx - coverx);
+ assert(ty >= ty - coverx);
+ assert(tx + spr->Width <= tx - coverx + cover->Width);
+ assert(ty + spr->Height <= ty - covery + cover->Height);
+ }
+
+
+ PTYPE *line, *end;
+ Uint8 *coverpix;
+
+ if (!yflip) {
+ line = (PTYPE*)target->pixels + clip.y*pitch;
+ end = line + clip.h*pitch;
+ srcdata += (clip.y - ty)*spr->Width;
+ if (COVER)
+ coverpix = (Uint8*)cover->pixels + (clip.y - ty + covery)*cover->Width;
+ } else {
+ line = (PTYPE*)target->pixels + (clip.y + clip.h - 1)*pitch;
+ end = line - clip.h*pitch;
+ srcdata += (ty + spr->Height - (clip.y + clip.h))*spr->Width;
+ if (COVER)
+ coverpix = (Uint8*)cover->pixels + (clip.y - ty + clip.h + covery - 1)*cover->Width;
+ }
+
+ PTYPE *pix, *endpix;
+ if (!XFLIP) {
+ pix = line + clip.x;
+ endpix = pix + clip.w;
+ srcdata += clip.x - tx;
+ if (COVER)
+ coverpix += clip.x - tx + coverx;
+ } else {
+ pix = line + clip.x + clip.w - 1;
+ endpix = pix - clip.w;
+ srcdata += tx + spr->Width - (clip.x + clip.w);
+ if (COVER)
+ coverpix += clip.x - tx + clip.w + coverx - 1;
+ }
+
+ const int yfactor = yflip ? -1 : 1;
+ const int xfactor = XFLIP ? -1 : 1;
+
+ while (line != end) {
+ do {
+ Uint32 p = *srcdata++;
+ Uint8 a = (Uint8)(p >> 24);
+ if (a != 0) {
+ if (!COVER || !*coverpix) {
+ Uint8 r = (Uint8)(p);
+ Uint8 g = (Uint8)(p >> 8);
+ Uint8 b = (Uint8)(p >> 16);
+ tint(r, g, b, a, flags);
+ blend(*pix, r, g, b, a);
+ }
+#ifdef HIGHLIGHTCOVER
+ else if (COVER) {
+ blend(*pix, 255, 255, 255, 255);
+ }
+#endif
+ }
+ if (!XFLIP) {
+ pix++;
+ if (COVER) coverpix++;
+ } else {
+ pix--;
+ if (COVER) coverpix--;
+ }
+ } while (pix != endpix);
+
+ // advance all pointers to the next line
+ pix += yfactor * pitch - xfactor * clip.w;
+ endpix += yfactor * pitch;
+ line += yfactor * pitch;
+ srcdata += (width - clip.w);
+ if (COVER)
+ coverpix += yfactor * cover->Width - xfactor * clip.w;
+ }
+
+}
+
+
+
+// call the BlitSprite{RLE,}_internal instantiation with the specified
+// COVER, XFLIP, RLE bools
+template<typename PTYPE, typename Shadow, typename Tinter, typename Blender>
+static void BlitSpritePAL_dispatch2(bool COVER, bool XFLIP,
+ SDL_Surface* target,
+ const Uint8* srcdata, const Color* col,
+ int tx, int ty,
+ int width, int height,
+ bool yflip,
+ const Region& clip,
+ int transindex,
+ const SpriteCover* cover,
+ const Sprite2D* spr, unsigned int flags,
+ const Shadow& shadow, const Tinter& tint, const Blender& blend, PTYPE /*dummy*/ = 0)
+{
+ bool RLE = false;
+ if (spr->BAM) {
+ Sprite2D_BAM_Internal *data = (Sprite2D_BAM_Internal*)spr->vptr;
+ RLE = data->RLE;
+ } else {
+ // Not BAM -> not RLE.
+ }
+
+ if (!COVER && !XFLIP)
+ if (RLE)
+ BlitSpriteRLE_internal<PTYPE, false, false, Shadow, Tinter, Blender>(target,
+ srcdata, col, tx, ty, width, height, yflip, clip, transindex, cover, spr, flags,
+ shadow, tint, blend);
+ else
+ BlitSprite_internal<PTYPE, false, false, Shadow, Tinter, Blender>(target,
+ srcdata, col, tx, ty, width, height, yflip, clip, transindex, cover, spr, flags,
+ shadow, tint, blend);
+ else if (!COVER && XFLIP)
+ if (RLE)
+ BlitSpriteRLE_internal<PTYPE, false, true, Shadow, Tinter, Blender>(target,
+ srcdata, col, tx, ty, width, height, yflip, clip, transindex, cover, spr, flags,
+ shadow, tint, blend);
+ else
+ BlitSprite_internal<PTYPE, false, true, Shadow, Tinter, Blender>(target,
+ srcdata, col, tx, ty, width, height, yflip, clip, transindex, cover, spr, flags,
+ shadow, tint, blend);
+ else if (COVER && !XFLIP)
+ if (RLE)
+ BlitSpriteRLE_internal<PTYPE, true, false, Shadow, Tinter, Blender>(target,
+ srcdata, col, tx, ty, width, height, yflip, clip, transindex, cover, spr, flags,
+ shadow, tint, blend);
+ else
+ BlitSprite_internal<PTYPE, true, false, Shadow, Tinter, Blender>(target,
+ srcdata, col, tx, ty, width, height, yflip, clip, transindex, cover, spr, flags,
+ shadow, tint, blend);
+ else // if (COVER && XFLIP)
+ if (RLE)
+ BlitSpriteRLE_internal<PTYPE, true, true, Shadow, Tinter, Blender>(target,
+ srcdata, col, tx, ty, width, height, yflip, clip, transindex, cover, spr, flags,
+ shadow, tint, blend);
+ else
+ BlitSprite_internal<PTYPE, true, true, Shadow, Tinter, Blender>(target,
+ srcdata, col, tx, ty, width, height, yflip, clip, transindex, cover, spr, flags,
+ shadow, tint, blend);
+}
+
+// call the BlitSpritePAL_dispatch2 instantiation with the right pixelformat
+// TODO: Hardcoded/non-hardcoded pixelformat
+template<typename Shadow, typename Tinter, typename Blender>
+static void BlitSpritePAL_dispatch(bool COVER, bool XFLIP,
+ SDL_Surface* target,
+ const Uint8* srcdata, const Color* col,
+ int tx, int ty,
+ int width, int height,
+ bool yflip,
+ const Region& clip,
+ int transindex,
+ const SpriteCover* cover,
+ const Sprite2D* spr, unsigned int flags,
+ const Shadow& shadow, const Tinter& tint, const Blender& /*dummy*/)
+{
+ if (target->format->BytesPerPixel == 4) {
+ SRBlender<Uint32, Blender, SRFormat_Hard> blend;
+ BlitSpritePAL_dispatch2<Uint32>(COVER, XFLIP, target, srcdata, col, tx, ty,
+ width, height, yflip, clip, transindex,
+ cover, spr, flags, shadow, tint, blend);
+ } else {
+ SRBlender<Uint16, Blender, SRFormat_Hard> blend;
+ BlitSpritePAL_dispatch2<Uint16>(COVER, XFLIP, target, srcdata, col, tx, ty,
+ width, height, yflip, clip, transindex,
+ cover, spr, flags, shadow, tint, blend);
+ }
+}
+
+// call the BlitSpriteRGB_internal instantiation with the specified
+// COVER, XFLIP bools
+template<typename PTYPE, typename Tinter, typename Blender>
+static void BlitSpriteRGB_dispatch2(bool COVER, bool XFLIP,
+ SDL_Surface* target,
+ const Uint32* srcdata,
+ int tx, int ty,
+ int width, int height,
+ bool yflip,
+ const Region& clip,
+ const SpriteCover* cover,
+ const Sprite2D* spr, unsigned int flags,
+ const Tinter& tint, const Blender& blend, PTYPE /*dummy*/ = 0)
+{
+ if (!COVER && !XFLIP)
+ BlitSpriteRGB_internal<PTYPE, false, false, Tinter, Blender>(target,
+ srcdata, tx, ty, width, height, yflip, clip, cover, spr, flags,
+ tint, blend);
+ else if (!COVER && XFLIP)
+ BlitSpriteRGB_internal<PTYPE, false, true, Tinter, Blender>(target,
+ srcdata, tx, ty, width, height, yflip, clip, cover, spr, flags,
+ tint, blend);
+ else if (COVER && !XFLIP)
+ BlitSpriteRGB_internal<PTYPE, true, false, Tinter, Blender>(target,
+ srcdata, tx, ty, width, height, yflip, clip, cover, spr, flags,
+ tint, blend);
+ else // if (COVER && XFLIP)
+ BlitSpriteRGB_internal<PTYPE, true, true, Tinter, Blender>(target,
+ srcdata, tx, ty, width, height, yflip, clip, cover, spr, flags,
+ tint, blend);
+}
+
+// call the BlitSpriteRGB_dispatch2 instantiation with the right pixelformat
+// TODO: Hardcoded/non-hardcoded pixelformat
+template<typename Tinter, typename Blender>
+static void BlitSpriteRGB_dispatch(bool COVER, bool XFLIP,
+ SDL_Surface* target,
+ const Uint32* srcdata,
+ int tx, int ty,
+ int width, int height,
+ bool yflip,
+ const Region& clip,
+ const SpriteCover* cover,
+ const Sprite2D* spr, unsigned int flags,
+ const Tinter& tint, const Blender& /*dummy*/)
+{
+ if (target->format->BytesPerPixel == 4) {
+ SRBlender<Uint32, Blender, SRFormat_Hard> blend;
+ BlitSpriteRGB_dispatch2<Uint32>(COVER, XFLIP, target, srcdata, tx, ty,
+ width, height, yflip, clip, cover, spr,
+ flags, tint, blend);
+ } else {
+ SRBlender<Uint16, Blender, SRFormat_Hard> blend;
+ BlitSpriteRGB_dispatch2<Uint16>(COVER, XFLIP, target, srcdata, tx, ty,
+ width, height, yflip, clip, cover, spr,
+ flags, tint, blend);
+ }
+}
diff --git a/gemrb/plugins/SDLVideo/TileRenderer.inl b/gemrb/plugins/SDLVideo/TileRenderer.inl
index 21825e0..cc81341 100644
--- a/gemrb/plugins/SDLVideo/TileRenderer.inl
+++ b/gemrb/plugins/SDLVideo/TileRenderer.inl
@@ -18,19 +18,50 @@
*
*/
+namespace {
+using namespace GemRB;
struct TRTinter_NoTint {
- Uint8 r(Uint8 v) const { return v; }
- Uint8 g(Uint8 v) const { return v; }
- Uint8 b(Uint8 v) const { return v; }
+ void operator()(Uint8&, Uint8&, Uint8&) const { }
};
struct TRTinter_Tint {
TRTinter_Tint(const Color& t) : tint(t) { }
- Uint8 r(Uint8 v) const { return (tint.r * v) >> 8; }
- Uint8 g(Uint8 v) const { return (tint.g * v) >> 8; }
- Uint8 b(Uint8 v) const { return (tint.b * v) >> 8; }
+ void operator()(Uint8& vr, Uint8& vg, Uint8& vb) const {
+ vr = (tint.r * vr) >> 8;
+ vg = (tint.g * vg) >> 8;
+ vb = (tint.b * vb) >> 8;
+ }
+
+ Color tint;
+};
+
+struct TRTinter_Grey {
+ TRTinter_Grey(const Color& t) : tint(t) { }
+
+ void operator()(Uint8& vr, Uint8& vg, Uint8& vb) const {
+ vr = (tint.r * vr) >> 10;
+ vg = (tint.g * vg) >> 10;
+ vb = (tint.b * vb) >> 10;
+ Uint8 a = vr + vg + vb;
+ vr = vg = vb = a;
+ }
+
+ Color tint;
+};
+struct TRTinter_Sepia {
+ TRTinter_Sepia(const Color& t) : tint(t) { }
+
+ void operator()(Uint8& vr, Uint8& vg, Uint8& vb) const {
+ vr = (tint.r * vr) >> 10;
+ vg = (tint.g * vg) >> 10;
+ vb = (tint.b * vb) >> 10;
+ Uint8 a = vr + vg + vb;
+ vr = a + 21; // can't overflow, since a is at most 189
+ vg = a;
+ vb = a < 32 ? 0 : a - 32;
+ }
Color tint;
};
@@ -77,9 +108,10 @@ static void BlitTile_internal(SDL_Surface* target,
for (unsigned int i = 0; i < 256; ++i)
{
- Uint8 r = tint.r(pal[i].r);
- Uint8 g = tint.g(pal[i].g);
- Uint8 b = tint.b(pal[i].b);
+ Uint8 r = pal[i].r;
+ Uint8 g = pal[i].g;
+ Uint8 b = pal[i].b;
+ tint(r, g, b);
opal[i] = (r >> target->format->Rloss) << target->format->Rshift
| (g >> target->format->Gloss) << target->format->Gshift
| (b >> target->format->Bloss) << target->format->Bshift;
@@ -120,3 +152,4 @@ static void BlitTile_internal(SDL_Surface* target,
}
}
+}
diff --git a/gemrb/plugins/SPLImporter/SPLImporter.cpp b/gemrb/plugins/SPLImporter/SPLImporter.cpp
index c8c9bfe..2db605e 100644
--- a/gemrb/plugins/SPLImporter/SPLImporter.cpp
+++ b/gemrb/plugins/SPLImporter/SPLImporter.cpp
@@ -24,13 +24,16 @@
#include "EffectMgr.h"
#include "Interface.h"
+#include "PluginMgr.h"
#include "TableMgr.h" //needed for autotable
+using namespace GemRB;
+
int *cgsounds = NULL;
int cgcount = -1;
//cannot call this at the time of initialization because the tablemanager isn't alive yet
-void Initializer()
+static void Initializer()
{
if (cgsounds) {
free(cgsounds);
@@ -39,8 +42,7 @@ void Initializer()
cgcount = 0;
AutoTable tm("cgtable");
if (!tm) {
- printStatus( "ERROR", LIGHT_RED );
- printf( "Cannot find cgtable.2da.\n");
+ Log(ERROR, "SPLImporter", "Cannot find cgtable.2da.");
return;
}
cgcount = tm->GetRowCount();
@@ -50,14 +52,14 @@ void Initializer()
}
}
-void ReleaseMemorySPL()
+static void ReleaseMemorySPL()
{
free(cgsounds);
cgsounds = NULL;
cgcount = -1;
}
-int GetCGSound(ieDword CastingGraphics)
+static int GetCGSound(ieDword CastingGraphics)
{
if (cgcount<0) {
Initializer();
@@ -79,26 +81,20 @@ int GetCGSound(ieDword CastingGraphics)
SPLImporter::SPLImporter(void)
{
str = NULL;
- autoFree = false;
}
SPLImporter::~SPLImporter(void)
{
- if (str && autoFree) {
- delete( str );
- }
+ delete str;
}
-bool SPLImporter::Open(DataStream* stream, bool autoFree)
+bool SPLImporter::Open(DataStream* stream)
{
if (stream == NULL) {
return false;
}
- if (str && this->autoFree) {
- delete( str );
- }
+ delete str;
str = stream;
- this->autoFree = autoFree;
char Signature[8];
str->Read( Signature, 8 );
if (strncmp( Signature, "SPL V1 ", 8 ) == 0) {
@@ -106,7 +102,7 @@ bool SPLImporter::Open(DataStream* stream, bool autoFree)
} else if (strncmp( Signature, "SPL V2.0", 8 ) == 0) {
version = 20;
} else {
- printf( "[SPLImporter]: This file is not a valid SPL File\n" );
+ print("[SPLImporter]: This file is not a valid SPL File");
return false;
}
@@ -200,7 +196,8 @@ void SPLImporter::GetExtHeader(Spell *s, SPLExtHeader* eh)
ieByte tmpByte;
str->Read( &eh->SpellForm, 1 );
- str->Read( &eh->unknown1, 1 );
+ //this byte is used in PST
+ str->Read( &eh->Hostile, 1 );
str->Read( &eh->Location, 1 );
str->Read( &eh->unknown2, 1 );
str->ReadResRef( eh->MemorisedIcon );
diff --git a/gemrb/plugins/SPLImporter/SPLImporter.h b/gemrb/plugins/SPLImporter/SPLImporter.h
index 2b355bb..b24cc6d 100644
--- a/gemrb/plugins/SPLImporter/SPLImporter.h
+++ b/gemrb/plugins/SPLImporter/SPLImporter.h
@@ -27,17 +27,18 @@
#include "Spell.h"
+namespace GemRB {
+
class SPLImporter : public SpellMgr {
private:
DataStream* str;
- bool autoFree;
int version;
public:
SPLImporter(void);
~SPLImporter(void);
- bool Open(DataStream* stream, bool autoFree = true);
+ bool Open(DataStream* stream);
Spell* GetSpell(Spell *spl, bool silent=false);
private:
void GetExtHeader(Spell *s, SPLExtHeader* eh);
@@ -45,4 +46,6 @@ private:
};
+}
+
#endif
diff --git a/gemrb/plugins/STOImporter/STOImporter.cpp b/gemrb/plugins/STOImporter/STOImporter.cpp
index 14dabd0..1b28515 100644
--- a/gemrb/plugins/STOImporter/STOImporter.cpp
+++ b/gemrb/plugins/STOImporter/STOImporter.cpp
@@ -27,29 +27,25 @@
#include "Inventory.h"
#include "GameScript/GameScript.h"
+using namespace GemRB;
+
STOImporter::STOImporter(void)
{
str = NULL;
- autoFree = false;
}
STOImporter::~STOImporter(void)
{
- if (str && autoFree) {
- delete( str );
- }
+ delete str;
}
-bool STOImporter::Open(DataStream* stream, bool autoFree)
+bool STOImporter::Open(DataStream* stream)
{
if (stream == NULL) {
return false;
}
- if (str && this->autoFree) {
- delete( str );
- }
+ delete str;
str = stream;
- this->autoFree = autoFree;
char Signature[8];
str->Read( Signature, 8 );
if (strncmp( Signature, "STORV1.0", 8 ) == 0) {
@@ -62,7 +58,7 @@ bool STOImporter::Open(DataStream* stream, bool autoFree)
//GemRB's internal version with all known fields supported
version = 0;
} else {
- printf( "[STOImporter]: This file is not a valid STO File\n" );
+ print("[STOImporter]: This file is not a valid STO File");
return false;
}
@@ -119,10 +115,20 @@ Store* STOImporter::GetStore(Store *s)
memset( s->unknown3, 0, 80 );
}
- //Allocation must be done in the same place as destruction.
- //Yeah, this is intentionally so ugly, someone who doesn't like this
- //may fix it.
- core->DoTheStoreHack(s);
+ size_t size = s->PurchasedCategoriesCount * sizeof( ieDword );
+ s->purchased_categories=(ieDword *) malloc(size);
+
+ size = s->CuresCount * sizeof( STOCure );
+ s->cures=(STOCure *) malloc(size);
+
+ size = s->DrinksCount * sizeof( STODrink );
+ s->drinks=(STODrink *) malloc(size);
+
+ for(size=0;size<s->ItemsCount;size++) {
+ STOItem *si = new STOItem();
+ memset(si, 0, sizeof(STOItem) );
+ s->items.push_back( si );
+ }
str->Seek( s->PurchasedCategoriesOffset, GEM_STREAM_START );
GetPurchasedCategories( s );
@@ -130,7 +136,7 @@ Store* STOImporter::GetStore(Store *s)
str->Seek( s->ItemsOffset, GEM_STREAM_START );
for (i = 0; i < s->ItemsCount; i++) {
STOItem *item = s->items[i];
- GetItem(item);
+ GetItem(item, s);
//it is important to handle this field as signed
if (item->InfiniteSupply>0) {
char *TriggerCode = core->GetString( (ieStrRef) item->InfiniteSupply );
@@ -156,7 +162,7 @@ Store* STOImporter::GetStore(Store *s)
return s;
}
-void STOImporter::GetItem(STOItem *it)
+void STOImporter::GetItem(STOItem *it, Store *s)
{
core->ReadItem(str, (CREItem *) it);
@@ -166,13 +172,20 @@ void STOImporter::GetItem(STOItem *it)
if (!it->AmountInStock) {
it->AmountInStock = 1;
}
- //another hack-fix
+ // make sure the inventory knows that it needs to update flags+weight
+ it->Weight = -1;
Item *item = gamedata->GetItem( it->ItemResRef );
if (item) {
- if (!item->LoreToID) {
+ it->MaxStackAmount = item->MaxStackAmount;
+ //another hack-fix
+ if (item->LoreToID <= s->Lore) {
it->Flags |= IE_INV_ITEM_IDENTIFIED;
}
gamedata->FreeItem( item, it->ItemResRef, false );
+ //make sure it has at least one charge for proper pricing purposes
+ if (!it->Usages[0]) {
+ it->Usages[0] = 1;
+ }
}
str->ReadDword( (ieDword *) &it->InfiniteSupply );
ieDwordSigned tmp;
@@ -221,24 +234,26 @@ void STOImporter::GetPurchasedCategories(Store* s)
}
//call this before any write, it updates offsets!
-int STOImporter::GetStoredFileSize(Store *s)
+void STOImporter::CalculateStoredFileSize(Store *s)
{
- int headersize, itemsize;
+ int headersize;
+ //int headersize, itemsize;
//header
switch (s->version) {
case 90:
//capacity on a dword and 80 bytes of crap
headersize = 156 + 84;
- itemsize = 28;
+ //itemsize = 28;
break;
case 11:
headersize = 156;
//trigger ref on a dword and 56 bytes of crap
- itemsize = 28 + 60;
+ //itemsize = 28 + 60;
+ break;
default:
headersize = 156;
- itemsize = 28;
+ //itemsize = 28;
break;
}
@@ -256,20 +271,17 @@ int STOImporter::GetStoredFileSize(Store *s)
//items
s->ItemsOffset = headersize;
- headersize += s->ItemsCount * itemsize;
-
- return headersize;
+ //headersize += s->ItemsCount * itemsize;
}
-int STOImporter::PutPurchasedCategories(DataStream *stream, Store* s)
+void STOImporter::PutPurchasedCategories(DataStream *stream, Store* s)
{
for (unsigned int i = 0; i < s->PurchasedCategoriesCount; i++) {
stream->WriteDword( s->purchased_categories+i );
}
- return 0;
}
-int STOImporter::PutHeader(DataStream *stream, Store *s)
+void STOImporter::PutHeader(DataStream *stream, Store *s)
{
char Signature[8];
ieDword tmpDword;
@@ -321,10 +333,9 @@ int STOImporter::PutHeader(DataStream *stream, Store *s)
stream->WriteDword( &tmpDword);
stream->Write( s->unknown3, 80); //writing out original fillers
}
- return 0;
}
-int STOImporter::PutItems(DataStream *stream, Store *store)
+void STOImporter::PutItems(DataStream *stream, Store *store)
{
for (unsigned int ic=0;ic<store->ItemsCount;ic++) {
STOItem *it = store->items[ic];
@@ -344,20 +355,18 @@ int STOImporter::PutItems(DataStream *stream, Store *store)
stream->WriteDword( (ieDword *) &it->InfiniteSupply );
}
}
- return 0;
}
-int STOImporter::PutCures(DataStream *stream, Store *s)
+void STOImporter::PutCures(DataStream *stream, Store *s)
{
for (unsigned int i=0;i<s->CuresCount;i++) {
STOCure *c = s->cures+i;
stream->WriteResRef( c->CureResRef);
stream->WriteDword( &c->Price);
}
- return 0;
}
-int STOImporter::PutDrinks(DataStream *stream, Store *s)
+void STOImporter::PutDrinks(DataStream *stream, Store *s)
{
for (unsigned int i=0;i<s->DrinksCount;i++) {
STODrink *d = s->drinks+i;
@@ -366,41 +375,23 @@ int STOImporter::PutDrinks(DataStream *stream, Store *s)
stream->WriteDword( &d->Price);
stream->WriteDword( &d->Strength);
}
- return 0;
}
//saves the store into a datastream, be it memory or file
-int STOImporter::PutStore(DataStream *stream, Store *store)
+bool STOImporter::PutStore(DataStream *stream, Store *store)
{
- int ret;
-
if (!stream || !store) {
- return -1;
- }
-
- ret = PutHeader( stream, store);
- if (ret) {
- return ret;
- }
-
- ret = PutDrinks( stream, store);
- if (ret) {
- return ret;
- }
-
- ret = PutCures( stream, store);
- if (ret) {
- return ret;
- }
-
- ret = PutPurchasedCategories (stream, store);
- if (ret) {
- return ret;
+ return false;
}
- ret = PutItems( stream, store);
+ CalculateStoredFileSize(store);
+ PutHeader(stream, store);
+ PutDrinks(stream, store);
+ PutCures(stream, store);
+ PutPurchasedCategories(stream, store);
+ PutItems(stream, store);
- return ret;
+ return true;
}
#include "plugindef.h"
diff --git a/gemrb/plugins/STOImporter/STOImporter.h b/gemrb/plugins/STOImporter/STOImporter.h
index c5c2025..d69adaf 100644
--- a/gemrb/plugins/STOImporter/STOImporter.h
+++ b/gemrb/plugins/STOImporter/STOImporter.h
@@ -27,36 +27,39 @@
#include "Store.h"
+namespace GemRB {
+
class STOImporter : public StoreMgr {
private:
DataStream* str;
- bool autoFree;
int version;
public:
STOImporter(void);
~STOImporter(void);
- bool Open(DataStream* stream, bool autoFree = true);
+ bool Open(DataStream* stream);
Store* GetStore(Store *store);
//returns saved size, updates internal offsets before save
- int GetStoredFileSize(Store *st);
+ void CalculateStoredFileSize(Store *st);
//saves file
- int PutStore(DataStream *stream, Store *store);
+ bool PutStore(DataStream *stream, Store *store);
private:
- void GetItem(STOItem *item);
+ void GetItem(STOItem *item, Store* s);
void GetDrink(STODrink *drink);
void GetCure(STOCure *cure);
void GetPurchasedCategories(Store* s);
- int PutItems(DataStream *stream, Store* s);
- int PutDrinks(DataStream *stream, Store* s);
- int PutCures(DataStream *stream, Store* s);
- int PutPurchasedCategories(DataStream *stream, Store* s);
- int PutHeader(DataStream *stream, Store *store);
+ void PutItems(DataStream *stream, Store* s);
+ void PutDrinks(DataStream *stream, Store* s);
+ void PutCures(DataStream *stream, Store* s);
+ void PutPurchasedCategories(DataStream *stream, Store* s);
+ void PutHeader(DataStream *stream, Store *store);
};
+}
+
#endif
diff --git a/gemrb/plugins/TISImporter/TISImporter.cpp b/gemrb/plugins/TISImporter/TISImporter.cpp
index 3a5cb19..9ed8dac 100644
--- a/gemrb/plugins/TISImporter/TISImporter.cpp
+++ b/gemrb/plugins/TISImporter/TISImporter.cpp
@@ -24,37 +24,34 @@
#include "win32def.h"
#include "Interface.h"
+#include "Sprite2D.h"
#include "Video.h"
+using namespace GemRB;
+
TISImporter::TISImporter(void)
{
str = NULL;
- autoFree = false;
}
TISImporter::~TISImporter(void)
{
- if (str && autoFree) {
- delete( str );
- }
+ delete str;
}
-bool TISImporter::Open(DataStream* stream, bool autoFree)
+bool TISImporter::Open(DataStream* stream)
{
if (stream == NULL) {
return false;
}
- if (str && this->autoFree) {
- delete( str );
- }
+ delete str;
str = stream;
- this->autoFree = autoFree;
char Signature[8];
str->Read( Signature, 8 );
headerShift = 0;
if (Signature[0] == 'T' && Signature[1] == 'I' && Signature[2] == 'S') {
if (strncmp( Signature, "TIS V1 ", 8 ) != 0) {
- printf( "[TISImporter]: Not a Valid TIS File.\n" );
+ print("[TISImporter]: Not a Valid TIS File.");
return false;
}
str->ReadDword( &TilesCount );
@@ -71,15 +68,15 @@ Tile* TISImporter::GetTile(unsigned short* indexes, int count,
unsigned short* secondary)
{
Animation* ani = new Animation( count );
- ani->x = ani->y = 0;
//pause key stops animation
ani->gameAnimation = true;
+ //the turning crystal in ar3202 (bg1) requires animations to be synced
+ ani->pos = 0;
for (int i = 0; i < count; i++) {
ani->AddFrame( GetTile( indexes[i] ), i );
}
if (secondary) {
Animation* sec = new Animation( count );
- sec->x = sec->y = 0;
for (int i = 0; i < count; i++) {
sec->AddFrame( GetTile( secondary[i] ), i );
}
@@ -98,11 +95,11 @@ Sprite2D* TISImporter::GetTile(int index)
// try to only report error once per file
static TISImporter *last_corrupt = NULL;
if (last_corrupt != this) {
- /*printf("Invalid tile index: %d\n",index);
- printf("FileSize: %ld\n", str->Size() );
- printf("Position: %ld\n", pos);
- printf("Shift: %d\n", headerShift);*/
- printf("Corrupt WED file encountered; couldn't find any more tiles at tile %d\n", index);
+ /*print("Invalid tile index: %d", index);
+ print("FileSize: %ld", str->Size());
+ print("Position: %ld", pos);
+ print("Shift: %d", headerShift);*/
+ print("Corrupt WED file encountered; couldn't find any more tiles at tile %d", index);
last_corrupt = this;
}
@@ -125,7 +122,7 @@ Sprite2D* TISImporter::GetTile(int index)
Palette[i].a = RevCol[i].a;
if (Palette[i].g==255 && !Palette[i].r && !Palette[i].b) {
if (transparent) {
- printMessage( "TISImporter", "Tile has two green (transparent) palette entries\n", LIGHT_RED );
+ Log(ERROR, "TISImporter", "Tile has two green (transparent) palette entries");
} else {
transparent = true;
transindex = i;
diff --git a/gemrb/plugins/TISImporter/TISImporter.h b/gemrb/plugins/TISImporter/TISImporter.h
index 0c049d9..de600ff 100644
--- a/gemrb/plugins/TISImporter/TISImporter.h
+++ b/gemrb/plugins/TISImporter/TISImporter.h
@@ -23,20 +23,23 @@
#include "TileSetMgr.h"
+namespace GemRB {
+
class TISImporter : public TileSetMgr {
private:
DataStream* str;
- bool autoFree;
ieDword headerShift;
ieDword TilesCount, TilesSectionLen, TileSize;
public:
TISImporter(void);
~TISImporter(void);
- bool Open(DataStream* stream, bool autoFree = true);
+ bool Open(DataStream* stream);
Tile* GetTile(unsigned short* indexes, int count,
unsigned short* secondary = NULL);
Sprite2D* GetTile(int index);
public:
};
+}
+
#endif
diff --git a/gemrb/plugins/TLKImporter/TLKImporter.cpp b/gemrb/plugins/TLKImporter/TLKImporter.cpp
index ed5732f..b5a31fe 100644
--- a/gemrb/plugins/TLKImporter/TLKImporter.cpp
+++ b/gemrb/plugins/TLKImporter/TLKImporter.cpp
@@ -27,7 +27,11 @@
#include "DialogHandler.h"
#include "Game.h"
#include "Interface.h"
+#include "TableMgr.h"
#include "GUI/GameControl.h"
+#include "Scriptable/Actor.h"
+
+using namespace GemRB;
//set this to -1 if charname is gabber (iwd2)
static int charname=0;
@@ -53,7 +57,6 @@ TLKImporter::TLKImporter(void)
}
str = NULL;
override = NULL;
- autoFree = false;
AutoTable tm("gender");
if (tm) {
@@ -73,17 +76,14 @@ TLKImporter::TLKImporter(void)
}
}
-void ReleaseGtEntry(void *poi)
+static void ReleaseGtEntry(void *poi)
{
delete (gt_type *) poi;
}
TLKImporter::~TLKImporter(void)
{
- if (str && autoFree) {
- delete( str );
- }
-
+ delete str;
gtmap.RemoveAll(ReleaseGtEntry);
@@ -105,25 +105,22 @@ void TLKImporter::OpenAux()
if (override) {
if (!override->Init()) {
CloseAux();
- printMessage("TlkImporter","Cannot open tlk override!\n", LIGHT_RED);
+ Log(ERROR, "TlkImporter", "Cannot open tlk override!");
}
}
}
-bool TLKImporter::Open(DataStream* stream, bool autoFree)
+bool TLKImporter::Open(DataStream* stream)
{
if (stream == NULL) {
return false;
}
- if (str && this->autoFree) {
- delete( str );
- }
+ delete str;
str = stream;
- this->autoFree = autoFree;
char Signature[8];
str->Read( Signature, 8 );
if (strncmp( Signature, "TLK\x20V1\x20\x20", 8 ) != 0) {
- printMessage( "TLKImporter","Not a valid TLK File.\n", LIGHT_RED );
+ Log(ERROR, "TLKImporter", "Not a valid TLK File.");
return false;
}
str->Seek( 2, GEM_CURRENT_POS );
@@ -132,21 +129,24 @@ bool TLKImporter::Open(DataStream* stream, bool autoFree)
return true;
}
-inline char* mystrncpy(char* dest, const char* source, int maxlength,
+//when copying the token, skip spaces
+inline const char* mystrncpy(char* dest, const char* source, int maxlength,
char delim)
{
while (*source && ( *source != delim ) && maxlength--) {
- *dest++ = *source++;
+ char chr = *source++;
+ if (chr!=' ') *dest++ = chr;
+ //*dest++ = *source++;
}
*dest = 0;
- return dest;
+ return source;
}
/* -1 - GABBER
0 - PROTAGONIST
1-9 - PLAYERx
*/
-inline Actor *GetActorFromSlot(int slot)
+static inline Actor *GetActorFromSlot(int slot)
{
if (slot==-1) {
GameControl *gc = core->GetGameControl();
@@ -187,6 +187,26 @@ char *TLKImporter::CharName(int slot)
return override->CS("?");
}
+int TLKImporter::ClassStrRef(int slot)
+{
+ Actor *act;
+ int clss;
+
+ act=GetActorFromSlot(slot);
+ if (act) {
+ clss=act->GetStat(IE_CLASS);
+ } else {
+ clss=0;
+ }
+
+ AutoTable tab("classes");
+ if (!tab) {
+ return -1;
+ }
+ int row = tab->FindTableValue("ID", clss, 0);
+ return atoi(tab->QueryField(row,0) );
+}
+
int TLKImporter::RaceStrRef(int slot)
{
Actor *act;
@@ -223,7 +243,7 @@ int TLKImporter::BuiltinToken(char* Token, char* dest)
{
char* Decoded = NULL;
int TokenLength; //decoded token length
- gt_type *entry;
+ gt_type *entry = NULL;
//these are gender specific tokens, they are customisable by gender.2da
if (gtmap.Lookup(Token, (void *&) entry) ) {
@@ -245,6 +265,14 @@ int TLKImporter::BuiltinToken(char* Token, char* dest)
Decoded = GetString( 10174, 0 );
goto exit_function;
}
+ if (!strcmp( Token, "CLASS" )) {
+ //allow this to be used by direct setting of the token
+ int strref = ClassStrRef(-1);
+ if (strref<=0) return -1;
+ Decoded = GetString( strref, 0);
+ goto exit_function;
+ }
+
if (!strcmp( Token, "RACE" )) {
Decoded = GetString( RaceStrRef(-1), 0);
goto exit_function;
@@ -262,6 +290,10 @@ int TLKImporter::BuiltinToken(char* Token, char* dest)
Decoded = CharName(charname);
goto exit_function;
}
+ if (!strcmp( Token, "PRO_CLASS" )) {
+ Decoded = GetString( ClassStrRef(0), 0);
+ goto exit_function;
+ }
if (!strcmp( Token, "PRO_RACE" )) {
Decoded = GetString( RaceStrRef(0), 0);
goto exit_function;
@@ -301,7 +333,7 @@ bool TLKImporter::ResolveTags(char* dest, char* source, int Length)
NewLength = 0;
for (int i = 0; source[i]; i++) {
if (source[i] == '<') {
- i += (int) (mystrncpy( Token, source + i + 1, MAX_VARIABLE_LENGTH, '>' ) - Token) + 1;
+ i = (int) (mystrncpy( Token, source + i + 1, MAX_VARIABLE_LENGTH, '>' ) - source);
int TokenLength = BuiltinToken( Token, dest + NewLength );
if (TokenLength == -1) {
TokenLength = core->GetTokenDictionary()->GetValueLength( Token );
@@ -341,7 +373,7 @@ bool TLKImporter::GetNewStringLength(char* string, int& Length)
if (string[i] == '<') {
// token
lChange = true;
- i += (int) (mystrncpy( Token, string + i + 1, MAX_VARIABLE_LENGTH, '>' ) - Token) + 1;
+ i = (int) (mystrncpy( Token, string + i + 1, MAX_VARIABLE_LENGTH, '>' ) - string);
int TokenLength = BuiltinToken( Token, NULL );
if (TokenLength == -1) {
NewLength += core->GetTokenDictionary()->GetValueLength( Token );
@@ -369,7 +401,7 @@ bool TLKImporter::GetNewStringLength(char* string, int& Length)
ieStrRef TLKImporter::UpdateString(ieStrRef strref, const char *newvalue)
{
if (!override) {
- printMessage("TLKImporter", "Custom string is not supported by this game format.\n", LIGHT_RED);
+ Log(ERROR, "TLKImporter", "Custom string is not supported by this game format.");
return 0xffffffff;
}
@@ -377,7 +409,7 @@ ieStrRef TLKImporter::UpdateString(ieStrRef strref, const char *newvalue)
return override->UpdateString(strref, newvalue);
}
- printMessage("TLKImporter", "Cannot set custom string.\n", LIGHT_RED);
+ Log(ERROR, "TLKImporter", "Cannot set custom string.");
return 0xffffffff;
}
@@ -443,7 +475,7 @@ empty:
if (SoundResRef[0] != 0) {
int xpos = 0;
int ypos = 0;
- unsigned int flag = GEM_SND_RELATIVE | (flags&GEM_SND_SPEECH);
+ unsigned int flag = GEM_SND_RELATIVE | (flags&(GEM_SND_SPEECH|GEM_SND_QUEUE));
//IE_STR_SPEECH will stop the previous sound source
core->GetAudioDrv()->Play( SoundResRef, xpos, ypos, flag);
}
diff --git a/gemrb/plugins/TLKImporter/TLKImporter.h b/gemrb/plugins/TLKImporter/TLKImporter.h
index c2a03e0..9996025 100644
--- a/gemrb/plugins/TLKImporter/TLKImporter.h
+++ b/gemrb/plugins/TLKImporter/TLKImporter.h
@@ -25,10 +25,11 @@
#include "TlkOverride.h"
+namespace GemRB {
+
class TLKImporter : public StringMgr {
private:
DataStream* str;
- bool autoFree;
//Data
ieDword StrRefCount, Offset;
@@ -41,7 +42,7 @@ public:
void OpenAux();
/** purge string defs coming from saved game */
void CloseAux();
- bool Open(DataStream* stream, bool autoFree = true);
+ bool Open(DataStream* stream);
/** construct a new custom string */
ieStrRef UpdateString(ieStrRef strref, const char *newvalue);
/** resolve a string reference */
@@ -59,10 +60,13 @@ private:
/**returns the decoded length of the built-in token
if dest is not NULL it also returns the decoded value */
int BuiltinToken(char* Token, char* dest);
+ int ClassStrRef(int slot);
int RaceStrRef(int slot);
int GenderStrRef(int slot, int malestrref, int femalestrref);
char *Gabber();
char *CharName(int slot);
};
+}
+
#endif
diff --git a/gemrb/plugins/TLKImporter/TlkOverride.cpp b/gemrb/plugins/TLKImporter/TlkOverride.cpp
index 74a1498..164ef94 100644
--- a/gemrb/plugins/TLKImporter/TlkOverride.cpp
+++ b/gemrb/plugins/TLKImporter/TlkOverride.cpp
@@ -25,6 +25,8 @@
#include <cstdio>
#include <cassert>
+using namespace GemRB;
+
CTlkOverride::CTlkOverride()
{
tot_str=NULL;
@@ -63,18 +65,13 @@ bool CTlkOverride::Init()
memset(Signature,0,8);
toh_str->Read( Signature, 4 );
if (strncmp( Signature, "TLK ", 4 ) != 0) {
- printMessage("TLKImporter", "Not a valid TOH file.\n", LIGHT_RED);
+ Log(ERROR, "TLKImporter", "Not a valid TOH file.");
return false;
}
toh_str->Seek( 8, GEM_CURRENT_POS );
toh_str->ReadDword( &AuxCount );
tot_str->ReadDword( &FreeOffset );
- tot_str->Read(Signature,4);
- if (strncmp( Signature, "\xff\xff\xff\xff",4) !=0) {
- printMessage("TLKImporter", "Not a valid TOT file.\n", LIGHT_RED);
- return false;
- }
return true;
}
@@ -307,7 +304,7 @@ DataStream* CTlkOverride::GetAuxHdr(bool create)
PathJoin( nPath, core->CachePath, "default.toh", NULL );
FileStream* fs = new FileStream();
retry:
- if (fs->Modify( nPath, true )) {
+ if (fs->Modify(nPath)) {
return fs;
}
if (create) {
@@ -328,7 +325,7 @@ DataStream* CTlkOverride::GetAuxTlk(bool create)
PathJoin( nPath, core->CachePath, "default.tot", NULL );
FileStream* fs = new FileStream();
retry:
- if (fs->Modify( nPath, true )) {
+ if (fs->Modify(nPath)) {
return fs;
}
if (create) {
diff --git a/gemrb/plugins/TLKImporter/TlkOverride.h b/gemrb/plugins/TLKImporter/TlkOverride.h
index a8b3a25..bc14d54 100644
--- a/gemrb/plugins/TLKImporter/TlkOverride.h
+++ b/gemrb/plugins/TLKImporter/TlkOverride.h
@@ -35,6 +35,8 @@
typedef std::map<ieStrRef, char *> StringMapType;
#endif
+namespace GemRB {
+
#define STRREF_START 300000
#define SEGMENT_SIZE 512
#define TOH_HEADER_SIZE 20
@@ -80,4 +82,6 @@ public:
};
#endif //TLKOVERRIDE_H
+}
+
diff --git a/gemrb/plugins/TTFImporter/CMakeLists.txt b/gemrb/plugins/TTFImporter/CMakeLists.txt
new file mode 100644
index 0000000..1a93c51
--- /dev/null
+++ b/gemrb/plugins/TTFImporter/CMakeLists.txt
@@ -0,0 +1,12 @@
+IF (FREETYPE_LIBRARY)
+ INCLUDE_DIRECTORIES( ${FREETYPE_INCLUDE_DIRS})
+ IF (ICONV_LIBRARY)
+ INCLUDE_DIRECTORIES( ${ICONV_INCLUDE_DIR} )
+ ENDIF (ICONV_LIBRARY)
+
+ ADD_GEMRB_PLUGIN (TTFImporter TTFFontManager.cpp TTFFont.cpp Freetype.cpp)
+ TARGET_LINK_LIBRARIES( TTFImporter ${FREETYPE_LIBRARY} )
+ IF (ICONV_LIBRARY)
+ TARGET_LINK_LIBRARIES( TTFImporter ${ICONV_LIBRARY} )
+ ENDIF (ICONV_LIBRARY)
+ENDIF (FREETYPE_LIBRARY)
diff --git a/gemrb/plugins/TTFImporter/Freetype.cpp b/gemrb/plugins/TTFImporter/Freetype.cpp
new file mode 100644
index 0000000..e91518c
--- /dev/null
+++ b/gemrb/plugins/TTFImporter/Freetype.cpp
@@ -0,0 +1,55 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "Freetype.h"
+#include "System/Logging.h"
+
+namespace GemRB {
+
+void LogFTError(FT_Error errCode)
+{
+#undef __FTERRORS_H__
+#define FT_ERRORDEF( e, v, s ) { e, s },
+#define FT_ERROR_START_LIST {
+#define FT_ERROR_END_LIST { 0, 0 } };
+
+ static const struct
+ {
+ int err_code;
+ const char* err_msg;
+ } ft_errors[] =
+#include FT_ERRORS_H
+ int i;
+ const char *err_msg;
+
+ err_msg = NULL;
+ for ( i=0; i < (int)((sizeof ft_errors)/(sizeof ft_errors[0])); ++i ) {
+ if ( errCode == ft_errors[i].err_code ) {
+ err_msg = ft_errors[i].err_msg;
+ break;
+ }
+ }
+ if ( !err_msg ) {
+ err_msg = "unknown FreeType error";
+ }
+ Log(ERROR, "FreeType", "%s", err_msg);
+}
+
+}
diff --git a/gemrb/plugins/TTFImporter/Freetype.h b/gemrb/plugins/TTFImporter/Freetype.h
new file mode 100644
index 0000000..01b40a1
--- /dev/null
+++ b/gemrb/plugins/TTFImporter/Freetype.h
@@ -0,0 +1,55 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef __GemRB__Freetype__
+#define __GemRB__Freetype__
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_GLYPH_H
+
+/**
+ * This macro turns the version numbers into a numeric value:
+ * \verbatim
+ (1,2,3) -> (1203)
+ \endverbatim
+ *
+ * This assumes that there will never be more than 100 patchlevels.
+ */
+#define FREETYPE_VERSIONNUM(X, Y, Z) \
+((X)*1000 + (Y)*100 + (Z))
+
+/**
+ * This is the version number macro for the current Freetype version.
+ */
+#define FREETYPE_COMPILEDVERSION \
+FREETYPE_VERSIONNUM(FREETYPE_MAJOR, FREETYPE_MINOR, FREETYPE_PATCH)
+
+/**
+ * This macro will evaluate to true if compiled with Freetype at least X.Y.Z.
+ */
+#define FREETYPE_VERSION_ATLEAST(X, Y, Z) \
+(FREETYPE_COMPILEDVERSION >= FREETYPE_VERSIONNUM(X, Y, Z))
+
+namespace GemRB {
+ void LogFTError(FT_Error errCode);
+}
+
+#endif /* defined(__GemRB__Freetype__) */
diff --git a/gemrb/plugins/TTFImporter/Makefile.am b/gemrb/plugins/TTFImporter/Makefile.am
new file mode 100644
index 0000000..7f69eb9
--- /dev/null
+++ b/gemrb/plugins/TTFImporter/Makefile.am
@@ -0,0 +1,9 @@
+## uncomment these lines to build TTFImporter
+## our build slave doesn't have SDL_TTF
+## in the near future SDL_TTF will be unneeded
+
+#plugin_LTLIBRARIES = TTFImporter.la
+#INCLUDES = $(SDL_CFLAGS)
+#TTFImporter_la_LDFLAGS = -module -avoid-version -shared
+#TTFImporter_la_LIBADD = @SDL_LIBS@
+#TTFImporter_la_SOURCES = TTFFontManager.cpp TTFFontManager.h
diff --git a/gemrb/plugins/TTFImporter/TTFFont.cpp b/gemrb/plugins/TTFImporter/TTFFont.cpp
new file mode 100644
index 0000000..1852131
--- /dev/null
+++ b/gemrb/plugins/TTFImporter/TTFFont.cpp
@@ -0,0 +1,287 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "TTFFont.h"
+#include "Interface.h"
+#include "Sprite2D.h"
+#include "Video.h"
+
+#define uint8_t unsigned char
+
+#if HAVE_ICONV
+#include <iconv.h>
+#include <errno.h>
+#endif
+
+/* Handy routines for converting from fixed point */
+#define FT_FLOOR(X) ((X & -64) / 64)
+#define FT_CEIL(X) (((X + 63) & -64) / 64)
+
+namespace GemRB {
+
+const Sprite2D* TTFFont::GetCharSprite(ieWord chr) const
+{
+#if HAVE_ICONV
+ char* oldchar = (char*)&chr;
+ ieWord unicodeChr = 0;
+ char* newchar = (char*)&unicodeChr;
+ size_t in = (multibyte) ? 2 : 1, out = 2;
+
+ // TODO: make this work on BE systems
+ // TODO: maybe we want to work witn non-unicode fonts?
+ iconv_t cd = iconv_open("UTF-16LE", core->TLKEncoding.c_str());
+#if __FreeBSD__
+ int ret = iconv(cd, (const char **)&oldchar, &in, &newchar, &out);
+#else
+ int ret = iconv(cd, &oldchar, &in, &newchar, &out);
+#endif
+ if (ret != GEM_OK) {
+ Log(ERROR, "FONT", "iconv error: %d", errno);
+ }
+ iconv_close(cd);
+ chr = unicodeChr;
+#endif
+ const Holder<Sprite2D>* sprCache = glyphCache->get(chr);
+ if (sprCache) {
+ // found in cache
+ return sprCache->get();
+ }
+
+ // generate glyph
+
+ // TODO: fix the font styles!
+ FT_Error error = 0;
+ FT_UInt index = FT_Get_Char_Index(face, chr);
+ if (!index) {
+ return blank;
+ }
+
+ int maxx, yoffset;
+ error = FT_Load_Glyph( face, index, FT_LOAD_DEFAULT | FT_LOAD_TARGET_MONO);
+ if( error ) {
+ LogFTError(error);
+ return blank;
+ }
+
+ FT_GlyphSlot glyph = face->glyph;
+ FT_Glyph_Metrics* metrics = &glyph->metrics;
+
+ /* Get the glyph metrics if desired */
+ if ( FT_IS_SCALABLE( face ) ) {
+ /* Get the bounding box */
+ maxx = FT_FLOOR(metrics->horiBearingX) + FT_CEIL(metrics->width);
+ yoffset = ascent - FT_FLOOR(metrics->horiBearingY);
+ } else {
+ /* Get the bounding box for non-scalable format.
+ * Again, freetype2 fills in many of the font metrics
+ * with the value of 0, so some of the values we
+ * need must be calculated differently with certain
+ * assumptions about non-scalable formats.
+ * */
+ maxx = FT_FLOOR(metrics->horiBearingX) + FT_CEIL(metrics->horiAdvance);
+ yoffset = 0;
+ }
+
+ // TODO: handle styles for fonts that dont do it themselves
+
+ /*
+ FIXME: maxx is currently unused.
+ glyph spacing is non existant right now
+ font styles are non functional too
+ */
+
+ FT_Bitmap* bitmap;
+ uint8_t* pixels = NULL;
+
+ /* Render the glyph */
+ error = FT_Render_Glyph( glyph, ft_render_mode_normal );
+ if( error ) {
+ LogFTError(error);
+ return blank;
+ }
+
+ bitmap = &glyph->bitmap;
+
+ int sprHeight = bitmap->rows;
+ int sprWidth = bitmap->width;
+
+ /* Ensure the width of the pixmap is correct. On some cases,
+ * freetype may report a larger pixmap than possible.*/
+ if (sprWidth > maxx) {
+ sprWidth = maxx;
+ }
+
+ if (sprWidth == 0 || sprHeight == 0) {
+ return blank;
+ }
+
+ // we need 1px empty space on each side
+ sprWidth += 2;
+
+ pixels = (uint8_t*)malloc(sprWidth * sprHeight);
+ uint8_t* dest = pixels;
+ uint8_t* src = bitmap->buffer;
+
+ for( int row = 0; row < sprHeight; row++ ) {
+ // TODO: handle italics. we will need to offset the row by font->glyph_italics * row i think.
+
+ // add 1px left padding
+ memset(dest++, 0, 1);
+ // -2 to account for padding
+ memcpy(dest, src, sprWidth - 2);
+ dest += sprWidth - 2;
+ src += bitmap->pitch;
+ // add 1px right padding
+ memset(dest++, 0, 1);
+ }
+ // assert that we fill the buffer exactly
+ assert((dest - pixels) == (sprWidth * sprHeight));
+
+ // TODO: do an underline if requested
+
+ Sprite2D* spr = core->GetVideoDriver()->CreateSprite8(sprWidth, sprHeight, 8, pixels, palette, true, 0);
+ // for some reason BAM fonts are all based of a YPos of 13
+ spr->YPos = 13 - yoffset;
+ // cache the glyph
+ glyphCache->set(chr, spr);
+ spr->release(); // retained by the cache holder
+ return spr;
+}
+
+int TTFFont::GetKerningOffset(ieWord leftChr, ieWord rightChr) const
+{
+ FT_UInt leftIndex = FT_Get_Char_Index(face, leftChr);
+ FT_UInt rightIndex = FT_Get_Char_Index(face, rightChr);
+ FT_Vector kerning = {0,0};
+ // FT_KERNING_DEFAULT is "grid fitted". we will end up with a scaled multiple of 64
+ FT_Error error = FT_Get_Kerning(face, leftIndex, rightIndex, FT_KERNING_DEFAULT, &kerning);
+ if (error) {
+ LogFTError(error);
+ return 0;
+ }
+ // kerning is in 26.6 format. basically divide by 64 to get the number of pixels.
+ return -kerning.x / 64;
+}
+
+TTFFont::TTFFont(FT_Face face, ieWord ptSize, FontStyle style, Palette* pal)
+ : style(style), ptSize(ptSize), face(face)
+{
+ glyphCache = new HashMap<ieWord, Holder<Sprite2D> >();
+ glyphCache->init(256, 128);
+
+// on FT < 2.4.2 the manager will difer ownership to this object
+#if FREETYPE_VERSION_ATLEAST(2,4,2)
+ FT_Reference_Face(face); // retain the face or the font manager will destroy it
+#endif
+ FT_Error error = 0;
+
+ /* Make sure that our font face is scalable (global metrics) */
+ if ( FT_IS_SCALABLE(face) ) {
+ FT_Fixed scale;
+ /* Set the character size and use default DPI (72) */
+ error = FT_Set_Char_Size( face, 0, ptSize * 64, 0, 0 );
+ if( error ) {
+ LogFTError(error);
+ } else {
+ /* Get the scalable font metrics for this font */
+ scale = face->size->metrics.y_scale;
+ ascent = FT_CEIL(FT_MulFix(face->ascender, scale));
+ descent = FT_CEIL(FT_MulFix(face->descender, scale));
+ maxHeight = ascent - descent + 1;
+ //font->lineskip = FT_CEIL(FT_MulFix(face->height, scale));
+ //font->underline_offset = FT_FLOOR(FT_MulFix(face->underline_position, scale));
+ //font->underline_height = FT_FLOOR(FT_MulFix(face->underline_thickness, scale));
+ }
+ } else {
+ /* Non-scalable font case. ptsize determines which family
+ * or series of fonts to grab from the non-scalable format.
+ * It is not the point size of the font.
+ * */
+ if ( ptSize >= face->num_fixed_sizes )
+ ptSize = face->num_fixed_sizes - 1;
+
+ error = FT_Set_Pixel_Sizes( face,
+ face->available_sizes[ptSize].height,
+ face->available_sizes[ptSize].width );
+
+ if (error) {
+ LogFTError(error);
+ }
+ /* With non-scalale fonts, Freetype2 likes to fill many of the
+ * font metrics with the value of 0. The size of the
+ * non-scalable fonts must be determined differently
+ * or sometimes cannot be determined.
+ * */
+ ascent = face->available_sizes[ptSize].height;
+ descent = 0;
+ maxHeight = face->available_sizes[ptSize].height;
+ //font->lineskip = FT_CEIL(font->ascent);
+ //font->underline_offset = FT_FLOOR(face->underline_position);
+ //font->underline_height = FT_FLOOR(face->underline_thickness);
+ }
+
+ /*
+ if ( font->underline_height < 1 ) {
+ font->underline_height = 1;
+ }
+ */
+
+ // Initialize the font face style
+ // currently gemrb has exclusive styles...
+ // TODO: make styles ORable
+ style = NORMAL;
+ if ( face->style_flags & FT_STYLE_FLAG_ITALIC ) {
+ style = ITALIC;
+ }
+ if ( face->style_flags & FT_STYLE_FLAG_BOLD ) {
+ // bold overrides italic
+ // TODO: allow bold and italic together
+ style = BOLD;
+ }
+
+ glyph_overhang = face->size->metrics.y_ppem / 10;
+ /* x offset = cos(((90.0-12)/360)*2*M_PI), or 12 degree angle */
+ glyph_italics = 0.207f;
+ glyph_italics *= height;
+
+ SetPalette(pal);
+
+ // TODO: ttf fonts have a "box" glyph they use for this
+ blank = core->GetVideoDriver()->CreateSprite8(0, 0, 8, NULL, palette->col);
+ // ttf fonts dont produce glyphs for whitespace
+ Sprite2D* space = core->GetVideoDriver()->CreateSprite8((int)(ptSize * 0.25), 0, 8, NULL, palette->col);;
+ Sprite2D* tab = core->GetVideoDriver()->CreateSprite8((space->Width)*4, 0, 8, NULL, palette->col);
+
+ // now cache these glyphs for quick access
+ // WARNING: if we ever did something to purge the cache these would be lost
+ glyphCache->set(' ', space);
+ glyphCache->set('\t', tab);
+ // retained by the cache
+ space->release();
+ tab->release();
+}
+
+TTFFont::~TTFFont()
+{
+ FT_Done_Face(face);
+ delete glyphCache;
+}
+
+}
diff --git a/gemrb/plugins/TTFImporter/TTFFont.h b/gemrb/plugins/TTFImporter/TTFFont.h
new file mode 100644
index 0000000..07b10af
--- /dev/null
+++ b/gemrb/plugins/TTFImporter/TTFFont.h
@@ -0,0 +1,62 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef __GemRB__TTFFont__
+#define __GemRB__TTFFont__
+
+#include "Font.h"
+#include "Freetype.h"
+#include "HashMap.h"
+#include "Holder.h"
+
+namespace GemRB {
+class Sprite2D;
+
+class TTFFont : public Font
+{
+private:
+ HashMap<ieWord, Holder<Sprite2D> >* glyphCache;
+
+ FontStyle style;
+ ieWord ptSize;
+
+ FT_Face face;
+ int height;
+ int ascent;
+ int descent;
+
+ int glyph_overhang;
+ float glyph_italics;
+
+protected:
+ int GetKerningOffset(ieWord leftChr, ieWord rightChr) const;
+public:
+ TTFFont(FT_Face face, ieWord ptSize, FontStyle style, Palette* pal);
+ ~TTFFont(void);
+
+ const Sprite2D* GetCharSprite(ieWord chr) const;
+
+ ieWord GetPointSize() const {return ptSize;};
+ FontStyle GetStyle() const {return style;};
+};
+
+}
+
+#endif /* defined(__GemRB__TTFFont__) */
diff --git a/gemrb/plugins/TTFImporter/TTFFontManager.cpp b/gemrb/plugins/TTFImporter/TTFFontManager.cpp
new file mode 100644
index 0000000..211ba28
--- /dev/null
+++ b/gemrb/plugins/TTFImporter/TTFFontManager.cpp
@@ -0,0 +1,135 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "Interface.h"
+#include "Palette.h"
+#include "TTFFont.h"
+#include "TTFFontManager.h"
+
+using namespace GemRB;
+
+FT_Library library = NULL;
+
+void loadFT()
+{
+ FT_Error error = FT_Init_FreeType( &library );
+ if ( error ) {
+ LogFTError(error);
+ }
+}
+
+void destroyFT()
+{
+ if (library) {
+ FT_Done_FreeType( library );
+ }
+}
+
+unsigned long TTFFontManager::read(FT_Stream stream,
+ unsigned long offset,
+ unsigned char* buffer,
+ unsigned long count )
+{
+ DataStream* dstream = (DataStream*)stream->descriptor.pointer;
+ dstream->Seek(offset, GEM_STREAM_START);
+ return dstream->Read(buffer, count);
+}
+
+void TTFFontManager::close( FT_Stream stream )
+{
+ if (stream)
+ free(stream);
+}
+
+TTFFontManager::~TTFFontManager(void)
+{
+// TTFFont uses FT_Reference_Face only available in 2.4.2 or later
+// if using prior freetype let the font own the face and destroy it
+// WARNING: this carries the implication that the font manager can only create a single font
+#if FREETYPE_VERSION_ATLEAST(2,4,2)
+ if (face) {
+ FT_Done_Face(face);
+ }
+#endif
+}
+
+TTFFontManager::TTFFontManager(void)
+: ftStream(NULL), face(NULL)
+{}
+
+bool TTFFontManager::Open(DataStream* stream)
+{
+ Close();
+ if (stream) {
+ FT_Error error;
+
+ ftStream = (FT_Stream)calloc(sizeof(*ftStream), 1);
+ ftStream->read = read;
+ ftStream->close = close;
+ ftStream->descriptor.pointer = stream;
+ ftStream->pos = stream->GetPos();
+ ftStream->size = stream->Size();
+
+ FT_Open_Args args = FT_Open_Args();
+ args.flags = FT_OPEN_STREAM;
+ args.stream = ftStream;
+
+ error = FT_Open_Face( library, &args, 0, &face );
+ if( error ) {
+ LogFTError(error);
+ Close();
+ return false;
+ }
+
+ // we always convert to UTF-16
+ // TODO: maybe we should allow an override encoding?
+ FT_Select_Charmap(face, FT_ENCODING_UNICODE);
+ return true;
+ }
+ return false;
+}
+
+void TTFFontManager::Close()
+{
+ if (face) {
+ FT_Done_Face(face);
+ }
+ close(ftStream);
+}
+
+Font* TTFFontManager::GetFont(unsigned short ptSize,
+ FontStyle style, Palette* pal)
+{
+ if (!pal) {
+ Color fore = {0xFF, 0xFF, 0xFF, 0}; //white
+ Color back = {0x00, 0x00, 0x00, 0}; //black
+ pal = core->CreatePalette( fore, back );
+ pal->CreateShadedAlphaChannel();
+ }
+ return new TTFFont(face, ptSize, style, pal);
+}
+
+#include "plugindef.h"
+
+GEMRB_PLUGIN(0x3AD6427C, "TTF Font Importer")
+PLUGIN_RESOURCE(TTFFontManager, "ttf")
+PLUGIN_INITIALIZER(loadFT)
+PLUGIN_CLEANUP(destroyFT)
+END_PLUGIN()
diff --git a/gemrb/plugins/TTFImporter/TTFFontManager.h b/gemrb/plugins/TTFImporter/TTFFontManager.h
new file mode 100644
index 0000000..fd8058c
--- /dev/null
+++ b/gemrb/plugins/TTFImporter/TTFFontManager.h
@@ -0,0 +1,62 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2011 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef GemRB_TTFFont_h
+#define GemRB_TTFFont_h
+
+#include "Freetype.h"
+
+#include "FontManager.h"
+
+namespace GemRB {
+
+class TTFFontManager : public FontManager {
+/*
+Private ivars
+*/
+private:
+ FT_Stream ftStream;
+ FT_Face face;
+
+public:
+/*
+Public methods
+*/
+ ~TTFFontManager(void);
+ TTFFontManager(void);
+
+ bool Open(DataStream* stream);
+ void Close();
+
+ Font* GetFont(unsigned short ptSize,
+ FontStyle style, Palette* pal = NULL);
+
+ // freetype "callbacks"
+ static unsigned long read( FT_Stream stream,
+ unsigned long offset,
+ unsigned char* buffer,
+ unsigned long count );
+
+ static void close( FT_Stream stream );
+};
+
+}
+
+#endif
diff --git a/gemrb/plugins/VLCPlayer/CMakeLists.txt b/gemrb/plugins/VLCPlayer/CMakeLists.txt
new file mode 100644
index 0000000..1e665d7
--- /dev/null
+++ b/gemrb/plugins/VLCPlayer/CMakeLists.txt
@@ -0,0 +1,5 @@
+IF (LIBVLC_LIBRARY)
+ INCLUDE_DIRECTORIES( ${LIBVLC_INCLUDE_DIR} )
+ ADD_GEMRB_PLUGIN ( VLCPlayer VLCPlayer.cpp VideoContext.cpp )
+ TARGET_LINK_LIBRARIES( VLCPlayer ${LIBVLC_LIBRARY} )
+ENDIF (LIBVLC_LIBRARY)
diff --git a/gemrb/plugins/VLCPlayer/VLCPlayer.cpp b/gemrb/plugins/VLCPlayer/VLCPlayer.cpp
new file mode 100644
index 0000000..7a0f406
--- /dev/null
+++ b/gemrb/plugins/VLCPlayer/VLCPlayer.cpp
@@ -0,0 +1,211 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2012 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "VLCPlayer.h"
+#include "Video.h"
+
+using namespace GemRB;
+
+VLCPlayer::VLCPlayer(void)
+{
+ libvlc = libvlc_new(0, NULL);
+ mediaPlayer = NULL;
+ media = NULL;
+ ctx = NULL;
+}
+
+VLCPlayer::~VLCPlayer(void)
+{
+ if (ctx) {
+ Stop(); // this call will lead to the dallocation of ctx
+ }
+ libvlc_release(libvlc);
+}
+
+bool VLCPlayer::Open(DataStream* stream)
+{
+ if (mediaPlayer) {
+ Stop();
+ }
+ if (stream) {
+ // we don't actually need anything from the stream. libVLC will open and use the file internally
+ media = libvlc_media_new_path(libvlc, stream->originalfile);
+ mediaPlayer = libvlc_media_player_new_from_media(media);
+ libvlc_media_release(media); //player retains the media
+
+ libvlc_video_set_callbacks(mediaPlayer, lock, unlock, display, &ctx);
+ libvlc_video_set_format_callbacks(mediaPlayer, setup, cleanup);
+
+ return true;
+ }
+ return false;
+}
+
+void VLCPlayer::CallBackAtFrames(ieDword /*cnt*/, ieDword* /*arg*/, ieDword* /*arg2*/ )
+{
+ // TODO: probably should do something here.
+ Log(MESSAGE, "VLCPlayer", "Unimplemented method: CallBackAtFrames");
+}
+
+void VLCPlayer::Stop()
+{
+ libvlc_media_player_stop(mediaPlayer);
+ libvlc_media_player_release(mediaPlayer);
+}
+
+int VLCPlayer::Play()
+{
+ int ret = GEM_ERROR;
+ Video* video = core->GetVideoDriver();
+ if (mediaPlayer && video) {
+ ret = libvlc_media_player_play(mediaPlayer);
+ if (ret == GEM_OK) {
+ // since ret is good we know that playback will start.
+ // wait here until it does
+
+ // FIXME: this is not very elegant and infinate loops are not a good thing :)
+ // maybe there is a function we can use to check the vlc player status instead of polling until our context is valid
+ while (!libvlc_media_player_is_playing(mediaPlayer) || ctx == NULL);
+
+ bool done = false;
+ while (!done && libvlc_media_player_is_playing(mediaPlayer)) {
+ ctx->Lock();
+ done = video->PollMovieEvents();
+
+ if (ctx->isYUV()) {
+ unsigned int strides[3];
+ strides[0] = ctx->GetStride(0);
+ strides[1] = ctx->GetStride(1);
+ strides[2] = ctx->GetStride(2);
+
+ void* planes[3];
+ planes[0] = ctx->GetPlane(0);
+ planes[1] = ctx->GetPlane(1);
+ planes[2] = ctx->GetPlane(2);
+
+ // TODO: center the video on the player.
+ video->showYUVFrame((unsigned char**)planes, strides,
+ ctx->Width(), ctx->Height(),
+ ctx->Width(), ctx->Height(),
+ 0, 0, 0);
+ } else {
+ video->showFrame((unsigned char*)ctx->GetPlane(0),
+ ctx->Width(), ctx->Height(), 0, 0,
+ ctx->Width(), ctx->Height(), 0, 0,
+ true, NULL, 0);
+ }
+ ctx->Unlock();
+ }
+ }
+ Stop();
+ }
+ return ret;
+}
+
+// static vlc callbacks
+
+void VLCPlayer::display(void* /*data*/, void *id){
+ assert(id == NULL); // we are using a single buffer so id should always be NULL
+}
+
+void VLCPlayer::unlock(void *data, void *id, void *const * /*planes*/){
+ assert(id == NULL); // we are using a single buffer so id should always be NULL
+ VideoContext* context = *(VideoContext**)data;
+ context->Unlock();
+}
+
+void* VLCPlayer::lock(void *data, void **planes){
+ VideoContext* context = *(VideoContext**)data;
+ context->Lock();
+ planes[0] = context->GetPlane(0);
+ planes[1] = context->GetPlane(1);
+ planes[2] = context->GetPlane(2);
+ return NULL; // we are using a single buffer so return NULL
+}
+
+void VLCPlayer::cleanup(void *opaque)
+{
+ VideoContext* context = *(VideoContext**)opaque;
+ delete context;
+ context = NULL;
+
+ core->GetVideoDriver()->DestroyMovieScreen();
+}
+
+unsigned VLCPlayer::setup(void **opaque, char *chroma, unsigned *width, unsigned *height, unsigned *pitches, unsigned *lines)
+{
+ Video* video = core->GetVideoDriver();
+ assert(video != NULL);
+
+ /*
+ other player plugins assume video is made specifically for IE games (dimensions and chroma).
+ we won't assume this here because this player is mostly for modders to use their own videos.
+
+ we will need to make sure the video is scaled down if it is larger than the window and we will
+ need to convert the chroma to one of the 2 formats the video driver is coded for.
+
+ currently the video drivers expect RGB555 or IYUV, but the SDL 2.0 driver can actually handle ARGB as well.
+ infact the texture is natively ARGB8888, and we are converting RGB555 data to ARGB which means here we may be
+ converting like this ARGB -> RGB555 -> ARGB which is quite dumb :)
+
+ TODO: figure out a way to support ARGB when using SDL 2
+ */
+
+ bool yuv;
+ if (strcmp(chroma, "RV16") == 0) { // 16bit RGB
+ yuv = false;
+ } else {
+ yuv = true;
+ memcpy(chroma, "YV12", 4);
+ }
+
+ int w = *width;
+ int h = *height;
+ video->InitMovieScreen(w, h, yuv); // may alter w and h
+
+ // TODO: proportionally scale the video to fit the player window
+ // for now we'll use the video native width and height.
+ w = *width;
+ h = *height;
+
+ VideoContext* context = new VideoContext(w, h, yuv);
+ **(VideoContext***)opaque = context; // a bit of a hack, but we need to set the player object's context.
+
+ // being lazy and making VLC convert frame pitches and scan lines
+ // note that I assume that InitMovieScreen with force w and h into a multiple of 32
+ pitches[0] = w;
+ pitches[1] = w;
+ pitches[2] = w;
+
+ lines[0] = h;
+ lines[1] = h;
+ lines[2] = h;
+
+ return 1; // indicates the number of buffers allocated
+}
+
+#include "plugindef.h"
+
+GEMRB_PLUGIN(0x218963DD, "VLC Video Player")
+// TODO: VLC is quite capable of playing various movie formats
+// it seems silly to hardcode a single value or add formats piecemeal.
+// it would be a shame to force modders or new content creators to use a specific format
+PLUGIN_RESOURCE(VLCPlayer, "mov") // at least some mac ports used Quicktime MOV format
+END_PLUGIN()
diff --git a/gemrb/plugins/VLCPlayer/VLCPlayer.h b/gemrb/plugins/VLCPlayer/VLCPlayer.h
new file mode 100644
index 0000000..7054b19
--- /dev/null
+++ b/gemrb/plugins/VLCPlayer/VLCPlayer.h
@@ -0,0 +1,73 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2012 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef VLCPLAY_H
+#define VLCPLAY_H
+
+#include <vlc/vlc.h>
+
+#include "Interface.h"
+#include "MoviePlayer.h"
+#include "VideoContext.h"
+
+namespace GemRB {
+
+/*
+ NOTE: using VLC player may result in poor video playback.
+ VLC will convert video to match our supported formats (RGB555 and YV12)
+ as well as scaleing. These operations are expensive and should be avoided
+ by using a video properly sized and in a supported colorspace.
+
+ There are a number of things we could do here to speed things up if necessary:
+
+ 1. we could enhance our video drivers to allow for additional pixel formats. (at least via bpp for RGB video)
+ 2. instead of VLC -> context -> video texture/surface we could provide a way to do VLC -> texture/surface
+ 3. in VLCPlayer::setup() we could use the provided pitches and lines instead of forcing VLC to convert
+ (see lazyness notes in VLCPlayer.cpp)
+*/
+
+class VLCPlayer : public MoviePlayer {
+private:
+ libvlc_instance_t *libvlc;
+ libvlc_media_t *media;
+ libvlc_media_player_t *mediaPlayer;
+
+ VideoContext* ctx;
+
+ // libvlc_video_set_callbacks
+ static void display(void *data, void *id);
+ static void unlock(void *data, void *id, void *const *planes);
+ static void* lock(void *data, void **planes);
+
+ // libvlc_video_set_format_callbacks
+ static unsigned setup(void **opaque, char *chroma, unsigned *width, unsigned *height, unsigned *pitches, unsigned *lines);
+ static void cleanup(void *opaque);
+public:
+ VLCPlayer(void);
+ ~VLCPlayer(void);
+ bool Open(DataStream* stream);
+ int Play();
+ void Stop();
+ void CallBackAtFrames(ieDword cnt, ieDword *arg, ieDword *arg2);
+};
+
+}
+
+#endif
diff --git a/gemrb/plugins/VLCPlayer/VideoContext.cpp b/gemrb/plugins/VLCPlayer/VideoContext.cpp
new file mode 100644
index 0000000..f6c521a
--- /dev/null
+++ b/gemrb/plugins/VLCPlayer/VideoContext.cpp
@@ -0,0 +1,82 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2012 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "VLCPlayer.h"
+#include "Video.h"
+
+using namespace GemRB;
+
+VideoContext::VideoContext(unsigned w, unsigned h, bool yuv)
+: YUV(yuv), width(w), height(h)
+{
+ if(pthread_mutex_init(&mutex, NULL) != GEM_OK) {
+ Log(ERROR, "VLC Player", "Unable to create mutex!");
+ }
+
+ int size = width * height;
+ if (YUV) {
+ planes[0] = new char[size];
+ planes[1] = new char[size / 2];
+ planes[2] = new char[size / 2];
+ } else { // 16bit RGB
+ planes[0] = new char[size * 2];
+ planes[1] = NULL;
+ planes[2] = NULL;
+ }
+}
+
+VideoContext::~VideoContext(void)
+{
+ pthread_mutex_destroy(&mutex);
+ delete[] (char*)planes[0];
+ if (YUV) {
+ delete[] (char*)planes[1];
+ delete[] (char*)planes[2];
+ }
+}
+
+int VideoContext::Lock()
+{
+ return pthread_mutex_lock(&mutex);
+}
+
+int VideoContext::Unlock()
+{
+ return pthread_mutex_unlock(&mutex);
+}
+
+void* VideoContext::GetPlane(unsigned idx)
+{
+ if (YUV) {
+ if (idx <= 3) return planes[idx];
+ } else {
+ return planes[0];
+ }
+ Log(ERROR, "VLCPlayer", "Plane index out of range.");
+ return NULL;
+}
+
+unsigned VideoContext::GetStride(unsigned /*idx*/)
+{
+ // idx is a placeholder if we decide to use the native strides
+ // for now we are lazy and will make VLC convert all plane strides to width
+
+ return width;
+}
diff --git a/gemrb/plugins/VLCPlayer/VideoContext.h b/gemrb/plugins/VLCPlayer/VideoContext.h
new file mode 100644
index 0000000..3d3eaf9
--- /dev/null
+++ b/gemrb/plugins/VLCPlayer/VideoContext.h
@@ -0,0 +1,53 @@
+/* GemRB - Infinity Engine Emulator
+ * Copyright (C) 2012 The GemRB Project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef VIDCTX_H
+#define VIDCTX_H
+
+#include <pthread.h>
+
+namespace GemRB {
+
+class VideoContext
+{
+private:
+ pthread_mutex_t mutex;
+ void* planes[3];
+
+ bool YUV;
+ unsigned width;
+ unsigned height;
+public:
+ VideoContext(unsigned w, unsigned h, bool yuv);
+ ~VideoContext(void);
+
+ int Lock();
+ int Unlock();
+
+ void* GetPlane(unsigned idx = 0);
+ unsigned GetStride(unsigned idx = 0);
+ bool isYUV() { return YUV; };
+ unsigned Width() { return width; };
+ unsigned Height() { return height; };
+};
+
+}
+
+#endif
diff --git a/gemrb/plugins/WAVReader/WAVReader.cpp b/gemrb/plugins/WAVReader/WAVReader.cpp
index 90c7010..360aa1e 100644
--- a/gemrb/plugins/WAVReader/WAVReader.cpp
+++ b/gemrb/plugins/WAVReader/WAVReader.cpp
@@ -20,6 +20,8 @@
#include <utility>
+using namespace GemRB;
+
// WAVEFORMATEX structure (from MS SDK)
struct cWAVEFORMATEX {
unsigned short wFormatTag; /* format type */
@@ -189,5 +191,5 @@ bool WavPCMReader::Open(DataStream* stream)
#include "plugindef.h"
GEMRB_PLUGIN(0x11BB1288, "WAV File Importer")
-PLUGIN_IE_RESOURCE(WavPCMReader, ".wav", (ieWord)IE_WAV_CLASS_ID)
+PLUGIN_IE_RESOURCE(WavPCMReader, "wav", (ieWord)IE_WAV_CLASS_ID)
END_PLUGIN()
diff --git a/gemrb/plugins/WAVReader/WAVReader.h b/gemrb/plugins/WAVReader/WAVReader.h
index 72b947b..cd8b503 100644
--- a/gemrb/plugins/WAVReader/WAVReader.h
+++ b/gemrb/plugins/WAVReader/WAVReader.h
@@ -29,6 +29,8 @@
#include <cstdlib>
#include <cstring>
+namespace GemRB {
+
// RAW file reader
class RawPCMReader : public SoundMgr {
protected:
@@ -56,4 +58,6 @@ public:
bool Open(DataStream* stream);
};
+}
+
#endif
diff --git a/gemrb/plugins/WEDImporter/WEDImporter.cpp b/gemrb/plugins/WEDImporter/WEDImporter.cpp
index 802937d..78e273a 100644
--- a/gemrb/plugins/WEDImporter/WEDImporter.cpp
+++ b/gemrb/plugins/WEDImporter/WEDImporter.cpp
@@ -18,10 +18,6 @@
*
*/
-#if defined(__HAIKU__)
-#include <unistd.h>
-#endif
-
#ifdef ANDROID
#include "swab.h"
#endif
@@ -32,8 +28,15 @@
#include "GameData.h"
#include "Interface.h"
+#include "PluginMgr.h"
#include "TileSetMgr.h"
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+using namespace GemRB;
+
struct wed_polygon {
ieDword FirstVertex;
ieDword CountVertex;
@@ -47,30 +50,24 @@ struct wed_polygon {
WEDImporter::WEDImporter(void)
{
str = NULL;
- autoFree = false;
}
WEDImporter::~WEDImporter(void)
{
- if (str && autoFree) {
- delete( str );
- }
+ delete str;
}
-bool WEDImporter::Open(DataStream* stream, bool autoFree)
+bool WEDImporter::Open(DataStream* stream)
{
if (stream == NULL) {
return false;
}
- if (str && this->autoFree) {
- delete( str );
- }
+ delete str;
str = stream;
- this->autoFree = autoFree;
char Signature[8];
str->Read( Signature, 8 );
if (strncmp( Signature, "WED V1.3", 8 ) != 0) {
- printf( "[WEDImporter]: This file is not a valid WED File\n" );
+ Log(ERROR, "WEDImporter", "This file is not a valid WED File");
return false;
}
str->ReadDword( &OverlaysCount );
@@ -214,7 +211,7 @@ void WEDImporter::GetDoorPolygonCount(ieWord count, ieDword offset)
ieDword basecount = offset-PolygonsOffset;
if (basecount%WED_POLYGON_SIZE) {
basecount+=WED_POLYGON_SIZE;
- printf("[WEDImporter]: Found broken door polygon header!\n");
+ Log(WARNING, "WEDImporter", "Found broken door polygon header!");
}
ieDword polycount = basecount/WED_POLYGON_SIZE+count-WallPolygonsCount;
if (polycount>DoorPolygonsCount) {
@@ -249,7 +246,7 @@ ieWord* WEDImporter::GetDoorIndices(char* ResRef, int* count, bool& BaseClosed)
//The door has no representation in the WED file
if (i == DoorsCount) {
*count = 0;
- printf( "[WEDImporter]: Found door without WED entry!\n" );
+ Log(ERROR, "WEDImporter", "Found door without WED entry!");
return NULL;
}
diff --git a/gemrb/plugins/WEDImporter/WEDImporter.h b/gemrb/plugins/WEDImporter/WEDImporter.h
index f725b78..43aba39 100644
--- a/gemrb/plugins/WEDImporter/WEDImporter.h
+++ b/gemrb/plugins/WEDImporter/WEDImporter.h
@@ -23,6 +23,8 @@
#include "TileMapMgr.h"
+namespace GemRB {
+
struct Overlay {
ieWord Width;
ieWord Height;
@@ -36,7 +38,6 @@ class WEDImporter : public TileMapMgr {
private:
std::vector< Overlay> overlays;
DataStream* str;
- bool autoFree;
ieDword OverlaysCount, DoorsCount, OverlaysOffset, SecHeaderOffset,
DoorsOffset, DoorTilesOffset;
ieDword WallPolygonsCount, PolygonsOffset, VerticesOffset,
@@ -52,7 +53,7 @@ private:
public:
WEDImporter(void);
~WEDImporter(void);
- bool Open(DataStream* stream, bool autoFree = true);
+ bool Open(DataStream* stream);
//if tilemap already exists, don't create it
TileMap* GetTileMap(TileMap *tm);
ieWord* GetDoorIndices(char* ResRef, int* count, bool& BaseClosed);
@@ -63,4 +64,6 @@ public:
void SetupClosedDoor(unsigned int &index, unsigned int &count);
};
+}
+
#endif
diff --git a/gemrb/plugins/WMPImporter/WMPImporter.cpp b/gemrb/plugins/WMPImporter/WMPImporter.cpp
index 929c76b..2f67ac3 100644
--- a/gemrb/plugins/WMPImporter/WMPImporter.cpp
+++ b/gemrb/plugins/WMPImporter/WMPImporter.cpp
@@ -26,45 +26,37 @@
#include "ImageMgr.h"
#include "Interface.h"
+using namespace GemRB;
+
WMPImporter::WMPImporter(void)
{
str1 = NULL;
str2 = NULL;
- autoFree = false;
}
WMPImporter::~WMPImporter(void)
{
- if (str1 && autoFree) {
- delete( str1 );
- }
- if (str2 && autoFree) {
- delete( str2 );
- }
+ delete str1;
+ delete str2;
}
-bool WMPImporter::Open(DataStream* stream1, DataStream* stream2, bool autoFree)
+bool WMPImporter::Open(DataStream* stream1, DataStream* stream2)
{
if ((stream1 == NULL) && (stream2 == NULL) ) {
return false;
}
- if (str1 && this->autoFree) {
- delete( str1 );
- }
- if (str2 && this->autoFree) {
- delete( str2 );
- }
+ delete str1;
+ delete str2;
str1 = stream1;
str2 = stream2;
- this->autoFree = autoFree;
char Signature[8];
if (str1) {
str1->Read( Signature, 8 );
if (strncmp( Signature, "WMAPV1.0", 8 ) != 0) {
- printMessage( "WMPImporter","This file is not a valid WMP File\n", LIGHT_RED);
- printf( "-->%s<--\n", stream1->filename);
+ Log(ERROR, "WMPImporter", "'%s' is not a valid WMP File",
+ stream1->filename);
return false;
}
str1->ReadDword( &WorldMapsCount1 );
@@ -77,8 +69,8 @@ bool WMPImporter::Open(DataStream* stream1, DataStream* stream2, bool autoFree)
if (str2) {
str2->Read( Signature, 8 );
if (strncmp( Signature, "WMAPV1.0", 8 ) != 0) {
- printMessage( "WMPImporter","This file is not a valid WMP File\n", LIGHT_RED);
- printf( "-->%s<--\n", stream2->filename);
+ Log(ERROR, "WMPImporter", "'%s' is not a valid WMP File",
+ stream2->filename);
return false;
}
str2->ReadDword( &WorldMapsCount2 );
@@ -115,6 +107,7 @@ void WMPImporter::GetWorldMap(DataStream *str, WorldMap *m, unsigned int index)
{
unsigned int i;
unsigned int WorldMapsOffset;
+ ieDword AreaEntriesCount, AreaEntriesOffset, AreaLinksCount, AreaLinksOffset;
if (index && str==str2) {
WorldMapsOffset=WorldMapsOffset2;
@@ -131,23 +124,23 @@ void WMPImporter::GetWorldMap(DataStream *str, WorldMap *m, unsigned int index)
str->ReadDword( &m->AreaName );
str->ReadDword( &m->unknown1 );
str->ReadDword( &m->unknown2 );
- str->ReadDword( &m->AreaEntriesCount );
- str->ReadDword( &m->AreaEntriesOffset );
- str->ReadDword( &m->AreaLinksOffset );
- str->ReadDword( &m->AreaLinksCount );
+ str->ReadDword( &AreaEntriesCount );
+ str->ReadDword( &AreaEntriesOffset );
+ str->ReadDword( &AreaLinksOffset );
+ str->ReadDword( &AreaLinksCount );
str->ReadResRef( m->MapIconResRef );
// Load map bitmap
ResourceHolder<ImageMgr> mos(m->MapResRef);
if (!mos) {
- printMessage( "WMPImporter","Worldmap image not found.\n", LIGHT_RED );
+ Log(ERROR, "WMPImporter", "Worldmap image not found.");
} else {
m->SetMapMOS(mos->GetSprite2D());
}
// Load location icon bam
if (!core->IsAvailable( IE_BAM_CLASS_ID )) {
- printMessage( "WMPImporter","No BAM Importer Available.\n", LIGHT_RED );
+ Log(ERROR, "WMPImporter", "No BAM Importer Available.");
} else {
AnimationFactory* af = ( AnimationFactory* )
gamedata->GetFactoryResource( m->MapIconResRef, IE_BAM_CLASS_ID, IE_NORMAL );
@@ -155,18 +148,18 @@ void WMPImporter::GetWorldMap(DataStream *str, WorldMap *m, unsigned int index)
m->SetMapIcons( af );
}
- str->Seek( m->AreaEntriesOffset, GEM_STREAM_START );
+ str->Seek( AreaEntriesOffset, GEM_STREAM_START );
WMPAreaLink al;
- for (i = 0; i < m->AreaEntriesCount; i++) {
+ for (i = 0; i < AreaEntriesCount; i++) {
//this weird stuff is requires so we don't create
//data here, all data is created in the core
m->SetAreaEntry(i,GetAreaEntry(str, m->GetNewAreaEntry()));
}
- str->Seek( m->AreaLinksOffset, GEM_STREAM_START );
- for (i = 0; i < m->AreaLinksCount; i++) {
+ str->Seek( AreaLinksOffset, GEM_STREAM_START );
+ for (i = 0; i < AreaLinksCount; i++) {
m->SetAreaLink(i,GetAreaLink(str, &al));
}
@@ -177,6 +170,7 @@ WMPAreaEntry* WMPImporter::GetAreaEntry(DataStream *str, WMPAreaEntry* ae)
str->ReadResRef( ae->AreaName );
str->ReadResRef( ae->AreaResRef );
str->Read( ae->AreaLongName, 32 );
+ ae->AreaLongName[32]=0;
ieDword tmpDword;
str->ReadDword( &tmpDword );
str->ReadDword( &ae->IconSeq );
@@ -201,6 +195,7 @@ WMPAreaLink* WMPImporter::GetAreaLink(DataStream *str, WMPAreaLink* al)
{
str->ReadDword( &al->AreaIndex );
str->Read( al->DestEntryPoint, 32 );
+ al->DestEntryPoint[32]=0;
str->ReadDword( &al->DistanceScale );
str->ReadDword( &al->DirectionFlags );
for (unsigned k = 0; k < 5; k++) {
@@ -239,12 +234,8 @@ int WMPImporter::GetStoredFileSize(WorldMapArray *wmap, unsigned int index)
headersize += 184;
WorldMap *map = wmap->GetWorldMap(i);
- //Update the links and entries counts now, in case the worldmap has changed
- map->AreaEntriesCount = map->GetEntryCount();
- headersize += map->AreaEntriesCount * 240;
-
- map->AreaLinksCount = map->GetLinkCount();
- headersize += map->AreaLinksCount * 216;
+ headersize += map->GetEntryCount() * 240;
+ headersize += map->GetLinkCount() * 216;
//put the first array into the first map
//the rest into the second map if not single
@@ -287,7 +278,8 @@ int WMPImporter::PutLinks(DataStream *stream, WorldMap *wmap)
char filling[128];
memset (filling,0,sizeof(filling));
- for(unsigned i=0;i<wmap->AreaLinksCount;i++) {
+ unsigned int cnt = wmap->GetLinkCount();
+ for (unsigned i = 0; i < cnt; i++) {
WMPAreaLink *al = wmap->GetLink(i);
stream->WriteDword( &al->AreaIndex );
@@ -307,9 +299,10 @@ int WMPImporter::PutAreas(DataStream *stream, WorldMap *wmap)
{
char filling[128];
ieDword tmpDword;
+ unsigned int cnt = wmap->GetEntryCount();
memset (filling,0,sizeof(filling));
- for(unsigned i=0;i<wmap->AreaEntriesCount;i++) {
+ for(unsigned i=0;i<cnt;i++) {
WMPAreaEntry *ae = wmap->GetEntry(i);
stream->WriteResRef( ae->AreaName );
diff --git a/gemrb/plugins/WMPImporter/WMPImporter.h b/gemrb/plugins/WMPImporter/WMPImporter.h
index 9c8d515..bf0974d 100644
--- a/gemrb/plugins/WMPImporter/WMPImporter.h
+++ b/gemrb/plugins/WMPImporter/WMPImporter.h
@@ -27,12 +27,13 @@
#include "WorldMap.h"
+namespace GemRB {
+
class WMPImporter : public WorldMapMgr {
private:
DataStream* str1;
DataStream* str2;
- bool autoFree;
ieDword WorldMapsCount;
ieDword WorldMapsCount1, WorldMapsCount2;
@@ -41,7 +42,7 @@ private:
public:
WMPImporter(void);
~WMPImporter(void);
- bool Open(DataStream* stream1, DataStream* stream2, bool autoFree = true);
+ bool Open(DataStream* stream1, DataStream* stream2);
WorldMapArray *GetWorldMapArray();
int GetStoredFileSize(WorldMapArray *wmap, unsigned int index);
@@ -58,4 +59,6 @@ private:
};
+}
+
#endif
diff --git a/gemrb/plugins/ZLibManager/ZLibManager.cpp b/gemrb/plugins/ZLibManager/ZLibManager.cpp
index 858ae71..4373922 100644
--- a/gemrb/plugins/ZLibManager/ZLibManager.cpp
+++ b/gemrb/plugins/ZLibManager/ZLibManager.cpp
@@ -25,6 +25,8 @@
#include <zlib.h>
+using namespace GemRB;
+
ZLibManager::ZLibManager(void)
{
@@ -39,7 +41,7 @@ ZLibManager::~ZLibManager(void)
#define OUTPUTSIZE 8192
// ZLib Decompression Routine
-int ZLibManager::Decompress(FILE* dest, DataStream* source, unsigned int size_guess) const
+int ZLibManager::Decompress(DataStream* dest, DataStream* source, unsigned int size_guess) const
{
unsigned char bufferin[INPUTSIZE], bufferout[OUTPUTSIZE];
z_stream stream;
@@ -84,8 +86,7 @@ int ZLibManager::Decompress(FILE* dest, DataStream* source, unsigned int size_gu
if (( result != Z_OK ) && ( result != Z_STREAM_END )) {
return GEM_ERROR;
}
- if (fwrite( bufferout, 1, OUTPUTSIZE - stream.avail_out, dest ) <
- OUTPUTSIZE - stream.avail_out) {
+ if (dest->Write(bufferout, OUTPUTSIZE - stream.avail_out) == GEM_ERROR) {
return GEM_ERROR;
}
if (result == Z_STREAM_END) {
diff --git a/gemrb/plugins/ZLibManager/ZLibManager.h b/gemrb/plugins/ZLibManager/ZLibManager.h
index 784494c..3015357 100644
--- a/gemrb/plugins/ZLibManager/ZLibManager.h
+++ b/gemrb/plugins/ZLibManager/ZLibManager.h
@@ -23,14 +23,18 @@
#include "Compressor.h"
+namespace GemRB {
+
class ZLibManager : public Compressor {
public:
ZLibManager(void);
~ZLibManager(void);
// ZLib Decompression Routine
- int Decompress(FILE* dest, DataStream* source, unsigned int size_guess) const;
+ int Decompress(DataStream* dest, DataStream* source, unsigned int size_guess) const;
// ZLib Compression
int Compress(DataStream* dest, DataStream* source) const;
};
+}
+
#endif
diff --git a/gemrb/tests/minimal/data/fonts.2da b/gemrb/tests/minimal/data/fonts.2da
index 5f0eccb..d18d692 100644
--- a/gemrb/tests/minimal/data/fonts.2da
+++ b/gemrb/tests/minimal/data/fonts.2da
@@ -1,4 +1,4 @@
2DA V1.0
- RESREF
-DEFAULT FOGOWAR
+ RESREF NEED_PALETTE FONT_NAME PT_SIZE STYLE COLOR
+DEFAULT NUMTEST 0 NUMTEST 10 0xffffffff
diff --git a/gemrb/tests/minimal/data/numtest.bam b/gemrb/tests/minimal/data/numtest.bam
new file mode 100644
index 0000000..1e26902
Binary files /dev/null and b/gemrb/tests/minimal/data/numtest.bam differ
diff --git a/gemrb/unhardcoded/Makefile.am b/gemrb/unhardcoded/Makefile.am
new file mode 100644
index 0000000..27691ea
--- /dev/null
+++ b/gemrb/unhardcoded/Makefile.am
@@ -0,0 +1,2 @@
+SUBDIRS = bg1 bg2 how iwd iwd2 pst shared
+EXTRA_DIST = CMakeLists.txt */CMakeLists.txt
diff --git a/gemrb/unhardcoded/bg1/Makefile.am b/gemrb/unhardcoded/bg1/Makefile.am
new file mode 100644
index 0000000..3b2aac1
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/Makefile.am
@@ -0,0 +1,3 @@
+bg1unhardcoded_DATA = *.2da *.bmp *.ini *.chu *.ids *.pro
+bg1unhardcodeddir = $(moddir)/unhardcoded/bg1/
+EXTRA_DIST = *.2da *.bmp *.ini *.chu *.ids *.pro
diff --git a/gemrb/override/bg1/ability.2da b/gemrb/unhardcoded/bg1/ability.2da
similarity index 100%
rename from gemrb/override/bg1/ability.2da
rename to gemrb/unhardcoded/bg1/ability.2da
diff --git a/gemrb/override/bg1/acidblgr.pro b/gemrb/unhardcoded/bg1/acidblgr.pro
similarity index 100%
rename from gemrb/override/bg1/acidblgr.pro
rename to gemrb/unhardcoded/bg1/acidblgr.pro
diff --git a/gemrb/override/bg1/acidblmu.pro b/gemrb/unhardcoded/bg1/acidblmu.pro
similarity index 100%
rename from gemrb/override/bg1/acidblmu.pro
rename to gemrb/unhardcoded/bg1/acidblmu.pro
diff --git a/gemrb/override/bg1/acidblob.pro b/gemrb/unhardcoded/bg1/acidblob.pro
similarity index 100%
rename from gemrb/override/bg1/acidblob.pro
rename to gemrb/unhardcoded/bg1/acidblob.pro
diff --git a/gemrb/override/bg1/acidbloc.pro b/gemrb/unhardcoded/bg1/acidbloc.pro
similarity index 100%
rename from gemrb/override/bg1/acidbloc.pro
rename to gemrb/unhardcoded/bg1/acidbloc.pro
diff --git a/gemrb/override/bg1/aligns.2da b/gemrb/unhardcoded/bg1/aligns.2da
similarity index 100%
rename from gemrb/override/bg1/aligns.2da
rename to gemrb/unhardcoded/bg1/aligns.2da
diff --git a/gemrb/override/bg1/areapro.2da b/gemrb/unhardcoded/bg1/areapro.2da
similarity index 100%
rename from gemrb/override/bg1/areapro.2da
rename to gemrb/unhardcoded/bg1/areapro.2da
diff --git a/gemrb/override/bg1/arrow.pro b/gemrb/unhardcoded/bg1/arrow.pro
similarity index 100%
rename from gemrb/override/bg1/arrow.pro
rename to gemrb/unhardcoded/bg1/arrow.pro
diff --git a/gemrb/override/bg1/arrowex.pro b/gemrb/unhardcoded/bg1/arrowex.pro
similarity index 100%
rename from gemrb/override/bg1/arrowex.pro
rename to gemrb/unhardcoded/bg1/arrowex.pro
diff --git a/gemrb/override/bg1/arrowflb.pro b/gemrb/unhardcoded/bg1/arrowflb.pro
similarity index 100%
rename from gemrb/override/bg1/arrowflb.pro
rename to gemrb/unhardcoded/bg1/arrowflb.pro
diff --git a/gemrb/override/bg1/arrowflg.pro b/gemrb/unhardcoded/bg1/arrowflg.pro
similarity index 100%
rename from gemrb/override/bg1/arrowflg.pro
rename to gemrb/unhardcoded/bg1/arrowflg.pro
diff --git a/gemrb/override/bg1/arrowfli.pro b/gemrb/unhardcoded/bg1/arrowfli.pro
similarity index 100%
rename from gemrb/override/bg1/arrowfli.pro
rename to gemrb/unhardcoded/bg1/arrowfli.pro
diff --git a/gemrb/override/bg1/arrowflm.pro b/gemrb/unhardcoded/bg1/arrowflm.pro
similarity index 100%
rename from gemrb/override/bg1/arrowflm.pro
rename to gemrb/unhardcoded/bg1/arrowflm.pro
diff --git a/gemrb/override/bg1/arrowhvy.pro b/gemrb/unhardcoded/bg1/arrowhvy.pro
similarity index 100%
rename from gemrb/override/bg1/arrowhvy.pro
rename to gemrb/unhardcoded/bg1/arrowhvy.pro
diff --git a/gemrb/unhardcoded/bg1/avatars.2da b/gemrb/unhardcoded/bg1/avatars.2da
new file mode 100644
index 0000000..5d0ac85
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/avatars.2da
@@ -0,0 +1,322 @@
+2DA V1.0
+*
+ AT_1 AT_2 AT_3 AT_4 TYPE SPACE PALETTE SIZE
+0x0100 SPCHUNKS SPCHUNKS SPCHUNKS SPCHUNKS 13 0 0 *
+0x0300 SPSMPUFF SPSMPUFF SPSMPUFF SPSMPUFF 13 0 0 *
+0x0400 SKLH SKLH SKLH SKLH 13 0 1 *
+0x0410 GLPHWRDH GLPHWRDH GLPHWRDH GLPHWRDH 13 0 1 *
+0x1000 MWYV MWYV MWYV MWYV 11 3 1 *
+0x1100 MTAN MTAN MTAN MTAN 11 3 1 *
+0x1200 MDR1 MDR1 MDR1 MDR1 12 7 1 *
+0x1201 MDR2 MDR2 MDR2 MDR2 12 7 1 *
+0x1202 MDR3 MDR3 MDR3 MDR3 12 7 1 *
+0x1203 MDR1 MDR1 MDR1 MDR1 12 7 GR *
+0x1204 MDR1 MDR1 MDR1 MDR1 12 7 AQ *
+0x1205 MDR1 MDR1 MDR1 MDR1 12 7 BL *
+0x1206 MDR1 MDR1 MDR1 MDR1 12 7 BR *
+0x1207 MDR1 MDR1 MDR1 MDR1 12 7 MC *
+0x1208 MDR1 MDR1 MDR1 MDR1 12 7 PU *
+0x2000 MSIR MSIR MSIR MSIR 2 2 0 +
+0x2100 UVOL UVOL UVOL UVOL 2 2 1 *
+0x2200 MOGM MOGM MOGM MOGM 2 2 0 S
+0x2300 MDKN MDKN MDKN MDKN 2 2 1 *
+0x3000 MAKH MAKH MAKH MAKH 17 3 1 *
+0x4000 SNOMC SNOMC SNOMC SNOMC 1 2 0 *
+0x4002 SNOMM SNOMM SNOMM SNOMM 1 2 0 *
+0x4010 SNOWC SNOWC SNOWC SNOWC 1 2 0 *
+0x4012 SNOWM SNOWM SNOWM SNOWM 1 2 0 *
+0x4100 SSIMC SSIMC SSIMC SSIMC 1 2 0 *
+0x4101 SSIMS SSIMS SSIMS SSIMS 1 2 0 *
+0x4102 SSIMM SSIMM SSIMM SSIMM 1 2 0 *
+0x4110 SSIWC SSIWC SSIWC SSIWC 1 2 0 *
+0x4112 SSIWM SSIWM SSIWM SSIWM 1 2 0 *
+0x4200 SHMCM SHMCM SHMCM SHMCM 1 2 0 *
+0x4300 MSPLG1 MSPLG1 MSPLG1 MSPLG1 1 2 1 *
+0x4400 LHMC LHMC LHMC LHMC 1 2 0 *
+0x4410 LHFC LHFC LHFC LHFC 1 2 0 *
+0x4500 LFAM LFAM LFAM LFAM 1 2 0 *
+0x4600 LDMF LDMF LDMF LDMF 1 2 0 *
+0x4700 LEMF LEMF LEMF LEMF 1 2 0 *
+0x4710 LEFF LEFF LEFF LEFF 1 2 0 *
+0x4800 LIMC LIMC LIMC LIMC 1 2 0 *
+0x5000 CHMC1 CHMC2 CHMC3 CHMC4 6 2 0 L
+0x5001 CEMC1 CEMC2 CEMC3 CEMC4 6 2 0 M
+0x5002 CDMC1 CDMC2 CDMC3 CDMC4 6 2 0 S
+0x5003 CIMC1 CIMC2 CIMC3 CIMC4 6 2 0 S
+0x5010 CHFC1 CHFC2 CHFC3 CHFC4 6 2 0 M
+0x5011 CEFC1 CEFC2 CEFC3 CEFC4 6 2 0 M
+0x5012 CDMC1 CDMC2 CDMC3 CDMC4 6 2 0 S
+0x5013 CIFC1 CIFC2 CIFC3 CIFC4 6 2 0 S
+0x5100 CHMF1 CHMF2 CHMF3 CHMF4 6 2 0 L
+0x5101 CEMF1 CEMF2 CEMF3 CHMF4 6 2 0 M
+0x5102 CDMF1 CDMF2 CDMF3 CDMF4 6 2 0 S
+0x5103 CIMF1 CIMF2 CIMF3 CIMF4 6 2 0 S
+0x5110 CHFF1 CHFF2 CHFF3 CHFF4 6 2 0 M
+0x5111 CEFF1 CEFF2 CEFF3 CEFF4 6 2 0 M
+0x5112 CDMF1 CDMF2 CDMF3 CDMF4 6 2 0 S
+0x5113 CIFF1 CIFF2 CIFF3 CIFF4 6 2 0 S
+0x5200 CHMW1 CHMW2 CHMW3 CHMW4 6 2 0 L
+0x5201 CEMW1 CEMW2 CEMW3 CEMW4 6 2 0 M
+0x5202 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
+0x5203 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
+0x5210 CHFW1 CHFW2 CHFW3 CHFW4 6 2 0 M
+0x5211 CEFW1 CEFW2 CEFW3 CEFW4 6 2 0 M
+0x5212 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
+0x5213 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
+0x5300 CHMT1 CHMT2 CHMT2 CHMT2 6 2 0 L
+0x5301 CEMT1 CEMT2 CEMT2 CEMT2 6 2 0 M
+0x5302 CDMT1 CDMT2 CDMT2 CDMT2 6 2 0 S
+0x5303 CIMT1 CIMT2 CIMT2 CIMT2 6 2 0 S
+0x5310 CHFT1 CHFT2 CHFT2 CHFT2 6 2 0 M
+0x5311 CEFT1 CEFT2 CEFT2 CEFT2 6 2 0 M
+0x5312 CDMT1 CDMT2 CDMT2 CDMT2 6 2 0 S
+0x5313 CIFT1 CIFT2 CIFT2 CIFT2 6 2 0 S
+0x6000 CHMC1 CHMC2 CHMC3 CHMC4 6 2 0 L
+0x6001 CEMC1 CEMC2 CEMC3 CEMC4 6 2 0 M
+0x6002 CDMC1 CDMC2 CDMC3 CDMC4 6 2 0 S
+0x6003 CIMC1 CIMC2 CIMC3 CIMC4 6 2 0 S
+0x6004 CDMC1 CDMC2 CDMC3 CDMC4 6 2 0 S
+0x6005 CHMC1 CHMC2 CHMC3 CHMC4 6 2 0 L
+0x6010 CHFC1 CHFC2 CHFC3 CHFC4 6 2 0 M
+0x6011 CEFC1 CEFC2 CEFC3 CEFC4 6 2 0 M
+0x6012 CDMC1 CDMC2 CDMC3 CDMC4 6 2 0 S
+0x6013 CIFC1 CIFC2 CIFC3 CIFC4 6 2 0 S
+0x6014 CIFC1 CIFC2 CIFC3 CIFC4 6 2 0 S
+0x6015 CHFC1 CHFC2 CHFC3 CHFC4 6 2 0 L
+0x6100 CHMF1 CHMF2 CHMF3 CHMF4 6 2 0 L
+0x6101 CEMF1 CEMF2 CEMF3 CEMF4 6 2 0 M
+0x6102 CDMF1 CDMF2 CDMF3 CDMF4 6 2 0 S
+0x6103 CIMF1 CIMF2 CIMF3 CIMF4 6 2 0 S
+0x6104 CDMF1 CDMF2 CDMF3 CDMF4 6 2 0 S
+0x6105 CHMF1 CHMF2 CHMF3 CHMF4 6 2 0 L
+0x6110 CHFF1 CHFF2 CHFF3 CHFF4 6 2 0 M
+0x6111 CEFF1 CEFF2 CEFF3 CEFF4 6 2 0 M
+0x6112 CDMF1 CDMF2 CDMF3 CDMF4 6 2 0 S
+0x6113 CIFF1 CIFF2 CIFF3 CIFF4 6 2 0 S
+0x6114 CIFF1 CIFF2 CIFF3 CIFF4 6 2 0 S
+0x6115 CHFF1 CHFF2 CHFF3 CHFF4 6 2 0 L
+0x6200 CHMW1 CHMW2 CHMW3 CHMW4 6 2 0 L
+0x6201 CEMW1 CEMW2 CEMW3 CEMW4 6 2 0 M
+0x6202 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
+0x6203 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
+0x6204 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
+0x6205 CHMW1 CHMW2 CHMW3 CHMW4 6 2 0 L
+0x6210 CHFW1 CHFW2 CHFW3 CHFW4 6 2 0 M
+0x6211 CEFW1 CEFW2 CEFW3 CEFW4 6 2 0 M
+0x6212 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
+0x6213 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
+0x6214 CDMW1 CIFW2 CIFW3 CIFW4 6 2 0 S
+0x6215 CHFW1 CHFW2 CHFW3 CHFW4 6 2 0 L
+0x6300 CHMT1 CHMT2 CHMT2 CHMT2 6 2 0 L
+0x6301 CEMT1 CEMT2 CEMT2 CEMT2 6 2 0 M
+0x6302 CDMT1 CDMT2 CDMT2 CDMT2 6 2 0 S
+0x6303 CIMT1 CIMT2 CIMT2 CIMT2 6 2 0 S
+0x6304 CDMT1 CDMT2 CDMT2 CDMT2 6 2 0 S
+0x6305 CHMT1 CHMT2 CHMT2 CHMT2 6 2 0 L
+0x6310 CHFT1 CHFT2 CHFT2 CHFT2 6 2 0 M
+0x6311 CEFT1 CEFT2 CEFT2 CEFT2 6 2 0 M
+0x6312 CDMT1 CDMT2 CDMT2 CDMT2 6 2 0 S
+0x6313 CIFT1 CIFT2 CIFT2 CIFT2 6 2 0 S
+0x6314 CIFT1 CIFT2 CIFT2 CIFT2 6 2 0 S
+0x6315 CHFT1 CHFT2 CHFT2 CHFT2 6 2 0 L
+0x6400 UDRZ1 UDRZ1 UDRZ1 UDRZ1 6 2 0 *
+0x6401 UELM1 UELM1 UELM1 UELM1 6 2 1 *
+0x6402 CMNK1 CMNK1 CMNK1 CMNK1 6 2 0 *
+0x6403 MSKL1 MSKL1 MSKL1 MSKL1 6 2 1 M
+0x6404 USAR1 USAR1 USAR1 USAR1 6 2 1 *
+0x6405 MDGU1 MDGU1 MDGU1 MDGU1 6 2 0 M
+0x6406 MDGU1 MDGU1 MDGU1 MDGU1 6 2 0 L
+0x6500 CHMM1 CHMC2 CHMC3 CHMC4 0 2 0 *
+0x6510 CHFM1 CHFC2 CHFC3 CHFC4 0 2 0 *
+0x7000 MOGH MOGH MOGH MOGH 14 2 0 *
+0x7001 MOGN MOGN MOGN MOGN 14 2 0 *
+0x7100 MBAS MBAS MBAS MBAS 14 2 1 *
+0x7101 MBAS MBAS MBAS MBAS 14 2 GR *
+0x7200 MBER MBER MBER MBER 14 2 BL *
+0x7201 MBER MBER MBER MBER 14 2 1 *
+0x7202 MBER MBER MBER MBER 14 2 CA *
+0x7203 MBER MBER MBER MBER 14 2 PO *
+0x7300 MEAE MEAE MEAE MEAE 4 2 1 *
+0x7301 MEAS MEAS MEAS MEAS 4 2 1 *
+0x7302 MEAE MEAE MEAE MEAE 4 2 SH *
+0x7310 MFIE MFIE MFIE MFIE 4 2 1 *
+0x7311 MFIS MFIS MFIS MFIS 4 2 1 *
+0x7320 MAIR MAIR MAIR MAIR 4 2 1 *
+0x7321 MAIS MAIS MAIS MAIS 4 2 1 *
+0x7400 MDOG MDOG MDOG MDOG 14 2 WI *
+0x7401 MDOG MDOG MDOG MDOG 14 2 WA *
+0x7402 MDOG MDOG MDOG MDOG 14 2 MO *
+0x7500 MDOP MDOP MDOP MDOP 14 2 1 *
+0x7501 MDOP MDOP MDOP MDOP 14 2 GR *
+0x7600 METT METT METT METT 14 2 1 *
+0x7701 MGHL MGHL MGHL MGHL 14 2 1 *
+0x7702 MGHL MGHL MGHL MGHL 14 2 RE *
+0x7703 MGHL MGHL MGHL MGHL 14 2 GA *
+0x7704 MSHD MSHD MSHD MSHD 4 2 1 *
+0x7800 MGIB MGIB MGIB MGIB 14 2 1 *
+0x7900 MSLI MSLI MSLI MSLI 14 3 GR *
+0x7901 MSLI MSLI MSLI MSLI 14 3 OL *
+0x7902 MSLI MSLI MSLI MSLI 14 3 MU *
+0x7903 MSLI MSLI MSLI MSLI 14 3 OC *
+0x7904 MSLI MSLI MSLI MSLI 14 3 1 *
+0x7A00 MSPI MSPI MSPI MSPI 14 2 GI *
+0x7A01 MSPI MSPI MSPI MSPI 14 2 HU *
+0x7A02 MSPI MSPI MSPI MSPI 14 2 PH *
+0x7A03 MSPI MSPI MSPI MSPI 14 2 SW *
+0x7A04 MSPI MSPI MSPI MSPI 14 2 WR *
+0x7B00 MWLF MWLF MWLF MWLF 14 2 1 *
+0x7B01 MWLF MWLF MWLF MWLF 14 2 WO *
+0x7B02 MWLF MWLF MWLF MWLF 14 2 DI *
+0x7B03 MWLF MWLF MWLF MWLF 14 2 WI *
+0x7B04 MWLF MWLF MWLF MWLF 14 2 VA *
+0x7B05 MWLF MWLF MWLF MWLF 14 2 DR *
+0x7B06 MWLS MWLS MWLS MWLS 14 2 1 *
+0x7C00 MXVT MXVT MXVT MXVT 14 2 0 *
+0x7C01 MTAS MTAS MTAS MTAS 14 2 1 *
+0x7D00 MZOM MZOM MZOM MZOM 14 2 0 *
+0x7E00 MWER MWER MWER MWER 14 2 1 *
+0x7E01 MGWE MGWE MGWE MGWE 14 2 1 *
+0x7F00 MTRO MTRO MTRO MTRO 4 2 1 *
+0x7F01 MMIN MMIN MMIN MMIN 4 2 1 *
+0x7F02 MBEH MBEH MBEH MBEH 4 3 1 *
+0x7F03 MIMP MIMP MIMP MIMP 4 2 1 *
+0x7F04 MIGO MIGO MIGO MIGO 4 4 1 *
+0x7F05 MDJI MDJI MDJI MDJI 4 2 1 *
+0x7F06 MDJL MDJL MDJL MDJL 4 2 1 *
+0x7F07 MGLC MGLC MGLC MGLC 4 2 1 *
+0x7F08 MOTY MOTY MOTY MOTY 4 4 1 *
+0x7F09 MSAH MSAH MSAH MSAH 4 2 1 *
+0x7F0A MGCP MGCP MGCP MGCP 4 2 1 *
+0x7F0B MGCL MGCL MGCL MGCL 4 2 1 *
+0x7F0C MKUO MKUO MKUO MKUO 4 2 1 *
+0x7F0D MLIC MLIC MLIC MLIC 4 2 1 *
+0x7F0E MDLI MDLI MDLI MDLI 4 2 1 *
+0x7F0F MTRS MTRS MTRS MTRS 4 2 1 *
+0x7F10 MRAK MRAK MRAK MRAK 4 2 1 *
+0x7F11 MUMB MUMB MUMB MUMB 4 2 1 *
+0x7F12 MVAM MVAM MVAM MVAM 4 2 1 *
+0x7F13 MSNK MSNK MSNK MSNK 4 2 1 *
+0x7F14 MGIT MGIT MGIT MGIT 4 2 1 *
+0x7F15 MBES MBES MBES MBES 4 2 1 *
+0x7F16 AMOO AMOO AMOO AMOO 4 3 1 *
+0x7F17 ARAB ARAB ARAB ARAB 4 1 1 *
+0x7F18 ADER ADER ADER ADER 4 2 1 *
+0x7F19 MDSW MDSW MDSW MDSW 4 2 1 *
+0x7F20 AGRO AGRO AGRO AGRO 4 2 1 *
+0x7F21 APHE APHE APHE APHE 4 2 1 *
+0x7F22 MVAF MVAF MVAF MVAF 4 2 1 *
+0x7F23 MSAT MSAT MSAT MSAT 4 2 1 *
+0x7F24 NPIR NPIR NPIR NPIR 4 2 1 *
+0x7F27 MDRO MDRO MDRO MDRO 4 2 1 *
+0x7F28 MKUL MKUL MKUL MKUL 4 2 1 *
+0x7F29 MFDR MFDR MFDR MFDR 4 2 1 *
+0x7F2A NSAI NSAI NSAI NSAI 4 2 1 *
+0x7F2C NSOL NSOL NSOL NSOL 4 2 1 *
+0x7F2D MWFM MWFM MWFM MWFM 4 2 1 *
+0x7F2E MRAV MRAV MRAV MRAV 4 3 1 *
+0x7F2F MSPS MSPS MSPS MSPS 4 2 1 *
+0x7F30 NBOH NBOH NBOH NBOH 4 2 1 *
+0x7F31 NELL NELL NELL NELL 4 2 1 *
+0x7F32 MSLY MSLY MSLY MSLY 4 2 1 *
+0x7F35 MMIS MMIS MMIS MMIS 4 2 1 *
+0x7F36 NSHD NSHD NSHD NSHD 4 2 1 *
+0x7F37 NIRE NIRE NIRE NIRE 4 2 1 *
+0x8000 MGNL MGNL MGNL MGNL 2 2 0 +
+0x8100 MHOB MHOB MHOB MHOB 2 2 0 +
+0x8200 MKOB MKOB MKOB MKOB 2 2 0 +
+0x9000 MOGR MOGR MOGR MOGR 5 2 0 *
+0xA000 MWYV MWYV MWYV MWYV 8 3 1 *
+0xA100 MCAR MCAR MCAR MCAR 8 3 1 *
+0xB000 ACOW ACOW ACOW ACOW 10 3 1 *
+0xB100 AHRS AHRS AHRS AHRS 10 3 1 *
+0xB200 NBEG NBEG NBEG NBEG 18 2 0 *
+0xB210 NPRO NPRO NPRO NPRO 18 2 0 *
+0xB300 NBOY NBOY NBOY NBOY 18 2 0 *
+0xB310 NGRL NGRL NGRL NGRL 18 2 0 *
+0xB400 NFAM NFAM NFAM NFAM 18 2 0 *
+0xB410 NFAW NFAW NFAW NFAW 18 2 0 *
+0xB500 NSIM NSIM NSIM NSIM 18 2 0 *
+0xB510 NSIW NSIW NSIW NSIW 18 2 0 *
+0xB600 NNOM NNOM NNOM NNOM 18 2 0 *
+0xB610 NNOW NNOW NNOW NNOW 18 2 0 *
+0xB700 NSLV NSLV NSLV NSLV 18 2 0 *
+0xC000 ABAT ABAT ABAT ABAT 3 1 1 *
+0xC100 ACAT ACAT ACAT ACAT 3 1 1 *
+0xC200 ACHK ACHK ACHK ACHK 3 1 1 *
+0xC300 ARAT ARAT ARAT ARAT 3 1 1 *
+0xC400 ASQU ASQU ASQU ASQU 3 1 1 *
+0xC500 ABAT ABAT ABAT ABAT 3 1 1 *
+0xC600 NBEG NBEG NBEG NBEG 18 2 0 *
+0xC610 NPRO NPRO NPRO NPRO 18 2 0 *
+0xC700 NBOY NBOY NBOY NBOY 18 2 0 *
+0xC710 NGRL NGRL NGRL NGRL 18 2 0 *
+0xC800 NFAM NFAM NFAM NFAM 18 2 0 *
+0xC810 NFAW NFAW NFAW NFAW 18 2 0 *
+0xC900 NSIM NSIM NSIM NSIM 18 2 0 *
+0xC910 NSIW NSIW NSIW NSIW 18 2 0 *
+0xCA00 NNOM NNOM NNOM NNOM 18 2 0 *
+0xCA10 NNOW NNOW NNOW NNOW 18 2 0 *
+0xCB00 NSLV NSLV NSLV NSLV 18 2 0 *
+0xD000 AEAGG1 AEAGG1 AEAGG1 AEAGG1 7 0 1 *
+0xD100 AGULG1 AGULG1 AGULG1 AGULG1 7 0 1 *
+0xD200 AVULG1 AVULG1 AVULG1 AVULG1 7 0 1 *
+0xD300 ABIRG1 ABIRG1 ABIRG1 ABIRG1 7 0 1 *
+0xD400 ABIRG1 ABIRG1 ABIRG1 ABIRG1 7 0 1 *
+0xE000 MCYC MCYC MCYC MCYC 9 4 1 *
+0xE010 METN METN METN METN 9 4 1 *
+0xE020 MTAN MTAN MTAN MTAN 9 4 1 *
+0xE040 MHIS MHIS MHIS MHIS 9 2 1 *
+0xE050 MLER MLER MLER MLER 9 2 1 *
+0xE060 MLIC MLIC MLIC MLIC 9 2 1 *
+0xE070 MMIN MMIN MMIN MMIN 9 2 1 *
+0xE080 MMUM MMUM MMUM MMUM 9 2 1 *
+0xE090 MMER MMER MMER MMER 9 2 1 *
+0xE0A0 MTIC MTIC MTIC MTIC 9 2 1 *
+0xE0B0 MTRO MTRO MTRO MTRO 9 2 1 *
+0xE0C0 MTSN MTSN MTSN MTSN 9 2 1 *
+0xE0D0 MUMB MUMB MUMB MUMB 9 2 1 *
+0xE0E0 MCOR MCOR MCOR MCOR 9 2 1 *
+0xE0F0 MGIC MGIC MGIC MGIC 9 2 1 *
+0xE0F1 MGLA MGLA MGLA MGLA 9 2 1 *
+0xE0F2 MWAV MWAV MWAV MWAV 9 2 1 *
+0xE200 MBET MBET MBET MBET 9 2 1 *
+0xE210 MBFI MBFI MBFI MBFI 9 2 1 *
+0xE220 MBBM MBBM MBBM MBBM 9 2 1 *
+0xE230 MBRH MBRH MBRH MBRH 9 5 1 *
+0xE300 MGHO MGHO MGHO MGHO 9 2 1 *
+0xE310 MGH2 MGH2 MGH2 MGH2 9 2 1 *
+0xE320 MGH3 MGH3 MGH3 MGH3 9 2 1 *
+0xE400 MGO1 MGO1 MGO1 MGO1 9 2 1 *
+0xE410 MGO2 MGO2 MGO2 MGO2 9 2 1 *
+0xE420 MGO3 MGO3 MGO3 MGO3 9 2 1 *
+0xE430 MGO4 MGO4 MGO4 MGO4 9 2 1 *
+0xE500 MLIZ MLIZ MLIZ MLIZ 9 2 1 *
+0xE510 MLI2 MLI2 MLI2 MLI2 9 2 1 *
+0xE520 MLI3 MLI3 MLI3 MLI3 9 2 1 *
+0xE600 MMYC MMYC MMYC MMYC 9 2 1 *
+0xE610 MMY2 MMY2 MMY2 MMY2 9 2 1 *
+0xE700 MNO1 MNO1 MNO1 MNO1 9 2 1 *
+0xE710 MNO2 MNO2 MNO2 MNO2 9 2 1 *
+0xE720 MNO3 MNO3 MNO3 MNO3 9 2 1 *
+0xE800 MOR1 MOR1 MOR1 MOR1 9 2 1 *
+0xE810 MOR2 MOR2 MOR2 MOR2 9 2 1 *
+0xE820 MOR3 MOR3 MOR3 MOR3 9 2 1 *
+0xE830 MOR4 MOR4 MOR4 MOR4 9 2 1 *
+0xE840 MOR5 MOR5 MOR5 MOR5 9 2 1 *
+0xE900 MSAL MSAL MSAL MSAL 9 2 1 *
+0xE910 MSA2 MSA2 MSA2 MSA2 9 2 1 *
+0xEA00 MSHR MSHR MSHR MSHR 9 2 1 *
+0xEA10 MSH1 MSH1 MSH1 MSH1 9 2 1 *
+0xEA20 MSH2 MSH2 MSH2 MSH2 9 2 1 *
+0xEB00 MSKT MSKT MSKT MSKT 9 2 1 *
+0xEB10 MSKA MSKA MSKA MSKA 9 2 1 *
+0xEB20 MSKB MSKB MSKB MSKB 9 2 1 *
+0xEC00 MWIG MWIG MWIG MWIG 9 2 1 *
+0xEC10 MWI2 MWI2 MWI2 MWI2 9 2 1 *
+0xEC20 MWI3 MWI3 MWI3 MWI3 9 2 1 *
+0xED00 MYU1 MYU1 MYU1 MYU1 9 2 1 *
+0xED10 MYU2 MYU2 MYU2 MYU2 9 2 1 *
+0xED20 MYU3 MYU3 MYU3 MYU3 9 2 1 *
+0xEE00 MZO2 MZO2 MZO2 MZO2 9 2 1 *
+0xEE10 MZO3 MZO3 MZO3 MZO3 9 2 1 *
+0xEF00 MWWE MWWE MWWE MWWE 9 2 1 *
diff --git a/gemrb/override/bg1/avprefc.2da b/gemrb/unhardcoded/bg1/avprefc.2da
similarity index 100%
rename from gemrb/override/bg1/avprefc.2da
rename to gemrb/unhardcoded/bg1/avprefc.2da
diff --git a/gemrb/override/bg1/avprefr.2da b/gemrb/unhardcoded/bg1/avprefr.2da
similarity index 100%
rename from gemrb/override/bg1/avprefr.2da
rename to gemrb/unhardcoded/bg1/avprefr.2da
diff --git a/gemrb/override/bg1/axe.pro b/gemrb/unhardcoded/bg1/axe.pro
similarity index 100%
rename from gemrb/override/bg1/axe.pro
rename to gemrb/unhardcoded/bg1/axe.pro
diff --git a/gemrb/override/bg1/axeex.pro b/gemrb/unhardcoded/bg1/axeex.pro
similarity index 100%
rename from gemrb/override/bg1/axeex.pro
rename to gemrb/unhardcoded/bg1/axeex.pro
diff --git a/gemrb/unhardcoded/bg1/bios.2da b/gemrb/unhardcoded/bg1/bios.2da
new file mode 100644
index 0000000..62b8a76
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/bios.2da
@@ -0,0 +1,24 @@
+2DA V1.0
+15889
+ CLASS BIO
+0 * *
+1 MAGE 15882
+2 FIGHTER 15881
+3 PRIEST 15884
+4 THIEF 15883
+5 BARD 15886
+6 PALADIN 15887
+7 FIGHTER_MAGE 15889
+8 FIGHTER_CLERIC 15889
+9 FIGHTER_THIEF 15889
+10 FIGHTER_MAGE_THIEF 15889
+11 DRUID 15885
+12 RANGER 15888
+13 MAGE_THIEF 15889
+14 CLERIC_MAGE 15889
+15 CLERIC_THIEF 15889
+16 FIGHTER_DRUID 15889
+17 FIGHTER_MAGE_CLERIC 15889
+18 CLERIC_RANGER 15889
+19 SORCERER *
+20 MONK *
diff --git a/gemrb/unhardcoded/bg1/bloodclr.2da b/gemrb/unhardcoded/bg1/bloodclr.2da
new file mode 100644
index 0000000..5d10be9
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/bloodclr.2da
@@ -0,0 +1,29 @@
+2DA V1.0
+0
+ VALUE MIN MAX FLAGS
+NORMAL 0x2f 0x1000 0xffff 0
+PURPLE 0x2d 0x4300 0x43ff 0
+MSKEL 0x25 0x5403 0x5403 1
+DOOMG 0x22 0x5405 0x5406 1
+MSKEL 0x25 0x6403 0x6403 1
+DOOMG 0x22 0x6405 0x6406 1
+YELLOW 0x32 0x7300 0x73ff 0
+PURPLE 0x3c 0x7500 0x75ff 0
+YELLOW 0x32 0x7600 0x76ff 1
+BLACK 0x66 0x7700 0x77ff 1
+SLI_GR 7 0x7900 0x7900 1
+SLI_OL 0x24 0x7901 0x7901 1
+SLI_MU 0x33 0x7902 0x7902 1
+SLI_OC 0x25 0x7903 0x7903 1
+SLIME 0x1b 0x7904 0x7904 1
+SPIDER 0x33 0x7a00 0x7aff 1
+ZOMBIE 0x25 0x7c00 0x7cff 1
+MTRO 0x33 0x7f00 0x7f00 0
+MMIN 0x3d 0x7f01 0x7f03 0
+MIGO 0x1a 0x7f04 0x7f04 1
+MGLC 0x5d 0x7f07 0x7f07 0
+MTRS 0x32 0x7f0f 0x7f0f 0
+MBES 0x3d 0x7f15 0x7f15 0
+MCAR 0x38 0xa100 0xa1ff 0
+UNDEAD 0x66 0xe300 0xe3ff 1
+MWWE 0x38 0xef00 0xefff 1
diff --git a/gemrb/override/bg1/bolt.pro b/gemrb/unhardcoded/bg1/bolt.pro
similarity index 100%
rename from gemrb/override/bg1/bolt.pro
rename to gemrb/unhardcoded/bg1/bolt.pro
diff --git a/gemrb/override/bg1/boltex.pro b/gemrb/unhardcoded/bg1/boltex.pro
similarity index 100%
rename from gemrb/override/bg1/boltex.pro
rename to gemrb/unhardcoded/bg1/boltex.pro
diff --git a/gemrb/override/bg1/bullet.pro b/gemrb/unhardcoded/bg1/bullet.pro
similarity index 100%
rename from gemrb/override/bg1/bullet.pro
rename to gemrb/unhardcoded/bg1/bullet.pro
diff --git a/gemrb/override/bg1/bulletex.pro b/gemrb/unhardcoded/bg1/bulletex.pro
similarity index 100%
rename from gemrb/override/bg1/bulletex.pro
rename to gemrb/unhardcoded/bg1/bulletex.pro
diff --git a/gemrb/override/bg1/cgtable.2da b/gemrb/unhardcoded/bg1/cgtable.2da
similarity index 100%
rename from gemrb/override/bg1/cgtable.2da
rename to gemrb/unhardcoded/bg1/cgtable.2da
diff --git a/gemrb/override/bg1/chromorb.pro b/gemrb/unhardcoded/bg1/chromorb.pro
similarity index 100%
rename from gemrb/override/bg1/chromorb.pro
rename to gemrb/unhardcoded/bg1/chromorb.pro
diff --git a/gemrb/unhardcoded/bg1/clabdrui.2da b/gemrb/unhardcoded/bg1/clabdrui.2da
new file mode 100644
index 0000000..441317c
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/clabdrui.2da
@@ -0,0 +1,6 @@
+2DA V1.0
+****
+ 1 2 3 4 5 6 7
+ABILITY1 **** **** **** **** **** **** GA_SPIN107
+ABILITY2 **** **** **** **** **** **** GA_SPIN110
+ABILITY3 **** **** **** **** **** **** GA_SPIN111
diff --git a/gemrb/unhardcoded/bg1/clabpala.2da b/gemrb/unhardcoded/bg1/clabpala.2da
new file mode 100644
index 0000000..e251a53
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/clabpala.2da
@@ -0,0 +1,6 @@
+2DA V1.0
+****
+ 1
+ABILITY1 GA_SPIN109
+ABILITY2 GA_SPIN120
+ABILITY3 GA_SPIN121
diff --git a/gemrb/unhardcoded/bg1/clabrngr.2da b/gemrb/unhardcoded/bg1/clabrngr.2da
new file mode 100644
index 0000000..a8dc46a
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/clabrngr.2da
@@ -0,0 +1,4 @@
+2DA V1.0
+****
+ 1
+ABILITY1 GA_SPIN108
diff --git a/gemrb/override/bg1/classes.2da b/gemrb/unhardcoded/bg1/classes.2da
similarity index 100%
rename from gemrb/override/bg1/classes.2da
rename to gemrb/unhardcoded/bg1/classes.2da
diff --git a/gemrb/override/bg1/cloud.pro b/gemrb/unhardcoded/bg1/cloud.pro
similarity index 100%
rename from gemrb/override/bg1/cloud.pro
rename to gemrb/unhardcoded/bg1/cloud.pro
diff --git a/gemrb/override/bg1/cloudkil.pro b/gemrb/unhardcoded/bg1/cloudkil.pro
similarity index 100%
rename from gemrb/override/bg1/cloudkil.pro
rename to gemrb/unhardcoded/bg1/cloudkil.pro
diff --git a/gemrb/override/bg1/clowncol.2da b/gemrb/unhardcoded/bg1/clowncol.2da
similarity index 100%
rename from gemrb/override/bg1/clowncol.2da
rename to gemrb/unhardcoded/bg1/clowncol.2da
diff --git a/gemrb/unhardcoded/bg1/clskills.2da b/gemrb/unhardcoded/bg1/clskills.2da
new file mode 100644
index 0000000..3257405
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/clskills.2da
@@ -0,0 +1,25 @@
+2DA V1.0
+*
+ DRUIDSPELL CLERICSPELL MAGESPELL BARDSKILL THIEFSKILL LAYHANDS TURNLEVEL BOOKTYPE HATERACE ABILITIES SAVEBONUS NO_PROF
+UNUSED * * * * * * 0 0 * * * *
+MAGE * * MXSPLWIZ * * * 0 1 * * 0 -4
+FIGHTER * * * * * * 0 0 * * 0 -2
+CLERIC * MXSPLPRS * * * * 1 1 * * 0 -3
+THIEF * * * * SKILLS * 0 0 * * 0 -3
+BARD * * MXSPLBRD SKILLBRD * * 0 1 * * 0 -3
+PALADIN * MXSPLPAL * * * PALADIN 5 1 * CLABPALA 2 -2
+FIGHTER_MAGE * * MXSPLWIZ * * * 0 1 * * 0 -2
+FIGHTER_CLERIC * MXSPLPRS * * * * 0 1 * * 0 -2
+FIGHTER_THIEF * * * * SKILLS * 0 0 * * 0 -2
+FIGHTER_MAGE_THIEF * * MXSPLWIZ * SKILLS * 0 1 * * 0 -2
+DRUID MXSPLPRS * * * * * 0 1 * CLABDRUI 0 -3
+RANGER MXSPLRAN * * * * * 0 1 HATERACE CLABRNGR 0 -2
+MAGE_THIEF * * MXSPLWIZ * SKILLS * 0 1 * * 0 -3
+CLERIC_MAGE * MXSPLPRS MXSPLWIZ * * * 0 1 * * 0 -3
+CLERIC_THIEF * MXSPLPRS * * SKILLS * 0 1 * * 0 -3
+FIGHTER_DRUID MXSPLPRS * * * * * 0 1 * *,DRUI 0 -2
+FIGHTER_MAGE_CLERIC * MXSPLPRS MXSPLWIZ * * * 0 1 * * 0 -2
+CLERIC_RANGER MXSPLRAN MXSPLPRS * * * * 0 1 HATERACE *,RNGR 0 -2
+SORCERER * * MXSPLSRC * * * 0 2 * * 0 -4
+MONK * * * * SKILLS * 0 0 * * 0 -3
+
diff --git a/gemrb/override/bg1/dagger.pro b/gemrb/unhardcoded/bg1/dagger.pro
similarity index 100%
rename from gemrb/override/bg1/dagger.pro
rename to gemrb/unhardcoded/bg1/dagger.pro
diff --git a/gemrb/override/bg1/daggerex.pro b/gemrb/unhardcoded/bg1/daggerex.pro
similarity index 100%
rename from gemrb/override/bg1/daggerex.pro
rename to gemrb/unhardcoded/bg1/daggerex.pro
diff --git a/gemrb/unhardcoded/bg1/damage.2da b/gemrb/unhardcoded/bg1/damage.2da
new file mode 100644
index 0000000..e0fef47
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/damage.2da
@@ -0,0 +1,16 @@
+2DA V1.0
+*
+ MAIN SPARKS GRADIENT
+CRIT BLOODCR * 47
+SMALL BLOODS * 47
+MEDIUM BLOODM * 47
+LARGE BLOODL * 47
+FIRES SPFIRIMP SPBURN 19
+FIREM SPFIRIMP SPBURN 19
+FIREL SPFIRIMP SPBURN 19
+SPARKS SPSHKIMP SPSPARKS -1
+SPARKM SPSHKIMP SPSPARKS -1
+SPARKL SPSHKIMP SPSPARKS -1
+ICES SPFIRIMP * 71
+ICEM SPFIRIMP * 71
+ICEL SPFIRIMP * 71
diff --git a/gemrb/override/bg1/dart.pro b/gemrb/unhardcoded/bg1/dart.pro
similarity index 100%
rename from gemrb/override/bg1/dart.pro
rename to gemrb/unhardcoded/bg1/dart.pro
diff --git a/gemrb/override/bg1/dartex.pro b/gemrb/unhardcoded/bg1/dartex.pro
similarity index 100%
rename from gemrb/override/bg1/dartex.pro
rename to gemrb/unhardcoded/bg1/dartex.pro
diff --git a/gemrb/unhardcoded/bg1/defsound.2da b/gemrb/unhardcoded/bg1/defsound.2da
new file mode 100644
index 0000000..eb499b5
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/defsound.2da
@@ -0,0 +1,36 @@
+2DA V1.0
+*
+ RESREF
+OPEN AMB_D03A
+CLOSE AMB_D03B
+HOPEN AMB_D04A
+HCLOSE AMB_D04B
+BUTTON1 GAM_09
+BUTTON2 GAM_03
+BUTTON3 GAM_04
+OPENFAIL *
+CLOSEFAIL *
+ITEM_GONE EFF_M02
+SECRET ACT_09
+PICKLOCK AMB_D21D
+PICKFAIL AMB_D21
+13 *
+14 *
+15 *
+16 *
+17 *
+18 *
+19 *
+LIGHTNING1 AMB_E13A
+LIGHTNING2 AMB_E13B
+LIGHTNING3 AMB_E13F
+RAIN AMB_E11
+SNOW AMB_E02B
+SOLD ACT_03D
+STOLEN GAM_36
+DRUNK GAM_07
+DONATE1 ACT_03
+DONATE2 ACT_03E
+IDENTIFY CAS_P04
+GOTXP *
+TOOLTIP PAPER
diff --git a/gemrb/unhardcoded/bg1/difflvls.2da b/gemrb/unhardcoded/bg1/difflvls.2da
new file mode 100644
index 0000000..d71ae9a
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/difflvls.2da
@@ -0,0 +1,5 @@
+2DA V1.0
+0
+ DEFAULT EASY NORMAL CORE HARD NIGHTMARE
+DMG 0 -50 -25 0 50 100
+XP 0 -50 0 0 0 0
diff --git a/gemrb/unhardcoded/bg1/dsclass.2da b/gemrb/unhardcoded/bg1/dsclass.2da
new file mode 100644
index 0000000..1d498b7
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/dsclass.2da
@@ -0,0 +1,24 @@
+2DA V1.0
+0
+ CLASS BONUS
+MAGE 1 5
+FIGHTER 2 10
+CLERIC 3 10
+THIEF 4 15
+BARD 5 15
+PALADIN 6 10
+FM 7 10
+FC 8 10
+FT 9 15
+FMT 10 15
+DRUID 11 10
+RANGER 12 10
+MT 13 15
+CM 14 10
+CT 15 15
+FD 16 10
+FMC 17 10
+CR 18 10
+SORC 19 5
+MONK 20 15
+
diff --git a/gemrb/unhardcoded/bg1/dsrace.2da b/gemrb/unhardcoded/bg1/dsrace.2da
new file mode 100644
index 0000000..5fb3c47
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/dsrace.2da
@@ -0,0 +1,7 @@
+2DA V1.0
+0
+ RACE BONUS
+ELF 2 20
+DWARF 4 10
+HALFLING 5 5
+
diff --git a/gemrb/unhardcoded/bg1/dstable.2da b/gemrb/unhardcoded/bg1/dstable.2da
new file mode 100644
index 0000000..b2d0df7
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/dstable.2da
@@ -0,0 +1,6 @@
+2DA V1.0
+*
+FILE STAT
+dsclass CLASS
+dsrace RACE
+
diff --git a/gemrb/override/bg1/dualclas.2da b/gemrb/unhardcoded/bg1/dualclas.2da
similarity index 100%
rename from gemrb/override/bg1/dualclas.2da
rename to gemrb/unhardcoded/bg1/dualclas.2da
diff --git a/gemrb/unhardcoded/bg1/effects.ids b/gemrb/unhardcoded/bg1/effects.ids
new file mode 100644
index 0000000..c4b8024
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/effects.ids
@@ -0,0 +1,319 @@
+IDS
+0x0 ACVsDamageTypeModifier
+0x1 AttacksPerRoundModifier
+0x2 Cure:Sleep
+0x3 State:Berserk
+0x4 Cure:Berserk
+0x5 State:Charmed
+0x6 CharismaModifier
+0x7 Color:SetPalette
+0x8 Color:SetRGB
+0x9 Color:PulseRGB
+0xa ConstitutionModifier
+0xb Cure:Poison
+0xc Damage
+0xd Death
+0xe Cure:Defrost
+0xf DexterityModifier
+0x10 State:Hasted
+0x11 CurrentHPModifier
+0x12 MaximumHPModifier
+0x13 IntelligenceModifier
+0x14 State:Invisible
+0x15 LoreModifier
+0x16 LuckModifier
+0x17 MoraleModifier
+0x18 State:Panic
+0x19 State:Poisoned
+0x1a RemoveCurse
+0x1b AcidResistanceModifier
+0x1c ColdResistanceModifier
+0x1d ElectricityResistanceModifier
+0x1e FireResistanceModifier
+0x1f MagicDamageResistanceModifier
+0x20 Cure:Death
+0x21 SaveVsDeathModifier
+0x22 SaveVsWandsModifier
+0x23 SaveVsPolyModifier
+0x24 SaveVsBreathModifier
+0x25 SaveVsSpellsModifier
+0x26 State:Silenced
+0x27 State:Helpless
+0x28 State:Slowed
+0x29 Sparkle
+0x2a WizardSpellSlotsModifier
+0x2b Cure:Petrification
+0x2c StrengthModifier
+0x2d State:Stun
+0x2e Cure:Stun
+0x2f Cure:Invisible
+0x30 Cure:Silence
+0x31 WisdomModifier
+0x32 Color:BriefRGB
+0x33 Color:DarkenRGB
+0x34 Color:GlowRGB
+0x35 AnimationIDModifier
+0x36 ToHitModifier
+0x37 KillCreatureType
+0x38 Alignment:Invert
+0x39 Alignment:Change
+0x3a DispelEffects
+0x3b StealthModifier
+0x3c MiscastMagicModifier
+0x3d AlchemyModifier
+0x3e PriestSpellSlotsModifier
+0x3f State:Infravision
+0x40 Cure:Infravision
+0x41 State:Blur
+0x42 TransparencyModifier
+0x43 SummonCreature
+0x44 UnsummonCreature
+0x45 State:NonDetection
+0x46 Cure:NonDetection
+0x47 SexModifier
+0x48 AIIdentifierModifier
+0x49 DamageBonusModifier
+0x4a State:Blind
+0x4b Cure:Blind
+0x4c State:Feeblemind
+0x4d Cure:Feeblemind
+0x4e State:Diseased
+0x4f Cure:Disease
+0x50 State:Deafness
+0x51 Cure:Deafness
+0x52 SetAIScript
+0x53 Protection:Projectile
+0x54 MagicalFireResistanceModifier
+0x55 MagicalColdResistanceModifier
+0x56 SlashingResistanceModifier
+0x57 CrushingResistanceModifier
+0x58 PiercingResistanceModifier
+0x59 MissilesResistanceModifier
+0x5a OpenLocksModifier
+0x5b FindTrapsModifier
+0x5c PickPocketsModifier
+0x5d FatigueModifier
+0x5e IntoxicationModifier
+0x5f TrackingModifier
+0x60 LevelModifier
+0x61 StrengthBonusModifier
+0x62 State:Regenerating
+0x63 SpellDurationModifier
+0x64 Protection:Creature
+0x65 Protection:Opcode
+0x66 Protection:SpellLevel
+0x67 ChangeName
+0x68 ExperienceModifier
+0x69 GoldModifier
+0x6a MoraleBreakModifier
+0x6b PortraitChange
+0x6c ReputationModifier
+0x6d State:HoldNoIcon
+0x6e RetreatFrom2
+0x6f Item:CreateMagic
+0x70 Item:Remove
+0x71 Item:Equip
+0x72 Dither
+0x73 DetectAlignment
+0x74 Cure:Invisible2
+0x75 Reveal:Area
+0x76 Reveal:Creatures
+0x77 MirrorImage
+0x78 Protection:Weapons
+0x79 VisualAnimationEffect
+0x7a Item:CreateInventory
+0x7b Item:RemoveInventory
+0x7c DimensionDoor
+0x7d Unlock
+0x7e MovementRateModifier
+0x7f MonsterSummoning
+0x80 State:Confused
+0x81 AidNonCumulative
+0x82 BlessNonCumulative
+0x83 ChantNonCumulative
+0x84 HolyNonCumulative
+0x85 LuckNonCumulative
+0x86 State:Petrification
+0x87 Polymorph
+0x88 ForceVisible
+0x89 ChantBadNonCumulative
+0x8a AnimationStateChange
+0x8b DisplayString
+0x8c CastingGlow
+0x8d VisualSpellHit
+0x8e Icon:Display
+0x8f Item:CreateInSlot
+0x90 DisableButton
+0x91 DisableCasting
+0x92 Spell:Cast
+0x93 Spell:Learn
+0x94 Spell:CastPoint
+0x95 Identify
+0x96 FindTraps
+0x97 ReplaceCreature
+0x98 PlayMovie
+0x99 Overlay:Sanctuary
+0x9a Overlay:Entangle
+0x9b Overlay:MinorGlobe
+0x9c Overlay:ShieldGlobe
+0x9d Overlay:Web
+0x9e Overlay:Grease
+0x9f MirrorImageModifier
+0xa0 Cure:Sanctuary
+0xa1 Cure:Panic
+0xa2 Cure:Hold
+0xa3 FreeAction
+0xa4 Cure:Intoxication
+0xa5 PauseTarget
+0xa6 MagicResistanceModifier
+0xa7 MissileHitModifier
+0xa8 RemoveCreature
+0xa9 Icon:Disable
+0xaa DamageAnimation
+0xab Spell:Add
+0xac Spell:Remove
+0xad PoisonResistanceModifier
+0xae PlaySound
+0xaf State:Hold
+0xb0 MovementRateModifier2
+0xb1 ApplyEffect
+0xb2 ToHitVsCreature
+0xb3 DamageVsCreature
+0xb4 CantUseItem
+0xb5 CantUseItemType
+0xb6 ApplyEffectItem
+0xb7 ApplyEffectItemType
+0xb8 DontJumpModifier
+0xb9 State:Hold2
+0xba MoveToArea
+0xbb Variable:StoreLocalVariable
+0xbc AuraCleansingModifier
+0xbd CastingSpeedModifier
+0xbe AttackSpeedModifier
+0xbf CastingLevelModifier
+0xc0 FindFamiliar
+0xc1 InvisibleDetection
+0xc2 IgnoreDialogPause
+0xc3 FamiliarBond
+0xc4 FamiliarMarker
+0xc5 Bounce:Projectile
+0xc6 Bounce:Opcode
+0xc7 Bounce:SpellLevel
+0xc8 Bounce:SpellLevelDec
+0xc9 Protection:SpellLevelDec
+0xca Bounce:School
+0xcb Bounce:SecondaryType
+0xcc Protection:School
+0xcd Protection:SecondaryType
+0xce Protection:Spell
+0xcf Bounce:Spell
+0xd0 MinimumHPModifier
+0xd1 PowerWordKill
+0xd2 PowerWordStun
+0xd3 State:Imprisonment
+0xd4 Cure:Imprisonment
+0xd5 Maze
+0xd6 CastFromList
+0xd7 PlayVisualEffect
+0xd8 LevelDrainModifier
+0xd9 PowerWordSleep
+0xda StoneskinModifier
+0xdb ACVsCreatureType
+0xdc DispelSchool
+0xdd DispelSecondaryType
+0xde RandomTeleport
+0xdf Protection:SchoolDec
+0xe0 Cure:LevelDrain
+0xe1 Reveal:Magic
+0xe2 Protection:SecondaryTypeDec
+0xe3 Bounce:SchoolDec
+0xe4 Bounce:SecondaryTypeDec
+0xe5 DispelSchoolOne
+0xe6 DispelSecondaryTypeOne
+0xe7 TimeStop
+0xe8 CastSpellOnCondition
+0xe9 Proficiency
+0xea CreateContingency
+0xeb WingBuffet
+0xec ProjectImage
+0xed PuppetMarker
+0xee Disintegrate
+0xef Farsee
+0xf0 Icon:Remove
+0xf1 ControlCreature
+0xf2 Cure:Confusion
+0xf3 DrainItems
+0xf4 DrainSpells
+0xf5 CheckForBerserkModifier
+0xf6 BerserkStage1Modifier
+0xf7 BerserkStage2Modifier
+0xf8 SetMeleeEffect
+0xf9 SetRangedEffect
+0xfa DamageLuckModifier
+0xfb ChangeBardSong
+0xfc SetTrap
+0xfd SetMapNote
+0xfe RemoveMapNote
+0xff Item:CreateDays
+0x100 Sequencer:Store
+0x101 Sequencer:Create
+0x102 Sequencer:Activate
+0x103 SpellTrap
+0x104 *Crash*
+0x105 RestoreSpells
+0x106 VisualRangeModifier
+0x107 BackstabModifier
+0x108 DropWeapon
+0x109 ModifyGlobalVariable
+0x10a RemoveImmunity
+0x10b Protection:String
+0x10c ExploreModifier
+0x10d ScreenShake
+0x10e Cure:CasterHold
+0x10f SummonDisable
+0x110 ApplyEffectRepeat
+0x111 RemoveProjectile
+0x112 TeleportToTarget
+0x113 HideInShadowsModifier
+0x114 DetectIllusionsModifier
+0x115 SetTrapsModifier
+0x116 ToHitBonusModifier
+0x117 RenableButton
+0x118 ForceSurgeModifier
+0x119 WildSurgeModifier
+0x11a ScriptingState
+0x11b ApplyEffectCurse
+0x11c MeleeHitModifier
+0x11d MeleeDamageModifier
+0x11e MissileDamageModifier
+0x11f NoCircleState
+0x120 FistHitModifier
+0x121 FistDamageModifier
+0x122 TitleModifier
+0x123 DisableOverlay
+0x124 Protection:Backstab
+0x125 OffscreenAIModifier
+0x126 ExistanceDelayModifier
+0x127 DisableChunk
+0x128 Protection:Animation
+0x129 Protection:Turn
+0x12a Cutscene2
+0x12b ChaosShieldModifier
+0x12c NPCBump
+0x12d CriticalHitModifier
+0x12e CanUseAnyItem
+0x12f AlwaysBackstab
+0x130 MassRaiseDead
+0x131 OffhandHitModifier
+0x132 RightHitModifier
+0x133 Reveal:Tracks
+0x134 Protection:Tracking
+0x135 ModifyLocalVariable
+0x136 TimelessState
+0x137 GenerateWish
+0x138 *Crash*
+0x139 HLA
+0x13a StoneSkin2Modifier
+0x13b AvatarRemovalModifier
+0x13c MagicalRest
+0x13d State:Haste2
diff --git a/gemrb/override/bg1/fireball.pro b/gemrb/unhardcoded/bg1/fireball.pro
similarity index 100%
rename from gemrb/override/bg1/fireball.pro
rename to gemrb/unhardcoded/bg1/fireball.pro
diff --git a/gemrb/override/bg1/fireblic.pro b/gemrb/unhardcoded/bg1/fireblic.pro
similarity index 100%
rename from gemrb/override/bg1/fireblic.pro
rename to gemrb/unhardcoded/bg1/fireblic.pro
diff --git a/gemrb/override/bg1/firebolt.pro b/gemrb/unhardcoded/bg1/firebolt.pro
similarity index 100%
rename from gemrb/override/bg1/firebolt.pro
rename to gemrb/unhardcoded/bg1/firebolt.pro
diff --git a/gemrb/override/bg1/firebtbl.pro b/gemrb/unhardcoded/bg1/firebtbl.pro
similarity index 100%
rename from gemrb/override/bg1/firebtbl.pro
rename to gemrb/unhardcoded/bg1/firebtbl.pro
diff --git a/gemrb/override/bg1/firestor.pro b/gemrb/unhardcoded/bg1/firestor.pro
similarity index 100%
rename from gemrb/override/bg1/firestor.pro
rename to gemrb/unhardcoded/bg1/firestor.pro
diff --git a/gemrb/override/bg1/fistweap.2da b/gemrb/unhardcoded/bg1/fistweap.2da
similarity index 100%
rename from gemrb/override/bg1/fistweap.2da
rename to gemrb/unhardcoded/bg1/fistweap.2da
diff --git a/gemrb/unhardcoded/bg1/fonts.2da b/gemrb/unhardcoded/bg1/fonts.2da
new file mode 100644
index 0000000..66cd616
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/fonts.2da
@@ -0,0 +1,17 @@
+2DA V1.0
+NORMAL
+ RESREF NEED_PALETTE FONT_NAME PT_SIZE STYLE COLOR
+0 NORMAL 1 NORMAL 14 0 0xffffffff
+1 TOOLFONT 1 TOOLFONT 14 0 0xffffffff
+2 NUMBER 0 NUMBER 14 0 0xffffffff
+3 INITIALS 0 INITIALS 14 0 0xffffffff
+4 NUMBER2 0 NUMBER2 14 0 0xffffffff
+5 NUMBER3 0 NUMBER3 14 0 0xffffffff
+6 REALMS 0 REALMS 14 0 0xffffffff
+7 STONEBIG 0 STONEBIG 14 0 0xffffffff
+8 STONESML 0 STONESML 14 0 0xffffffff
+# state "fonts" are the status icons. You probably don't want to edit these.
+9 STATES 0 STATES 14 0 0xffffffff
+10 STATES2 0 STATES2 14 0 0xffffffff
+
+# Customization How To: http://gemrb.sourceforge.net/wiki/doku.php?id=plugins:ttf
diff --git a/gemrb/override/bg1/formatio.2da b/gemrb/unhardcoded/bg1/formatio.2da
similarity index 100%
rename from gemrb/override/bg1/formatio.2da
rename to gemrb/unhardcoded/bg1/formatio.2da
diff --git a/gemrb/unhardcoded/bg1/gametime.2da b/gemrb/unhardcoded/bg1/gametime.2da
new file mode 100644
index 0000000..026d707
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/gametime.2da
@@ -0,0 +1,6 @@
+2DA V1.0
+0
+ DURATION
+ROUND_SECONDS 6
+TURN_SECONDS 60
+ATTACK_ROUND 100
diff --git a/gemrb/override/bg1/gaze.pro b/gemrb/unhardcoded/bg1/gaze.pro
similarity index 100%
rename from gemrb/override/bg1/gaze.pro
rename to gemrb/unhardcoded/bg1/gaze.pro
diff --git a/gemrb/unhardcoded/bg1/gemact.ids b/gemrb/unhardcoded/bg1/gemact.ids
new file mode 100644
index 0000000..c0def86
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/gemact.ids
@@ -0,0 +1,14 @@
+IDS
+399 ApplySpellPoint(P:Target*,I:Spell*Spell)
+399 ApplySpellPointRES(P:Target*,S:SpellName*)
+398 ChangeDestination(O:Object*,S:Destination*)
+397 UnmakeGlobal(O:Object*)
+396 SetToken2DA(S:ResRef*)
+395 StartDialogOverride(S:DialogFile*,O:Target*,I:Unused,I:Unused,I:ConverseAsItem)
+394 SetTrackString(I:StrRef, I:Flags, I:Difficulty)
+393 AdvanceTime(I:Seconds*)
+181 ReallyForceSpellDead(O:Target,I:Spell*Spell)
+168 Interact(O:Object*)
+148 BashDoor(O:Object)
+112 UseContainer()
+93 LeaveAreaName(O:Target*)
diff --git a/gemrb/override/bg1/gemprjtl.ids b/gemrb/unhardcoded/bg1/gemprjtl.ids
similarity index 100%
rename from gemrb/override/bg1/gemprjtl.ids
rename to gemrb/unhardcoded/bg1/gemprjtl.ids
diff --git a/gemrb/unhardcoded/bg1/gemrb.ini b/gemrb/unhardcoded/bg1/gemrb.ini
new file mode 100644
index 0000000..3fa43a9
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/gemrb.ini
@@ -0,0 +1,129 @@
+; GemRB - Infinity Engine Emulator
+; Copyright (C) 2003 The GemRB Project
+;
+; This program is free software; you can redistribute it and/or
+; modify it under the terms of the GNU General Public License
+; as published by the Free Software Foundation; either version 2
+; of the License, or (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program; if not, write to the Free Software
+; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+;
+
+
+; gemrb.ini - game type-specific settings for GemRB engine
+
+[resources]
+
+; Bitmap resource for cursors
+CursorBAM = CAROT
+
+; Bitmap resource for scroll cursor arrow
+ScrollCursorBAM = CURSARW
+
+; Bitmap resource for dialog buttons font
+ButtonFont = STONESML
+
+; Font used to display tooltips
+TooltipFont = TOOLFONT
+
+; Sprite displayed behind the tooltip text, if any
+TooltipBack = TOOLTIP
+
+; Tooltip text color (RGBA)
+TooltipColor = #f0b08000
+
+; Space between tooltip text and sides of TooltipBack (x2)
+#TooltipMargin = 10
+TooltipMargin = 5
+
+; INI file from the original games
+INIConfig = baldur.ini
+
+; Palette bitmaps in various widths
+Palette16 = MPALETTE
+Palette32 = MPALETTE
+Palette256 = MPAL256
+
+3EdRules = 0
+AllStringsTagged = 1
+AreaVisitedVar = 0
+AreaOverride = 0
+AutomapINI = 0
+AutoSearchHidden = 1
+BiographyIsRes = 0
+BreakableWeapons = 1
+CastingSounds = 0
+ChallengeRating = 0
+CharNameIsGabber = 0
+CheckAbilities = 0
+ClearUnusedArea = 1
+CutsceneAreascripts = 1
+DeathOnZeroStat = 1
+DialogueScrolls = 0
+EnhancedCastingSounds = 0
+EnhancedEffects = 0
+FistStat = 232
+FlexibleWorldmap = 0
+ForceAreaScript = 0
+ForceStereo = 1
+HasBeastsINI = 0
+HasDescIcon = 1
+HasDPLAYER = 1
+HasEXPTABLE = 0
+HasFloatMenu = 0
+HasHideInShadows = 0
+HasKaputz = 0
+HasNoNPCFlag = 0
+HasPartyINI = 0
+HasPickSound = 0
+HasResDataIni = 0
+HasSongList = 0
+HasSoundsIni = 0
+HasSpecificDamageBonus = 0
+HasSpellList = 0
+HasUsePointFlag = 0
+HasWisdomBonusTable = 0
+HealOn100Plus = 1
+IgnoreButtonFrames = 0
+ImplicitAreaAnimBackground = 0
+InPartyAllowsDead = 1
+IWD2DeathVarFormat = 0
+IWD2ScriptName = 0
+IWDMapDimensions = 0
+JournalHasSections = 0
+KnowWorld = 0
+LevelslotPerClass = 0
+LowerLabelText = 1
+MagicBit = 0
+MaximumAbility = 25
+NoDropCanMove = 1
+NoNewVariables = 0
+OneByteAnimationID = 0
+OnScreenText = 0
+ProperBackstab = 0
+ProtagonistTalks = 0
+PSTStateFlags = 0
+RareActionSounds = 0
+RedrawTile = 1
+ReverseDoor = 0
+ReverseToHit = 1
+SaveForHalfDamage = 0
+SelectiveMagicRes = 0
+SkipUpdateHack = 0
+SmallFog = 1
+SoundFolders = 0
+SpawnIni = 0
+SpellBookIconHack = 0
+StartActive = 0
+StealIsAttack = 0
+StrrefSaveGame = 0
+TeamMovement = 0
+UpperButtonText = 0
+ZeroTimerIsValid = 0
diff --git a/gemrb/unhardcoded/bg1/gemtrig.ids b/gemrb/unhardcoded/bg1/gemtrig.ids
new file mode 100644
index 0000000..d5ad70f
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/gemtrig.ids
@@ -0,0 +1,9 @@
+IDS
+0x4076 OpenState(O:Object*,I:Open*BOOLEAN)
+0x4077 NumItems(S:ResRef*,O:Object*,I:Num*)
+0x4078 NumItemsGT(S:ResRef*,O:Object*,I:Num*)
+0x4079 NumItemsLT(S:ResRef*,O:Object*,I:Num*)
+0x407A NumItemsParty(S:ResRef*,I:Num*)
+0x407B NumItemsPartyGT(S:ResRef*,I:Num*)
+0x407C NumItemsPartyLT(S:ResRef*,I:Num*)
+0x407D IsOverMe(O:Object*)
diff --git a/gemrb/override/bg1/grease.pro b/gemrb/unhardcoded/bg1/grease.pro
similarity index 100%
rename from gemrb/override/bg1/grease.pro
rename to gemrb/unhardcoded/bg1/grease.pro
diff --git a/gemrb/unhardcoded/bg1/guibtact.2da b/gemrb/unhardcoded/bg1/guibtact.2da
new file mode 100644
index 0000000..eb6c945
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/guibtact.2da
@@ -0,0 +1,37 @@
+2DA V1.0
+100
+ 1 2 3 4 TOOLTIP RESREF
+Stealth 30 31 32 33 4968 guibtact
+Thieving 26 27 28 29 4971 guibtact
+Cast 12 13 52 53 4688 guibtact
+QSpell1 8 9 32 33 4938 guibtbut
+QSpell2 10 11 34 35 4938 guibtbut
+QSpell3 12 13 36 37 4938 guibtbut
+Turn 8 9 10 11 4974 guibtact
+Talk 4 5 6 7 4933 guibtact
+UseItem 18 19 56 57 4978 guibtact
+QItem1 14 15 38 39 4937 guibtbut
+QItem4 16 17 40 41 4937 guibtbut
+QItem2 18 19 42 43 4937 guibtbut
+QItem3 20 21 44 45 4937 guibtbut
+Innate 38 39 54 55 4954 guibtact
+Defend 0 1 2 3 15925 guibtact
+Attack 14 15 16 17 4666 guibtact
+QWeapon1 0 1 24 25 4950 guibtbut
+QWeapon2 2 3 26 27 4950 guibtbut
+QWeapon3 4 5 28 29 4950 guibtbut
+QWeapon4 6 7 30 31 4950 guibtbut
+BardSong 22 23 24 25 11798 guibtact
+Stop 58 59 60 61 15924 guibtact
+Search 34 35 36 37 4927 guibtact
+23 * * * * * *
+24 * * * * * *
+25 * * * * * *
+26 * * * * * *
+27 * * * * * *
+28 * * * * * *
+29 * * * * * *
+30 * * * * * *
+31 * * * * * *
+Left 44 45 100 100 -1 guibtact
+Right 42 43 100 100 -1 guibtact
diff --git a/gemrb/override/bg1/guils.chu b/gemrb/unhardcoded/bg1/guils.chu
similarity index 100%
rename from gemrb/override/bg1/guils.chu
rename to gemrb/unhardcoded/bg1/guils.chu
diff --git a/gemrb/override/bg1/haterace.2da b/gemrb/unhardcoded/bg1/haterace.2da
similarity index 100%
rename from gemrb/override/bg1/haterace.2da
rename to gemrb/unhardcoded/bg1/haterace.2da
diff --git a/gemrb/override/bg2/hlymite.pro b/gemrb/unhardcoded/bg1/hlymite.pro
similarity index 100%
copy from gemrb/override/bg2/hlymite.pro
copy to gemrb/unhardcoded/bg1/hlymite.pro
diff --git a/gemrb/override/bg1/icestorm.pro b/gemrb/unhardcoded/bg1/icestorm.pro
similarity index 100%
rename from gemrb/override/bg1/icestorm.pro
rename to gemrb/unhardcoded/bg1/icestorm.pro
diff --git a/gemrb/override/bg1/inarea.pro b/gemrb/unhardcoded/bg1/inarea.pro
similarity index 100%
rename from gemrb/override/bg1/inarea.pro
rename to gemrb/unhardcoded/bg1/inarea.pro
diff --git a/gemrb/unhardcoded/bg1/inareapa.pro b/gemrb/unhardcoded/bg1/inareapa.pro
new file mode 100644
index 0000000..fedb699
Binary files /dev/null and b/gemrb/unhardcoded/bg1/inareapa.pro differ
diff --git a/gemrb/override/bg1/inareasm.pro b/gemrb/unhardcoded/bg1/inareasm.pro
similarity index 100%
copy from gemrb/override/bg1/inareasm.pro
copy to gemrb/unhardcoded/bg1/inareasm.pro
diff --git a/gemrb/override/bg1/item_use.2da b/gemrb/unhardcoded/bg1/item_use.2da
similarity index 100%
rename from gemrb/override/bg1/item_use.2da
rename to gemrb/unhardcoded/bg1/item_use.2da
diff --git a/gemrb/override/bg1/itemsnd.2da b/gemrb/unhardcoded/bg1/itemsnd.2da
similarity index 100%
rename from gemrb/override/bg1/itemsnd.2da
rename to gemrb/unhardcoded/bg1/itemsnd.2da
diff --git a/gemrb/override/bg1/itemtype.2da b/gemrb/unhardcoded/bg1/itemtype.2da
similarity index 100%
rename from gemrb/override/bg1/itemtype.2da
rename to gemrb/unhardcoded/bg1/itemtype.2da
diff --git a/gemrb/override/bg1/itemuse.2da b/gemrb/unhardcoded/bg1/itemuse.2da
similarity index 100%
rename from gemrb/override/bg1/itemuse.2da
rename to gemrb/unhardcoded/bg1/itemuse.2da
diff --git a/gemrb/override/bg1/k_m_e.2da b/gemrb/unhardcoded/bg1/k_m_e.2da
similarity index 100%
rename from gemrb/override/bg1/k_m_e.2da
rename to gemrb/unhardcoded/bg1/k_m_e.2da
diff --git a/gemrb/override/bg1/k_m_g.2da b/gemrb/unhardcoded/bg1/k_m_g.2da
similarity index 100%
rename from gemrb/override/bg1/k_m_g.2da
rename to gemrb/unhardcoded/bg1/k_m_g.2da
diff --git a/gemrb/override/bg1/k_m_h.2da b/gemrb/unhardcoded/bg1/k_m_h.2da
similarity index 100%
rename from gemrb/override/bg1/k_m_h.2da
rename to gemrb/unhardcoded/bg1/k_m_h.2da
diff --git a/gemrb/override/bg1/k_m_he.2da b/gemrb/unhardcoded/bg1/k_m_he.2da
similarity index 100%
rename from gemrb/override/bg1/k_m_he.2da
rename to gemrb/unhardcoded/bg1/k_m_he.2da
diff --git a/gemrb/override/bg1/kitlist.2da b/gemrb/unhardcoded/bg1/kitlist.2da
similarity index 100%
rename from gemrb/override/bg1/kitlist.2da
rename to gemrb/unhardcoded/bg1/kitlist.2da
diff --git a/gemrb/override/bg1/kittable.2da b/gemrb/unhardcoded/bg1/kittable.2da
similarity index 100%
rename from gemrb/override/bg1/kittable.2da
rename to gemrb/unhardcoded/bg1/kittable.2da
diff --git a/gemrb/override/bg1/lightsto.pro b/gemrb/unhardcoded/bg1/lightsto.pro
similarity index 100%
rename from gemrb/override/bg1/lightsto.pro
rename to gemrb/unhardcoded/bg1/lightsto.pro
diff --git a/gemrb/unhardcoded/bg1/magesch.2da b/gemrb/unhardcoded/bg1/magesch.2da
new file mode 100644
index 0000000..a2c8a88
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/magesch.2da
@@ -0,0 +1,13 @@
+2DA V1.0
+-1
+ NAME_REF DESC_REF CAP_REF KIT
+GENERALIST 18039 9563 9987 0x4000
+ABJURER 597 9564 502 0x40
+CONJURER 2179 9565 504 0x80
+DIVINER 2846 9566 2012 0x100
+ENCHANTER 2861 9567 2022 0x200
+ILLUSIONIST 2862 9568 12785 0x400
+INVOKER 3015 9569 12786 0x800
+NECROMANCER 12744 9570 12787 0x1000
+TRANSMUTER 12745 9571 12788 0x2000
+WILDMAGE 54893 54892 54894 0x8000
diff --git a/gemrb/override/bg1/magicmis.pro b/gemrb/unhardcoded/bg1/magicmis.pro
similarity index 100%
rename from gemrb/override/bg1/magicmis.pro
rename to gemrb/unhardcoded/bg1/magicmis.pro
diff --git a/gemrb/override/bg1/mpal256.bmp b/gemrb/unhardcoded/bg1/mpal256.bmp
similarity index 100%
rename from gemrb/override/bg1/mpal256.bmp
rename to gemrb/unhardcoded/bg1/mpal256.bmp
diff --git a/gemrb/override/bg1/music.2da b/gemrb/unhardcoded/bg1/music.2da
similarity index 100%
rename from gemrb/override/bg1/music.2da
rename to gemrb/unhardcoded/bg1/music.2da
diff --git a/gemrb/unhardcoded/bg1/overlay.2da b/gemrb/unhardcoded/bg1/overlay.2da
new file mode 100644
index 0000000..de9ffc2
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/overlay.2da
@@ -0,0 +1,35 @@
+2DA V1.0
+*
+ VVC UNDER FLAGS
+SANCTUARY SANCTRY 0 1
+ENTANGLE SPENTACI 0 0
+SPELLTRAP SPMAGGLO 0 0
+SHIELDGLOBE SPSHIELD 1 1
+GREASE GREASED 1 0
+WEB WEBENTD 1 0
+MINORGLOBE MINORGLB 0 1
+GLOBE GOINVUC 0 1
+FLAMESHROUD SOFLAMC 0 0
+ANTIMAGIC AMSHELC 0 0
+RESILIENT ORSPHEC 0 0
+PROTFROMMISS PFNMISC 0 0
+CLOAKOFFEAR COFEARC 0 0
+ENTROPY ESHIELC 0 0
+FIREAURA FIAURAC 0 0
+FROSTAURA FRAURAC 0 0
+INSECT IPLAGUC 0 0
+STORMSHELL SSHELLC 0 0
+LATHANDER1 SOLATC1 0 0
+LATHANDER2 SOLATC2 1 0
+GLATHANDER1 GSOLAC1 0 0
+GLATHANDER2 GSOLAC2 1 0
+SEVENEYES1 SEYESC1 0 0
+SEVENEYES2 SEYESC2 1 0
+BOUNCE SPTURNI2 1 0
+BOUNCE2 SPSTURNI 1 0
+FIRESHIELD1 FSHIRC1 0 0
+FIRESHIELD2 FSHIRC2 1 0
+ICESHIELD1 FSHIBC1 0 0
+ICESHIELD2 FSHIBC2 1 0
+TORTOISE TSHELLC 0 0
+DEATHARMOR DARMORC 0 0
diff --git a/gemrb/override/bg1/pathfind.2da b/gemrb/unhardcoded/bg1/pathfind.2da
similarity index 100%
rename from gemrb/override/bg1/pathfind.2da
rename to gemrb/unhardcoded/bg1/pathfind.2da
diff --git a/gemrb/unhardcoded/bg1/pdolls.2da b/gemrb/unhardcoded/bg1/pdolls.2da
new file mode 100644
index 0000000..6fa0c6b
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/pdolls.2da
@@ -0,0 +1,89 @@
+2DA V1.0
+*
+ LEVEL1 LEVEL2 LEVEL3 LEVEL4 SIZE
+0x5000 CHMC1INV CHMC2INV CHMC3INV CHMC4INV L
+0x5001 CEMC1INV CEMC2INV CEMC3INV CEMC4INV M
+0x5002 CDMC1INV CDMC2INV CDMC3INV CDMC4INV S
+0x5003 CIMC1INV CIMC2INV CIMC3INV CIMC4INV S
+0x5010 CHFC1INV CHMC2INV CHMC3INV CHMC4INV M
+0x5011 CEFC1INV CEMC2INV CEMC3INV CEMC4INV M
+0x5012 CDMC1INV CDMC2INV CDMC3INV CDMC4INV S
+0x5013 CIFC1INV CIMC2INV CIMC3INV CIMC4INV S
+0x5100 CHMF1INV CHMF2INV CHMF3INV CHMC4INV L
+0x5101 CEMF1INV CEMF2INV CEMF3INV CEMC4INV M
+0x5102 CDMF1INV CDMF2INV CDMF3INV CDMC4INV S
+0x5103 CIMF1INV CIMF2INV CIMF3INV CIMC4INV S
+0x5110 CHFF1INV CHFF2INV CHMF3INV CHMC4INV M
+0x5111 CEFF1INV CEFF2INV CEMF3INV CEMC4INV M
+0x5112 CDMF1INV CDMF2INV CDMF3INV CDMC4INV S
+0x5113 CIFF1INV CIFF2INV CIMF3INV CIMC4INV S
+0x5200 CHMW1INV CHMW2INV CHMW3INV CHMW4INV L
+0x5201 CEMW1INV CEMW2INV CEMW3INV CEMW4INV M
+0x5202 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
+0x5203 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
+0x5210 CHFW1INV CHMW2INV CHMW3INV CHMW4INV M
+0x5211 CEFW1INV CEMW2INV CEMW3INV CEMW4INV M
+0x5212 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
+0x5213 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
+0x5300 CHMT1INV CHMT2INV CHMF3INV CHMF4INV L
+0x5301 CEMT1INV CEMT2INV CEMF3INV CEMF4INV M
+0x5302 CDMT1INV CDMT2INV CDMF3INV CDMF4INV S
+0x5303 CIMT1INV CIMT2INV CIMF3INV CIMF4INV S
+0x5310 CHFT1INV CHMT2INV CHMF3INV CHMF4INV M
+0x5311 CEFT1INV CEMT2INV CEMF3INV CEMF4INV M
+0x5312 CDMT1INV CDMT2INV CDMF3INV CDMF4INV S
+0x5313 CIFT1INV CIMT2INV CIMF3INV CIMF4INV S
+0x6000 CHMC1INV CHMC2INV CHMC3INV CHMC4INV L
+0x6001 CEMC1INV CEMC2INV CEMC3INV CEMC4INV M
+0x6002 CDMC1INV CDMC2INV CDMC3INV CDMC4INV S
+0x6003 CIMC1INV CIMC2INV CIMC3INV CIMC4INV S
+0x6004 CIMC1INV CIMC2INV CIMC3INV CIMC4INV S
+0x6005 CHMC1INV CHMC2INV CHMC3INV CHMC4INV L
+0x6010 CHFC1INV CHFC2INV CHFC3INV CHFC4INV M
+0x6011 CEFC1INV CEFC2INV CEFC3INV CEFC4INV M
+0x6012 CDMC1INV CDMC2INV CDMC3INV CDMC4INV S
+0x6013 CIFC1INV CIFC2INV CIFC3INV CIFC4INV S
+0x6014 CIFC1INV CIFC2INV CIFC3INV CIFC4INV S
+0x6015 CHFC1INV CHFC2INV CHFC3INV CHFC4INV M
+0x6100 CHMF1INV CHMF2INV CHMF3INV CHMF4INV L
+0x6101 CEMF1INV CEMF2INV CEMF3INV CEMF4INV M
+0x6102 CDMF1INV CDMF2INV CDMF3INV CDMF4INV S
+0x6103 CIMF1INV CIMF2INV CIMF3INV CIMF4INV S
+0x6104 CIMF1INV CIMF2INV CIMF3INV CIMF4INV S
+0x6105 CHMF1INV CHMF2INV CHMF3INV CHMF4INV L
+0x6110 CHFF1INV CHFF2INV CHFF3INV CHFF4INV M
+0x6111 CEFF1INV CEFF2INV CEFF3INV CEFF4INV M
+0x6112 CDMF1INV CDMF2INV CDMF3INV CDMF4INV S
+0x6113 CIFF1INV CIFF2INV CIFF3INV CIFF4INV S
+0x6114 CIFF1INV CIFF2INV CIFF3INV CIFF4INV S
+0x6115 CHFF1INV CHFF2INV CHFF3INV CHFF4INV M
+0x6200 CHMW1INV CHMW2INV CHMW3INV CHMW4INV L
+0x6201 CEMW1INV CEMW2INV CEMW3INV CHMW4INV M
+0x6202 CDMW1INV CDMW2INV CDMW3INV CHMW4INV S
+0x6203 CIMW1INV CIMW2INV CIMW3INV CHMW4INV S
+0x6204 CIMW1INV CIMW2INV CIMW3INV CHMW4INV S
+0x6205 CHMW1INV CHMW2INV CHMW3INV CHMW4INV L
+0x6210 CHFW1INV CHFW2INV CHFW3INV CHFW4INV M
+0x6211 CEFW1INV CEFW2INV CEFW3INV CHFW4INV M
+0x6212 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
+0x6213 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
+0x6214 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
+0x6215 CHFW1INV CHFW2INV CHFW3INV CHFW4INV M
+0x6300 CHMT1INV CHMT2INV CHMF3INV CHMF4INV L
+0x6301 CEMT1INV CEMT2INV CEMF3INV CEMF4INV M
+0x6302 CDMT1INV CDMT2INV CDMF3INV CDMF4INV S
+0x6303 CIMT1INV CIMT2INV CIMF3INV CIMF4INV S
+0x6304 CIMT1INV CIMT2INV CIMF3INV CIMF4INV S
+0x6305 CHMT1INV CHMT2INV CHMF3INV CHMF4INV L
+0x6310 CHFT1INV CHFT2INV CHFF3INV CHFF4INV M
+0x6311 CEFT1INV CEFT2INV CEFF3INV CEFF4INV M
+0x6312 CDMT1INV CDMT2INV CDMF3INV CDMF4INV S
+0x6313 CIFT1INV CIFT2INV CIFF3INV CIFF4INV S
+0x6314 CIFT1INV CIFT2INV CIFF3INV CIFF4INV S
+0x6315 CHFT1INV CHFT2INV CHFF3INV CHFF4INV M
+0x6402 CMNKINV CHMT2INV CHMF3INV CHMF4INV M
+0x6500 CHMM1INV CHMT2INV CHMF3INV CHMF4INV L
+0x6510 CHFM1INV CHFT2INV CHMF3INV CHMF4INV M
+0x7200 MBER0INV MBER0INV MBER0INV MBER0INV *
+0x7201 MBER1INV MBER1INV MBER1INV MBER1INV *
+0x7b00 MWLF0INV MWLF0INV MWLF0INV MWLF0INV *
diff --git a/gemrb/override/bg1/pictures.2da b/gemrb/unhardcoded/bg1/pictures.2da
similarity index 100%
rename from gemrb/override/bg1/pictures.2da
rename to gemrb/unhardcoded/bg1/pictures.2da
diff --git a/gemrb/unhardcoded/bg1/polish.ini b/gemrb/unhardcoded/bg1/polish.ini
new file mode 100644
index 0000000..3155954
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/polish.ini
@@ -0,0 +1,30 @@
+[charset]
+CharCount = 24
+
+# Characters left from the original encoding
+Letter1 = 138,154 # Sv
+Letter2 = 140,156 # OE
+Letter3 = 159,255 # Y:
+Letter4 = 192,224 # A`
+Letter5 = 193,225 # A'
+Letter6 = 194,226 # A^
+Letter7 = 195,227 # A~
+Letter8 = 196,228 # A:
+Letter9 = 216,248 # O/
+Letter10 = 217,249 # U`
+Letter11 = 218,250 # U'
+Letter12 = 219,251 # U^
+Letter13 = 220,252 # U:
+Letter14 = 221,253 # Y'
+Letter15 = 222,254 # Thorn
+
+# Polish characters
+Letter16 = 229,238 # Ac
+Letter17 = 230,239 # C'
+Letter18 = 231,240 # Ec
+Letter19 = 232,241 # L/
+Letter20 = 233,243 # O'
+Letter21 = 234,242 # N'
+Letter22 = 235,244 # S'
+Letter23 = 236,245 # Z'
+Letter24 = 237,246 # Z-
diff --git a/gemrb/unhardcoded/bg1/proftype.2da b/gemrb/unhardcoded/bg1/proftype.2da
new file mode 100644
index 0000000..2c45ea7
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/proftype.2da
@@ -0,0 +1,35 @@
+2DA V1.0
+-1
+ OLD_PROFICIENCY
+0 -1
+1 -1
+2 -1
+3 -1
+4 -1
+5 -1
+6 -1
+7 -1
+8 -1
+9 -1
+10 -1
+11 -1
+12 -1
+13 -1
+14 -1
+15_BOW 2
+16_DAGGER 1
+17_MACE 4
+18_SLING 7
+19_SWORD 1
+20_BIG 0
+21_HAMMER 4
+22_MS 5
+23_FLAIL 5
+24_DART 7
+25_AXE 6
+26_STAFF 4
+27_XBOW -1
+28_HAND -2
+29_SPEAR 3
+30_HALBERD 3
+
diff --git a/gemrb/unhardcoded/bg1/qslots.2da b/gemrb/unhardcoded/bg1/qslots.2da
new file mode 100644
index 0000000..f3103af
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/qslots.2da
@@ -0,0 +1,23 @@
+2DA V1.0
+100
+ SLOT1 SLOT2 SLOT3 SLOT4 SLOT5 SLOT6 SLOT7 SLOT8 SLOT9
+MAGE 3 4 5 2 8 9 11 12 13
+FIGHTER 18 19 14 100 8 9 11 12 13
+CLERIC 6 3 4 2 8 9 11 12 13
+THIEF 22 0 1 100 8 9 11 12 13
+BARD 20 1 3 2 8 9 11 12 13
+PALADIN 18 14 6 2 8 9 11 12 13
+FIGHTER_MAGE 3 4 5 2 8 9 11 12 13
+FIGHTER_CLERIC 6 3 4 2 8 9 11 12 13
+FIGHTER_THIEF 18 22 0 1 8 9 11 12 13
+FIGHTER_MAGE_THIEF 22 0 1 2 8 9 11 12 13
+DRUID 3 4 5 2 8 9 11 12 13
+RANGER 18 14 0 2 8 9 11 12 13
+MAGE_THIEF 22 0 1 2 8 9 11 12 13
+CLERIC_MAGE 6 3 4 2 8 9 11 12 13
+CLERIC_THIEF 22 0 1 2 8 9 11 12 13
+FIGHTER_DRUID 3 4 5 2 8 9 11 12 13
+FIGHTER_MAGE_CLERIC 6 3 4 2 8 9 11 12 13
+CLERIC_RANGER 6 3 4 2 8 9 11 12 13
+SORCERER 3 4 5 2 8 9 11 12 13
+MONK 18 14 22 0 8 9 11 12 13
diff --git a/gemrb/override/bg1/races.2da b/gemrb/unhardcoded/bg1/races.2da
similarity index 100%
rename from gemrb/override/bg1/races.2da
rename to gemrb/unhardcoded/bg1/races.2da
diff --git a/gemrb/override/bg1/randitem.2da b/gemrb/unhardcoded/bg1/randitem.2da
similarity index 100%
rename from gemrb/override/bg1/randitem.2da
rename to gemrb/unhardcoded/bg1/randitem.2da
diff --git a/gemrb/unhardcoded/bg1/restmov.2da b/gemrb/unhardcoded/bg1/restmov.2da
new file mode 100644
index 0000000..25ded1f
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/restmov.2da
@@ -0,0 +1,11 @@
+2DA V1.0
+*
+ REST DAY NIGHT
+0 * * *
+1 REST * *
+2 REST * *
+3 REST * *
+4 REST * *
+5 REST * *
+6 REST * *
+7 REST * *
diff --git a/gemrb/override/bg1/savegame.2da b/gemrb/unhardcoded/bg1/savegame.2da
similarity index 100%
rename from gemrb/override/bg1/savegame.2da
rename to gemrb/unhardcoded/bg1/savegame.2da
diff --git a/gemrb/override/bg1/script.2da b/gemrb/unhardcoded/bg1/script.2da
similarity index 100%
rename from gemrb/override/bg1/script.2da
rename to gemrb/unhardcoded/bg1/script.2da
diff --git a/gemrb/unhardcoded/bg1/shtable.2da b/gemrb/unhardcoded/bg1/shtable.2da
new file mode 100644
index 0000000..50304eb
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/shtable.2da
@@ -0,0 +1,42 @@
+2DA V1.0
+*
+ RESREF
+0 SHAIR
+1 SHEARTH
+2 SHWATER
+3 *
+4 SHAIR
+5 SHEARTH
+6 SHWATER
+7 *
+8 SHAIR
+9 SHEARTH
+10 SHWATER
+11 *
+12 SHAIR
+13 SHEARTH
+14 SHWATER
+15 *
+16 SHAIR
+17 SHEARTH
+18 SHWATER
+19 *
+20 SHAIR
+21 SHEARTH
+22 SHWATER
+23 *
+24 SHAIR
+25 SHEARTH
+26 SHWATER
+27 *
+28 SHAIR
+29 SHEARTH
+30 SHWATER
+31 *
+32
+33
+34
+35 FLMSTRK
+36 HLYMITE
+37
+38 SPDIMDR1
diff --git a/gemrb/override/bg1/skills.2da b/gemrb/unhardcoded/bg1/skills.2da
similarity index 100%
rename from gemrb/override/bg1/skills.2da
rename to gemrb/unhardcoded/bg1/skills.2da
diff --git a/gemrb/override/bg1/sleep.pro b/gemrb/unhardcoded/bg1/sleep.pro
similarity index 100%
rename from gemrb/override/bg1/sleep.pro
rename to gemrb/unhardcoded/bg1/sleep.pro
diff --git a/gemrb/override/bg1/slottype.2da b/gemrb/unhardcoded/bg1/slottype.2da
similarity index 100%
rename from gemrb/override/bg1/slottype.2da
rename to gemrb/unhardcoded/bg1/slottype.2da
diff --git a/gemrb/override/bg1/sparbknp.pro b/gemrb/unhardcoded/bg1/sparbknp.pro
similarity index 100%
rename from gemrb/override/bg1/sparbknp.pro
rename to gemrb/unhardcoded/bg1/sparbknp.pro
diff --git a/gemrb/override/bg1/sparbkpa.pro b/gemrb/unhardcoded/bg1/sparbkpa.pro
similarity index 100%
rename from gemrb/override/bg1/sparbkpa.pro
rename to gemrb/unhardcoded/bg1/sparbkpa.pro
diff --git a/gemrb/override/bg1/sparblnp.pro b/gemrb/unhardcoded/bg1/sparblnp.pro
similarity index 100%
rename from gemrb/override/bg1/sparblnp.pro
rename to gemrb/unhardcoded/bg1/sparblnp.pro
diff --git a/gemrb/override/bg1/sparblpa.pro b/gemrb/unhardcoded/bg1/sparblpa.pro
similarity index 100%
rename from gemrb/override/bg1/sparblpa.pro
rename to gemrb/unhardcoded/bg1/sparblpa.pro
diff --git a/gemrb/override/bg1/sparchnp.pro b/gemrb/unhardcoded/bg1/sparchnp.pro
similarity index 100%
rename from gemrb/override/bg1/sparchnp.pro
rename to gemrb/unhardcoded/bg1/sparchnp.pro
diff --git a/gemrb/override/bg1/sparchpa.pro b/gemrb/unhardcoded/bg1/sparchpa.pro
similarity index 100%
rename from gemrb/override/bg1/sparchpa.pro
rename to gemrb/unhardcoded/bg1/sparchpa.pro
diff --git a/gemrb/override/bg1/spargonp.pro b/gemrb/unhardcoded/bg1/spargonp.pro
similarity index 100%
rename from gemrb/override/bg1/spargonp.pro
rename to gemrb/unhardcoded/bg1/spargonp.pro
diff --git a/gemrb/override/bg1/spargopa.pro b/gemrb/unhardcoded/bg1/spargopa.pro
similarity index 100%
rename from gemrb/override/bg1/spargopa.pro
rename to gemrb/unhardcoded/bg1/spargopa.pro
diff --git a/gemrb/override/bg1/spargrnp.pro b/gemrb/unhardcoded/bg1/spargrnp.pro
similarity index 100%
rename from gemrb/override/bg1/spargrnp.pro
rename to gemrb/unhardcoded/bg1/spargrnp.pro
diff --git a/gemrb/override/bg1/spargrpa.pro b/gemrb/unhardcoded/bg1/spargrpa.pro
similarity index 100%
rename from gemrb/override/bg1/spargrpa.pro
rename to gemrb/unhardcoded/bg1/spargrpa.pro
diff --git a/gemrb/override/bg1/sparicnp.pro b/gemrb/unhardcoded/bg1/sparicnp.pro
similarity index 100%
rename from gemrb/override/bg1/sparicnp.pro
rename to gemrb/unhardcoded/bg1/sparicnp.pro
diff --git a/gemrb/override/bg1/sparicpa.pro b/gemrb/unhardcoded/bg1/sparicpa.pro
similarity index 100%
rename from gemrb/override/bg1/sparicpa.pro
rename to gemrb/unhardcoded/bg1/sparicpa.pro
diff --git a/gemrb/override/bg1/sparklbk.pro b/gemrb/unhardcoded/bg1/sparklbk.pro
similarity index 100%
rename from gemrb/override/bg1/sparklbk.pro
rename to gemrb/unhardcoded/bg1/sparklbk.pro
diff --git a/gemrb/override/bg1/sparklbl.pro b/gemrb/unhardcoded/bg1/sparklbl.pro
similarity index 100%
rename from gemrb/override/bg1/sparklbl.pro
rename to gemrb/unhardcoded/bg1/sparklbl.pro
diff --git a/gemrb/override/bg1/sparklch.pro b/gemrb/unhardcoded/bg1/sparklch.pro
similarity index 100%
rename from gemrb/override/bg1/sparklch.pro
rename to gemrb/unhardcoded/bg1/sparklch.pro
diff --git a/gemrb/override/bg1/sparklgo.pro b/gemrb/unhardcoded/bg1/sparklgo.pro
similarity index 100%
rename from gemrb/override/bg1/sparklgo.pro
rename to gemrb/unhardcoded/bg1/sparklgo.pro
diff --git a/gemrb/override/bg1/sparklgr.pro b/gemrb/unhardcoded/bg1/sparklgr.pro
similarity index 100%
rename from gemrb/override/bg1/sparklgr.pro
rename to gemrb/unhardcoded/bg1/sparklgr.pro
diff --git a/gemrb/override/bg1/sparklic.pro b/gemrb/unhardcoded/bg1/sparklic.pro
similarity index 100%
rename from gemrb/override/bg1/sparklic.pro
rename to gemrb/unhardcoded/bg1/sparklic.pro
diff --git a/gemrb/override/bg1/sparklma.pro b/gemrb/unhardcoded/bg1/sparklma.pro
similarity index 100%
rename from gemrb/override/bg1/sparklma.pro
rename to gemrb/unhardcoded/bg1/sparklma.pro
diff --git a/gemrb/override/bg1/sparklor.pro b/gemrb/unhardcoded/bg1/sparklor.pro
similarity index 100%
rename from gemrb/override/bg1/sparklor.pro
rename to gemrb/unhardcoded/bg1/sparklor.pro
diff --git a/gemrb/override/bg1/sparklpu.pro b/gemrb/unhardcoded/bg1/sparklpu.pro
similarity index 100%
rename from gemrb/override/bg1/sparklpu.pro
rename to gemrb/unhardcoded/bg1/sparklpu.pro
diff --git a/gemrb/override/bg1/sparklre.pro b/gemrb/unhardcoded/bg1/sparklre.pro
similarity index 100%
rename from gemrb/override/bg1/sparklre.pro
rename to gemrb/unhardcoded/bg1/sparklre.pro
diff --git a/gemrb/override/bg1/sparklst.pro b/gemrb/unhardcoded/bg1/sparklst.pro
similarity index 100%
rename from gemrb/override/bg1/sparklst.pro
rename to gemrb/unhardcoded/bg1/sparklst.pro
diff --git a/gemrb/override/bg1/sparmanp.pro b/gemrb/unhardcoded/bg1/sparmanp.pro
similarity index 100%
rename from gemrb/override/bg1/sparmanp.pro
rename to gemrb/unhardcoded/bg1/sparmanp.pro
diff --git a/gemrb/override/bg1/sparmapa.pro b/gemrb/unhardcoded/bg1/sparmapa.pro
similarity index 100%
rename from gemrb/override/bg1/sparmapa.pro
rename to gemrb/unhardcoded/bg1/sparmapa.pro
diff --git a/gemrb/override/bg1/sparornp.pro b/gemrb/unhardcoded/bg1/sparornp.pro
similarity index 100%
rename from gemrb/override/bg1/sparornp.pro
rename to gemrb/unhardcoded/bg1/sparornp.pro
diff --git a/gemrb/override/bg1/sparorpa.pro b/gemrb/unhardcoded/bg1/sparorpa.pro
similarity index 100%
rename from gemrb/override/bg1/sparorpa.pro
rename to gemrb/unhardcoded/bg1/sparorpa.pro
diff --git a/gemrb/override/bg1/sparpunp.pro b/gemrb/unhardcoded/bg1/sparpunp.pro
similarity index 100%
rename from gemrb/override/bg1/sparpunp.pro
rename to gemrb/unhardcoded/bg1/sparpunp.pro
diff --git a/gemrb/override/bg1/sparpupa.pro b/gemrb/unhardcoded/bg1/sparpupa.pro
similarity index 100%
rename from gemrb/override/bg1/sparpupa.pro
rename to gemrb/unhardcoded/bg1/sparpupa.pro
diff --git a/gemrb/override/bg1/sparrenp.pro b/gemrb/unhardcoded/bg1/sparrenp.pro
similarity index 100%
rename from gemrb/override/bg1/sparrenp.pro
rename to gemrb/unhardcoded/bg1/sparrenp.pro
diff --git a/gemrb/override/bg1/sparrepa.pro b/gemrb/unhardcoded/bg1/sparrepa.pro
similarity index 100%
rename from gemrb/override/bg1/sparrepa.pro
rename to gemrb/unhardcoded/bg1/sparrepa.pro
diff --git a/gemrb/override/bg1/sparstnp.pro b/gemrb/unhardcoded/bg1/sparstnp.pro
similarity index 100%
rename from gemrb/override/bg1/sparstnp.pro
rename to gemrb/unhardcoded/bg1/sparstnp.pro
diff --git a/gemrb/override/bg1/sparstpa.pro b/gemrb/unhardcoded/bg1/sparstpa.pro
similarity index 100%
rename from gemrb/override/bg1/sparstpa.pro
rename to gemrb/unhardcoded/bg1/sparstpa.pro
diff --git a/gemrb/override/bg1/spear.pro b/gemrb/unhardcoded/bg1/spear.pro
similarity index 100%
rename from gemrb/override/bg1/spear.pro
rename to gemrb/unhardcoded/bg1/spear.pro
diff --git a/gemrb/override/bg1/spearex.pro b/gemrb/unhardcoded/bg1/spearex.pro
similarity index 100%
rename from gemrb/override/bg1/spearex.pro
rename to gemrb/unhardcoded/bg1/spearex.pro
diff --git a/gemrb/override/bg1/spfirebl.pro b/gemrb/unhardcoded/bg1/spfirebl.pro
similarity index 100%
rename from gemrb/override/bg1/spfirebl.pro
rename to gemrb/unhardcoded/bg1/spfirebl.pro
diff --git a/gemrb/override/bg1/spklarbk.pro b/gemrb/unhardcoded/bg1/spklarbk.pro
similarity index 100%
rename from gemrb/override/bg1/spklarbk.pro
rename to gemrb/unhardcoded/bg1/spklarbk.pro
diff --git a/gemrb/override/bg1/spklarbl.pro b/gemrb/unhardcoded/bg1/spklarbl.pro
similarity index 100%
rename from gemrb/override/bg1/spklarbl.pro
rename to gemrb/unhardcoded/bg1/spklarbl.pro
diff --git a/gemrb/override/bg1/spklarch.pro b/gemrb/unhardcoded/bg1/spklarch.pro
similarity index 100%
rename from gemrb/override/bg1/spklarch.pro
rename to gemrb/unhardcoded/bg1/spklarch.pro
diff --git a/gemrb/override/bg1/spklargo.pro b/gemrb/unhardcoded/bg1/spklargo.pro
similarity index 100%
rename from gemrb/override/bg1/spklargo.pro
rename to gemrb/unhardcoded/bg1/spklargo.pro
diff --git a/gemrb/override/bg1/spklargr.pro b/gemrb/unhardcoded/bg1/spklargr.pro
similarity index 100%
rename from gemrb/override/bg1/spklargr.pro
rename to gemrb/unhardcoded/bg1/spklargr.pro
diff --git a/gemrb/override/bg1/spklaric.pro b/gemrb/unhardcoded/bg1/spklaric.pro
similarity index 100%
rename from gemrb/override/bg1/spklaric.pro
rename to gemrb/unhardcoded/bg1/spklaric.pro
diff --git a/gemrb/override/bg1/spklarma.pro b/gemrb/unhardcoded/bg1/spklarma.pro
similarity index 100%
rename from gemrb/override/bg1/spklarma.pro
rename to gemrb/unhardcoded/bg1/spklarma.pro
diff --git a/gemrb/override/bg1/spklaror.pro b/gemrb/unhardcoded/bg1/spklaror.pro
similarity index 100%
rename from gemrb/override/bg1/spklaror.pro
rename to gemrb/unhardcoded/bg1/spklaror.pro
diff --git a/gemrb/override/bg1/spklarpu.pro b/gemrb/unhardcoded/bg1/spklarpu.pro
similarity index 100%
rename from gemrb/override/bg1/spklarpu.pro
rename to gemrb/unhardcoded/bg1/spklarpu.pro
diff --git a/gemrb/override/bg1/spklarre.pro b/gemrb/unhardcoded/bg1/spklarre.pro
similarity index 100%
rename from gemrb/override/bg1/spklarre.pro
rename to gemrb/unhardcoded/bg1/spklarre.pro
diff --git a/gemrb/override/bg1/spklarst.pro b/gemrb/unhardcoded/bg1/spklarst.pro
similarity index 100%
rename from gemrb/override/bg1/spklarst.pro
rename to gemrb/unhardcoded/bg1/spklarst.pro
diff --git a/gemrb/override/bg1/splspec.2da b/gemrb/unhardcoded/bg1/splspec.2da
similarity index 100%
rename from gemrb/override/bg1/splspec.2da
rename to gemrb/unhardcoded/bg1/splspec.2da
diff --git a/gemrb/override/bg1/spscorch.pro b/gemrb/unhardcoded/bg1/spscorch.pro
similarity index 100%
rename from gemrb/override/bg1/spscorch.pro
rename to gemrb/unhardcoded/bg1/spscorch.pro
diff --git a/gemrb/override/bg1/spscoric.pro b/gemrb/unhardcoded/bg1/spscoric.pro
similarity index 100%
rename from gemrb/override/bg1/spscoric.pro
rename to gemrb/unhardcoded/bg1/spscoric.pro
diff --git a/gemrb/unhardcoded/bg1/stances.2da b/gemrb/unhardcoded/bg1/stances.2da
new file mode 100644
index 0000000..873dcda
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/stances.2da
@@ -0,0 +1,6 @@
+2DA V1.0
+*
+ STANCE OVERRIDE
+0x2200 11 13
+0x8000 11 13
+0x8200 13 12
diff --git a/gemrb/override/pst/start.2da b/gemrb/unhardcoded/bg1/start.2da
similarity index 100%
rename from gemrb/override/pst/start.2da
rename to gemrb/unhardcoded/bg1/start.2da
diff --git a/gemrb/override/bg1/stone.pro b/gemrb/unhardcoded/bg1/stone.pro
similarity index 100%
rename from gemrb/override/bg1/stone.pro
rename to gemrb/unhardcoded/bg1/stone.pro
diff --git a/gemrb/unhardcoded/bg1/strings.2da b/gemrb/unhardcoded/bg1/strings.2da
new file mode 100644
index 0000000..292bd24
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/strings.2da
@@ -0,0 +1,187 @@
+2DA V1.0
+-1
+ STRREF
+SCATTERED 16457
+WHOLEPARTY 16484
+DOORLOCKED 16485
+MAGICTRAP 16486
+NORMALTRAP 16487
+TRAP 16488
+CANNOTGO 16489
+TRAPREMOVED 16490
+OVERSTOCKED 16491
+SLEEP 16492
+AMBUSH 16493
+CONTLOCKED 16494
+NOMONEY 16495
+CURSED 16304
+SPELLDISRUPT 16497
+DIED 16498
+MAYNOTREST 16499
+CANTRESTMONS 16500
+CANTSAVEMONS 16501
+CANTSAVE 16502
+NODIALOG 10945
+CANTSAVEDIALOG 19253
+CANTSAVEDIALOG2 19254
+CANTSAVEMOVIE 19255
+TARGETBUSY -1
+CANTTALKTRANS -1
+GOTGOLD 17572
+LOSTGOLD 17573
+GOTXP 17574
+LOSTXP 17575
+GOTITEM 17576
+LOSTITEM 17577
+GOTREP 19686
+LOSTREP 19687
+GOTABILITY 10514
+GOTSPELL 10514
+GOTSONG 10514
+NOTHINGTOSAY -1
+JOURNALCHANGE 11359
+WORLDMAPCHANGE 11360
+PAUSED 16321
+UNPAUSED 16322
+SCRIPTPAUSED -1
+AP_UNUSABLE 17113
+AP_ATTACKED 17114
+AP_HIT 17115
+AP_WOUNDED 17116
+AP_DEAD 17117
+AP_NOTARGET 17118
+AP_ENDROUND 10014
+AP_ENEMY 23511
+AP_TRAP -1
+AP_SPELLCAST -1
+AP_GENERIC 17166
+AP_RESERVED1 -1
+AP_RESERVED2 -1
+AP_RESERVED3 -1
+CHARMED 14672
+DIRECHARMED 14780
+CONTROLLED -1
+EVIL 16505
+GNE_NEUTRAL 16504
+GOOD 16503
+STR_LAWFUL -1
+LNC_NEUTRAL -1
+CHAOTIC -1
+ACTION_CAST 16464
+ACTION_ATTACK 16465
+ACTION_TURN 16466
+ACTION_SONG 16467
+ACTION_FINDTRAP 16468
+MAGICWEAPON 10141
+OFFHAND_USED 9380
+TWOHANDED_USED 9381
+CANNOT_USE_ITEM 9382
+CANT_DROP_ITEM 25697
+NOT_IN_OFFHAND 9375
+ITEM_IS_CURSED 16304
+NO_CRITICAL 20696
+TRACKING -1
+TRACKINGFAILED -1
+DOOR_NOPICK 23169
+CONT_NOPICK 23169
+CANTSAVECOMBAT 16502
+CANTSAVENOCTRL 16502
+LOCKPICK_DONE 16517
+LOCKPICK_FAILED 16518
+STATIC_DISSIPATE -1
+LIGHTNING_DISSIPATE -1
+HAS_NO_ABILITY 17317
+NEEDS_IDENTIFY 17316
+WRONG_ITEMTYPE 9375
+HAS_ITEMEXCL 20685
+PICKPOCKET_DONE 10072
+PICKPOCKET_NONE 10070
+PICKPOCKET_FAIL 10069
+PICKPOCKET_EVIL 10068
+PICKPOCKET_ARMOR 10067
+USING_FEAT -1
+STOPPED_FEAT -1
+DISARM_DONE 16520
+DISARM_FAIL 1608
+DOORBASH_DONE 9915
+DOORBASH_FAIL 9913
+CONTBASH_DONE 9916
+CONTBASH_FAIL 9914
+MAYNOTSETTRAP -1
+SNAREFAILED -1
+SNARESUCCEED -1
+NOMORETRAP -1
+DISABLEDMAGE -1
+SAVESUCCEED 1682
+QSAVESUCCEED 10237
+UNINJURED -1
+INJURED1 -1
+INJURED2 -1
+INJURED3 -1
+INJURED4 -1
+HOURS 10700
+HOUR 10701
+DAYS 10697
+DAY 10698
+REST 10690
+JOURNEY 10689
+SUMMONINGLIMIT -1
+INVFULL 17999
+TOOFARAWAY 18002
+DAMAGE_IMMUNITY -1
+DAMAGE_STR1 14027
+DAMAGE_STR2 -1
+DAMAGE_STR3 -1
+DMG_POISON -1
+DMG_MAGIC -1
+DMG_MISSILE -1
+DMG_SLASHING -1
+DMG_PIERCING -1
+DMG_CRUSHING -1
+DMG_FIRE -1
+DMG_ELECTRIC -1
+DMG_COLD -1
+DMG_ACID -1
+DMG_OTHER -1
+GOTQUESTXP -1
+LEVELUP 17119
+INVFULL_ITEMDROP 24106
+CONT_DUP -1
+CONT_TRIG -1
+CONT_FAIL -1
+SEQ_DUP -1
+CRITICAL_HIT 16462
+CRITICAL_MISS 16463
+DEATH 14026
+BACKSTAB 12128
+BACKSTAB_BAD 10013
+BACKSTAB_FAIL -1
+CASTER_LVL_INC -1
+CASTER_LVL_DEC -1
+CHARS_EXPORTED -1
+PALADIN_FALL 19620
+RANGER_FALL 19621
+RES_RESISTED -1
+DEADMAGIC_FAIL -1
+MISCASTMAGIC -1
+WILDSURGE -1
+FAMBLOCK -1
+FAMPROTAGONIST -1
+MAGIC_RESISTED 19224
+CANTSAVESTORE 10841
+NOSEE_NOCAST -1
+AURACLEANSED 23797
+INDOOR_FAIL 9744
+SPELL_DISRUPTED 14796
+CHAOSSHIELD -1
+RAPIDSHOT -1
+HAMSTRING -1
+ARTERIAL -1
+EXPERTISE -1
+POWERATTACK -1
+CLEAVE -1
+HELD 14102
+SLOWED 19503
+CANTMOVE 19504
+CASTS -1
+WEAPONINEFFECTIVE 11025
diff --git a/gemrb/unhardcoded/bg1/textscrn.2da b/gemrb/unhardcoded/bg1/textscrn.2da
new file mode 100644
index 0000000..f058f45
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/textscrn.2da
@@ -0,0 +1,22 @@
+2DA V1.0
+*
+ WINDOW MUSIC STRING
+CHPTXT0 0 CHAPTER 17556
+CHPTXT1 1 CHAPTER 17556
+CHPTXT2 2 CHAPTER 17556
+CHPTXT3 3 CHAPTER 17556
+CHPTXT4 4 CHAPTER 17556
+CHPTXT5 5 CHAPTER 17556
+CHPTXT6 6 CHAPTER 17556
+CHPTXT7 7 CHAPTER 17556
+CHPTXT8 8 CHAPTER 17556
+DRMTXT2 52 DREAM 17558
+DRMTXT3 53 DREAM 17558
+DRMTXT4 54 DREAM 17558
+DRMTXT5 55 DREAM 17558
+DRMTXT6 56 DREAM 17558
+DRMTXT7 57 DREAM 17558
+ISLON 58 * 17557
+ISLOFF 59 * 17557
+TOSCST 60 * 17557
+TOSCEND 61 * 17557
diff --git a/gemrb/override/bg1/trapglyp.pro b/gemrb/unhardcoded/bg1/trapglyp.pro
similarity index 100%
rename from gemrb/override/bg1/trapglyp.pro
rename to gemrb/unhardcoded/bg1/trapglyp.pro
diff --git a/gemrb/override/bg1/trapskul.pro b/gemrb/unhardcoded/bg1/trapskul.pro
similarity index 100%
rename from gemrb/override/bg1/trapskul.pro
rename to gemrb/unhardcoded/bg1/trapskul.pro
diff --git a/gemrb/unhardcoded/bg1/vcremap.2da b/gemrb/unhardcoded/bg1/vcremap.2da
new file mode 100644
index 0000000..758d0e1
--- /dev/null
+++ b/gemrb/unhardcoded/bg1/vcremap.2da
@@ -0,0 +1,11 @@
+2DA V1.0
+*
+ ORIGINAL NEW COMMENT
+SELR1 63 35 rare selects (in bg1 there are 4 in bg2 there are 2)
+SELR2 64 36
+SELR3 65 37
+SELR4 66 38
+RESP1 59 58 no second hostile response
+RESP2 60 58 no third hostile response
+DLG1 61 59 hostile dialog shifts
+DLG2 62 60 default dialog shifts
diff --git a/gemrb/override/bg1/walksnd.2da b/gemrb/unhardcoded/bg1/walksnd.2da
similarity index 100%
rename from gemrb/override/bg1/walksnd.2da
rename to gemrb/unhardcoded/bg1/walksnd.2da
diff --git a/gemrb/override/bg1/weapprof.2da b/gemrb/unhardcoded/bg1/weapprof.2da
similarity index 100%
rename from gemrb/override/bg1/weapprof.2da
rename to gemrb/unhardcoded/bg1/weapprof.2da
diff --git a/gemrb/override/bg1/web.pro b/gemrb/unhardcoded/bg1/web.pro
similarity index 100%
rename from gemrb/override/bg1/web.pro
rename to gemrb/unhardcoded/bg1/web.pro
diff --git a/gemrb/override/bg1/wssingle.2da b/gemrb/unhardcoded/bg1/wssingle.2da
similarity index 100%
rename from gemrb/override/bg1/wssingle.2da
rename to gemrb/unhardcoded/bg1/wssingle.2da
diff --git a/gemrb/override/bg2/HPBARB.2da b/gemrb/unhardcoded/bg2/HPBARB.2da
similarity index 100%
rename from gemrb/override/bg2/HPBARB.2da
rename to gemrb/unhardcoded/bg2/HPBARB.2da
diff --git a/gemrb/unhardcoded/bg2/Makefile.am b/gemrb/unhardcoded/bg2/Makefile.am
new file mode 100644
index 0000000..ec98237
--- /dev/null
+++ b/gemrb/unhardcoded/bg2/Makefile.am
@@ -0,0 +1,3 @@
+bg2unhardcoded_DATA = *.2da *.ini *.chu *.ids *.vvc *.spl *.pro
+bg2unhardcodeddir = $(moddir)/unhardcoded/bg2/
+EXTRA_DIST = *.2da *.ini *.chu *.ids *.vvc *.spl *.pro
diff --git a/gemrb/override/bg2/ability.2da b/gemrb/unhardcoded/bg2/ability.2da
similarity index 100%
rename from gemrb/override/bg2/ability.2da
rename to gemrb/unhardcoded/bg2/ability.2da
diff --git a/gemrb/override/bg2/aligns.2da b/gemrb/unhardcoded/bg2/aligns.2da
similarity index 100%
rename from gemrb/override/bg2/aligns.2da
rename to gemrb/unhardcoded/bg2/aligns.2da
diff --git a/gemrb/override/bg2/areapro.2da b/gemrb/unhardcoded/bg2/areapro.2da
similarity index 100%
rename from gemrb/override/bg2/areapro.2da
rename to gemrb/unhardcoded/bg2/areapro.2da
diff --git a/gemrb/override/bg2/at2xlvl.spl b/gemrb/unhardcoded/bg2/at2xlvl.spl
similarity index 100%
rename from gemrb/override/bg2/at2xlvl.spl
rename to gemrb/unhardcoded/bg2/at2xlvl.spl
diff --git a/gemrb/unhardcoded/bg2/avatars.2da b/gemrb/unhardcoded/bg2/avatars.2da
new file mode 100644
index 0000000..3d971c5
--- /dev/null
+++ b/gemrb/unhardcoded/bg2/avatars.2da
@@ -0,0 +1,332 @@
+2DA V1.0
+*
+ AT_1 AT_2 AT_3 AT_4 TYPE SPACE PALETTE SIZE
+0x0100 SPCHUNKS SPCHUNKS SPCHUNKS SPCHUNKS 13 0 0 *
+0x0300 SPSMPUFF SPSMPUFF SPSMPUFF SPSMPUFF 13 0 0 *
+0x0400 SKLH SKLH SKLH SKLH 13 0 1 *
+0x0410 GLPHWRDH GLPHWRDH GLPHWRDH GLPHWRDH 13 0 1 *
+0x1000 MWYV MWYV MWYV MWYV 11 3 1 *
+0x1100 MTAN MTAN MTAN MTAN 11 3 1 *
+0x1200 MDR1 MDR1 MDR1 MDR1 12 7 1 *
+0x1201 MDR2 MDR2 MDR2 MDR2 12 7 1 *
+0x1202 MDR3 MDR3 MDR3 MDR3 12 7 1 *
+0x1203 MDR1 MDR1 MDR1 MDR1 12 7 GR *
+0x1204 MDR1 MDR1 MDR1 MDR1 12 7 AQ *
+0x1205 MDR1 MDR1 MDR1 MDR1 12 7 BL *
+0x1206 MDR1 MDR1 MDR1 MDR1 12 7 BR *
+0x1207 MDR1 MDR1 MDR1 MDR1 12 7 MC *
+0x1208 MDR1 MDR1 MDR1 MDR1 12 7 PU *
+0x2000 MSIR MSIR MSIR MSIR 2 2 0 +
+0x2100 UVOL UVOL UVOL UVOL 2 2 1 *
+0x2200 MOGM MOGM MOGM MOGM 2 2 0 S
+0x2300 MDKN MDKN MDKN MDKN 2 2 1 *
+0x3000 MAKH MAKH MAKH MAKH 17 3 1 *
+0x4000 SNOMC SNOMC SNOMC SNOMC 1 2 0 *
+0x4002 SNOMM SNOMM SNOMM SNOMM 1 2 0 *
+0x4010 SNOWC SNOWC SNOWC SNOWC 1 2 0 *
+0x4012 SNOWM SNOWM SNOWM SNOWM 1 2 0 *
+0x4100 SSIMC SSIMC SSIMC SSIMC 1 2 0 *
+0x4101 SSIMS SSIMS SSIMS SSIMS 1 2 0 *
+0x4102 SSIMM SSIMM SSIMM SSIMM 1 2 0 *
+0x4110 SSIWC SSIWC SSIWC SSIWC 1 2 0 *
+0x4112 SSIWM SSIWM SSIWM SSIWM 1 2 0 *
+0x4200 SHMCM SHMCM SHMCM SHMCM 1 2 0 *
+0x4300 MSPLG1 MSPLG1 MSPLG1 MSPLG1 1 2 1 *
+0x4400 LHMC LHMC LHMC LHMC 1 2 0 *
+0x4410 LHFC LHFC LHFC LHFC 1 2 0 *
+0x4500 LFAM LFAM LFAM LFAM 1 2 0 *
+0x4600 LDMF LDMF LDMF LDMF 1 2 0 *
+0x4700 LEMF LEMF LEMF LEMF 1 2 0 *
+0x4710 LEFF LEFF LEFF LEFF 1 2 0 *
+0x4800 LIMC LIMC LIMC LIMC 1 2 0 *
+0x5000 CHMB1 CHMB2 CHMB3 CHMC4 0 2 0 L
+0x5001 CEMB1 CEMB2 CEMB3 CEMC4 0 2 0 M
+0x5002 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 S
+0x5003 CIMB1 CIMB2 CIMB3 CIMC4 0 2 0 S
+0x5010 CHFB1 CHFB2 CHFB3 CHFC4 0 2 0 N
+0x5011 CEFB1 CEFB2 CEFB3 CEFC4 0 2 0 M
+0x5012 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 S
+0x5013 CIFB1 CIFB2 CIFB3 CIFC4 0 2 0 S
+0x5100 CHMB1 CHMB2 CHMB3 CHMF4 0 2 0 L
+0x5101 CEMB1 CEMB2 CEMB3 CHMF4 0 2 0 M
+0x5102 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 S
+0x5103 CIMB1 CIMB2 CIMB3 CIMF4 0 2 0 S
+0x5110 CHFB1 CHFB2 CHFB3 CHFF4 0 2 0 N
+0x5111 CEFB1 CEFB2 CEFB3 CEFF4 0 2 0 M
+0x5112 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 S
+0x5113 CIFB1 CIFB2 CIFB3 CIFF4 0 2 0 S
+0x5200 CHMW1 CHMW2 CHMW3 CHMW4 0 2 0 L
+0x5201 CEMW1 CEMW2 CEMW3 CEMW4 0 2 0 M
+0x5202 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
+0x5203 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
+0x5210 CHFW1 CHFW2 CHFW3 CHFW4 0 2 0 N
+0x5211 CEFW1 CEFW2 CEFW3 CEFW4 0 2 0 M
+0x5212 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
+0x5213 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
+0x5300 CHMB1 CHMT2 CHMB3 CHMF4 0 2 0 L
+0x5301 CEMB1 CEMT2 CEMB3 CEMF4 0 2 0 M
+0x5302 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 S
+0x5303 CIMB1 CIMT2 CIMB3 CIMF4 0 2 0 S
+0x5310 CHFB1 CHFT2 CHFB3 CHFF4 0 2 0 N
+0x5311 CEFB1 CEFT2 CEFB3 CEFF4 0 2 0 M
+0x5312 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 S
+0x5313 CIFB1 CIFT2 CIFB3 CIFF4 0 2 0 S
+0x6000 CHMB1 CHMB2 CHMB3 CHMC4 0 2 0 L
+0x6001 CEMB1 CEMB2 CEMB3 CEMC4 0 2 0 M
+0x6002 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 S
+0x6003 CIMB1 CIMB2 CIMB3 CIMC4 0 2 0 S
+0x6004 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 S
+0x6005 CHMB1 CHMB2 CHMB3 CHMC4 0 2 0 L
+0x6010 CHFB1 CHFB2 CHFB3 CHFC4 0 2 0 N
+0x6011 CEFB1 CEFB2 CEFB3 CEFC4 0 2 0 M
+0x6012 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 S
+0x6013 CIFB1 CIFB2 CIFB3 CIFC4 0 2 0 S
+0x6014 CIFB1 CIFB2 CIFB3 CIFC4 0 2 0 S
+0x6015 CHFB1 CHFB2 CHFB3 CHFC4 0 2 0 N
+0x6100 CHMB1 CHMB2 CHMB3 CHMF4 0 2 0 L
+0x6101 CEMB1 CEMB2 CEMB3 CEMF4 0 2 0 M
+0x6102 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 S
+0x6103 CIMB1 CIMB2 CIMB3 CIMF4 0 2 0 S
+0x6104 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 S
+0x6105 CHMB1 CHMB2 CHMB3 CHMF4 0 2 0 L
+0x6110 CHFB1 CHFB2 CHFB3 CHFF4 0 2 0 N
+0x6111 CEFB1 CEFB2 CEFB3 CEFF4 0 2 0 M
+0x6112 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 S
+0x6113 CIFB1 CIFB2 CIFB3 CIFF4 0 2 0 S
+0x6114 CIFB1 CIFB2 CIFB3 CIFF4 0 2 0 S
+0x6115 CHFB1 CHFB2 CHFB3 CHFF4 0 2 0 N
+0x6200 CHMW1 CHMW2 CHMW3 CHMW4 0 2 0 L
+0x6201 CEMW1 CEMW2 CEMW3 CEMW4 0 2 0 M
+0x6202 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
+0x6203 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
+0x6204 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
+0x6205 CHMW1 CHMW2 CHMW3 CHMW4 0 2 0 L
+0x6210 CHFW1 CHFW2 CHFW3 CHFW4 0 2 0 N
+0x6211 CEFW1 CEFW2 CEFW3 CEFW4 0 2 0 M
+0x6212 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
+0x6213 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
+0x6214 CDMW1 CIFW2 CIFW3 CIFW4 0 2 0 S
+0x6215 CHFW1 CHFW2 CHFW3 CHFW4 0 2 0 N
+0x6300 CHMB1 CHMT2 CHMB3 CHMF4 0 2 0 L
+0x6301 CEMB1 CEMT2 CEMB3 CEMF4 0 2 0 M
+0x6302 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 S
+0x6303 CIMB1 CIMT2 CIMB3 CIMF4 0 2 0 S
+0x6304 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 S
+0x6305 CHMB1 CHMT2 CHMB3 CHMF4 0 2 0 L
+0x6310 CHFB1 CHFT2 CHFB3 CHFF4 0 2 0 N
+0x6311 CEFB1 CEFT2 CEFB3 CEFF4 0 2 0 M
+0x6312 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 S
+0x6313 CIFB1 CIFT2 CIFB3 CIFF4 0 2 0 S
+0x6314 CIFB1 CIFT2 CIFB3 CIFF4 0 2 0 S
+0x6315 CHFB1 CHFT2 CHFT3 CHFF4 0 2 0 N
+0x6400 UDRZ1 UDRZ1 UDRZ1 UDRZ1 6 2 0 *
+0x6401 UELM1 UELM1 UELM1 UELM1 6 2 1 *
+0x6402 CMNK1 CMNK1 CMNK1 CMNK1 6 2 0 M
+0x6403 MSKL1 MSKL1 MSKL1 MSKL1 6 2 1 M
+0x6404 USAR1 USAR1 USAR1 USAR1 6 2 1 *
+0x6405 MDGU1 MDGU1 MDGU1 MDGU1 6 2 0 M
+0x6406 MDGU1 MDGU1 MDGU1 MDGU1 6 2 0 L
+0x6500 CHMM1 CHMB2 CHMB3 CHMC4 0 2 0 L
+0x6510 CHFM1 CHFB2 CHFB3 CHFC4 0 2 0 N
+0x7000 MOGH MOGH MOGH MOGH 14 2 0 *
+0x7001 MOGN MOGN MOGN MOGN 14 2 0 *
+0x7100 MBAS MBAS MBAS MBAS 14 2 1 *
+0x7101 MBAS MBAS MBAS MBAS 14 2 GR *
+0x7200 MBER MBER MBER MBER 14 2 BL *
+0x7201 MBER MBER MBER MBER 14 2 1 *
+0x7202 MBER MBER MBER MBER 14 2 CA *
+0x7203 MBER MBER MBER MBER 14 2 PO *
+0x7300 MEAE MEAE MEAE MEAE 4 2 1 *
+0x7301 MEAS MEAS MEAS MEAS 4 2 1 *
+0x7302 MEAE MEAE MEAE MEAE 4 2 SH *
+0x7310 MFIE MFIE MFIE MFIE 4 2 1 *
+0x7311 MFIS MFIS MFIS MFIS 4 2 1 *
+0x7320 MAIR MAIR MAIR MAIR 4 2 1 *
+0x7321 MAIS MAIS MAIS MAIS 4 2 1 *
+0x7400 MDOG MDOG MDOG MDOG 14 2 WI *
+0x7401 MDOG MDOG MDOG MDOG 14 2 WA *
+0x7402 MDOG MDOG MDOG MDOG 14 2 MO *
+0x7500 MDOP MDOP MDOP MDOP 14 2 1 *
+0x7501 MDOP MDOP MDOP MDOP 14 2 GR *
+0x7600 METT METT METT METT 14 2 1 *
+0x7701 MGHL MGHL MGHL MGHL 14 2 1 *
+0x7702 MGHL MGHL MGHL MGHL 14 2 RE *
+0x7703 MGHL MGHL MGHL MGHL 14 2 GA *
+0x7704 MSHD MSHD MSHD MSHD 4 2 1 *
+0x7800 MGIB MGIB MGIB MGIB 14 2 1 *
+0x7900 MSLI MSLI MSLI MSLI 14 3 GR *
+0x7901 MSLI MSLI MSLI MSLI 14 3 OL *
+0x7902 MSLI MSLI MSLI MSLI 14 3 MU *
+0x7903 MSLI MSLI MSLI MSLI 14 3 OC *
+0x7904 MSLI MSLI MSLI MSLI 14 3 1 *
+0x7A00 MSPI MSPI MSPI MSPI 14 2 GI *
+0x7A01 MSPI MSPI MSPI MSPI 14 2 HU *
+0x7A02 MSPI MSPI MSPI MSPI 14 2 PH *
+0x7A03 MSPI MSPI MSPI MSPI 14 2 SW *
+0x7A04 MSPI MSPI MSPI MSPI 14 2 WR *
+0x7B00 MWLF MWLF MWLF MWLF 14 2 1 *
+0x7B01 MWLF MWLF MWLF MWLF 14 2 WO *
+0x7B02 MWLF MWLF MWLF MWLF 14 2 DI *
+0x7B03 MWLF MWLF MWLF MWLF 14 2 WI *
+0x7B04 MWLF MWLF MWLF MWLF 14 2 VA *
+0x7B05 MWLF MWLF MWLF MWLF 14 2 DR *
+0x7B06 MWLS MWLS MWLS MWLS 14 2 1 *
+0x7C00 MXVT MXVT MXVT MXVT 14 2 0 *
+0x7C01 MTAS MTAS MTAS MTAS 14 2 1 *
+0x7D00 MZOM MZOM MZOM MZOM 14 2 0 *
+0x7E00 MWER MWER MWER MWER 14 2 1 *
+0x7E01 MGWE MGWE MGWE MGWE 14 2 1 *
+0x7F00 MTRO MTRO MTRO MTRO 4 2 1 *
+0x7F01 MMIN MMIN MMIN MMIN 4 2 1 *
+0x7F02 MBEH MBEH MBEH MBEH 4 3 1 *
+0x7F03 MIMP MIMP MIMP MIMP 4 2 1 *
+0x7F04 MIGO MIGO MIGO MIGO 15 4 1 *
+0x7F05 MDJI MDJI MDJI MDJI 4 2 1 *
+0x7F06 MDJL MDJL MDJL MDJL 4 2 1 *
+0x7F07 MGLC MGLC MGLC MGLC 4 2 1 *
+0x7F08 MOTY MOTY MOTY MOTY 4 4 1 *
+0x7F09 MSAH MSAH MSAH MSAH 4 2 1 *
+0x7F0A MGCP MGCP MGCP MGCP 4 2 1 *
+0x7F0B MGCL MGCL MGCL MGCL 4 2 1 *
+0x7F0C MKUO MKUO MKUO MKUO 4 2 1 *
+0x7F0D MLIC MLIC MLIC MLIC 4 2 1 *
+0x7F0E MDLI MDLI MDLI MDLI 4 2 1 *
+0x7F0F MTRS MTRS MTRS MTRS 4 2 1 *
+0x7F10 MRAK MRAK MRAK MRAK 4 2 1 *
+0x7F11 MUMB MUMB MUMB MUMB 4 2 1 *
+0x7F12 MVAM MVAM MVAM MVAM 4 2 1 *
+0x7F13 MSNK MSNK MSNK MSNK 4 2 1 *
+0x7F14 MGIT MGIT MGIT MGIT 4 2 1 *
+0x7F15 MBES MBES MBES MBES 4 2 1 *
+0x7F16 AMOO AMOO AMOO AMOO 4 3 1 *
+0x7F17 ARAB ARAB ARAB ARAB 4 2 1 *
+0x7F18 ADER ADER ADER ADER 4 2 1 *
+0x7F19 MDSW MDSW MDSW MDSW 4 2 1 *
+0x7F20 AGRO AGRO AGRO AGRO 4 2 1 *
+0x7F21 APHE APHE APHE APHE 4 2 1 *
+0x7F22 MVAF MVAF MVAF MVAF 4 2 1 *
+0x7F23 MSAT MSAT MSAT MSAT 4 2 1 *
+0x7F24 NPIR NPIR NPIR NPIR 4 2 1 *
+0x7F27 MDRO MDRO MDRO MDRO 4 2 1 *
+0x7F28 MKUL MKUL MKUL MKUL 15 2 1 *
+0x7F29 MFDR MFDR MFDR MFDR 4 2 1 *
+0x7F2A NSAI NSAI NSAI NSAI 4 2 1 *
+0x7F2B MMAX MMAX MMAX MMAX 14 2 1 *
+0x7F2C NSOL NSOL NSOL NSOL 4 2 1 *
+0x7F2D MWFM MWFM MWFM MWFM 4 2 1 *
+0x7F2E MRAV MRAV MRAV MRAV 4 3 1 *
+0x7F2F MSPS MSPS MSPS MSPS 15 2 1 *
+0x7F30 NBOH NBOH NBOH NBOH 4 2 1 *
+0x7F31 NELL NELL NELL NELL 4 2 1 *
+0x7F32 MSLY MSLY MSLY MSLY 4 2 1 *
+0x7F33 MKUR MKUR MKUR MKUR 14 2 1 *
+0x7F34 MDOC MDOC MDOC MDOC 14 2 1 *
+0x7F35 MMIS MMIS MMIS MMIS 4 2 1 *
+0x7F36 NSHD NSHD NSHD NSHD 4 2 1 *
+0x7F37 NIRE NIRE NIRE NIRE 4 2 1 *
+0x7F38 MEYE MEYE MEYE MEYE 14 2 1 *
+0x7F39 MMST MMST MMST MMST 14 2 1 *
+0x7F3A NIRO NIRO NIRO NIRO 4 2 1 *
+0x7F3B MSOL MSOL MSOL MSOL 4 2 1 *
+0x7F3C MASL MASL MASL MASL 4 2 1 *
+0x7F3D MMEL MMEL MMEL MMEL 14 2 1 *
+0x7F3E MFIG MFIG MFIG MFIG 4 3 1 *
+0x8000 MGNL MGNL MGNL MGNL 2 2 0 +
+0x8100 MHOB MHOB MHOB MHOB 2 2 0 +
+0x8200 MKOB MKOB MKOB MKOB 2 2 0 +
+0x9000 MOGR MOGR MOGR MOGR 5 2 0 *
+0xA000 MWYV MWYV MWYV MWYV 8 3 1 *
+0xA100 MCAR MCAR MCAR MCAR 8 3 1 *
+0xB000 ACOW ACOW ACOW ACOW 10 3 1 *
+0xB100 AHRS AHRS AHRS AHRS 10 3 1 *
+0xB200 NBEG NBEG NBEG NBEG 18 2 0 *
+0xB210 NPRO NPRO NPRO NPRO 18 2 0 *
+0xB300 NBOY NBOY NBOY NBOY 18 2 0 *
+0xB310 NGRL NGRL NGRL NGRL 18 2 0 *
+0xB400 NFAM NFAM NFAM NFAM 18 2 0 *
+0xB410 NFAW NFAW NFAW NFAW 18 2 0 *
+0xB500 NSIM NSIM NSIM NSIM 18 2 0 *
+0xB510 NSIW NSIW NSIW NSIW 18 2 0 *
+0xB600 NNOM NNOM NNOM NNOM 18 2 0 *
+0xB610 NNOW NNOW NNOW NNOW 18 2 0 *
+0xB700 NSLV NSLV NSLV NSLV 18 2 0 *
+0xC000 ABAT ABAT ABAT ABAT 3 1 1 *
+0xC100 ACAT ACAT ACAT ACAT 3 1 1 *
+0xC200 ACHK ACHK ACHK ACHK 3 1 1 *
+0xC300 ARAT ARAT ARAT ARAT 3 1 1 *
+0xC400 ASQU ASQU ASQU ASQU 3 1 1 *
+0xC500 ABAT ABAT ABAT ABAT 3 1 1 *
+0xC600 NBEG NBEG NBEG NBEG 18 2 0 *
+0xC610 NPRO NPRO NPRO NPRO 18 2 0 *
+0xC700 NBOY NBOY NBOY NBOY 18 2 0 *
+0xC710 NGRL NGRL NGRL NGRL 18 2 0 *
+0xC800 NFAM NFAM NFAM NFAM 18 2 0 *
+0xC810 NFAW NFAW NFAW NFAW 18 2 0 *
+0xC900 NSIM NSIM NSIM NSIM 18 2 0 *
+0xC910 NSIW NSIW NSIW NSIW 18 2 0 *
+0xCA00 NNOM NNOM NNOM NNOM 18 2 0 *
+0xCA10 NNOW NNOW NNOW NNOW 18 2 0 *
+0xCB00 NSLV NSLV NSLV NSLV 18 2 0 *
+0xD000 AEAGG1 AEAGG1 AEAGG1 AEAGG1 7 0 1 *
+0xD100 AGULG1 AGULG1 AGULG1 AGULG1 7 0 1 *
+0xD200 AVULG1 AVULG1 AVULG1 AVULG1 7 0 1 *
+0xD300 ABIRG1 ABIRG1 ABIRG1 ABIRG1 7 0 1 *
+0xD400 ABIRG1 ABIRG1 ABIRG1 ABIRG1 7 0 1 *
+0xE000 MCYC MCYC MCYC MCYC 9 4 1 *
+0xE010 METN METN METN METN 9 4 1 *
+0xE020 MTAN MTAN MTAN MTAN 9 4 1 *
+0xE040 MHIS MHIS MHIS MHIS 9 2 1 *
+0xE050 MLER MLER MLER MLER 9 2 1 *
+0xE060 MLIC MLIC MLIC MLIC 9 2 1 *
+0xE070 MMIN MMIN MMIN MMIN 9 2 1 *
+0xE080 MMUM MMUM MMUM MMUM 9 2 1 *
+0xE090 MMER MMER MMER MMER 9 2 1 *
+0xE0A0 MTIC MTIC MTIC MTIC 9 2 1 *
+0xE0B0 MTRO MTRO MTRO MTRO 9 2 1 *
+0xE0C0 MTSN MTSN MTSN MTSN 9 2 1 *
+0xE0D0 MUMB MUMB MUMB MUMB 9 2 1 *
+0xE0E0 MCOR MCOR MCOR MCOR 9 2 1 *
+0xE0F0 MGIC MGIC MGIC MGIC 9 2 1 *
+0xE0F1 MGLA MGLA MGLA MGLA 9 2 1 *
+0xE0F2 MWAV MWAV MWAV MWAV 9 2 1 *
+0xE200 MBET MBET MBET MBET 9 2 1 *
+0xE210 MBFI MBFI MBFI MBFI 9 2 1 *
+0xE220 MBBM MBBM MBBM MBBM 9 2 1 *
+0xE230 MBRH MBRH MBRH MBRH 9 5 1 *
+0xE300 MGHO MGHO MGHO MGHO 9 2 1 *
+0xE310 MGH2 MGH2 MGH2 MGH2 9 2 1 *
+0xE320 MGH3 MGH3 MGH3 MGH3 9 2 1 *
+0xE400 MGO1 MGO1 MGO1 MGO1 9 2 1 *
+0xE410 MGO2 MGO2 MGO2 MGO2 9 2 1 *
+0xE420 MGO3 MGO3 MGO3 MGO3 9 2 1 *
+0xE430 MGO4 MGO4 MGO4 MGO4 9 2 1 *
+0xE500 MLIZ MLIZ MLIZ MLIZ 9 2 1 *
+0xE510 MLI2 MLI2 MLI2 MLI2 9 2 1 *
+0xE520 MLI3 MLI3 MLI3 MLI3 9 2 1 *
+0xE600 MMYC MMYC MMYC MMYC 9 2 1 *
+0xE610 MMY2 MMY2 MMY2 MMY2 9 2 1 *
+0xE700 MNO1 MNO1 MNO1 MNO1 9 2 1 *
+0xE710 MNO2 MNO2 MNO2 MNO2 9 2 1 *
+0xE720 MNO3 MNO3 MNO3 MNO3 9 2 1 *
+0xE800 MOR1 MOR1 MOR1 MOR1 9 2 1 *
+0xE810 MOR2 MOR2 MOR2 MOR2 9 2 1 *
+0xE820 MOR3 MOR3 MOR3 MOR3 9 2 1 *
+0xE830 MOR4 MOR4 MOR4 MOR4 9 2 1 *
+0xE840 MOR5 MOR5 MOR5 MOR5 9 2 1 *
+0xE900 MSAL MSAL MSAL MSAL 9 2 1 *
+0xE910 MSA2 MSA2 MSA2 MSA2 9 2 1 *
+0xEA00 MSHR MSHR MSHR MSHR 9 2 1 *
+0xEA10 MSH1 MSH1 MSH1 MSH1 9 2 1 *
+0xEA20 MSH2 MSH2 MSH2 MSH2 9 2 1 *
+0xEB00 MSKT MSKT MSKT MSKT 9 2 1 *
+0xEB10 MSKA MSKA MSKA MSKA 9 2 1 *
+0xEB20 MSKB MSKB MSKB MSKB 9 2 1 *
+0xEC00 MWIG MWIG MWIG MWIG 9 2 1 *
+0xEC10 MWI2 MWI2 MWI2 MWI2 9 2 1 *
+0xEC20 MWI3 MWI3 MWI3 MWI3 9 2 1 *
+0xED00 MYU1 MYU1 MYU1 MYU1 9 2 1 *
+0xED10 MYU2 MYU2 MYU2 MYU2 9 2 1 *
+0xED20 MYU3 MYU3 MYU3 MYU3 9 2 1 *
+0xEE00 MZO2 MZO2 MZO2 MZO2 9 2 1 *
+0xEE10 MZO3 MZO3 MZO3 MZO3 9 2 1 *
+0xEF00 MWWE MWWE MWWE MWWE 9 2 1 *
diff --git a/gemrb/override/bg2/avprefc.2da b/gemrb/unhardcoded/bg2/avprefc.2da
similarity index 100%
rename from gemrb/override/bg2/avprefc.2da
rename to gemrb/unhardcoded/bg2/avprefc.2da
diff --git a/gemrb/override/bg2/avprefr.2da b/gemrb/unhardcoded/bg2/avprefr.2da
similarity index 100%
rename from gemrb/override/bg2/avprefr.2da
rename to gemrb/unhardcoded/bg2/avprefr.2da
diff --git a/gemrb/unhardcoded/bg2/bloodclr.2da b/gemrb/unhardcoded/bg2/bloodclr.2da
new file mode 100644
index 0000000..5d10be9
--- /dev/null
+++ b/gemrb/unhardcoded/bg2/bloodclr.2da
@@ -0,0 +1,29 @@
+2DA V1.0
+0
+ VALUE MIN MAX FLAGS
+NORMAL 0x2f 0x1000 0xffff 0
+PURPLE 0x2d 0x4300 0x43ff 0
+MSKEL 0x25 0x5403 0x5403 1
+DOOMG 0x22 0x5405 0x5406 1
+MSKEL 0x25 0x6403 0x6403 1
+DOOMG 0x22 0x6405 0x6406 1
+YELLOW 0x32 0x7300 0x73ff 0
+PURPLE 0x3c 0x7500 0x75ff 0
+YELLOW 0x32 0x7600 0x76ff 1
+BLACK 0x66 0x7700 0x77ff 1
+SLI_GR 7 0x7900 0x7900 1
+SLI_OL 0x24 0x7901 0x7901 1
+SLI_MU 0x33 0x7902 0x7902 1
+SLI_OC 0x25 0x7903 0x7903 1
+SLIME 0x1b 0x7904 0x7904 1
+SPIDER 0x33 0x7a00 0x7aff 1
+ZOMBIE 0x25 0x7c00 0x7cff 1
+MTRO 0x33 0x7f00 0x7f00 0
+MMIN 0x3d 0x7f01 0x7f03 0
+MIGO 0x1a 0x7f04 0x7f04 1
+MGLC 0x5d 0x7f07 0x7f07 0
+MTRS 0x32 0x7f0f 0x7f0f 0
+MBES 0x3d 0x7f15 0x7f15 0
+MCAR 0x38 0xa100 0xa1ff 0
+UNDEAD 0x66 0xe300 0xe3ff 1
+MWWE 0x38 0xef00 0xefff 1
diff --git a/gemrb/override/bg2/cgtable.2da b/gemrb/unhardcoded/bg2/cgtable.2da
similarity index 100%
rename from gemrb/override/bg2/cgtable.2da
rename to gemrb/unhardcoded/bg2/cgtable.2da
diff --git a/gemrb/override/bg2/classes.2da b/gemrb/unhardcoded/bg2/classes.2da
similarity index 100%
rename from gemrb/override/bg2/classes.2da
rename to gemrb/unhardcoded/bg2/classes.2da
diff --git a/gemrb/override/bg2/clowncol.2da b/gemrb/unhardcoded/bg2/clowncol.2da
similarity index 100%
rename from gemrb/override/bg2/clowncol.2da
rename to gemrb/unhardcoded/bg2/clowncol.2da
diff --git a/gemrb/unhardcoded/bg2/clskills.2da b/gemrb/unhardcoded/bg2/clskills.2da
new file mode 100644
index 0000000..c33fbb9
--- /dev/null
+++ b/gemrb/unhardcoded/bg2/clskills.2da
@@ -0,0 +1,25 @@
+2DA V1.0
+*
+ DRUIDSPELL CLERICSPELL MAGESPELL STARTXP BARDSKILL THIEFSKILL LAYHANDS TURNLEVEL BOOKTYPE HATERACE ABILITIES NO_PROF STARTXP2 RANGERSKILL SAVEBONUS
+UNUSED * * * * * * * 0 0 * * * * * *
+MAGE * * MXSPLWIZ 89000 * * * 0 1 * CLABMA01 -4 2500000 * 0
+FIGHTER * * * 89000 * * * 0 0 * CLABFI01 -2 2500000 * 0
+CLERIC * MXSPLPRS * 89000 * * * 1 1 * CLABPR01 -3 2500000 * 0
+THIEF * * * 89000 * SKILLS * 0 0 * CLABTH01 -3 2500000 * 0
+BARD * * MXSPLBRD 89000 SKILLBRD * * 0 1 * CLABBA01 -3 2500000 * 0
+PALADIN * MXSPLPAL * 89000 * * PALADIN 5 1 * CLABPA01 -2 2500000 * 2
+FIGHTER_MAGE * * MXSPLWIZ 89000 * * * 0 1 * CLABFI01 -2 2500000 * 0
+FIGHTER_CLERIC * MXSPLPRS * 89000 * * * 1 1 * FI01,PR01 -2 2500000 * 0
+FIGHTER_THIEF * * * 89000 * SKILLS * 0 0 * FI01,TH01 -2 2500000 * 0
+FIGHTER_MAGE_THIEF * * MXSPLWIZ 89000 * SKILLS * 0 1 * FI01,TH01 -2 2500000 * 0
+DRUID MXSPLDRU * * 89000 * * * 0 1 * CLABDR01 -3 2500000 * 0
+RANGER MXSPLRAN * * 89000 * * * 0 1 HATERACE CLABRN01 -2 2500000 SKILLRNG 0
+MAGE_THIEF * * MXSPLWIZ 89000 * SKILLS * 0 1 * CLABTH01 -3 2500000 * 0
+CLERIC_MAGE * MXSPLPRS MXSPLWIZ 89000 * * * 1 1 * CLABPR01 -3 2500000 * 0
+CLERIC_THIEF * MXSPLPRS * 89000 * SKILLS * 1 1 * PR01,TH01 -3 2500000 * 0
+FIGHTER_DRUID MXSPLDRU * * 89000 * * * 0 1 * FI01,DR01 -2 2500000 * 0
+FIGHTER_MAGE_CLERIC * MXSPLPRS MXSPLWIZ 89000 * * * 1 1 * FI01,PR01 -2 2500000 * 0
+CLERIC_RANGER MXSPLRAN MXSPLPRS * 89000 * * * 1 1 HATERACE PR01,RN01 -2 2500000 SKILLRNG 0
+SORCERER * * MXSPLSRC 89000 * * * 0 2 * * -4 2500000 * 0
+MONK * * * 89000 * SKILLS * 0 0 * CLABMO01 -3 2500000 * 0
+
diff --git a/gemrb/override/bg2/colrspry.pro b/gemrb/unhardcoded/bg2/colrspry.pro
similarity index 100%
rename from gemrb/override/bg2/colrspry.pro
rename to gemrb/unhardcoded/bg2/colrspry.pro
diff --git a/gemrb/override/bg2/comet.pro b/gemrb/unhardcoded/bg2/comet.pro
similarity index 100%
rename from gemrb/override/bg2/comet.pro
rename to gemrb/unhardcoded/bg2/comet.pro
diff --git a/gemrb/unhardcoded/bg2/damage.2da b/gemrb/unhardcoded/bg2/damage.2da
new file mode 100644
index 0000000..e0fef47
--- /dev/null
+++ b/gemrb/unhardcoded/bg2/damage.2da
@@ -0,0 +1,16 @@
+2DA V1.0
+*
+ MAIN SPARKS GRADIENT
+CRIT BLOODCR * 47
+SMALL BLOODS * 47
+MEDIUM BLOODM * 47
+LARGE BLOODL * 47
+FIRES SPFIRIMP SPBURN 19
+FIREM SPFIRIMP SPBURN 19
+FIREL SPFIRIMP SPBURN 19
+SPARKS SPSHKIMP SPSPARKS -1
+SPARKM SPSHKIMP SPSPARKS -1
+SPARKL SPSHKIMP SPSPARKS -1
+ICES SPFIRIMP * 71
+ICEM SPFIRIMP * 71
+ICEL SPFIRIMP * 71
diff --git a/gemrb/unhardcoded/bg2/defsound.2da b/gemrb/unhardcoded/bg2/defsound.2da
new file mode 100644
index 0000000..2294e41
--- /dev/null
+++ b/gemrb/unhardcoded/bg2/defsound.2da
@@ -0,0 +1,36 @@
+2DA V1.0
+*
+ RESREF
+OPEN AMB_D03A
+CLOSE AMB_D03B
+HOPEN AMB_D04A
+HCLOSE AMB_D04B
+BUTTON1 GAM_09
+BUTTON2 GAM_03
+BUTTON3 GAM_04
+OPENFAIL AMB_D20
+CLOSEFAIL *
+ITEM_GONE EFF_M02
+SECRET ACT_09
+PICKLOCK AMB_D21D
+PICKFAIL AMB_D21
+13 *
+14 *
+15 *
+16 *
+17 *
+18 *
+19 *
+LIGHTNING1 AMB_E13A
+LIGHTNING2 AMB_E13B
+LIGHTNING3 AMB_E13F
+RAIN AMB_E11
+SNOW AMB_E02B
+SOLD ACT_03D
+STOLEN GAM_36
+DRUNK GAM_07
+DONATE1 ACT_03
+DONATE2 ACT_03E
+IDENTIFY CAS_P04
+GOTXP *
+TOOLTIP PAPER
diff --git a/gemrb/override/bg2/denyspl.2da b/gemrb/unhardcoded/bg2/denyspl.2da
similarity index 100%
rename from gemrb/override/bg2/denyspl.2da
rename to gemrb/unhardcoded/bg2/denyspl.2da
diff --git a/gemrb/unhardcoded/bg2/dsclass.2da b/gemrb/unhardcoded/bg2/dsclass.2da
new file mode 100644
index 0000000..1d498b7
--- /dev/null
+++ b/gemrb/unhardcoded/bg2/dsclass.2da
@@ -0,0 +1,24 @@
+2DA V1.0
+0
+ CLASS BONUS
+MAGE 1 5
+FIGHTER 2 10
+CLERIC 3 10
+THIEF 4 15
+BARD 5 15
+PALADIN 6 10
+FM 7 10
+FC 8 10
+FT 9 15
+FMT 10 15
+DRUID 11 10
+RANGER 12 10
+MT 13 15
+CM 14 10
+CT 15 15
+FD 16 10
+FMC 17 10
+CR 18 10
+SORC 19 5
+MONK 20 15
+
diff --git a/gemrb/unhardcoded/bg2/dsrace.2da b/gemrb/unhardcoded/bg2/dsrace.2da
new file mode 100644
index 0000000..5fb3c47
--- /dev/null
+++ b/gemrb/unhardcoded/bg2/dsrace.2da
@@ -0,0 +1,7 @@
+2DA V1.0
+0
+ RACE BONUS
+ELF 2 20
+DWARF 4 10
+HALFLING 5 5
+
diff --git a/gemrb/unhardcoded/bg2/dstable.2da b/gemrb/unhardcoded/bg2/dstable.2da
new file mode 100644
index 0000000..9940319
--- /dev/null
+++ b/gemrb/unhardcoded/bg2/dstable.2da
@@ -0,0 +1,6 @@
+2DA V1.0
+*
+FILE STAT CHECKCOL READCOL
+dsclass CLASS 0 1
+dsrace RACE 0 1
+
diff --git a/gemrb/unhardcoded/bg2/effects.ids b/gemrb/unhardcoded/bg2/effects.ids
new file mode 100644
index 0000000..7143177
--- /dev/null
+++ b/gemrb/unhardcoded/bg2/effects.ids
@@ -0,0 +1,321 @@
+IDS
+0x0 ACVsDamageTypeModifier
+0x1 AttacksPerRoundModifier
+0x2 Cure:Sleep
+0x3 State:Berserk
+0x4 Cure:Berserk
+0x5 State:Charmed
+0x6 CharismaModifier
+0x7 Color:SetPalette
+0x8 Color:SetRGB
+0x9 Color:PulseRGB
+0xa ConstitutionModifier
+0xb Cure:Poison
+0xc Damage
+0xd Death
+0xe Cure:Defrost
+0xf DexterityModifier
+0x10 State:Hasted
+0x11 CurrentHPModifier
+0x12 MaximumHPModifier
+0x13 IntelligenceModifier
+0x14 State:Invisible
+0x15 LoreModifier
+0x16 LuckModifier
+0x17 MoraleModifier
+0x18 State:Panic
+0x19 State:Poisoned
+0x1a RemoveCurse
+0x1b AcidResistanceModifier
+0x1c ColdResistanceModifier
+0x1d ElectricityResistanceModifier
+0x1e FireResistanceModifier
+0x1f MagicDamageResistanceModifier
+0x20 Cure:Death
+0x21 SaveVsDeathModifier
+0x22 SaveVsWandsModifier
+0x23 SaveVsPolyModifier
+0x24 SaveVsBreathModifier
+0x25 SaveVsSpellsModifier
+0x26 State:Silenced
+0x27 State:Helpless
+0x28 State:Slowed
+0x29 Sparkle
+0x2a WizardSpellSlotsModifier
+0x2b Cure:Petrification
+0x2c StrengthModifier
+0x2d State:Stun
+0x2e Cure:Stun
+0x2f Cure:Invisible
+0x30 Cure:Silence
+0x31 WisdomModifier
+0x32 Color:BriefRGB
+0x33 Color:DarkenRGB
+0x34 Color:GlowRGB
+0x35 AnimationIDModifier
+0x36 ToHitModifier
+0x37 KillCreatureType
+0x38 Alignment:Invert
+0x39 Alignment:Change
+0x3a DispelEffects
+0x3b StealthModifier
+0x3c MiscastMagicModifier
+0x3d AlchemyModifier
+0x3e PriestSpellSlotsModifier
+0x3f State:Infravision
+0x40 Cure:Infravision
+0x41 State:Blur
+0x42 TransparencyModifier
+0x43 SummonCreature
+0x44 UnsummonCreature
+0x45 State:NonDetection
+0x46 Cure:NonDetection
+0x47 SexModifier
+0x48 AIIdentifierModifier
+0x49 DamageBonusModifier
+0x4a State:Blind
+0x4b Cure:Blind
+0x4c State:Feeblemind
+0x4d Cure:Feeblemind
+0x4e State:Diseased
+0x4f Cure:Disease
+0x50 State:Deafness
+0x51 Cure:Deafness
+0x52 SetAIScript
+0x53 Protection:Projectile
+0x54 MagicalFireResistanceModifier
+0x55 MagicalColdResistanceModifier
+0x56 SlashingResistanceModifier
+0x57 CrushingResistanceModifier
+0x58 PiercingResistanceModifier
+0x59 MissilesResistanceModifier
+0x5a OpenLocksModifier
+0x5b FindTrapsModifier
+0x5c PickPocketsModifier
+0x5d FatigueModifier
+0x5e IntoxicationModifier
+0x5f TrackingModifier
+0x60 LevelModifier
+0x61 StrengthBonusModifier
+0x62 State:Regenerating
+0x63 SpellDurationModifier
+0x64 Protection:Creature
+0x65 Protection:Opcode
+0x66 Protection:SpellLevel
+0x67 ChangeName
+0x68 ExperienceModifier
+0x69 GoldModifier
+0x6a MoraleBreakModifier
+0x6b PortraitChange
+0x6c ReputationModifier
+0x6d State:HoldNoIcon
+0x6e RetreatFrom2
+0x6f Item:CreateMagic
+0x70 Item:Remove
+0x71 Item:Equip
+0x72 Dither
+0x73 DetectAlignment
+0x74 Cure:Invisible2
+0x75 Reveal:Area
+0x76 Reveal:Creatures
+0x77 MirrorImage
+0x78 Protection:Weapons
+0x79 VisualAnimationEffect
+0x7a Item:CreateInventory
+0x7b Item:RemoveInventory
+0x7c DimensionDoor
+0x7d Unlock
+0x7e MovementRateModifier
+0x7f MonsterSummoning
+0x80 State:Confused
+0x81 AidNonCumulative
+0x82 BlessNonCumulative
+0x83 ChantNonCumulative
+0x84 HolyNonCumulative
+0x85 LuckNonCumulative
+0x86 State:Petrification
+0x87 Polymorph
+0x88 ForceVisible
+0x89 ChantBadNonCumulative
+0x8a AnimationStateChange
+0x8b DisplayString
+0x8c CastingGlow
+0x8d VisualSpellHit
+0x8e Icon:Display
+0x8f Item:CreateInSlot
+0x90 DisableButton
+0x91 DisableCasting
+0x92 Spell:Cast
+0x93 Spell:Learn
+0x94 Spell:CastPoint
+0x95 Identify
+0x96 FindTraps
+0x97 ReplaceCreature
+0x98 PlayMovie
+0x99 Overlay:Sanctuary
+0x9a Overlay:Entangle
+0x9b Overlay:MinorGlobe
+0x9c Overlay:ShieldGlobe
+0x9d Overlay:Web
+0x9e Overlay:Grease
+0x9f MirrorImageModifier
+0xa0 Cure:Sanctuary
+0xa1 Cure:Panic
+0xa2 Cure:Hold
+0xa3 FreeAction
+0xa4 Cure:Intoxication
+0xa5 PauseTarget
+0xa6 MagicResistanceModifier
+0xa7 MissileHitModifier
+0xa8 RemoveCreature
+0xa9 Icon:Disable
+0xaa DamageAnimation
+0xab Spell:Add
+0xac Spell:Remove
+0xad PoisonResistanceModifier
+0xae PlaySound
+0xaf State:Hold
+0xb0 MovementRateModifier2
+0xb1 ApplyEffect
+0xb2 ToHitVsCreature
+0xb3 DamageVsCreature
+0xb4 CantUseItem
+0xb5 CantUseItemType
+0xb6 ApplyEffectItem
+0xb7 ApplyEffectItemType
+0xb8 DontJumpModifier
+0xb9 State:Hold2
+0xba MoveToArea
+0xbb Variable:StoreLocalVariable
+0xbc AuraCleansingModifier
+0xbd CastingSpeedModifier
+0xbe AttackSpeedModifier
+0xbf CastingLevelModifier
+0xc0 FindFamiliar
+0xc1 InvisibleDetection
+0xc2 IgnoreDialogPause
+0xc3 FamiliarBond
+0xc4 FamiliarMarker
+0xc5 Bounce:Projectile
+0xc6 Bounce:Opcode
+0xc7 Bounce:SpellLevel
+0xc8 Bounce:SpellLevelDec
+0xc9 Protection:SpellLevelDec
+0xca Bounce:School
+0xcb Bounce:SecondaryType
+0xcc Protection:School
+0xcd Protection:SecondaryType
+0xce Protection:Spell
+0xcf Bounce:Spell
+0xd0 MinimumHPModifier
+0xd1 PowerWordKill
+0xd2 PowerWordStun
+0xd3 State:Imprisonment
+0xd4 Cure:Imprisonment
+0xd5 Maze
+0xd6 CastFromList
+0xd7 PlayVisualEffect
+0xd8 LevelDrainModifier
+0xd9 PowerWordSleep
+0xda StoneskinModifier
+0xdb ACVsCreatureType
+0xdc DispelSchool
+0xdd DispelSecondaryType
+0xde RandomTeleport
+0xdf Protection:SchoolDec
+0xe0 Cure:LevelDrain
+0xe1 Reveal:Magic
+0xe2 Protection:SecondaryTypeDec
+0xe3 Bounce:SchoolDec
+0xe4 Bounce:SecondaryTypeDec
+0xe5 DispelSchoolOne
+0xe6 DispelSecondaryTypeOne
+0xe7 TimeStop
+0xe8 CastSpellOnCondition
+0xe9 Proficiency
+0xea CreateContingency
+0xeb WingBuffet
+0xec ProjectImage
+0xed PuppetMarker
+0xee Disintegrate
+0xef Farsee
+0xf0 Icon:Remove
+0xf1 ControlCreature
+0xf2 Cure:Confusion
+0xf3 DrainItems
+0xf4 DrainSpells
+0xf5 CheckForBerserkModifier
+0xf6 BerserkStage1Modifier
+0xf7 BerserkStage2Modifier
+0xf8 SetMeleeEffect
+0xf9 SetRangedEffect
+0xfa DamageLuckModifier
+0xfb ChangeBardSong
+0xfc SetTrap
+0xfd SetMapNote
+0xfe RemoveMapNote
+0xff Item:CreateDays
+0x100 Sequencer:Store
+0x101 Sequencer:Create
+0x102 Sequencer:Activate
+0x103 SpellTrap
+0x104 *Crash*
+0x105 RestoreSpells
+0x106 VisualRangeModifier
+0x107 BackstabModifier
+0x108 DropWeapon
+0x109 ModifyGlobalVariable
+0x10a RemoveImmunity
+0x10b Protection:String
+0x10c ExploreModifier
+0x10d ScreenShake
+0x10e Cure:CasterHold
+0x10f SummonDisable
+0x110 ApplyEffectRepeat
+0x111 RemoveProjectile
+0x112 TeleportToTarget
+0x113 HideInShadowsModifier
+0x114 DetectIllusionsModifier
+0x115 SetTrapsModifier
+0x116 ToHitBonusModifier
+0x117 RenableButton
+0x118 ForceSurgeModifier
+0x119 WildSurgeModifier
+0x11a ScriptingState
+0x11b ApplyEffectCurse
+0x11c MeleeHitModifier
+0x11d MeleeDamageModifier
+0x11e MissileDamageModifier
+0x11f NoCircleState
+0x120 FistHitModifier
+0x121 FistDamageModifier
+0x122 TitleModifier
+0x123 DisableOverlay
+0x124 Protection:Backstab
+0x125 OffscreenAIModifier
+0x126 ExistanceDelayModifier
+0x127 DisableChunk
+0x128 Protection:Animation
+0x129 Protection:Turn
+0x12a CutScene2
+0x12b ChaosShieldModifier
+0x12c NPCBump
+0x12d CriticalHitModifier
+0x12e CanUseAnyItem
+0x12f AlwaysBackstab
+0x130 MassRaiseDead
+0x131 OffhandHitModifier
+0x132 RightHitModifier
+0x133 Reveal:Tracks
+0x134 Protection:Tracking
+0x135 ModifyLocalVariable
+0x136 TimelessState
+0x137 GenerateWish
+0x138 *Crash*
+0x139 HLA
+0x13a StoneSkin2Modifier
+0x13b AvatarRemovalModifier
+0x13c MagicalRest
+0x13d State:Haste2
+0x13e ChangeWeather
+
diff --git a/gemrb/override/bg2/findtrap.spl b/gemrb/unhardcoded/bg2/findtrap.spl
similarity index 100%
rename from gemrb/override/bg2/findtrap.spl
rename to gemrb/unhardcoded/bg2/findtrap.spl
diff --git a/gemrb/override/bg2/fistweap.2da b/gemrb/unhardcoded/bg2/fistweap.2da
similarity index 100%
rename from gemrb/override/bg2/fistweap.2da
rename to gemrb/unhardcoded/bg2/fistweap.2da
diff --git a/gemrb/unhardcoded/bg2/fonts.2da b/gemrb/unhardcoded/bg2/fonts.2da
new file mode 100644
index 0000000..0e8e7c4
--- /dev/null
+++ b/gemrb/unhardcoded/bg2/fonts.2da
@@ -0,0 +1,21 @@
+2DA V1.0
+NORMAL
+ RESREF NEED_PALETTE FONT_NAME PT_SIZE STYLE COLOR
+0 NORMAL 1 NORMAL 14 0 0xffffffff
+1 FLOATTXT 1 FLOATTXT 14 0 0xffffffff
+2 NUMBER 0 NUMBER 14 0 0xffffffff
+3 INITIALS 0 INITIALS 14 0 0xffffffff
+4 NUMBER2 0 NUMBER2 14 0 0xffffffff
+5 NUMBER3 0 NUMBER3 14 0 0xffffffff
+6 REALMS 0 REALMS 14 0 0xffffffff
+7 STONEBIG 0 STONEBIG 14 1 0xffffffff
+8 STONESML 0 STONESML 14 1 0xffffffff
+9 TOOLFONT 1 TOOLFONT 14 0 0xffffffff
+10 STONESM2 0 STONESM2 14 1 0xffffffff
+11 TOOLTIP 1 TOOLTIP 14 0 0xffffffff
+12 STONSML 0 STONSML 14 1 0xffffffff
+# state "fonts" are the status icons. You probably don't want to edit these.
+13 STATES 0 STATES 14 0 0xffffffff
+14 STATES2 0 STATES2 14 0 0xffffffff
+
+# Customization How To: http://gemrb.sourceforge.net/wiki/doku.php?id=plugins:ttf
diff --git a/gemrb/override/bg2/formatio.2da b/gemrb/unhardcoded/bg2/formatio.2da
similarity index 100%
rename from gemrb/override/bg2/formatio.2da
rename to gemrb/unhardcoded/bg2/formatio.2da
diff --git a/gemrb/unhardcoded/bg2/gametime.2da b/gemrb/unhardcoded/bg2/gametime.2da
new file mode 100644
index 0000000..026d707
--- /dev/null
+++ b/gemrb/unhardcoded/bg2/gametime.2da
@@ -0,0 +1,6 @@
+2DA V1.0
+0
+ DURATION
+ROUND_SECONDS 6
+TURN_SECONDS 60
+ATTACK_ROUND 100
diff --git a/gemrb/override/bg2/gemprjtl.ids b/gemrb/unhardcoded/bg2/gemprjtl.ids
similarity index 100%
rename from gemrb/override/bg2/gemprjtl.ids
rename to gemrb/unhardcoded/bg2/gemprjtl.ids
diff --git a/gemrb/unhardcoded/bg2/gemrb.ini b/gemrb/unhardcoded/bg2/gemrb.ini
new file mode 100644
index 0000000..24f8774
--- /dev/null
+++ b/gemrb/unhardcoded/bg2/gemrb.ini
@@ -0,0 +1,132 @@
+; GemRB - Infinity Engine Emulator
+; Copyright (C) 2003 The GemRB Project
+;
+; This program is free software; you can redistribute it and/or
+; modify it under the terms of the GNU General Public License
+; as published by the Free Software Foundation; either version 2
+; of the License, or (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program; if not, write to the Free Software
+; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+;
+
+
+; gemrb.ini - game type-specific settings for GemRB engine
+
+[resources]
+
+; Bitmap resource for cursors
+CursorBAM = CAROT
+
+; Bitmap resource for scroll cursor arrow
+ScrollCursorBAM = CURSARW
+
+; Bitmap resource for dialog buttons font
+ButtonFont = STONESML
+
+; Font used to display subtitles (ToB)
+MovieFont = STONESML
+
+; Font used to display tooltips
+TooltipFont = TOOLFONT
+
+; Sprite displayed behind the tooltip text, if any
+TooltipBack = TOOLSCRL
+
+; Tooltip text color (RGBA)
+TooltipColor = #f0b08000
+
+; Space between tooltip text and sides of TooltipBack (x2)
+#TooltipMargin = 10
+TooltipMargin = 5
+
+; INI file from the original games
+INIConfig = baldur.ini
+
+; Palette bitmaps in various widths
+Palette16 = MPALETTE
+Palette32 = MPALETTE
+Palette256 = MPAL256
+
+3EdRules = 0
+AllStringsTagged = 0
+AreaVisitedVar = 0
+AreaOverride = 0
+AutomapINI = 0
+AutoSearchHidden = 1
+BiographyIsRes = 0
+BreakableWeapons = 0
+CastingSounds = 1
+ChallengeRating = 0
+CharNameIsGabber = 0
+CheckAbilities = 1
+ClearUnusedArea = 0
+CutsceneAreascripts = 0
+DeathOnZeroStat = 1
+DialogueScrolls = 0
+EnhancedCastingSounds = 1
+EnhancedEffects = 0
+FistStat = 232
+ForceAreaScript = 0
+FlexibleWorldmap = 0
+ForceStereo = 0
+HasBeastsINI = 0
+HasDescIcon = 1
+HasDPLAYER = 1
+HasEXPTABLE = 0
+HasFloatMenu = 0
+HasHideInShadows = 1
+HasKaputz = 0
+HasNoNPCFlag = 1
+HasPartyINI = 0
+HasPickSound = 0
+HasResDataIni = 0
+HasSongList = 1
+HasSoundsIni = 0
+HasSpecificDamageBonus = 0
+HasSpellList = 0
+HasUsePointFlag = 1
+HasWisdomBonusTable = 0
+HealOn100Plus = 1
+IgnoreButtonFrames = 1
+ImplicitAreaAnimBackground = 0
+InPartyAllowsDead = 0
+IWD2DeathVarFormat = 0
+IWD2ScriptName = 0
+IWDMapDimensions = 0
+JournalHasSections = 1
+KnowWorld = 0
+LevelslotPerClass = 0
+LowerLabelText = 0
+MagicBit = 0
+MaximumAbility = 25
+NoDropCanMove = 0
+NoNewVariables = 0
+OneByteAnimationID = 0
+OnScreenText = 0
+ProperBackstab = 1
+ProtagonistTalks = 0
+PSTStateFlags = 0
+RareActionSounds = 0
+RedrawTile = 0
+ReverseDoor = 0
+ReverseToHit = 1
+SaveForHalfDamage = 0
+SelectiveMagicRes = 1
+SkipUpdateHack = 0
+SmallFog = 0
+SoundFolders = 0
+SpawnIni = 0
+SpellBookIconHack = 1
+StartActive = 1
+StealIsAttack = 1
+StrrefSaveGame = 0
+TeamMovement = 0
+UpperButtonText = 1
+ZeroTimerIsValid = 0
diff --git a/gemrb/override/bg2/gender.2da b/gemrb/unhardcoded/bg2/gender.2da
similarity index 100%
rename from gemrb/override/bg2/gender.2da
rename to gemrb/unhardcoded/bg2/gender.2da
diff --git a/gemrb/override/bg2/guibtact.2da b/gemrb/unhardcoded/bg2/guibtact.2da
similarity index 100%
rename from gemrb/override/bg2/guibtact.2da
rename to gemrb/unhardcoded/bg2/guibtact.2da
diff --git a/gemrb/override/bg2/guiid.chu b/gemrb/unhardcoded/bg2/guiid.chu
similarity index 100%
rename from gemrb/override/bg2/guiid.chu
rename to gemrb/unhardcoded/bg2/guiid.chu
diff --git a/gemrb/override/bg2/guils.chu b/gemrb/unhardcoded/bg2/guils.chu
similarity index 100%
rename from gemrb/override/bg2/guils.chu
rename to gemrb/unhardcoded/bg2/guils.chu
diff --git a/gemrb/override/bg2/halvdur.spl b/gemrb/unhardcoded/bg2/halvdur.spl
similarity index 100%
rename from gemrb/override/bg2/halvdur.spl
rename to gemrb/unhardcoded/bg2/halvdur.spl
diff --git a/gemrb/override/pst/hlymite.pro b/gemrb/unhardcoded/bg2/hlymite.pro
similarity index 100%
rename from gemrb/override/pst/hlymite.pro
rename to gemrb/unhardcoded/bg2/hlymite.pro
diff --git a/gemrb/override/bg2/item_use.2da b/gemrb/unhardcoded/bg2/item_use.2da
similarity index 100%
rename from gemrb/override/bg2/item_use.2da
rename to gemrb/unhardcoded/bg2/item_use.2da
diff --git a/gemrb/override/bg2/itemsnd.2da b/gemrb/unhardcoded/bg2/itemsnd.2da
similarity index 100%
rename from gemrb/override/bg2/itemsnd.2da
rename to gemrb/unhardcoded/bg2/itemsnd.2da
diff --git a/gemrb/override/bg2/itemspec.2da b/gemrb/unhardcoded/bg2/itemspec.2da
similarity index 100%
rename from gemrb/override/bg2/itemspec.2da
rename to gemrb/unhardcoded/bg2/itemspec.2da
diff --git a/gemrb/override/bg2/itemtype.2da b/gemrb/unhardcoded/bg2/itemtype.2da
similarity index 100%
rename from gemrb/override/bg2/itemtype.2da
rename to gemrb/unhardcoded/bg2/itemtype.2da
diff --git a/gemrb/override/bg2/itemuse.2da b/gemrb/unhardcoded/bg2/itemuse.2da
similarity index 100%
rename from gemrb/override/bg2/itemuse.2da
rename to gemrb/unhardcoded/bg2/itemuse.2da
diff --git a/gemrb/override/bg2/k_bn_d.2da b/gemrb/unhardcoded/bg2/k_bn_d.2da
similarity index 100%
rename from gemrb/override/bg2/k_bn_d.2da
rename to gemrb/unhardcoded/bg2/k_bn_d.2da
diff --git a/gemrb/override/bg2/k_bn_e.2da b/gemrb/unhardcoded/bg2/k_bn_e.2da
similarity index 100%
rename from gemrb/override/bg2/k_bn_e.2da
rename to gemrb/unhardcoded/bg2/k_bn_e.2da
diff --git a/gemrb/override/bg2/k_bn_g.2da b/gemrb/unhardcoded/bg2/k_bn_g.2da
similarity index 100%
rename from gemrb/override/bg2/k_bn_g.2da
rename to gemrb/unhardcoded/bg2/k_bn_g.2da
diff --git a/gemrb/override/bg2/k_bn_h.2da b/gemrb/unhardcoded/bg2/k_bn_h.2da
similarity index 100%
rename from gemrb/override/bg2/k_bn_h.2da
rename to gemrb/unhardcoded/bg2/k_bn_h.2da
diff --git a/gemrb/override/bg2/k_bn_he.2da b/gemrb/unhardcoded/bg2/k_bn_he.2da
similarity index 100%
rename from gemrb/override/bg2/k_bn_he.2da
rename to gemrb/unhardcoded/bg2/k_bn_he.2da
diff --git a/gemrb/override/bg2/k_bn_hl.2da b/gemrb/unhardcoded/bg2/k_bn_hl.2da
similarity index 100%
rename from gemrb/override/bg2/k_bn_hl.2da
rename to gemrb/unhardcoded/bg2/k_bn_hl.2da
diff --git a/gemrb/override/bg2/k_bn_ho.2da b/gemrb/unhardcoded/bg2/k_bn_ho.2da
similarity index 100%
rename from gemrb/override/bg2/k_bn_ho.2da
rename to gemrb/unhardcoded/bg2/k_bn_ho.2da
diff --git a/gemrb/override/bg2/k_m_e.2da b/gemrb/unhardcoded/bg2/k_m_e.2da
similarity index 100%
rename from gemrb/override/bg2/k_m_e.2da
rename to gemrb/unhardcoded/bg2/k_m_e.2da
diff --git a/gemrb/override/bg2/k_m_g.2da b/gemrb/unhardcoded/bg2/k_m_g.2da
similarity index 100%
rename from gemrb/override/bg2/k_m_g.2da
rename to gemrb/unhardcoded/bg2/k_m_g.2da
diff --git a/gemrb/override/bg2/k_m_h.2da b/gemrb/unhardcoded/bg2/k_m_h.2da
similarity index 100%
rename from gemrb/override/bg2/k_m_h.2da
rename to gemrb/unhardcoded/bg2/k_m_h.2da
diff --git a/gemrb/override/bg2/k_m_he.2da b/gemrb/unhardcoded/bg2/k_m_he.2da
similarity index 100%
rename from gemrb/override/bg2/k_m_he.2da
rename to gemrb/unhardcoded/bg2/k_m_he.2da
diff --git a/gemrb/override/bg2/lightb.pro b/gemrb/unhardcoded/bg2/lightb.pro
similarity index 100%
rename from gemrb/override/bg2/lightb.pro
rename to gemrb/unhardcoded/bg2/lightb.pro
diff --git a/gemrb/override/shared/lightbnb.pro b/gemrb/unhardcoded/bg2/lightbnb.pro
similarity index 100%
rename from gemrb/override/shared/lightbnb.pro
rename to gemrb/unhardcoded/bg2/lightbnb.pro
diff --git a/gemrb/unhardcoded/bg2/magesch.2da b/gemrb/unhardcoded/bg2/magesch.2da
new file mode 100644
index 0000000..a2c8a88
--- /dev/null
+++ b/gemrb/unhardcoded/bg2/magesch.2da
@@ -0,0 +1,13 @@
+2DA V1.0
+-1
+ NAME_REF DESC_REF CAP_REF KIT
+GENERALIST 18039 9563 9987 0x4000
+ABJURER 597 9564 502 0x40
+CONJURER 2179 9565 504 0x80
+DIVINER 2846 9566 2012 0x100
+ENCHANTER 2861 9567 2022 0x200
+ILLUSIONIST 2862 9568 12785 0x400
+INVOKER 3015 9569 12786 0x800
+NECROMANCER 12744 9570 12787 0x1000
+TRANSMUTER 12745 9571 12788 0x2000
+WILDMAGE 54893 54892 54894 0x8000
diff --git a/gemrb/override/bg2/modal.2da b/gemrb/unhardcoded/bg2/modal.2da
similarity index 100%
rename from gemrb/override/bg2/modal.2da
rename to gemrb/unhardcoded/bg2/modal.2da
diff --git a/gemrb/override/bg2/monkbon.2da b/gemrb/unhardcoded/bg2/monkbon.2da
similarity index 100%
rename from gemrb/override/bg2/monkbon.2da
rename to gemrb/unhardcoded/bg2/monkbon.2da
diff --git a/gemrb/unhardcoded/bg2/overlay.2da b/gemrb/unhardcoded/bg2/overlay.2da
new file mode 100644
index 0000000..e3398a1
--- /dev/null
+++ b/gemrb/unhardcoded/bg2/overlay.2da
@@ -0,0 +1,35 @@
+2DA V1.0
+*
+ VVC UNDER FLAGS
+SANCTUARY SANCTRY 0 1
+ENTANGLE SPENTACI 0 0
+SPELLTRAP SPMAGGLO 0 0
+SHIELDGLOBE SPSHIELD 0 1
+GREASE GREASED 1 0
+WEB WEBENTD 1 0
+MINORGLOBE MINORGLB 0 1
+GLOBE GOINVUC 0 1
+FLAMESHROUD SOFLAMC 0 0
+ANTIMAGIC AMSHELC 0 0
+RESILIENT ORSPHEC 0 0
+PROTFROMMISS PFNMISC 0 0
+CLOAKOFFEAR COFEARC 0 0
+ENTROPY ESHIELC 0 0
+FIREAURA FIAURAC 0 0
+FROSTAURA FRAURAC 0 0
+INSECT IPLAGUC 0 0
+STORMSHELL SSHELLC 0 0
+LATHANDER1 SOLATC1 0 0
+LATHANDER2 SOLATC2 1 0
+GLATHANDER1 GSOLAC1 0 0
+GLATHANDER2 GSOLAC2 1 0
+SEVENEYES1 SEYESC1 0 0
+SEVENEYES2 SEYESC2 1 0
+BOUNCE SPTURNI2 1 0
+BOUNCE2 SPSTURNI 1 0
+FIRESHIELD1 FSHIRC1 0 0
+FIRESHIELD2 FSHIRC2 1 0
+ICESHIELD1 FSHIBC1 0 0
+ICESHIELD2 FSHIBC2 1 0
+TORTOISE TSHELLC 0 0
+DEATHARMOR DARMORC 0 0
diff --git a/gemrb/unhardcoded/bg2/pathfind.2da b/gemrb/unhardcoded/bg2/pathfind.2da
new file mode 100644
index 0000000..07f55b1
--- /dev/null
+++ b/gemrb/unhardcoded/bg2/pathfind.2da
@@ -0,0 +1,6 @@
+2DA V1.0
+*
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f
+PASSABLE 8 1 1 1 1 1 1 1 0 1 8 1 0 8 3 1
+COST 10 4
+SOUND * WAL_04 WAL_MT WAL_02 WAL_05 WAL_06 WAL_01 WAL_03 * WAL_02 * WAL_01 * * * WAL_04
diff --git a/gemrb/unhardcoded/bg2/pdolls.2da b/gemrb/unhardcoded/bg2/pdolls.2da
new file mode 100644
index 0000000..bdb9c31
--- /dev/null
+++ b/gemrb/unhardcoded/bg2/pdolls.2da
@@ -0,0 +1,106 @@
+2DA V1.0
+*
+ LEVEL1 LEVEL2 LEVEL3 LEVEL4 SIZE
+0x5000 CHMC1INV CHMC2INV CHMC3INV CHMC4INV L
+0x5001 CEMC1INV CEMC2INV CEMC3INV CEMC4INV M
+0x5002 CDMC1INV CDMC2INV CDMC3INV CDMC4INV S
+0x5003 CIMC1INV CIMC2INV CIMC3INV CIMC4INV H
+0x5010 CHFC1INV CHMC2INV CHMC3INV CHMC4INV N
+0x5011 CEFC1INV CEMC2INV CEMC3INV CEMC4INV M
+0x5012 CDMC1INV CDMC2INV CDMC3INV CDMC4INV S
+0x5013 CIFC1INV CIMC2INV CIMC3INV CIMC4INV S
+0x5100 CHMF1INV CHMF2INV CHMF3INV CHMC4INV L
+0x5101 CEMF1INV CEMF2INV CEMF3INV CEMC4INV M
+0x5102 CDMF1INV CDMF2INV CDMF3INV CDMC4INV S
+0x5103 CIMF1INV CIMF2INV CIMF3INV CIMC4INV H
+0x5110 CHFF1INV CHFF2INV CHMF3INV CHMC4INV N
+0x5111 CEFF1INV CEFF2INV CEMF3INV CEMC4INV M
+0x5112 CDMF1INV CDMF2INV CDMF3INV CDMC4INV S
+0x5113 CIFF1INV CIFF2INV CIMF3INV CIMC4INV S
+0x5200 CHMW1INV CHMW2INV CHMW3INV CHMW4INV L
+0x5201 CEMW1INV CEMW2INV CEMW3INV CEMW4INV M
+0x5202 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
+0x5203 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
+0x5210 CHFW1INV CHMW2INV CHMW3INV CHMW4INV N
+0x5211 CEFW1INV CEMW2INV CEMW3INV CEMW4INV M
+0x5212 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
+0x5213 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
+0x5300 CHMT1INV CHMT2INV CHMF3INV CHMF4INV L
+0x5301 CEMT1INV CEMT2INV CEMF3INV CEMF4INV M
+0x5302 CDMT1INV CDMT2INV CDMF3INV CDMF4INV S
+0x5303 CIMT1INV CIMT2INV CIMF3INV CIMF4INV H
+0x5310 CHFT1INV CHMT2INV CHMF3INV CHMF4INV N
+0x5311 CEFT1INV CEMT2INV CEMF3INV CEMF4INV M
+0x5312 CDMT1INV CDMT2INV CDMF3INV CDMF4INV S
+0x5313 CIFT1INV CIMT2INV CIMF3INV CIMF4INV S
+0x6000 CHMC1INV CHMC2INV CHMC3INV CHMC4INV L
+0x6001 CEMC1INV CEMC2INV CEMC3INV CEMC4INV M
+0x6002 CDMC1INV CDMC2INV CDMC3INV CDMC4INV S
+0x6003 CIMC1INV CIMC2INV CIMC3INV CIMC4INV H
+0x6004 CIMC1INV CIMC2INV CIMC3INV CIMC4INV H
+0x6005 CHMC1INV CHMC2INV CHMC3INV CHMC4INV L
+0x6010 CHFC1INV CHFC2INV CHFC3INV CHFC4INV N
+0x6011 CEFC1INV CEFC2INV CEFC3INV CEFC4INV M
+0x6012 CDMC1INV CDMC2INV CDMC3INV CDMC4INV S
+0x6013 CIFC1INV CIFC2INV CIFC3INV CIFC4INV S
+0x6014 CIFC1INV CIFC2INV CIFC3INV CIFC4INV S
+0x6015 CHFC1INV CHFC2INV CHFC3INV CHFC4INV N
+0x6100 CHMF1INV CHMF2INV CHMF3INV CHMF4INV L
+0x6101 CEMF1INV CEMF2INV CEMF3INV CEMF4INV M
+0x6102 CDMF1INV CDMF2INV CDMF3INV CDMF4INV S
+0x6103 CIMF1INV CIMF2INV CIMF3INV CIMF4INV H
+0x6104 CIMF1INV CIMF2INV CIMF3INV CIMF4INV H
+0x6105 CHMF1INV CHMF2INV CHMF3INV CHMF4INV L
+0x6110 CHFF1INV CHFF2INV CHFF3INV CHFF4INV N
+0x6111 CEFF1INV CEFF2INV CEFF3INV CEFF4INV M
+0x6112 CDMF1INV CDMF2INV CDMF3INV CDMF4INV S
+0x6113 CIFF1INV CIFF2INV CIFF3INV CIFF4INV S
+0x6114 CIFF1INV CIFF2INV CIFF3INV CIFF4INV S
+0x6115 CHFF1INV CHFF2INV CHFF3INV CHFF4INV N
+0x6200 CHMW1INV CHMW2INV CHMW3INV CHMW4INV L
+0x6201 CEMW1INV CEMW2INV CEMW3INV CEMW4INV M
+0x6202 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
+0x6203 CDMW1INV CDMW2INV CDMW3INV CDMW4INV S
+0x6204 CGMW1INV CGMW2INV CGMW3INV CGMW4INV S
+0x6205 CHMW1INV CHMW2INV CHMW3INV CHMW4INV L
+0x6210 CHFW1INV CHFW2INV CHFW3INV CHFW4INV N
+0x6211 CEFW1INV CEFW2INV CEFW3INV CEFW4INV M
+0x6212 CIFT1INV CIFT2INV CIFT3INV CIFT4INV S
+0x6213 CIFT1INV CIFT2INV CIFT3INV CIFT4INV S
+0x6214 CIFT1INV CIFT2INV CIFT3INV CIFT4INV S
+0x6215 CHFW1INV CHFW2INV CHFW3INV CHFW4INV N
+0x6300 CHMT1INV CHMT2INV CHMF3INV CHMF4INV L
+0x6301 CEMT1INV CEMT2INV CEMF3INV CEMF4INV M
+0x6302 CDMT1INV CDMT2INV CDMF3INV CDMF4INV S
+0x6303 CIMT1INV CIMT2INV CIMF3INV CIMF4INV H
+0x6304 CIMT1INV CIMT2INV CIMF3INV CIMF4INV H
+0x6305 CHMT1INV CHMT2INV CHMF3INV CHMF4INV L
+0x6310 CHFT1INV CHFT2INV CHFF3INV CHFF4INV N
+0x6311 CEFT1INV CEFT2INV CEFF3INV CEFF4INV M
+0x6312 CDMT1INV CDMT2INV CDMF3INV CDMF4INV S
+0x6313 CIFT1INV CIFT2INV CIFF3INV CIFF4INV S
+0x6314 CIFT1INV CIFT2INV CIFF3INV CIFF4INV S
+0x6315 CHFT1INV CHFT2INV CHFF3INV CHFF4INV N
+0x6402 CMNKINV CHMT2INV CHMF3INV CHMF4INV M
+0x6500 CHMM1INV CHMT2INV CHMF3INV CHMF4INV L
+0x6510 CHFM1INV CHFT2INV CHMF3INV CHMF4INV N
+0x7200 MBER0INV MBER0INV MBER0INV MBER0INV *
+0x7201 MBER1INV MBER1INV MBER1INV MBER1INV *
+0x7300 MEAEINV MEAEINV MEAEINV MEAEINV L
+0x7310 MFIEINV MFIEINV MFIEINV MFIEINV L
+0x7900 MSLI2INV MSLI2INV MSLI2INV MSLI2INV M
+0x7A00 MWYVINV MWYVINV MWYVINV MWYVINV M
+0x7A03 MSPI3INV MSPI3INV MSPI3INV MSPI3INV S
+0x7B00 MWLF0INV MWLF0INV MWLF0INV MWLF0INV *
+0x7B03 MWLF0INV MWLF0INV MWLF0INV MWLF0INV *
+0x7E00 MGWEINV MGWEINV MGWEINV MGWEINV M
+0x7E01 MGWEINV MGWEINV MGWEINV MGWEINV M
+0x7F00 MTROINV MTROINV MTROINV MTROINV L
+0x7F01 MMININV MMININV MMININV MMININV M
+0x7F04 MIGOINV MIGOINV MIGOINV MIGOINV L
+0x7F32 MSLYINV MSLYINV MSLYINV MSLYINV L
+0x8000 MGNLINV MGNLINV MGNLINV MGNLINV M
+0x9000 MOGRINV MOGRINV MOGRINV MOGRINV L
+0xC300 ARATINV ARATINV ARATINV ARATINV S
+0xC400 ASQUINV ASQUINV ASQUINV ASQUINV S
+0xE900 MSALINV MSALINV MSALINV MSALINV L
diff --git a/gemrb/override/bg2/pictures.2da b/gemrb/unhardcoded/bg2/pictures.2da
similarity index 100%
rename from gemrb/override/bg2/pictures.2da
rename to gemrb/unhardcoded/bg2/pictures.2da
diff --git a/gemrb/unhardcoded/bg2/proftype.2da b/gemrb/unhardcoded/bg2/proftype.2da
new file mode 100644
index 0000000..2c45ea7
--- /dev/null
+++ b/gemrb/unhardcoded/bg2/proftype.2da
@@ -0,0 +1,35 @@
+2DA V1.0
+-1
+ OLD_PROFICIENCY
+0 -1
+1 -1
+2 -1
+3 -1
+4 -1
+5 -1
+6 -1
+7 -1
+8 -1
+9 -1
+10 -1
+11 -1
+12 -1
+13 -1
+14 -1
+15_BOW 2
+16_DAGGER 1
+17_MACE 4
+18_SLING 7
+19_SWORD 1
+20_BIG 0
+21_HAMMER 4
+22_MS 5
+23_FLAIL 5
+24_DART 7
+25_AXE 6
+26_STAFF 4
+27_XBOW -1
+28_HAND -2
+29_SPEAR 3
+30_HALBERD 3
+
diff --git a/gemrb/override/bg2/qslot2.2da b/gemrb/unhardcoded/bg2/qslot2.2da
similarity index 100%
rename from gemrb/override/bg2/qslot2.2da
rename to gemrb/unhardcoded/bg2/qslot2.2da
diff --git a/gemrb/unhardcoded/bg2/qslots.2da b/gemrb/unhardcoded/bg2/qslots.2da
new file mode 100644
index 0000000..502dae5
--- /dev/null
+++ b/gemrb/unhardcoded/bg2/qslots.2da
@@ -0,0 +1,23 @@
+2DA V1.0
+100
+ SLOT1 SLOT2 SLOT3 SLOT4 SLOT5 SLOT6 SLOT7 SLOT8 SLOT9
+MAGE 3 4 5 2 8 9 11 12 13
+FIGHTER 18 19 14 100 8 9 11 12 13
+CLERIC 6 3 4 2 8 9 11 12 13
+THIEF 22 0 1 100 8 9 11 12 13
+BARD 20 1 3 2 8 9 11 12 13
+PALADIN 18 14 6 2 8 9 11 12 13
+FIGHTER_MAGE 3 4 5 2 8 9 11 12 13
+FIGHTER_CLERIC 6 3 4 2 8 9 11 12 13
+FIGHTER_THIEF 18 22 0 1 8 9 11 12 13
+FIGHTER_MAGE_THIEF 22 0 1 2 8 9 11 12 13
+DRUID 3 4 5 2 8 9 11 12 13
+RANGER 18 14 0 2 8 9 11 12 13
+MAGE_THIEF 22 0 1 2 8 9 11 12 13
+CLERIC_MAGE 6 3 4 2 8 9 11 12 13
+CLERIC_THIEF 22 0 1 2 8 9 11 12 13
+FIGHTER_DRUID 3 4 5 2 8 9 11 12 13
+FIGHTER_MAGE_CLERIC 6 3 4 2 8 9 11 12 13
+CLERIC_RANGER 6 3 4 2 8 9 11 12 13
+SORCERER 3 4 5 2 8 9 11 12 13
+MONK 18 14 22 0 8 9 11 12 13
diff --git a/gemrb/unhardcoded/bg2/races.2da b/gemrb/unhardcoded/bg2/races.2da
new file mode 100644
index 0000000..50462b2
--- /dev/null
+++ b/gemrb/unhardcoded/bg2/races.2da
@@ -0,0 +1,12 @@
+2DA V1.0
+-1
+ NAME_REF DESC_REF CAP_REF ID USABILITY SAVE
+HUMAN 7193 9550 1096 1 0x08000000 *
+ELF 7194 9552 1097 2 0x00800000 *
+HALF_ELF 7197 9555 1098 3 0x02000000 *
+GNOME 7196 9553 1099 6 0x10000000 SAVECNG
+HALFLING 7195 9554 1101 5 0x04000000 SAVECNDH
+DWARF 7182 9551 1100 4 0x01000000 SAVECNDH
+HALFORC 53186 53191 53212 7 0x80000000 *
+TIEFLING 8332 -1 8330 153 0 *
+ILLITHID 54775 54776 2796 124 0 *
diff --git a/gemrb/override/bg2/randitem.2da b/gemrb/unhardcoded/bg2/randitem.2da
similarity index 100%
rename from gemrb/override/bg2/randitem.2da
rename to gemrb/unhardcoded/bg2/randitem.2da
diff --git a/gemrb/override/bg2/rest.spl b/gemrb/unhardcoded/bg2/rest.spl
similarity index 100%
rename from gemrb/override/bg2/rest.spl
rename to gemrb/unhardcoded/bg2/rest.spl
diff --git a/gemrb/override/bg2/restmov.2da b/gemrb/unhardcoded/bg2/restmov.2da
similarity index 100%
rename from gemrb/override/bg2/restmov.2da
rename to gemrb/unhardcoded/bg2/restmov.2da
diff --git a/gemrb/override/bg2/sanctry.vvc b/gemrb/unhardcoded/bg2/sanctry.vvc
similarity index 100%
rename from gemrb/override/bg2/sanctry.vvc
rename to gemrb/unhardcoded/bg2/sanctry.vvc
diff --git a/gemrb/override/bg2/savegame.2da b/gemrb/unhardcoded/bg2/savegame.2da
similarity index 100%
rename from gemrb/override/bg2/savegame.2da
rename to gemrb/unhardcoded/bg2/savegame.2da
diff --git a/gemrb/override/bg2/script.2da b/gemrb/unhardcoded/bg2/script.2da
similarity index 100%
rename from gemrb/override/bg2/script.2da
rename to gemrb/unhardcoded/bg2/script.2da
diff --git a/gemrb/override/bg2/shtable.2da b/gemrb/unhardcoded/bg2/shtable.2da
similarity index 100%
rename from gemrb/override/bg2/shtable.2da
rename to gemrb/unhardcoded/bg2/shtable.2da
diff --git a/gemrb/override/bg2/skills.2da b/gemrb/unhardcoded/bg2/skills.2da
similarity index 100%
rename from gemrb/override/bg2/skills.2da
rename to gemrb/unhardcoded/bg2/skills.2da
diff --git a/gemrb/override/bg2/slottype.2da b/gemrb/unhardcoded/bg2/slottype.2da
similarity index 100%
rename from gemrb/override/bg2/slottype.2da
rename to gemrb/unhardcoded/bg2/slottype.2da
diff --git a/gemrb/override/bg2/snow.spl b/gemrb/unhardcoded/bg2/snow.spl
similarity index 100%
rename from gemrb/override/bg2/snow.spl
rename to gemrb/unhardcoded/bg2/snow.spl
diff --git a/gemrb/override/bg2/spbrnhnd.pro b/gemrb/unhardcoded/bg2/spbrnhnd.pro
similarity index 100%
rename from gemrb/override/bg2/spbrnhnd.pro
rename to gemrb/unhardcoded/bg2/spbrnhnd.pro
diff --git a/gemrb/override/bg2/spconeco.pro b/gemrb/unhardcoded/bg2/spconeco.pro
similarity index 100%
rename from gemrb/override/bg2/spconeco.pro
rename to gemrb/unhardcoded/bg2/spconeco.pro
diff --git a/gemrb/override/bg2/spentaci.vvc b/gemrb/unhardcoded/bg2/spentaci.vvc
similarity index 100%
rename from gemrb/override/bg2/spentaci.vvc
rename to gemrb/unhardcoded/bg2/spentaci.vvc
diff --git a/gemrb/override/bg2/spfdeath.pro b/gemrb/unhardcoded/bg2/spfdeath.pro
similarity index 100%
rename from gemrb/override/bg2/spfdeath.pro
rename to gemrb/unhardcoded/bg2/spfdeath.pro
diff --git a/gemrb/override/bg2/spfirewl.pro b/gemrb/unhardcoded/bg2/spfirewl.pro
similarity index 100%
rename from gemrb/override/bg2/spfirewl.pro
rename to gemrb/unhardcoded/bg2/spfirewl.pro
diff --git a/gemrb/override/bg2/spgenhla.pro b/gemrb/unhardcoded/bg2/spgenhla.pro
similarity index 100%
rename from gemrb/override/bg2/spgenhla.pro
rename to gemrb/unhardcoded/bg2/spgenhla.pro
diff --git a/gemrb/override/bg2/spholymt.pro b/gemrb/unhardcoded/bg2/spholymt.pro
similarity index 100%
rename from gemrb/override/bg2/spholymt.pro
rename to gemrb/unhardcoded/bg2/spholymt.pro
diff --git a/gemrb/unhardcoded/bg2/splspec.2da b/gemrb/unhardcoded/bg2/splspec.2da
new file mode 100644
index 0000000..aa82945
--- /dev/null
+++ b/gemrb/unhardcoded/bg2/splspec.2da
@@ -0,0 +1,9 @@
+2DA V1.0
+*
+ IDENTIFY_SILENCE
+SPWI110 1
+SPWI219 2
+SPIN649 2
+SPCL412 2
+SPCL414 2
+SPWI124 4
diff --git a/gemrb/override/bg2/spscorch.pro b/gemrb/unhardcoded/bg2/spscorch.pro
similarity index 100%
rename from gemrb/override/bg2/spscorch.pro
rename to gemrb/unhardcoded/bg2/spscorch.pro
diff --git a/gemrb/override/bg2/spscoric.pro b/gemrb/unhardcoded/bg2/spscoric.pro
similarity index 100%
rename from gemrb/override/bg2/spscoric.pro
rename to gemrb/unhardcoded/bg2/spscoric.pro
diff --git a/gemrb/override/bg2/spshield.vvc b/gemrb/unhardcoded/bg2/spshield.vvc
similarity index 100%
rename from gemrb/override/bg2/spshield.vvc
rename to gemrb/unhardcoded/bg2/spshield.vvc
diff --git a/gemrb/unhardcoded/bg2/stances.2da b/gemrb/unhardcoded/bg2/stances.2da
new file mode 100644
index 0000000..873dcda
--- /dev/null
+++ b/gemrb/unhardcoded/bg2/stances.2da
@@ -0,0 +1,6 @@
+2DA V1.0
+*
+ STANCE OVERRIDE
+0x2200 11 13
+0x8000 11 13
+0x8200 13 12
diff --git a/gemrb/override/bg2/start.2da b/gemrb/unhardcoded/bg2/start.2da
similarity index 100%
rename from gemrb/override/bg2/start.2da
rename to gemrb/unhardcoded/bg2/start.2da
diff --git a/gemrb/unhardcoded/bg2/strings.2da b/gemrb/unhardcoded/bg2/strings.2da
new file mode 100644
index 0000000..5c65540
--- /dev/null
+++ b/gemrb/unhardcoded/bg2/strings.2da
@@ -0,0 +1,187 @@
+2DA V1.0
+-1
+ STRREF
+SCATTERED 16457
+WHOLEPARTY 16484
+DOORLOCKED 16485
+MAGICTRAP 16486
+NORMALTRAP 16487
+TRAP 16488
+CANNOTGO 16489
+TRAPREMOVED 16490
+OVERSTOCKED 16491
+SLEEP 16492
+AMBUSH 16493
+CONTLOCKED 15874
+NOMONEY 16495
+CURSED 16304
+SPELLDISRUPT 16497
+DIED 16498
+MAYNOTREST 16499
+CANTRESTMONS 16500
+CANTSAVEMONS 16501
+CANTSAVE 16502
+NODIALOG 10945
+CANTSAVEDIALOG 19253
+CANTSAVEDIALOG2 19254
+CANTSAVEMOVIE 19255
+TARGETBUSY 61393
+CANTTALKTRANS 62158
+GOTGOLD 17572
+LOSTGOLD 17573
+GOTXP 17574
+LOSTXP 17575
+GOTITEM 17576
+LOSTITEM 17577
+GOTREP 19686
+LOSTREP 19687
+GOTABILITY 10514
+GOTSPELL 61354
+GOTSONG 10514
+NOTHINGTOSAY 32092
+JOURNALCHANGE 11359
+WORLDMAPCHANGE 11360
+PAUSED 16321
+UNPAUSED 16322
+SCRIPTPAUSED 54381
+AP_UNUSABLE 17113
+AP_ATTACKED 17114
+AP_HIT 17115
+AP_WOUNDED 17116
+AP_DEAD 17117
+AP_NOTARGET 17118
+AP_ENDROUND 10014
+AP_ENEMY 23511
+AP_TRAP 58225
+AP_SPELLCAST 31874
+AP_GENERIC 17166
+AP_RESERVED1 -1
+AP_RESERVED2 -1
+AP_RESERVED3 -1
+CHARMED 14672
+DIRECHARMED 14780
+CONTROLLED 61394
+EVIL 16505
+GNE_NEUTRAL 16504
+GOOD 16503
+STR_LAWFUL -1
+LNC_NEUTRAL -1
+CHAOTIC -1
+ACTION_CAST 16464
+ACTION_ATTACK 16465
+ACTION_TURN 16466
+ACTION_SONG 16467
+ACTION_FINDTRAP 16468
+MAGICWEAPON 10141
+OFFHAND_USED 9380
+TWOHANDED_USED 9381
+CANNOT_USE_ITEM 9382
+CANT_DROP_ITEM 25697
+NOT_IN_OFFHAND 26342
+ITEM_IS_CURSED 16304
+NO_CRITICAL 20696
+TRACKING 67807
+TRACKINGFAILED 19534
+DOOR_NOPICK 23169
+CONT_NOPICK 23169
+CANTSAVECOMBAT 3041
+CANTSAVENOCTRL 54401
+LOCKPICK_DONE 16517
+LOCKPICK_FAILED 16518
+STATIC_DISSIPATE -1
+LIGHTNING_DISSIPATE -1
+HAS_NO_ABILITY 17317
+NEEDS_IDENTIFY 17316
+WRONG_ITEMTYPE 9375
+HAS_ITEMEXCL 20685
+PICKPOCKET_DONE 10072
+PICKPOCKET_NONE 55369
+PICKPOCKET_FAIL 10069
+PICKPOCKET_EVIL 10068
+PICKPOCKET_ARMOR 10067
+USING_FEAT -1
+STOPPED_FEAT -1
+DISARM_DONE 16520
+DISARM_FAIL 1608
+DOORBASH_DONE 9915
+DOORBASH_FAIL 9913
+CONTBASH_DONE 9916
+CONTBASH_FAIL 9914
+MAYNOTSETTRAP 31891
+SNAREFAILED 56378
+SNARESUCCEED 3799
+NOMORETRAP 72712
+DISABLEDMAGE 8856
+SAVESUCCEED 1682
+QSAVESUCCEED 10237
+UNINJURED 38551
+INJURED1 38552
+INJURED2 38553
+INJURED3 38554
+INJURED4 38555
+HOURS 10700
+HOUR 10701
+DAYS 10697
+DAY 10698
+REST 10690
+JOURNEY 10689
+SUMMONINGLIMIT 20969
+INVFULL 61794
+TOOFARAWAY 18002
+DAMAGE_IMMUNITY 5199
+DAMAGE_STR1 14027
+DAMAGE_STR2 3805
+DAMAGE_STR3 -1
+DMG_POISON -1
+DMG_MAGIC -1
+DMG_MISSILE -1
+DMG_SLASHING -1
+DMG_PIERCING -1
+DMG_CRUSHING -1
+DMG_FIRE -1
+DMG_ELECTRIC -1
+DMG_COLD -1
+DMG_ACID -1
+DMG_OTHER -1
+GOTQUESTXP 46858
+LEVELUP 17119
+INVFULL_ITEMDROP 32879
+CONT_DUP 32876
+CONT_TRIG 36936
+CONT_FAIL 36937
+SEQ_DUP 39722
+CRITICAL_HIT 16462
+CRITICAL_MISS 16463
+DEATH 14026
+BACKSTAB 12128
+BACKSTAB_BAD 10013
+BACKSTAB_FAIL 3042
+CASTER_LVL_INC 73544
+CASTER_LVL_DEC 73545
+CHARS_EXPORTED -1
+PALADIN_FALL 19620
+RANGER_FALL 19621
+RES_RESISTED -1
+DEADMAGIC_FAIL 70306
+MISCASTMAGIC 467
+WILDSURGE 52260
+FAMBLOCK 8537
+FAMPROTAGONIST 8538
+MAGIC_RESISTED 19224
+CANTSAVESTORE 10841
+NOSEE_NOCAST 46529
+AURACLEANSED 23797
+INDOOR_FAIL 9744
+SPELL_DISRUPTED 14796
+CHAOSSHIELD 64298
+RAPIDSHOT -1
+HAMSTRING -1
+ARTERIAL -1
+EXPERTISE -1
+POWERATTACK -1
+CLEAVE -1
+HELD 14102
+SLOWED 19503
+CANTMOVE 19504
+CASTS -1
+WEAPONINEFFECTIVE -1
diff --git a/gemrb/override/bg2/walksnd.2da b/gemrb/unhardcoded/bg2/walksnd.2da
similarity index 100%
rename from gemrb/override/bg2/walksnd.2da
rename to gemrb/unhardcoded/bg2/walksnd.2da
diff --git a/gemrb/override/bg2/wildmag.2da b/gemrb/unhardcoded/bg2/wildmag.2da
similarity index 100%
rename from gemrb/override/bg2/wildmag.2da
rename to gemrb/unhardcoded/bg2/wildmag.2da
diff --git a/gemrb/override/bg2/wishcode.2da b/gemrb/unhardcoded/bg2/wishcode.2da
similarity index 100%
rename from gemrb/override/bg2/wishcode.2da
rename to gemrb/unhardcoded/bg2/wishcode.2da
diff --git a/gemrb/override/bg2/wsshield.2da b/gemrb/unhardcoded/bg2/wsshield.2da
similarity index 100%
rename from gemrb/override/bg2/wsshield.2da
rename to gemrb/unhardcoded/bg2/wsshield.2da
diff --git a/gemrb/override/bg2/wssingle.2da b/gemrb/unhardcoded/bg2/wssingle.2da
similarity index 100%
rename from gemrb/override/bg2/wssingle.2da
rename to gemrb/unhardcoded/bg2/wssingle.2da
diff --git a/gemrb/override/bg2/wstwohnd.2da b/gemrb/unhardcoded/bg2/wstwohnd.2da
similarity index 100%
rename from gemrb/override/bg2/wstwohnd.2da
rename to gemrb/unhardcoded/bg2/wstwohnd.2da
diff --git a/gemrb/override/bg2/wstwowpn.2da b/gemrb/unhardcoded/bg2/wstwowpn.2da
similarity index 100%
rename from gemrb/override/bg2/wstwowpn.2da
rename to gemrb/unhardcoded/bg2/wstwowpn.2da
diff --git a/gemrb/unhardcoded/how/Makefile.am b/gemrb/unhardcoded/how/Makefile.am
new file mode 100644
index 0000000..d0c15fa
--- /dev/null
+++ b/gemrb/unhardcoded/how/Makefile.am
@@ -0,0 +1,3 @@
+howunhardcoded_DATA = *.2da *.ini *.chu *.ids *.spl *.pro
+howunhardcodeddir = $(moddir)/unhardcoded/how/
+EXTRA_DIST = *.2da *.ini *.chu *.ids *.spl *.pro
diff --git a/gemrb/override/how/ability.2da b/gemrb/unhardcoded/how/ability.2da
similarity index 100%
rename from gemrb/override/how/ability.2da
rename to gemrb/unhardcoded/how/ability.2da
diff --git a/gemrb/override/how/abjurap.pro b/gemrb/unhardcoded/how/abjurap.pro
similarity index 100%
rename from gemrb/override/how/abjurap.pro
rename to gemrb/unhardcoded/how/abjurap.pro
diff --git a/gemrb/override/how/abjurh.pro b/gemrb/unhardcoded/how/abjurh.pro
similarity index 100%
rename from gemrb/override/how/abjurh.pro
rename to gemrb/unhardcoded/how/abjurh.pro
diff --git a/gemrb/override/how/abjurt.pro b/gemrb/unhardcoded/how/abjurt.pro
similarity index 100%
rename from gemrb/override/how/abjurt.pro
rename to gemrb/unhardcoded/how/abjurt.pro
diff --git a/gemrb/override/how/acidblgr.pro b/gemrb/unhardcoded/how/acidblgr.pro
similarity index 100%
rename from gemrb/override/how/acidblgr.pro
rename to gemrb/unhardcoded/how/acidblgr.pro
diff --git a/gemrb/override/how/acidblmu.pro b/gemrb/unhardcoded/how/acidblmu.pro
similarity index 100%
rename from gemrb/override/how/acidblmu.pro
rename to gemrb/unhardcoded/how/acidblmu.pro
diff --git a/gemrb/override/how/acidblob.pro b/gemrb/unhardcoded/how/acidblob.pro
similarity index 100%
rename from gemrb/override/how/acidblob.pro
rename to gemrb/unhardcoded/how/acidblob.pro
diff --git a/gemrb/override/how/acidbloc.pro b/gemrb/unhardcoded/how/acidbloc.pro
similarity index 100%
rename from gemrb/override/how/acidbloc.pro
rename to gemrb/unhardcoded/how/acidbloc.pro
diff --git a/gemrb/override/how/acidh.pro b/gemrb/unhardcoded/how/acidh.pro
similarity index 100%
rename from gemrb/override/how/acidh.pro
rename to gemrb/unhardcoded/how/acidh.pro
diff --git a/gemrb/override/how/adhwil.pro b/gemrb/unhardcoded/how/adhwil.pro
similarity index 100%
rename from gemrb/override/how/adhwil.pro
rename to gemrb/unhardcoded/how/adhwil.pro
diff --git a/gemrb/override/how/adhwilh.pro b/gemrb/unhardcoded/how/adhwilh.pro
similarity index 100%
rename from gemrb/override/how/adhwilh.pro
rename to gemrb/unhardcoded/how/adhwilh.pro
diff --git a/gemrb/override/how/alance.pro b/gemrb/unhardcoded/how/alance.pro
similarity index 100%
rename from gemrb/override/how/alance.pro
rename to gemrb/unhardcoded/how/alance.pro
diff --git a/gemrb/override/how/aligns.2da b/gemrb/unhardcoded/how/aligns.2da
similarity index 100%
rename from gemrb/override/how/aligns.2da
rename to gemrb/unhardcoded/how/aligns.2da
diff --git a/gemrb/override/how/altera.pro b/gemrb/unhardcoded/how/altera.pro
similarity index 100%
rename from gemrb/override/how/altera.pro
rename to gemrb/unhardcoded/how/altera.pro
diff --git a/gemrb/override/how/alteranp.pro b/gemrb/unhardcoded/how/alteranp.pro
similarity index 100%
rename from gemrb/override/how/alteranp.pro
rename to gemrb/unhardcoded/how/alteranp.pro
diff --git a/gemrb/override/how/alterap.pro b/gemrb/unhardcoded/how/alterap.pro
similarity index 100%
rename from gemrb/override/how/alterap.pro
rename to gemrb/unhardcoded/how/alterap.pro
diff --git a/gemrb/override/how/alteras.pro b/gemrb/unhardcoded/how/alteras.pro
similarity index 100%
rename from gemrb/override/how/alteras.pro
rename to gemrb/unhardcoded/how/alteras.pro
diff --git a/gemrb/override/how/alterh.pro b/gemrb/unhardcoded/how/alterh.pro
similarity index 100%
rename from gemrb/override/how/alterh.pro
rename to gemrb/unhardcoded/how/alterh.pro
diff --git a/gemrb/override/how/altert.pro b/gemrb/unhardcoded/how/altert.pro
similarity index 100%
rename from gemrb/override/how/altert.pro
rename to gemrb/unhardcoded/how/altert.pro
diff --git a/gemrb/override/how/area1np.pro b/gemrb/unhardcoded/how/area1np.pro
similarity index 100%
rename from gemrb/override/how/area1np.pro
rename to gemrb/unhardcoded/how/area1np.pro
diff --git a/gemrb/override/how/area1p.pro b/gemrb/unhardcoded/how/area1p.pro
similarity index 100%
rename from gemrb/override/how/area1p.pro
rename to gemrb/unhardcoded/how/area1p.pro
diff --git a/gemrb/override/how/area2.pro b/gemrb/unhardcoded/how/area2.pro
similarity index 100%
rename from gemrb/override/how/area2.pro
rename to gemrb/unhardcoded/how/area2.pro
diff --git a/gemrb/override/how/area2np.pro b/gemrb/unhardcoded/how/area2np.pro
similarity index 100%
rename from gemrb/override/how/area2np.pro
rename to gemrb/unhardcoded/how/area2np.pro
diff --git a/gemrb/override/how/area3p.pro b/gemrb/unhardcoded/how/area3p.pro
similarity index 100%
rename from gemrb/override/how/area3p.pro
rename to gemrb/unhardcoded/how/area3p.pro
diff --git a/gemrb/override/how/area4np.pro b/gemrb/unhardcoded/how/area4np.pro
similarity index 100%
rename from gemrb/override/how/area4np.pro
rename to gemrb/unhardcoded/how/area4np.pro
diff --git a/gemrb/override/how/areapro.2da b/gemrb/unhardcoded/how/areapro.2da
similarity index 100%
rename from gemrb/override/how/areapro.2da
rename to gemrb/unhardcoded/how/areapro.2da
diff --git a/gemrb/override/how/armorh.pro b/gemrb/unhardcoded/how/armorh.pro
similarity index 100%
rename from gemrb/override/how/armorh.pro
rename to gemrb/unhardcoded/how/armorh.pro
diff --git a/gemrb/override/how/arrow.pro b/gemrb/unhardcoded/how/arrow.pro
similarity index 100%
rename from gemrb/override/how/arrow.pro
rename to gemrb/unhardcoded/how/arrow.pro
diff --git a/gemrb/override/how/arrowex.pro b/gemrb/unhardcoded/how/arrowex.pro
similarity index 100%
rename from gemrb/override/how/arrowex.pro
rename to gemrb/unhardcoded/how/arrowex.pro
diff --git a/gemrb/override/how/arrowflb.pro b/gemrb/unhardcoded/how/arrowflb.pro
similarity index 100%
rename from gemrb/override/how/arrowflb.pro
rename to gemrb/unhardcoded/how/arrowflb.pro
diff --git a/gemrb/override/how/arrowflg.pro b/gemrb/unhardcoded/how/arrowflg.pro
similarity index 100%
rename from gemrb/override/how/arrowflg.pro
rename to gemrb/unhardcoded/how/arrowflg.pro
diff --git a/gemrb/override/how/arrowfli.pro b/gemrb/unhardcoded/how/arrowfli.pro
similarity index 100%
rename from gemrb/override/how/arrowfli.pro
rename to gemrb/unhardcoded/how/arrowfli.pro
diff --git a/gemrb/override/how/arrowflm.pro b/gemrb/unhardcoded/how/arrowflm.pro
similarity index 100%
rename from gemrb/override/how/arrowflm.pro
rename to gemrb/unhardcoded/how/arrowflm.pro
diff --git a/gemrb/override/how/arrowhvy.pro b/gemrb/unhardcoded/how/arrowhvy.pro
similarity index 100%
rename from gemrb/override/how/arrowhvy.pro
rename to gemrb/unhardcoded/how/arrowhvy.pro
diff --git a/gemrb/override/how/ascorch.pro b/gemrb/unhardcoded/how/ascorch.pro
similarity index 100%
rename from gemrb/override/how/ascorch.pro
rename to gemrb/unhardcoded/how/ascorch.pro
diff --git a/gemrb/override/how/astorm.pro b/gemrb/unhardcoded/how/astorm.pro
similarity index 100%
rename from gemrb/override/how/astorm.pro
rename to gemrb/unhardcoded/how/astorm.pro
diff --git a/gemrb/override/how/asumm1.pro b/gemrb/unhardcoded/how/asumm1.pro
similarity index 100%
rename from gemrb/override/how/asumm1.pro
rename to gemrb/unhardcoded/how/asumm1.pro
diff --git a/gemrb/override/how/asumm1h.pro b/gemrb/unhardcoded/how/asumm1h.pro
similarity index 100%
rename from gemrb/override/how/asumm1h.pro
rename to gemrb/unhardcoded/how/asumm1h.pro
diff --git a/gemrb/override/how/asumm1x.pro b/gemrb/unhardcoded/how/asumm1x.pro
similarity index 100%
rename from gemrb/override/how/asumm1x.pro
rename to gemrb/unhardcoded/how/asumm1x.pro
diff --git a/gemrb/override/how/asumm2h.pro b/gemrb/unhardcoded/how/asumm2h.pro
similarity index 100%
rename from gemrb/override/how/asumm2h.pro
rename to gemrb/unhardcoded/how/asumm2h.pro
diff --git a/gemrb/override/how/asumm3h.pro b/gemrb/unhardcoded/how/asumm3h.pro
similarity index 100%
rename from gemrb/override/how/asumm3h.pro
rename to gemrb/unhardcoded/how/asumm3h.pro
diff --git a/gemrb/unhardcoded/how/avatars.2da b/gemrb/unhardcoded/how/avatars.2da
new file mode 100644
index 0000000..668ffc3
--- /dev/null
+++ b/gemrb/unhardcoded/how/avatars.2da
@@ -0,0 +1,417 @@
+2DA V1.0
+*
+ AT_1 AT_2 AT_3 AT_4 TYPE SPACE PALETTE SIZE
+0x0100 SPCHUNKS SPCHUNKS SPCHUNKS SPCHUNKS 13 0 0 *
+0x0300 SPSMPUFF SPSMPUFF SPSMPUFF SPSMPUFF 13 0 0 *
+0x0400 SKLH SKLH SKLH SKLH 13 0 1 *
+0x0410 GLPHWRDH GLPHWRDH GLPHWRDH GLPHWRDH 13 0 1 *
+0x1000 MWYV MWYV MWYV MWYV 11 5 1 *
+0x1001 MWYV MWYV MWYV MWYV 11 5 1 *
+0x1100 MTAN MTAN MTAN MTAN 11 5 1 *
+0x1200 MDR1 MDR1 MDR1 MDR1 12 5 1 *
+0x1201 MDR2 MDR2 MDR2 MDR2 12 5 1 *
+0x1202 MDR3 MDR3 MDR3 MDR3 12 5 1 *
+0x1203 MDR1 MDR1 MDR1 MDR1 12 7 GR *
+0x1204 MDR1 MDR1 MDR1 MDR1 12 7 AQ *
+0x1205 MDR1 MDR1 MDR1 MDR1 12 7 BL *
+0x1206 MDR1 MDR1 MDR1 MDR1 12 7 BR *
+0x1207 MDR1 MDR1 MDR1 MDR1 12 7 MC *
+0x1208 MDR1 MDR1 MDR1 MDR1 12 7 PU *
+0x2000 MSIR MSIR MSIR MSIR 2 2 0 *
+0x2100 UVOL UVOL UVOL UVOL 2 2 1 *
+0x2200 MOGM MOGM MOGM MOGM 2 2 0 S
+0x2300 MDKN MDKN MDKN MDKN 2 2 1 *
+0x3000 MAKH MAKH MAKH MAKH 2 3 1 *
+0x4000 SNOMC SNOMC SNOMC SNOMC 1 2 0 *
+0x4002 SNOMM SNOMM SNOMM SNOMM 1 2 0 *
+0x4010 SNOWC SNOWC SNOWC SNOWC 1 2 0 *
+0x4012 SNOWM SNOWM SNOWM SNOWM 1 2 0 *
+0x4100 SSIMC SSIMC SSIMC SSIMC 1 2 0 *
+0x4101 SSIMS SSIMS SSIMS SSIMS 1 2 0 *
+0x4102 SSIMM SSIMM SSIMM SSIMM 1 2 0 *
+0x4110 SSIWC SSIWC SSIWC SSIWC 1 2 0 *
+0x4112 SSIWM SSIWM SSIWM SSIWM 1 2 0 *
+0x4200 SHMCM SHMCM SHMCM SHMCM 1 2 0 *
+0x4300 MSPLG1 MSPLG1 MSPLG1 MSPLG1 1 2 1 *
+0x4400 LHMC LHMC LHMC LHMC 1 2 0 *
+0x4410 LHFC LHFC LHFC LHFC 1 2 0 *
+0x4500 LFAM LFAM LFAM LFAM 1 2 0 *
+0x4600 LDMF LDMF LDMF LDMF 1 2 0 *
+0x4700 LEMF LEMF LEMF LEMF 1 2 0 *
+0x4710 LEFF LEFF LEFF LEFF 1 2 0 *
+0x4800 LIMC LIMC LIMC LIMC 1 2 0 *
+0x5000 CHMB1 CHMB2 CHMB3 CHMC4 0 2 0 L
+0x5001 CEMB1 CEMB2 CEMB3 CEMC4 0 2 0 M
+0x5002 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 S
+0x5003 CIMB1 CIMB2 CIMB3 CIMC4 0 2 0 S
+0x5010 CHFB1 CHFB2 CHFB3 CHFC4 0 2 0 M
+0x5011 CEFB1 CEFB2 CEFB3 CEFC4 0 2 0 M
+0x5012 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 S
+0x5013 CIFB1 CIFB2 CIFB3 CIFC4 0 2 0 S
+0x5100 CHMB1 CHMB2 CHMB3 CHMF4 0 2 0 L
+0x5101 CEMB1 CEMB2 CEMB3 CHMF4 0 2 0 M
+0x5102 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 S
+0x5103 CIMB1 CIMB2 CIMB3 CIMF4 0 2 0 S
+0x5110 CHFB1 CHFB2 CHFB3 CHFF4 0 2 0 M
+0x5111 CEFB1 CEFB2 CEFB3 CEFF4 0 2 0 M
+0x5112 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 S
+0x5113 CIFB1 CIFB2 CIFB3 CIFF4 0 2 0 S
+0x5200 CHMW1 CHMW2 CHMW3 CHMW4 0 2 0 L
+0x5201 CEMW1 CEMW2 CEMW3 CEMW4 0 2 0 M
+0x5202 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
+0x5203 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
+0x5210 CHFW1 CHFW2 CHFW3 CHFW4 0 2 0 M
+0x5211 CEFW1 CEFW2 CEFW3 CEFW4 0 2 0 M
+0x5212 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
+0x5213 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
+0x5300 CHMB1 CHMT2 CHMB3 CHMF4 0 2 0 L
+0x5301 CEMB1 CEMT2 CEMB3 CEMF4 0 2 0 M
+0x5302 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 S
+0x5303 CIMB1 CIMT2 CIMB3 CIMF4 0 2 0 S
+0x5310 CHFB1 CHFT2 CHFB3 CHFF4 0 2 0 M
+0x5311 CEFB1 CEFT2 CEFB3 CEFF4 0 2 0 M
+0x5312 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 S
+0x5313 CIFB1 CIFT2 CIFB3 CIFF4 0 2 0 S
+0x6000 CHMB1 CHMB2 CHMB3 CHMC4 0 2 0 L
+0x6001 CEMB1 CEMB2 CEMB3 CEMC4 0 2 0 M
+0x6002 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 S
+0x6003 CIMB1 CIMB2 CIMB3 CIMC4 0 2 0 S
+0x6004 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 S
+0x6010 CHFB1 CHFB2 CHFB3 CHFC4 0 2 0 M
+0x6011 CEFB1 CEFB2 CEFB3 CEFC4 0 2 0 M
+0x6012 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 S
+0x6013 CIFB1 CIFB2 CIFB3 CIFC4 0 2 0 S
+0x6014 CIFB1 CIFB2 CIFB3 CIFC4 0 2 0 S
+0x6100 CHMB1 CHMB2 CHMB3 CHMF4 0 2 0 L
+0x6101 CEMB1 CEMB2 CEMB3 CEMF4 0 2 0 M
+0x6102 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 S
+0x6103 CIMB1 CIMB2 CIMB3 CIMF4 0 2 0 S
+0x6104 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 S
+0x6110 CHFB1 CHFB2 CHFB3 CHFF4 0 2 0 M
+0x6111 CEFB1 CEFB2 CEFB3 CEFF4 0 2 0 M
+0x6112 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 S
+0x6113 CIFB1 CIFB2 CIFB3 CIFF4 0 2 0 S
+0x6114 CIFB1 CIFB2 CIFB3 CIFF4 0 2 0 S
+0x6200 CHMW1 CHMW2 CHMW3 CHMW4 0 2 0 L
+0x6201 CEMW1 CEMW2 CEMW3 CEMW4 0 2 0 M
+0x6202 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
+0x6203 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
+0x6204 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
+0x6210 CHFW1 CHFW2 CHFW3 CHFW4 0 2 0 M
+0x6211 CEFW1 CEFW2 CEFW3 CEFW4 0 2 0 M
+0x6212 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
+0x6213 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
+0x6214 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 S
+0x6300 CHMB1 CHMT2 CHMB3 CHMF4 0 2 0 L
+0x6301 CEMB1 CEMT2 CEMB3 CEMF4 0 2 0 M
+0x6302 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 S
+0x6303 CIMB1 CIMT2 CIMB3 CIMF4 0 2 0 S
+0x6304 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 S
+0x6310 CHFB1 CHFT2 CHFB3 CHFF4 0 2 0 M
+0x6311 CEFB1 CEFT2 CEFB3 CEFF4 0 2 0 M
+0x6312 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 S
+0x6313 CIFB1 CIFT2 CIFB3 CIFF4 0 2 0 S
+0x6314 CIFB1 CIFT2 CIFB3 CIFF4 0 2 0 S
+0x6400 UDRZ1 UDRZ1 UDRZ1 UDRZ1 6 2 0 *
+0x6401 UELM1 UELM1 UELM1 UELM1 6 2 1 *
+0x6402 CMNK1 CMNK1 CMNK1 CMNK1 6 2 0 *
+0x6403 MSKL1 MSKL1 MSKL1 MSKL1 6 2 0 M
+0x6404 USAR1 USAR1 USAR1 USAR1 6 2 1 *
+0x6405 MDGU1 MDGU1 MDGU1 MDGU1 6 2 0 M
+0x6406 MDGU1 MDGU1 MDGU1 MDGU1 6 2 0 L
+0x6500 CHMM1 CHMB2 CHMB3 CHMC4 0 2 0 M
+0x6510 CHFM1 CHFB2 CHFB3 CHFC4 0 2 0 M
+0x7000 MOGH MOGH MOGH MOGH 2 2 0 *
+0x7001 MOGN MOGN MOGN MOGN 2 2 0 *
+0x7100 MBAS MBAS MBAS MBAS 2 2 1 *
+0x7101 MBAS MBAS MBAS MBAS 2 2 GR *
+0x7200 MBER MBER MBER MBER 3 2 BL *
+0x7201 MBER MBER MBER MBER 3 2 1 *
+0x7202 MBER MBER MBER MBER 3 2 CA *
+0x7203 MBER MBER MBER MBER 3 2 PO *
+0x7300 MEAE MEAE MEAE MEAE 4 2 1 *
+0x7301 MEAS MEAS MEAS MEAS 4 2 1 *
+0x7302 MEAE MEAE MEAE MEAE 4 2 SH *
+0x7310 MFIE MFIE MFIE MFIE 4 2 1 *
+0x7311 MFIS MFIS MFIS MFIS 4 2 1 *
+0x7320 MAIR MAIR MAIR MAIR 4 2 1 *
+0x7321 MAIS MAIS MAIS MAIS 4 2 1 *
+0x7400 MDOG MDOG MDOG MDOG 2 2 WI *
+0x7401 MDOG MDOG MDOG MDOG 2 2 WA *
+0x7402 MDOG MDOG MDOG MDOG 2 2 MO *
+0x7500 MDOP MDOP MDOP MDOP 3 2 1 *
+0x7501 MDOP MDOP MDOP MDOP 3 2 GR *
+0x7600 METT METT METT METT 2 2 1 *
+0x7701 MGHL MGHL MGHL MGHL 2 2 1 *
+0x7702 MGHL MGHL MGHL MGHL 2 2 RE *
+0x7703 MGHL MGHL MGHL MGHL 2 2 GA *
+0x7704 MSHD MSHD MSHD MSHD 4 2 1 *
+0x7800 MGIB MGIB MGIB MGIB 14 2 1 *
+0x7900 MSLI MSLI MSLI MSLI 3 3 GR *
+0x7901 MSLI MSLI MSLI MSLI 3 3 OL *
+0x7902 MSLI MSLI MSLI MSLI 3 3 MU *
+0x7903 MSLI MSLI MSLI MSLI 3 3 OC *
+0x7904 MSLI MSLI MSLI MSLI 3 3 1 *
+0x7A00 MSPI MSPI MSPI MSPI 3 2 GI *
+0x7A01 MSPI MSPI MSPI MSPI 3 2 HU *
+0x7A02 MSPI MSPI MSPI MSPI 3 2 PH *
+0x7A03 MSPI MSPI MSPI MSPI 3 2 SW *
+0x7A04 MSPI MSPI MSPI MSPI 3 2 WR *
+0x7B00 MWLF MWLF MWLF MWLF 2 2 1 *
+0x7B01 MWLF MWLF MWLF MWLF 2 2 WO *
+0x7B02 MWLF MWLF MWLF MWLF 2 2 DI *
+0x7B03 MWLF MWLF MWLF MWLF 2 2 WI *
+0x7B04 MWLF MWLF MWLF MWLF 2 2 VA *
+0x7B05 MWLF MWLF MWLF MWLF 2 2 DR *
+0x7B06 MWLS MWLS MWLS MWLS 2 2 1 *
+0x7C00 MXVT MXVT MXVT MXVT 2 2 0 *
+0x7C01 MTAS MTAS MTAS MTAS 2 2 0 *
+0x7D00 MZOM MZOM MZOM MZOM 2 2 0 *
+0x7E00 MWER MWER MWER MWER 2 2 1 *
+0x7E01 MGWE MGWE MGWE MGWE 2 2 1 *
+0x7F00 MTRO MTRO MTRO MTRO 4 2 1 *
+0x7F01 MMIN MMIN MMIN MMIN 4 2 1 *
+0x7F02 MBEH MBEH MBEH MBEH 4 3 1 *
+0x7F03 MIMP MIMP MIMP MIMP 4 2 1 *
+0x7F04 MIGO MIGO MIGO MIGO 4 2 1 *
+0x7F05 MDJI MDJI MDJI MDJI 4 2 1 *
+0x7F06 MDJL MDJL MDJL MDJL 4 2 1 *
+0x7F07 MGLC MGLC MGLC MGLC 4 3 1 *
+0x7F08 MOTY MOTY MOTY MOTY 4 4 1 *
+0x7F09 MSAH MSAH MSAH MSAH 4 2 1 *
+0x7F0A MGCP MGCP MGCP MGCP 4 2 1 *
+0x7F0B MGCL MGCL MGCL MGCL 4 2 1 *
+0x7F0C MKUO MKUO MKUO MKUO 4 2 1 *
+0x7F0D MLIC MLIC MLIC MLIC 4 2 1 *
+0x7F0E MDLI MDLI MDLI MDLI 4 2 1 *
+0x7F0F MTRS MTRS MTRS MTRS 4 2 1 *
+0x7F10 MRAK MRAK MRAK MRAK 4 2 1 *
+0x7F11 MUMB MUMB MUMB MUMB 4 2 1 *
+0x7F12 MVAM MVAM MVAM MVAM 4 2 1 *
+0x7F13 MSNK MSNK MSNK MSNK 4 2 1 *
+0x7F14 MGIT MGIT MGIT MGIT 4 2 1 *
+0x7F15 MBES MBES MBES MBES 4 2 1 *
+0x7F16 AMOO AMOO AMOO AMOO 4 3 1 *
+0x7F17 ARAB ARAB ARAB ARAB 4 1 1 *
+0x7F18 ADER ADER ADER ADER 4 2 1 *
+0x7F19 MDSW MDSW MDSW MDSW 4 2 1 *
+0x7F20 AGRO AGRO AGRO AGRO 4 2 1 *
+0x7F21 APHE APHE APHE APHE 4 2 1 *
+0x7F22 MVAF MVAF MVAF MVAF 4 2 1 *
+0x7F23 MSAT MSAT MSAT MSAT 4 3 1 *
+0x7F24 NPIR NPIR NPIR NPIR 4 2 1 *
+0x7F27 MDRO MDRO MDRO MDRO 4 2 1 *
+0x7F28 MKUL MKUL MKUL MKUL 4 3 1 *
+0x7F29 MFDR MFDR MFDR MFDR 4 2 1 *
+0x7F2A NSAI NSAI NSAI NSAI 4 2 1 *
+0x7F2C NSOL NSOL NSOL NSOL 4 2 1 *
+0x7F2D MWFM MWFM MWFM MWFM 4 2 1 *
+0x7F2E MRAV MRAV MRAV MRAV 4 3 1 *
+0x7F2F MSPS MSPS MSPS MSPS 4 2 1 *
+0x7F30 NBOH NBOH NBOH NBOH 4 2 1 *
+0x7F31 NELL NELL NELL NELL 4 2 1 *
+0x7F32 MSLY MSLY MSLY MSLY 4 2 1 *
+0x7F35 MMIS MMIS MMIS MMIS 4 3 1 *
+0x7F36 NSHD NSHD NSHD NSHD 4 2 1 *
+0x7F37 NIRE NIRE NIRE NIRE 4 2 1 *
+0x8000 MGNL MGNL MGNL MGNL 2 2 0 *
+0x8100 MHOB MHOB MHOB MHOB 2 2 0 *
+0x8200 MKOB MKOB MKOB MKOB 2 2 0 *
+0x9000 MOGR MOGR MOGR MOGR 5 2 0 *
+0xA000 MWYV MWYV MWYV MWYV 8 3 1 *
+0xA100 MCAR MCAR MCAR MCAR 8 3 1 *
+0xB000 ACOW ACOW ACOW ACOW 10 3 1 *
+0xB100 AHRS AHRS AHRS AHRS 10 3 1 *
+0xB200 NBEGL NBEGL NBEGL NBEGL 2 2 0 *
+0xB210 NPROL NPROL NPROL NPROL 2 2 0 *
+0xB300 NBOYL NBOYL NBOYL NBOYL 3 2 0 *
+0xB310 NGRLL NGRLL NGRLL NGRLL 3 2 0 *
+0xB400 NFAML NFAML NFAML NFAML 2 2 0 *
+0xB410 NFAWL NFAWL NFAWL NFAWL 2 2 0 *
+0xB500 NSIML NSIML NSIML NSIML 2 2 0 *
+0xB510 NSIWL NSIWL NSIWL NSIWL 2 2 0 *
+0xB600 NNOML NNOML NNOML NNOML 2 2 0 *
+0xB610 NNOWL NNOWL NNOWL NNOWL 2 2 0 *
+0xB700 NSVLL NSVLL NSIWL NSIWL 2 2 0 *
+0xC000 ABAT ABAT ABAT ABAT 2 1 1 *
+0xC100 ACAT ACAT ACAT ACAT 2 1 1 *
+0xC200 ACHK ACHK ACHK ACHK 2 1 1 *
+0xC300 ARAT ARAT ARAT ARAT 2 1 1 *
+0xC400 ASQU ASQU ASQU ASQU 2 1 1 *
+0xC500 ABAT ABAT ABAT ABAT 2 1 1 *
+0xC600 NBEGH NBEGH NBEGH NBEGH 2 2 0 *
+0xC610 NPROH NPROH NPROH NPROH 2 2 0 *
+0xC700 NBOYH NBOYH NBOYH NBOYH 3 2 0 *
+0xC710 NGRLH NGRLH NGRLH NGRLH 3 2 0 *
+0xC800 NFAMH NFAMH NFAMH NFAMH 2 2 0 *
+0xC810 NFAWH NFAWH NFAWH NFAWH 2 2 0 *
+0xC900 NSIMH NSIMH NSIMH NSIMH 2 2 0 *
+0xC910 NSIWH NSIWH NSIWH NSIWH 2 2 0 *
+0xCA00 NNOMH NNOMH NNOMH NNOMH 2 2 0 *
+0xCA10 NNOWH NNOWH NNOWH NNOWH 2 2 0 *
+0xCB00 NSLVH NSLVH NSLVH NSLVH 2 2 0 *
+0xD000 AEAGG1 AEAGG1 AEAGG1 AEAGG1 7 0 1 *
+0xD100 AGULG1 AGULG1 AGULG1 AGULG1 7 0 1 *
+0xD200 AVULG1 AVULG1 AVULG1 AVULG1 7 0 1 *
+0xD300 ABIRG1 ABIRG1 ABIRG1 ABIRG1 7 0 1 *
+0xD400 ABIRG1 ABIRG1 ABIRG1 ABIRG1 7 0 1 *
+0xE000 MBET MBET MBET MBET 9 2 1 *
+0xE010 MBBM MBBM MBBM MBBM 16 2 1 *
+0xE020 MBBR MBBR MBBR MBBR 9 2 1 *
+0xE030 MBFI MBFI MBFI MBFI 9 2 1 *
+0xE040 MBRH MBRH MBRH MBRH 9 5 1 *
+0xE050 MREM MREM MREM MREM 9 4 1 *
+0xE060 MLIC MLIC MLIC MLIC 9 2 1 *
+0xE068 MHOH MHOH MHOH MHOH 9 2 1 *
+0xE070 MMIN MMIN MMIN MMIN 9 2 1 *
+0xE090 MMER MMER MMER MMER 9 2 1 *
+0xE0A0 MTIC MTIC MTIC MTIC 9 2 1 *
+0xE0B0 MTRO MTRO MTRO MTRO 9 2 1 *
+0xE0C0 MTSN MTSN MTSN MTSN 9 2 1 *
+0xE0D0 MUMB MUMB MUMB MUMB 9 2 1 *
+0xE0E0 MCOR MCOR MCOR MCOR 9 3 1 *
+0xE0F0 MGLA MGLA MGLA MGLA 9 2 1 *
+0xE100 MCYC MCYC MCYC MCYC 9 4 1 *
+0xE110 METN METN METN METN 9 4 1 *
+0xE130 MGFR MGFR MGFR MGFR 9 4 1 *
+0xE140 MGVE MGVE MGVE MGVE 9 4 1 *
+0xE150 MGFO MGFO MGFO MGFO 9 4 1 *
+0xE200 MELA MELA MELA MELA 9 4 1 *
+0xE210 MELE MELE MELE MELE 9 4 1 *
+0xE220 MELF MELF MELF MELF 9 4 1 *
+0xE230 MELW MELW MELW MELW 9 4 1 *
+0xE240 MHAR MHAR MHAR MHAR 9 2 1 *
+0xE250 MWWE MWWE MWWE MWWE 9 2 1 *
+0xE260 MFEY MFEY MFEY MFEY 9 2 1 *
+0xE270 MDTR MDTR MDTR MDTR 9 3 1 *
+0xE280 MFE2 MFE2 MFE2 MFE2 9 3 1 *
+0xE290 MEW2 MEW2 MEW2 MEW2 9 2 1 *
+0xE300 MGH2 MGH2 MGH2 MGH2 9 2 1 *
+0xE310 MGH3 MGH3 MGH3 MGH3 9 2 1 *
+0xE320 MWIG MWIG MWIG MWIG 9 2 1 *
+0xE330 MZO2 MZO2 MZO2 MZO2 9 2 1 *
+0xE340 MZO3 MZO3 MZO3 MZO3 16 2 1 *
+0xE350 MWI2 MWI2 MWI2 MWI2 9 2 1 *
+0xE360 MWI3 MWI3 MWI3 MWI3 9 2 1 *
+0xE380 MMUM MMUM MMUM MMUM 9 2 1 *
+0xE380 MMUM MMUM MMUM MMUM 9 2 1 *
+0xE390 MHIS MHIS MHIS MHIS 9 2 1 *
+0xE3A0 MDRD MDRD MDRD MDRD 9 2 1 *
+0xE3B0 MWAV MWAV MWAV MWAV 9 2 1 *
+0xE400 MGO1 MGO1 MGO1 MGO1 9 2 1 *
+0xE410 MGO2 MGO2 MGO2 MGO2 16 2 1 *
+0xE420 MGO3 MGO3 MGO3 MGO3 9 2 1 *
+0xE430 MGO4 MGO4 MGO4 MGO4 16 2 1 *
+0xE440 MSVI MSVI MSVI MSVI 9 2 1 *
+0xE450 MSV2 MSV2 MSV2 MSV2 9 2 1 *
+0xE460 MGWO MGWO MGWO MGWO 9 2 1 *
+0xE470 MGOC MGOC MGOC MGOC 9 2 1 *
+0xE480 MGW2 MGW2 MGW2 MGW2 9 2 1 *
+0xE490 MGO5 MGO5 MGO5 MGO5 9 2 1 *
+0xE500 MLIZ MLIZ MLIZ MLIZ 9 2 1 *
+0xE510 MGIR MGIR MGIR MGIR 9 3 1 *
+0xE520 MGIC MGIC MGIC MGIC 9 2 1 *
+0xE600 MMYC MMYC MMYC MMYC 9 2 1 *
+0xE610 MMY2 MMY2 MMY2 MMY2 9 2 1 *
+0xE620 MSKB MSKB MSKB MSKB 9 2 1 *
+0xE700 MNO1 MNO1 MNO1 MNO1 9 2 1 *
+0xE710 MNO2 MNO2 MNO2 MNO2 9 2 1 *
+0xE718 MTRO MTRO MTRO MTRO 9 2 1 *
+0xE720 MNO3 MNO3 MNO3 MNO3 9 2 1 *
+0xE730 MTSN MTSN MTSN MTSN 9 2 1 *
+0xE750 MUMB MUMB MUMB MUMB 9 2 1 *
+0xE760 MYET MYET MYET MYET 9 2 1 *
+0xE770 MBA4 MBA4 MBA4 MBA4 9 2 1 *
+0xE780 MBA5 MBA5 MBA5 MBA5 9 2 1 *
+0xE790 MBA6 MBA6 MBA6 MBA6 9 2 1 *
+0xE7A0 MBAI MBAI MBAI MBAI 9 2 1 *
+0xE7B0 MBOA MBOA MBOA MBOA 9 2 1 *
+0xE7C0 MABW MABW MABW MABW 9 2 1 *
+0xE7D0 MMAL MMAL MMAL MMAL 9 2 1 *
+0xE7E0 MSCR MSCR MSCR MSCR 9 2 1 *
+0xE7F0 MUM2 MUM2 MUM2 MUM2 9 2 1 *
+0xE800 MOR6 MOR6 MOR6 MOR6 9 2 1 *
+0xE810 MOR1 MOR1 MOR1 MOR1 9 2 1 *
+0xE820 MOR2 MOR2 MOR2 MOR2 16 2 1 *
+0xE830 MOR3 MOR3 MOR3 MOR3 9 2 1 *
+0xE840 MOR4 MOR4 MOR4 MOR4 16 2 1 *
+0xE850 MOR5 MOR5 MOR5 MOR5 9 2 1 *
+0xE860 MNO1 MNO1 MNO1 MNO1 9 2 1 *
+0xE870 MNO2 MNO2 MNO2 MNO2 9 2 1 *
+0xE880 MNO3 MNO3 MNO3 MNO3 9 2 1 *
+0xE890 MLI3 MLI3 MLI3 MLI3 9 2 1 *
+0xE8A0 MYU3 MYU3 MYU3 MYU3 9 2 1 *
+0xE8B0 MYUH MYUH MYUH MYUH 9 2 1 *
+0xE8C0 MBUG MBUG MBUG MBUG 9 2 1 *
+0xE8D0 MNOS MNOS MNOS MNOS 9 2 1 *
+0xE8E0 MBU2 MBU2 MBU2 MBU2 9 2 1 *
+0xE8F0 MOR7 MOR7 MOR7 MOR7 9 2 1 *
+0xE900 MSAL MSAL MSAL MSAL 16 2 1 *
+0xE908 MSH1 MSH1 MSH1 MSH1 16 2 1 *
+0xE910 MSA2 MSA2 MSA2 MSA2 16 2 1 *
+0xE918 MSH2 MSH2 MSH2 MSH2 16 2 1 *
+0xE920 MGHO MGHO MGHO MGHO 9 2 1 *
+0xEA00 MSHR MSHR MSHR MSHR 9 2 1 *
+0xEA10 MSH1 MSH1 MSH1 MSH1 16 2 1 *
+0xEA20 MCRD MCRD MCRD MCRD 9 2 1 *
+0xEB00 MSKT MSKT MSKT MSKT 9 2 1 *
+0xEB00 MANI MANI MANI MANI 9 3 1 *
+0xEB10 MSKA MSKA MSKA MSKA 9 2 1 *
+0xEB10 MANI MANI MANI MANI 9 2 1 *
+0xEB20 MAN2 MAN2 MAN2 MAN2 9 2 1 *
+0xEB30 MBE1 MBE1 MBE1 MBE1 9 2 1 *
+0xEB40 MBE2 MBE2 MBE2 MBE2 9 2 1 *
+0xEB51 MSEE MSEE MSEE MSEE 9 2 1 *
+0xEB52 MFIR MFIR MFIR MFIR 9 2 1 *
+0xEB60 MLIC MLIC MLIC MLIC 9 2 1 *
+0xEB70 MLER MLER MLER MLER 9 2 1 *
+0xEB80 MMAN MMAN MMAN MMAN 9 2 1 *
+0xEB90 MMYC MMYC MMYC MMYC 9 2 1 *
+0xEBA0 MMY2 MMY2 MMY2 MMY2 9 2 1 *
+0xEBB0 MSHR MSHR MSHR MSHR 9 2 1 *
+0xEBC0 MTAN MTAN MTAN MTAN 9 4 1 *
+0xEBD0 MSAL MSAL MSAL MSAL 16 2 1 *
+0xEBE0 MSA2 MSA2 MSA2 MSA2 16 2 1 *
+0xEBF0 MARU MARU MARU MARU 9 2 1 *
+0xEC00 MWDR MWDR MWDR MWDR 9 2 1 *
+0xEC10 MCHY MCHY MCHY MCHY 9 2 1 *
+0xEC20 MSHE MSHE MSHE MSHE 9 2 1 *
+0xEC30 MCHI MCHI MCHI MCHI 9 2 1 *
+0xEC40 MDH1 MDH1 MDH1 MDH1 9 2 1 *
+0xEC50 MDH2 MDH2 MDH2 MDH2 9 2 1 *
+0xED00 MYU1 MYU1 MYU1 MYU1 9 2 1 *
+0xED09 MCOR MCOR MCOR MCOR 9 3 1 *
+0xED10 MYU2 MYU2 MYU2 MYU2 9 2 1 *
+0xED19 MGLA MGLA MGLA MGLA 9 2 1 *
+0xED20 MYU3 MYU3 MYU3 MYU3 9 2 1 *
+0xED20 MLEM MLEM MLEM MLEM 9 2 1 *
+0xEE00 MWEB MWEB MWEB MWEB 9 2 1 *
+0xEE10 MWRA MWRA MWRA MWRA 9 2 1 *
+0xEF00 MISA MISA MISA MISA 9 2 1 *
+0xEF10 MMAD MMAD MMAD MMAD 9 2 1 *
+0xEF20 MWOR MWOR MWOR MWOR 9 2 1 *
+0xEF50 MKG1 MKG1 MKG1 MKG1 9 2 1 *
+0xEF60 MKG2 MKG2 MKG2 MKG2 9 2 1 *
+0xEF70 MKG3 MKG3 MKG3 MKG3 9 2 1 *
+0xEF90 MWIL MWIL MWIL MWIL 9 2 1 *
+0xEFA0 MGEN MGEN MGEN MGEN 9 2 1 *
+0xEFB0 MGEN MGEN MGEN MGEN 9 3 1 *
+0xEFC0 MGEN MGEN MGEN MGEN 9 4 1 *
+0xEFD0 MGEN MGEN MGEN MGEN 9 5 1 *
+0xEFE0 MGEN MGEN MGEN MGEN 9 1 1 *
+0xEFF0 MGEN MGEN MGEN MGEN 9 6 1 *
+0xF000 MSKA MSKA MSKA MSKA 9 2 1 *
+0xF010 MSKT MSKT MSKT MSKT 9 2 1 *
+0xF020 MWI4 MWI4 MWI4 MWI4 9 2 1 *
+0xF100 MYU1 MYU1 MYU1 MYU1 9 2 1 *
+0xF110 MYU2 MYU2 MYU2 MYU2 9 2 1 *
+0xF200 MLIZ MLIZ MLIZ MLIZ 9 2 1 *
+0xF210 MLI2 MLI2 MLI2 MLI2 9 2 1 *
+0xF300 MGFI MGFI MGFI MGFI 9 4 1 *
+0xF400 MSAH MSAH MSAH MSAH 9 2 1 *
+0xF410 MSAT MSAT MSAT MSAT 9 2 1 *
+0xF500 MDRM MDRM MDRM MDRM 9 4 1 *
+0xF510 MDRF MDRF MDRF MDRF 9 4 1 *
+0xF770 MBA1 MBA1 MBA1 MBA1 9 2 1 *
+0xF780 MBA2 MBA2 MBA2 MBA2 9 2 1 *
+0xF790 MBA3 MBA3 MBA3 MBA3 9 2 1 *
diff --git a/gemrb/override/how/avprefc.2da b/gemrb/unhardcoded/how/avprefc.2da
similarity index 100%
rename from gemrb/override/how/avprefc.2da
rename to gemrb/unhardcoded/how/avprefc.2da
diff --git a/gemrb/override/how/avprefr.2da b/gemrb/unhardcoded/how/avprefr.2da
similarity index 100%
rename from gemrb/override/how/avprefr.2da
rename to gemrb/unhardcoded/how/avprefr.2da
diff --git a/gemrb/override/how/axe.pro b/gemrb/unhardcoded/how/axe.pro
similarity index 100%
rename from gemrb/override/how/axe.pro
rename to gemrb/unhardcoded/how/axe.pro
diff --git a/gemrb/override/how/axeex.pro b/gemrb/unhardcoded/how/axeex.pro
similarity index 100%
rename from gemrb/override/how/axeex.pro
rename to gemrb/unhardcoded/how/axeex.pro
diff --git a/gemrb/override/how/bbarrh1.pro b/gemrb/unhardcoded/how/bbarrh1.pro
similarity index 100%
rename from gemrb/override/how/bbarrh1.pro
rename to gemrb/unhardcoded/how/bbarrh1.pro
diff --git a/gemrb/override/how/bbarrh2.pro b/gemrb/unhardcoded/how/bbarrh2.pro
similarity index 100%
rename from gemrb/override/how/bbarrh2.pro
rename to gemrb/unhardcoded/how/bbarrh2.pro
diff --git a/gemrb/override/how/bbarrier.pro b/gemrb/unhardcoded/how/bbarrier.pro
similarity index 100%
rename from gemrb/override/how/bbarrier.pro
rename to gemrb/unhardcoded/how/bbarrier.pro
diff --git a/gemrb/override/how/bdeath.pro b/gemrb/unhardcoded/how/bdeath.pro
similarity index 100%
rename from gemrb/override/how/bdeath.pro
rename to gemrb/unhardcoded/how/bdeath.pro
diff --git a/gemrb/override/how/blessh.pro b/gemrb/unhardcoded/how/blessh.pro
similarity index 100%
rename from gemrb/override/how/blessh.pro
rename to gemrb/unhardcoded/how/blessh.pro
diff --git a/gemrb/unhardcoded/how/bloodclr.2da b/gemrb/unhardcoded/how/bloodclr.2da
new file mode 100644
index 0000000..5d10be9
--- /dev/null
+++ b/gemrb/unhardcoded/how/bloodclr.2da
@@ -0,0 +1,29 @@
+2DA V1.0
+0
+ VALUE MIN MAX FLAGS
+NORMAL 0x2f 0x1000 0xffff 0
+PURPLE 0x2d 0x4300 0x43ff 0
+MSKEL 0x25 0x5403 0x5403 1
+DOOMG 0x22 0x5405 0x5406 1
+MSKEL 0x25 0x6403 0x6403 1
+DOOMG 0x22 0x6405 0x6406 1
+YELLOW 0x32 0x7300 0x73ff 0
+PURPLE 0x3c 0x7500 0x75ff 0
+YELLOW 0x32 0x7600 0x76ff 1
+BLACK 0x66 0x7700 0x77ff 1
+SLI_GR 7 0x7900 0x7900 1
+SLI_OL 0x24 0x7901 0x7901 1
+SLI_MU 0x33 0x7902 0x7902 1
+SLI_OC 0x25 0x7903 0x7903 1
+SLIME 0x1b 0x7904 0x7904 1
+SPIDER 0x33 0x7a00 0x7aff 1
+ZOMBIE 0x25 0x7c00 0x7cff 1
+MTRO 0x33 0x7f00 0x7f00 0
+MMIN 0x3d 0x7f01 0x7f03 0
+MIGO 0x1a 0x7f04 0x7f04 1
+MGLC 0x5d 0x7f07 0x7f07 0
+MTRS 0x32 0x7f0f 0x7f0f 0
+MBES 0x3d 0x7f15 0x7f15 0
+MCAR 0x38 0xa100 0xa1ff 0
+UNDEAD 0x66 0xe300 0xe3ff 1
+MWWE 0x38 0xef00 0xefff 1
diff --git a/gemrb/override/how/bolt.pro b/gemrb/unhardcoded/how/bolt.pro
similarity index 100%
rename from gemrb/override/how/bolt.pro
rename to gemrb/unhardcoded/how/bolt.pro
diff --git a/gemrb/override/how/boltex.pro b/gemrb/unhardcoded/how/boltex.pro
similarity index 100%
rename from gemrb/override/how/boltex.pro
rename to gemrb/unhardcoded/how/boltex.pro
diff --git a/gemrb/override/how/bscloud.pro b/gemrb/unhardcoded/how/bscloud.pro
similarity index 100%
rename from gemrb/override/how/bscloud.pro
rename to gemrb/unhardcoded/how/bscloud.pro
diff --git a/gemrb/override/how/bullet.pro b/gemrb/unhardcoded/how/bullet.pro
similarity index 100%
rename from gemrb/override/how/bullet.pro
rename to gemrb/unhardcoded/how/bullet.pro
diff --git a/gemrb/override/how/bulletex.pro b/gemrb/unhardcoded/how/bulletex.pro
similarity index 100%
rename from gemrb/override/how/bulletex.pro
rename to gemrb/unhardcoded/how/bulletex.pro
diff --git a/gemrb/override/how/calllih.pro b/gemrb/unhardcoded/how/calllih.pro
similarity index 100%
rename from gemrb/override/how/calllih.pro
rename to gemrb/unhardcoded/how/calllih.pro
diff --git a/gemrb/override/how/ccdamah.pro b/gemrb/unhardcoded/how/ccdamah.pro
similarity index 100%
rename from gemrb/override/how/ccdamah.pro
rename to gemrb/unhardcoded/how/ccdamah.pro
diff --git a/gemrb/override/how/ccommah.pro b/gemrb/unhardcoded/how/ccommah.pro
similarity index 100%
rename from gemrb/override/how/ccommah.pro
rename to gemrb/unhardcoded/how/ccommah.pro
diff --git a/gemrb/override/how/ccwounh.pro b/gemrb/unhardcoded/how/ccwounh.pro
similarity index 100%
rename from gemrb/override/how/ccwounh.pro
rename to gemrb/unhardcoded/how/ccwounh.pro
diff --git a/gemrb/override/how/cdiseah.pro b/gemrb/unhardcoded/how/cdiseah.pro
similarity index 100%
rename from gemrb/override/how/cdiseah.pro
rename to gemrb/unhardcoded/how/cdiseah.pro
diff --git a/gemrb/override/how/ceelem1.pro b/gemrb/unhardcoded/how/ceelem1.pro
similarity index 100%
rename from gemrb/override/how/ceelem1.pro
rename to gemrb/unhardcoded/how/ceelem1.pro
diff --git a/gemrb/override/how/ceelemh.pro b/gemrb/unhardcoded/how/ceelemh.pro
similarity index 100%
rename from gemrb/override/how/ceelemh.pro
rename to gemrb/unhardcoded/how/ceelemh.pro
diff --git a/gemrb/override/how/ceelemx.pro b/gemrb/unhardcoded/how/ceelemx.pro
similarity index 100%
rename from gemrb/override/how/ceelemx.pro
rename to gemrb/unhardcoded/how/ceelemx.pro
diff --git a/gemrb/override/how/cfelem1.pro b/gemrb/unhardcoded/how/cfelem1.pro
similarity index 100%
rename from gemrb/override/how/cfelem1.pro
rename to gemrb/unhardcoded/how/cfelem1.pro
diff --git a/gemrb/override/how/cfelemh.pro b/gemrb/unhardcoded/how/cfelemh.pro
similarity index 100%
rename from gemrb/override/how/cfelemh.pro
rename to gemrb/unhardcoded/how/cfelemh.pro
diff --git a/gemrb/override/how/cfelemx.pro b/gemrb/unhardcoded/how/cfelemx.pro
similarity index 100%
rename from gemrb/override/how/cfelemx.pro
rename to gemrb/unhardcoded/how/cfelemx.pro
diff --git a/gemrb/override/how/cfog.pro b/gemrb/unhardcoded/how/cfog.pro
similarity index 100%
rename from gemrb/override/how/cfog.pro
rename to gemrb/unhardcoded/how/cfog.pro
diff --git a/gemrb/override/how/cgraceh.pro b/gemrb/unhardcoded/how/cgraceh.pro
similarity index 100%
rename from gemrb/override/how/cgraceh.pro
rename to gemrb/unhardcoded/how/cgraceh.pro
diff --git a/gemrb/override/how/cgtable.2da b/gemrb/unhardcoded/how/cgtable.2da
similarity index 100%
rename from gemrb/override/how/cgtable.2da
rename to gemrb/unhardcoded/how/cgtable.2da
diff --git a/gemrb/override/how/chant.pro b/gemrb/unhardcoded/how/chant.pro
similarity index 100%
rename from gemrb/override/how/chant.pro
rename to gemrb/unhardcoded/how/chant.pro
diff --git a/gemrb/override/how/chromorb.pro b/gemrb/unhardcoded/how/chromorb.pro
similarity index 100%
rename from gemrb/override/how/chromorb.pro
rename to gemrb/unhardcoded/how/chromorb.pro
diff --git a/gemrb/override/how/classes.2da b/gemrb/unhardcoded/how/classes.2da
similarity index 100%
rename from gemrb/override/how/classes.2da
rename to gemrb/unhardcoded/how/classes.2da
diff --git a/gemrb/override/how/cldamah.pro b/gemrb/unhardcoded/how/cldamah.pro
similarity index 100%
rename from gemrb/override/how/cldamah.pro
rename to gemrb/unhardcoded/how/cldamah.pro
diff --git a/gemrb/override/how/cloud.pro b/gemrb/unhardcoded/how/cloud.pro
similarity index 100%
rename from gemrb/override/how/cloud.pro
rename to gemrb/unhardcoded/how/cloud.pro
diff --git a/gemrb/override/how/cloudb.pro b/gemrb/unhardcoded/how/cloudb.pro
similarity index 100%
rename from gemrb/override/how/cloudb.pro
rename to gemrb/unhardcoded/how/cloudb.pro
diff --git a/gemrb/override/how/cloudbh.pro b/gemrb/unhardcoded/how/cloudbh.pro
similarity index 100%
rename from gemrb/override/how/cloudbh.pro
rename to gemrb/unhardcoded/how/cloudbh.pro
diff --git a/gemrb/override/how/cloudkil.pro b/gemrb/unhardcoded/how/cloudkil.pro
similarity index 100%
rename from gemrb/override/how/cloudkil.pro
rename to gemrb/unhardcoded/how/cloudkil.pro
diff --git a/gemrb/override/how/cloudks.pro b/gemrb/unhardcoded/how/cloudks.pro
similarity index 100%
rename from gemrb/override/how/cloudks.pro
rename to gemrb/unhardcoded/how/cloudks.pro
diff --git a/gemrb/override/how/clowncol.2da b/gemrb/unhardcoded/how/clowncol.2da
similarity index 100%
rename from gemrb/override/how/clowncol.2da
rename to gemrb/unhardcoded/how/clowncol.2da
diff --git a/gemrb/unhardcoded/how/clskills.2da b/gemrb/unhardcoded/how/clskills.2da
new file mode 100644
index 0000000..0aa4d32
--- /dev/null
+++ b/gemrb/unhardcoded/how/clskills.2da
@@ -0,0 +1,22 @@
+2DA V1.0
+*
+ DRUIDSPELL CLERICSPELL MAGESPELL STARTXP BARDSKILL THIEFSKILL LAYHANDS TURNLEVEL BOOKTYPE HATERACE ABILITIES NO_PROF SAVEBONUS
+UNUSED * * * * * * * * 0 * * * 0
+MAGE * * MXSPLWIZ 0 * * * * 1 * * -4 0
+FIGHTER * * * 0 * * * * 0 * * -2 0
+CLERIC * MXSPLPRS * 0 * * * 1 1 * * -3 0
+THIEF * * * 0 * SKILLS * * 0 * * -3 0
+BARD * * MXSPLBRD 0 SKILLBRD * * * 1 * * -3 0
+PALADIN * MXSPLPAL * 0 * * PALADIN 5 1 * * -2 2
+FIGHTER_MAGE * * MXSPLWIZ 0 * * * * 1 * * -2 0
+FIGHTER_CLERIC * MXSPLPRS * 0 * * * * 1 * * -2 0
+FIGHTER_THIEF * * * 0 * SKILLS * * 0 * * -2 0
+FIGHTER_MAGE_THIEF * * MXSPLWIZ 0 * SKILLS * * 1 * * -2 0
+DRUID MXSPLDRU * * 0 * * * * 1 * * -3 0
+RANGER MXSPLRAN * * 0 * * * * 1 HATERACE * -2 0
+MAGE_THIEF * * MXSPLWIZ 0 * SKILLS * * 1 * * -3 0
+CLERIC_MAGE * MXSPLPRS MXSPLWIZ 0 * * * * 1 * * -3 0
+CLERIC_THIEF * MXSPLPRS * 0 * SKILLS * * 1 * * -3 0
+FIGHTER_DRUID MXSPLDRU * * 0 * * * * 1 * * -2 0
+FIGHTER_MAGE_CLERIC * MXSPLPRS MXSPLWIZ 0 * * * * 1 * * -2 0
+CLERIC_RANGER MXSPLRAN MXSPLPRS * 0 * * * * 1 HATERACE * -2 0
diff --git a/gemrb/override/how/clssplab.2da b/gemrb/unhardcoded/how/clssplab.2da
similarity index 100%
rename from gemrb/override/how/clssplab.2da
rename to gemrb/unhardcoded/how/clssplab.2da
diff --git a/gemrb/override/how/clwounh.pro b/gemrb/unhardcoded/how/clwounh.pro
similarity index 100%
rename from gemrb/override/how/clwounh.pro
rename to gemrb/unhardcoded/how/clwounh.pro
diff --git a/gemrb/override/how/cmdamah.pro b/gemrb/unhardcoded/how/cmdamah.pro
similarity index 100%
rename from gemrb/override/how/cmdamah.pro
rename to gemrb/unhardcoded/how/cmdamah.pro
diff --git a/gemrb/override/how/cmwounh.pro b/gemrb/unhardcoded/how/cmwounh.pro
similarity index 100%
rename from gemrb/override/how/cmwounh.pro
rename to gemrb/unhardcoded/how/cmwounh.pro
diff --git a/gemrb/override/how/cobones.pro b/gemrb/unhardcoded/how/cobones.pro
similarity index 100%
rename from gemrb/override/how/cobones.pro
rename to gemrb/unhardcoded/how/cobones.pro
diff --git a/gemrb/override/how/cobonh1.pro b/gemrb/unhardcoded/how/cobonh1.pro
similarity index 100%
rename from gemrb/override/how/cobonh1.pro
rename to gemrb/unhardcoded/how/cobonh1.pro
diff --git a/gemrb/override/how/cobonh2.pro b/gemrb/unhardcoded/how/cobonh2.pro
similarity index 100%
rename from gemrb/override/how/cobonh2.pro
rename to gemrb/unhardcoded/how/cobonh2.pro
diff --git a/gemrb/override/how/cocold.pro b/gemrb/unhardcoded/how/cocold.pro
similarity index 100%
rename from gemrb/override/how/cocold.pro
rename to gemrb/unhardcoded/how/cocold.pro
diff --git a/gemrb/override/how/cocoldh.pro b/gemrb/unhardcoded/how/cocoldh.pro
similarity index 100%
rename from gemrb/override/how/cocoldh.pro
rename to gemrb/unhardcoded/how/cocoldh.pro
diff --git a/gemrb/override/how/cofire.pro b/gemrb/unhardcoded/how/cofire.pro
similarity index 100%
rename from gemrb/override/how/cofire.pro
rename to gemrb/unhardcoded/how/cofire.pro
diff --git a/gemrb/override/how/coldh.pro b/gemrb/unhardcoded/how/coldh.pro
similarity index 100%
rename from gemrb/override/how/coldh.pro
rename to gemrb/unhardcoded/how/coldh.pro
diff --git a/gemrb/override/how/colrspry.pro b/gemrb/unhardcoded/how/colrspry.pro
similarity index 100%
rename from gemrb/override/how/colrspry.pro
rename to gemrb/unhardcoded/how/colrspry.pro
diff --git a/gemrb/override/how/confush.pro b/gemrb/unhardcoded/how/confush.pro
similarity index 100%
rename from gemrb/override/how/confush.pro
rename to gemrb/unhardcoded/how/confush.pro
diff --git a/gemrb/override/how/confusp.pro b/gemrb/unhardcoded/how/confusp.pro
similarity index 100%
rename from gemrb/override/how/confusp.pro
rename to gemrb/unhardcoded/how/confusp.pro
diff --git a/gemrb/override/how/confusw.pro b/gemrb/unhardcoded/how/confusw.pro
similarity index 100%
rename from gemrb/override/how/confusw.pro
rename to gemrb/unhardcoded/how/confusw.pro
diff --git a/gemrb/override/how/conjuh.pro b/gemrb/unhardcoded/how/conjuh.pro
similarity index 100%
rename from gemrb/override/how/conjuh.pro
rename to gemrb/unhardcoded/how/conjuh.pro
diff --git a/gemrb/override/how/conjut.pro b/gemrb/unhardcoded/how/conjut.pro
similarity index 100%
rename from gemrb/override/how/conjut.pro
rename to gemrb/unhardcoded/how/conjut.pro
diff --git a/gemrb/override/how/copest.pro b/gemrb/unhardcoded/how/copest.pro
similarity index 100%
rename from gemrb/override/how/copest.pro
rename to gemrb/unhardcoded/how/copest.pro
diff --git a/gemrb/override/how/cry150.pro b/gemrb/unhardcoded/how/cry150.pro
similarity index 100%
rename from gemrb/override/how/cry150.pro
rename to gemrb/unhardcoded/how/cry150.pro
diff --git a/gemrb/override/how/cry200.pro b/gemrb/unhardcoded/how/cry200.pro
similarity index 100%
rename from gemrb/override/how/cry200.pro
rename to gemrb/unhardcoded/how/cry200.pro
diff --git a/gemrb/override/how/cry225.pro b/gemrb/unhardcoded/how/cry225.pro
similarity index 100%
rename from gemrb/override/how/cry225.pro
rename to gemrb/unhardcoded/how/cry225.pro
diff --git a/gemrb/override/how/cry250.pro b/gemrb/unhardcoded/how/cry250.pro
similarity index 100%
rename from gemrb/override/how/cry250.pro
rename to gemrb/unhardcoded/how/cry250.pro
diff --git a/gemrb/override/how/cry500np.pro b/gemrb/unhardcoded/how/cry500np.pro
similarity index 100%
rename from gemrb/override/how/cry500np.pro
rename to gemrb/unhardcoded/how/cry500np.pro
diff --git a/gemrb/override/how/csdamah.pro b/gemrb/unhardcoded/how/csdamah.pro
similarity index 100%
rename from gemrb/override/how/csdamah.pro
rename to gemrb/unhardcoded/how/csdamah.pro
diff --git a/gemrb/override/how/cstrenh.pro b/gemrb/unhardcoded/how/cstrenh.pro
similarity index 100%
rename from gemrb/override/how/cstrenh.pro
rename to gemrb/unhardcoded/how/cstrenh.pro
diff --git a/gemrb/override/how/cswounh.pro b/gemrb/unhardcoded/how/cswounh.pro
similarity index 100%
rename from gemrb/override/how/cswounh.pro
rename to gemrb/unhardcoded/how/cswounh.pro
diff --git a/gemrb/override/how/curseh.pro b/gemrb/unhardcoded/how/curseh.pro
similarity index 100%
rename from gemrb/override/how/curseh.pro
rename to gemrb/unhardcoded/how/curseh.pro
diff --git a/gemrb/override/how/cwelem1.pro b/gemrb/unhardcoded/how/cwelem1.pro
similarity index 100%
rename from gemrb/override/how/cwelem1.pro
rename to gemrb/unhardcoded/how/cwelem1.pro
diff --git a/gemrb/override/how/cwelemh.pro b/gemrb/unhardcoded/how/cwelemh.pro
similarity index 100%
rename from gemrb/override/how/cwelemh.pro
rename to gemrb/unhardcoded/how/cwelemh.pro
diff --git a/gemrb/override/how/cwelemx.pro b/gemrb/unhardcoded/how/cwelemx.pro
similarity index 100%
rename from gemrb/override/how/cwelemx.pro
rename to gemrb/unhardcoded/how/cwelemx.pro
diff --git a/gemrb/override/how/cynicism.2da b/gemrb/unhardcoded/how/cynicism.2da
similarity index 100%
rename from gemrb/override/how/cynicism.2da
rename to gemrb/unhardcoded/how/cynicism.2da
diff --git a/gemrb/override/how/dagger.pro b/gemrb/unhardcoded/how/dagger.pro
similarity index 100%
rename from gemrb/override/how/dagger.pro
rename to gemrb/unhardcoded/how/dagger.pro
diff --git a/gemrb/override/how/daggerex.pro b/gemrb/unhardcoded/how/daggerex.pro
similarity index 100%
rename from gemrb/override/how/daggerex.pro
rename to gemrb/unhardcoded/how/daggerex.pro
diff --git a/gemrb/override/how/damage.2da b/gemrb/unhardcoded/how/damage.2da
similarity index 100%
rename from gemrb/override/how/damage.2da
rename to gemrb/unhardcoded/how/damage.2da
diff --git a/gemrb/override/how/dart.pro b/gemrb/unhardcoded/how/dart.pro
similarity index 100%
rename from gemrb/override/how/dart.pro
rename to gemrb/unhardcoded/how/dart.pro
diff --git a/gemrb/override/how/dartex.pro b/gemrb/unhardcoded/how/dartex.pro
similarity index 100%
rename from gemrb/override/how/dartex.pro
rename to gemrb/unhardcoded/how/dartex.pro
diff --git a/gemrb/override/how/dbreath.pro b/gemrb/unhardcoded/how/dbreath.pro
similarity index 100%
rename from gemrb/override/how/dbreath.pro
rename to gemrb/unhardcoded/how/dbreath.pro
diff --git a/gemrb/override/how/ddeath.pro b/gemrb/unhardcoded/how/ddeath.pro
similarity index 100%
rename from gemrb/override/how/ddeath.pro
rename to gemrb/unhardcoded/how/ddeath.pro
diff --git a/gemrb/override/how/ddeath2.pro b/gemrb/unhardcoded/how/ddeath2.pro
similarity index 100%
rename from gemrb/override/how/ddeath2.pro
rename to gemrb/unhardcoded/how/ddeath2.pro
diff --git a/gemrb/override/how/ddoorh.pro b/gemrb/unhardcoded/how/ddoorh.pro
similarity index 100%
rename from gemrb/override/how/ddoorh.pro
rename to gemrb/unhardcoded/how/ddoorh.pro
diff --git a/gemrb/unhardcoded/how/defsound.2da b/gemrb/unhardcoded/how/defsound.2da
new file mode 100644
index 0000000..3684027
--- /dev/null
+++ b/gemrb/unhardcoded/how/defsound.2da
@@ -0,0 +1,36 @@
+2DA V1.0
+*
+ RESREF
+OPEN AMB_D03A
+CLOSE AMB_D03B
+HOPEN AMB_D04A
+HCLOSE AMB_D04B
+BUTTON1 GAM_09
+BUTTON2 GAM_03
+BUTTON3 GAM_04
+OPENFAIL AMB_D20
+CLOSEFAIL *
+ITEM_GONE EFF_M02
+SECRET ACT_09
+PICKLOCK AMB_D21D
+PICKFAIL AMB_D21
+13 *
+14 *
+15 *
+16 *
+17 *
+18 *
+19 *
+LIGHTNING1 AMB_E13A
+LIGHTNING2 AMB_E13B
+LIGHTNING3 AMB_E13F
+RAIN AMB_E11
+SNOW AMB_E02B
+SOLD ACT_03D
+STOLEN GAM_36
+DRUNK GAM_07
+DONATE1 ACT_03
+DONATE2 ACT_03E
+IDENTIFY CAS_P04
+GOTXP *
+TOOLTIP G_PAPR1
diff --git a/gemrb/override/how/destruh.pro b/gemrb/unhardcoded/how/destruh.pro
similarity index 100%
rename from gemrb/override/how/destruh.pro
rename to gemrb/unhardcoded/how/destruh.pro
diff --git a/gemrb/override/how/dfog.pro b/gemrb/unhardcoded/how/dfog.pro
similarity index 100%
rename from gemrb/override/how/dfog.pro
rename to gemrb/unhardcoded/how/dfog.pro
diff --git a/gemrb/unhardcoded/how/difflvls.2da b/gemrb/unhardcoded/how/difflvls.2da
new file mode 100644
index 0000000..9e8413f
--- /dev/null
+++ b/gemrb/unhardcoded/how/difflvls.2da
@@ -0,0 +1,5 @@
+2DA V1.0
+0
+ DEFAULT EASY NORMAL CORE HARD NIGHTMARE
+DMG 0 -50 -25 0 50 100
+XP 0 0 0 0 50 100
diff --git a/gemrb/override/how/disint.pro b/gemrb/unhardcoded/how/disint.pro
similarity index 100%
rename from gemrb/override/how/disint.pro
rename to gemrb/unhardcoded/how/disint.pro
diff --git a/gemrb/override/how/disinth.pro b/gemrb/unhardcoded/how/disinth.pro
similarity index 100%
rename from gemrb/override/how/disinth.pro
rename to gemrb/unhardcoded/how/disinth.pro
diff --git a/gemrb/override/how/dispel.pro b/gemrb/unhardcoded/how/dispel.pro
similarity index 100%
rename from gemrb/override/how/dispel.pro
rename to gemrb/unhardcoded/how/dispel.pro
diff --git a/gemrb/override/how/divinh.pro b/gemrb/unhardcoded/how/divinh.pro
similarity index 100%
rename from gemrb/override/how/divinh.pro
rename to gemrb/unhardcoded/how/divinh.pro
diff --git a/gemrb/override/how/divint.pro b/gemrb/unhardcoded/how/divint.pro
similarity index 100%
rename from gemrb/override/how/divint.pro
rename to gemrb/unhardcoded/how/divint.pro
diff --git a/gemrb/unhardcoded/how/dsclass.2da b/gemrb/unhardcoded/how/dsclass.2da
new file mode 100644
index 0000000..1d498b7
--- /dev/null
+++ b/gemrb/unhardcoded/how/dsclass.2da
@@ -0,0 +1,24 @@
+2DA V1.0
+0
+ CLASS BONUS
+MAGE 1 5
+FIGHTER 2 10
+CLERIC 3 10
+THIEF 4 15
+BARD 5 15
+PALADIN 6 10
+FM 7 10
+FC 8 10
+FT 9 15
+FMT 10 15
+DRUID 11 10
+RANGER 12 10
+MT 13 15
+CM 14 10
+CT 15 15
+FD 16 10
+FMC 17 10
+CR 18 10
+SORC 19 5
+MONK 20 15
+
diff --git a/gemrb/override/how/dspell.pro b/gemrb/unhardcoded/how/dspell.pro
similarity index 100%
rename from gemrb/override/how/dspell.pro
rename to gemrb/unhardcoded/how/dspell.pro
diff --git a/gemrb/override/how/dspellh.pro b/gemrb/unhardcoded/how/dspellh.pro
similarity index 100%
rename from gemrb/override/how/dspellh.pro
rename to gemrb/unhardcoded/how/dspellh.pro
diff --git a/gemrb/unhardcoded/how/dsrace.2da b/gemrb/unhardcoded/how/dsrace.2da
new file mode 100644
index 0000000..5fb3c47
--- /dev/null
+++ b/gemrb/unhardcoded/how/dsrace.2da
@@ -0,0 +1,7 @@
+2DA V1.0
+0
+ RACE BONUS
+ELF 2 20
+DWARF 4 10
+HALFLING 5 5
+
diff --git a/gemrb/unhardcoded/how/dstable.2da b/gemrb/unhardcoded/how/dstable.2da
new file mode 100644
index 0000000..b2d0df7
--- /dev/null
+++ b/gemrb/unhardcoded/how/dstable.2da
@@ -0,0 +1,6 @@
+2DA V1.0
+*
+FILE STAT
+dsclass CLASS
+dsrace RACE
+
diff --git a/gemrb/override/how/dualclas.2da b/gemrb/unhardcoded/how/dualclas.2da
similarity index 100%
rename from gemrb/override/how/dualclas.2da
rename to gemrb/unhardcoded/how/dualclas.2da
diff --git a/gemrb/unhardcoded/how/effects.ids b/gemrb/unhardcoded/how/effects.ids
new file mode 100644
index 0000000..7e0c04a
--- /dev/null
+++ b/gemrb/unhardcoded/how/effects.ids
@@ -0,0 +1,301 @@
+IDS
+0x0 ACVsDamageTypeModifier
+0x1 AttacksPerRoundModifier
+0x2 Cure:Sleep
+0x3 State:Berserk
+0x4 Cure:Berserk
+0x5 State:Charmed
+0x6 CharismaModifier
+0x7 Color:SetPalette
+0x8 Color:SetRGB
+0x9 Color:PulseRGB
+0xa ConstitutionModifier
+0xb Cure:Poison
+0xc Damage
+0xd Death
+0xe Cure:Defrost
+0xf DexterityModifier
+0x10 State:Hasted
+0x11 CurrentHPModifier
+0x12 MaximumHPModifier
+0x13 IntelligenceModifier
+0x14 State:Invisible
+0x15 LoreModifier
+0x16 LuckModifier
+0x17 MoraleModifier
+0x18 State:Panic
+0x19 State:Poisoned
+0x1a RemoveCurse
+0x1b AcidResistanceModifier
+0x1c ColdResistanceModifier
+0x1d ElectricityResistanceModifier
+0x1e FireResistanceModifier
+0x1f MagicDamageResistanceModifier
+0x20 Cure:Death
+0x21 SaveVsDeathModifier
+0x22 SaveVsWandsModifier
+0x23 SaveVsPolyModifier
+0x24 SaveVsBreathModifier
+0x25 SaveVsSpellsModifier
+0x26 State:Silenced
+0x27 State:Helpless
+0x28 State:Slowed
+0x29 Sparkle
+0x2a WizardSpellSlotsModifier
+0x2b Cure:Petrification
+0x2c StrengthModifier
+0x2d State:Stun
+0x2e Cure:Stun
+0x2f Cure:Invisible
+0x30 Cure:Silence
+0x31 WisdomModifier
+0x32 Color:BriefRGB
+0x33 Color:DarkenRGB
+0x34 Color:GlowRGB
+0x35 AnimationIDModifier
+0x36 ToHitModifier
+0x37 KillCreatureType
+0x38 Alignment:Invert
+0x39 Alignment:Change
+0x3a DispelEffects
+0x3b StealthModifier
+0x3c MiscastMagicModifier
+0x3d AlchemyModifier
+0x3e PriestSpellSlotsModifier
+0x3f State:Infravision
+0x40 Cure:Infravision
+0x41 State:Blur
+0x42 TransparencyModifier
+0x43 SummonCreature
+0x44 UnsummonCreature
+0x45 State:NonDetection
+0x46 Cure:NonDetection
+0x47 SexModifier
+0x48 AIIdentifierModifier
+0x49 DamageBonusModifier2
+0x4a State:Blind
+0x4b Cure:Blind
+0x4c State:Feeblemind
+0x4d Cure:Feeblemind
+0x4e State:Diseased
+0x4f Cure:Disease
+0x50 State:Deafness
+0x51 Cure:Deafness
+0x52 SetAIScript
+0x53 Protection:Projectile
+0x54 MagicalFireResistanceModifier
+0x55 MagicalColdResistanceModifier
+0x56 SlashingResistanceModifier
+0x57 CrushingResistanceModifier
+0x58 PiercingResistanceModifier
+0x59 MissilesResistanceModifier
+0x5a OpenLocksModifier
+0x5b FindTrapsModifier
+0x5c PickPocketsModifier
+0x5d FatigueModifier
+0x5e IntoxicationModifier
+0x5f TrackingModifier
+0x60 LevelModifier
+0x61 StrengthBonusModifier
+0x62 State:Regenerating
+0x63 SpellDurationModifier
+0x64 Protection:Creature
+0x65 Protection:Opcode
+0x66 Protection:SpellLevel
+0x67 ChangeName
+0x68 ExperienceModifier
+0x69 GoldModifier
+0x6a MoraleBreakModifier
+0x6b PortraitChange
+0x6c ReputationModifier
+0x6d State:Hold3
+0x6e RetreatFrom
+0x6f Item:CreateMagic
+0x70 Item:Remove
+0x71 Item:Equip
+0x72 Dither
+0x73 DetectAlignment
+0x74 Cure:Invisible2
+0x75 Reveal:Area
+0x76 Reveal:Creatures
+0x77 MirrorImage
+0x78 Protection:Weapons
+0x79 VisualAnimationEffect
+0x7a Item:CreateInventory
+0x7b Item:RemoveInventory
+0x7c DimensionDoor
+0x7d Unlock
+0x7e MovementRateModifier
+0x7f MonsterSummoning
+0x80 State:Confused
+0x81 AidNonCumulative
+0x82 BlessNonCumulative
+0x83 ChantNonCumulative
+0x84 HolyNonCumulative
+0x85 LuckNonCumulative
+0x86 State:Petrification
+0x87 Polymorph
+0x88 ForceVisible
+0x89 ChantBadNonCumulative
+0x8a AnimationStateChange
+0x8b DisplayString
+0x8c CastingGlow
+0x8d VisualSpellHit
+0x8e Icon:Display
+0x8f Item:CreateInSlot
+0x90 DisableButton
+0x91 DisableCasting
+0x92 Spell:Cast
+0x93 Spell:Learn
+0x94 Spell:CastPoint
+0x95 Identify
+0x96 FindTraps
+0x97 ReplaceCreature
+0x98 PlayMovie
+0x99 Overlay:Sanctuary
+0x9a Overlay:Entangle
+0x9b Overlay:MinorGlobe
+0x9c Overlay:ShieldGlobe
+0x9d Overlay:Web
+0x9e Overlay:Grease
+0x9f MirrorImageModifier
+0xa0 Cure:Sanctuary
+0xa1 Cure:Panic
+0xa2 Cure:Hold
+0xa3 FreeAction
+0xa4 Cure:Intoxication
+0xa5 PauseTarget
+0xa6 MagicResistanceModifier
+0xa7 MissileHitModifier
+0xa8 RemoveCreature
+0xa9 Icon:Disable
+0xaa DamageAnimation
+0xab Spell:Add
+0xac Spell:Remove
+0xad PoisonResistanceModifier
+0xae PlaySound
+0xaf State:Hold
+0xb0 MovementRateModifier2
+0xb1 ApplyEffect
+0xb2 ToHitVsCreature
+0xb3 DamageVsCreature
+0xb4 CantUseItem
+0xb5 CantUseItemType
+0xb6 ApplyEffectItem
+0xb7 ApplyEffectItemType
+0xb8 DontJumpModifier
+0xb9 State:Hold2
+0xba MoveToArea
+0xbb Variable:StoreLocalVariable
+0xbc AuraCleansingModifier
+0xbd CastingSpeedModifier
+0xbe AttackSpeedModifier
+0xbf CastingLevelModifier
+0xc0 FindFamiliar
+0xc1 InvisibleDetection
+0xc2 IgnoreDialogPause
+0xc3 FamiliarBond
+0xc4 FamiliarMarker
+0xc5 Bounce:Projectile
+0xc6 Bounce:Opcode
+0xc7 Bounce:SpellLevel
+0xc8 Bounce:SpellLevelDec
+0xc9 Protection:SpellLevelDec
+0xca Bounce:School
+0xcb Bounce:SecondaryType
+0xcc Protection:School
+0xcd Protection:SecondaryType
+0xce Protection:Spell2
+0xcf Bounce:Spell
+0xd0 MinimumHPModifier
+0xd1 PowerWordKill
+0xd2 PowerWordStun
+0xd3 State:Imprisonment
+0xd4 Cure:Imprisonment
+0xd5 Maze
+0xd6 CastFromList
+0xd7 PlayVisualEffect
+0xd8 LevelDrainModifier
+0xd9 PowerWordSleep
+0xda StoneskinModifier
+0xdb ACVsCreatureType
+0xdc DispelSchool
+0xdd DispelSecondaryType
+0xde RandomTeleport
+0xdf Protection:SchoolDec
+0xe0 Cure:LevelDrain
+0xe1 Reveal:Magic
+0xe2 Protection:SecondaryTypeDec
+0xe3 Bounce:SchoolDec
+0xe4 Bounce:SecondaryTypeDec
+0xe5 DispelSchoolOne
+0xe6 DispelSecondaryTypeOne
+0xe7 TimeStop
+0xe8 Color:FadeRGB
+0xe9 IWDVisualSpellHit
+0xea ColdDamage
+0xeb CastingGlow2
+0xec ChillTouch
+0xed CrushingDamage
+0xee SaveBonus
+0xef SlowPoison
+0xf0 IWDMonsterSummoning
+0xf1 VampiricTouch
+0xf2 Overlay
+0xf3 AnimateDead
+0xf4 Prayer2
+0xf5 Curse2
+0xf6 SummonMonster2
+0xf7 BurningBlood
+0xf8 SummonShadowMonster
+0xf9 Recitation
+0xfa RecitationBad
+0xfb Hold2
+0xfc BlindingOrb
+0xfd ACVsDamageTypeModifier2
+0xfe RemoveEffects
+0xff SalamanderAura
+0x100 UmberHulkGaze
+0x101 ZombieLordAura
+0x102 Protection:Spell
+0x103 SummonCreature2
+0x104 AvatarRemoval
+0x105 Protection:Opcode2
+0x106 SummonPomab
+0x107 ControlUndead
+0x108 StaticCharge
+0x109 CloakOfFear
+0x10a MovementRateModifier3
+0x10b Cure:Confusion
+0x10c EyeOfTheMind
+0x10d EyeOfTheSword
+0x10e EyeOfTheMage
+0x10f EyeOfVenom
+0x110 EyeOfTheSpirit
+0x111 EyeOfFortitude
+0x112 EyeOfStone
+0x113 RemoveSevenEyes
+0x114 RemoveEffect
+0x115 SoulEater
+0x116 ShroudOfFlame
+0x117 AnimalRage
+0x118 TurnUndead
+0x119 VitriolicSphere
+0x11a SuppressHP
+0x11b FloatText
+0x11c MaceOfDisruption
+0x11d State:Sleep
+0x11e Reveal:Tracks
+0x11f Protection:Backstab
+0x120 State:Set
+0x121 Cutscene
+0x122 Protection:Spell3
+0x123 RodOfSmithing
+0x124 MagicalRest
+0x125 BeholderDispelMagic
+0x126 HarpyWail
+0x127 JackalWereGaze
+0x128 ModifyGlobalVariable
+0x129 HideInShadowsModifier
+0x12a UseMagicDeviceModifier
+399 AlterAnimation
diff --git a/gemrb/override/how/electrh.pro b/gemrb/unhardcoded/how/electrh.pro
similarity index 100%
rename from gemrb/override/how/electrh.pro
rename to gemrb/unhardcoded/how/electrh.pro
diff --git a/gemrb/override/how/emotion.pro b/gemrb/unhardcoded/how/emotion.pro
similarity index 100%
rename from gemrb/override/how/emotion.pro
rename to gemrb/unhardcoded/how/emotion.pro
diff --git a/gemrb/override/how/enchah.pro b/gemrb/unhardcoded/how/enchah.pro
similarity index 100%
rename from gemrb/override/how/enchah.pro
rename to gemrb/unhardcoded/how/enchah.pro
diff --git a/gemrb/override/how/enchannp.pro b/gemrb/unhardcoded/how/enchannp.pro
similarity index 100%
rename from gemrb/override/how/enchannp.pro
rename to gemrb/unhardcoded/how/enchannp.pro
diff --git a/gemrb/override/how/enchat.pro b/gemrb/unhardcoded/how/enchat.pro
similarity index 100%
rename from gemrb/override/how/enchat.pro
rename to gemrb/unhardcoded/how/enchat.pro
diff --git a/gemrb/override/how/entangle.pro b/gemrb/unhardcoded/how/entangle.pro
similarity index 100%
rename from gemrb/override/how/entangle.pro
rename to gemrb/unhardcoded/how/entangle.pro
diff --git a/gemrb/override/how/equake.pro b/gemrb/unhardcoded/how/equake.pro
similarity index 100%
rename from gemrb/override/how/equake.pro
rename to gemrb/unhardcoded/how/equake.pro
diff --git a/gemrb/override/how/exaltah.pro b/gemrb/unhardcoded/how/exaltah.pro
similarity index 100%
rename from gemrb/override/how/exaltah.pro
rename to gemrb/unhardcoded/how/exaltah.pro
diff --git a/gemrb/override/how/factioh.pro b/gemrb/unhardcoded/how/factioh.pro
similarity index 100%
rename from gemrb/override/how/factioh.pro
rename to gemrb/unhardcoded/how/factioh.pro
diff --git a/gemrb/override/how/findtrap.pro b/gemrb/unhardcoded/how/findtrap.pro
similarity index 100%
rename from gemrb/override/how/findtrap.pro
rename to gemrb/unhardcoded/how/findtrap.pro
diff --git a/gemrb/override/how/fireball.pro b/gemrb/unhardcoded/how/fireball.pro
similarity index 100%
rename from gemrb/override/how/fireball.pro
rename to gemrb/unhardcoded/how/fireball.pro
diff --git a/gemrb/override/how/fireblic.pro b/gemrb/unhardcoded/how/fireblic.pro
similarity index 100%
rename from gemrb/override/how/fireblic.pro
rename to gemrb/unhardcoded/how/fireblic.pro
diff --git a/gemrb/override/how/firebolt.pro b/gemrb/unhardcoded/how/firebolt.pro
similarity index 100%
rename from gemrb/override/how/firebolt.pro
rename to gemrb/unhardcoded/how/firebolt.pro
diff --git a/gemrb/override/how/firebtbl.pro b/gemrb/unhardcoded/how/firebtbl.pro
similarity index 100%
rename from gemrb/override/how/firebtbl.pro
rename to gemrb/unhardcoded/how/firebtbl.pro
diff --git a/gemrb/override/how/fireh.pro b/gemrb/unhardcoded/how/fireh.pro
similarity index 100%
rename from gemrb/override/how/fireh.pro
rename to gemrb/unhardcoded/how/fireh.pro
diff --git a/gemrb/override/how/firestor.pro b/gemrb/unhardcoded/how/firestor.pro
similarity index 100%
rename from gemrb/override/how/firestor.pro
rename to gemrb/unhardcoded/how/firestor.pro
diff --git a/gemrb/override/how/fistweap.2da b/gemrb/unhardcoded/how/fistweap.2da
similarity index 100%
rename from gemrb/override/how/fistweap.2da
rename to gemrb/unhardcoded/how/fistweap.2da
diff --git a/gemrb/override/how/fodeath.pro b/gemrb/unhardcoded/how/fodeath.pro
similarity index 100%
rename from gemrb/override/how/fodeath.pro
rename to gemrb/unhardcoded/how/fodeath.pro
diff --git a/gemrb/unhardcoded/how/fonts.2da b/gemrb/unhardcoded/how/fonts.2da
new file mode 100644
index 0000000..e7afbbb
--- /dev/null
+++ b/gemrb/unhardcoded/how/fonts.2da
@@ -0,0 +1,22 @@
+2DA V1.0
+NORMAL
+ RESREF NEED_PALETTE FONT_NAME PT_SIZE STYLE COLOR
+0 NORMAL 1 NORMAL 14 0 0xffffffff
+1 INFOFONT 1 INFOFONT 14 0 0xffffffff
+2 NUMBER 0 NUMBER 14 0 0xffffffff
+3 INITIALS 0 INITIALS 14 0 0xffffffff
+4 NUMBER2 0 NUMBER2 14 0 0xffffffff
+5 NUMBER3 0 NUMBER3 14 0 0xffffffff
+6 NUMFONT 1 NUMFONT 14 0 0xffffffff
+7 REALMS 0 REALMS 14 0 0xffffffff
+8 REALMS2 1 REALMS2 14 0 0xffffffff
+9 STONEBIG 0 STONEBIG 14 0 0xffffffff
+10 STONESM2 0 STONESM2 14 0 0xffffffff
+11 STONESM3 0 STONESM3 14 0 0xffffffff
+12 STONESML 0 STONESML 14 0 0xffffffff
+13 TOOLFONT 1 TOOLFONT 14 0 0xffffffff
+# state "fonts" are the status icons. You probably don't want to edit these.
+14 STATES 0 STATES 14 0 0xffffffff
+15 STATES2 0 STATES2 14 0 0xffffffff
+
+# Customization How To: http://gemrb.sourceforge.net/wiki/doku.php?id=plugins:ttf
diff --git a/gemrb/override/how/formatio.2da b/gemrb/unhardcoded/how/formatio.2da
similarity index 100%
rename from gemrb/override/how/formatio.2da
rename to gemrb/unhardcoded/how/formatio.2da
diff --git a/gemrb/override/how/fseed.pro b/gemrb/unhardcoded/how/fseed.pro
similarity index 100%
rename from gemrb/override/how/fseed.pro
rename to gemrb/unhardcoded/how/fseed.pro
diff --git a/gemrb/override/how/fstrikh.pro b/gemrb/unhardcoded/how/fstrikh.pro
similarity index 100%
rename from gemrb/override/how/fstrikh.pro
rename to gemrb/unhardcoded/how/fstrikh.pro
diff --git a/gemrb/unhardcoded/how/gametime.2da b/gemrb/unhardcoded/how/gametime.2da
new file mode 100644
index 0000000..ba22bbe
--- /dev/null
+++ b/gemrb/unhardcoded/how/gametime.2da
@@ -0,0 +1,6 @@
+2DA V1.0
+0
+ DURATION
+ROUND_SECONDS 7
+TURN_SECONDS 70
+ATTACK_ROUND 100
diff --git a/gemrb/override/how/garmorh.pro b/gemrb/unhardcoded/how/garmorh.pro
similarity index 100%
rename from gemrb/override/how/garmorh.pro
rename to gemrb/unhardcoded/how/garmorh.pro
diff --git a/gemrb/override/how/gaze.pro b/gemrb/unhardcoded/how/gaze.pro
similarity index 100%
rename from gemrb/override/how/gaze.pro
rename to gemrb/unhardcoded/how/gaze.pro
diff --git a/gemrb/override/how/gemprjtl.ids b/gemrb/unhardcoded/how/gemprjtl.ids
similarity index 100%
rename from gemrb/override/how/gemprjtl.ids
rename to gemrb/unhardcoded/how/gemprjtl.ids
diff --git a/gemrb/unhardcoded/how/gemrb.ini b/gemrb/unhardcoded/how/gemrb.ini
new file mode 100644
index 0000000..7cf7aaf
--- /dev/null
+++ b/gemrb/unhardcoded/how/gemrb.ini
@@ -0,0 +1,133 @@
+; GemRB - Infinity Engine Emulator
+; Copyright (C) 2003 The GemRB Project
+;
+; This program is free software; you can redistribute it and/or
+; modify it under the terms of the GNU General Public License
+; as published by the Free Software Foundation; either version 2
+; of the License, or (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program; if not, write to the Free Software
+; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+;
+
+
+; gemrb.ini - game type-specific settings for GemRB engine
+
+[resources]
+
+; Bitmap resource for cursors
+CursorBAM = CAROT
+
+; Bitmap resource for scroll cursor arrow
+ScrollCursorBAM = CURSARW
+
+; Bitmap resource for dialog buttons font
+ButtonFont = STONESML
+
+; Font used to display tooltips
+TooltipFont = TOOLFONT
+
+; Font used to display subtitles
+MovieFont = NORMAL
+
+; Sprite displayed behind the tooltip text, if any
+TooltipBack = TOOLTIP
+
+; Tooltip text color (RGBA)
+TooltipColor = #ffffffff
+
+; Space between tooltip text and sides of TooltipBack (x2)
+TooltipMargin = 2
+
+; INI file from the original games
+INIConfig = icewind.ini
+
+; Palette bitmaps in various widths
+Palette16 = MPALETTE
+Palette32 = MPALETTE
+Palette256 = MPAL256
+
+3EdRules = 0
+AllStringsTagged = 1
+AreaVisitedVar = 1
+AreaOverride = 0
+AutomapINI = 0
+AutoSearchHidden = 1
+BiographyIsRes = 1
+BreakableWeapons = 0
+CastingSounds = 1
+ChallengeRating = 0
+CharNameIsGabber = 1
+CheckAbilities = 0
+ClearUnusedArea = 0
+CutsceneAreascripts = 0
+DeathOnZeroStat = 0
+DialogueScrolls = 0
+EnhancedCastingSounds = 0
+EnhancedEffects = 0
+FistStat = 232
+FlexibleWorldmap = 1
+ForceAreaScript = 1
+ForceStereo = 0
+HasBeastsINI = 0
+HasDescIcon = 0
+HasDPLAYER = 1
+HasEXPTABLE = 1
+HasFloatMenu = 0
+HasHideInShadows = 1
+HasKaputz = 0
+HasNoNPCFlag = 0
+HasPartyINI = 0
+HasPickSound = 0
+HasResDataIni = 0
+HasSongList = 0
+HasSoundsIni = 1
+HasSpecificDamageBonus = 1
+HasSpellList = 0
+HasUsePointFlag = 0
+HasWisdomBonusTable = 0
+HealOn100Plus = 1
+IgnoreButtonFrames = 0
+ImplicitAreaAnimBackground = 1
+InPartyAllowsDead = 1
+IWD2DeathVarFormat = 0
+IWD2ScriptName = 1
+IWDMapDimensions = 1
+JournalHasSections = 0
+KnowWorld = 0
+LevelslotPerClass = 0
+LowerLabelText = 0
+MagicBit = 1
+MaximumAbility = 25
+NoDropCanMove = 0
+NoNewVariables = 0
+OneByteAnimationID = 0
+OnScreenText = 0
+NoUndroppable = 1
+OverrideCursorPos = 0
+ProperBackstab = 0
+ProtagonistTalks = 0
+PSTStateFlags = 0
+RareActionSounds = 0
+RedrawTile = 0
+ReverseDoor = 0
+ReverseToHit = 1
+SaveForHalfDamage = 0
+SelectiveMagicRes = 1
+SkipUpdateHack = 1
+SmallFog = 0
+SoundFolders = 1
+SpawnIni = 1
+SpellBookIconHack = 0
+StartActive = 0
+StealIsAttack = 0
+StrrefSaveGame = 0
+TeamMovement = 0
+UpperButtonText = 0
+ZeroTimerIsValid = 1
diff --git a/gemrb/override/how/gender.2da b/gemrb/unhardcoded/how/gender.2da
similarity index 100%
rename from gemrb/override/how/gender.2da
rename to gemrb/unhardcoded/how/gender.2da
diff --git a/gemrb/override/how/golcloud.pro b/gemrb/unhardcoded/how/golcloud.pro
similarity index 100%
rename from gemrb/override/how/golcloud.pro
rename to gemrb/unhardcoded/how/golcloud.pro
diff --git a/gemrb/override/how/grease.pro b/gemrb/unhardcoded/how/grease.pro
similarity index 100%
rename from gemrb/override/how/grease.pro
rename to gemrb/unhardcoded/how/grease.pro
diff --git a/gemrb/override/how/gshout.pro b/gemrb/unhardcoded/how/gshout.pro
similarity index 100%
rename from gemrb/override/how/gshout.pro
rename to gemrb/unhardcoded/how/gshout.pro
diff --git a/gemrb/override/how/guibtact.2da b/gemrb/unhardcoded/how/guibtact.2da
similarity index 100%
rename from gemrb/override/how/guibtact.2da
rename to gemrb/unhardcoded/how/guibtact.2da
diff --git a/gemrb/override/how/guils.chu b/gemrb/unhardcoded/how/guils.chu
similarity index 100%
rename from gemrb/override/how/guils.chu
rename to gemrb/unhardcoded/how/guils.chu
diff --git a/gemrb/override/how/harmh.pro b/gemrb/unhardcoded/how/harmh.pro
similarity index 100%
rename from gemrb/override/how/harmh.pro
rename to gemrb/unhardcoded/how/harmh.pro
diff --git a/gemrb/override/how/harmony.pro b/gemrb/unhardcoded/how/harmony.pro
similarity index 100%
rename from gemrb/override/how/harmony.pro
rename to gemrb/unhardcoded/how/harmony.pro
diff --git a/gemrb/override/how/haterace.2da b/gemrb/unhardcoded/how/haterace.2da
similarity index 100%
rename from gemrb/override/how/haterace.2da
rename to gemrb/unhardcoded/how/haterace.2da
diff --git a/gemrb/override/how/healh.pro b/gemrb/unhardcoded/how/healh.pro
similarity index 100%
rename from gemrb/override/how/healh.pro
rename to gemrb/unhardcoded/how/healh.pro
diff --git a/gemrb/override/how/hmighth.pro b/gemrb/unhardcoded/how/hmighth.pro
similarity index 100%
rename from gemrb/override/how/hmighth.pro
rename to gemrb/unhardcoded/how/hmighth.pro
diff --git a/gemrb/override/how/hold.pro b/gemrb/unhardcoded/how/hold.pro
similarity index 100%
rename from gemrb/override/how/hold.pro
rename to gemrb/unhardcoded/how/hold.pro
diff --git a/gemrb/override/how/hsmite.pro b/gemrb/unhardcoded/how/hsmite.pro
similarity index 100%
rename from gemrb/override/how/hsmite.pro
rename to gemrb/unhardcoded/how/hsmite.pro
diff --git a/gemrb/override/how/hword.pro b/gemrb/unhardcoded/how/hword.pro
similarity index 100%
rename from gemrb/override/how/hword.pro
rename to gemrb/unhardcoded/how/hword.pro
diff --git a/gemrb/override/how/icelance.pro b/gemrb/unhardcoded/how/icelance.pro
similarity index 100%
rename from gemrb/override/how/icelance.pro
rename to gemrb/unhardcoded/how/icelance.pro
diff --git a/gemrb/override/how/icestorm.pro b/gemrb/unhardcoded/how/icestorm.pro
similarity index 100%
rename from gemrb/override/how/icestorm.pro
rename to gemrb/unhardcoded/how/icestorm.pro
diff --git a/gemrb/override/how/icloud.pro b/gemrb/unhardcoded/how/icloud.pro
similarity index 100%
rename from gemrb/override/how/icloud.pro
rename to gemrb/unhardcoded/how/icloud.pro
diff --git a/gemrb/override/how/iclouda.pro b/gemrb/unhardcoded/how/iclouda.pro
similarity index 100%
rename from gemrb/override/how/iclouda.pro
rename to gemrb/unhardcoded/how/iclouda.pro
diff --git a/gemrb/override/how/icloudb.pro b/gemrb/unhardcoded/how/icloudb.pro
similarity index 100%
rename from gemrb/override/how/icloudb.pro
rename to gemrb/unhardcoded/how/icloudb.pro
diff --git a/gemrb/override/how/illush.pro b/gemrb/unhardcoded/how/illush.pro
similarity index 100%
rename from gemrb/override/how/illush.pro
rename to gemrb/unhardcoded/how/illush.pro
diff --git a/gemrb/override/how/illust.pro b/gemrb/unhardcoded/how/illust.pro
similarity index 100%
rename from gemrb/override/how/illust.pro
rename to gemrb/unhardcoded/how/illust.pro
diff --git a/gemrb/override/how/inarea.pro b/gemrb/unhardcoded/how/inarea.pro
similarity index 100%
rename from gemrb/override/how/inarea.pro
rename to gemrb/unhardcoded/how/inarea.pro
diff --git a/gemrb/override/how/inareanp.pro b/gemrb/unhardcoded/how/inareanp.pro
similarity index 100%
copy from gemrb/override/how/inareanp.pro
copy to gemrb/unhardcoded/how/inareanp.pro
diff --git a/gemrb/unhardcoded/how/inareapa.pro b/gemrb/unhardcoded/how/inareapa.pro
new file mode 100644
index 0000000..fedb699
Binary files /dev/null and b/gemrb/unhardcoded/how/inareapa.pro differ
diff --git a/gemrb/override/how/inareasm.pro b/gemrb/unhardcoded/how/inareasm.pro
similarity index 100%
rename from gemrb/override/how/inareasm.pro
rename to gemrb/unhardcoded/how/inareasm.pro
diff --git a/gemrb/override/how/invoch.pro b/gemrb/unhardcoded/how/invoch.pro
similarity index 100%
rename from gemrb/override/how/invoch.pro
rename to gemrb/unhardcoded/how/invoch.pro
diff --git a/gemrb/override/how/invoct.pro b/gemrb/unhardcoded/how/invoct.pro
similarity index 100%
rename from gemrb/override/how/invoct.pro
rename to gemrb/unhardcoded/how/invoct.pro
diff --git a/gemrb/override/how/iplague.pro b/gemrb/unhardcoded/how/iplague.pro
similarity index 100%
rename from gemrb/override/how/iplague.pro
rename to gemrb/unhardcoded/how/iplague.pro
diff --git a/gemrb/override/how/island00.2da b/gemrb/unhardcoded/how/island00.2da
similarity index 100%
rename from gemrb/override/how/island00.2da
rename to gemrb/unhardcoded/how/island00.2da
diff --git a/gemrb/unhardcoded/how/itemsnd.2da b/gemrb/unhardcoded/how/itemsnd.2da
new file mode 100644
index 0000000..adffeb0
--- /dev/null
+++ b/gemrb/unhardcoded/how/itemsnd.2da
@@ -0,0 +1,81 @@
+2DA V1.0
+*
+ TAKE DROP
+MISC G_BOOK1 G_BOOK2
+AMULET G_NECK1 G_NECK2
+ARMOR G_CLOAK1 G_CLOAK2
+BELT G_BELT1 G_BELT2
+BOOT G_BOOT1 G_BOOT2
+ARROW G_ARRW1 G_ARRW2
+BRACER G_GLOVE1 G_GLOVE2
+HELMET G_HELM1 G_HELM2
+KEY G_KEY1 G_KEY2
+POTION G_POTN1 G_POTN2
+RING G_RING1 G_RING2
+SCROLL G_SCROL1 G_SCROL2
+SHIELD GAM_21A GAM_21B
+FOOD GAM_21A GAM_21B
+BULLET G_BULLT1 G_BULLT2
+BOW G_BOW1 G_BOW2
+DAGGER G_DAGGR1 G_DAGGR2
+MACE G_MACE1 G_MACE2
+SLING G_SLING1 G_SLING2
+SMSWORD G_SMSWD1 G_SMSWD2
+BGSWORD G_LGSWD1 G_LGSWD2
+HAMMER G_HAMMR1 G_HAMMR2
+MSTAR G_MSTAR1 G_MSTAR2
+FLAIL G_FLAIL1 G_FLAIL2
+DART G_DART1 G_DART2
+AXE G_AXE1 G_AXE2
+STAFF G_STAFF1 G_STAFF2
+XBOW G_CROSB1 G_CROSB2
+FIST GAM_21A GAM_21B
+SPEAR G_SPEAR1 G_SPEAR2
+POLEARM G_HALB1 G_HALB2
+BOLT G_BOLT1 G_BOLT2
+CLOAK G_CLOAK1 G_CLOAK2
+COIN G_GOLD1 G_GOLD2
+GEM G_GEM1 G_GEM2
+WAND G_WAND1 G_WAND2
+BROKEN1 G_B_ARM1 G_B_ARM2
+BROKEN2 G_B_SHD1 G_B_SHD2
+BROKEN3 G_B_WPN1 G_B_WPN2
+UNUSED1 GAM_21A GAM_21B
+UNUSED2 G_BROKN1 G_BROKN2
+BUCKLER G_BUCKR1 G_BUCKR2
+CANDLE G_CAND1 G_CAND2
+CBODY G_CHILD1 G_CHILD2
+CLUB G_CLUB1 G_CLUB2
+FBODY G_FEM1 G_FEM2
+KEY2 G_KEYS1 G_KEYS2
+LSHIELD G_LGSLD1 G_LGSLD2
+MBODY G_MALE1 G_MALE2
+MSHIELD G_MDSLD1 G_MDSLD2
+NOTES G_PAPR1 G_PAPR2
+ROD G_ROD1 G_ROD2
+SKULL G_SKULL1 G_SKULL2
+SSHIELD G_SMSLD1 G_SMSLD2
+SPIDER G_SPIDR1 G_SPIDR2
+TELESCOPE G_TELE1 G_TELE2
+DRINK G_WINE1 G_WINE2
+GTSWORD G_LGSWD1 G_LGSWD2
+BAG GAM_21A GAM_21B
+FUR G_LETHR1 G_LETHR2
+LARMOR G_CLOAK1 G_CLOAK2
+SLARMOR G_CLOAK1 G_CLOAK2
+CHARMOR G_CLOAK1 G_CLOAK2
+SPARMOR G_CLOAK1 G_CLOAK2
+HPARMOR G_CLOAK1 G_CLOAK2
+FPARMOR G_CLOAK1 G_CLOAK2
+HARMOR G_CLOAK1 G_CLOAK2
+ROBE G_CLOAK1 G_CLOAK2
+SCALE G_CLOAK1 G_CLOAK2
+BTSWORD G_LGSWD1 G_LGSWD2
+SCARF G_GLOVE1 G_GLOVE2
+FOOD2 G_SLING1 G_SLING2
+HAT G_GLOVE1 G_GLOVE2
+GAUNTLET G_CAND1 G_CAND2
+DEFAULT GAM_21A GAM_21B
+LEATHER G_LETHR1 G_LETHR2
+CHAIN G_Chain1 G_Chain2
+PLATE G_Plate1 G_Plate2
diff --git a/gemrb/unhardcoded/how/itemtype.2da b/gemrb/unhardcoded/how/itemtype.2da
new file mode 100644
index 0000000..f5b10f8
--- /dev/null
+++ b/gemrb/unhardcoded/how/itemtype.2da
@@ -0,0 +1,77 @@
+2DA V1.0
+0
+ HELMET ARMOR SHIELD GLOVES RING AMULET BELT BOOTS WEAPON QUIVER CLOAK QUICK SCROLL BAG POTION
+MISC 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
+AMULET 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
+ARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+BELT 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
+BOOT 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
+ARROW 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
+BRACER 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
+HELMET 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+KEY 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+POTION 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
+RING 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
+SCROLL 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0
+SHIELD 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
+FOOD 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
+BULLET 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
+BOW 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+DAGGER 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+MACE 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+SLING 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+SMSWORD 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+BGSWORD 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+HAMMER 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+MSTAR 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+FLAIL 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+DART 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+AXE 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+STAFF 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+XBOW 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+FIST 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+SPEAR 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+POLEARM 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+BOLT 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
+CLOAK 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
+COIN 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+GEM 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
+WAND 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
+BROKEN1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+BROKEN2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+BROKEN3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+UNUSED1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+UNUSED2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+BUCKLER 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
+CANDLE 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+UNUSED3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+CLUB 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+UNUSED4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+UNUSED5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+LSHIELD 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
+UNUSED6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+MSHIELD 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
+NOTES 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+UNUSED7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+UNUSED8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+SSHIELD 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
+UNUSED9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+TELESCOPE 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+DRINK 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
+GTSWORD 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+BAG 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
+FUR 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+LARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+SLARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+CHARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+SPARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+HPARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+FPARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+HARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+ROBE 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+UNUSED10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+BTSWORD 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+SCARF 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
+FOOD2 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
+HAT 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+GAUNTLET 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
diff --git a/gemrb/override/how/itemuse.2da b/gemrb/unhardcoded/how/itemuse.2da
similarity index 100%
rename from gemrb/override/how/itemuse.2da
rename to gemrb/unhardcoded/how/itemuse.2da
diff --git a/gemrb/override/how/kitlist.2da b/gemrb/unhardcoded/how/kitlist.2da
similarity index 100%
rename from gemrb/override/how/kitlist.2da
rename to gemrb/unhardcoded/how/kitlist.2da
diff --git a/gemrb/override/how/lightb.pro b/gemrb/unhardcoded/how/lightb.pro
similarity index 100%
rename from gemrb/override/how/lightb.pro
rename to gemrb/unhardcoded/how/lightb.pro
diff --git a/gemrb/unhardcoded/how/lightbnb.pro b/gemrb/unhardcoded/how/lightbnb.pro
new file mode 100644
index 0000000..60ad208
Binary files /dev/null and b/gemrb/unhardcoded/how/lightbnb.pro differ
diff --git a/gemrb/override/how/lightsto.pro b/gemrb/unhardcoded/how/lightsto.pro
similarity index 100%
rename from gemrb/override/how/lightsto.pro
rename to gemrb/unhardcoded/how/lightsto.pro
diff --git a/gemrb/override/how/lodisr.pro b/gemrb/unhardcoded/how/lodisr.pro
similarity index 100%
rename from gemrb/override/how/lodisr.pro
rename to gemrb/unhardcoded/how/lodisr.pro
diff --git a/gemrb/unhardcoded/how/magesch.2da b/gemrb/unhardcoded/how/magesch.2da
new file mode 100644
index 0000000..70deb9f
--- /dev/null
+++ b/gemrb/unhardcoded/how/magesch.2da
@@ -0,0 +1,12 @@
+2DA V1.0
+-1
+ NAME_REF DESC_REF CAP_REF KIT
+GENERALIST 18039 9563 9987 0x4000
+ABJURER 597 9564 502 0x40
+CONJURER 2179 9565 504 0x80
+DIVINER 2846 9566 2012 0x100
+ENCHANTER 2861 9567 2022 0x200
+ILLUSIONIST 2862 9568 12785 0x400
+INVOKER 3015 9569 12786 0x800
+NECROMANCER 12744 9570 12787 0x1000
+TRANSMUTER 12745 9571 12788 0x2000
diff --git a/gemrb/override/how/magicmis.pro b/gemrb/unhardcoded/how/magicmis.pro
similarity index 100%
rename from gemrb/override/how/magicmis.pro
rename to gemrb/unhardcoded/how/magicmis.pro
diff --git a/gemrb/override/how/malison.pro b/gemrb/unhardcoded/how/malison.pro
similarity index 100%
rename from gemrb/override/how/malison.pro
rename to gemrb/unhardcoded/how/malison.pro
diff --git a/gemrb/override/how/mfmiss.pro b/gemrb/unhardcoded/how/mfmiss.pro
similarity index 100%
rename from gemrb/override/how/mfmiss.pro
rename to gemrb/unhardcoded/how/mfmiss.pro
diff --git a/gemrb/override/how/mfmiss2.pro b/gemrb/unhardcoded/how/mfmiss2.pro
similarity index 100%
rename from gemrb/override/how/mfmiss2.pro
rename to gemrb/unhardcoded/how/mfmiss2.pro
diff --git a/gemrb/override/how/mfmissh.pro b/gemrb/unhardcoded/how/mfmissh.pro
similarity index 100%
rename from gemrb/override/how/mfmissh.pro
rename to gemrb/unhardcoded/how/mfmissh.pro
diff --git a/gemrb/override/how/mmagich.pro b/gemrb/unhardcoded/how/mmagich.pro
similarity index 100%
rename from gemrb/override/how/mmagich.pro
rename to gemrb/unhardcoded/how/mmagich.pro
diff --git a/gemrb/override/how/mmissile.pro b/gemrb/unhardcoded/how/mmissile.pro
similarity index 100%
rename from gemrb/override/how/mmissile.pro
rename to gemrb/unhardcoded/how/mmissile.pro
diff --git a/gemrb/override/how/moelda.pro b/gemrb/unhardcoded/how/moelda.pro
similarity index 100%
rename from gemrb/override/how/moelda.pro
rename to gemrb/unhardcoded/how/moelda.pro
diff --git a/gemrb/override/how/mrage.pro b/gemrb/unhardcoded/how/mrage.pro
similarity index 100%
rename from gemrb/override/how/mrage.pro
rename to gemrb/unhardcoded/how/mrage.pro
diff --git a/gemrb/override/how/mrageh.pro b/gemrb/unhardcoded/how/mrageh.pro
similarity index 100%
rename from gemrb/override/how/mrageh.pro
rename to gemrb/unhardcoded/how/mrageh.pro
diff --git a/gemrb/override/how/mspore.pro b/gemrb/unhardcoded/how/mspore.pro
similarity index 100%
rename from gemrb/override/how/mspore.pro
rename to gemrb/unhardcoded/how/mspore.pro
diff --git a/gemrb/override/how/msumm1.pro b/gemrb/unhardcoded/how/msumm1.pro
similarity index 100%
rename from gemrb/override/how/msumm1.pro
rename to gemrb/unhardcoded/how/msumm1.pro
diff --git a/gemrb/override/how/msumm1h.pro b/gemrb/unhardcoded/how/msumm1h.pro
similarity index 100%
rename from gemrb/override/how/msumm1h.pro
rename to gemrb/unhardcoded/how/msumm1h.pro
diff --git a/gemrb/override/how/msumm1x.pro b/gemrb/unhardcoded/how/msumm1x.pro
similarity index 100%
rename from gemrb/override/how/msumm1x.pro
rename to gemrb/unhardcoded/how/msumm1x.pro
diff --git a/gemrb/override/how/msumm2h.pro b/gemrb/unhardcoded/how/msumm2h.pro
similarity index 100%
rename from gemrb/override/how/msumm2h.pro
rename to gemrb/unhardcoded/how/msumm2h.pro
diff --git a/gemrb/override/how/msumm3h.pro b/gemrb/unhardcoded/how/msumm3h.pro
similarity index 100%
rename from gemrb/override/how/msumm3h.pro
rename to gemrb/unhardcoded/how/msumm3h.pro
diff --git a/gemrb/override/how/msumm4h.pro b/gemrb/unhardcoded/how/msumm4h.pro
similarity index 100%
rename from gemrb/override/how/msumm4h.pro
rename to gemrb/unhardcoded/how/msumm4h.pro
diff --git a/gemrb/override/how/msumm5h.pro b/gemrb/unhardcoded/how/msumm5h.pro
similarity index 100%
rename from gemrb/override/how/msumm5h.pro
rename to gemrb/unhardcoded/how/msumm5h.pro
diff --git a/gemrb/override/how/msumm6h.pro b/gemrb/unhardcoded/how/msumm6h.pro
similarity index 100%
rename from gemrb/override/how/msumm6h.pro
rename to gemrb/unhardcoded/how/msumm6h.pro
diff --git a/gemrb/override/how/msumm7h.pro b/gemrb/unhardcoded/how/msumm7h.pro
similarity index 100%
rename from gemrb/override/how/msumm7h.pro
rename to gemrb/unhardcoded/how/msumm7h.pro
diff --git a/gemrb/override/how/mswordh.pro b/gemrb/unhardcoded/how/mswordh.pro
similarity index 100%
rename from gemrb/override/how/mswordh.pro
rename to gemrb/unhardcoded/how/mswordh.pro
diff --git a/gemrb/override/how/mtouchh.pro b/gemrb/unhardcoded/how/mtouchh.pro
similarity index 100%
rename from gemrb/override/how/mtouchh.pro
rename to gemrb/unhardcoded/how/mtouchh.pro
diff --git a/gemrb/override/how/necroh.pro b/gemrb/unhardcoded/how/necroh.pro
similarity index 100%
rename from gemrb/override/how/necroh.pro
rename to gemrb/unhardcoded/how/necroh.pro
diff --git a/gemrb/override/how/necrot.pro b/gemrb/unhardcoded/how/necrot.pro
similarity index 100%
rename from gemrb/override/how/necrot.pro
rename to gemrb/unhardcoded/how/necrot.pro
diff --git a/gemrb/override/how/npoisoh.pro b/gemrb/unhardcoded/how/npoisoh.pro
similarity index 100%
rename from gemrb/override/how/npoisoh.pro
rename to gemrb/unhardcoded/how/npoisoh.pro
diff --git a/gemrb/override/how/ofsphe.pro b/gemrb/unhardcoded/how/ofsphe.pro
similarity index 100%
rename from gemrb/override/how/ofsphe.pro
rename to gemrb/unhardcoded/how/ofsphe.pro
diff --git a/gemrb/unhardcoded/how/overlay.2da b/gemrb/unhardcoded/how/overlay.2da
new file mode 100644
index 0000000..4b83cc6
--- /dev/null
+++ b/gemrb/unhardcoded/how/overlay.2da
@@ -0,0 +1,35 @@
+2DA V1.0
+*
+ VVC UNDER FLAGS
+SANCTUARY SANCTUC 0 1
+ENTANGLE ENTANGC 0 0
+WISP WISP 0 0
+SHIELDGLOBE SHIELDC 0 1
+GREASE GREASEC 1 0
+WEB WEBC 1 0
+MINORGLOBE MGOINVC 0 1
+GLOBE GOINVUC 0 1
+FLAMESHROUD SOFLAMC 0 0
+ANTIMAGIC AMSHELC 0 0
+RESILIENT ORSPHEC 0 0
+PROTFROMMISS PFNMISC 0 0
+CLOAKOFFEAR COFEARC 0 0
+ENTROPY ESHIELC 0 0
+FIREAURA FIAURAC 0 0
+FROSTAURA FRAURAC 0 0
+INSECT IPLAGUC 0 0
+STORMSHELL SSHELLC 0 0
+LATHANDER1 SOLATC1 0 0
+LATHANDER2 SOLATC2 1 0
+GLATHANDER1 GSOLAC1 0 0
+GLATHANDER2 GSOLAC2 1 0
+SEVENEYES1 SEYESC1 0 0
+SEVENEYES2 SEYESC2 1 0
+BOUNCE SPTURNI2 1 0
+BOUNCE2 SPSTURNI 1 0
+FIRESHIELD1 FSHIRC1 0 0
+FIRESHIELD2 FSHIRC2 1 0
+ICESHIELD1 FSHIBC1 0 0
+ICESHIELD2 FSHIBC2 1 0
+TORTOISE TSHELLC 0 0
+DEATHARMOR DARMORC 0 0
diff --git a/gemrb/override/how/paralh.pro b/gemrb/unhardcoded/how/paralh.pro
similarity index 100%
rename from gemrb/override/how/paralh.pro
rename to gemrb/unhardcoded/how/paralh.pro
diff --git a/gemrb/override/how/pathfind.2da b/gemrb/unhardcoded/how/pathfind.2da
similarity index 100%
copy from gemrb/override/how/pathfind.2da
copy to gemrb/unhardcoded/how/pathfind.2da
diff --git a/gemrb/override/how/pdolls.2da b/gemrb/unhardcoded/how/pdolls.2da
similarity index 100%
rename from gemrb/override/how/pdolls.2da
rename to gemrb/unhardcoded/how/pdolls.2da
diff --git a/gemrb/override/how/pfire.pro b/gemrb/unhardcoded/how/pfire.pro
similarity index 100%
rename from gemrb/override/how/pfire.pro
rename to gemrb/unhardcoded/how/pfire.pro
diff --git a/gemrb/override/how/pictures.2da b/gemrb/unhardcoded/how/pictures.2da
similarity index 100%
rename from gemrb/override/how/pictures.2da
rename to gemrb/unhardcoded/how/pictures.2da
diff --git a/gemrb/override/how/poisonh.pro b/gemrb/unhardcoded/how/poisonh.pro
similarity index 100%
rename from gemrb/override/how/poisonh.pro
rename to gemrb/unhardcoded/how/poisonh.pro
diff --git a/gemrb/override/how/pomab.2da b/gemrb/unhardcoded/how/pomab.2da
similarity index 100%
rename from gemrb/override/how/pomab.2da
rename to gemrb/unhardcoded/how/pomab.2da
diff --git a/gemrb/override/how/portal.pro b/gemrb/unhardcoded/how/portal.pro
similarity index 100%
rename from gemrb/override/how/portal.pro
rename to gemrb/unhardcoded/how/portal.pro
diff --git a/gemrb/override/how/prayer.pro b/gemrb/unhardcoded/how/prayer.pro
similarity index 100%
rename from gemrb/override/how/prayer.pro
rename to gemrb/unhardcoded/how/prayer.pro
diff --git a/gemrb/override/how/prayerh.pro b/gemrb/unhardcoded/how/prayerh.pro
similarity index 100%
rename from gemrb/override/how/prayerh.pro
rename to gemrb/unhardcoded/how/prayerh.pro
diff --git a/gemrb/unhardcoded/how/proftype.2da b/gemrb/unhardcoded/how/proftype.2da
new file mode 100644
index 0000000..ebd9cfa
--- /dev/null
+++ b/gemrb/unhardcoded/how/proftype.2da
@@ -0,0 +1,61 @@
+2DA V1.0
+-1
+ OLD_PROFICIENCY
+0 -1
+1 -1
+2 -1
+3 -1
+4 -1
+5 -1
+6 -1
+7 -1
+8 -1
+9 -1
+10 -1
+11 -1
+12 -1
+13 -1
+14 -1
+15_BOW 2
+16_DAGGER 7
+17_MACE 9
+18_SLING 5
+19_SWORD 1
+20_BIG 0
+21_HAMMER 11
+22_MS 9
+23_FLAIL 10
+24_DART 5
+25_AXE 4
+26_STAFF 13
+27_XBOW 14
+28_HAND -2
+29_SPEAR 3
+30_HALBERD 8
+31 -1
+32 -1
+33 -1
+34 -1
+35 -1
+36 -1
+37 -1
+38 -1
+39 -1
+40 -1
+41 -1
+42 -1
+43 -1
+44_CLUB 12
+45 -1
+46 -1
+47 -1
+48 -1
+49 -1
+50 -1
+51 -1
+52 -1
+53 -1
+54 -1
+55 -1
+56 -1
+57_GREATSWORD 6
diff --git a/gemrb/override/how/protevil.pro b/gemrb/unhardcoded/how/protevil.pro
similarity index 100%
rename from gemrb/override/how/protevil.pro
rename to gemrb/unhardcoded/how/protevil.pro
diff --git a/gemrb/override/how/prtl_cl.pro b/gemrb/unhardcoded/how/prtl_cl.pro
similarity index 100%
rename from gemrb/override/how/prtl_cl.pro
rename to gemrb/unhardcoded/how/prtl_cl.pro
diff --git a/gemrb/override/how/prtl_cl.spl b/gemrb/unhardcoded/how/prtl_cl.spl
similarity index 100%
rename from gemrb/override/how/prtl_cl.spl
rename to gemrb/unhardcoded/how/prtl_cl.spl
diff --git a/gemrb/override/how/prtl_op.pro b/gemrb/unhardcoded/how/prtl_op.pro
similarity index 100%
rename from gemrb/override/how/prtl_op.pro
rename to gemrb/unhardcoded/how/prtl_op.pro
diff --git a/gemrb/override/how/prtl_op.spl b/gemrb/unhardcoded/how/prtl_op.spl
similarity index 100%
rename from gemrb/override/how/prtl_op.spl
rename to gemrb/unhardcoded/how/prtl_op.spl
diff --git a/gemrb/override/how/pspray.pro b/gemrb/unhardcoded/how/pspray.pro
similarity index 100%
rename from gemrb/override/how/pspray.pro
rename to gemrb/unhardcoded/how/pspray.pro
diff --git a/gemrb/override/how/pwkill.pro b/gemrb/unhardcoded/how/pwkill.pro
similarity index 100%
rename from gemrb/override/how/pwkill.pro
rename to gemrb/unhardcoded/how/pwkill.pro
diff --git a/gemrb/override/how/pwsileh.pro b/gemrb/unhardcoded/how/pwsileh.pro
similarity index 100%
rename from gemrb/override/how/pwsileh.pro
rename to gemrb/unhardcoded/how/pwsileh.pro
diff --git a/gemrb/override/how/pwstun.pro b/gemrb/unhardcoded/how/pwstun.pro
similarity index 100%
rename from gemrb/override/how/pwstun.pro
rename to gemrb/unhardcoded/how/pwstun.pro
diff --git a/gemrb/override/how/pwstunh.pro b/gemrb/unhardcoded/how/pwstunh.pro
similarity index 100%
rename from gemrb/override/how/pwstunh.pro
rename to gemrb/unhardcoded/how/pwstunh.pro
diff --git a/gemrb/unhardcoded/how/qslots.2da b/gemrb/unhardcoded/how/qslots.2da
new file mode 100644
index 0000000..f3103af
--- /dev/null
+++ b/gemrb/unhardcoded/how/qslots.2da
@@ -0,0 +1,23 @@
+2DA V1.0
+100
+ SLOT1 SLOT2 SLOT3 SLOT4 SLOT5 SLOT6 SLOT7 SLOT8 SLOT9
+MAGE 3 4 5 2 8 9 11 12 13
+FIGHTER 18 19 14 100 8 9 11 12 13
+CLERIC 6 3 4 2 8 9 11 12 13
+THIEF 22 0 1 100 8 9 11 12 13
+BARD 20 1 3 2 8 9 11 12 13
+PALADIN 18 14 6 2 8 9 11 12 13
+FIGHTER_MAGE 3 4 5 2 8 9 11 12 13
+FIGHTER_CLERIC 6 3 4 2 8 9 11 12 13
+FIGHTER_THIEF 18 22 0 1 8 9 11 12 13
+FIGHTER_MAGE_THIEF 22 0 1 2 8 9 11 12 13
+DRUID 3 4 5 2 8 9 11 12 13
+RANGER 18 14 0 2 8 9 11 12 13
+MAGE_THIEF 22 0 1 2 8 9 11 12 13
+CLERIC_MAGE 6 3 4 2 8 9 11 12 13
+CLERIC_THIEF 22 0 1 2 8 9 11 12 13
+FIGHTER_DRUID 3 4 5 2 8 9 11 12 13
+FIGHTER_MAGE_CLERIC 6 3 4 2 8 9 11 12 13
+CLERIC_RANGER 6 3 4 2 8 9 11 12 13
+SORCERER 3 4 5 2 8 9 11 12 13
+MONK 18 14 22 0 8 9 11 12 13
diff --git a/gemrb/override/how/races.2da b/gemrb/unhardcoded/how/races.2da
similarity index 100%
rename from gemrb/override/how/races.2da
rename to gemrb/unhardcoded/how/races.2da
diff --git a/gemrb/override/how/rad100.pro b/gemrb/unhardcoded/how/rad100.pro
similarity index 100%
rename from gemrb/override/how/rad100.pro
rename to gemrb/unhardcoded/how/rad100.pro
diff --git a/gemrb/override/how/rad250.pro b/gemrb/unhardcoded/how/rad250.pro
similarity index 100%
rename from gemrb/override/how/rad250.pro
rename to gemrb/unhardcoded/how/rad250.pro
diff --git a/gemrb/override/how/randitem.2da b/gemrb/unhardcoded/how/randitem.2da
similarity index 100%
rename from gemrb/override/how/randitem.2da
rename to gemrb/unhardcoded/how/randitem.2da
diff --git a/gemrb/override/how/rdeadh.pro b/gemrb/unhardcoded/how/rdeadh.pro
similarity index 100%
rename from gemrb/override/how/rdeadh.pro
rename to gemrb/unhardcoded/how/rdeadh.pro
diff --git a/gemrb/override/how/recitah.pro b/gemrb/unhardcoded/how/recitah.pro
similarity index 100%
rename from gemrb/override/how/recitah.pro
rename to gemrb/unhardcoded/how/recitah.pro
diff --git a/gemrb/override/how/resurrh.pro b/gemrb/unhardcoded/how/resurrh.pro
similarity index 100%
rename from gemrb/override/how/resurrh.pro
rename to gemrb/unhardcoded/how/resurrh.pro
diff --git a/gemrb/override/how/rng450.pro b/gemrb/unhardcoded/how/rng450.pro
similarity index 100%
rename from gemrb/override/how/rng450.pro
rename to gemrb/unhardcoded/how/rng450.pro
diff --git a/gemrb/override/how/rparalh.pro b/gemrb/unhardcoded/how/rparalh.pro
similarity index 100%
rename from gemrb/override/how/rparalh.pro
rename to gemrb/unhardcoded/how/rparalh.pro
diff --git a/gemrb/override/how/rwotfag.pro b/gemrb/unhardcoded/how/rwotfag.pro
similarity index 100%
rename from gemrb/override/how/rwotfag.pro
rename to gemrb/unhardcoded/how/rwotfag.pro
diff --git a/gemrb/override/how/rwotfah.pro b/gemrb/unhardcoded/how/rwotfah.pro
similarity index 100%
rename from gemrb/override/how/rwotfah.pro
rename to gemrb/unhardcoded/how/rwotfah.pro
diff --git a/gemrb/override/how/sarmorh.pro b/gemrb/unhardcoded/how/sarmorh.pro
similarity index 100%
rename from gemrb/override/how/sarmorh.pro
rename to gemrb/unhardcoded/how/sarmorh.pro
diff --git a/gemrb/override/how/savegame.2da b/gemrb/unhardcoded/how/savegame.2da
similarity index 100%
rename from gemrb/override/how/savegame.2da
rename to gemrb/unhardcoded/how/savegame.2da
diff --git a/gemrb/override/how/scharge.pro b/gemrb/unhardcoded/how/scharge.pro
similarity index 100%
rename from gemrb/override/how/scharge.pro
rename to gemrb/unhardcoded/how/scharge.pro
diff --git a/gemrb/override/how/scharge.spl b/gemrb/unhardcoded/how/scharge.spl
similarity index 100%
rename from gemrb/override/how/scharge.spl
rename to gemrb/unhardcoded/how/scharge.spl
diff --git a/gemrb/override/how/schargh.pro b/gemrb/unhardcoded/how/schargh.pro
similarity index 100%
rename from gemrb/override/how/schargh.pro
rename to gemrb/unhardcoded/how/schargh.pro
diff --git a/gemrb/override/how/script.2da b/gemrb/unhardcoded/how/script.2da
similarity index 100%
rename from gemrb/override/how/script.2da
rename to gemrb/unhardcoded/how/script.2da
diff --git a/gemrb/override/how/seater.pro b/gemrb/unhardcoded/how/seater.pro
similarity index 100%
rename from gemrb/override/how/seater.pro
rename to gemrb/unhardcoded/how/seater.pro
diff --git a/gemrb/override/how/seaterh.pro b/gemrb/unhardcoded/how/seaterh.pro
similarity index 100%
rename from gemrb/override/how/seaterh.pro
rename to gemrb/unhardcoded/how/seaterh.pro
diff --git a/gemrb/override/how/sgrowth.pro b/gemrb/unhardcoded/how/sgrowth.pro
similarity index 100%
rename from gemrb/override/how/sgrowth.pro
rename to gemrb/unhardcoded/how/sgrowth.pro
diff --git a/gemrb/override/how/shout.pro b/gemrb/unhardcoded/how/shout.pro
similarity index 100%
rename from gemrb/override/how/shout.pro
rename to gemrb/unhardcoded/how/shout.pro
diff --git a/gemrb/override/how/shroud.pro b/gemrb/unhardcoded/how/shroud.pro
similarity index 100%
rename from gemrb/override/how/shroud.pro
rename to gemrb/unhardcoded/how/shroud.pro
diff --git a/gemrb/override/how/shtable.2da b/gemrb/unhardcoded/how/shtable.2da
similarity index 100%
rename from gemrb/override/how/shtable.2da
rename to gemrb/unhardcoded/how/shtable.2da
diff --git a/gemrb/override/how/skills.2da b/gemrb/unhardcoded/how/skills.2da
similarity index 100%
rename from gemrb/override/how/skills.2da
rename to gemrb/unhardcoded/how/skills.2da
diff --git a/gemrb/override/how/sleep.pro b/gemrb/unhardcoded/how/sleep.pro
similarity index 100%
rename from gemrb/override/how/sleep.pro
rename to gemrb/unhardcoded/how/sleep.pro
diff --git a/gemrb/override/how/slivinh.pro b/gemrb/unhardcoded/how/slivinh.pro
similarity index 100%
rename from gemrb/override/how/slivinh.pro
rename to gemrb/unhardcoded/how/slivinh.pro
diff --git a/gemrb/override/how/slottype.2da b/gemrb/unhardcoded/how/slottype.2da
similarity index 100%
rename from gemrb/override/how/slottype.2da
rename to gemrb/unhardcoded/how/slottype.2da
diff --git a/gemrb/override/how/soflamh.pro b/gemrb/unhardcoded/how/soflamh.pro
similarity index 100%
rename from gemrb/override/how/soflamh.pro
rename to gemrb/unhardcoded/how/soflamh.pro
diff --git a/gemrb/override/how/sohope.pro b/gemrb/unhardcoded/how/sohope.pro
similarity index 100%
rename from gemrb/override/how/sohope.pro
rename to gemrb/unhardcoded/how/sohope.pro
diff --git a/gemrb/override/how/sooneh.pro b/gemrb/unhardcoded/how/sooneh.pro
similarity index 100%
rename from gemrb/override/how/sooneh.pro
rename to gemrb/unhardcoded/how/sooneh.pro
diff --git a/gemrb/override/how/sopain.pro b/gemrb/unhardcoded/how/sopain.pro
similarity index 100%
rename from gemrb/override/how/sopain.pro
rename to gemrb/unhardcoded/how/sopain.pro
diff --git a/gemrb/override/how/sparbknp.pro b/gemrb/unhardcoded/how/sparbknp.pro
similarity index 100%
rename from gemrb/override/how/sparbknp.pro
rename to gemrb/unhardcoded/how/sparbknp.pro
diff --git a/gemrb/override/how/sparbkpa.pro b/gemrb/unhardcoded/how/sparbkpa.pro
similarity index 100%
rename from gemrb/override/how/sparbkpa.pro
rename to gemrb/unhardcoded/how/sparbkpa.pro
diff --git a/gemrb/override/how/sparblnp.pro b/gemrb/unhardcoded/how/sparblnp.pro
similarity index 100%
rename from gemrb/override/how/sparblnp.pro
rename to gemrb/unhardcoded/how/sparblnp.pro
diff --git a/gemrb/override/how/sparblpa.pro b/gemrb/unhardcoded/how/sparblpa.pro
similarity index 100%
rename from gemrb/override/how/sparblpa.pro
rename to gemrb/unhardcoded/how/sparblpa.pro
diff --git a/gemrb/override/how/sparchnp.pro b/gemrb/unhardcoded/how/sparchnp.pro
similarity index 100%
rename from gemrb/override/how/sparchnp.pro
rename to gemrb/unhardcoded/how/sparchnp.pro
diff --git a/gemrb/override/how/sparchpa.pro b/gemrb/unhardcoded/how/sparchpa.pro
similarity index 100%
rename from gemrb/override/how/sparchpa.pro
rename to gemrb/unhardcoded/how/sparchpa.pro
diff --git a/gemrb/override/how/spargonp.pro b/gemrb/unhardcoded/how/spargonp.pro
similarity index 100%
rename from gemrb/override/how/spargonp.pro
rename to gemrb/unhardcoded/how/spargonp.pro
diff --git a/gemrb/override/how/spargopa.pro b/gemrb/unhardcoded/how/spargopa.pro
similarity index 100%
rename from gemrb/override/how/spargopa.pro
rename to gemrb/unhardcoded/how/spargopa.pro
diff --git a/gemrb/override/how/spargrnp.pro b/gemrb/unhardcoded/how/spargrnp.pro
similarity index 100%
rename from gemrb/override/how/spargrnp.pro
rename to gemrb/unhardcoded/how/spargrnp.pro
diff --git a/gemrb/override/how/spargrpa.pro b/gemrb/unhardcoded/how/spargrpa.pro
similarity index 100%
rename from gemrb/override/how/spargrpa.pro
rename to gemrb/unhardcoded/how/spargrpa.pro
diff --git a/gemrb/override/how/sparicnp.pro b/gemrb/unhardcoded/how/sparicnp.pro
similarity index 100%
rename from gemrb/override/how/sparicnp.pro
rename to gemrb/unhardcoded/how/sparicnp.pro
diff --git a/gemrb/override/how/sparicpa.pro b/gemrb/unhardcoded/how/sparicpa.pro
similarity index 100%
rename from gemrb/override/how/sparicpa.pro
rename to gemrb/unhardcoded/how/sparicpa.pro
diff --git a/gemrb/override/how/sparklbk.pro b/gemrb/unhardcoded/how/sparklbk.pro
similarity index 100%
rename from gemrb/override/how/sparklbk.pro
rename to gemrb/unhardcoded/how/sparklbk.pro
diff --git a/gemrb/override/how/sparklbl.pro b/gemrb/unhardcoded/how/sparklbl.pro
similarity index 100%
rename from gemrb/override/how/sparklbl.pro
rename to gemrb/unhardcoded/how/sparklbl.pro
diff --git a/gemrb/override/how/sparklch.pro b/gemrb/unhardcoded/how/sparklch.pro
similarity index 100%
rename from gemrb/override/how/sparklch.pro
rename to gemrb/unhardcoded/how/sparklch.pro
diff --git a/gemrb/override/how/sparklgo.pro b/gemrb/unhardcoded/how/sparklgo.pro
similarity index 100%
rename from gemrb/override/how/sparklgo.pro
rename to gemrb/unhardcoded/how/sparklgo.pro
diff --git a/gemrb/override/how/sparklgr.pro b/gemrb/unhardcoded/how/sparklgr.pro
similarity index 100%
rename from gemrb/override/how/sparklgr.pro
rename to gemrb/unhardcoded/how/sparklgr.pro
diff --git a/gemrb/override/how/sparklic.pro b/gemrb/unhardcoded/how/sparklic.pro
similarity index 100%
rename from gemrb/override/how/sparklic.pro
rename to gemrb/unhardcoded/how/sparklic.pro
diff --git a/gemrb/override/how/sparklma.pro b/gemrb/unhardcoded/how/sparklma.pro
similarity index 100%
rename from gemrb/override/how/sparklma.pro
rename to gemrb/unhardcoded/how/sparklma.pro
diff --git a/gemrb/override/how/sparklor.pro b/gemrb/unhardcoded/how/sparklor.pro
similarity index 100%
rename from gemrb/override/how/sparklor.pro
rename to gemrb/unhardcoded/how/sparklor.pro
diff --git a/gemrb/override/how/sparklpu.pro b/gemrb/unhardcoded/how/sparklpu.pro
similarity index 100%
rename from gemrb/override/how/sparklpu.pro
rename to gemrb/unhardcoded/how/sparklpu.pro
diff --git a/gemrb/override/how/sparklre.pro b/gemrb/unhardcoded/how/sparklre.pro
similarity index 100%
rename from gemrb/override/how/sparklre.pro
rename to gemrb/unhardcoded/how/sparklre.pro
diff --git a/gemrb/override/how/sparklst.pro b/gemrb/unhardcoded/how/sparklst.pro
similarity index 100%
rename from gemrb/override/how/sparklst.pro
rename to gemrb/unhardcoded/how/sparklst.pro
diff --git a/gemrb/override/how/sparmanp.pro b/gemrb/unhardcoded/how/sparmanp.pro
similarity index 100%
rename from gemrb/override/how/sparmanp.pro
rename to gemrb/unhardcoded/how/sparmanp.pro
diff --git a/gemrb/override/how/sparmapa.pro b/gemrb/unhardcoded/how/sparmapa.pro
similarity index 100%
rename from gemrb/override/how/sparmapa.pro
rename to gemrb/unhardcoded/how/sparmapa.pro
diff --git a/gemrb/override/how/sparornp.pro b/gemrb/unhardcoded/how/sparornp.pro
similarity index 100%
rename from gemrb/override/how/sparornp.pro
rename to gemrb/unhardcoded/how/sparornp.pro
diff --git a/gemrb/override/how/sparorpa.pro b/gemrb/unhardcoded/how/sparorpa.pro
similarity index 100%
rename from gemrb/override/how/sparorpa.pro
rename to gemrb/unhardcoded/how/sparorpa.pro
diff --git a/gemrb/override/how/sparpunp.pro b/gemrb/unhardcoded/how/sparpunp.pro
similarity index 100%
rename from gemrb/override/how/sparpunp.pro
rename to gemrb/unhardcoded/how/sparpunp.pro
diff --git a/gemrb/override/how/sparpupa.pro b/gemrb/unhardcoded/how/sparpupa.pro
similarity index 100%
rename from gemrb/override/how/sparpupa.pro
rename to gemrb/unhardcoded/how/sparpupa.pro
diff --git a/gemrb/override/how/sparrenp.pro b/gemrb/unhardcoded/how/sparrenp.pro
similarity index 100%
rename from gemrb/override/how/sparrenp.pro
rename to gemrb/unhardcoded/how/sparrenp.pro
diff --git a/gemrb/override/how/sparrepa.pro b/gemrb/unhardcoded/how/sparrepa.pro
similarity index 100%
rename from gemrb/override/how/sparrepa.pro
rename to gemrb/unhardcoded/how/sparrepa.pro
diff --git a/gemrb/override/how/sparstnp.pro b/gemrb/unhardcoded/how/sparstnp.pro
similarity index 100%
rename from gemrb/override/how/sparstnp.pro
rename to gemrb/unhardcoded/how/sparstnp.pro
diff --git a/gemrb/override/how/sparstpa.pro b/gemrb/unhardcoded/how/sparstpa.pro
similarity index 100%
rename from gemrb/override/how/sparstpa.pro
rename to gemrb/unhardcoded/how/sparstpa.pro
diff --git a/gemrb/override/how/spear.pro b/gemrb/unhardcoded/how/spear.pro
similarity index 100%
rename from gemrb/override/how/spear.pro
rename to gemrb/unhardcoded/how/spear.pro
diff --git a/gemrb/override/how/spearex.pro b/gemrb/unhardcoded/how/spearex.pro
similarity index 100%
rename from gemrb/override/how/spearex.pro
rename to gemrb/unhardcoded/how/spearex.pro
diff --git a/gemrb/override/how/spfirebl.pro b/gemrb/unhardcoded/how/spfirebl.pro
similarity index 100%
rename from gemrb/override/how/spfirebl.pro
rename to gemrb/unhardcoded/how/spfirebl.pro
diff --git a/gemrb/override/how/spklarbk.pro b/gemrb/unhardcoded/how/spklarbk.pro
similarity index 100%
rename from gemrb/override/how/spklarbk.pro
rename to gemrb/unhardcoded/how/spklarbk.pro
diff --git a/gemrb/override/how/spklarbl.pro b/gemrb/unhardcoded/how/spklarbl.pro
similarity index 100%
rename from gemrb/override/how/spklarbl.pro
rename to gemrb/unhardcoded/how/spklarbl.pro
diff --git a/gemrb/override/how/spklarch.pro b/gemrb/unhardcoded/how/spklarch.pro
similarity index 100%
rename from gemrb/override/how/spklarch.pro
rename to gemrb/unhardcoded/how/spklarch.pro
diff --git a/gemrb/override/how/spklargo.pro b/gemrb/unhardcoded/how/spklargo.pro
similarity index 100%
rename from gemrb/override/how/spklargo.pro
rename to gemrb/unhardcoded/how/spklargo.pro
diff --git a/gemrb/override/how/spklargr.pro b/gemrb/unhardcoded/how/spklargr.pro
similarity index 100%
rename from gemrb/override/how/spklargr.pro
rename to gemrb/unhardcoded/how/spklargr.pro
diff --git a/gemrb/override/how/spklaric.pro b/gemrb/unhardcoded/how/spklaric.pro
similarity index 100%
rename from gemrb/override/how/spklaric.pro
rename to gemrb/unhardcoded/how/spklaric.pro
diff --git a/gemrb/override/how/spklarma.pro b/gemrb/unhardcoded/how/spklarma.pro
similarity index 100%
rename from gemrb/override/how/spklarma.pro
rename to gemrb/unhardcoded/how/spklarma.pro
diff --git a/gemrb/override/how/spklaror.pro b/gemrb/unhardcoded/how/spklaror.pro
similarity index 100%
rename from gemrb/override/how/spklaror.pro
rename to gemrb/unhardcoded/how/spklaror.pro
diff --git a/gemrb/override/how/spklarpu.pro b/gemrb/unhardcoded/how/spklarpu.pro
similarity index 100%
rename from gemrb/override/how/spklarpu.pro
rename to gemrb/unhardcoded/how/spklarpu.pro
diff --git a/gemrb/override/how/spklarre.pro b/gemrb/unhardcoded/how/spklarre.pro
similarity index 100%
rename from gemrb/override/how/spklarre.pro
rename to gemrb/unhardcoded/how/spklarre.pro
diff --git a/gemrb/override/how/spklarst.pro b/gemrb/unhardcoded/how/spklarst.pro
similarity index 100%
rename from gemrb/override/how/spklarst.pro
rename to gemrb/unhardcoded/how/spklarst.pro
diff --git a/gemrb/override/how/splprot.2da b/gemrb/unhardcoded/how/splprot.2da
similarity index 100%
rename from gemrb/override/how/splprot.2da
rename to gemrb/unhardcoded/how/splprot.2da
diff --git a/gemrb/override/how/splspec.2da b/gemrb/unhardcoded/how/splspec.2da
similarity index 100%
rename from gemrb/override/how/splspec.2da
rename to gemrb/unhardcoded/how/splspec.2da
diff --git a/gemrb/override/how/spoisoh.pro b/gemrb/unhardcoded/how/spoisoh.pro
similarity index 100%
rename from gemrb/override/how/spoisoh.pro
rename to gemrb/unhardcoded/how/spoisoh.pro
diff --git a/gemrb/override/how/spscorch.pro b/gemrb/unhardcoded/how/spscorch.pro
similarity index 100%
rename from gemrb/override/how/spscorch.pro
rename to gemrb/unhardcoded/how/spscorch.pro
diff --git a/gemrb/override/how/spscoric.pro b/gemrb/unhardcoded/how/spscoric.pro
similarity index 100%
rename from gemrb/override/how/spscoric.pro
rename to gemrb/unhardcoded/how/spscoric.pro
diff --git a/gemrb/override/how/spwrath.pro b/gemrb/unhardcoded/how/spwrath.pro
similarity index 100%
rename from gemrb/override/how/spwrath.pro
rename to gemrb/unhardcoded/how/spwrath.pro
diff --git a/gemrb/override/how/ssorbh.pro b/gemrb/unhardcoded/how/ssorbh.pro
similarity index 100%
rename from gemrb/override/how/ssorbh.pro
rename to gemrb/unhardcoded/how/ssorbh.pro
diff --git a/gemrb/override/how/ssswarm.pro b/gemrb/unhardcoded/how/ssswarm.pro
similarity index 100%
rename from gemrb/override/how/ssswarm.pro
rename to gemrb/unhardcoded/how/ssswarm.pro
diff --git a/gemrb/override/how/sstone.pro b/gemrb/unhardcoded/how/sstone.pro
similarity index 100%
rename from gemrb/override/how/sstone.pro
rename to gemrb/unhardcoded/how/sstone.pro
diff --git a/gemrb/override/how/sstoneh.pro b/gemrb/unhardcoded/how/sstoneh.pro
similarity index 100%
rename from gemrb/override/how/sstoneh.pro
rename to gemrb/unhardcoded/how/sstoneh.pro
diff --git a/gemrb/override/how/start.2da b/gemrb/unhardcoded/how/start.2da
similarity index 100%
rename from gemrb/override/how/start.2da
rename to gemrb/unhardcoded/how/start.2da
diff --git a/gemrb/override/how/stone.pro b/gemrb/unhardcoded/how/stone.pro
similarity index 100%
rename from gemrb/override/how/stone.pro
rename to gemrb/unhardcoded/how/stone.pro
diff --git a/gemrb/override/how/strengh.pro b/gemrb/unhardcoded/how/strengh.pro
similarity index 100%
rename from gemrb/override/how/strengh.pro
rename to gemrb/unhardcoded/how/strengh.pro
diff --git a/gemrb/unhardcoded/how/strings.2da b/gemrb/unhardcoded/how/strings.2da
new file mode 100644
index 0000000..485f411
--- /dev/null
+++ b/gemrb/unhardcoded/how/strings.2da
@@ -0,0 +1,187 @@
+2DA V1.0
+-1
+ STRREF
+SCATTERED 16457
+WHOLEPARTY 16484
+DOORLOCKED 16485
+MAGICTRAP 16486
+NORMALTRAP 16487
+TRAP 16488
+CANNOTGO 16489
+TRAPREMOVED 16490
+OVERSTOCKED 16491
+SLEEP 16492
+AMBUSH 16493
+CONTLOCKED 16494
+NOMONEY 16495
+CURSED 16304
+SPELLDISRUPT 16497
+DIED 16498
+MAYNOTREST 16499
+CANTRESTMONS 16500
+CANTSAVEMONS 16501
+CANTSAVE 16502
+NODIALOG 10945
+CANTSAVEDIALOG 19253
+CANTSAVEDIALOG2 19254
+CANTSAVEMOVIE 19255
+TARGETBUSY -1
+CANTTALKTRANS -1
+GOTGOLD 17572
+LOSTGOLD 17573
+GOTXP 17574
+LOSTXP 17575
+GOTITEM 17576
+LOSTITEM 17577
+GOTREP 19686
+LOSTREP 19687
+GOTABILITY 10514
+GOTSPELL 10514
+GOTSONG 26320
+NOTHINGTOSAY -1
+JOURNALCHANGE 11359
+WORLDMAPCHANGE 11360
+PAUSED 16321
+UNPAUSED 16322
+SCRIPTPAUSED 7666
+AP_UNUSABLE 17113
+AP_ATTACKED 17114
+AP_HIT 17115
+AP_WOUNDED 17116
+AP_DEAD 17117
+AP_NOTARGET 17118
+AP_ENDROUND 10014
+AP_ENEMY 23511
+AP_TRAP -1
+AP_SPELLCAST -1
+AP_GENERIC 17166
+AP_RESERVED1 -1
+AP_RESERVED2 -1
+AP_RESERVED3 -1
+CHARMED 14672
+DIRECHARMED 14780
+CONTROLLED -1
+EVIL 16505
+GNE_NEUTRAL 16504
+GOOD 16503
+STR_LAWFUL -1
+LNC_NEUTRAL -1
+CHAOTIC -1
+ACTION_CAST 16464
+ACTION_ATTACK 16465
+ACTION_TURN 16466
+ACTION_SONG 16467
+ACTION_FINDTRAP 16468
+MAGICWEAPON 10141
+OFFHAND_USED 9380
+TWOHANDED_USED 9381
+CANNOT_USE_ITEM 9382
+CANT_DROP_ITEM 25697
+NOT_IN_OFFHAND 26342
+ITEM_IS_CURSED 16304
+NO_CRITICAL 20696
+TRACKING -1
+TRACKINGFAILED 19534
+DOOR_NOPICK 23169
+CONT_NOPICK 23169
+CANTSAVECOMBAT -1
+CANTSAVENOCTRL -1
+LOCKPICK_DONE 16517
+LOCKPICK_FAILED 16518
+STATIC_DISSIPATE 26518
+LIGHTNING_DISSIPATE -1
+HAS_NO_ABILITY 17317
+NEEDS_IDENTIFY 17316
+WRONG_ITEMTYPE 9375
+HAS_ITEMEXCL 20685
+PICKPOCKET_DONE 10072
+PICKPOCKET_NONE 18297
+PICKPOCKET_FAIL 10069
+PICKPOCKET_EVIL 10068
+PICKPOCKET_ARMOR 10067
+USING_FEAT -1
+STOPPED_FEAT -1
+DISARM_DONE 16520
+DISARM_FAIL 1608
+DOORBASH_DONE 9915
+DOORBASH_FAIL 9913
+CONTBASH_DONE 9916
+CONTBASH_FAIL 9914
+MAYNOTSETTRAP -1
+SNAREFAILED -1
+SNARESUCCEED -1
+NOMORETRAP -1
+DISABLEDMAGE -1
+SAVESUCCEED 1682
+QSAVESUCCEED 10237
+UNINJURED 2943
+INJURED1 2944
+INJURED2 2945
+INJURED3 2946
+INJURED4 2947
+HOURS 10700
+HOUR 10701
+DAYS 10697
+DAY 10698
+REST 10690
+JOURNEY 10689
+SUMMONINGLIMIT -1
+INVFULL 17999
+TOOFARAWAY 18002
+DAMAGE_IMMUNITY 25038
+DAMAGE_STR1 25028
+DAMAGE_STR2 25017
+DAMAGE_STR3 26223
+DMG_POISON 25018
+DMG_MAGIC 25019
+DMG_MISSILE 25020
+DMG_SLASHING 25021
+DMG_PIERCING 25022
+DMG_CRUSHING 25023
+DMG_FIRE 25024
+DMG_ELECTRIC 25025
+DMG_COLD 25026
+DMG_ACID 25027
+DMG_OTHER 0
+GOTQUESTXP -1
+LEVELUP 17119
+INVFULL_ITEMDROP 32879
+CONT_DUP 32876
+CONT_TRIG -1
+CONT_FAIL -1
+SEQ_DUP -1
+CRITICAL_HIT 16462
+CRITICAL_MISS 16463
+DEATH 14026
+BACKSTAB 12128
+BACKSTAB_BAD 10013
+BACKSTAB_FAIL -1
+CASTER_LVL_INC -1
+CASTER_LVL_DEC -1
+CHARS_EXPORTED 26827
+PALADIN_FALL 19620
+RANGER_FALL 19621
+RES_RESISTED 26818
+DEADMAGIC_FAIL -1
+MISCASTMAGIC -1
+WILDSURGE -1
+FAMBLOCK 8537
+FAMPROTAGONIST 8538
+MAGIC_RESISTED 19224
+CANTSAVESTORE 10841
+NOSEE_NOCAST -1
+AURACLEANSED 23797
+INDOOR_FAIL 9744
+SPELL_DISRUPTED 14796
+CHAOSSHIELD -1
+RAPIDSHOT -1
+HAMSTRING -1
+ARTERIAL -1
+EXPERTISE -1
+POWERATTACK -1
+CLEAVE -1
+HELD 14102
+SLOWED 19503
+CANTMOVE 19504
+CASTS -1
+WEAPONINEFFECTIVE -1
diff --git a/gemrb/override/how/suffoc.pro b/gemrb/unhardcoded/how/suffoc.pro
similarity index 100%
rename from gemrb/override/how/suffoc.pro
rename to gemrb/unhardcoded/how/suffoc.pro
diff --git a/gemrb/override/how/suffoch.pro b/gemrb/unhardcoded/how/suffoch.pro
similarity index 100%
rename from gemrb/override/how/suffoch.pro
rename to gemrb/unhardcoded/how/suffoch.pro
diff --git a/gemrb/override/how/sunfire.pro b/gemrb/unhardcoded/how/sunfire.pro
similarity index 100%
rename from gemrb/override/how/sunfire.pro
rename to gemrb/unhardcoded/how/sunfire.pro
diff --git a/gemrb/override/how/sunray.pro b/gemrb/unhardcoded/how/sunray.pro
similarity index 100%
rename from gemrb/override/how/sunray.pro
rename to gemrb/unhardcoded/how/sunray.pro
diff --git a/gemrb/override/how/sunscoh.pro b/gemrb/unhardcoded/how/sunscoh.pro
similarity index 100%
rename from gemrb/override/how/sunscoh.pro
rename to gemrb/unhardcoded/how/sunscoh.pro
diff --git a/gemrb/override/how/swave.pro b/gemrb/unhardcoded/how/swave.pro
similarity index 100%
rename from gemrb/override/how/swave.pro
rename to gemrb/unhardcoded/how/swave.pro
diff --git a/gemrb/override/how/swaveh.pro b/gemrb/unhardcoded/how/swaveh.pro
similarity index 100%
rename from gemrb/override/how/swaveh.pro
rename to gemrb/unhardcoded/how/swaveh.pro
diff --git a/gemrb/override/how/trapglyp.pro b/gemrb/unhardcoded/how/trapglyp.pro
similarity index 100%
rename from gemrb/override/how/trapglyp.pro
rename to gemrb/unhardcoded/how/trapglyp.pro
diff --git a/gemrb/override/how/trapskul.pro b/gemrb/unhardcoded/how/trapskul.pro
similarity index 100%
rename from gemrb/override/how/trapskul.pro
rename to gemrb/unhardcoded/how/trapskul.pro
diff --git a/gemrb/override/how/tspray.pro b/gemrb/unhardcoded/how/tspray.pro
similarity index 100%
rename from gemrb/override/how/tspray.pro
rename to gemrb/unhardcoded/how/tspray.pro
diff --git a/gemrb/override/how/turn.spl b/gemrb/unhardcoded/how/turn.spl
similarity index 100%
rename from gemrb/override/how/turn.spl
rename to gemrb/unhardcoded/how/turn.spl
diff --git a/gemrb/override/how/ublight.pro b/gemrb/unhardcoded/how/ublight.pro
similarity index 100%
rename from gemrb/override/how/ublight.pro
rename to gemrb/unhardcoded/how/ublight.pro
diff --git a/gemrb/override/how/uward.pro b/gemrb/unhardcoded/how/uward.pro
similarity index 100%
rename from gemrb/override/how/uward.pro
rename to gemrb/unhardcoded/how/uward.pro
diff --git a/gemrb/override/how/uwardh.pro b/gemrb/unhardcoded/how/uwardh.pro
similarity index 100%
rename from gemrb/override/how/uwardh.pro
rename to gemrb/unhardcoded/how/uwardh.pro
diff --git a/gemrb/unhardcoded/how/vcremap.2da b/gemrb/unhardcoded/how/vcremap.2da
new file mode 100644
index 0000000..f6cce8f
--- /dev/null
+++ b/gemrb/unhardcoded/how/vcremap.2da
@@ -0,0 +1,32 @@
+2DA V1.0
+*
+ ORIGINAL NEW
+BCRY 9 3
+2 10 4
+3 11 5
+4 12 6
+5 13 7
+LEAD 6 8
+TIRE 7 10
+BORE 8 13
+DMG 20 14
+SEL 26 16
+2 27 17
+3 28 18
+4 29 19
+5 30 20
+6 31 21
+ACT 32 23
+2 33 24
+3 34 25
+4 35 26
+5 36 27
+6 37 28
+7 38 29
+RARE1 63 30
+RARE2 64 31
+HIT 18 34
+DYING 19 37
+REACT 53 39
+2 54 40
+BIO 74 63
diff --git a/gemrb/override/how/vspherh.pro b/gemrb/unhardcoded/how/vspherh.pro
similarity index 100%
rename from gemrb/override/how/vspherh.pro
rename to gemrb/unhardcoded/how/vspherh.pro
diff --git a/gemrb/override/how/wdeath1.pro b/gemrb/unhardcoded/how/wdeath1.pro
similarity index 100%
rename from gemrb/override/how/wdeath1.pro
rename to gemrb/unhardcoded/how/wdeath1.pro
diff --git a/gemrb/override/how/wdeath2.pro b/gemrb/unhardcoded/how/wdeath2.pro
similarity index 100%
rename from gemrb/override/how/wdeath2.pro
rename to gemrb/unhardcoded/how/wdeath2.pro
diff --git a/gemrb/override/how/weapprof.2da b/gemrb/unhardcoded/how/weapprof.2da
similarity index 100%
rename from gemrb/override/how/weapprof.2da
rename to gemrb/unhardcoded/how/weapprof.2da
diff --git a/gemrb/override/how/web.pro b/gemrb/unhardcoded/how/web.pro
similarity index 100%
rename from gemrb/override/how/web.pro
rename to gemrb/unhardcoded/how/web.pro
diff --git a/gemrb/override/how/whirlw.pro b/gemrb/unhardcoded/how/whirlw.pro
similarity index 100%
rename from gemrb/override/how/whirlw.pro
rename to gemrb/unhardcoded/how/whirlw.pro
diff --git a/gemrb/override/how/womoon.pro b/gemrb/unhardcoded/how/womoon.pro
similarity index 100%
rename from gemrb/override/how/womoon.pro
rename to gemrb/unhardcoded/how/womoon.pro
diff --git a/gemrb/override/how/wowisp.pro b/gemrb/unhardcoded/how/wowisp.pro
similarity index 100%
rename from gemrb/override/how/wowisp.pro
rename to gemrb/unhardcoded/how/wowisp.pro
diff --git a/gemrb/override/how/wvdeath.pro b/gemrb/unhardcoded/how/wvdeath.pro
similarity index 100%
rename from gemrb/override/how/wvdeath.pro
rename to gemrb/unhardcoded/how/wvdeath.pro
diff --git a/gemrb/override/how/wvhith.pro b/gemrb/unhardcoded/how/wvhith.pro
similarity index 100%
rename from gemrb/override/how/wvhith.pro
rename to gemrb/unhardcoded/how/wvhith.pro
diff --git a/gemrb/override/how/wwolf.pro b/gemrb/unhardcoded/how/wwolf.pro
similarity index 100%
rename from gemrb/override/how/wwolf.pro
rename to gemrb/unhardcoded/how/wwolf.pro
diff --git a/gemrb/override/how/zlaura.pro b/gemrb/unhardcoded/how/zlaura.pro
similarity index 100%
rename from gemrb/override/how/zlaura.pro
rename to gemrb/unhardcoded/how/zlaura.pro
diff --git a/gemrb/unhardcoded/iwd/Makefile.am b/gemrb/unhardcoded/iwd/Makefile.am
new file mode 100644
index 0000000..f34f31a
--- /dev/null
+++ b/gemrb/unhardcoded/iwd/Makefile.am
@@ -0,0 +1,3 @@
+iwdunhardcoded_DATA = *.2da *.bmp *.ini *.chu *.ids *.pro *.spl
+iwdunhardcodeddir = $(moddir)/unhardcoded/iwd/
+EXTRA_DIST = *.2da *.bmp *.ini *.chu *.ids *.pro *.spl
diff --git a/gemrb/override/iwd/ability.2da b/gemrb/unhardcoded/iwd/ability.2da
similarity index 100%
rename from gemrb/override/iwd/ability.2da
rename to gemrb/unhardcoded/iwd/ability.2da
diff --git a/gemrb/override/iwd/abjurap.pro b/gemrb/unhardcoded/iwd/abjurap.pro
similarity index 100%
rename from gemrb/override/iwd/abjurap.pro
rename to gemrb/unhardcoded/iwd/abjurap.pro
diff --git a/gemrb/override/iwd/abjurh.pro b/gemrb/unhardcoded/iwd/abjurh.pro
similarity index 100%
rename from gemrb/override/iwd/abjurh.pro
rename to gemrb/unhardcoded/iwd/abjurh.pro
diff --git a/gemrb/override/iwd/abjurt.pro b/gemrb/unhardcoded/iwd/abjurt.pro
similarity index 100%
rename from gemrb/override/iwd/abjurt.pro
rename to gemrb/unhardcoded/iwd/abjurt.pro
diff --git a/gemrb/override/iwd/acidblgr.pro b/gemrb/unhardcoded/iwd/acidblgr.pro
similarity index 100%
rename from gemrb/override/iwd/acidblgr.pro
rename to gemrb/unhardcoded/iwd/acidblgr.pro
diff --git a/gemrb/override/iwd/acidblmu.pro b/gemrb/unhardcoded/iwd/acidblmu.pro
similarity index 100%
rename from gemrb/override/iwd/acidblmu.pro
rename to gemrb/unhardcoded/iwd/acidblmu.pro
diff --git a/gemrb/override/iwd/acidblob.pro b/gemrb/unhardcoded/iwd/acidblob.pro
similarity index 100%
rename from gemrb/override/iwd/acidblob.pro
rename to gemrb/unhardcoded/iwd/acidblob.pro
diff --git a/gemrb/override/iwd/acidbloc.pro b/gemrb/unhardcoded/iwd/acidbloc.pro
similarity index 100%
rename from gemrb/override/iwd/acidbloc.pro
rename to gemrb/unhardcoded/iwd/acidbloc.pro
diff --git a/gemrb/override/iwd/acidh.pro b/gemrb/unhardcoded/iwd/acidh.pro
similarity index 100%
rename from gemrb/override/iwd/acidh.pro
rename to gemrb/unhardcoded/iwd/acidh.pro
diff --git a/gemrb/override/iwd/adhwil.pro b/gemrb/unhardcoded/iwd/adhwil.pro
similarity index 100%
rename from gemrb/override/iwd/adhwil.pro
rename to gemrb/unhardcoded/iwd/adhwil.pro
diff --git a/gemrb/override/iwd/adhwilh.pro b/gemrb/unhardcoded/iwd/adhwilh.pro
similarity index 100%
rename from gemrb/override/iwd/adhwilh.pro
rename to gemrb/unhardcoded/iwd/adhwilh.pro
diff --git a/gemrb/override/iwd/alance.pro b/gemrb/unhardcoded/iwd/alance.pro
similarity index 100%
rename from gemrb/override/iwd/alance.pro
rename to gemrb/unhardcoded/iwd/alance.pro
diff --git a/gemrb/override/iwd/aligns.2da b/gemrb/unhardcoded/iwd/aligns.2da
similarity index 100%
rename from gemrb/override/iwd/aligns.2da
rename to gemrb/unhardcoded/iwd/aligns.2da
diff --git a/gemrb/override/iwd/altera.pro b/gemrb/unhardcoded/iwd/altera.pro
similarity index 100%
rename from gemrb/override/iwd/altera.pro
rename to gemrb/unhardcoded/iwd/altera.pro
diff --git a/gemrb/override/iwd/alteranp.pro b/gemrb/unhardcoded/iwd/alteranp.pro
similarity index 100%
rename from gemrb/override/iwd/alteranp.pro
rename to gemrb/unhardcoded/iwd/alteranp.pro
diff --git a/gemrb/override/iwd/alterap.pro b/gemrb/unhardcoded/iwd/alterap.pro
similarity index 100%
rename from gemrb/override/iwd/alterap.pro
rename to gemrb/unhardcoded/iwd/alterap.pro
diff --git a/gemrb/override/iwd/alteras.pro b/gemrb/unhardcoded/iwd/alteras.pro
similarity index 100%
rename from gemrb/override/iwd/alteras.pro
rename to gemrb/unhardcoded/iwd/alteras.pro
diff --git a/gemrb/override/iwd/alterh.pro b/gemrb/unhardcoded/iwd/alterh.pro
similarity index 100%
rename from gemrb/override/iwd/alterh.pro
rename to gemrb/unhardcoded/iwd/alterh.pro
diff --git a/gemrb/override/iwd/altert.pro b/gemrb/unhardcoded/iwd/altert.pro
similarity index 100%
rename from gemrb/override/iwd/altert.pro
rename to gemrb/unhardcoded/iwd/altert.pro
diff --git a/gemrb/override/iwd/area1np.pro b/gemrb/unhardcoded/iwd/area1np.pro
similarity index 100%
rename from gemrb/override/iwd/area1np.pro
rename to gemrb/unhardcoded/iwd/area1np.pro
diff --git a/gemrb/override/iwd/area1p.pro b/gemrb/unhardcoded/iwd/area1p.pro
similarity index 100%
rename from gemrb/override/iwd/area1p.pro
rename to gemrb/unhardcoded/iwd/area1p.pro
diff --git a/gemrb/override/iwd/area2.pro b/gemrb/unhardcoded/iwd/area2.pro
similarity index 100%
rename from gemrb/override/iwd/area2.pro
rename to gemrb/unhardcoded/iwd/area2.pro
diff --git a/gemrb/override/iwd/area2np.pro b/gemrb/unhardcoded/iwd/area2np.pro
similarity index 100%
rename from gemrb/override/iwd/area2np.pro
rename to gemrb/unhardcoded/iwd/area2np.pro
diff --git a/gemrb/override/iwd/area3p.pro b/gemrb/unhardcoded/iwd/area3p.pro
similarity index 100%
rename from gemrb/override/iwd/area3p.pro
rename to gemrb/unhardcoded/iwd/area3p.pro
diff --git a/gemrb/override/iwd/area4np.pro b/gemrb/unhardcoded/iwd/area4np.pro
similarity index 100%
rename from gemrb/override/iwd/area4np.pro
rename to gemrb/unhardcoded/iwd/area4np.pro
diff --git a/gemrb/override/iwd/armorh.pro b/gemrb/unhardcoded/iwd/armorh.pro
similarity index 100%
rename from gemrb/override/iwd/armorh.pro
rename to gemrb/unhardcoded/iwd/armorh.pro
diff --git a/gemrb/override/iwd/arrow.pro b/gemrb/unhardcoded/iwd/arrow.pro
similarity index 100%
rename from gemrb/override/iwd/arrow.pro
rename to gemrb/unhardcoded/iwd/arrow.pro
diff --git a/gemrb/override/iwd/arrowex.pro b/gemrb/unhardcoded/iwd/arrowex.pro
similarity index 100%
rename from gemrb/override/iwd/arrowex.pro
rename to gemrb/unhardcoded/iwd/arrowex.pro
diff --git a/gemrb/override/iwd/arrowflb.pro b/gemrb/unhardcoded/iwd/arrowflb.pro
similarity index 100%
rename from gemrb/override/iwd/arrowflb.pro
rename to gemrb/unhardcoded/iwd/arrowflb.pro
diff --git a/gemrb/override/iwd/arrowflg.pro b/gemrb/unhardcoded/iwd/arrowflg.pro
similarity index 100%
rename from gemrb/override/iwd/arrowflg.pro
rename to gemrb/unhardcoded/iwd/arrowflg.pro
diff --git a/gemrb/override/iwd/arrowfli.pro b/gemrb/unhardcoded/iwd/arrowfli.pro
similarity index 100%
rename from gemrb/override/iwd/arrowfli.pro
rename to gemrb/unhardcoded/iwd/arrowfli.pro
diff --git a/gemrb/override/iwd/arrowflm.pro b/gemrb/unhardcoded/iwd/arrowflm.pro
similarity index 100%
rename from gemrb/override/iwd/arrowflm.pro
rename to gemrb/unhardcoded/iwd/arrowflm.pro
diff --git a/gemrb/override/iwd/arrowhvy.pro b/gemrb/unhardcoded/iwd/arrowhvy.pro
similarity index 100%
rename from gemrb/override/iwd/arrowhvy.pro
rename to gemrb/unhardcoded/iwd/arrowhvy.pro
diff --git a/gemrb/override/iwd/ascorch.pro b/gemrb/unhardcoded/iwd/ascorch.pro
similarity index 100%
rename from gemrb/override/iwd/ascorch.pro
rename to gemrb/unhardcoded/iwd/ascorch.pro
diff --git a/gemrb/override/iwd/astorm.pro b/gemrb/unhardcoded/iwd/astorm.pro
similarity index 100%
rename from gemrb/override/iwd/astorm.pro
rename to gemrb/unhardcoded/iwd/astorm.pro
diff --git a/gemrb/override/iwd/asumm1.pro b/gemrb/unhardcoded/iwd/asumm1.pro
similarity index 100%
rename from gemrb/override/iwd/asumm1.pro
rename to gemrb/unhardcoded/iwd/asumm1.pro
diff --git a/gemrb/override/iwd/asumm1h.pro b/gemrb/unhardcoded/iwd/asumm1h.pro
similarity index 100%
rename from gemrb/override/iwd/asumm1h.pro
rename to gemrb/unhardcoded/iwd/asumm1h.pro
diff --git a/gemrb/override/iwd/asumm1x.pro b/gemrb/unhardcoded/iwd/asumm1x.pro
similarity index 100%
rename from gemrb/override/iwd/asumm1x.pro
rename to gemrb/unhardcoded/iwd/asumm1x.pro
diff --git a/gemrb/override/iwd/asumm2h.pro b/gemrb/unhardcoded/iwd/asumm2h.pro
similarity index 100%
rename from gemrb/override/iwd/asumm2h.pro
rename to gemrb/unhardcoded/iwd/asumm2h.pro
diff --git a/gemrb/override/iwd/asumm3h.pro b/gemrb/unhardcoded/iwd/asumm3h.pro
similarity index 100%
rename from gemrb/override/iwd/asumm3h.pro
rename to gemrb/unhardcoded/iwd/asumm3h.pro
diff --git a/gemrb/unhardcoded/iwd/avatars.2da b/gemrb/unhardcoded/iwd/avatars.2da
new file mode 100644
index 0000000..c25d308
--- /dev/null
+++ b/gemrb/unhardcoded/iwd/avatars.2da
@@ -0,0 +1,414 @@
+2DA V1.0
+*
+ AT_1 AT_2 AT_3 AT_4 TYPE SPACE PALETTE SIZE
+0x0100 SPCHUNKS SPCHUNKS SPCHUNKS SPCHUNKS 13 0 0 *
+0x0300 SPSMPUFF SPSMPUFF SPSMPUFF SPSMPUFF 13 0 0 *
+0x0400 SKLH SKLH SKLH SKLH 13 0 1 *
+0x0410 GLPHWRDH GLPHWRDH GLPHWRDH GLPHWRDH 13 0 1 *
+0x1000 MWYV MWYV MWYV MWYV 11 5 1 *
+0x1001 MWYV MWYV MWYV MWYV 11 5 1 *
+0x1100 MTAN MTAN MTAN MTAN 11 5 1 *
+0x1200 MDR1 MDR1 MDR1 MDR1 12 5 1 *
+0x1201 MDR2 MDR2 MDR2 MDR2 12 5 1 *
+0x1202 MDR3 MDR3 MDR3 MDR3 12 5 1 *
+0x1203 MDR1 MDR1 MDR1 MDR1 12 7 GR *
+0x1204 MDR1 MDR1 MDR1 MDR1 12 7 AQ *
+0x1205 MDR1 MDR1 MDR1 MDR1 12 7 BL *
+0x1206 MDR1 MDR1 MDR1 MDR1 12 7 BR *
+0x1207 MDR1 MDR1 MDR1 MDR1 12 7 MC *
+0x1208 MDR1 MDR1 MDR1 MDR1 12 7 PU *
+0x2000 MSIR MSIR MSIR MSIR 2 2 0 *
+0x2100 UVOL UVOL UVOL UVOL 2 2 1 *
+0x2200 MOGM MOGM MOGM MOGM 2 2 0 S
+0x2300 MDKN MDKN MDKN MDKN 2 2 1 *
+0x3000 MAKH MAKH MAKH MAKH 2 3 1 *
+0x4000 SNOMC SNOMC SNOMC SNOMC 1 2 0 *
+0x4002 SNOMM SNOMM SNOMM SNOMM 1 2 0 *
+0x4010 SNOWC SNOWC SNOWC SNOWC 1 2 0 *
+0x4012 SNOWM SNOWM SNOWM SNOWM 1 2 0 *
+0x4100 SSIMC SSIMC SSIMC SSIMC 1 2 0 *
+0x4101 SSIMS SSIMS SSIMS SSIMS 1 2 0 *
+0x4102 SSIMM SSIMM SSIMM SSIMM 1 2 0 *
+0x4110 SSIWC SSIWC SSIWC SSIWC 1 2 0 *
+0x4112 SSIWM SSIWM SSIWM SSIWM 1 2 0 *
+0x4200 SHMCM SHMCM SHMCM SHMCM 1 2 0 *
+0x4300 MSPLG1 MSPLG1 MSPLG1 MSPLG1 1 2 1 *
+0x4400 LHMC LHMC LHMC LHMC 1 2 0 *
+0x4410 LHFC LHFC LHFC LHFC 1 2 0 *
+0x4500 LFAM LFAM LFAM LFAM 1 2 0 *
+0x4600 LDMF LDMF LDMF LDMF 1 2 0 *
+0x4700 LEMF LEMF LEMF LEMF 1 2 0 *
+0x4710 LEFF LEFF LEFF LEFF 1 2 0 *
+0x4800 LIMC LIMC LIMC LIMC 1 2 0 *
+0x5000 CHMC1 CHMC2 CHMC3 CHMC4 6 2 0 L
+0x5001 CEMC1 CEMC2 CEMC3 CEMC4 6 2 0 M
+0x5002 CDMC1 CDMC2 CDMC3 CDMC4 6 2 0 S
+0x5003 CIMC1 CIMC2 CIMC3 CIMC4 6 2 0 S
+0x5010 CHFC1 CHFC2 CHFC3 CHFC4 6 2 0 M
+0x5011 CEFC1 CEFC2 CEFC3 CEFC4 6 2 0 M
+0x5012 CDMC1 CDMC2 CDMC3 CDMC4 6 2 0 S
+0x5013 CIFC1 CIFC2 CIFC3 CIFC4 6 2 0 S
+0x5100 CHMF1 CHMF2 CHMF3 CHMF4 6 2 0 L
+0x5101 CEMF1 CEMF2 CEMF3 CHMF4 6 2 0 M
+0x5102 CDMF1 CDMF2 CDMF3 CDMF4 6 2 0 S
+0x5103 CIMF1 CIMF2 CIMF3 CIMF4 6 2 0 S
+0x5110 CHFF1 CHFF2 CHFF3 CHFF4 6 2 0 M
+0x5111 CEFF1 CEFF2 CEFF3 CEFF4 6 2 0 M
+0x5112 CDMF1 CDMF2 CDMF3 CDMF4 6 2 0 S
+0x5113 CIFF1 CIFF2 CIFF3 CIFF4 6 2 0 S
+0x5200 CHMW1 CHMW2 CHMW3 CHMW4 6 2 0 L
+0x5201 CEMW1 CEMW2 CEMW3 CEMW4 6 2 0 M
+0x5202 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
+0x5203 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
+0x5210 CHFW1 CHFW2 CHFW3 CHFW4 6 2 0 M
+0x5211 CEFW1 CEFW2 CEFW3 CEFW4 6 2 0 M
+0x5212 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
+0x5213 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
+0x5300 CHMT1 CHMT2 CHMT2 CHMT2 6 2 0 L
+0x5301 CEMT1 CEMT2 CEMT2 CEMT2 6 2 0 M
+0x5302 CDMT1 CDMT2 CDMT2 CDMT2 6 2 0 S
+0x5303 CIMT1 CIMT2 CIMT2 CIMT2 6 2 0 S
+0x5310 CHFT1 CHFT2 CHFT2 CHFT2 6 2 0 M
+0x5311 CEFT1 CEFT2 CEFT2 CEFT2 6 2 0 M
+0x5312 CDMT1 CDMT2 CDMT2 CDMT2 6 2 0 S
+0x5313 CIFT1 CIFT2 CIFT2 CIFT2 6 2 0 S
+0x6000 CHMC1 CHMC2 CHMC3 CHMC4 6 2 0 L
+0x6001 CEMC1 CEMC2 CEMC3 CEMC4 6 2 0 M
+0x6002 CDMC1 CDMC2 CDMC3 CDMC4 6 2 0 S
+0x6003 CIMC1 CIMC2 CIMC3 CIMC4 6 2 0 S
+0x6010 CHFC1 CHFC2 CHFC3 CHFC4 6 2 0 M
+0x6011 CEFC1 CEFC2 CEFC3 CEFC4 6 2 0 M
+0x6012 CDMC1 CDMC2 CDMC3 CDMC4 6 2 0 S
+0x6013 CIFC1 CIFC2 CIFC3 CIFC4 6 2 0 S
+0x6100 CHMF1 CHMF2 CHMF3 CHMF4 6 2 0 L
+0x6101 CEMF1 CEMF2 CEMF3 CEMF4 6 2 0 M
+0x6102 CDMF1 CDMF2 CDMF3 CDMF4 6 2 0 S
+0x6103 CIMF1 CIMF2 CIMF3 CIMF4 6 2 0 S
+0x6110 CHFF1 CHFF2 CHFF3 CHFF4 6 2 0 M
+0x6111 CEFF1 CEFF2 CEFF3 CEFF4 6 2 0 M
+0x6112 CDMF1 CDMF2 CDMF3 CDMF4 6 2 0 S
+0x6113 CIFF1 CIFF2 CIFF3 CIFF4 6 2 0 S
+0x6200 CHMW1 CHMW2 CHMW3 CHMW4 6 2 0 L
+0x6201 CEMW1 CEMW2 CEMW3 CEMW4 6 2 0 M
+0x6202 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
+0x6203 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
+0x6210 CHFW1 CHFW2 CHFW3 CHFW4 6 2 0 M
+0x6211 CEFW1 CEFW2 CEFW3 CEFW4 6 2 0 M
+0x6212 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
+0x6213 CDMW1 CDMW2 CDMW3 CDMW4 6 2 0 S
+0x6300 CHMT1 CHMT2 CHMT2 CHMT2 6 2 0 L
+0x6301 CEMT1 CEMT2 CEMT2 CEMT2 6 2 0 M
+0x6302 CDMT1 CDMT2 CDMT2 CDMT2 6 2 0 S
+0x6303 CIMT1 CIMT2 CIMT2 CIMT2 6 2 0 S
+0x6310 CHFT1 CHFT2 CHFT2 CHFT2 6 2 0 M
+0x6311 CEFT1 CEFT2 CEFT2 CEFT2 6 2 0 M
+0x6312 CDMT1 CDMT2 CDMT2 CDMT2 6 2 0 S
+0x6313 CIFT1 CIFT2 CIFT2 CIFT2 6 2 0 S
+0x6400 UDRZ1 UDRZ1 UDRZ1 UDRZ1 6 2 0 *
+0x6401 UELM1 UELM1 UELM1 UELM1 6 2 1 *
+0x6402 CMNK1 CMNK1 CMNK1 CMNK1 6 2 0 *
+0x6403 MSKL1 MSKL1 MSKL1 MSKL1 6 2 0 M
+0x6404 USAR1 USAR1 USAR1 USAR1 6 2 1 *
+0x6405 MDGU1 MDGU1 MDGU1 MDGU1 6 2 0 M
+0x6406 MDGU1 MDGU1 MDGU1 MDGU1 6 2 0 L
+0x6500 CHMM1 CHMB2 CHMB3 CHMC4 6 2 0 *
+0x6510 CHFM1 CHFB2 CHFB3 CHFC4 6 2 0 *
+0x7000 MOGH MOGH MOGH MOGH 2 2 0 *
+0x7001 MOGN MOGN MOGN MOGN 2 2 0 *
+0x7100 MBAS MBAS MBAS MBAS 2 2 0 *
+0x7101 MBAS MBAS MBAS MBAS 2 2 GR *
+0x7200 MBER MBER MBER MBER 3 2 BL *
+0x7201 MBER MBER MBER MBER 3 2 1 *
+0x7202 MBER MBER MBER MBER 3 2 CA *
+0x7203 MBER MBER MBER MBER 3 2 PO *
+0x7300 MEAE MEAE MEAE MEAE 4 2 1 *
+0x7301 MEAS MEAS MEAS MEAS 4 2 1 *
+0x7310 MFIE MFIE MFIE MFIE 4 2 1 *
+0x7311 MFIS MFIS MFIS MFIS 4 2 1 *
+0x7320 MAIR MAIR MAIR MAIR 4 2 1 *
+0x7321 MAIS MAIS MAIS MAIS 4 2 1 *
+0x7400 MDOG MDOG MDOG MDOG 2 2 WI *
+0x7401 MDOG MDOG MDOG MDOG 2 2 WA *
+0x7402 MDOG MDOG MDOG MDOG 2 2 MO *
+0x7500 MDOP MDOP MDOP MDOP 3 2 1 *
+0x7501 MDOP MDOP MDOP MDOP 3 2 GR *
+0x7600 METT METT METT METT 2 2 1 *
+0x7701 MGHL MGHL MGHL MGHL 2 2 1 *
+0x7702 MGHL MGHL MGHL MGHL 2 2 RE *
+0x7703 MGHL MGHL MGHL MGHL 2 2 GA *
+0x7704 MSHD MSHD MSHD MSHD 4 2 1 *
+0x7800 MGIB MGIB MGIB MGIB 14 2 1 *
+0x7900 MSLI MSLI MSLI MSLI 3 3 GR *
+0x7901 MSLI MSLI MSLI MSLI 3 3 OL *
+0x7902 MSLI MSLI MSLI MSLI 3 3 MU *
+0x7903 MSLI MSLI MSLI MSLI 3 3 OC *
+0x7904 MSLI MSLI MSLI MSLI 3 3 1 *
+0x7A00 MSPI MSPI MSPI MSPI 3 2 GI *
+0x7A01 MSPI MSPI MSPI MSPI 3 2 HU *
+0x7A02 MSPI MSPI MSPI MSPI 3 2 PH *
+0x7A03 MSPI MSPI MSPI MSPI 3 2 SW *
+0x7A04 MSPI MSPI MSPI MSPI 3 2 WR *
+0x7B00 MWLF MWLF MWLF MWLF 2 2 1 *
+0x7B01 MWLF MWLF MWLF MWLF 2 2 WO *
+0x7B02 MWLF MWLF MWLF MWLF 2 2 DI *
+0x7B03 MWLF MWLF MWLF MWLF 2 2 WI *
+0x7B04 MWLF MWLF MWLF MWLF 2 2 VA *
+0x7B05 MWLF MWLF MWLF MWLF 2 2 DR *
+0x7B06 MWLS MWLS MWLS MWLS 2 2 1 *
+0x7C00 MXVT MXVT MXVT MXVT 2 2 0 *
+0x7C01 MTAS MTAS MTAS MTAS 2 2 0 *
+0x7D00 MZOM MZOM MZOM MZOM 2 2 0 *
+0x7E00 MWER MWER MWER MWER 2 2 1 *
+0x7E01 MGWE MGWE MGWE MGWE 2 2 1 *
+0x7F00 MTRO MTRO MTRO MTRO 4 2 1 *
+0x7F01 MMIN MMIN MMIN MMIN 4 2 1 *
+0x7F02 MBEH MBEH MBEH MBEH 4 3 1 *
+0x7F03 MIMP MIMP MIMP MIMP 4 2 1 *
+0x7F04 MIGO MIGO MIGO MIGO 4 2 1 *
+0x7F05 MDJI MDJI MDJI MDJI 4 2 1 *
+0x7F06 MDJL MDJL MDJL MDJL 4 2 1 *
+0x7F07 MGLC MGLC MGLC MGLC 4 3 1 *
+0x7F08 MOTY MOTY MOTY MOTY 4 4 1 *
+0x7F09 MSAH MSAH MSAH MSAH 4 2 1 *
+0x7F0A MGCP MGCP MGCP MGCP 4 2 1 *
+0x7F0B MGCL MGCL MGCL MGCL 4 2 1 *
+0x7F0C MKUO MKUO MKUO MKUO 4 2 1 *
+0x7F0D MLIC MLIC MLIC MLIC 4 2 1 *
+0x7F0E MDLI MDLI MDLI MDLI 4 2 1 *
+0x7F0F MTRS MTRS MTRS MTRS 4 2 1 *
+0x7F10 MRAK MRAK MRAK MRAK 4 2 1 *
+0x7F11 MUMB MUMB MUMB MUMB 4 2 1 *
+0x7F12 MVAM MVAM MVAM MVAM 4 2 1 *
+0x7F13 MSNK MSNK MSNK MSNK 4 2 1 *
+0x7F14 MGIT MGIT MGIT MGIT 4 2 1 *
+0x7F15 MBES MBES MBES MBES 4 2 1 *
+0x7F16 AMOO AMOO AMOO AMOO 4 3 1 *
+0x7F17 ARAB ARAB ARAB ARAB 4 1 1 *
+0x7F18 ADER ADER ADER ADER 4 2 1 *
+0x7F19 MDSW MDSW MDSW MDSW 4 2 1 *
+0x7F20 AGRO AGRO AGRO AGRO 4 2 1 *
+0x7F21 APHE APHE APHE APHE 4 2 1 *
+0x7F22 MVAF MVAF MVAF MVAF 4 2 1 *
+0x7F23 MSAT MSAT MSAT MSAT 4 3 1 *
+0x7F24 NPIR NPIR NPIR NPIR 4 2 1 *
+0x7F27 MDRO MDRO MDRO MDRO 4 2 1 *
+0x7F28 MKUL MKUL MKUL MKUL 4 3 1 *
+0x7F29 MFDR MFDR MFDR MFDR 4 2 1 *
+0x7F2A NSAI NSAI NSAI NSAI 4 2 1 *
+0x7F2C NSOL NSOL NSOL NSOL 4 2 1 *
+0x7F2D MWFM MWFM MWFM MWFM 4 2 1 *
+0x7F2E MRAV MRAV MRAV MRAV 4 3 1 *
+0x7F2F MSPS MSPS MSPS MSPS 4 2 1 *
+0x7F30 NBOH NBOH NBOH NBOH 4 2 1 *
+0x7F31 NELL NELL NELL NELL 4 2 1 *
+0x7F32 MSLY MSLY MSLY MSLY 4 2 1 *
+0x7F35 MMIS MMIS MMIS MMIS 4 3 1 *
+0x7F36 NSHD NSHD NSHD NSHD 4 2 1 *
+0x7F37 NIRE NIRE NIRE NIRE 4 2 1 *
+0x8000 MGNL MGNL MGNL MGNL 2 2 0 *
+0x8100 MHOB MHOB MHOB MHOB 2 2 0 *
+0x8200 MKOB MKOB MKOB MKOB 2 2 0 *
+0x9000 MOGR MOGR MOGR MOGR 5 2 0 *
+0xA000 MWYV MWYV MWYV MWYV 8 3 1 *
+0xA100 MCAR MCAR MCAR MCAR 8 3 1 *
+0xB000 ACOW ACOW ACOW ACOW 10 3 1 *
+0xB100 AHRS AHRS AHRS AHRS 10 3 1 *
+0xB200 NBEGL NBEGL NBEGL NBEGL 2 2 0 *
+0xB210 NPROL NPROL NPROL NPROL 2 2 0 *
+0xB300 NBOYL NBOYL NBOYL NBOYL 3 2 0 *
+0xB310 NGRLL NGRLL NGRLL NGRLL 3 2 0 *
+0xB400 NFAML NFAML NFAML NFAML 2 2 0 *
+0xB410 NFAWL NFAWL NFAWL NFAWL 2 2 0 *
+0xB500 NSIML NSIML NSIML NSIML 2 2 0 *
+0xB510 NSIWL NSIWL NSIWL NSIWL 2 2 0 *
+0xB600 NNOML NNOML NNOML NNOML 2 2 0 *
+0xB610 NNOWL NNOWL NNOWL NNOWL 2 2 0 *
+0xB700 NSVLL NSVLL NSIWL NSIWL 2 2 0 *
+0xC000 ABAT ABAT ABAT ABAT 2 1 1 *
+0xC100 ACAT ACAT ACAT ACAT 2 1 1 *
+0xC200 ACHK ACHK ACHK ACHK 2 1 1 *
+0xC300 ARAT ARAT ARAT ARAT 2 1 1 *
+0xC400 ASQU ASQU ASQU ASQU 2 1 1 *
+0xC500 ABAT ABAT ABAT ABAT 2 1 1 *
+0xC600 NBEGH NBEGH NBEGH NBEGH 2 2 0 *
+0xC610 NPROH NPROH NPROH NPROH 2 2 0 *
+0xC700 NBOYH NBOYH NBOYH NBOYH 3 2 0 *
+0xC710 NGRLH NGRLH NGRLH NGRLH 3 2 0 *
+0xC800 NFAMH NFAMH NFAMH NFAMH 2 2 0 *
+0xC810 NFAWH NFAWH NFAWH NFAWH 2 2 0 *
+0xC900 NSIMH NSIMH NSIMH NSIMH 2 2 0 *
+0xC910 NSIWH NSIWH NSIWH NSIWH 2 2 0 *
+0xCA00 NNOMH NNOMH NNOMH NNOMH 2 2 0 *
+0xCA10 NNOWH NNOWH NNOWH NNOWH 2 2 0 *
+0xCB00 NSLVH NSLVH NSLVH NSLVH 2 2 0 *
+0xD000 AEAGG1 AEAGG1 AEAGG1 AEAGG1 7 0 1 *
+0xD100 AGULG1 AGULG1 AGULG1 AGULG1 7 0 1 *
+0xD200 AVULG1 AVULG1 AVULG1 AVULG1 7 0 1 *
+0xD300 ABIRG1 ABIRG1 ABIRG1 ABIRG1 7 0 1 *
+0xD400 ABIRG1 ABIRG1 ABIRG1 ABIRG1 7 0 1 *
+0xE000 MBET MBET MBET MBET 9 2 1 *
+0xE012 MBBM MBBM MBBM MBBM 16 2 1 *
+0xE020 MTAN MTAN MTAN MTAN 9 4 1 *
+0xE022 MBBR MBBR MBBR MBBR 9 2 1 *
+0xE038 MBFI MBFI MBFI MBFI 9 2 1 *
+0xE048 MBRH MBRH MBRH MBRH 9 5 1 *
+0xE050 MREM MREM MREM MREM 9 4 1 *
+0xE060 MLIC MLIC MLIC MLIC 9 2 1 *
+0xE068 MHOH MHOH MHOH MHOH 9 2 1 *
+0xE070 MMIN MMIN MMIN MMIN 9 2 1 *
+0xE090 MMER MMER MMER MMER 9 2 1 *
+0xE0A0 MTIC MTIC MTIC MTIC 9 2 1 *
+0xE0B0 MTRO MTRO MTRO MTRO 9 2 1 *
+0xE0C0 MTSN MTSN MTSN MTSN 9 2 1 *
+0xE0D0 MUMB MUMB MUMB MUMB 9 2 1 *
+0xE0E0 MCOR MCOR MCOR MCOR 9 3 1 *
+0xE0F0 MGIC MGIC MGIC MGIC 9 2 1 *
+0xE0F1 MGLA MGLA MGLA MGLA 9 2 1 *
+0xE108 MCYC MCYC MCYC MCYC 9 4 1 *
+0xE118 METN METN METN METN 9 4 1 *
+0xE138 MGFR MGFR MGFR MGFR 9 4 1 *
+0xE148 MGVE MGVE MGVE MGVE 9 4 1 *
+0xE15A MGFO MGFO MGFO MGFO 9 4 1 *
+0xE218 MELE MELE MELE MELE 9 4 1 *
+0xE228 MELF MELF MELF MELF 9 4 1 *
+0xE238 MELW MELW MELW MELW 9 4 1 *
+0xE249 MHAR MHAR MHAR MHAR 9 2 1 *
+0xE252 MWWE MWWE MWWE MWWE 9 2 1 *
+0xE269 MFEY MFEY MFEY MFEY 9 2 1 *
+0xE278 MDTR MDTR MDTR MDTR 9 3 1 *
+0xE289 MFE2 MFE2 MFE2 MFE2 9 3 1 *
+0xE298 MEW2 MEW2 MEW2 MEW2 9 2 1 *
+0xE300 MGHO MGHO MGHO MGHO 9 2 1 *
+0xE308 MGH2 MGH2 MGH2 MGH2 9 2 1 *
+0xE318 MGH3 MGH3 MGH3 MGH3 9 2 1 *
+0xE329 MWIG MWIG MWIG MWIG 9 2 1 *
+0xE338 MZO2 MZO2 MZO2 MZO2 9 2 1 *
+0xE348 MZO3 MZO3 MZO3 MZO3 16 2 1 *
+0xE359 MWI2 MWI2 MWI2 MWI2 9 2 1 *
+0xE369 MWI3 MWI3 MWI3 MWI3 9 2 1 *
+0xE388 MMUM MMUM MMUM MMUM 9 2 1 *
+0xE389 MMUM MMUM MMUM MMUM 9 2 1 *
+0xE39C MHIS MHIS MHIS MHIS 9 2 1 *
+0xE3A8 MDRD MDRD MDRD MDRD 9 2 1 *
+0xE3BB MWAV MWAV MWAV MWAV 9 2 1 *
+0xE408 MGO1 MGO1 MGO1 MGO1 9 2 1 *
+0xE412 MGO2 MGO2 MGO2 MGO2 16 2 1 *
+0xE428 MGO3 MGO3 MGO3 MGO3 9 2 1 *
+0xE432 MGO4 MGO4 MGO4 MGO4 16 2 1 *
+0xE449 MSVI MSVI MSVI MSVI 9 2 1 *
+0xE459 MSV2 MSV2 MSV2 MSV2 9 2 1 *
+0xE468 MGWO MGWO MGWO MGWO 9 2 1 *
+0xE479 MGOC MGOC MGOC MGOC 9 2 1 *
+0xE488 MGW2 MGW2 MGW2 MGW2 9 2 1 *
+0xE498 MGO5 MGO5 MGO5 MGO5 9 2 1 *
+0xE500 MLIZ MLIZ MLIZ MLIZ 9 2 1 *
+0xE510 MLI2 MLI2 MLI2 MLI2 9 2 1 *
+0xE51D MGIR MGIR MGIR MGIR 9 3 1 *
+0xE520 MLI3 MLI3 MLI3 MLI3 9 2 1 *
+0xE528 MGIC MGIC MGIC MGIC 9 2 1 *
+0xE600 MMYC MMYC MMYC MMYC 9 2 1 *
+0xE610 MMY2 MMY2 MMY2 MMY2 9 2 1 *
+0xE62C MSKB MSKB MSKB MSKB 9 2 1 *
+0xE700 MNO1 MNO1 MNO1 MNO1 9 2 1 *
+0xE708 MMIN MMIN MMIN MMIN 9 2 1 *
+0xE710 MNO2 MNO2 MNO2 MNO2 9 2 1 *
+0xE718 MTRO MTRO MTRO MTRO 9 2 1 *
+0xE720 MNO3 MNO3 MNO3 MNO3 9 2 1 *
+0xE728 MTIC MTIC MTIC MTIC 9 2 1 *
+0xE738 MTSN MTSN MTSN MTSN 9 2 1 *
+0xE759 MUMB MUMB MUMB MUMB 9 2 1 *
+0xE76C MYET MYET MYET MYET 9 2 1 *
+0xE771 MBA4 MBA4 MBA4 MBA4 9 2 1 *
+0xE781 MBA5 MBA5 MBA5 MBA5 9 2 1 *
+0xE791 MBA6 MBA6 MBA6 MBA6 9 2 1 *
+0xE7AC MBAI MBAI MBAI MBAI 9 2 1 *
+0xE7B8 MBOA MBOA MBOA MBOA 9 2 1 *
+0xE7C9 MABW MABW MABW MABW 9 2 1 *
+0xE7D9 MMAL MMAL MMAL MMAL 9 2 1 *
+0xE7E8 MSCR MSCR MSCR MSCR 9 2 1 *
+0xE7F9 MUM2 MUM2 MUM2 MUM2 9 2 1 *
+0xE800 MOR6 MOR6 MOR6 MOR6 9 2 1 *
+0xE810 MOR1 MOR1 MOR1 MOR1 9 2 1 *
+0xE820 MOR2 MOR2 MOR2 MOR2 16 2 1 *
+0xE830 MOR3 MOR3 MOR3 MOR3 9 2 1 *
+0xE840 MOR4 MOR4 MOR4 MOR4 16 2 1 *
+0xE850 MOR5 MOR5 MOR5 MOR5 9 2 1 *
+0xE860 MNO1 MNO1 MNO1 MNO1 9 2 1 *
+0xE870 MNO2 MNO2 MNO2 MNO2 9 2 1 *
+0xE880 MNO3 MNO3 MNO3 MNO3 9 2 1 *
+0xE890 MLI3 MLI3 MLI3 MLI3 9 2 1 *
+0xE8A0 MYU3 MYU3 MYU3 MYU3 9 2 1 *
+0xE8B0 MYUH MYUH MYUH MYUH 9 2 1 *
+0xE8C0 MBUG MBUG MBUG MBUG 9 2 1 *
+0xE8D0 MNOS MNOS MNOS MNOS 9 2 1 *
+0xE8E0 MBU2 MBU2 MBU2 MBU2 9 2 1 *
+0xE8F0 MOR7 MOR7 MOR7 MOR7 9 2 1 *
+0xE900 MSAL MSAL MSAL MSAL 16 2 1 *
+0xE908 MSH1 MSH1 MSH1 MSH1 16 2 1 *
+0xE910 MSA2 MSA2 MSA2 MSA2 16 2 1 *
+0xE918 MSH2 MSH2 MSH2 MSH2 16 2 1 *
+0xE928 MGHO MGHO MGHO MGHO 9 2 1 *
+0xEA00 MSHR MSHR MSHR MSHR 9 2 1 *
+0xEA10 MSH1 MSH1 MSH1 MSH1 16 2 1 *
+0xEA20 MCRD MCRD MCRD MCRD 9 2 1 *
+0xEB00 MSKT MSKT MSKT MSKT 9 2 1 *
+0xEB08 MANI MANI MANI MANI 9 3 1 *
+0xEB10 MSKA MSKA MSKA MSKA 9 2 1 *
+0xEB18 MANI MANI MANI MANI 9 2 1 *
+0xEB28 MAN2 MAN2 MAN2 MAN2 9 2 1 *
+0xEB39 MBE1 MBE1 MBE1 MBE1 9 2 1 *
+0xEB49 MBE2 MBE2 MBE2 MBE2 9 2 1 *
+0xEB51 MSEE MSEE MSEE MSEE 9 2 1 *
+0xEB52 MFIR MFIR MFIR MFIR 9 2 1 *
+0xEB69 MLIC MLIC MLIC MLIC 9 2 1 *
+0xEB79 MLER MLER MLER MLER 9 2 1 *
+0xEB89 MMAN MMAN MMAN MMAN 9 2 1 *
+0xEB99 MMYC MMYC MMYC MMYC 9 2 1 *
+0xEBA9 MMY2 MMY2 MMY2 MMY2 9 2 1 *
+0xEBB1 MSHR MSHR MSHR MSHR 9 2 1 *
+0xEBCD MTAN MTAN MTAN MTAN 9 4 1 *
+0xEBD8 MSAL MSAL MSAL MSAL 16 2 1 *
+0xEBE8 MSA2 MSA2 MSA2 MSA2 16 2 1 *
+0xEBF1 MARU MARU MARU MARU 9 2 1 *
+0xEC0B MWDR MWDR MWDR MWDR 9 2 1 *
+0xEC1D MCHY MCHY MCHY MCHY 9 2 1 *
+0xEC2B MSHE MSHE MSHE MSHE 9 2 1 *
+0xEC33 MCHI MCHI MCHI MCHI 9 2 1 *
+0xEC4B MDH1 MDH1 MDH1 MDH1 9 2 1 *
+0xEC5B MDH2 MDH2 MDH2 MDH2 9 2 1 *
+0xED00 MYU1 MYU1 MYU1 MYU1 9 2 1 *
+0xED09 MCOR MCOR MCOR MCOR 9 3 1 *
+0xED10 MYU2 MYU2 MYU2 MYU2 9 2 1 *
+0xED19 MGLA MGLA MGLA MGLA 9 2 1 *
+0xED20 MYU3 MYU3 MYU3 MYU3 9 2 1 *
+0xED28 MLEM MLEM MLEM MLEM 9 2 1 *
+0xEE08 MWEB MWEB MWEB MWEB 9 2 1 *
+0xEE18 MWRA MWRA MWRA MWRA 9 2 1 *
+0xEF0D MISA MISA MISA MISA 9 2 1 *
+0xEF1D MMAD MMAD MMAD MMAD 9 2 1 *
+0xEF28 MWOR MWOR MWOR MWOR 9 2 1 *
+0xEF50 MKG1 MKG1 MKG1 MKG1 9 2 1 *
+0xEF60 MKG2 MKG2 MKG2 MKG2 9 2 1 *
+0xEF70 MKG3 MKG3 MKG3 MKG3 9 2 1 *
+0xEF92 MWIL MWIL MWIL MWIL 9 2 1 *
+0xEFA3 MGEN MGEN MGEN MGEN 9 2 1 *
+0xEFB3 MGEN MGEN MGEN MGEN 9 3 1 *
+0xEFC3 MGEN MGEN MGEN MGEN 9 4 1 *
+0xEFD3 MGEN MGEN MGEN MGEN 9 5 1 *
+0xEFE3 MGEN MGEN MGEN MGEN 9 1 1 *
+0xEFF3 MGEN MGEN MGEN MGEN 9 6 1 *
+0xF008 MSKA MSKA MSKA MSKA 9 2 1 *
+0xF019 MSKT MSKT MSKT MSKT 9 2 1 *
+0xF029 MWI4 MWI4 MWI4 MWI4 9 2 1 *
+0xF10E MYU1 MYU1 MYU1 MYU1 9 2 1 *
+0xF11E MYU2 MYU2 MYU2 MYU2 9 2 1 *
+0xF209 MLIZ MLIZ MLIZ MLIZ 9 2 1 *
+0xF218 MLI2 MLI2 MLI2 MLI2 9 2 1 *
+0xF308 MGFI MGFI MGFI MGFI 9 4 1 *
+0xF40B MSAH MSAH MSAH MSAH 9 2 1 *
+0xF41B MSAT MSAT MSAT MSAT 9 2 1 *
+0xF50B MDRM MDRM MDRM MDRM 9 4 1 *
+0xF51B MDRF MDRF MDRF MDRF 9 4 1 *
+0xF77A MBA1 MBA1 MBA1 MBA1 9 2 1 *
+0xF78A MBA2 MBA2 MBA2 MBA2 9 2 1 *
+0xF798 MBA3 MBA3 MBA3 MBA3 9 2 1 *
diff --git a/gemrb/override/iwd/avprefc.2da b/gemrb/unhardcoded/iwd/avprefc.2da
similarity index 100%
rename from gemrb/override/iwd/avprefc.2da
rename to gemrb/unhardcoded/iwd/avprefc.2da
diff --git a/gemrb/override/iwd/avprefr.2da b/gemrb/unhardcoded/iwd/avprefr.2da
similarity index 100%
rename from gemrb/override/iwd/avprefr.2da
rename to gemrb/unhardcoded/iwd/avprefr.2da
diff --git a/gemrb/override/iwd/axe.pro b/gemrb/unhardcoded/iwd/axe.pro
similarity index 100%
rename from gemrb/override/iwd/axe.pro
rename to gemrb/unhardcoded/iwd/axe.pro
diff --git a/gemrb/override/iwd/axeex.pro b/gemrb/unhardcoded/iwd/axeex.pro
similarity index 100%
rename from gemrb/override/iwd/axeex.pro
rename to gemrb/unhardcoded/iwd/axeex.pro
diff --git a/gemrb/override/iwd/bbarrh1.pro b/gemrb/unhardcoded/iwd/bbarrh1.pro
similarity index 100%
rename from gemrb/override/iwd/bbarrh1.pro
rename to gemrb/unhardcoded/iwd/bbarrh1.pro
diff --git a/gemrb/override/iwd/bbarrh2.pro b/gemrb/unhardcoded/iwd/bbarrh2.pro
similarity index 100%
rename from gemrb/override/iwd/bbarrh2.pro
rename to gemrb/unhardcoded/iwd/bbarrh2.pro
diff --git a/gemrb/override/iwd/bbarrier.pro b/gemrb/unhardcoded/iwd/bbarrier.pro
similarity index 100%
rename from gemrb/override/iwd/bbarrier.pro
rename to gemrb/unhardcoded/iwd/bbarrier.pro
diff --git a/gemrb/override/iwd/bdeath.pro b/gemrb/unhardcoded/iwd/bdeath.pro
similarity index 100%
rename from gemrb/override/iwd/bdeath.pro
rename to gemrb/unhardcoded/iwd/bdeath.pro
diff --git a/gemrb/override/iwd/blessh.pro b/gemrb/unhardcoded/iwd/blessh.pro
similarity index 100%
rename from gemrb/override/iwd/blessh.pro
rename to gemrb/unhardcoded/iwd/blessh.pro
diff --git a/gemrb/unhardcoded/iwd/bloodclr.2da b/gemrb/unhardcoded/iwd/bloodclr.2da
new file mode 100644
index 0000000..5d10be9
--- /dev/null
+++ b/gemrb/unhardcoded/iwd/bloodclr.2da
@@ -0,0 +1,29 @@
+2DA V1.0
+0
+ VALUE MIN MAX FLAGS
+NORMAL 0x2f 0x1000 0xffff 0
+PURPLE 0x2d 0x4300 0x43ff 0
+MSKEL 0x25 0x5403 0x5403 1
+DOOMG 0x22 0x5405 0x5406 1
+MSKEL 0x25 0x6403 0x6403 1
+DOOMG 0x22 0x6405 0x6406 1
+YELLOW 0x32 0x7300 0x73ff 0
+PURPLE 0x3c 0x7500 0x75ff 0
+YELLOW 0x32 0x7600 0x76ff 1
+BLACK 0x66 0x7700 0x77ff 1
+SLI_GR 7 0x7900 0x7900 1
+SLI_OL 0x24 0x7901 0x7901 1
+SLI_MU 0x33 0x7902 0x7902 1
+SLI_OC 0x25 0x7903 0x7903 1
+SLIME 0x1b 0x7904 0x7904 1
+SPIDER 0x33 0x7a00 0x7aff 1
+ZOMBIE 0x25 0x7c00 0x7cff 1
+MTRO 0x33 0x7f00 0x7f00 0
+MMIN 0x3d 0x7f01 0x7f03 0
+MIGO 0x1a 0x7f04 0x7f04 1
+MGLC 0x5d 0x7f07 0x7f07 0
+MTRS 0x32 0x7f0f 0x7f0f 0
+MBES 0x3d 0x7f15 0x7f15 0
+MCAR 0x38 0xa100 0xa1ff 0
+UNDEAD 0x66 0xe300 0xe3ff 1
+MWWE 0x38 0xef00 0xefff 1
diff --git a/gemrb/override/iwd/bolt.pro b/gemrb/unhardcoded/iwd/bolt.pro
similarity index 100%
rename from gemrb/override/iwd/bolt.pro
rename to gemrb/unhardcoded/iwd/bolt.pro
diff --git a/gemrb/override/iwd/boltex.pro b/gemrb/unhardcoded/iwd/boltex.pro
similarity index 100%
rename from gemrb/override/iwd/boltex.pro
rename to gemrb/unhardcoded/iwd/boltex.pro
diff --git a/gemrb/override/iwd/bscloud.pro b/gemrb/unhardcoded/iwd/bscloud.pro
similarity index 100%
rename from gemrb/override/iwd/bscloud.pro
rename to gemrb/unhardcoded/iwd/bscloud.pro
diff --git a/gemrb/override/iwd/bullet.pro b/gemrb/unhardcoded/iwd/bullet.pro
similarity index 100%
rename from gemrb/override/iwd/bullet.pro
rename to gemrb/unhardcoded/iwd/bullet.pro
diff --git a/gemrb/override/iwd/bulletex.pro b/gemrb/unhardcoded/iwd/bulletex.pro
similarity index 100%
rename from gemrb/override/iwd/bulletex.pro
rename to gemrb/unhardcoded/iwd/bulletex.pro
diff --git a/gemrb/override/iwd/calllih.pro b/gemrb/unhardcoded/iwd/calllih.pro
similarity index 100%
rename from gemrb/override/iwd/calllih.pro
rename to gemrb/unhardcoded/iwd/calllih.pro
diff --git a/gemrb/override/iwd/ccdamah.pro b/gemrb/unhardcoded/iwd/ccdamah.pro
similarity index 100%
rename from gemrb/override/iwd/ccdamah.pro
rename to gemrb/unhardcoded/iwd/ccdamah.pro
diff --git a/gemrb/override/iwd/ccommah.pro b/gemrb/unhardcoded/iwd/ccommah.pro
similarity index 100%
rename from gemrb/override/iwd/ccommah.pro
rename to gemrb/unhardcoded/iwd/ccommah.pro
diff --git a/gemrb/override/iwd/ccwounh.pro b/gemrb/unhardcoded/iwd/ccwounh.pro
similarity index 100%
rename from gemrb/override/iwd/ccwounh.pro
rename to gemrb/unhardcoded/iwd/ccwounh.pro
diff --git a/gemrb/override/iwd/cdiseah.pro b/gemrb/unhardcoded/iwd/cdiseah.pro
similarity index 100%
rename from gemrb/override/iwd/cdiseah.pro
rename to gemrb/unhardcoded/iwd/cdiseah.pro
diff --git a/gemrb/override/iwd/ceelem1.pro b/gemrb/unhardcoded/iwd/ceelem1.pro
similarity index 100%
rename from gemrb/override/iwd/ceelem1.pro
rename to gemrb/unhardcoded/iwd/ceelem1.pro
diff --git a/gemrb/override/iwd/ceelemh.pro b/gemrb/unhardcoded/iwd/ceelemh.pro
similarity index 100%
rename from gemrb/override/iwd/ceelemh.pro
rename to gemrb/unhardcoded/iwd/ceelemh.pro
diff --git a/gemrb/override/iwd/ceelemx.pro b/gemrb/unhardcoded/iwd/ceelemx.pro
similarity index 100%
rename from gemrb/override/iwd/ceelemx.pro
rename to gemrb/unhardcoded/iwd/ceelemx.pro
diff --git a/gemrb/override/iwd/cfelem1.pro b/gemrb/unhardcoded/iwd/cfelem1.pro
similarity index 100%
rename from gemrb/override/iwd/cfelem1.pro
rename to gemrb/unhardcoded/iwd/cfelem1.pro
diff --git a/gemrb/override/iwd/cfelemh.pro b/gemrb/unhardcoded/iwd/cfelemh.pro
similarity index 100%
rename from gemrb/override/iwd/cfelemh.pro
rename to gemrb/unhardcoded/iwd/cfelemh.pro
diff --git a/gemrb/override/iwd/cfelemx.pro b/gemrb/unhardcoded/iwd/cfelemx.pro
similarity index 100%
rename from gemrb/override/iwd/cfelemx.pro
rename to gemrb/unhardcoded/iwd/cfelemx.pro
diff --git a/gemrb/override/iwd/cfog.pro b/gemrb/unhardcoded/iwd/cfog.pro
similarity index 100%
rename from gemrb/override/iwd/cfog.pro
rename to gemrb/unhardcoded/iwd/cfog.pro
diff --git a/gemrb/override/iwd/cgraceh.pro b/gemrb/unhardcoded/iwd/cgraceh.pro
similarity index 100%
rename from gemrb/override/iwd/cgraceh.pro
rename to gemrb/unhardcoded/iwd/cgraceh.pro
diff --git a/gemrb/override/iwd/cgtable.2da b/gemrb/unhardcoded/iwd/cgtable.2da
similarity index 100%
rename from gemrb/override/iwd/cgtable.2da
rename to gemrb/unhardcoded/iwd/cgtable.2da
diff --git a/gemrb/override/iwd/chant.pro b/gemrb/unhardcoded/iwd/chant.pro
similarity index 100%
rename from gemrb/override/iwd/chant.pro
rename to gemrb/unhardcoded/iwd/chant.pro
diff --git a/gemrb/override/iwd/chromorb.pro b/gemrb/unhardcoded/iwd/chromorb.pro
similarity index 100%
rename from gemrb/override/iwd/chromorb.pro
rename to gemrb/unhardcoded/iwd/chromorb.pro
diff --git a/gemrb/override/iwd/classes.2da b/gemrb/unhardcoded/iwd/classes.2da
similarity index 100%
rename from gemrb/override/iwd/classes.2da
rename to gemrb/unhardcoded/iwd/classes.2da
diff --git a/gemrb/override/iwd/cldamah.pro b/gemrb/unhardcoded/iwd/cldamah.pro
similarity index 100%
rename from gemrb/override/iwd/cldamah.pro
rename to gemrb/unhardcoded/iwd/cldamah.pro
diff --git a/gemrb/override/iwd/cloud.pro b/gemrb/unhardcoded/iwd/cloud.pro
similarity index 100%
rename from gemrb/override/iwd/cloud.pro
rename to gemrb/unhardcoded/iwd/cloud.pro
diff --git a/gemrb/override/iwd/cloudb.pro b/gemrb/unhardcoded/iwd/cloudb.pro
similarity index 100%
rename from gemrb/override/iwd/cloudb.pro
rename to gemrb/unhardcoded/iwd/cloudb.pro
diff --git a/gemrb/override/iwd/cloudbh.pro b/gemrb/unhardcoded/iwd/cloudbh.pro
similarity index 100%
rename from gemrb/override/iwd/cloudbh.pro
rename to gemrb/unhardcoded/iwd/cloudbh.pro
diff --git a/gemrb/override/iwd/cloudkil.pro b/gemrb/unhardcoded/iwd/cloudkil.pro
similarity index 100%
rename from gemrb/override/iwd/cloudkil.pro
rename to gemrb/unhardcoded/iwd/cloudkil.pro
diff --git a/gemrb/override/iwd/cloudks.pro b/gemrb/unhardcoded/iwd/cloudks.pro
similarity index 100%
rename from gemrb/override/iwd/cloudks.pro
rename to gemrb/unhardcoded/iwd/cloudks.pro
diff --git a/gemrb/override/iwd/clowncol.2da b/gemrb/unhardcoded/iwd/clowncol.2da
similarity index 100%
rename from gemrb/override/iwd/clowncol.2da
rename to gemrb/unhardcoded/iwd/clowncol.2da
diff --git a/gemrb/unhardcoded/iwd/clskills.2da b/gemrb/unhardcoded/iwd/clskills.2da
new file mode 100644
index 0000000..0aa4d32
--- /dev/null
+++ b/gemrb/unhardcoded/iwd/clskills.2da
@@ -0,0 +1,22 @@
+2DA V1.0
+*
+ DRUIDSPELL CLERICSPELL MAGESPELL STARTXP BARDSKILL THIEFSKILL LAYHANDS TURNLEVEL BOOKTYPE HATERACE ABILITIES NO_PROF SAVEBONUS
+UNUSED * * * * * * * * 0 * * * 0
+MAGE * * MXSPLWIZ 0 * * * * 1 * * -4 0
+FIGHTER * * * 0 * * * * 0 * * -2 0
+CLERIC * MXSPLPRS * 0 * * * 1 1 * * -3 0
+THIEF * * * 0 * SKILLS * * 0 * * -3 0
+BARD * * MXSPLBRD 0 SKILLBRD * * * 1 * * -3 0
+PALADIN * MXSPLPAL * 0 * * PALADIN 5 1 * * -2 2
+FIGHTER_MAGE * * MXSPLWIZ 0 * * * * 1 * * -2 0
+FIGHTER_CLERIC * MXSPLPRS * 0 * * * * 1 * * -2 0
+FIGHTER_THIEF * * * 0 * SKILLS * * 0 * * -2 0
+FIGHTER_MAGE_THIEF * * MXSPLWIZ 0 * SKILLS * * 1 * * -2 0
+DRUID MXSPLDRU * * 0 * * * * 1 * * -3 0
+RANGER MXSPLRAN * * 0 * * * * 1 HATERACE * -2 0
+MAGE_THIEF * * MXSPLWIZ 0 * SKILLS * * 1 * * -3 0
+CLERIC_MAGE * MXSPLPRS MXSPLWIZ 0 * * * * 1 * * -3 0
+CLERIC_THIEF * MXSPLPRS * 0 * SKILLS * * 1 * * -3 0
+FIGHTER_DRUID MXSPLDRU * * 0 * * * * 1 * * -2 0
+FIGHTER_MAGE_CLERIC * MXSPLPRS MXSPLWIZ 0 * * * * 1 * * -2 0
+CLERIC_RANGER MXSPLRAN MXSPLPRS * 0 * * * * 1 HATERACE * -2 0
diff --git a/gemrb/override/iwd/clssplab.2da b/gemrb/unhardcoded/iwd/clssplab.2da
similarity index 100%
rename from gemrb/override/iwd/clssplab.2da
rename to gemrb/unhardcoded/iwd/clssplab.2da
diff --git a/gemrb/override/iwd/clwounh.pro b/gemrb/unhardcoded/iwd/clwounh.pro
similarity index 100%
rename from gemrb/override/iwd/clwounh.pro
rename to gemrb/unhardcoded/iwd/clwounh.pro
diff --git a/gemrb/override/iwd/cmdamah.pro b/gemrb/unhardcoded/iwd/cmdamah.pro
similarity index 100%
rename from gemrb/override/iwd/cmdamah.pro
rename to gemrb/unhardcoded/iwd/cmdamah.pro
diff --git a/gemrb/override/iwd/cmwounh.pro b/gemrb/unhardcoded/iwd/cmwounh.pro
similarity index 100%
rename from gemrb/override/iwd/cmwounh.pro
rename to gemrb/unhardcoded/iwd/cmwounh.pro
diff --git a/gemrb/override/iwd/cobones.pro b/gemrb/unhardcoded/iwd/cobones.pro
similarity index 100%
rename from gemrb/override/iwd/cobones.pro
rename to gemrb/unhardcoded/iwd/cobones.pro
diff --git a/gemrb/override/iwd/cobonh1.pro b/gemrb/unhardcoded/iwd/cobonh1.pro
similarity index 100%
rename from gemrb/override/iwd/cobonh1.pro
rename to gemrb/unhardcoded/iwd/cobonh1.pro
diff --git a/gemrb/override/iwd/cobonh2.pro b/gemrb/unhardcoded/iwd/cobonh2.pro
similarity index 100%
rename from gemrb/override/iwd/cobonh2.pro
rename to gemrb/unhardcoded/iwd/cobonh2.pro
diff --git a/gemrb/override/iwd/cocold.pro b/gemrb/unhardcoded/iwd/cocold.pro
similarity index 100%
rename from gemrb/override/iwd/cocold.pro
rename to gemrb/unhardcoded/iwd/cocold.pro
diff --git a/gemrb/override/iwd/cocoldh.pro b/gemrb/unhardcoded/iwd/cocoldh.pro
similarity index 100%
rename from gemrb/override/iwd/cocoldh.pro
rename to gemrb/unhardcoded/iwd/cocoldh.pro
diff --git a/gemrb/override/iwd/cofire.pro b/gemrb/unhardcoded/iwd/cofire.pro
similarity index 100%
rename from gemrb/override/iwd/cofire.pro
rename to gemrb/unhardcoded/iwd/cofire.pro
diff --git a/gemrb/override/iwd/coldh.pro b/gemrb/unhardcoded/iwd/coldh.pro
similarity index 100%
rename from gemrb/override/iwd/coldh.pro
rename to gemrb/unhardcoded/iwd/coldh.pro
diff --git a/gemrb/override/iwd/colrspry.pro b/gemrb/unhardcoded/iwd/colrspry.pro
similarity index 100%
rename from gemrb/override/iwd/colrspry.pro
rename to gemrb/unhardcoded/iwd/colrspry.pro
diff --git a/gemrb/override/iwd/confush.pro b/gemrb/unhardcoded/iwd/confush.pro
similarity index 100%
rename from gemrb/override/iwd/confush.pro
rename to gemrb/unhardcoded/iwd/confush.pro
diff --git a/gemrb/override/iwd/confusp.pro b/gemrb/unhardcoded/iwd/confusp.pro
similarity index 100%
rename from gemrb/override/iwd/confusp.pro
rename to gemrb/unhardcoded/iwd/confusp.pro
diff --git a/gemrb/override/iwd/confusw.pro b/gemrb/unhardcoded/iwd/confusw.pro
similarity index 100%
rename from gemrb/override/iwd/confusw.pro
rename to gemrb/unhardcoded/iwd/confusw.pro
diff --git a/gemrb/override/iwd/conjuh.pro b/gemrb/unhardcoded/iwd/conjuh.pro
similarity index 100%
rename from gemrb/override/iwd/conjuh.pro
rename to gemrb/unhardcoded/iwd/conjuh.pro
diff --git a/gemrb/override/iwd/conjut.pro b/gemrb/unhardcoded/iwd/conjut.pro
similarity index 100%
rename from gemrb/override/iwd/conjut.pro
rename to gemrb/unhardcoded/iwd/conjut.pro
diff --git a/gemrb/override/iwd/copest.pro b/gemrb/unhardcoded/iwd/copest.pro
similarity index 100%
rename from gemrb/override/iwd/copest.pro
rename to gemrb/unhardcoded/iwd/copest.pro
diff --git a/gemrb/override/iwd/cry150.pro b/gemrb/unhardcoded/iwd/cry150.pro
similarity index 100%
rename from gemrb/override/iwd/cry150.pro
rename to gemrb/unhardcoded/iwd/cry150.pro
diff --git a/gemrb/override/iwd/cry200.pro b/gemrb/unhardcoded/iwd/cry200.pro
similarity index 100%
rename from gemrb/override/iwd/cry200.pro
rename to gemrb/unhardcoded/iwd/cry200.pro
diff --git a/gemrb/override/iwd/cry225.pro b/gemrb/unhardcoded/iwd/cry225.pro
similarity index 100%
rename from gemrb/override/iwd/cry225.pro
rename to gemrb/unhardcoded/iwd/cry225.pro
diff --git a/gemrb/override/iwd/cry250.pro b/gemrb/unhardcoded/iwd/cry250.pro
similarity index 100%
rename from gemrb/override/iwd/cry250.pro
rename to gemrb/unhardcoded/iwd/cry250.pro
diff --git a/gemrb/override/iwd/cry500np.pro b/gemrb/unhardcoded/iwd/cry500np.pro
similarity index 100%
rename from gemrb/override/iwd/cry500np.pro
rename to gemrb/unhardcoded/iwd/cry500np.pro
diff --git a/gemrb/override/iwd/csdamah.pro b/gemrb/unhardcoded/iwd/csdamah.pro
similarity index 100%
rename from gemrb/override/iwd/csdamah.pro
rename to gemrb/unhardcoded/iwd/csdamah.pro
diff --git a/gemrb/override/iwd/cstrenh.pro b/gemrb/unhardcoded/iwd/cstrenh.pro
similarity index 100%
rename from gemrb/override/iwd/cstrenh.pro
rename to gemrb/unhardcoded/iwd/cstrenh.pro
diff --git a/gemrb/override/iwd/cswounh.pro b/gemrb/unhardcoded/iwd/cswounh.pro
similarity index 100%
rename from gemrb/override/iwd/cswounh.pro
rename to gemrb/unhardcoded/iwd/cswounh.pro
diff --git a/gemrb/override/iwd/curseh.pro b/gemrb/unhardcoded/iwd/curseh.pro
similarity index 100%
rename from gemrb/override/iwd/curseh.pro
rename to gemrb/unhardcoded/iwd/curseh.pro
diff --git a/gemrb/override/iwd/cwelem1.pro b/gemrb/unhardcoded/iwd/cwelem1.pro
similarity index 100%
rename from gemrb/override/iwd/cwelem1.pro
rename to gemrb/unhardcoded/iwd/cwelem1.pro
diff --git a/gemrb/override/iwd/cwelemh.pro b/gemrb/unhardcoded/iwd/cwelemh.pro
similarity index 100%
rename from gemrb/override/iwd/cwelemh.pro
rename to gemrb/unhardcoded/iwd/cwelemh.pro
diff --git a/gemrb/override/iwd/cwelemx.pro b/gemrb/unhardcoded/iwd/cwelemx.pro
similarity index 100%
rename from gemrb/override/iwd/cwelemx.pro
rename to gemrb/unhardcoded/iwd/cwelemx.pro
diff --git a/gemrb/override/iwd/cynicism.2da b/gemrb/unhardcoded/iwd/cynicism.2da
similarity index 100%
rename from gemrb/override/iwd/cynicism.2da
rename to gemrb/unhardcoded/iwd/cynicism.2da
diff --git a/gemrb/override/iwd/dagger.pro b/gemrb/unhardcoded/iwd/dagger.pro
similarity index 100%
rename from gemrb/override/iwd/dagger.pro
rename to gemrb/unhardcoded/iwd/dagger.pro
diff --git a/gemrb/override/iwd/daggerex.pro b/gemrb/unhardcoded/iwd/daggerex.pro
similarity index 100%
rename from gemrb/override/iwd/daggerex.pro
rename to gemrb/unhardcoded/iwd/daggerex.pro
diff --git a/gemrb/override/iwd/damage.2da b/gemrb/unhardcoded/iwd/damage.2da
similarity index 100%
rename from gemrb/override/iwd/damage.2da
rename to gemrb/unhardcoded/iwd/damage.2da
diff --git a/gemrb/override/iwd/dart.pro b/gemrb/unhardcoded/iwd/dart.pro
similarity index 100%
rename from gemrb/override/iwd/dart.pro
rename to gemrb/unhardcoded/iwd/dart.pro
diff --git a/gemrb/override/iwd/dartex.pro b/gemrb/unhardcoded/iwd/dartex.pro
similarity index 100%
rename from gemrb/override/iwd/dartex.pro
rename to gemrb/unhardcoded/iwd/dartex.pro
diff --git a/gemrb/override/iwd/dbreath.pro b/gemrb/unhardcoded/iwd/dbreath.pro
similarity index 100%
rename from gemrb/override/iwd/dbreath.pro
rename to gemrb/unhardcoded/iwd/dbreath.pro
diff --git a/gemrb/override/iwd/ddeath.pro b/gemrb/unhardcoded/iwd/ddeath.pro
similarity index 100%
rename from gemrb/override/iwd/ddeath.pro
rename to gemrb/unhardcoded/iwd/ddeath.pro
diff --git a/gemrb/override/iwd/ddeath2.pro b/gemrb/unhardcoded/iwd/ddeath2.pro
similarity index 100%
rename from gemrb/override/iwd/ddeath2.pro
rename to gemrb/unhardcoded/iwd/ddeath2.pro
diff --git a/gemrb/override/iwd/ddoorh.pro b/gemrb/unhardcoded/iwd/ddoorh.pro
similarity index 100%
rename from gemrb/override/iwd/ddoorh.pro
rename to gemrb/unhardcoded/iwd/ddoorh.pro
diff --git a/gemrb/unhardcoded/iwd/defsound.2da b/gemrb/unhardcoded/iwd/defsound.2da
new file mode 100644
index 0000000..45b6dd2
--- /dev/null
+++ b/gemrb/unhardcoded/iwd/defsound.2da
@@ -0,0 +1,36 @@
+2DA V1.0
+*
+ RESREF
+OPEN AMB_D03A
+CLOSE AMB_D03B
+HOPEN AMB_D04A
+HCLOSE AMB_D04B
+BUTTON1 GAM_09
+BUTTON2 GAM_03
+BUTTON3 GAM_04
+OPENFAIL AMB_D20
+CLOSEFAIL *
+ITEM_GONE EFF_M02
+SECRET ACT_09
+PICKLOCK AMB_D21D
+PICKFAIL AMB_D21
+13 *
+14 *
+15 *
+16 *
+17 *
+18 *
+19 *
+LIGHTNING1 AMB_E13A
+LIGHTNING2 AMB_E13B
+LIGHTNING3 AMB_E13F
+RAIN AMB_E11
+SNOW AMB_E02B
+SOLD ACT_03D
+STOLEN GAM_36
+DRUNK GAM_07
+DONATE1 ACT_03
+DONATE2 ACT_03E
+IDENTIFY CAS_P04
+GOTXP *
+TOOLTIP G_PAPR1
diff --git a/gemrb/override/iwd/destruh.pro b/gemrb/unhardcoded/iwd/destruh.pro
similarity index 100%
rename from gemrb/override/iwd/destruh.pro
rename to gemrb/unhardcoded/iwd/destruh.pro
diff --git a/gemrb/override/iwd/dfog.pro b/gemrb/unhardcoded/iwd/dfog.pro
similarity index 100%
rename from gemrb/override/iwd/dfog.pro
rename to gemrb/unhardcoded/iwd/dfog.pro
diff --git a/gemrb/override/iwd/disint.pro b/gemrb/unhardcoded/iwd/disint.pro
similarity index 100%
rename from gemrb/override/iwd/disint.pro
rename to gemrb/unhardcoded/iwd/disint.pro
diff --git a/gemrb/override/iwd/disinth.pro b/gemrb/unhardcoded/iwd/disinth.pro
similarity index 100%
rename from gemrb/override/iwd/disinth.pro
rename to gemrb/unhardcoded/iwd/disinth.pro
diff --git a/gemrb/override/iwd/dispel.pro b/gemrb/unhardcoded/iwd/dispel.pro
similarity index 100%
rename from gemrb/override/iwd/dispel.pro
rename to gemrb/unhardcoded/iwd/dispel.pro
diff --git a/gemrb/override/iwd/divinh.pro b/gemrb/unhardcoded/iwd/divinh.pro
similarity index 100%
rename from gemrb/override/iwd/divinh.pro
rename to gemrb/unhardcoded/iwd/divinh.pro
diff --git a/gemrb/override/iwd/divint.pro b/gemrb/unhardcoded/iwd/divint.pro
similarity index 100%
rename from gemrb/override/iwd/divint.pro
rename to gemrb/unhardcoded/iwd/divint.pro
diff --git a/gemrb/unhardcoded/iwd/dsclass.2da b/gemrb/unhardcoded/iwd/dsclass.2da
new file mode 100644
index 0000000..1d498b7
--- /dev/null
+++ b/gemrb/unhardcoded/iwd/dsclass.2da
@@ -0,0 +1,24 @@
+2DA V1.0
+0
+ CLASS BONUS
+MAGE 1 5
+FIGHTER 2 10
+CLERIC 3 10
+THIEF 4 15
+BARD 5 15
+PALADIN 6 10
+FM 7 10
+FC 8 10
+FT 9 15
+FMT 10 15
+DRUID 11 10
+RANGER 12 10
+MT 13 15
+CM 14 10
+CT 15 15
+FD 16 10
+FMC 17 10
+CR 18 10
+SORC 19 5
+MONK 20 15
+
diff --git a/gemrb/override/iwd/dspell.pro b/gemrb/unhardcoded/iwd/dspell.pro
similarity index 100%
rename from gemrb/override/iwd/dspell.pro
rename to gemrb/unhardcoded/iwd/dspell.pro
diff --git a/gemrb/override/iwd/dspellh.pro b/gemrb/unhardcoded/iwd/dspellh.pro
similarity index 100%
rename from gemrb/override/iwd/dspellh.pro
rename to gemrb/unhardcoded/iwd/dspellh.pro
diff --git a/gemrb/unhardcoded/iwd/dsrace.2da b/gemrb/unhardcoded/iwd/dsrace.2da
new file mode 100644
index 0000000..5fb3c47
--- /dev/null
+++ b/gemrb/unhardcoded/iwd/dsrace.2da
@@ -0,0 +1,7 @@
+2DA V1.0
+0
+ RACE BONUS
+ELF 2 20
+DWARF 4 10
+HALFLING 5 5
+
diff --git a/gemrb/unhardcoded/iwd/dstable.2da b/gemrb/unhardcoded/iwd/dstable.2da
new file mode 100644
index 0000000..b2d0df7
--- /dev/null
+++ b/gemrb/unhardcoded/iwd/dstable.2da
@@ -0,0 +1,6 @@
+2DA V1.0
+*
+FILE STAT
+dsclass CLASS
+dsrace RACE
+
diff --git a/gemrb/override/iwd/dualclas.2da b/gemrb/unhardcoded/iwd/dualclas.2da
similarity index 100%
rename from gemrb/override/iwd/dualclas.2da
rename to gemrb/unhardcoded/iwd/dualclas.2da
diff --git a/gemrb/unhardcoded/iwd/effects.ids b/gemrb/unhardcoded/iwd/effects.ids
new file mode 100644
index 0000000..1abfbea
--- /dev/null
+++ b/gemrb/unhardcoded/iwd/effects.ids
@@ -0,0 +1,300 @@
+IDS
+0x0 ACVsDamageTypeModifier
+0x1 AttacksPerRoundModifier
+0x2 Cure:Sleep
+0x3 State:Berserk
+0x4 Cure:Berserk
+0x5 State:Charmed
+0x6 CharismaModifier
+0x7 Color:SetPalette
+0x8 Color:SetRGB
+0x9 Color:PulseRGB
+0xa ConstitutionModifier
+0xb Cure:Poison
+0xc Damage
+0xd Death
+0xe Cure:Defrost
+0xf DexterityModifier
+0x10 State:Hasted
+0x11 CurrentHPModifier
+0x12 MaximumHPModifier
+0x13 IntelligenceModifier
+0x14 State:Invisible
+0x15 LoreModifier
+0x16 LuckModifier
+0x17 MoraleModifier
+0x18 State:Panic
+0x19 State:Poisoned
+0x1a RemoveCurse
+0x1b AcidResistanceModifier
+0x1c ColdResistanceModifier
+0x1d ElectricityResistanceModifier
+0x1e FireResistanceModifier
+0x1f MagicDamageResistanceModifier
+0x20 Cure:Death
+0x21 SaveVsDeathModifier
+0x22 SaveVsWandsModifier
+0x23 SaveVsPolyModifier
+0x24 SaveVsBreathModifier
+0x25 SaveVsSpellsModifier
+0x26 State:Silenced
+0x27 State:Helpless
+0x28 State:Slowed
+0x29 Sparkle
+0x2a WizardSpellSlotsModifier
+0x2b Cure:Petrification
+0x2c StrengthModifier
+0x2d State:Stun
+0x2e Cure:Stun
+0x2f Cure:Invisible
+0x30 Cure:Silence
+0x31 WisdomModifier
+0x32 Color:BriefRGB
+0x33 Color:DarkenRGB
+0x34 Color:GlowRGB
+0x35 AnimationIDModifier
+0x36 ToHitModifier
+0x37 KillCreatureType
+0x38 Alignment:Invert
+0x39 Alignment:Change
+0x3a DispelEffects
+0x3b StealthModifier
+0x3c MiscastMagicModifier
+0x3d AlchemyModifier
+0x3e PriestSpellSlotsModifier
+0x3f State:Infravision
+0x40 Cure:Infravision
+0x41 State:Blur
+0x42 TransparencyModifier
+0x43 SummonCreature
+0x44 UnsummonCreature
+0x45 State:NonDetection
+0x46 Cure:NonDetection
+0x47 SexModifier
+0x48 AIIdentifierModifier
+0x49 DamageBonusModifier2
+0x4a State:Blind
+0x4b Cure:Blind
+0x4c State:Feeblemind
+0x4d Cure:Feeblemind
+0x4e State:Diseased
+0x4f Cure:Disease
+0x50 State:Deafness
+0x51 Cure:Deafness
+0x52 SetAIScript
+0x53 Protection:Projectile
+0x54 MagicalFireResistanceModifier
+0x55 MagicalColdResistanceModifier
+0x56 SlashingResistanceModifier
+0x57 CrushingResistanceModifier
+0x58 PiercingResistanceModifier
+0x59 MissilesResistanceModifier
+0x5a OpenLocksModifier
+0x5b FindTrapsModifier
+0x5c PickPocketsModifier
+0x5d FatigueModifier
+0x5e IntoxicationModifier
+0x5f TrackingModifier
+0x60 LevelModifier
+0x61 StrengthBonusModifier
+0x62 State:Regenerating
+0x63 SpellDurationModifier
+0x64 Protection:Creature
+0x65 Protection:Opcode
+0x66 Protection:SpellLevel
+0x67 ChangeName
+0x68 ExperienceModifier
+0x69 GoldModifier
+0x6a MoraleBreakModifier
+0x6b PortraitChange
+0x6c ReputationModifier
+0x6d State:HoldNoIcon
+0x6e RetreatFrom
+0x6f Item:CreateMagic
+0x70 Item:Remove
+0x71 Item:Equip
+0x72 Dither
+0x73 DetectAlignment
+0x74 Cure:Invisible2
+0x75 Reveal:Area
+0x76 Reveal:Creatures
+0x77 MirrorImage
+0x78 Protection:Weapons
+0x79 VisualAnimationEffect
+0x7a Item:CreateInventory
+0x7b Item:RemoveInventory
+0x7c DimensionDoor
+0x7d Unlock
+0x7e MovementRateModifier
+0x7f MonsterSummoning
+0x80 State:Confused
+0x81 AidNonCumulative
+0x82 BlessNonCumulative
+0x83 ChantNonCumulative
+0x84 HolyNonCumulative
+0x85 LuckNonCumulative
+0x86 State:Petrification
+0x87 Polymorph
+0x88 ForceVisible
+0x89 ChantBadNonCumulative
+0x8a AnimationStateChange
+0x8b DisplayString
+0x8c CastingGlow
+0x8d VisualSpellHit
+0x8e Icon:Display
+0x8f Item:CreateInSlot
+0x90 DisableButton
+0x91 DisableCasting
+0x92 Spell:Cast
+0x93 Spell:Learn
+0x94 Spell:CastPoint
+0x95 Identify
+0x96 FindTraps
+0x97 ReplaceCreature
+0x98 PlayMovie
+0x99 Overlay:Sanctuary
+0x9a Overlay:Entangle
+0x9b Overlay:MinorGlobe
+0x9c Overlay:ShieldGlobe
+0x9d Overlay:Web
+0x9e Overlay:Grease
+0x9f MirrorImageModifier
+0xa0 Cure:Sanctuary
+0xa1 Cure:Panic
+0xa2 Cure:Hold
+0xa3 FreeAction
+0xa4 Cure:Intoxication
+0xa5 PauseTarget
+0xa6 MagicResistanceModifier
+0xa7 MissileHitModifier
+0xa8 RemoveCreature
+0xa9 Icon:Disable
+0xaa DamageAnimation
+0xab Spell:Add
+0xac Spell:Remove
+0xad PoisonResistanceModifier
+0xae PlaySound
+0xaf State:Hold
+0xb0 MovementRateModifier2
+0xb1 ApplyEffect
+0xb2 ToHitVsCreature
+0xb3 DamageVsCreature
+0xb4 CantUseItem
+0xb5 CantUseItemType
+0xb6 ApplyEffectItem
+0xb7 ApplyEffectItemType
+0xb8 DontJumpModifier
+0xb9 State:Hold2
+0xba MoveToArea
+0xbb Variable:StoreLocalVariable
+0xbc AuraCleansingModifier
+0xbd CastingSpeedModifier
+0xbe AttackSpeedModifier
+0xbf CastingLevelModifier
+0xc0 FindFamiliar
+0xc1 InvisibleDetection
+0xc2 IgnoreDialogPause
+0xc3 FamiliarBond
+0xc4 FamiliarMarker
+0xc5 Bounce:Projectile
+0xc6 Bounce:Opcode
+0xc7 Bounce:SpellLevel
+0xc8 Bounce:SpellLevelDec
+0xc9 Protection:SpellLevelDec
+0xca Bounce:School
+0xcb Bounce:SecondaryType
+0xcc Protection:School
+0xcd Protection:SecondaryType
+0xce Protection:Spell2
+0xcf Bounce:Spell
+0xd0 MinimumHPModifier
+0xd1 PowerWordKill
+0xd2 PowerWordStun
+0xd3 State:Imprisonment
+0xd4 Cure:Imprisonment
+0xd5 Maze
+0xd6 CastFromList
+0xd7 PlayVisualEffect
+0xd8 LevelDrainModifier
+0xd9 PowerWordSleep
+0xda StoneskinModifier
+0xdb ACVsCreatureType
+0xdc DispelSchool
+0xdd DispelSecondaryType
+0xde RandomTeleport
+0xdf Protection:SchoolDec
+0xe0 Cure:LevelDrain
+0xe1 Reveal:Magic
+0xe2 Protection:SecondaryTypeDec
+0xe3 Bounce:SchoolDec
+0xe4 Bounce:SecondaryTypeDec
+0xe5 DispelSchoolOne
+0xe6 DispelSecondaryTypeOne
+0xe7 TimeStop
+0xe8 Color:FadeRGB
+0xe9 IWDVisualSpellHit
+0xea ColdDamage
+0xeb CastingGlow2
+0xec ChillTouch
+0xed CrushingDamage
+0xee SaveBonus
+0xef SlowPoison
+0xf0 IWDMonsterSummoning
+0xf1 VampiricTouch
+0xf2 Overlay
+0xf3 AnimateDead
+0xf4 Prayer2
+0xf5 Curse2
+0xf6 SummonMonster2
+0xf7 BurningBlood
+0xf8 SummonShadowMonster
+0xf9 Recitation
+0xfa RecitationBad
+0xfb Hold2
+0xfc BlindingOrb
+0xfd ACVsDamageTypeModifier2
+0xfe RemoveEffects
+0xff SalamanderAura
+0x100 UmberHulkGaze
+0x101 ZombieLordAura
+0x102 Protection:Spell
+0x103 SummonCreature2
+0x104 AvatarRemoval
+0x105 Protection:Opcode2
+0x106 SummonPomab
+0x107 ControlCreature
+0x108 StaticCharge
+0x109 CloakOfFear
+0x10a MovementRateModifier3
+0x10b Cure:Confusion
+0x10c EyeOfTheMind
+0x10d EyeOfTheSword
+0x10e EyeOfTheMage
+0x10f EyeOfVenom
+0x110 EyeOfTheSpirit
+0x111 EyeOfFortitude
+0x112 EyeOfStone
+0x113 RemoveSevenEyes
+0x114 RemoveEffect
+0x115 SoulEater
+0x116 ShroudOfFlame
+0x117 AnimalRage
+0x118 TurnUndead
+0x119 VitriolicSphere
+0x11a SuppressHP
+0x11b FloatText
+0x11c MaceOfDisruption
+0x11d State:Sleep
+0x11e Reveal:Tracks
+0x11f Protection:Backstab
+0x120 State:Set
+0x121 Cutscene
+0x122 Protection:Spell3
+0x123 RodOfSmithing
+0x124 MagicalRest
+0x125 BeholderDispelMagic
+0x126 HarpyWail
+0x127 JackalWereGaze
+0x128 ModifyGlobalVariable
+0x129 HideInShadowsModifier
+0x12a UseMagicDeviceModifier
diff --git a/gemrb/override/iwd/electrh.pro b/gemrb/unhardcoded/iwd/electrh.pro
similarity index 100%
rename from gemrb/override/iwd/electrh.pro
rename to gemrb/unhardcoded/iwd/electrh.pro
diff --git a/gemrb/override/iwd/emotion.pro b/gemrb/unhardcoded/iwd/emotion.pro
similarity index 100%
rename from gemrb/override/iwd/emotion.pro
rename to gemrb/unhardcoded/iwd/emotion.pro
diff --git a/gemrb/override/iwd/enchah.pro b/gemrb/unhardcoded/iwd/enchah.pro
similarity index 100%
rename from gemrb/override/iwd/enchah.pro
rename to gemrb/unhardcoded/iwd/enchah.pro
diff --git a/gemrb/override/iwd/enchannp.pro b/gemrb/unhardcoded/iwd/enchannp.pro
similarity index 100%
rename from gemrb/override/iwd/enchannp.pro
rename to gemrb/unhardcoded/iwd/enchannp.pro
diff --git a/gemrb/override/iwd/enchat.pro b/gemrb/unhardcoded/iwd/enchat.pro
similarity index 100%
rename from gemrb/override/iwd/enchat.pro
rename to gemrb/unhardcoded/iwd/enchat.pro
diff --git a/gemrb/override/iwd/entangle.pro b/gemrb/unhardcoded/iwd/entangle.pro
similarity index 100%
rename from gemrb/override/iwd/entangle.pro
rename to gemrb/unhardcoded/iwd/entangle.pro
diff --git a/gemrb/override/iwd/equake.pro b/gemrb/unhardcoded/iwd/equake.pro
similarity index 100%
rename from gemrb/override/iwd/equake.pro
rename to gemrb/unhardcoded/iwd/equake.pro
diff --git a/gemrb/override/iwd/exaltah.pro b/gemrb/unhardcoded/iwd/exaltah.pro
similarity index 100%
rename from gemrb/override/iwd/exaltah.pro
rename to gemrb/unhardcoded/iwd/exaltah.pro
diff --git a/gemrb/override/iwd/factioh.pro b/gemrb/unhardcoded/iwd/factioh.pro
similarity index 100%
rename from gemrb/override/iwd/factioh.pro
rename to gemrb/unhardcoded/iwd/factioh.pro
diff --git a/gemrb/override/iwd/findtrap.pro b/gemrb/unhardcoded/iwd/findtrap.pro
similarity index 100%
rename from gemrb/override/iwd/findtrap.pro
rename to gemrb/unhardcoded/iwd/findtrap.pro
diff --git a/gemrb/override/iwd/fireball.pro b/gemrb/unhardcoded/iwd/fireball.pro
similarity index 100%
rename from gemrb/override/iwd/fireball.pro
rename to gemrb/unhardcoded/iwd/fireball.pro
diff --git a/gemrb/override/iwd/fireblic.pro b/gemrb/unhardcoded/iwd/fireblic.pro
similarity index 100%
rename from gemrb/override/iwd/fireblic.pro
rename to gemrb/unhardcoded/iwd/fireblic.pro
diff --git a/gemrb/override/iwd/firebolt.pro b/gemrb/unhardcoded/iwd/firebolt.pro
similarity index 100%
rename from gemrb/override/iwd/firebolt.pro
rename to gemrb/unhardcoded/iwd/firebolt.pro
diff --git a/gemrb/override/iwd/firebtbl.pro b/gemrb/unhardcoded/iwd/firebtbl.pro
similarity index 100%
rename from gemrb/override/iwd/firebtbl.pro
rename to gemrb/unhardcoded/iwd/firebtbl.pro
diff --git a/gemrb/override/iwd/fireh.pro b/gemrb/unhardcoded/iwd/fireh.pro
similarity index 100%
rename from gemrb/override/iwd/fireh.pro
rename to gemrb/unhardcoded/iwd/fireh.pro
diff --git a/gemrb/override/iwd/firestor.pro b/gemrb/unhardcoded/iwd/firestor.pro
similarity index 100%
rename from gemrb/override/iwd/firestor.pro
rename to gemrb/unhardcoded/iwd/firestor.pro
diff --git a/gemrb/override/iwd/fistweap.2da b/gemrb/unhardcoded/iwd/fistweap.2da
similarity index 100%
rename from gemrb/override/iwd/fistweap.2da
rename to gemrb/unhardcoded/iwd/fistweap.2da
diff --git a/gemrb/override/iwd/fodeath.pro b/gemrb/unhardcoded/iwd/fodeath.pro
similarity index 100%
rename from gemrb/override/iwd/fodeath.pro
rename to gemrb/unhardcoded/iwd/fodeath.pro
diff --git a/gemrb/unhardcoded/iwd/fonts.2da b/gemrb/unhardcoded/iwd/fonts.2da
new file mode 100644
index 0000000..df11966
--- /dev/null
+++ b/gemrb/unhardcoded/iwd/fonts.2da
@@ -0,0 +1,22 @@
+2DA V1.0
+NORMAL
+ RESREF NEED_PALETTE FONT_NAME PT_SIZE STYLE COLOR
+0 NORMAL 1 NORMAL 14 0 0xffffffff
+1 INFOFONT 1 INFOFONT 14 0 0xffffffff
+2 NUMBER 0 NUMBER 14 0 0xffffffff
+3 INITIALS 0 INITIALS 14 0 0xffffffff
+4 NUMBER2 0 NUMBER2 14 0 0xffffffff
+5 NUMBER3 0 NUMBER3 14 0 0xffffffff
+6 NUMFONT 1 NUMFONT 14 0 0xffffffff
+7 REALMS 0 REALMS 14 0 0xffffffff
+8 REALMS2 1 REALMS2 14 0 0xffffffff
+9 STONEBIG 0 STONEBIG 14 0 0xffffffff
+10 STONESM2 0 STONESM2 14 0 0xffffffff
+11 STONESM3 0 STONESM3 14 0 0xffffffff
+12 STONESML 0 STONESML 14 0 0xffffffff
+13 TOOLFONT 1 TOOLFONT 14 0 0xffffffff
+# state "fonts" are the status icons. You probably don't want to edit these.
+14 STATES 0 STATES 14 0 0xffffffff
+15 STATES2 0 STATES2 14 0 0xffffffff
+
+# Customization How To: http://gemrb.sourceforge.net/wiki/doku.php?id=plugins:ttf
diff --git a/gemrb/override/iwd/formatio.2da b/gemrb/unhardcoded/iwd/formatio.2da
similarity index 100%
rename from gemrb/override/iwd/formatio.2da
rename to gemrb/unhardcoded/iwd/formatio.2da
diff --git a/gemrb/override/iwd/fseed.pro b/gemrb/unhardcoded/iwd/fseed.pro
similarity index 100%
rename from gemrb/override/iwd/fseed.pro
rename to gemrb/unhardcoded/iwd/fseed.pro
diff --git a/gemrb/override/iwd/fstrikh.pro b/gemrb/unhardcoded/iwd/fstrikh.pro
similarity index 100%
rename from gemrb/override/iwd/fstrikh.pro
rename to gemrb/unhardcoded/iwd/fstrikh.pro
diff --git a/gemrb/unhardcoded/iwd/gametime.2da b/gemrb/unhardcoded/iwd/gametime.2da
new file mode 100644
index 0000000..ba22bbe
--- /dev/null
+++ b/gemrb/unhardcoded/iwd/gametime.2da
@@ -0,0 +1,6 @@
+2DA V1.0
+0
+ DURATION
+ROUND_SECONDS 7
+TURN_SECONDS 70
+ATTACK_ROUND 100
diff --git a/gemrb/override/iwd/garmorh.pro b/gemrb/unhardcoded/iwd/garmorh.pro
similarity index 100%
rename from gemrb/override/iwd/garmorh.pro
rename to gemrb/unhardcoded/iwd/garmorh.pro
diff --git a/gemrb/override/iwd/gaze.pro b/gemrb/unhardcoded/iwd/gaze.pro
similarity index 100%
rename from gemrb/override/iwd/gaze.pro
rename to gemrb/unhardcoded/iwd/gaze.pro
diff --git a/gemrb/override/iwd/gemprjtl.ids b/gemrb/unhardcoded/iwd/gemprjtl.ids
similarity index 100%
rename from gemrb/override/iwd/gemprjtl.ids
rename to gemrb/unhardcoded/iwd/gemprjtl.ids
diff --git a/gemrb/unhardcoded/iwd/gemrb.ini b/gemrb/unhardcoded/iwd/gemrb.ini
new file mode 100644
index 0000000..9578960
--- /dev/null
+++ b/gemrb/unhardcoded/iwd/gemrb.ini
@@ -0,0 +1,133 @@
+; GemRB - Infinity Engine Emulator
+; Copyright (C) 2003 The GemRB Project
+;
+; This program is free software; you can redistribute it and/or
+; modify it under the terms of the GNU General Public License
+; as published by the Free Software Foundation; either version 2
+; of the License, or (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program; if not, write to the Free Software
+; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+;
+
+
+; gemrb.ini - game type-specific settings for GemRB engine
+
+[resources]
+
+; Bitmap resource for cursors
+CursorBAM = CAROT
+
+; Bitmap resource for scroll cursor arrow
+ScrollCursorBAM = CURSARW
+
+; Bitmap resource for dialog buttons font
+ButtonFont = STONESML
+
+; Font used to display tooltips
+TooltipFont = TOOLFONT
+
+; Font used to display subtitles
+MovieFont = REALMS2
+
+; Sprite displayed behind the tooltip text, if any
+TooltipBack = TOOLTIP
+
+; Tooltip text color (RGBA)
+TooltipColor = #ffffffff
+
+; Space between tooltip text and sides of TooltipBack (x2)
+TooltipMargin = 2
+
+; INI file from the original games
+INIConfig = icewind.ini
+
+; Palette bitmaps in various widths
+Palette16 = MPALETTE
+Palette32 = MPALETTE
+Palette256 = MPAL256
+
+3EdRules = 0
+AllStringsTagged = 1
+AreaVisitedVar = 1
+AreaOverride = 0
+AutomapINI = 0
+AutoSearchHidden = 1
+BiographyIsRes = 1
+BreakableWeapons = 0
+CastingSounds = 1
+ChallengeRating = 0
+CharNameIsGabber = 1
+CheckAbilities = 0
+ClearUnusedArea = 0
+CutsceneAreascripts = 0
+DeathOnZeroStat = 0
+DialogueScrolls = 0
+EnhancedCastingSounds = 0
+EnhancedEffects = 0
+FistStat = 232
+FlexibleWorldmap = 1
+ForceAreaScript = 1
+ForceStereo = 0
+HasBeastsINI = 0
+HasDescIcon = 0
+HasDPLAYER = 1
+HasEXPTABLE = 1
+HasFloatMenu = 0
+HasHideInShadows = 1
+HasKaputz = 0
+HasNoNPCFlag = 0
+HasPartyINI = 0
+HasPickSound = 0
+HasResDataIni = 0
+HasSongList = 0
+HasSoundsIni = 1
+HasSpecificDamageBonus = 0
+HasSpellList = 0
+HasUsePointFlag = 0
+HasWisdomBonusTable = 0
+HealOn100Plus = 1
+IgnoreButtonFrames = 0
+ImplicitAreaAnimBackground = 1
+InPartyAllowsDead = 1
+IWD2DeathVarFormat = 0
+IWD2ScriptName = 1
+IWDMapDimensions = 1
+JournalHasSections = 0
+KnowWorld = 0
+LevelslotPerClass = 0
+LowerLabelText = 0
+MagicBit = 0
+MaximumAbility = 25
+NoDropCanMove = 0
+NoNewVariables = 0
+OneByteAnimationID = 0
+OnScreenText = 0
+NoUndroppable = 1
+OverrideCursorPos = 0
+ProperBackstab = 0
+ProtagonistTalks = 0
+PSTStateFlags = 0
+RareActionSounds = 0
+RedrawTile = 0
+ReverseDoor = 0
+ReverseToHit = 1
+SaveForHalfDamage = 0
+SelectiveMagicRes = 0
+SkipUpdateHack = 1
+SmallFog = 0
+SoundFolders = 1
+SpawnIni = 1
+SpellBookIconHack = 0
+StartActive = 0
+StealIsAttack = 0
+StrrefSaveGame = 0
+TeamMovement = 0
+UpperButtonText = 0
+ZeroTimerIsValid = 1
diff --git a/gemrb/override/iwd/gender.2da b/gemrb/unhardcoded/iwd/gender.2da
similarity index 100%
rename from gemrb/override/iwd/gender.2da
rename to gemrb/unhardcoded/iwd/gender.2da
diff --git a/gemrb/override/iwd/golcloud.pro b/gemrb/unhardcoded/iwd/golcloud.pro
similarity index 100%
rename from gemrb/override/iwd/golcloud.pro
rename to gemrb/unhardcoded/iwd/golcloud.pro
diff --git a/gemrb/override/iwd/grease.pro b/gemrb/unhardcoded/iwd/grease.pro
similarity index 100%
rename from gemrb/override/iwd/grease.pro
rename to gemrb/unhardcoded/iwd/grease.pro
diff --git a/gemrb/override/iwd/gshout.pro b/gemrb/unhardcoded/iwd/gshout.pro
similarity index 100%
rename from gemrb/override/iwd/gshout.pro
rename to gemrb/unhardcoded/iwd/gshout.pro
diff --git a/gemrb/override/iwd/guibtact.2da b/gemrb/unhardcoded/iwd/guibtact.2da
similarity index 100%
rename from gemrb/override/iwd/guibtact.2da
rename to gemrb/unhardcoded/iwd/guibtact.2da
diff --git a/gemrb/override/iwd/guils.chu b/gemrb/unhardcoded/iwd/guils.chu
similarity index 100%
rename from gemrb/override/iwd/guils.chu
rename to gemrb/unhardcoded/iwd/guils.chu
diff --git a/gemrb/override/iwd/harmh.pro b/gemrb/unhardcoded/iwd/harmh.pro
similarity index 100%
rename from gemrb/override/iwd/harmh.pro
rename to gemrb/unhardcoded/iwd/harmh.pro
diff --git a/gemrb/override/iwd/harmony.pro b/gemrb/unhardcoded/iwd/harmony.pro
similarity index 100%
rename from gemrb/override/iwd/harmony.pro
rename to gemrb/unhardcoded/iwd/harmony.pro
diff --git a/gemrb/override/iwd/haterace.2da b/gemrb/unhardcoded/iwd/haterace.2da
similarity index 100%
rename from gemrb/override/iwd/haterace.2da
rename to gemrb/unhardcoded/iwd/haterace.2da
diff --git a/gemrb/override/iwd/healh.pro b/gemrb/unhardcoded/iwd/healh.pro
similarity index 100%
rename from gemrb/override/iwd/healh.pro
rename to gemrb/unhardcoded/iwd/healh.pro
diff --git a/gemrb/override/iwd/hmighth.pro b/gemrb/unhardcoded/iwd/hmighth.pro
similarity index 100%
rename from gemrb/override/iwd/hmighth.pro
rename to gemrb/unhardcoded/iwd/hmighth.pro
diff --git a/gemrb/override/iwd/hold.pro b/gemrb/unhardcoded/iwd/hold.pro
similarity index 100%
rename from gemrb/override/iwd/hold.pro
rename to gemrb/unhardcoded/iwd/hold.pro
diff --git a/gemrb/override/iwd/hsmite.pro b/gemrb/unhardcoded/iwd/hsmite.pro
similarity index 100%
rename from gemrb/override/iwd/hsmite.pro
rename to gemrb/unhardcoded/iwd/hsmite.pro
diff --git a/gemrb/override/iwd/hword.pro b/gemrb/unhardcoded/iwd/hword.pro
similarity index 100%
rename from gemrb/override/iwd/hword.pro
rename to gemrb/unhardcoded/iwd/hword.pro
diff --git a/gemrb/override/iwd/icelance.pro b/gemrb/unhardcoded/iwd/icelance.pro
similarity index 100%
rename from gemrb/override/iwd/icelance.pro
rename to gemrb/unhardcoded/iwd/icelance.pro
diff --git a/gemrb/override/iwd/icestorm.pro b/gemrb/unhardcoded/iwd/icestorm.pro
similarity index 100%
rename from gemrb/override/iwd/icestorm.pro
rename to gemrb/unhardcoded/iwd/icestorm.pro
diff --git a/gemrb/override/iwd/icloud.pro b/gemrb/unhardcoded/iwd/icloud.pro
similarity index 100%
rename from gemrb/override/iwd/icloud.pro
rename to gemrb/unhardcoded/iwd/icloud.pro
diff --git a/gemrb/override/iwd/iclouda.pro b/gemrb/unhardcoded/iwd/iclouda.pro
similarity index 100%
rename from gemrb/override/iwd/iclouda.pro
rename to gemrb/unhardcoded/iwd/iclouda.pro
diff --git a/gemrb/override/iwd/icloudb.pro b/gemrb/unhardcoded/iwd/icloudb.pro
similarity index 100%
rename from gemrb/override/iwd/icloudb.pro
rename to gemrb/unhardcoded/iwd/icloudb.pro
diff --git a/gemrb/override/iwd/illush.pro b/gemrb/unhardcoded/iwd/illush.pro
similarity index 100%
rename from gemrb/override/iwd/illush.pro
rename to gemrb/unhardcoded/iwd/illush.pro
diff --git a/gemrb/override/iwd/illust.pro b/gemrb/unhardcoded/iwd/illust.pro
similarity index 100%
rename from gemrb/override/iwd/illust.pro
rename to gemrb/unhardcoded/iwd/illust.pro
diff --git a/gemrb/override/iwd/inarea.pro b/gemrb/unhardcoded/iwd/inarea.pro
similarity index 100%
rename from gemrb/override/iwd/inarea.pro
rename to gemrb/unhardcoded/iwd/inarea.pro
diff --git a/gemrb/override/iwd/inareanp.pro b/gemrb/unhardcoded/iwd/inareanp.pro
similarity index 100%
rename from gemrb/override/iwd/inareanp.pro
rename to gemrb/unhardcoded/iwd/inareanp.pro
diff --git a/gemrb/unhardcoded/iwd/inareapa.pro b/gemrb/unhardcoded/iwd/inareapa.pro
new file mode 100644
index 0000000..fedb699
Binary files /dev/null and b/gemrb/unhardcoded/iwd/inareapa.pro differ
diff --git a/gemrb/override/iwd/inareasm.pro b/gemrb/unhardcoded/iwd/inareasm.pro
similarity index 100%
rename from gemrb/override/iwd/inareasm.pro
rename to gemrb/unhardcoded/iwd/inareasm.pro
diff --git a/gemrb/override/iwd/invoch.pro b/gemrb/unhardcoded/iwd/invoch.pro
similarity index 100%
rename from gemrb/override/iwd/invoch.pro
rename to gemrb/unhardcoded/iwd/invoch.pro
diff --git a/gemrb/override/iwd/invoct.pro b/gemrb/unhardcoded/iwd/invoct.pro
similarity index 100%
rename from gemrb/override/iwd/invoct.pro
rename to gemrb/unhardcoded/iwd/invoct.pro
diff --git a/gemrb/override/iwd/iplague.pro b/gemrb/unhardcoded/iwd/iplague.pro
similarity index 100%
rename from gemrb/override/iwd/iplague.pro
rename to gemrb/unhardcoded/iwd/iplague.pro
diff --git a/gemrb/unhardcoded/iwd/itemsnd.2da b/gemrb/unhardcoded/iwd/itemsnd.2da
new file mode 100644
index 0000000..adffeb0
--- /dev/null
+++ b/gemrb/unhardcoded/iwd/itemsnd.2da
@@ -0,0 +1,81 @@
+2DA V1.0
+*
+ TAKE DROP
+MISC G_BOOK1 G_BOOK2
+AMULET G_NECK1 G_NECK2
+ARMOR G_CLOAK1 G_CLOAK2
+BELT G_BELT1 G_BELT2
+BOOT G_BOOT1 G_BOOT2
+ARROW G_ARRW1 G_ARRW2
+BRACER G_GLOVE1 G_GLOVE2
+HELMET G_HELM1 G_HELM2
+KEY G_KEY1 G_KEY2
+POTION G_POTN1 G_POTN2
+RING G_RING1 G_RING2
+SCROLL G_SCROL1 G_SCROL2
+SHIELD GAM_21A GAM_21B
+FOOD GAM_21A GAM_21B
+BULLET G_BULLT1 G_BULLT2
+BOW G_BOW1 G_BOW2
+DAGGER G_DAGGR1 G_DAGGR2
+MACE G_MACE1 G_MACE2
+SLING G_SLING1 G_SLING2
+SMSWORD G_SMSWD1 G_SMSWD2
+BGSWORD G_LGSWD1 G_LGSWD2
+HAMMER G_HAMMR1 G_HAMMR2
+MSTAR G_MSTAR1 G_MSTAR2
+FLAIL G_FLAIL1 G_FLAIL2
+DART G_DART1 G_DART2
+AXE G_AXE1 G_AXE2
+STAFF G_STAFF1 G_STAFF2
+XBOW G_CROSB1 G_CROSB2
+FIST GAM_21A GAM_21B
+SPEAR G_SPEAR1 G_SPEAR2
+POLEARM G_HALB1 G_HALB2
+BOLT G_BOLT1 G_BOLT2
+CLOAK G_CLOAK1 G_CLOAK2
+COIN G_GOLD1 G_GOLD2
+GEM G_GEM1 G_GEM2
+WAND G_WAND1 G_WAND2
+BROKEN1 G_B_ARM1 G_B_ARM2
+BROKEN2 G_B_SHD1 G_B_SHD2
+BROKEN3 G_B_WPN1 G_B_WPN2
+UNUSED1 GAM_21A GAM_21B
+UNUSED2 G_BROKN1 G_BROKN2
+BUCKLER G_BUCKR1 G_BUCKR2
+CANDLE G_CAND1 G_CAND2
+CBODY G_CHILD1 G_CHILD2
+CLUB G_CLUB1 G_CLUB2
+FBODY G_FEM1 G_FEM2
+KEY2 G_KEYS1 G_KEYS2
+LSHIELD G_LGSLD1 G_LGSLD2
+MBODY G_MALE1 G_MALE2
+MSHIELD G_MDSLD1 G_MDSLD2
+NOTES G_PAPR1 G_PAPR2
+ROD G_ROD1 G_ROD2
+SKULL G_SKULL1 G_SKULL2
+SSHIELD G_SMSLD1 G_SMSLD2
+SPIDER G_SPIDR1 G_SPIDR2
+TELESCOPE G_TELE1 G_TELE2
+DRINK G_WINE1 G_WINE2
+GTSWORD G_LGSWD1 G_LGSWD2
+BAG GAM_21A GAM_21B
+FUR G_LETHR1 G_LETHR2
+LARMOR G_CLOAK1 G_CLOAK2
+SLARMOR G_CLOAK1 G_CLOAK2
+CHARMOR G_CLOAK1 G_CLOAK2
+SPARMOR G_CLOAK1 G_CLOAK2
+HPARMOR G_CLOAK1 G_CLOAK2
+FPARMOR G_CLOAK1 G_CLOAK2
+HARMOR G_CLOAK1 G_CLOAK2
+ROBE G_CLOAK1 G_CLOAK2
+SCALE G_CLOAK1 G_CLOAK2
+BTSWORD G_LGSWD1 G_LGSWD2
+SCARF G_GLOVE1 G_GLOVE2
+FOOD2 G_SLING1 G_SLING2
+HAT G_GLOVE1 G_GLOVE2
+GAUNTLET G_CAND1 G_CAND2
+DEFAULT GAM_21A GAM_21B
+LEATHER G_LETHR1 G_LETHR2
+CHAIN G_Chain1 G_Chain2
+PLATE G_Plate1 G_Plate2
diff --git a/gemrb/unhardcoded/iwd/itemtype.2da b/gemrb/unhardcoded/iwd/itemtype.2da
new file mode 100644
index 0000000..f5b10f8
--- /dev/null
+++ b/gemrb/unhardcoded/iwd/itemtype.2da
@@ -0,0 +1,77 @@
+2DA V1.0
+0
+ HELMET ARMOR SHIELD GLOVES RING AMULET BELT BOOTS WEAPON QUIVER CLOAK QUICK SCROLL BAG POTION
+MISC 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
+AMULET 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
+ARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+BELT 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
+BOOT 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
+ARROW 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
+BRACER 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
+HELMET 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+KEY 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+POTION 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
+RING 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
+SCROLL 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0
+SHIELD 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
+FOOD 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
+BULLET 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
+BOW 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+DAGGER 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+MACE 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+SLING 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+SMSWORD 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+BGSWORD 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+HAMMER 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+MSTAR 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+FLAIL 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+DART 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+AXE 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+STAFF 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+XBOW 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+FIST 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+SPEAR 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+POLEARM 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+BOLT 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
+CLOAK 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
+COIN 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+GEM 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
+WAND 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
+BROKEN1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+BROKEN2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+BROKEN3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+UNUSED1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+UNUSED2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+BUCKLER 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
+CANDLE 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+UNUSED3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+CLUB 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+UNUSED4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+UNUSED5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+LSHIELD 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
+UNUSED6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+MSHIELD 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
+NOTES 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+UNUSED7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+UNUSED8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+SSHIELD 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
+UNUSED9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+TELESCOPE 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+DRINK 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
+GTSWORD 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+BAG 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
+FUR 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+LARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+SLARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+CHARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+SPARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+HPARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+FPARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+HARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+ROBE 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+UNUSED10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+BTSWORD 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+SCARF 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
+FOOD2 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
+HAT 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+GAUNTLET 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
diff --git a/gemrb/override/iwd/itemuse.2da b/gemrb/unhardcoded/iwd/itemuse.2da
similarity index 100%
rename from gemrb/override/iwd/itemuse.2da
rename to gemrb/unhardcoded/iwd/itemuse.2da
diff --git a/gemrb/override/iwd/kitlist.2da b/gemrb/unhardcoded/iwd/kitlist.2da
similarity index 100%
rename from gemrb/override/iwd/kitlist.2da
rename to gemrb/unhardcoded/iwd/kitlist.2da
diff --git a/gemrb/override/iwd/lightb.pro b/gemrb/unhardcoded/iwd/lightb.pro
similarity index 100%
rename from gemrb/override/iwd/lightb.pro
rename to gemrb/unhardcoded/iwd/lightb.pro
diff --git a/gemrb/unhardcoded/iwd/lightbnb.pro b/gemrb/unhardcoded/iwd/lightbnb.pro
new file mode 100644
index 0000000..60ad208
Binary files /dev/null and b/gemrb/unhardcoded/iwd/lightbnb.pro differ
diff --git a/gemrb/override/iwd/lightsto.pro b/gemrb/unhardcoded/iwd/lightsto.pro
similarity index 100%
rename from gemrb/override/iwd/lightsto.pro
rename to gemrb/unhardcoded/iwd/lightsto.pro
diff --git a/gemrb/override/iwd/lodisr.pro b/gemrb/unhardcoded/iwd/lodisr.pro
similarity index 100%
rename from gemrb/override/iwd/lodisr.pro
rename to gemrb/unhardcoded/iwd/lodisr.pro
diff --git a/gemrb/unhardcoded/iwd/magesch.2da b/gemrb/unhardcoded/iwd/magesch.2da
new file mode 100644
index 0000000..70deb9f
--- /dev/null
+++ b/gemrb/unhardcoded/iwd/magesch.2da
@@ -0,0 +1,12 @@
+2DA V1.0
+-1
+ NAME_REF DESC_REF CAP_REF KIT
+GENERALIST 18039 9563 9987 0x4000
+ABJURER 597 9564 502 0x40
+CONJURER 2179 9565 504 0x80
+DIVINER 2846 9566 2012 0x100
+ENCHANTER 2861 9567 2022 0x200
+ILLUSIONIST 2862 9568 12785 0x400
+INVOKER 3015 9569 12786 0x800
+NECROMANCER 12744 9570 12787 0x1000
+TRANSMUTER 12745 9571 12788 0x2000
diff --git a/gemrb/override/iwd/magicmis.pro b/gemrb/unhardcoded/iwd/magicmis.pro
similarity index 100%
rename from gemrb/override/iwd/magicmis.pro
rename to gemrb/unhardcoded/iwd/magicmis.pro
diff --git a/gemrb/override/iwd/malison.pro b/gemrb/unhardcoded/iwd/malison.pro
similarity index 100%
rename from gemrb/override/iwd/malison.pro
rename to gemrb/unhardcoded/iwd/malison.pro
diff --git a/gemrb/override/iwd/mfmiss.pro b/gemrb/unhardcoded/iwd/mfmiss.pro
similarity index 100%
rename from gemrb/override/iwd/mfmiss.pro
rename to gemrb/unhardcoded/iwd/mfmiss.pro
diff --git a/gemrb/override/iwd/mfmiss2.pro b/gemrb/unhardcoded/iwd/mfmiss2.pro
similarity index 100%
rename from gemrb/override/iwd/mfmiss2.pro
rename to gemrb/unhardcoded/iwd/mfmiss2.pro
diff --git a/gemrb/override/iwd/mfmissh.pro b/gemrb/unhardcoded/iwd/mfmissh.pro
similarity index 100%
rename from gemrb/override/iwd/mfmissh.pro
rename to gemrb/unhardcoded/iwd/mfmissh.pro
diff --git a/gemrb/override/iwd/mmagich.pro b/gemrb/unhardcoded/iwd/mmagich.pro
similarity index 100%
rename from gemrb/override/iwd/mmagich.pro
rename to gemrb/unhardcoded/iwd/mmagich.pro
diff --git a/gemrb/override/iwd/mmissile.pro b/gemrb/unhardcoded/iwd/mmissile.pro
similarity index 100%
rename from gemrb/override/iwd/mmissile.pro
rename to gemrb/unhardcoded/iwd/mmissile.pro
diff --git a/gemrb/override/iwd/moelda.pro b/gemrb/unhardcoded/iwd/moelda.pro
similarity index 100%
rename from gemrb/override/iwd/moelda.pro
rename to gemrb/unhardcoded/iwd/moelda.pro
diff --git a/gemrb/override/iwd/mpal256.bmp b/gemrb/unhardcoded/iwd/mpal256.bmp
similarity index 100%
rename from gemrb/override/iwd/mpal256.bmp
rename to gemrb/unhardcoded/iwd/mpal256.bmp
diff --git a/gemrb/override/iwd/mrage.pro b/gemrb/unhardcoded/iwd/mrage.pro
similarity index 100%
rename from gemrb/override/iwd/mrage.pro
rename to gemrb/unhardcoded/iwd/mrage.pro
diff --git a/gemrb/override/iwd/mrageh.pro b/gemrb/unhardcoded/iwd/mrageh.pro
similarity index 100%
rename from gemrb/override/iwd/mrageh.pro
rename to gemrb/unhardcoded/iwd/mrageh.pro
diff --git a/gemrb/override/iwd/mspore.pro b/gemrb/unhardcoded/iwd/mspore.pro
similarity index 100%
rename from gemrb/override/iwd/mspore.pro
rename to gemrb/unhardcoded/iwd/mspore.pro
diff --git a/gemrb/override/iwd/msumm1.pro b/gemrb/unhardcoded/iwd/msumm1.pro
similarity index 100%
rename from gemrb/override/iwd/msumm1.pro
rename to gemrb/unhardcoded/iwd/msumm1.pro
diff --git a/gemrb/override/iwd/msumm1h.pro b/gemrb/unhardcoded/iwd/msumm1h.pro
similarity index 100%
rename from gemrb/override/iwd/msumm1h.pro
rename to gemrb/unhardcoded/iwd/msumm1h.pro
diff --git a/gemrb/override/iwd/msumm1x.pro b/gemrb/unhardcoded/iwd/msumm1x.pro
similarity index 100%
rename from gemrb/override/iwd/msumm1x.pro
rename to gemrb/unhardcoded/iwd/msumm1x.pro
diff --git a/gemrb/override/iwd/msumm2h.pro b/gemrb/unhardcoded/iwd/msumm2h.pro
similarity index 100%
rename from gemrb/override/iwd/msumm2h.pro
rename to gemrb/unhardcoded/iwd/msumm2h.pro
diff --git a/gemrb/override/iwd/msumm3h.pro b/gemrb/unhardcoded/iwd/msumm3h.pro
similarity index 100%
rename from gemrb/override/iwd/msumm3h.pro
rename to gemrb/unhardcoded/iwd/msumm3h.pro
diff --git a/gemrb/override/iwd/msumm4h.pro b/gemrb/unhardcoded/iwd/msumm4h.pro
similarity index 100%
rename from gemrb/override/iwd/msumm4h.pro
rename to gemrb/unhardcoded/iwd/msumm4h.pro
diff --git a/gemrb/override/iwd/msumm5h.pro b/gemrb/unhardcoded/iwd/msumm5h.pro
similarity index 100%
rename from gemrb/override/iwd/msumm5h.pro
rename to gemrb/unhardcoded/iwd/msumm5h.pro
diff --git a/gemrb/override/iwd/msumm6h.pro b/gemrb/unhardcoded/iwd/msumm6h.pro
similarity index 100%
rename from gemrb/override/iwd/msumm6h.pro
rename to gemrb/unhardcoded/iwd/msumm6h.pro
diff --git a/gemrb/override/iwd/msumm7h.pro b/gemrb/unhardcoded/iwd/msumm7h.pro
similarity index 100%
rename from gemrb/override/iwd/msumm7h.pro
rename to gemrb/unhardcoded/iwd/msumm7h.pro
diff --git a/gemrb/override/iwd/mswordh.pro b/gemrb/unhardcoded/iwd/mswordh.pro
similarity index 100%
rename from gemrb/override/iwd/mswordh.pro
rename to gemrb/unhardcoded/iwd/mswordh.pro
diff --git a/gemrb/override/iwd/mtouchh.pro b/gemrb/unhardcoded/iwd/mtouchh.pro
similarity index 100%
rename from gemrb/override/iwd/mtouchh.pro
rename to gemrb/unhardcoded/iwd/mtouchh.pro
diff --git a/gemrb/override/iwd/necroh.pro b/gemrb/unhardcoded/iwd/necroh.pro
similarity index 100%
rename from gemrb/override/iwd/necroh.pro
rename to gemrb/unhardcoded/iwd/necroh.pro
diff --git a/gemrb/override/iwd/necrot.pro b/gemrb/unhardcoded/iwd/necrot.pro
similarity index 100%
rename from gemrb/override/iwd/necrot.pro
rename to gemrb/unhardcoded/iwd/necrot.pro
diff --git a/gemrb/override/iwd/npoisoh.pro b/gemrb/unhardcoded/iwd/npoisoh.pro
similarity index 100%
rename from gemrb/override/iwd/npoisoh.pro
rename to gemrb/unhardcoded/iwd/npoisoh.pro
diff --git a/gemrb/override/iwd/ofsphe.pro b/gemrb/unhardcoded/iwd/ofsphe.pro
similarity index 100%
rename from gemrb/override/iwd/ofsphe.pro
rename to gemrb/unhardcoded/iwd/ofsphe.pro
diff --git a/gemrb/unhardcoded/iwd/overlay.2da b/gemrb/unhardcoded/iwd/overlay.2da
new file mode 100644
index 0000000..6fe746e
--- /dev/null
+++ b/gemrb/unhardcoded/iwd/overlay.2da
@@ -0,0 +1,35 @@
+2DA V1.0
+*
+ VVC UNDER FLAGS
+SANCTUARY SANCTUC 0 1
+ENTANGLE ENTANGC 0 0
+WISP WISP 0 0
+SHIELDGLOBE SHIELDC 0 1
+GREASE GREASEC 1 0
+WEB WEBC 1 0
+MINORGLOBE MGOINVC 0 1
+GLOBE GOINVUC 0 1
+FLAMESHROUD SOFLAMC 0 0
+ANTIMAGIC AMSHELC 0 0
+RESILIENT ORSPHEC 0 0
+PROTFROMMISS PFNMISC 0 0
+CLOAKOFFEAR COFEARC 0 0
+ENTROPY ESHIELC 0 0
+FIREAURA FIAURAC 0 0
+FROSTAURA FRAURAC 0 0
+INSECT IPLAGUC 0 0
+STORMSHELL SSHELLC 0 0
+LATHANDER1 SOLATC1 0 0
+LATHANDER2 SOLATC2 1 0
+GLATHANDER1 GSOLAC1 0 0
+GLATHANDER2 GSOLAC2 1 0
+SEVENEYES1 SEYESC1 0 0
+SEVENEYES2 SEYESC2 1 0
+BOUNCE SPTURNI2 1 0
+BOUNCE2 SPSTURNI 1 0
+FIRESHIELD1 FSHIRC1 0 0
+FIRESHIELD2 FSHIRC2 1 0
+ICESHIELD1 FSHIBC1 0 0
+ICESHIELD2 FSHIBC2 1 0
+TORTOISE TSHELLC 0 0
+DEATHARMOR DARMORC 0 0
diff --git a/gemrb/override/iwd/paralh.pro b/gemrb/unhardcoded/iwd/paralh.pro
similarity index 100%
rename from gemrb/override/iwd/paralh.pro
rename to gemrb/unhardcoded/iwd/paralh.pro
diff --git a/gemrb/override/iwd/pathfind.2da b/gemrb/unhardcoded/iwd/pathfind.2da
similarity index 100%
rename from gemrb/override/iwd/pathfind.2da
rename to gemrb/unhardcoded/iwd/pathfind.2da
diff --git a/gemrb/override/iwd/pdolls.2da b/gemrb/unhardcoded/iwd/pdolls.2da
similarity index 100%
rename from gemrb/override/iwd/pdolls.2da
rename to gemrb/unhardcoded/iwd/pdolls.2da
diff --git a/gemrb/override/iwd/pfire.pro b/gemrb/unhardcoded/iwd/pfire.pro
similarity index 100%
rename from gemrb/override/iwd/pfire.pro
rename to gemrb/unhardcoded/iwd/pfire.pro
diff --git a/gemrb/override/iwd/pictures.2da b/gemrb/unhardcoded/iwd/pictures.2da
similarity index 100%
rename from gemrb/override/iwd/pictures.2da
rename to gemrb/unhardcoded/iwd/pictures.2da
diff --git a/gemrb/override/iwd/poisonh.pro b/gemrb/unhardcoded/iwd/poisonh.pro
similarity index 100%
rename from gemrb/override/iwd/poisonh.pro
rename to gemrb/unhardcoded/iwd/poisonh.pro
diff --git a/gemrb/override/iwd/pomab.2da b/gemrb/unhardcoded/iwd/pomab.2da
similarity index 100%
rename from gemrb/override/iwd/pomab.2da
rename to gemrb/unhardcoded/iwd/pomab.2da
diff --git a/gemrb/override/iwd/portal.pro b/gemrb/unhardcoded/iwd/portal.pro
similarity index 100%
rename from gemrb/override/iwd/portal.pro
rename to gemrb/unhardcoded/iwd/portal.pro
diff --git a/gemrb/override/iwd/prayer.pro b/gemrb/unhardcoded/iwd/prayer.pro
similarity index 100%
rename from gemrb/override/iwd/prayer.pro
rename to gemrb/unhardcoded/iwd/prayer.pro
diff --git a/gemrb/override/iwd/prayerh.pro b/gemrb/unhardcoded/iwd/prayerh.pro
similarity index 100%
rename from gemrb/override/iwd/prayerh.pro
rename to gemrb/unhardcoded/iwd/prayerh.pro
diff --git a/gemrb/unhardcoded/iwd/proftype.2da b/gemrb/unhardcoded/iwd/proftype.2da
new file mode 100644
index 0000000..ebd9cfa
--- /dev/null
+++ b/gemrb/unhardcoded/iwd/proftype.2da
@@ -0,0 +1,61 @@
+2DA V1.0
+-1
+ OLD_PROFICIENCY
+0 -1
+1 -1
+2 -1
+3 -1
+4 -1
+5 -1
+6 -1
+7 -1
+8 -1
+9 -1
+10 -1
+11 -1
+12 -1
+13 -1
+14 -1
+15_BOW 2
+16_DAGGER 7
+17_MACE 9
+18_SLING 5
+19_SWORD 1
+20_BIG 0
+21_HAMMER 11
+22_MS 9
+23_FLAIL 10
+24_DART 5
+25_AXE 4
+26_STAFF 13
+27_XBOW 14
+28_HAND -2
+29_SPEAR 3
+30_HALBERD 8
+31 -1
+32 -1
+33 -1
+34 -1
+35 -1
+36 -1
+37 -1
+38 -1
+39 -1
+40 -1
+41 -1
+42 -1
+43 -1
+44_CLUB 12
+45 -1
+46 -1
+47 -1
+48 -1
+49 -1
+50 -1
+51 -1
+52 -1
+53 -1
+54 -1
+55 -1
+56 -1
+57_GREATSWORD 6
diff --git a/gemrb/override/iwd/protevil.pro b/gemrb/unhardcoded/iwd/protevil.pro
similarity index 100%
rename from gemrb/override/iwd/protevil.pro
rename to gemrb/unhardcoded/iwd/protevil.pro
diff --git a/gemrb/override/iwd/prtl_cl.pro b/gemrb/unhardcoded/iwd/prtl_cl.pro
similarity index 100%
rename from gemrb/override/iwd/prtl_cl.pro
rename to gemrb/unhardcoded/iwd/prtl_cl.pro
diff --git a/gemrb/override/iwd/prtl_cl.spl b/gemrb/unhardcoded/iwd/prtl_cl.spl
similarity index 100%
rename from gemrb/override/iwd/prtl_cl.spl
rename to gemrb/unhardcoded/iwd/prtl_cl.spl
diff --git a/gemrb/override/iwd/prtl_op.pro b/gemrb/unhardcoded/iwd/prtl_op.pro
similarity index 100%
rename from gemrb/override/iwd/prtl_op.pro
rename to gemrb/unhardcoded/iwd/prtl_op.pro
diff --git a/gemrb/override/iwd/prtl_op.spl b/gemrb/unhardcoded/iwd/prtl_op.spl
similarity index 100%
rename from gemrb/override/iwd/prtl_op.spl
rename to gemrb/unhardcoded/iwd/prtl_op.spl
diff --git a/gemrb/override/iwd/pspray.pro b/gemrb/unhardcoded/iwd/pspray.pro
similarity index 100%
rename from gemrb/override/iwd/pspray.pro
rename to gemrb/unhardcoded/iwd/pspray.pro
diff --git a/gemrb/override/iwd/pwkill.pro b/gemrb/unhardcoded/iwd/pwkill.pro
similarity index 100%
rename from gemrb/override/iwd/pwkill.pro
rename to gemrb/unhardcoded/iwd/pwkill.pro
diff --git a/gemrb/override/iwd/pwsileh.pro b/gemrb/unhardcoded/iwd/pwsileh.pro
similarity index 100%
rename from gemrb/override/iwd/pwsileh.pro
rename to gemrb/unhardcoded/iwd/pwsileh.pro
diff --git a/gemrb/override/iwd/pwstun.pro b/gemrb/unhardcoded/iwd/pwstun.pro
similarity index 100%
rename from gemrb/override/iwd/pwstun.pro
rename to gemrb/unhardcoded/iwd/pwstun.pro
diff --git a/gemrb/override/iwd/pwstunh.pro b/gemrb/unhardcoded/iwd/pwstunh.pro
similarity index 100%
rename from gemrb/override/iwd/pwstunh.pro
rename to gemrb/unhardcoded/iwd/pwstunh.pro
diff --git a/gemrb/unhardcoded/iwd/qslots.2da b/gemrb/unhardcoded/iwd/qslots.2da
new file mode 100644
index 0000000..f3103af
--- /dev/null
+++ b/gemrb/unhardcoded/iwd/qslots.2da
@@ -0,0 +1,23 @@
+2DA V1.0
+100
+ SLOT1 SLOT2 SLOT3 SLOT4 SLOT5 SLOT6 SLOT7 SLOT8 SLOT9
+MAGE 3 4 5 2 8 9 11 12 13
+FIGHTER 18 19 14 100 8 9 11 12 13
+CLERIC 6 3 4 2 8 9 11 12 13
+THIEF 22 0 1 100 8 9 11 12 13
+BARD 20 1 3 2 8 9 11 12 13
+PALADIN 18 14 6 2 8 9 11 12 13
+FIGHTER_MAGE 3 4 5 2 8 9 11 12 13
+FIGHTER_CLERIC 6 3 4 2 8 9 11 12 13
+FIGHTER_THIEF 18 22 0 1 8 9 11 12 13
+FIGHTER_MAGE_THIEF 22 0 1 2 8 9 11 12 13
+DRUID 3 4 5 2 8 9 11 12 13
+RANGER 18 14 0 2 8 9 11 12 13
+MAGE_THIEF 22 0 1 2 8 9 11 12 13
+CLERIC_MAGE 6 3 4 2 8 9 11 12 13
+CLERIC_THIEF 22 0 1 2 8 9 11 12 13
+FIGHTER_DRUID 3 4 5 2 8 9 11 12 13
+FIGHTER_MAGE_CLERIC 6 3 4 2 8 9 11 12 13
+CLERIC_RANGER 6 3 4 2 8 9 11 12 13
+SORCERER 3 4 5 2 8 9 11 12 13
+MONK 18 14 22 0 8 9 11 12 13
diff --git a/gemrb/override/iwd/races.2da b/gemrb/unhardcoded/iwd/races.2da
similarity index 100%
rename from gemrb/override/iwd/races.2da
rename to gemrb/unhardcoded/iwd/races.2da
diff --git a/gemrb/override/iwd/rad100.pro b/gemrb/unhardcoded/iwd/rad100.pro
similarity index 100%
rename from gemrb/override/iwd/rad100.pro
rename to gemrb/unhardcoded/iwd/rad100.pro
diff --git a/gemrb/override/iwd/rad250.pro b/gemrb/unhardcoded/iwd/rad250.pro
similarity index 100%
rename from gemrb/override/iwd/rad250.pro
rename to gemrb/unhardcoded/iwd/rad250.pro
diff --git a/gemrb/override/iwd/randitem.2da b/gemrb/unhardcoded/iwd/randitem.2da
similarity index 100%
rename from gemrb/override/iwd/randitem.2da
rename to gemrb/unhardcoded/iwd/randitem.2da
diff --git a/gemrb/override/iwd/rdeadh.pro b/gemrb/unhardcoded/iwd/rdeadh.pro
similarity index 100%
rename from gemrb/override/iwd/rdeadh.pro
rename to gemrb/unhardcoded/iwd/rdeadh.pro
diff --git a/gemrb/override/iwd/recitah.pro b/gemrb/unhardcoded/iwd/recitah.pro
similarity index 100%
rename from gemrb/override/iwd/recitah.pro
rename to gemrb/unhardcoded/iwd/recitah.pro
diff --git a/gemrb/override/iwd/resurrh.pro b/gemrb/unhardcoded/iwd/resurrh.pro
similarity index 100%
rename from gemrb/override/iwd/resurrh.pro
rename to gemrb/unhardcoded/iwd/resurrh.pro
diff --git a/gemrb/override/iwd/rng450.pro b/gemrb/unhardcoded/iwd/rng450.pro
similarity index 100%
rename from gemrb/override/iwd/rng450.pro
rename to gemrb/unhardcoded/iwd/rng450.pro
diff --git a/gemrb/override/iwd/rparalh.pro b/gemrb/unhardcoded/iwd/rparalh.pro
similarity index 100%
rename from gemrb/override/iwd/rparalh.pro
rename to gemrb/unhardcoded/iwd/rparalh.pro
diff --git a/gemrb/override/iwd/rwotfag.pro b/gemrb/unhardcoded/iwd/rwotfag.pro
similarity index 100%
rename from gemrb/override/iwd/rwotfag.pro
rename to gemrb/unhardcoded/iwd/rwotfag.pro
diff --git a/gemrb/override/iwd/rwotfah.pro b/gemrb/unhardcoded/iwd/rwotfah.pro
similarity index 100%
rename from gemrb/override/iwd/rwotfah.pro
rename to gemrb/unhardcoded/iwd/rwotfah.pro
diff --git a/gemrb/override/iwd/sarmorh.pro b/gemrb/unhardcoded/iwd/sarmorh.pro
similarity index 100%
rename from gemrb/override/iwd/sarmorh.pro
rename to gemrb/unhardcoded/iwd/sarmorh.pro
diff --git a/gemrb/override/iwd/savegame.2da b/gemrb/unhardcoded/iwd/savegame.2da
similarity index 100%
rename from gemrb/override/iwd/savegame.2da
rename to gemrb/unhardcoded/iwd/savegame.2da
diff --git a/gemrb/override/iwd/scharge.pro b/gemrb/unhardcoded/iwd/scharge.pro
similarity index 100%
rename from gemrb/override/iwd/scharge.pro
rename to gemrb/unhardcoded/iwd/scharge.pro
diff --git a/gemrb/override/iwd/scharge.spl b/gemrb/unhardcoded/iwd/scharge.spl
similarity index 100%
rename from gemrb/override/iwd/scharge.spl
rename to gemrb/unhardcoded/iwd/scharge.spl
diff --git a/gemrb/override/iwd/schargh.pro b/gemrb/unhardcoded/iwd/schargh.pro
similarity index 100%
rename from gemrb/override/iwd/schargh.pro
rename to gemrb/unhardcoded/iwd/schargh.pro
diff --git a/gemrb/override/iwd/script.2da b/gemrb/unhardcoded/iwd/script.2da
similarity index 100%
rename from gemrb/override/iwd/script.2da
rename to gemrb/unhardcoded/iwd/script.2da
diff --git a/gemrb/override/iwd/seater.pro b/gemrb/unhardcoded/iwd/seater.pro
similarity index 100%
rename from gemrb/override/iwd/seater.pro
rename to gemrb/unhardcoded/iwd/seater.pro
diff --git a/gemrb/override/iwd/seaterh.pro b/gemrb/unhardcoded/iwd/seaterh.pro
similarity index 100%
rename from gemrb/override/iwd/seaterh.pro
rename to gemrb/unhardcoded/iwd/seaterh.pro
diff --git a/gemrb/override/iwd/sgrowth.pro b/gemrb/unhardcoded/iwd/sgrowth.pro
similarity index 100%
rename from gemrb/override/iwd/sgrowth.pro
rename to gemrb/unhardcoded/iwd/sgrowth.pro
diff --git a/gemrb/override/iwd/shout.pro b/gemrb/unhardcoded/iwd/shout.pro
similarity index 100%
rename from gemrb/override/iwd/shout.pro
rename to gemrb/unhardcoded/iwd/shout.pro
diff --git a/gemrb/override/iwd/shroud.pro b/gemrb/unhardcoded/iwd/shroud.pro
similarity index 100%
rename from gemrb/override/iwd/shroud.pro
rename to gemrb/unhardcoded/iwd/shroud.pro
diff --git a/gemrb/override/iwd/shtable.2da b/gemrb/unhardcoded/iwd/shtable.2da
similarity index 100%
rename from gemrb/override/iwd/shtable.2da
rename to gemrb/unhardcoded/iwd/shtable.2da
diff --git a/gemrb/override/iwd/skills.2da b/gemrb/unhardcoded/iwd/skills.2da
similarity index 100%
rename from gemrb/override/iwd/skills.2da
rename to gemrb/unhardcoded/iwd/skills.2da
diff --git a/gemrb/override/iwd/sleep.pro b/gemrb/unhardcoded/iwd/sleep.pro
similarity index 100%
rename from gemrb/override/iwd/sleep.pro
rename to gemrb/unhardcoded/iwd/sleep.pro
diff --git a/gemrb/override/iwd/slivinh.pro b/gemrb/unhardcoded/iwd/slivinh.pro
similarity index 100%
rename from gemrb/override/iwd/slivinh.pro
rename to gemrb/unhardcoded/iwd/slivinh.pro
diff --git a/gemrb/override/iwd/slottype.2da b/gemrb/unhardcoded/iwd/slottype.2da
similarity index 100%
rename from gemrb/override/iwd/slottype.2da
rename to gemrb/unhardcoded/iwd/slottype.2da
diff --git a/gemrb/override/iwd/soflamh.pro b/gemrb/unhardcoded/iwd/soflamh.pro
similarity index 100%
rename from gemrb/override/iwd/soflamh.pro
rename to gemrb/unhardcoded/iwd/soflamh.pro
diff --git a/gemrb/override/iwd/sohope.pro b/gemrb/unhardcoded/iwd/sohope.pro
similarity index 100%
rename from gemrb/override/iwd/sohope.pro
rename to gemrb/unhardcoded/iwd/sohope.pro
diff --git a/gemrb/override/iwd/sooneh.pro b/gemrb/unhardcoded/iwd/sooneh.pro
similarity index 100%
rename from gemrb/override/iwd/sooneh.pro
rename to gemrb/unhardcoded/iwd/sooneh.pro
diff --git a/gemrb/override/iwd/sopain.pro b/gemrb/unhardcoded/iwd/sopain.pro
similarity index 100%
rename from gemrb/override/iwd/sopain.pro
rename to gemrb/unhardcoded/iwd/sopain.pro
diff --git a/gemrb/override/iwd/sparbknp.pro b/gemrb/unhardcoded/iwd/sparbknp.pro
similarity index 100%
rename from gemrb/override/iwd/sparbknp.pro
rename to gemrb/unhardcoded/iwd/sparbknp.pro
diff --git a/gemrb/override/iwd/sparbkpa.pro b/gemrb/unhardcoded/iwd/sparbkpa.pro
similarity index 100%
rename from gemrb/override/iwd/sparbkpa.pro
rename to gemrb/unhardcoded/iwd/sparbkpa.pro
diff --git a/gemrb/override/iwd/sparblnp.pro b/gemrb/unhardcoded/iwd/sparblnp.pro
similarity index 100%
rename from gemrb/override/iwd/sparblnp.pro
rename to gemrb/unhardcoded/iwd/sparblnp.pro
diff --git a/gemrb/override/iwd/sparblpa.pro b/gemrb/unhardcoded/iwd/sparblpa.pro
similarity index 100%
rename from gemrb/override/iwd/sparblpa.pro
rename to gemrb/unhardcoded/iwd/sparblpa.pro
diff --git a/gemrb/override/iwd/sparchnp.pro b/gemrb/unhardcoded/iwd/sparchnp.pro
similarity index 100%
rename from gemrb/override/iwd/sparchnp.pro
rename to gemrb/unhardcoded/iwd/sparchnp.pro
diff --git a/gemrb/override/iwd/sparchpa.pro b/gemrb/unhardcoded/iwd/sparchpa.pro
similarity index 100%
rename from gemrb/override/iwd/sparchpa.pro
rename to gemrb/unhardcoded/iwd/sparchpa.pro
diff --git a/gemrb/override/iwd/spargonp.pro b/gemrb/unhardcoded/iwd/spargonp.pro
similarity index 100%
rename from gemrb/override/iwd/spargonp.pro
rename to gemrb/unhardcoded/iwd/spargonp.pro
diff --git a/gemrb/override/iwd/spargopa.pro b/gemrb/unhardcoded/iwd/spargopa.pro
similarity index 100%
rename from gemrb/override/iwd/spargopa.pro
rename to gemrb/unhardcoded/iwd/spargopa.pro
diff --git a/gemrb/override/iwd/spargrnp.pro b/gemrb/unhardcoded/iwd/spargrnp.pro
similarity index 100%
rename from gemrb/override/iwd/spargrnp.pro
rename to gemrb/unhardcoded/iwd/spargrnp.pro
diff --git a/gemrb/override/iwd/spargrpa.pro b/gemrb/unhardcoded/iwd/spargrpa.pro
similarity index 100%
rename from gemrb/override/iwd/spargrpa.pro
rename to gemrb/unhardcoded/iwd/spargrpa.pro
diff --git a/gemrb/override/iwd/sparicnp.pro b/gemrb/unhardcoded/iwd/sparicnp.pro
similarity index 100%
rename from gemrb/override/iwd/sparicnp.pro
rename to gemrb/unhardcoded/iwd/sparicnp.pro
diff --git a/gemrb/override/iwd/sparicpa.pro b/gemrb/unhardcoded/iwd/sparicpa.pro
similarity index 100%
rename from gemrb/override/iwd/sparicpa.pro
rename to gemrb/unhardcoded/iwd/sparicpa.pro
diff --git a/gemrb/override/iwd/sparklbk.pro b/gemrb/unhardcoded/iwd/sparklbk.pro
similarity index 100%
rename from gemrb/override/iwd/sparklbk.pro
rename to gemrb/unhardcoded/iwd/sparklbk.pro
diff --git a/gemrb/override/iwd/sparklbl.pro b/gemrb/unhardcoded/iwd/sparklbl.pro
similarity index 100%
rename from gemrb/override/iwd/sparklbl.pro
rename to gemrb/unhardcoded/iwd/sparklbl.pro
diff --git a/gemrb/override/iwd/sparklch.pro b/gemrb/unhardcoded/iwd/sparklch.pro
similarity index 100%
rename from gemrb/override/iwd/sparklch.pro
rename to gemrb/unhardcoded/iwd/sparklch.pro
diff --git a/gemrb/override/iwd/sparklgo.pro b/gemrb/unhardcoded/iwd/sparklgo.pro
similarity index 100%
rename from gemrb/override/iwd/sparklgo.pro
rename to gemrb/unhardcoded/iwd/sparklgo.pro
diff --git a/gemrb/override/iwd/sparklgr.pro b/gemrb/unhardcoded/iwd/sparklgr.pro
similarity index 100%
rename from gemrb/override/iwd/sparklgr.pro
rename to gemrb/unhardcoded/iwd/sparklgr.pro
diff --git a/gemrb/override/iwd/sparklic.pro b/gemrb/unhardcoded/iwd/sparklic.pro
similarity index 100%
rename from gemrb/override/iwd/sparklic.pro
rename to gemrb/unhardcoded/iwd/sparklic.pro
diff --git a/gemrb/override/iwd/sparklma.pro b/gemrb/unhardcoded/iwd/sparklma.pro
similarity index 100%
rename from gemrb/override/iwd/sparklma.pro
rename to gemrb/unhardcoded/iwd/sparklma.pro
diff --git a/gemrb/override/iwd/sparklor.pro b/gemrb/unhardcoded/iwd/sparklor.pro
similarity index 100%
rename from gemrb/override/iwd/sparklor.pro
rename to gemrb/unhardcoded/iwd/sparklor.pro
diff --git a/gemrb/override/iwd/sparklpu.pro b/gemrb/unhardcoded/iwd/sparklpu.pro
similarity index 100%
rename from gemrb/override/iwd/sparklpu.pro
rename to gemrb/unhardcoded/iwd/sparklpu.pro
diff --git a/gemrb/override/iwd/sparklre.pro b/gemrb/unhardcoded/iwd/sparklre.pro
similarity index 100%
rename from gemrb/override/iwd/sparklre.pro
rename to gemrb/unhardcoded/iwd/sparklre.pro
diff --git a/gemrb/override/iwd/sparklst.pro b/gemrb/unhardcoded/iwd/sparklst.pro
similarity index 100%
rename from gemrb/override/iwd/sparklst.pro
rename to gemrb/unhardcoded/iwd/sparklst.pro
diff --git a/gemrb/override/iwd/sparmanp.pro b/gemrb/unhardcoded/iwd/sparmanp.pro
similarity index 100%
rename from gemrb/override/iwd/sparmanp.pro
rename to gemrb/unhardcoded/iwd/sparmanp.pro
diff --git a/gemrb/override/iwd/sparmapa.pro b/gemrb/unhardcoded/iwd/sparmapa.pro
similarity index 100%
rename from gemrb/override/iwd/sparmapa.pro
rename to gemrb/unhardcoded/iwd/sparmapa.pro
diff --git a/gemrb/override/iwd/sparornp.pro b/gemrb/unhardcoded/iwd/sparornp.pro
similarity index 100%
rename from gemrb/override/iwd/sparornp.pro
rename to gemrb/unhardcoded/iwd/sparornp.pro
diff --git a/gemrb/override/iwd/sparorpa.pro b/gemrb/unhardcoded/iwd/sparorpa.pro
similarity index 100%
rename from gemrb/override/iwd/sparorpa.pro
rename to gemrb/unhardcoded/iwd/sparorpa.pro
diff --git a/gemrb/override/iwd/sparpunp.pro b/gemrb/unhardcoded/iwd/sparpunp.pro
similarity index 100%
rename from gemrb/override/iwd/sparpunp.pro
rename to gemrb/unhardcoded/iwd/sparpunp.pro
diff --git a/gemrb/override/iwd/sparpupa.pro b/gemrb/unhardcoded/iwd/sparpupa.pro
similarity index 100%
rename from gemrb/override/iwd/sparpupa.pro
rename to gemrb/unhardcoded/iwd/sparpupa.pro
diff --git a/gemrb/override/iwd/sparrenp.pro b/gemrb/unhardcoded/iwd/sparrenp.pro
similarity index 100%
rename from gemrb/override/iwd/sparrenp.pro
rename to gemrb/unhardcoded/iwd/sparrenp.pro
diff --git a/gemrb/override/iwd/sparrepa.pro b/gemrb/unhardcoded/iwd/sparrepa.pro
similarity index 100%
rename from gemrb/override/iwd/sparrepa.pro
rename to gemrb/unhardcoded/iwd/sparrepa.pro
diff --git a/gemrb/override/iwd/sparstnp.pro b/gemrb/unhardcoded/iwd/sparstnp.pro
similarity index 100%
rename from gemrb/override/iwd/sparstnp.pro
rename to gemrb/unhardcoded/iwd/sparstnp.pro
diff --git a/gemrb/override/iwd/sparstpa.pro b/gemrb/unhardcoded/iwd/sparstpa.pro
similarity index 100%
rename from gemrb/override/iwd/sparstpa.pro
rename to gemrb/unhardcoded/iwd/sparstpa.pro
diff --git a/gemrb/override/iwd/spear.pro b/gemrb/unhardcoded/iwd/spear.pro
similarity index 100%
rename from gemrb/override/iwd/spear.pro
rename to gemrb/unhardcoded/iwd/spear.pro
diff --git a/gemrb/override/iwd/spearex.pro b/gemrb/unhardcoded/iwd/spearex.pro
similarity index 100%
rename from gemrb/override/iwd/spearex.pro
rename to gemrb/unhardcoded/iwd/spearex.pro
diff --git a/gemrb/override/iwd/spfirebl.pro b/gemrb/unhardcoded/iwd/spfirebl.pro
similarity index 100%
rename from gemrb/override/iwd/spfirebl.pro
rename to gemrb/unhardcoded/iwd/spfirebl.pro
diff --git a/gemrb/override/iwd/spklarbk.pro b/gemrb/unhardcoded/iwd/spklarbk.pro
similarity index 100%
rename from gemrb/override/iwd/spklarbk.pro
rename to gemrb/unhardcoded/iwd/spklarbk.pro
diff --git a/gemrb/override/iwd/spklarbl.pro b/gemrb/unhardcoded/iwd/spklarbl.pro
similarity index 100%
rename from gemrb/override/iwd/spklarbl.pro
rename to gemrb/unhardcoded/iwd/spklarbl.pro
diff --git a/gemrb/override/iwd/spklarch.pro b/gemrb/unhardcoded/iwd/spklarch.pro
similarity index 100%
rename from gemrb/override/iwd/spklarch.pro
rename to gemrb/unhardcoded/iwd/spklarch.pro
diff --git a/gemrb/override/iwd/spklargo.pro b/gemrb/unhardcoded/iwd/spklargo.pro
similarity index 100%
rename from gemrb/override/iwd/spklargo.pro
rename to gemrb/unhardcoded/iwd/spklargo.pro
diff --git a/gemrb/override/iwd/spklargr.pro b/gemrb/unhardcoded/iwd/spklargr.pro
similarity index 100%
rename from gemrb/override/iwd/spklargr.pro
rename to gemrb/unhardcoded/iwd/spklargr.pro
diff --git a/gemrb/override/iwd/spklaric.pro b/gemrb/unhardcoded/iwd/spklaric.pro
similarity index 100%
rename from gemrb/override/iwd/spklaric.pro
rename to gemrb/unhardcoded/iwd/spklaric.pro
diff --git a/gemrb/override/iwd/spklarma.pro b/gemrb/unhardcoded/iwd/spklarma.pro
similarity index 100%
rename from gemrb/override/iwd/spklarma.pro
rename to gemrb/unhardcoded/iwd/spklarma.pro
diff --git a/gemrb/override/iwd/spklaror.pro b/gemrb/unhardcoded/iwd/spklaror.pro
similarity index 100%
rename from gemrb/override/iwd/spklaror.pro
rename to gemrb/unhardcoded/iwd/spklaror.pro
diff --git a/gemrb/override/iwd/spklarpu.pro b/gemrb/unhardcoded/iwd/spklarpu.pro
similarity index 100%
rename from gemrb/override/iwd/spklarpu.pro
rename to gemrb/unhardcoded/iwd/spklarpu.pro
diff --git a/gemrb/override/iwd/spklarre.pro b/gemrb/unhardcoded/iwd/spklarre.pro
similarity index 100%
rename from gemrb/override/iwd/spklarre.pro
rename to gemrb/unhardcoded/iwd/spklarre.pro
diff --git a/gemrb/override/iwd/spklarst.pro b/gemrb/unhardcoded/iwd/spklarst.pro
similarity index 100%
rename from gemrb/override/iwd/spklarst.pro
rename to gemrb/unhardcoded/iwd/spklarst.pro
diff --git a/gemrb/override/iwd/splprot.2da b/gemrb/unhardcoded/iwd/splprot.2da
similarity index 100%
rename from gemrb/override/iwd/splprot.2da
rename to gemrb/unhardcoded/iwd/splprot.2da
diff --git a/gemrb/override/iwd/splspec.2da b/gemrb/unhardcoded/iwd/splspec.2da
similarity index 100%
rename from gemrb/override/iwd/splspec.2da
rename to gemrb/unhardcoded/iwd/splspec.2da
diff --git a/gemrb/override/iwd/spoisoh.pro b/gemrb/unhardcoded/iwd/spoisoh.pro
similarity index 100%
rename from gemrb/override/iwd/spoisoh.pro
rename to gemrb/unhardcoded/iwd/spoisoh.pro
diff --git a/gemrb/override/iwd/spscorch.pro b/gemrb/unhardcoded/iwd/spscorch.pro
similarity index 100%
rename from gemrb/override/iwd/spscorch.pro
rename to gemrb/unhardcoded/iwd/spscorch.pro
diff --git a/gemrb/override/iwd/spscoric.pro b/gemrb/unhardcoded/iwd/spscoric.pro
similarity index 100%
rename from gemrb/override/iwd/spscoric.pro
rename to gemrb/unhardcoded/iwd/spscoric.pro
diff --git a/gemrb/override/iwd/spwrath.pro b/gemrb/unhardcoded/iwd/spwrath.pro
similarity index 100%
rename from gemrb/override/iwd/spwrath.pro
rename to gemrb/unhardcoded/iwd/spwrath.pro
diff --git a/gemrb/override/iwd/ssorbh.pro b/gemrb/unhardcoded/iwd/ssorbh.pro
similarity index 100%
rename from gemrb/override/iwd/ssorbh.pro
rename to gemrb/unhardcoded/iwd/ssorbh.pro
diff --git a/gemrb/override/iwd/ssswarm.pro b/gemrb/unhardcoded/iwd/ssswarm.pro
similarity index 100%
rename from gemrb/override/iwd/ssswarm.pro
rename to gemrb/unhardcoded/iwd/ssswarm.pro
diff --git a/gemrb/override/iwd/sstone.pro b/gemrb/unhardcoded/iwd/sstone.pro
similarity index 100%
rename from gemrb/override/iwd/sstone.pro
rename to gemrb/unhardcoded/iwd/sstone.pro
diff --git a/gemrb/override/iwd/sstoneh.pro b/gemrb/unhardcoded/iwd/sstoneh.pro
similarity index 100%
rename from gemrb/override/iwd/sstoneh.pro
rename to gemrb/unhardcoded/iwd/sstoneh.pro
diff --git a/gemrb/override/iwd/start.2da b/gemrb/unhardcoded/iwd/start.2da
similarity index 100%
rename from gemrb/override/iwd/start.2da
rename to gemrb/unhardcoded/iwd/start.2da
diff --git a/gemrb/override/iwd/stone.pro b/gemrb/unhardcoded/iwd/stone.pro
similarity index 100%
rename from gemrb/override/iwd/stone.pro
rename to gemrb/unhardcoded/iwd/stone.pro
diff --git a/gemrb/override/iwd/strengh.pro b/gemrb/unhardcoded/iwd/strengh.pro
similarity index 100%
rename from gemrb/override/iwd/strengh.pro
rename to gemrb/unhardcoded/iwd/strengh.pro
diff --git a/gemrb/unhardcoded/iwd/strings.2da b/gemrb/unhardcoded/iwd/strings.2da
new file mode 100644
index 0000000..c47fe59
--- /dev/null
+++ b/gemrb/unhardcoded/iwd/strings.2da
@@ -0,0 +1,187 @@
+2DA V1.0
+-1
+ STRREF
+SCATTERED 16457
+WHOLEPARTY 16484
+DOORLOCKED 16485
+MAGICTRAP 16486
+NORMALTRAP 16487
+TRAP 16488
+CANNOTGO 16489
+TRAPREMOVED 16490
+OVERSTOCKED 16491
+SLEEP 16492
+AMBUSH 16493
+CONTLOCKED 16494
+NOMONEY 16495
+CURSED 16304
+SPELLDISRUPT 16497
+DIED 16498
+MAYNOTREST 16499
+CANTRESTMONS 16500
+CANTSAVEMONS 16501
+CANTSAVE 16502
+NODIALOG 10945
+CANTSAVEDIALOG 19253
+CANTSAVEDIALOG2 19254
+CANTSAVEMOVIE 19255
+TARGETBUSY -1
+CANTTALKTRANS -1
+GOTGOLD 17572
+LOSTGOLD 17573
+GOTXP 17574
+LOSTXP 17575
+GOTITEM 17576
+LOSTITEM 17577
+GOTREP 19686
+LOSTREP 19687
+GOTABILITY 10514
+GOTSPELL 10514
+GOTSONG 26320
+NOTHINGTOSAY -1
+JOURNALCHANGE 11359
+WORLDMAPCHANGE 11360
+PAUSED 16321
+UNPAUSED 16322
+SCRIPTPAUSED 7666
+AP_UNUSABLE 17113
+AP_ATTACKED 17114
+AP_HIT 17115
+AP_WOUNDED 17116
+AP_DEAD 17117
+AP_NOTARGET 17118
+AP_ENDROUND 10014
+AP_ENEMY 23511
+AP_TRAP -1
+AP_SPELLCAST -1
+AP_GENERIC 17166
+AP_RESERVED1 -1
+AP_RESERVED2 -1
+AP_RESERVED3 -1
+CHARMED 14672
+DIRECHARMED 14780
+CONTROLLED -1
+EVIL 16505
+GNE_NEUTRAL 16504
+GOOD 16503
+STR_LAWFUL -1
+LNC_NEUTRAL -1
+CHAOTIC -1
+ACTION_CAST 16464
+ACTION_ATTACK 16465
+ACTION_TURN 16466
+ACTION_SONG 16467
+ACTION_FINDTRAP 16468
+MAGICWEAPON 10141
+OFFHAND_USED 9380
+TWOHANDED_USED 9381
+CANNOT_USE_ITEM 9382
+CANT_DROP_ITEM 25697
+NOT_IN_OFFHAND 26342
+ITEM_IS_CURSED 16304
+NO_CRITICAL 20696
+TRACKING -1
+TRACKINGFAILED 19534
+DOOR_NOPICK 23169
+CONT_NOPICK 23169
+CANTSAVECOMBAT -1
+CANTSAVENOCTRL -1
+LOCKPICK_DONE 16517
+LOCKPICK_FAILED 16518
+STATIC_DISSIPATE -1
+LIGHTNING_DISSIPATE -1
+HAS_NO_ABILITY 17317
+NEEDS_IDENTIFY 17316
+WRONG_ITEMTYPE 9375
+HAS_ITEMEXCL 20685
+PICKPOCKET_DONE 10072
+PICKPOCKET_NONE 18297
+PICKPOCKET_FAIL 10069
+PICKPOCKET_EVIL 10068
+PICKPOCKET_ARMOR 10067
+USING_FEAT -1
+STOPPED_FEAT -1
+DISARM_DONE 16520
+DISARM_FAIL 1608
+DOORBASH_DONE 9915
+DOORBASH_FAIL 9913
+CONTBASH_DONE 9916
+CONTBASH_FAIL 9914
+MAYNOTSETTRAP -1
+SNAREFAILED -1
+SNARESUCCEED -1
+NOMORETRAP -1
+DISABLEDMAGE -1
+SAVESUCCEED 1682
+QSAVESUCCEED 10237
+UNINJURED 2943
+INJURED1 2944
+INJURED2 2945
+INJURED3 2946
+INJURED4 2947
+HOURS 10700
+HOUR 10701
+DAYS 10697
+DAY 10698
+REST 10690
+JOURNEY 10689
+SUMMONINGLIMIT -1
+INVFULL 17999
+TOOFARAWAY 18002
+DAMAGE_IMMUNITY -1
+DAMAGE_STR1 14027
+DAMAGE_STR2 -1
+DAMAGE_STR3 -1
+DMG_POISON -1
+DMG_MAGIC -1
+DMG_MISSILE -1
+DMG_SLASHING -1
+DMG_PIERCING -1
+DMG_CRUSHING -1
+DMG_FIRE -1
+DMG_ELECTRIC -1
+DMG_COLD -1
+DMG_ACID -1
+DMG_OTHER -1
+GOTQUESTXP -1
+LEVELUP 17119
+INVFULL_ITEMDROP 32879
+CONT_DUP 32876
+CONT_TRIG -1
+CONT_FAIL -1
+SEQ_DUP -1
+CRITICAL_HIT 16462
+CRITICAL_MISS 16463
+DEATH 14026
+BACKSTAB 12128
+BACKSTAB_BAD 10013
+BACKSTAB_FAIL -1
+CASTER_LVL_INC -1
+CASTER_LVL_DEC -1
+CHARS_EXPORTED 26827
+PALADIN_FALL 19620
+RANGER_FALL 19621
+RES_RESISTED 26818
+DEADMAGIC_FAIL -1
+MISCASTMAGIC -1
+WILDSURGE -1
+FAMBLOCK -1
+FAMPROTAGONIST -1
+MAGIC_RESISTED 19224
+CANTSAVESTORE 10841
+NOSEE_NOCAST -1
+AURACLEANSED 23797
+INDOOR_FAIL 9744
+SPELL_DISRUPTED 14796
+CHAOSSHIELD -1
+RAPIDSHOT -1
+HAMSTRING -1
+ARTERIAL -1
+EXPERTISE -1
+POWERATTACK -1
+CLEAVE -1
+HELD 14102
+SLOWED 19503
+CANTMOVE 19504
+CASTS -1
+WEAPONINEFFECTIVE -1
diff --git a/gemrb/override/iwd/suffoc.pro b/gemrb/unhardcoded/iwd/suffoc.pro
similarity index 100%
rename from gemrb/override/iwd/suffoc.pro
rename to gemrb/unhardcoded/iwd/suffoc.pro
diff --git a/gemrb/override/iwd/suffoch.pro b/gemrb/unhardcoded/iwd/suffoch.pro
similarity index 100%
rename from gemrb/override/iwd/suffoch.pro
rename to gemrb/unhardcoded/iwd/suffoch.pro
diff --git a/gemrb/override/iwd/sunfire.pro b/gemrb/unhardcoded/iwd/sunfire.pro
similarity index 100%
rename from gemrb/override/iwd/sunfire.pro
rename to gemrb/unhardcoded/iwd/sunfire.pro
diff --git a/gemrb/override/iwd/sunray.pro b/gemrb/unhardcoded/iwd/sunray.pro
similarity index 100%
rename from gemrb/override/iwd/sunray.pro
rename to gemrb/unhardcoded/iwd/sunray.pro
diff --git a/gemrb/override/iwd/sunscoh.pro b/gemrb/unhardcoded/iwd/sunscoh.pro
similarity index 100%
rename from gemrb/override/iwd/sunscoh.pro
rename to gemrb/unhardcoded/iwd/sunscoh.pro
diff --git a/gemrb/override/iwd/swave.pro b/gemrb/unhardcoded/iwd/swave.pro
similarity index 100%
rename from gemrb/override/iwd/swave.pro
rename to gemrb/unhardcoded/iwd/swave.pro
diff --git a/gemrb/override/iwd/swaveh.pro b/gemrb/unhardcoded/iwd/swaveh.pro
similarity index 100%
rename from gemrb/override/iwd/swaveh.pro
rename to gemrb/unhardcoded/iwd/swaveh.pro
diff --git a/gemrb/override/iwd/trapglyp.pro b/gemrb/unhardcoded/iwd/trapglyp.pro
similarity index 100%
rename from gemrb/override/iwd/trapglyp.pro
rename to gemrb/unhardcoded/iwd/trapglyp.pro
diff --git a/gemrb/override/iwd/trapskul.pro b/gemrb/unhardcoded/iwd/trapskul.pro
similarity index 100%
rename from gemrb/override/iwd/trapskul.pro
rename to gemrb/unhardcoded/iwd/trapskul.pro
diff --git a/gemrb/override/iwd/tspray.pro b/gemrb/unhardcoded/iwd/tspray.pro
similarity index 100%
rename from gemrb/override/iwd/tspray.pro
rename to gemrb/unhardcoded/iwd/tspray.pro
diff --git a/gemrb/override/iwd/ublight.pro b/gemrb/unhardcoded/iwd/ublight.pro
similarity index 100%
rename from gemrb/override/iwd/ublight.pro
rename to gemrb/unhardcoded/iwd/ublight.pro
diff --git a/gemrb/override/iwd/uward.pro b/gemrb/unhardcoded/iwd/uward.pro
similarity index 100%
rename from gemrb/override/iwd/uward.pro
rename to gemrb/unhardcoded/iwd/uward.pro
diff --git a/gemrb/override/iwd/uwardh.pro b/gemrb/unhardcoded/iwd/uwardh.pro
similarity index 100%
rename from gemrb/override/iwd/uwardh.pro
rename to gemrb/unhardcoded/iwd/uwardh.pro
diff --git a/gemrb/unhardcoded/iwd/vcremap.2da b/gemrb/unhardcoded/iwd/vcremap.2da
new file mode 100644
index 0000000..f6cce8f
--- /dev/null
+++ b/gemrb/unhardcoded/iwd/vcremap.2da
@@ -0,0 +1,32 @@
+2DA V1.0
+*
+ ORIGINAL NEW
+BCRY 9 3
+2 10 4
+3 11 5
+4 12 6
+5 13 7
+LEAD 6 8
+TIRE 7 10
+BORE 8 13
+DMG 20 14
+SEL 26 16
+2 27 17
+3 28 18
+4 29 19
+5 30 20
+6 31 21
+ACT 32 23
+2 33 24
+3 34 25
+4 35 26
+5 36 27
+6 37 28
+7 38 29
+RARE1 63 30
+RARE2 64 31
+HIT 18 34
+DYING 19 37
+REACT 53 39
+2 54 40
+BIO 74 63
diff --git a/gemrb/override/iwd/vspherh.pro b/gemrb/unhardcoded/iwd/vspherh.pro
similarity index 100%
rename from gemrb/override/iwd/vspherh.pro
rename to gemrb/unhardcoded/iwd/vspherh.pro
diff --git a/gemrb/override/iwd/wdeath1.pro b/gemrb/unhardcoded/iwd/wdeath1.pro
similarity index 100%
rename from gemrb/override/iwd/wdeath1.pro
rename to gemrb/unhardcoded/iwd/wdeath1.pro
diff --git a/gemrb/override/iwd/wdeath2.pro b/gemrb/unhardcoded/iwd/wdeath2.pro
similarity index 100%
rename from gemrb/override/iwd/wdeath2.pro
rename to gemrb/unhardcoded/iwd/wdeath2.pro
diff --git a/gemrb/override/iwd/weapprof.2da b/gemrb/unhardcoded/iwd/weapprof.2da
similarity index 100%
rename from gemrb/override/iwd/weapprof.2da
rename to gemrb/unhardcoded/iwd/weapprof.2da
diff --git a/gemrb/override/iwd/web.pro b/gemrb/unhardcoded/iwd/web.pro
similarity index 100%
rename from gemrb/override/iwd/web.pro
rename to gemrb/unhardcoded/iwd/web.pro
diff --git a/gemrb/override/iwd/whirlw.pro b/gemrb/unhardcoded/iwd/whirlw.pro
similarity index 100%
rename from gemrb/override/iwd/whirlw.pro
rename to gemrb/unhardcoded/iwd/whirlw.pro
diff --git a/gemrb/override/iwd/womoon.pro b/gemrb/unhardcoded/iwd/womoon.pro
similarity index 100%
rename from gemrb/override/iwd/womoon.pro
rename to gemrb/unhardcoded/iwd/womoon.pro
diff --git a/gemrb/override/iwd/wowisp.pro b/gemrb/unhardcoded/iwd/wowisp.pro
similarity index 100%
rename from gemrb/override/iwd/wowisp.pro
rename to gemrb/unhardcoded/iwd/wowisp.pro
diff --git a/gemrb/override/iwd/wvdeath.pro b/gemrb/unhardcoded/iwd/wvdeath.pro
similarity index 100%
rename from gemrb/override/iwd/wvdeath.pro
rename to gemrb/unhardcoded/iwd/wvdeath.pro
diff --git a/gemrb/override/iwd/wvhith.pro b/gemrb/unhardcoded/iwd/wvhith.pro
similarity index 100%
rename from gemrb/override/iwd/wvhith.pro
rename to gemrb/unhardcoded/iwd/wvhith.pro
diff --git a/gemrb/override/iwd/wwolf.pro b/gemrb/unhardcoded/iwd/wwolf.pro
similarity index 100%
rename from gemrb/override/iwd/wwolf.pro
rename to gemrb/unhardcoded/iwd/wwolf.pro
diff --git a/gemrb/override/iwd/zlaura.pro b/gemrb/unhardcoded/iwd/zlaura.pro
similarity index 100%
rename from gemrb/override/iwd/zlaura.pro
rename to gemrb/unhardcoded/iwd/zlaura.pro
diff --git a/gemrb/unhardcoded/iwd2/Makefile.am b/gemrb/unhardcoded/iwd2/Makefile.am
new file mode 100644
index 0000000..a629f86
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/Makefile.am
@@ -0,0 +1,3 @@
+iwd2unhardcoded_DATA = *.2da *.ini *.chu *.ids *.pro *.spl *.vvc *.eff
+iwd2unhardcodeddir = $(moddir)/unhardcoded/iwd2/
+EXTRA_DIST = *.2da *.ini *.chu *.ids *.pro *.spl *.vvc *.eff
diff --git a/gemrb/unhardcoded/iwd2/ability.2da b/gemrb/unhardcoded/iwd2/ability.2da
new file mode 100644
index 0000000..a98547d
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/ability.2da
@@ -0,0 +1,9 @@
+2DA V1.0
+-1
+ NAME_REF DESC_REF CAP_REF STAT_ID
+STRENGTH 11975 9582 1145 STR
+DEXTERITY 11977 9584 1151 DEX
+CONSTITUTION 11978 9583 1178 CON
+INTELLIGENCE 11979 9585 1179 INT
+WISDOM 11980 9586 1180 WIS
+CHARISMA 11981 9587 1181 CHR
diff --git a/gemrb/override/iwd2/abjura.pro b/gemrb/unhardcoded/iwd2/abjura.pro
similarity index 100%
rename from gemrb/override/iwd2/abjura.pro
rename to gemrb/unhardcoded/iwd2/abjura.pro
diff --git a/gemrb/override/iwd2/abjurap.pro b/gemrb/unhardcoded/iwd2/abjurap.pro
similarity index 100%
rename from gemrb/override/iwd2/abjurap.pro
rename to gemrb/unhardcoded/iwd2/abjurap.pro
diff --git a/gemrb/override/iwd2/abjurh.pro b/gemrb/unhardcoded/iwd2/abjurh.pro
similarity index 100%
rename from gemrb/override/iwd2/abjurh.pro
rename to gemrb/unhardcoded/iwd2/abjurh.pro
diff --git a/gemrb/override/iwd2/abjurt.pro b/gemrb/unhardcoded/iwd2/abjurt.pro
similarity index 100%
rename from gemrb/override/iwd2/abjurt.pro
rename to gemrb/unhardcoded/iwd2/abjurt.pro
diff --git a/gemrb/override/iwd2/abreath.pro b/gemrb/unhardcoded/iwd2/abreath.pro
similarity index 100%
rename from gemrb/override/iwd2/abreath.pro
rename to gemrb/unhardcoded/iwd2/abreath.pro
diff --git a/gemrb/override/iwd2/acidblgr.pro b/gemrb/unhardcoded/iwd2/acidblgr.pro
similarity index 100%
rename from gemrb/override/iwd2/acidblgr.pro
rename to gemrb/unhardcoded/iwd2/acidblgr.pro
diff --git a/gemrb/override/iwd2/acidblmu.pro b/gemrb/unhardcoded/iwd2/acidblmu.pro
similarity index 100%
rename from gemrb/override/iwd2/acidblmu.pro
rename to gemrb/unhardcoded/iwd2/acidblmu.pro
diff --git a/gemrb/override/iwd2/acidblob.pro b/gemrb/unhardcoded/iwd2/acidblob.pro
similarity index 100%
rename from gemrb/override/iwd2/acidblob.pro
rename to gemrb/unhardcoded/iwd2/acidblob.pro
diff --git a/gemrb/override/iwd2/acidbloc.pro b/gemrb/unhardcoded/iwd2/acidbloc.pro
similarity index 100%
rename from gemrb/override/iwd2/acidbloc.pro
rename to gemrb/unhardcoded/iwd2/acidbloc.pro
diff --git a/gemrb/override/iwd2/acidh.pro b/gemrb/unhardcoded/iwd2/acidh.pro
similarity index 100%
rename from gemrb/override/iwd2/acidh.pro
rename to gemrb/unhardcoded/iwd2/acidh.pro
diff --git a/gemrb/unhardcoded/iwd2/acidh.vvc b/gemrb/unhardcoded/iwd2/acidh.vvc
new file mode 100644
index 0000000..d7606bb
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/acidh.vvc differ
diff --git a/gemrb/override/iwd2/adhwil.pro b/gemrb/unhardcoded/iwd2/adhwil.pro
similarity index 100%
rename from gemrb/override/iwd2/adhwil.pro
rename to gemrb/unhardcoded/iwd2/adhwil.pro
diff --git a/gemrb/override/iwd2/adhwilh.pro b/gemrb/unhardcoded/iwd2/adhwilh.pro
similarity index 100%
rename from gemrb/override/iwd2/adhwilh.pro
rename to gemrb/unhardcoded/iwd2/adhwilh.pro
diff --git a/gemrb/override/iwd2/alance.pro b/gemrb/unhardcoded/iwd2/alance.pro
similarity index 100%
rename from gemrb/override/iwd2/alance.pro
rename to gemrb/unhardcoded/iwd2/alance.pro
diff --git a/gemrb/override/iwd2/aligns.2da b/gemrb/unhardcoded/iwd2/aligns.2da
similarity index 100%
rename from gemrb/override/iwd2/aligns.2da
rename to gemrb/unhardcoded/iwd2/aligns.2da
diff --git a/gemrb/override/iwd2/altera.pro b/gemrb/unhardcoded/iwd2/altera.pro
similarity index 100%
rename from gemrb/override/iwd2/altera.pro
rename to gemrb/unhardcoded/iwd2/altera.pro
diff --git a/gemrb/override/iwd2/alteranp.pro b/gemrb/unhardcoded/iwd2/alteranp.pro
similarity index 100%
rename from gemrb/override/iwd2/alteranp.pro
rename to gemrb/unhardcoded/iwd2/alteranp.pro
diff --git a/gemrb/override/iwd2/alterap.pro b/gemrb/unhardcoded/iwd2/alterap.pro
similarity index 100%
rename from gemrb/override/iwd2/alterap.pro
rename to gemrb/unhardcoded/iwd2/alterap.pro
diff --git a/gemrb/override/iwd2/alteraps.pro b/gemrb/unhardcoded/iwd2/alteraps.pro
similarity index 100%
rename from gemrb/override/iwd2/alteraps.pro
rename to gemrb/unhardcoded/iwd2/alteraps.pro
diff --git a/gemrb/override/iwd2/alteras.pro b/gemrb/unhardcoded/iwd2/alteras.pro
similarity index 100%
rename from gemrb/override/iwd2/alteras.pro
rename to gemrb/unhardcoded/iwd2/alteras.pro
diff --git a/gemrb/override/iwd2/alterh.pro b/gemrb/unhardcoded/iwd2/alterh.pro
similarity index 100%
rename from gemrb/override/iwd2/alterh.pro
rename to gemrb/unhardcoded/iwd2/alterh.pro
diff --git a/gemrb/override/iwd2/altert.pro b/gemrb/unhardcoded/iwd2/altert.pro
similarity index 100%
rename from gemrb/override/iwd2/altert.pro
rename to gemrb/unhardcoded/iwd2/altert.pro
diff --git a/gemrb/override/iwd2/area1np.pro b/gemrb/unhardcoded/iwd2/area1np.pro
similarity index 100%
rename from gemrb/override/iwd2/area1np.pro
rename to gemrb/unhardcoded/iwd2/area1np.pro
diff --git a/gemrb/override/iwd2/area1npl.pro b/gemrb/unhardcoded/iwd2/area1npl.pro
similarity index 100%
rename from gemrb/override/iwd2/area1npl.pro
rename to gemrb/unhardcoded/iwd2/area1npl.pro
diff --git a/gemrb/override/iwd2/area1p.pro b/gemrb/unhardcoded/iwd2/area1p.pro
similarity index 100%
rename from gemrb/override/iwd2/area1p.pro
rename to gemrb/unhardcoded/iwd2/area1p.pro
diff --git a/gemrb/override/iwd2/area1pl.pro b/gemrb/unhardcoded/iwd2/area1pl.pro
similarity index 100%
rename from gemrb/override/iwd2/area1pl.pro
rename to gemrb/unhardcoded/iwd2/area1pl.pro
diff --git a/gemrb/override/iwd2/area1ps.pro b/gemrb/unhardcoded/iwd2/area1ps.pro
similarity index 100%
rename from gemrb/override/iwd2/area1ps.pro
rename to gemrb/unhardcoded/iwd2/area1ps.pro
diff --git a/gemrb/override/iwd2/area2.pro b/gemrb/unhardcoded/iwd2/area2.pro
similarity index 100%
rename from gemrb/override/iwd2/area2.pro
rename to gemrb/unhardcoded/iwd2/area2.pro
diff --git a/gemrb/override/iwd2/area2np.pro b/gemrb/unhardcoded/iwd2/area2np.pro
similarity index 100%
rename from gemrb/override/iwd2/area2np.pro
rename to gemrb/unhardcoded/iwd2/area2np.pro
diff --git a/gemrb/override/iwd2/area3p.pro b/gemrb/unhardcoded/iwd2/area3p.pro
similarity index 100%
rename from gemrb/override/iwd2/area3p.pro
rename to gemrb/unhardcoded/iwd2/area3p.pro
diff --git a/gemrb/override/iwd2/area4np.pro b/gemrb/unhardcoded/iwd2/area4np.pro
similarity index 100%
rename from gemrb/override/iwd2/area4np.pro
rename to gemrb/unhardcoded/iwd2/area4np.pro
diff --git a/gemrb/override/iwd2/armorh.pro b/gemrb/unhardcoded/iwd2/armorh.pro
similarity index 100%
rename from gemrb/override/iwd2/armorh.pro
rename to gemrb/unhardcoded/iwd2/armorh.pro
diff --git a/gemrb/override/iwd2/arrow.pro b/gemrb/unhardcoded/iwd2/arrow.pro
similarity index 100%
rename from gemrb/override/iwd2/arrow.pro
rename to gemrb/unhardcoded/iwd2/arrow.pro
diff --git a/gemrb/override/iwd2/arrowex.pro b/gemrb/unhardcoded/iwd2/arrowex.pro
similarity index 100%
rename from gemrb/override/iwd2/arrowex.pro
rename to gemrb/unhardcoded/iwd2/arrowex.pro
diff --git a/gemrb/override/iwd2/arrowflb.pro b/gemrb/unhardcoded/iwd2/arrowflb.pro
similarity index 100%
rename from gemrb/override/iwd2/arrowflb.pro
rename to gemrb/unhardcoded/iwd2/arrowflb.pro
diff --git a/gemrb/override/iwd2/arrowflg.pro b/gemrb/unhardcoded/iwd2/arrowflg.pro
similarity index 100%
rename from gemrb/override/iwd2/arrowflg.pro
rename to gemrb/unhardcoded/iwd2/arrowflg.pro
diff --git a/gemrb/override/iwd2/arrowfli.pro b/gemrb/unhardcoded/iwd2/arrowfli.pro
similarity index 100%
rename from gemrb/override/iwd2/arrowfli.pro
rename to gemrb/unhardcoded/iwd2/arrowfli.pro
diff --git a/gemrb/override/iwd2/arrowflm.pro b/gemrb/unhardcoded/iwd2/arrowflm.pro
similarity index 100%
rename from gemrb/override/iwd2/arrowflm.pro
rename to gemrb/unhardcoded/iwd2/arrowflm.pro
diff --git a/gemrb/override/iwd2/arrowhvy.pro b/gemrb/unhardcoded/iwd2/arrowhvy.pro
similarity index 100%
rename from gemrb/override/iwd2/arrowhvy.pro
rename to gemrb/unhardcoded/iwd2/arrowhvy.pro
diff --git a/gemrb/unhardcoded/iwd2/artstr.spl b/gemrb/unhardcoded/iwd2/artstr.spl
new file mode 100644
index 0000000..572bbbf
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/artstr.spl differ
diff --git a/gemrb/override/iwd2/ascorch.pro b/gemrb/unhardcoded/iwd2/ascorch.pro
similarity index 100%
rename from gemrb/override/iwd2/ascorch.pro
rename to gemrb/unhardcoded/iwd2/ascorch.pro
diff --git a/gemrb/override/iwd2/astorm.pro b/gemrb/unhardcoded/iwd2/astorm.pro
similarity index 100%
rename from gemrb/override/iwd2/astorm.pro
rename to gemrb/unhardcoded/iwd2/astorm.pro
diff --git a/gemrb/override/iwd2/asumm1.pro b/gemrb/unhardcoded/iwd2/asumm1.pro
similarity index 100%
rename from gemrb/override/iwd2/asumm1.pro
rename to gemrb/unhardcoded/iwd2/asumm1.pro
diff --git a/gemrb/override/iwd2/asumm1h.pro b/gemrb/unhardcoded/iwd2/asumm1h.pro
similarity index 100%
rename from gemrb/override/iwd2/asumm1h.pro
rename to gemrb/unhardcoded/iwd2/asumm1h.pro
diff --git a/gemrb/override/iwd2/asumm1x.pro b/gemrb/unhardcoded/iwd2/asumm1x.pro
similarity index 100%
rename from gemrb/override/iwd2/asumm1x.pro
rename to gemrb/unhardcoded/iwd2/asumm1x.pro
diff --git a/gemrb/override/iwd2/asumm2h.pro b/gemrb/unhardcoded/iwd2/asumm2h.pro
similarity index 100%
rename from gemrb/override/iwd2/asumm2h.pro
rename to gemrb/unhardcoded/iwd2/asumm2h.pro
diff --git a/gemrb/override/iwd2/asumm3h.pro b/gemrb/unhardcoded/iwd2/asumm3h.pro
similarity index 100%
rename from gemrb/override/iwd2/asumm3h.pro
rename to gemrb/unhardcoded/iwd2/asumm3h.pro
diff --git a/gemrb/unhardcoded/iwd2/avatars.2da b/gemrb/unhardcoded/iwd2/avatars.2da
new file mode 100644
index 0000000..ecc82d4
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/avatars.2da
@@ -0,0 +1,433 @@
+2DA V1.0
+*
+ AT_1 AT_2 AT_3 AT_4 TYPE SPACE PALETTE SIZE
+0x0100 SPCHUNKS SPCHUNKS SPCHUNKS SPCHUNKS 13 0 0 *
+0x0300 SPSMPUFF SPSMPUFF SPSMPUFF SPSMPUFF 13 0 0 *
+0x0400 SKLH SKLH SKLH SKLH 13 0 1 *
+0x0410 GLPHWRDH GLPHWRDH GLPHWRDH GLPHWRDH 13 0 1 *
+0x1000 MWYV MWYV MWYV MWYV 11 5 1 *
+0x1001 MWY2 MWY2 MWY2 MWY2 11 5 1 *
+0x1100 MTAN MTAN MTAN MTAN 11 5 1 *
+0x1200 MDR1 MDR1 MDR1 MDR1 12 5 1 *
+0x1201 MDR2 MDR2 MDR2 MDR2 12 5 1 *
+0x1202 MDR3 MDR3 MDR3 MDR3 12 5 1 *
+0x1203 MDR1 MDR1 MDR1 MDR1 12 7 GR *
+0x1204 MDR1 MDR1 MDR1 MDR1 12 7 AQ *
+0x1205 MDR1 MDR1 MDR1 MDR1 12 7 BL *
+0x1206 MDR1 MDR1 MDR1 MDR1 12 7 BR *
+0x1207 MDR1 MDR1 MDR1 MDR1 12 7 MC *
+0x1208 MDR1 MDR1 MDR1 MDR1 12 7 PU *
+0x2000 MSIR MSIR MSIR MSIR 2 2 0 *
+0x2100 UVOL UVOL UVOL UVOL 2 2 1 *
+0x2200 MOGM MOGM MOGM MOGM 2 2 0 S
+0x2300 MDKN MDKN MDKN MDKN 2 2 1 *
+0x3000 MAKH MAKH MAKH MAKH 2 3 1 *
+0x4000 SNOMC SNOMC SNOMC SNOMC 1 2 0 *
+0x4002 SNOMM SNOMM SNOMM SNOMM 1 2 0 *
+0x4010 SNOWC SNOWC SNOWC SNOWC 1 2 0 *
+0x4012 SNOWM SNOWM SNOWM SNOWM 1 2 0 *
+0x4100 SSIMC SSIMC SSIMC SSIMC 1 2 0 *
+0x4101 SSIMS SSIMS SSIMS SSIMS 1 2 0 *
+0x4102 SSIMM SSIMM SSIMM SSIMM 1 2 0 *
+0x4110 SSIWC SSIWC SSIWC SSIWC 1 2 0 *
+0x4112 SSIWM SSIWM SSIWM SSIWM 1 2 0 *
+0x4200 SHMCM SHMCM SHMCM SHMCM 1 2 0 *
+0x4300 MSPLG1 MSPLG1 MSPLG1 MSPLG1 1 2 1 *
+0x4400 LHMC LHMC LHMC LHMC 1 2 0 *
+0x4410 LHFC LHFC LHFC LHFC 1 2 0 *
+0x4500 LFAM LFAM LFAM LFAM 1 2 0 *
+0x4600 LDMF LDMF LDMF LDMF 1 2 0 *
+0x4700 LEMF LEMF LEMF LEMF 1 2 0 *
+0x4710 LEFF LEFF LEFF LEFF 1 2 0 *
+0x4800 LIMC LIMC LIMC LIMC 1 2 0 *
+0x5000 CHMB1 CHMB2 CHMB3 CHMC4 0 2 0 *
+0x5001 CEMB1 CEMB2 CEMB3 CEMC4 0 2 0 *
+0x5002 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 *
+0x5003 CIMB1 CIMB2 CIMB3 CIMC4 0 2 0 *
+0x5010 CHFB1 CHFB2 CHFB3 CHFC4 0 2 0 *
+0x5011 CEFB1 CEFB2 CEFB3 CEFC4 0 2 0 *
+0x5012 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 *
+0x5013 CIFB1 CIFB2 CIFB3 CIFC4 0 2 0 *
+0x5100 CHMB1 CHMB2 CHMB3 CHMF4 0 2 0 *
+0x5101 CEMB1 CEMB2 CEMB3 CHMF4 0 2 0 *
+0x5102 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 *
+0x5103 CIMB1 CIMB2 CIMB3 CIMF4 0 2 0 *
+0x5110 CHFB1 CHFB2 CHFB3 CHFF4 0 2 0 *
+0x5111 CEFB1 CEFB2 CEFB3 CEFF4 0 2 0 *
+0x5112 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 *
+0x5113 CIFB1 CIFB2 CIFB3 CIFF4 0 2 0 *
+0x5200 CHMW1 CHMW2 CHMW3 CHMW4 0 2 0 *
+0x5201 CEMW1 CEMW2 CEMW3 CEMW4 0 2 0 *
+0x5202 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 *
+0x5203 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 *
+0x5210 CHFW1 CHFW2 CHFW3 CHFW4 0 2 0 *
+0x5211 CEFW1 CEFW2 CEFW3 CEFW4 0 2 0 *
+0x5212 CDMW1 CDFW2 CDFW3 CDFW4 0 2 0 *
+0x5213 CDMW1 CDFW2 CDFW3 CDFW4 0 2 0 *
+0x5300 CHMB1 CHMT2 CHMB3 CHMF4 0 2 0 *
+0x5301 CEMB1 CEMT2 CEMB3 CEMF4 0 2 0 *
+0x5302 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 *
+0x5303 CIMB1 CIMT2 CIMB3 CIMF4 0 2 0 *
+0x5310 CHFB1 CHFT2 CHFB3 CHFF4 0 2 0 *
+0x5311 CEFB1 CEFT2 CEFB3 CEFF4 0 2 0 *
+0x5312 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 *
+0x5313 CIFB1 CIFT2 CIFB3 CIFF4 0 2 0 *
+0x6000 CHMB1 CHMB2 CHMB3 CHMC4 0 2 0 *
+0x6001 CEMB1 CEMB2 CEMB3 CEMC4 0 2 0 *
+0x6002 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 *
+0x6003 CIMB1 CIMB2 CIMB3 CIMC4 0 2 0 *
+0x6004 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 *
+0x6005 CHMB1 CHMB2 CHMB3 CHMC4 0 2 0 *
+0x6010 CHFB1 CHFB2 CHFB3 CHFC4 0 2 0 *
+0x6011 CEFB1 CEFB2 CEFB3 CEFC4 0 2 0 *
+0x6012 CDMB1 CDMB2 CDMB3 CDMC4 0 2 0 *
+0x6013 CIFB1 CIFB2 CIFB3 CIFC4 0 2 0 *
+0x6014 CIFB1 CIFB2 CIFB3 CIFC4 0 2 0 *
+0x6015 CHFB1 CHFB2 CHFB3 CHFC4 0 2 0 *
+0x6100 CHMB1 CHMB2 CHMB3 CHMF4 0 2 0 *
+0x6101 CEMB1 CEMB2 CEMB3 CEMF4 0 2 0 *
+0x6102 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 *
+0x6103 CIMB1 CIMB2 CIMB3 CIMF4 0 2 0 *
+0x6104 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 *
+0x6105 CHMB1 CHMB2 CHMB3 CHMF4 0 2 0 *
+0x6110 CHFB1 CHFB2 CHFB3 CHFF4 0 2 0 *
+0x6111 CEFB1 CEFB2 CEFB3 CEFF4 0 2 0 *
+0x6112 CDMB1 CDMB2 CDMB3 CDMF4 0 2 0 *
+0x6113 CIFB1 CIFB2 CIFB3 CIFF4 0 2 0 *
+0x6114 CIFB1 CIFB2 CIFB3 CIFF4 0 2 0 *
+0x6115 CHFB1 CHFB2 CHFB3 CHFF4 0 2 0 *
+0x6200 CHMW1 CHMW2 CHMW3 CHMW4 0 2 0 *
+0x6201 CEMW1 CEMW2 CEMW3 CEMW4 0 2 0 *
+0x6202 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 *
+0x6203 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 *
+0x6204 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 *
+0x6205 CHMW1 CHMW2 CHMW3 CHMW4 0 2 0 *
+0x6210 CHFW1 CHFW2 CHFW3 CHFW4 0 2 0 *
+0x6211 CEFW1 CEFW2 CEFW3 CEFW4 0 2 0 *
+0x6212 CDMW1 CDFW2 CDFW3 CDFW4 0 2 0 *
+0x6213 CDMW1 CDFW2 CDFW3 CDFW4 0 2 0 *
+0x6214 CDMW1 CDMW2 CDMW3 CDMW4 0 2 0 *
+0x6215 CHFW1 CHFW2 CHFW3 CHFW4 0 2 0 *
+0x6300 CHMB1 CHMT2 CHMB3 CHMF4 0 2 0 *
+0x6301 CEMB1 CEMT2 CEMB3 CEMF4 0 2 0 *
+0x6302 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 *
+0x6303 CIMB1 CIMT2 CIMB3 CIMF4 0 2 0 *
+0x6304 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 *
+0x6305 CHMB1 CHMT2 CHMB3 CHMF4 0 2 0 *
+0x6310 CHFB1 CHFT2 CHFB3 CHFF4 0 2 0 *
+0x6311 CEFB1 CEFT2 CEFB3 CEFF4 0 2 0 *
+0x6312 CDMB1 CDMT2 CDMB3 CDMF4 0 2 0 *
+0x6313 CIFB1 CIFT2 CIFB3 CIFF4 0 2 0 *
+0x6314 CIFB1 CIFT2 CIFB3 CIFF4 0 2 0 *
+0x6315 CHFB1 CHFT2 CHFT3 CHFF4 0 2 0 *
+0x6400 UDRZ1 UDRZ1 UDRZ1 UDRZ1 6 2 0 *
+0x6401 UELM1 UELM1 UELM1 UELM1 6 2 1 *
+0x6402 CMNK1 CMNK1 CMNK1 CMNK1 6 2 0 *
+0x6403 MSKL1 MSKL1 MSKL1 MSKL1 6 2 0 M
+0x6404 USAR1 USAR1 USAR1 USAR1 6 2 1 *
+0x6405 MDGU1 MDGU1 MDGU1 MDGU1 6 2 0 M
+0x6406 MDGU1 MDGU1 MDGU1 MDGU1 6 2 0 L
+0x6500 CHMM1 CHMB2 CHMB3 CHMC4 0 2 0 *
+0x6510 CHFM1 CHFB2 CHFB3 CHFC4 0 2 0 *
+0x7000 MOGH MOGH MOGH MOGH 2 2 0 *
+0x7001 MOGN MOGN MOGN MOGN 2 2 0 *
+0x7100 MBAS MBAS MBAS MBAS 2 2 1 *
+0x7101 MBAS MBAS MBAS MBAS 2 2 GR *
+0x7200 MBER MBER MBER MBER 3 2 BL *
+0x7201 MBER MBER MBER MBER 3 2 1 *
+0x7202 MBER MBER MBER MBER 3 2 CA *
+0x7203 MBER MBER MBER MBER 3 2 PO *
+0x7300 MEAE MEAE MEAE MEAE 4 2 1 *
+0x7301 MEAS MEAS MEAS MEAS 4 2 1 *
+0x7310 MFIE MFIE MFIE MFIE 4 2 1 *
+0x7311 MFIS MFIS MFIS MFIS 4 2 1 *
+0x7320 MAIR MAIR MAIR MAIR 4 2 1 *
+0x7321 MAIS MAIS MAIS MAIS 4 2 1 *
+0x7400 MDOG MDOG MDOG MDOG 2 2 WI *
+0x7401 MDOG MDOG MDOG MDOG 2 2 WA *
+0x7402 MDOG MDOG MDOG MDOG 2 2 MO *
+0x7500 MDOP MDOP MDOP MDOP 3 2 1 *
+0x7501 MDOP MDOP MDOP MDOP 3 2 GR *
+0x7600 METT METT METT METT 2 2 1 *
+0x7701 MGHL MGHL MGHL MGHL 2 2 1 *
+0x7702 MGHL MGHL MGHL MGHL 2 2 RE *
+0x7703 MGHL MGHL MGHL MGHL 2 2 GA *
+0x7704 MSHD MSHD MSHD MSHD 4 2 1 *
+0x7800 MGIB MGIB MGIB MGIB 14 2 1 *
+0x7900 MSLI MSLI MSLI MSLI 3 3 GR *
+0x7901 MSLI MSLI MSLI MSLI 3 3 OL *
+0x7902 MSLI MSLI MSLI MSLI 3 3 MU *
+0x7903 MSLI MSLI MSLI MSLI 3 3 OC *
+0x7904 MSLI MSLI MSLI MSLI 3 3 1 *
+0x7A00 MSPI MSPI MSPI MSPI 3 2 GI *
+0x7A01 MSPI MSPI MSPI MSPI 3 2 HU *
+0x7A02 MSPI MSPI MSPI MSPI 3 2 PH *
+0x7A03 MSPI MSPI MSPI MSPI 3 2 SW *
+0x7A04 MSPI MSPI MSPI MSPI 3 2 WR *
+0x7B00 MWLF MWLF MWLF MWLF 2 2 1 *
+0x7B01 MWLF MWLF MWLF MWLF 2 2 WO *
+0x7B02 MWLF MWLF MWLF MWLF 2 2 DI *
+0x7B03 MWLF MWLF MWLF MWLF 2 2 WI *
+0x7B04 MWLF MWLF MWLF MWLF 2 2 VA *
+0x7B05 MWLF MWLF MWLF MWLF 2 2 DR *
+0x7B06 MWLS MWLS MWLS MWLS 2 2 1 *
+0x7C00 MXVT MXVT MXVT MXVT 2 2 0 *
+0x7C01 MTAS MTAS MTAS MTAS 2 2 0 *
+0x7D00 MZOM MZOM MZOM MZOM 2 2 0 *
+0x7E00 MWER MWER MWER MWER 2 2 1 *
+0x7E01 MGWE MGWE MGWE MGWE 2 2 1 *
+0x7F00 MTRO MTRO MTRO MTRO 4 2 1 *
+0x7F01 MMIN MMIN MMIN MMIN 4 2 1 *
+0x7F02 MBEH MBEH MBEH MBEH 4 3 1 *
+0x7F03 MIMP MIMP MIMP MIMP 4 2 1 *
+0x7F04 MIGO MIGO MIGO MIGO 4 2 1 *
+0x7F05 MDJI MDJI MDJI MDJI 4 2 1 *
+0x7F06 MDJL MDJL MDJL MDJL 4 2 1 *
+0x7F07 MGLC MGLC MGLC MGLC 4 3 1 *
+0x7F08 MOTY MOTY MOTY MOTY 4 4 1 *
+0x7F09 MSAH MSAH MSAH MSAH 4 2 1 *
+0x7F0A MGCP MGCP MGCP MGCP 4 2 1 *
+0x7F0B MGCL MGCL MGCL MGCL 4 2 1 *
+0x7F0C MKUO MKUO MKUO MKUO 4 2 1 *
+0x7F0D MLIC MLIC MLIC MLIC 4 2 1 *
+0x7F0E MDLI MDLI MDLI MDLI 4 2 1 *
+0x7F0F MTRS MTRS MTRS MTRS 4 2 1 *
+0x7F10 MRAK MRAK MRAK MRAK 4 2 1 *
+0x7F11 MUMB MUMB MUMB MUMB 4 2 1 *
+0x7F12 MVAM MVAM MVAM MVAM 4 2 1 *
+0x7F13 MSNK MSNK MSNK MSNK 4 2 1 *
+0x7F14 MGIT MGIT MGIT MGIT 4 2 1 *
+0x7F15 MBES MBES MBES MBES 4 2 1 *
+0x7F16 AMOO AMOO AMOO AMOO 4 3 1 *
+0x7F17 ARAB ARAB ARAB ARAB 4 1 1 *
+0x7F18 ADER ADER ADER ADER 4 2 1 *
+0x7F19 MDSW MDSW MDSW MDSW 4 2 1 *
+0x7F20 AGRO AGRO AGRO AGRO 4 2 1 *
+0x7F21 APHE APHE APHE APHE 4 2 1 *
+0x7F22 MVAF MVAF MVAF MVAF 4 2 1 *
+0x7F23 MSAT MSAT MSAT MSAT 4 3 1 *
+0x7F24 NPIR NPIR NPIR NPIR 4 2 1 *
+0x7F27 MDRO MDRO MDRO MDRO 4 2 1 *
+0x7F28 MKUL MKUL MKUL MKUL 4 3 1 *
+0x7F29 MFDR MFDR MFDR MFDR 4 2 1 *
+0x7F2A NSAI NSAI NSAI NSAI 4 2 1 *
+0x7F2B MMAX MMAX MMAX MMAX 4 2 1 *
+0x7F2C NSOL NSOL NSOL NSOL 4 2 1 *
+0x7F2D MWFM MWFM MWFM MWFM 4 2 1 *
+0x7F2E MRAV MRAV MRAV MRAV 4 3 1 *
+0x7F2F MSPS MSPS MSPS MSPS 4 2 1 *
+0x7F30 NBOH NBOH NBOH NBOH 4 2 1 *
+0x7F31 NELL NELL NELL NELL 4 2 1 *
+0x7F32 MSLY MSLY MSLY MSLY 4 2 1 *
+0x7F33 MKUR MKUR MKUR MKUR 4 2 1 *
+0x7F34 MDOC MDOC MDOC MDOC 4 2 1 *
+0x7F35 MMIS MMIS MMIS MMIS 4 3 1 *
+0x7F36 NSHD NSHD NSHD NSHD 4 2 1 *
+0x7F37 NIRE NIRE NIRE NIRE 4 2 1 *
+0x8000 MGNL MGNL MGNL MGNL 2 2 0 *
+0x8100 MHOB MHOB MHOB MHOB 2 2 0 *
+0x8200 MKOB MKOB MKOB MKOB 2 2 0 *
+0x9000 MOGR MOGR MOGR MOGR 5 2 0 *
+0xA000 MWYV MWYV MWYV MWYV 8 3 1 *
+0xA100 MCAR MCAR MCAR MCAR 8 3 1 *
+0xB000 ACOW ACOW ACOW ACOW 10 3 1 *
+0xB100 AHRS AHRS AHRS AHRS 10 3 1 *
+0xB200 NBEGL NBEGL NBEGL NBEGL 3 2 0 *
+0xB210 NPROL NPROL NPROL NPROL 3 2 0 *
+0xB300 NBOYL NBOYL NBOYL NBOYL 3 2 0 *
+0xB310 NGRLL NGRLL NGRLL NGRLL 3 2 0 *
+0xB400 NFAML NFAML NFAML NFAML 3 2 0 *
+0xB410 NFAWL NFAWL NFAWL NFAWL 3 2 0 *
+0xB500 NSIML NSIML NSIML NSIML 3 2 0 *
+0xB510 NSIWL NSIWL NSIWL NSIWL 3 2 0 *
+0xB600 NNOML NNOML NNOML NNOML 3 2 0 *
+0xB610 NNOWL NNOWL NNOWL NNOWL 3 2 0 *
+0xB700 NSLVL NSLVL NSLVL NSLVL 3 2 0 *
+0xC000 ABAT ABAT ABAT ABAT 3 1 1 *
+0xC100 ACAT ACAT ACAT ACAT 3 1 1 *
+0xC200 ACHK ACHK ACHK ACHK 3 1 1 *
+0xC300 ARAT ARAT ARAT ARAT 3 1 1 *
+0xC400 ASQU ASQU ASQU ASQU 3 1 1 *
+0xC500 ABAT ABAT ABAT ABAT 3 1 1 *
+0xC600 NBEGH NBEGH NBEGH NBEGH 3 2 0 *
+0xC610 NPROH NPROH NPROH NPROH 3 2 0 *
+0xC700 NBOYH NBOYH NBOYH NBOYH 3 2 0 *
+0xC710 NGRLH NGRLH NGRLH NGRLH 3 2 0 *
+0xC800 NFAMH NFAMH NFAMH NFAMH 3 2 0 *
+0xC810 NFAWH NFAWH NFAWH NFAWH 3 2 0 *
+0xC900 NSIMH NSIMH NSIMH NSIMH 3 2 0 *
+0xC910 NSIWH NSIWH NSIWH NSIWH 3 2 0 *
+0xCA00 NNOMH NNOMH NNOMH NNOMH 3 2 0 *
+0xCA10 NNOWH NNOWH NNOWH NNOWH 3 2 0 *
+0xCB00 NSLVH NSLVH NSLVH NSLVH 3 2 0 *
+0xD000 AEAGG1 AEAGG1 AEAGG1 AEAGG1 7 0 1 *
+0xD100 AGULG1 AGULG1 AGULG1 AGULG1 7 0 1 *
+0xD200 AVULG1 AVULG1 AVULG1 AVULG1 7 0 1 *
+0xD300 ABIRG1 ABIRG1 ABIRG1 ABIRG1 7 0 1 *
+0xD400 ABIRG1 ABIRG1 ABIRG1 ABIRG1 7 0 1 *
+0xE000 MBET MBET MBET MBET 9 2 1 *
+0xE012 MBBM MBBM MBBM MBBM 9 2 1 *
+0xE020 MTAN MTAN MTAN MTAN 9 4 1 *
+0xEBCD MTAN MTAN MTAN MTAN 9 4 1 *
+0xE022 MBBR MBBR MBBR MBBR 9 2 1 *
+0xE038 MBFI MBFI MBFI MBFI 9 2 1 *
+0xE048 MBRH MBRH MBRH MBRH 9 5 1 *
+0xE050 MREM MREM MREM MREM 9 4 1 *
+0xE060 MLIC MLIC MLIC MLIC 9 2 1 *
+0xEB69 MLIC MLIC MLIC MLIC 9 2 1 *
+0xE068 MHOH MHOH MHOH MHOH 9 2 1 *
+0xE070 MMIN MMIN MMIN MMIN 9 2 1 *
+0xE090 MMER MMER MMER MMER 9 2 1 *
+0xE0A0 MTIC MTIC MTIC MTIC 9 2 1 *
+0xE728 MTIC MTIC MTIC MTIC 9 2 1 *
+0xE0B0 MTRO MTRO MTRO MTRO 9 2 1 *
+0xE718 MTRO MTRO MTRO MTRO 9 2 1 *
+0xE0C0 MTSN MTSN MTSN MTSN 9 2 1 *
+0xE738 MTSN MTSN MTSN MTSN 9 2 1 *
+0xE0D0 MUMB MUMB MUMB MUMB 9 2 1 *
+0xE759 MUMB MUMB MUMB MUMB 9 2 1 *
+0xE0E0 MCOR MCOR MCOR MCOR 9 3 1 *
+0xED09 MCOR MCOR MCOR MCOR 9 3 1 *
+0xE0F0 MGIC MGIC MGIC MGIC 9 2 1 *
+0xE0F1 MGLA MGLA MGLA MGLA 9 2 1 *
+0xE108 MCYC MCYC MCYC MCYC 9 4 1 *
+0xE118 METN METN METN METN 9 4 1 *
+0xE138 MGFR MGFR MGFR MGFR 9 4 1 *
+0xE148 MGVE MGVE MGVE MGVE 9 4 1 *
+0xE15A MGFO MGFO MGFO MGFO 9 4 1 *
+0xE218 MELE MELE MELE MELE 9 4 1 *
+0xE228 MELF MELF MELF MELF 9 4 1 *
+0xE238 MELW MELW MELW MELW 9 4 1 *
+0xE249 MHAR MHAR MHAR MHAR 9 2 1 *
+0xE252 MWWE MWWE MWWE MWWE 9 2 1 *
+0xE269 MFEY MFEY MFEY MFEY 9 2 1 *
+0xE278 MDTR MDTR MDTR MDTR 9 3 1 *
+0xE289 MFE2 MFE2 MFE2 MFE2 9 3 1 *
+0xE298 MEW2 MEW2 MEW2 MEW2 9 2 1 *
+0xE300 MGHO MGHO MGHO MGHO 9 2 1 *
+0xE928 MGHO MGHO MGHO MGHO 9 2 1 *
+0xE308 MGH2 MGH2 MGH2 MGH2 9 2 1 *
+0xE318 MGH3 MGH3 MGH3 MGH3 9 2 1 *
+0xE329 MWIG MWIG MWIG MWIG 9 2 1 *
+0xE338 MZO2 MZO2 MZO2 MZO2 9 2 1 *
+0xE348 MZO3 MZO3 MZO3 MZO3 9 2 1 *
+0xE359 MWI2 MWI2 MWI2 MWI2 9 2 1 *
+0xE369 MWI3 MWI3 MWI3 MWI3 9 2 1 *
+0xE388 MMUM MMUM MMUM MMUM 9 2 1 *
+0xE39C MHIS MHIS MHIS MHIS 9 2 1 *
+0xE3A8 MDRD MDRD MDRD MDRD 9 2 1 *
+0xE3BB MWAV MWAV MWAV MWAV 9 2 1 *
+0xE408 MGO1 MGO1 MGO1 MGO1 9 2 1 *
+0xE412 MGO2 MGO2 MGO2 MGO2 9 2 1 *
+0xE428 MGO3 MGO3 MGO3 MGO3 9 2 1 *
+0xE432 MGO4 MGO4 MGO4 MGO4 9 2 1 *
+0xE449 MSVI MSVI MSVI MSVI 9 2 1 *
+0xE459 MSV2 MSV2 MSV2 MSV2 9 2 1 *
+0xE468 MGWO MGWO MGWO MGWO 9 2 1 *
+0xE479 MGOC MGOC MGOC MGOC 9 2 1 *
+0xE488 MGW2 MGW2 MGW2 MGW2 9 2 1 *
+0xE498 MGO5 MGO5 MGO5 MGO5 9 2 1 *
+0xE500 MLIZ MLIZ MLIZ MLIZ 9 2 1 *
+0xF209 MLIZ MLIZ MLIZ MLIZ 9 2 1 *
+0xE510 MLI2 MLI2 MLI2 MLI2 9 2 1 *
+0xF218 MLI2 MLI2 MLI2 MLI2 9 2 1 *
+0xE51D MGIR MGIR MGIR MGIR 9 2 1 *
+0xE520 MLI3 MLI3 MLI3 MLI3 9 2 1 *
+0xE899 MLI3 MLI3 MLI3 MLI3 9 2 1 *
+0xE528 MGIC MGIC MGIC MGIC 9 2 1 *
+0xE600 MMYC MMYC MMYC MMYC 9 2 1 *
+0xEB99 MMYC MMYC MMYC MMYC 9 2 1 *
+0xE610 MMY2 MMY2 MMY2 MMY2 9 2 1 *
+0xEBA9 MMY2 MMY2 MMY2 MMY2 9 2 1 *
+0xE62C MSKB MSKB MSKB MSKB 9 2 1 *
+0xE700 MNO1 MNO1 MNO1 MNO1 9 2 1 *
+0xE868 MNO1 MNO1 MNO1 MNO1 9 2 1 *
+0xE710 MNO2 MNO2 MNO2 MNO2 9 2 1 *
+0xE878 MNO2 MNO2 MNO2 MNO2 9 2 1 *
+0xE720 MNO3 MNO3 MNO3 MNO3 9 2 1 *
+0xE888 MNO3 MNO3 MNO3 MNO3 9 2 1 *
+0xE88C MNO3 MNO3 MNO3 MNO3 9 2 1 *
+0xE76C MYET MYET MYET MYET 9 2 1 *
+0xE771 MBA4 MBA4 MBA4 MBA4 9 2 1 *
+0xE781 MBA5 MBA5 MBA5 MBA5 9 2 1 *
+0xE791 MBA6 MBA6 MBA6 MBA6 9 2 1 *
+0xE7AC MBAI MBAI MBAI MBAI 9 2 1 *
+0xE7B8 MBOA MBOA MBOA MBOA 9 2 1 *
+0xE7C9 MABW MABW MABW MABW 9 2 1 *
+0xE7E8 MSCR MSCR MSCR MSCR 9 2 1 *
+0xE7F9 MUM2 MUM2 MUM2 MUM2 9 2 1 *
+0xE800 MOR1 MOR1 MOR1 MOR1 9 2 1 *
+0xE818 MOR1 MOR1 MOR1 MOR1 9 2 1 *
+0xE808 MOR6 MOR6 MOR6 MOR6 9 2 1 *
+0xE810 MOR2 MOR2 MOR2 MOR2 9 2 1 *
+0xE822 MOR2 MOR2 MOR2 MOR2 9 2 1 *
+0xE820 MOR3 MOR3 MOR3 MOR3 9 2 1 *
+0xE838 MOR3 MOR3 MOR3 MOR3 9 2 1 *
+0xE830 MOR4 MOR4 MOR4 MOR4 9 2 1 *
+0xE842 MOR4 MOR4 MOR4 MOR4 9 2 1 *
+0xE840 MOR5 MOR5 MOR5 MOR5 9 2 1 *
+0xE859 MOR5 MOR5 MOR5 MOR5 9 2 1 *
+0xE8C8 MBUG MBUG MBUG MBUG 9 2 1 *
+0xE8D9 MNOS MNOS MNOS MNOS 9 2 1 *
+0xE8E8 MBU2 MBU2 MBU2 MBU2 9 2 1 *
+0xE8F9 MOR7 MOR7 MOR7 MOR7 9 2 1 *
+0xE900 MSAL MSAL MSAL MSAL 9 2 1 *
+0xEBD8 MSAL MSAL MSAL MSAL 9 2 1 *
+0xE910 MSA2 MSA2 MSA2 MSA2 9 2 1 *
+0xEBE8 MSA2 MSA2 MSA2 MSA2 9 2 1 *
+0xE918 MSH2 MSH2 MSH2 MSH2 9 2 1 *
+0xEA00 MSHR MSHR MSHR MSHR 9 2 1 *
+0xEBB1 MSHR MSHR MSHR MSHR 9 2 1 *
+0xEBF1 MARU MARU MARU MARU 9 2 1 *
+0xEA10 MSH1 MSH1 MSH1 MSH1 9 2 1 *
+0xE908 MSH1 MSH1 MSH1 MSH1 9 2 1 *
+0xEA20 MCRD MCRD MCRD MCRD 9 2 1 *
+0xEB00 MSKT MSKT MSKT MSKT 9 2 1 *
+0xF019 MSKT MSKT MSKT MSKT 9 2 1 *
+0xEB10 MSKA MSKA MSKA MSKA 9 2 1 *
+0xEB18 MANI MANI MANI MANI 9 2 1 *
+0xEB28 MAN2 MAN2 MAN2 MAN2 9 2 1 *
+0xEB39 MBE1 MBE1 MBE1 MBE1 9 2 1 *
+0xEB49 MBE2 MBE2 MBE2 MBE2 9 2 1 *
+0xEB79 MLER MLER MLER MLER 9 2 1 *
+0xEC0B MWDR MWDR MWDR MWDR 9 2 1 *
+0xEC2B MSHE MSHE MSHE MSHE 9 2 1 *
+0xEC33 MCHI MCHI MCHI MCHI 9 2 1 *
+0xEC4B MDH1 MDH1 MDH1 MDH1 9 2 1 *
+0xEC5B MDH2 MDH2 MDH2 MDH2 9 2 1 *
+0xF008 MSKA MSKA MSKA MSKA 9 2 1 *
+0xED00 MYU1 MYU1 MYU1 MYU1 9 2 1 *
+0xF10E MYU1 MYU1 MYU1 MYU1 9 2 1 *
+0xED10 MYU2 MYU2 MYU2 MYU2 9 2 1 *
+0xF11E MYU2 MYU2 MYU2 MYU2 9 2 1 *
+0xED19 MGLA MGLA MGLA MGLA 9 2 1 *
+0xED20 MYU3 MYU3 MYU3 MYU3 9 2 1 *
+0xE8A1 MYU3 MYU3 MYU3 MYU3 9 2 1 *
+0xED28 MLEM MLEM MLEM MLEM 9 2 1 *
+0xEE08 MWEB MWEB MWEB MWEB 9 2 1 *
+0xEE18 MWRA MWRA MWRA MWRA 9 2 1 *
+0xEF0D MISA MISA MISA MISA 9 2 1 *
+0xEF28 MWOR MWOR MWOR MWOR 9 2 1 *
+0xEF50 MKG1 MKG1 MKG1 MKG1 9 2 1 *
+0xEF60 MKG2 MKG2 MKG2 MKG2 9 2 1 *
+0xEF70 MKG3 MKG3 MKG3 MKG3 9 2 1 *
+0xEF92 MWIL MWIL MWIL MWIL 9 2 1 *
+0xEFA3 MGEN MGEN MGEN MGEN 9 2 1 *
+0xEFB3 MGEN MGEN MGEN MGEN 9 3 1 *
+0xEFC3 MGEN MGEN MGEN MGEN 9 4 1 *
+0xEFD3 MGEN MGEN MGEN MGEN 9 5 1 *
+0xEFE3 MGEN MGEN MGEN MGEN 9 1 1 *
+0xEFF3 MGEN MGEN MGEN MGEN 9 6 1 *
+0xE708 MMIN MMIN MMIN MMIN 9 2 1 *
+0xE7D9 MMAL MMAL MMAL MMAL 9 2 1 *
+0xE8B9 MYUH MYUH MYUH MYUH 9 2 1 *
+0xEF1D MMAD MMAD MMAD MMAD 9 2 1 *
+0xF029 MWI4 MWI4 MWI4 MWI4 9 2 1 *
+0xF308 MGFI MGFI MGFI MGFI 9 4 1 *
+0xF40B MSAH MSAH MSAH MSAH 9 2 1 *
+0xF41B MSAT MSAT MSAT MSAT 9 2 1 *
+0xF50B MDRM MDRM MDRM MDRM 9 4 1 *
+0xF51B MDRF MDRF MDRF MDRF 9 4 1 *
+0xF77A MBA1 MBA1 MBA1 MBA1 9 2 1 *
+0xF78A MBA2 MBA2 MBA2 MBA2 9 2 1 *
+0xF798 MBA3 MBA3 MBA3 MBA3 9 2 1 *
diff --git a/gemrb/override/iwd2/avprefc.2da b/gemrb/unhardcoded/iwd2/avprefc.2da
similarity index 100%
rename from gemrb/override/iwd2/avprefc.2da
rename to gemrb/unhardcoded/iwd2/avprefc.2da
diff --git a/gemrb/override/iwd2/avprefr.2da b/gemrb/unhardcoded/iwd2/avprefr.2da
similarity index 100%
rename from gemrb/override/iwd2/avprefr.2da
rename to gemrb/unhardcoded/iwd2/avprefr.2da
diff --git a/gemrb/override/iwd2/axe.pro b/gemrb/unhardcoded/iwd2/axe.pro
similarity index 100%
rename from gemrb/override/iwd2/axe.pro
rename to gemrb/unhardcoded/iwd2/axe.pro
diff --git a/gemrb/override/iwd2/axeex.pro b/gemrb/unhardcoded/iwd2/axeex.pro
similarity index 100%
rename from gemrb/override/iwd2/axeex.pro
rename to gemrb/unhardcoded/iwd2/axeex.pro
diff --git a/gemrb/override/iwd2/bbarrh1.pro b/gemrb/unhardcoded/iwd2/bbarrh1.pro
similarity index 100%
rename from gemrb/override/iwd2/bbarrh1.pro
rename to gemrb/unhardcoded/iwd2/bbarrh1.pro
diff --git a/gemrb/override/iwd2/bbarrh2.pro b/gemrb/unhardcoded/iwd2/bbarrh2.pro
similarity index 100%
rename from gemrb/override/iwd2/bbarrh2.pro
rename to gemrb/unhardcoded/iwd2/bbarrh2.pro
diff --git a/gemrb/override/iwd2/bbarrier.pro b/gemrb/unhardcoded/iwd2/bbarrier.pro
similarity index 100%
rename from gemrb/override/iwd2/bbarrier.pro
rename to gemrb/unhardcoded/iwd2/bbarrier.pro
diff --git a/gemrb/override/iwd2/bdeath.pro b/gemrb/unhardcoded/iwd2/bdeath.pro
similarity index 100%
rename from gemrb/override/iwd2/bdeath.pro
rename to gemrb/unhardcoded/iwd2/bdeath.pro
diff --git a/gemrb/override/iwd2/bigboldr.pro b/gemrb/unhardcoded/iwd2/bigboldr.pro
similarity index 100%
rename from gemrb/override/iwd2/bigboldr.pro
rename to gemrb/unhardcoded/iwd2/bigboldr.pro
diff --git a/gemrb/unhardcoded/iwd2/bios.2da b/gemrb/unhardcoded/iwd2/bios.2da
new file mode 100644
index 0000000..84d966f
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/bios.2da
@@ -0,0 +1,14 @@
+2DA V1.0
+*
+ CLASS BIO
+0 BARBARIAN 27862
+1 BARD 19425
+2 CLERIC 19422
+3 DRUID 19421
+4 FIGHTER 19423
+5 MONK 27860
+6 PALADIN 13427
+7 RANGER 19429
+8 ROGUE 19428
+9 SORCERER 27863
+10 WIZARD 19430
diff --git a/gemrb/override/iwd2/blessh.pro b/gemrb/unhardcoded/iwd2/blessh.pro
similarity index 100%
rename from gemrb/override/iwd2/blessh.pro
rename to gemrb/unhardcoded/iwd2/blessh.pro
diff --git a/gemrb/unhardcoded/iwd2/bloodclr.2da b/gemrb/unhardcoded/iwd2/bloodclr.2da
new file mode 100644
index 0000000..5d10be9
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/bloodclr.2da
@@ -0,0 +1,29 @@
+2DA V1.0
+0
+ VALUE MIN MAX FLAGS
+NORMAL 0x2f 0x1000 0xffff 0
+PURPLE 0x2d 0x4300 0x43ff 0
+MSKEL 0x25 0x5403 0x5403 1
+DOOMG 0x22 0x5405 0x5406 1
+MSKEL 0x25 0x6403 0x6403 1
+DOOMG 0x22 0x6405 0x6406 1
+YELLOW 0x32 0x7300 0x73ff 0
+PURPLE 0x3c 0x7500 0x75ff 0
+YELLOW 0x32 0x7600 0x76ff 1
+BLACK 0x66 0x7700 0x77ff 1
+SLI_GR 7 0x7900 0x7900 1
+SLI_OL 0x24 0x7901 0x7901 1
+SLI_MU 0x33 0x7902 0x7902 1
+SLI_OC 0x25 0x7903 0x7903 1
+SLIME 0x1b 0x7904 0x7904 1
+SPIDER 0x33 0x7a00 0x7aff 1
+ZOMBIE 0x25 0x7c00 0x7cff 1
+MTRO 0x33 0x7f00 0x7f00 0
+MMIN 0x3d 0x7f01 0x7f03 0
+MIGO 0x1a 0x7f04 0x7f04 1
+MGLC 0x5d 0x7f07 0x7f07 0
+MTRS 0x32 0x7f0f 0x7f0f 0
+MBES 0x3d 0x7f15 0x7f15 0
+MCAR 0x38 0xa100 0xa1ff 0
+UNDEAD 0x66 0xe300 0xe3ff 1
+MWWE 0x38 0xef00 0xefff 1
diff --git a/gemrb/override/iwd2/bolt.pro b/gemrb/unhardcoded/iwd2/bolt.pro
similarity index 100%
rename from gemrb/override/iwd2/bolt.pro
rename to gemrb/unhardcoded/iwd2/bolt.pro
diff --git a/gemrb/override/iwd2/boltex.pro b/gemrb/unhardcoded/iwd2/boltex.pro
similarity index 100%
rename from gemrb/override/iwd2/boltex.pro
rename to gemrb/unhardcoded/iwd2/boltex.pro
diff --git a/gemrb/override/iwd2/boulder.pro b/gemrb/unhardcoded/iwd2/boulder.pro
similarity index 100%
rename from gemrb/override/iwd2/boulder.pro
rename to gemrb/unhardcoded/iwd2/boulder.pro
diff --git a/gemrb/override/iwd2/bscloud.pro b/gemrb/unhardcoded/iwd2/bscloud.pro
similarity index 100%
rename from gemrb/override/iwd2/bscloud.pro
rename to gemrb/unhardcoded/iwd2/bscloud.pro
diff --git a/gemrb/override/iwd2/bullet.pro b/gemrb/unhardcoded/iwd2/bullet.pro
similarity index 100%
rename from gemrb/override/iwd2/bullet.pro
rename to gemrb/unhardcoded/iwd2/bullet.pro
diff --git a/gemrb/override/iwd2/bulletex.pro b/gemrb/unhardcoded/iwd2/bulletex.pro
similarity index 100%
rename from gemrb/override/iwd2/bulletex.pro
rename to gemrb/unhardcoded/iwd2/bulletex.pro
diff --git a/gemrb/override/iwd2/calllih.pro b/gemrb/unhardcoded/iwd2/calllih.pro
similarity index 100%
rename from gemrb/override/iwd2/calllih.pro
rename to gemrb/unhardcoded/iwd2/calllih.pro
diff --git a/gemrb/override/iwd2/ccdamah.pro b/gemrb/unhardcoded/iwd2/ccdamah.pro
similarity index 100%
rename from gemrb/override/iwd2/ccdamah.pro
rename to gemrb/unhardcoded/iwd2/ccdamah.pro
diff --git a/gemrb/override/iwd2/ccommah.pro b/gemrb/unhardcoded/iwd2/ccommah.pro
similarity index 100%
rename from gemrb/override/iwd2/ccommah.pro
rename to gemrb/unhardcoded/iwd2/ccommah.pro
diff --git a/gemrb/override/iwd2/ccwounh.pro b/gemrb/unhardcoded/iwd2/ccwounh.pro
similarity index 100%
rename from gemrb/override/iwd2/ccwounh.pro
rename to gemrb/unhardcoded/iwd2/ccwounh.pro
diff --git a/gemrb/override/iwd2/cdiseah.pro b/gemrb/unhardcoded/iwd2/cdiseah.pro
similarity index 100%
rename from gemrb/override/iwd2/cdiseah.pro
rename to gemrb/unhardcoded/iwd2/cdiseah.pro
diff --git a/gemrb/override/iwd2/ceelem1.pro b/gemrb/unhardcoded/iwd2/ceelem1.pro
similarity index 100%
rename from gemrb/override/iwd2/ceelem1.pro
rename to gemrb/unhardcoded/iwd2/ceelem1.pro
diff --git a/gemrb/override/iwd2/ceelemh.pro b/gemrb/unhardcoded/iwd2/ceelemh.pro
similarity index 100%
rename from gemrb/override/iwd2/ceelemh.pro
rename to gemrb/unhardcoded/iwd2/ceelemh.pro
diff --git a/gemrb/override/iwd2/ceelemx.pro b/gemrb/unhardcoded/iwd2/ceelemx.pro
similarity index 100%
rename from gemrb/override/iwd2/ceelemx.pro
rename to gemrb/unhardcoded/iwd2/ceelemx.pro
diff --git a/gemrb/override/iwd2/cfelem1.pro b/gemrb/unhardcoded/iwd2/cfelem1.pro
similarity index 100%
rename from gemrb/override/iwd2/cfelem1.pro
rename to gemrb/unhardcoded/iwd2/cfelem1.pro
diff --git a/gemrb/override/iwd2/cfelemh.pro b/gemrb/unhardcoded/iwd2/cfelemh.pro
similarity index 100%
rename from gemrb/override/iwd2/cfelemh.pro
rename to gemrb/unhardcoded/iwd2/cfelemh.pro
diff --git a/gemrb/override/iwd2/cfelemx.pro b/gemrb/unhardcoded/iwd2/cfelemx.pro
similarity index 100%
rename from gemrb/override/iwd2/cfelemx.pro
rename to gemrb/unhardcoded/iwd2/cfelemx.pro
diff --git a/gemrb/override/iwd2/cfog.pro b/gemrb/unhardcoded/iwd2/cfog.pro
similarity index 100%
rename from gemrb/override/iwd2/cfog.pro
rename to gemrb/unhardcoded/iwd2/cfog.pro
diff --git a/gemrb/override/iwd2/cgraceh.pro b/gemrb/unhardcoded/iwd2/cgraceh.pro
similarity index 100%
rename from gemrb/override/iwd2/cgraceh.pro
rename to gemrb/unhardcoded/iwd2/cgraceh.pro
diff --git a/gemrb/override/iwd2/cgtable.2da b/gemrb/unhardcoded/iwd2/cgtable.2da
similarity index 100%
rename from gemrb/override/iwd2/cgtable.2da
rename to gemrb/unhardcoded/iwd2/cgtable.2da
diff --git a/gemrb/override/iwd2/chant.pro b/gemrb/unhardcoded/iwd2/chant.pro
similarity index 100%
rename from gemrb/override/iwd2/chant.pro
rename to gemrb/unhardcoded/iwd2/chant.pro
diff --git a/gemrb/override/iwd2/chromorb.pro b/gemrb/unhardcoded/iwd2/chromorb.pro
similarity index 100%
rename from gemrb/override/iwd2/chromorb.pro
rename to gemrb/unhardcoded/iwd2/chromorb.pro
diff --git a/gemrb/unhardcoded/iwd2/classes.2da b/gemrb/unhardcoded/iwd2/classes.2da
new file mode 100644
index 0000000..e208f7d
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/classes.2da
@@ -0,0 +1,38 @@
+2DA V1.0
+*
+ NAME_REF DESC_REF ID CLASS CLAB SAVE HP USABILITY HUMAN ELF HALF_ELF DWARF HALFLING GNOME HALFORC TOHIT
+BARBARIAN 34 37 1 0 CLABFI05 SAVEWAR HPBARB 1 1 1 1 1 1 1 1 BAATFGT
+BARD 1083 9562 2 0 CLABBA01 SAVEBRD HPBRD 2 1 1 1 1 1 1 1 BAATNFG
+CLERIC 1079 9559 3 0 CLABPR01 SAVEPRS HPPRS 4 1 1 1 1 1 1 1 BAATNFG
+DRUID 1080 9560 4 0 CLABDR01 SAVEPRS HPPRS 8 1 1 1 1 1 1 1 BAATNFG
+FIGHTER 10174 9556 5 0 CLABFI01 SAVEWAR HPWAR 16 1 1 1 1 1 1 1 BAATFGT
+MONK 33 36 6 0 CLABMO01 SAVEMONK HPMONK 32 1 1 1 1 1 1 1 BAATMKU
+PALADIN 1078 9558 7 0 CLABPA01 SAVEWAR HPWAR 64 1 1 1 1 1 1 1 BAATFGT
+RANGER 1077 9557 8 0 CLABRN01 SAVEWAR HPWAR 128 1 1 1 1 1 1 1 BAATFGT
+ROGUE 1082 9561 9 0 CLABTH01 SAVEROG HPROG 256 1 1 1 1 1 1 1 BAATNFG
+SORCERER 32 35 10 0 CLABSR01 SAVEWIZ HPWIZ 512 1 1 1 1 1 1 1 BAATMAG
+WIZARD 9987 9563 11 0 CLABMA01 SAVEWIZ HPWIZ 1024 1 1 1 1 1 1 1 BAATMAG
+PALADIN_ILMATER 36875 39407 1 7 CLABPA01 SAVEWAR HPWAR 1 1 1 1 1 1 1 1 BAATFGT
+PALADIN_HELM 36872 39408 2 7 CLABPA01 SAVEWAR HPWAR 2 1 1 1 1 1 1 1 BAATFGT
+PALADIN_MYSTRA 36873 39409 4 7 CLABPA01 SAVEWAR HPWAR 4 1 1 1 1 1 1 1 BAATFGT
+MONK_OLD_ORDER 36877 39410 8 6 CLABMO01 SAVEMONK HPMONK 8 1 1 1 1 1 1 1 BAATMKU
+MONK_BROKEN_ONES 36878 39411 0x10 6 CLABMO01 SAVEMONK HPMONK 16 1 1 1 1 1 1 1 BAATMKU
+MONK_DARK_MOON 36879 39412 0x20 6 CLABMO01 SAVEMONK HPMONK 32 1 1 1 1 1 1 1 BAATMKU
+MAGE_GENERALIST 9987 9563 0x4000 11 CLABMA01 SAVEWIZ HPWIZ 0x4000 1 1 1 1 1 1 1 BAATMAG
+MAGE_ABJURER 502 9564 0x40 11 CLABMA02 SAVEWIZ HPWIZ 0x40 1 1 1 1 1 1 1 BAATMAG
+MAGE_CONJURER 504 9565 0x80 11 CLABMA06 SAVEWIZ HPWIZ 0x80 1 1 1 1 1 1 1 BAATMAG
+MAGE_DIVINER 2012 9566 0x100 11 CLABMA05 SAVEWIZ HPWIZ 0x100 1 1 1 1 1 1 1 BAATMAG
+MAGE_ENCHANTER 2022 9567 0x200 11 CLABMA09 SAVEWIZ HPWIZ 0x200 1 1 1 1 1 1 1 BAATMAG
+MAGE_EVOKER 12786 9569 0x800 11 CLABMA07 SAVEWIZ HPWIZ 0x400 1 1 1 1 1 1 1 BAATMAG
+MAGE_ILLUSIONIST 12785 9568 0x400 11 CLABMA08 SAVEWIZ HPWIZ 0x800 1 1 1 1 1 1 1 BAATMAG
+MAGE_NECROMANCER 12787 9570 0x1000 11 CLABMA03 SAVEWIZ HPWIZ 0x1000 1 1 1 1 1 1 1 BAATMAG
+MAGE_TRANSMUTER 12788 9571 0x2000 11 CLABMA04 SAVEWIZ HPWIZ 0x2000 1 1 1 1 1 1 1 BAATMAG
+CLERIC_ILMATER 38097 38118 0x8000 3 CLABCL01 SAVEPRS HPPRS 0x8000 1 1 1 1 1 1 1 BAATNFG
+CLERIC_LATHANDER 38098 38119 0x10000 3 CLABCL02 SAVEPRS HPPRS 0x10000 1 1 1 1 1 1 1 BAATNFG
+CLERIC_SELUNE 38099 38120 0x20000 3 CLABCL03 SAVEPRS HPPRS 0x20000 1 1 1 1 1 1 1 BAATNFG
+CLERIC_HELM 38100 38121 0x40000 3 CLABCL04 SAVEPRS HPPRS 0x40000 1 1 1 1 1 1 1 BAATNFG
+CLERIC_OGHMA 38101 38122 0x80000 3 CLABCL05 SAVEPRS HPPRS 0x80000 1 1 1 1 1 1 1 BAATNFG
+CLERIC_TEMPUS 38102 38123 0x100000 3 CLABCL06 SAVEPRS HPPRS 0x100000 1 1 1 1 1 1 1 BAATNFG
+CLERIC_BANE 38103 38124 0x200000 3 CLABCL07 SAVEPRS HPPRS 0x200000 1 1 1 1 1 1 1 BAATNFG
+CLERIC_MASK 38106 38125 0x400000 3 CLABCL08 SAVEPRS HPPRS 0x400000 1 1 1 1 1 1 1 BAATNFG
+CLERIC_TALOS 38107 38126 0x800000 3 CLABCL09 SAVEPRS HPPRS 0x800000 1 1 1 1 1 1 1 BAATNFG
diff --git a/gemrb/override/iwd2/cldamah.pro b/gemrb/unhardcoded/iwd2/cldamah.pro
similarity index 100%
rename from gemrb/override/iwd2/cldamah.pro
rename to gemrb/unhardcoded/iwd2/cldamah.pro
diff --git a/gemrb/override/iwd2/cloud.pro b/gemrb/unhardcoded/iwd2/cloud.pro
similarity index 100%
rename from gemrb/override/iwd2/cloud.pro
rename to gemrb/unhardcoded/iwd2/cloud.pro
diff --git a/gemrb/override/iwd2/cloudb.pro b/gemrb/unhardcoded/iwd2/cloudb.pro
similarity index 100%
rename from gemrb/override/iwd2/cloudb.pro
rename to gemrb/unhardcoded/iwd2/cloudb.pro
diff --git a/gemrb/override/iwd2/cloudbh.pro b/gemrb/unhardcoded/iwd2/cloudbh.pro
similarity index 100%
rename from gemrb/override/iwd2/cloudbh.pro
rename to gemrb/unhardcoded/iwd2/cloudbh.pro
diff --git a/gemrb/override/iwd2/cloudkil.pro b/gemrb/unhardcoded/iwd2/cloudkil.pro
similarity index 100%
rename from gemrb/override/iwd2/cloudkil.pro
rename to gemrb/unhardcoded/iwd2/cloudkil.pro
diff --git a/gemrb/override/iwd2/cloudks.pro b/gemrb/unhardcoded/iwd2/cloudks.pro
similarity index 100%
rename from gemrb/override/iwd2/cloudks.pro
rename to gemrb/unhardcoded/iwd2/cloudks.pro
diff --git a/gemrb/override/iwd2/clowncol.2da b/gemrb/unhardcoded/iwd2/clowncol.2da
similarity index 100%
rename from gemrb/override/iwd2/clowncol.2da
rename to gemrb/unhardcoded/iwd2/clowncol.2da
diff --git a/gemrb/unhardcoded/iwd2/clskills.2da b/gemrb/unhardcoded/iwd2/clskills.2da
new file mode 100644
index 0000000..976ad59
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/clskills.2da
@@ -0,0 +1,15 @@
+2DA V1.0
+*
+ HATERACE CLERICSPELL MAGESPELL STARTXP BARDSKILL THIEFSKILL LAYHANDS TURNLEVEL BOOKTYPE CASTING
+UNUSED * * * * 0 * * * 0 0 *
+BARBARIAN * * * 0 * SKILLS * 0 0 *
+BARD * * MXSPLBRD 0 SKILLBRD SKILLS * 0 2 42
+CLERIC * MXSPLCLR * 0 * SKILLS * 1 1 39
+DRUID * MXSPLDRD * 0 * SKILLS * 0 5 39
+FIGHTER * * * 0 * SKILLS * 0 0 *
+MONK * * * 0 * SKILLS * 0 0 *
+PALADIN * MXSPLPAL * 0 * SKILLS LAYHANDS 5 1 39
+RANGER HATERACE MXSPLRGR * 0 * SKILLS * 0 1 39
+ROGUE * * * 0 * SKILLS * 0 0 *
+SORCERER * * MXSPLSOR 0 * SKILLS * 0 2 42
+WIZARD * * MXSPLWIZ 0 * SKILLS * 0 1 38
diff --git a/gemrb/override/iwd2/clwounh.pro b/gemrb/unhardcoded/iwd2/clwounh.pro
similarity index 100%
rename from gemrb/override/iwd2/clwounh.pro
rename to gemrb/unhardcoded/iwd2/clwounh.pro
diff --git a/gemrb/override/iwd2/cmdamah.pro b/gemrb/unhardcoded/iwd2/cmdamah.pro
similarity index 100%
rename from gemrb/override/iwd2/cmdamah.pro
rename to gemrb/unhardcoded/iwd2/cmdamah.pro
diff --git a/gemrb/override/iwd2/cmwounh.pro b/gemrb/unhardcoded/iwd2/cmwounh.pro
similarity index 100%
rename from gemrb/override/iwd2/cmwounh.pro
rename to gemrb/unhardcoded/iwd2/cmwounh.pro
diff --git a/gemrb/override/iwd2/cobones.pro b/gemrb/unhardcoded/iwd2/cobones.pro
similarity index 100%
rename from gemrb/override/iwd2/cobones.pro
rename to gemrb/unhardcoded/iwd2/cobones.pro
diff --git a/gemrb/override/iwd2/cobonh1.pro b/gemrb/unhardcoded/iwd2/cobonh1.pro
similarity index 100%
rename from gemrb/override/iwd2/cobonh1.pro
rename to gemrb/unhardcoded/iwd2/cobonh1.pro
diff --git a/gemrb/override/iwd2/cobonh2.pro b/gemrb/unhardcoded/iwd2/cobonh2.pro
similarity index 100%
rename from gemrb/override/iwd2/cobonh2.pro
rename to gemrb/unhardcoded/iwd2/cobonh2.pro
diff --git a/gemrb/override/iwd2/cocold.pro b/gemrb/unhardcoded/iwd2/cocold.pro
similarity index 100%
rename from gemrb/override/iwd2/cocold.pro
rename to gemrb/unhardcoded/iwd2/cocold.pro
diff --git a/gemrb/override/iwd2/cocoldh.pro b/gemrb/unhardcoded/iwd2/cocoldh.pro
similarity index 100%
rename from gemrb/override/iwd2/cocoldh.pro
rename to gemrb/unhardcoded/iwd2/cocoldh.pro
diff --git a/gemrb/override/iwd2/cofire.pro b/gemrb/unhardcoded/iwd2/cofire.pro
similarity index 100%
rename from gemrb/override/iwd2/cofire.pro
rename to gemrb/unhardcoded/iwd2/cofire.pro
diff --git a/gemrb/override/iwd2/coldh.pro b/gemrb/unhardcoded/iwd2/coldh.pro
similarity index 100%
rename from gemrb/override/iwd2/coldh.pro
rename to gemrb/unhardcoded/iwd2/coldh.pro
diff --git a/gemrb/unhardcoded/iwd2/coldh.vvc b/gemrb/unhardcoded/iwd2/coldh.vvc
new file mode 100644
index 0000000..7bf1f38
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/coldh.vvc differ
diff --git a/gemrb/override/iwd2/colrspry.pro b/gemrb/unhardcoded/iwd2/colrspry.pro
similarity index 100%
rename from gemrb/override/iwd2/colrspry.pro
rename to gemrb/unhardcoded/iwd2/colrspry.pro
diff --git a/gemrb/override/iwd2/confush.pro b/gemrb/unhardcoded/iwd2/confush.pro
similarity index 100%
rename from gemrb/override/iwd2/confush.pro
rename to gemrb/unhardcoded/iwd2/confush.pro
diff --git a/gemrb/override/iwd2/confusp.pro b/gemrb/unhardcoded/iwd2/confusp.pro
similarity index 100%
rename from gemrb/override/iwd2/confusp.pro
rename to gemrb/unhardcoded/iwd2/confusp.pro
diff --git a/gemrb/override/iwd2/confusw.pro b/gemrb/unhardcoded/iwd2/confusw.pro
similarity index 100%
rename from gemrb/override/iwd2/confusw.pro
rename to gemrb/unhardcoded/iwd2/confusw.pro
diff --git a/gemrb/override/iwd2/conjuh.pro b/gemrb/unhardcoded/iwd2/conjuh.pro
similarity index 100%
rename from gemrb/override/iwd2/conjuh.pro
rename to gemrb/unhardcoded/iwd2/conjuh.pro
diff --git a/gemrb/override/iwd2/conjut.pro b/gemrb/unhardcoded/iwd2/conjut.pro
similarity index 100%
rename from gemrb/override/iwd2/conjut.pro
rename to gemrb/unhardcoded/iwd2/conjut.pro
diff --git a/gemrb/override/iwd2/copest.pro b/gemrb/unhardcoded/iwd2/copest.pro
similarity index 100%
rename from gemrb/override/iwd2/copest.pro
rename to gemrb/unhardcoded/iwd2/copest.pro
diff --git a/gemrb/unhardcoded/iwd2/cripstr.spl b/gemrb/unhardcoded/iwd2/cripstr.spl
new file mode 100644
index 0000000..55552ea
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/cripstr.spl differ
diff --git a/gemrb/override/iwd2/cry150.pro b/gemrb/unhardcoded/iwd2/cry150.pro
similarity index 100%
rename from gemrb/override/iwd2/cry150.pro
rename to gemrb/unhardcoded/iwd2/cry150.pro
diff --git a/gemrb/override/iwd2/cry200.pro b/gemrb/unhardcoded/iwd2/cry200.pro
similarity index 100%
rename from gemrb/override/iwd2/cry200.pro
rename to gemrb/unhardcoded/iwd2/cry200.pro
diff --git a/gemrb/override/iwd2/cry225.pro b/gemrb/unhardcoded/iwd2/cry225.pro
similarity index 100%
rename from gemrb/override/iwd2/cry225.pro
rename to gemrb/unhardcoded/iwd2/cry225.pro
diff --git a/gemrb/override/iwd2/cry250.pro b/gemrb/unhardcoded/iwd2/cry250.pro
similarity index 100%
rename from gemrb/override/iwd2/cry250.pro
rename to gemrb/unhardcoded/iwd2/cry250.pro
diff --git a/gemrb/override/iwd2/cry500np.pro b/gemrb/unhardcoded/iwd2/cry500np.pro
similarity index 100%
rename from gemrb/override/iwd2/cry500np.pro
rename to gemrb/unhardcoded/iwd2/cry500np.pro
diff --git a/gemrb/override/iwd2/csdamah.pro b/gemrb/unhardcoded/iwd2/csdamah.pro
similarity index 100%
rename from gemrb/override/iwd2/csdamah.pro
rename to gemrb/unhardcoded/iwd2/csdamah.pro
diff --git a/gemrb/override/iwd2/cstrenh.pro b/gemrb/unhardcoded/iwd2/cstrenh.pro
similarity index 100%
rename from gemrb/override/iwd2/cstrenh.pro
rename to gemrb/unhardcoded/iwd2/cstrenh.pro
diff --git a/gemrb/override/iwd2/cswounh.pro b/gemrb/unhardcoded/iwd2/cswounh.pro
similarity index 100%
rename from gemrb/override/iwd2/cswounh.pro
rename to gemrb/unhardcoded/iwd2/cswounh.pro
diff --git a/gemrb/override/iwd2/curseh.pro b/gemrb/unhardcoded/iwd2/curseh.pro
similarity index 100%
rename from gemrb/override/iwd2/curseh.pro
rename to gemrb/unhardcoded/iwd2/curseh.pro
diff --git a/gemrb/override/iwd2/cwelem1.pro b/gemrb/unhardcoded/iwd2/cwelem1.pro
similarity index 100%
rename from gemrb/override/iwd2/cwelem1.pro
rename to gemrb/unhardcoded/iwd2/cwelem1.pro
diff --git a/gemrb/override/iwd2/cwelemh.pro b/gemrb/unhardcoded/iwd2/cwelemh.pro
similarity index 100%
rename from gemrb/override/iwd2/cwelemh.pro
rename to gemrb/unhardcoded/iwd2/cwelemh.pro
diff --git a/gemrb/override/iwd2/cwelemx.pro b/gemrb/unhardcoded/iwd2/cwelemx.pro
similarity index 100%
rename from gemrb/override/iwd2/cwelemx.pro
rename to gemrb/unhardcoded/iwd2/cwelemx.pro
diff --git a/gemrb/override/iwd2/dagger.pro b/gemrb/unhardcoded/iwd2/dagger.pro
similarity index 100%
rename from gemrb/override/iwd2/dagger.pro
rename to gemrb/unhardcoded/iwd2/dagger.pro
diff --git a/gemrb/override/iwd2/daggerex.pro b/gemrb/unhardcoded/iwd2/daggerex.pro
similarity index 100%
rename from gemrb/override/iwd2/daggerex.pro
rename to gemrb/unhardcoded/iwd2/daggerex.pro
diff --git a/gemrb/unhardcoded/iwd2/damage.2da b/gemrb/unhardcoded/iwd2/damage.2da
new file mode 100644
index 0000000..6f4eb73
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/damage.2da
@@ -0,0 +1,19 @@
+2DA V1.0
+*
+ MAIN SPARKS GRADIENT
+CRIT BLOODCR * 47
+SMALL BLOODS * 47
+MEDIUM BLOODM * 47
+LARGE BLOODL * 47
+FIRES fireh FIREL -1
+FIREM fireh FIREL -1
+FIREL fireh FIREL -1
+SPARKS ElectrH ElectrL -1
+SPARKM ElectrH ElectrL -1
+SPARKL ElectrH ElectrL -1
+ICES COLDH COLDL -1
+ICEM COLDH COLDL -1
+ICEL COLDH COLDL -1
+ACIDS ACIDH ACIDL -1
+ACIDM ACIDH ACIDL -1
+ACIDL ACIDH ACIDL -1
\ No newline at end of file
diff --git a/gemrb/override/iwd2/dart.pro b/gemrb/unhardcoded/iwd2/dart.pro
similarity index 100%
rename from gemrb/override/iwd2/dart.pro
rename to gemrb/unhardcoded/iwd2/dart.pro
diff --git a/gemrb/override/iwd2/dartex.pro b/gemrb/unhardcoded/iwd2/dartex.pro
similarity index 100%
rename from gemrb/override/iwd2/dartex.pro
rename to gemrb/unhardcoded/iwd2/dartex.pro
diff --git a/gemrb/override/iwd2/dattach.pro b/gemrb/unhardcoded/iwd2/dattach.pro
similarity index 100%
rename from gemrb/override/iwd2/dattach.pro
rename to gemrb/unhardcoded/iwd2/dattach.pro
diff --git a/gemrb/override/iwd2/dbreath.pro b/gemrb/unhardcoded/iwd2/dbreath.pro
similarity index 100%
rename from gemrb/override/iwd2/dbreath.pro
rename to gemrb/unhardcoded/iwd2/dbreath.pro
diff --git a/gemrb/override/iwd2/ddeath.pro b/gemrb/unhardcoded/iwd2/ddeath.pro
similarity index 100%
rename from gemrb/override/iwd2/ddeath.pro
rename to gemrb/unhardcoded/iwd2/ddeath.pro
diff --git a/gemrb/override/iwd2/ddeath2.pro b/gemrb/unhardcoded/iwd2/ddeath2.pro
similarity index 100%
rename from gemrb/override/iwd2/ddeath2.pro
rename to gemrb/unhardcoded/iwd2/ddeath2.pro
diff --git a/gemrb/override/iwd2/ddoorh.pro b/gemrb/unhardcoded/iwd2/ddoorh.pro
similarity index 100%
rename from gemrb/override/iwd2/ddoorh.pro
rename to gemrb/unhardcoded/iwd2/ddoorh.pro
diff --git a/gemrb/unhardcoded/iwd2/defsound.2da b/gemrb/unhardcoded/iwd2/defsound.2da
new file mode 100644
index 0000000..7d3725d
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/defsound.2da
@@ -0,0 +1,36 @@
+2DA V1.0
+*
+ RESREF
+OPEN AMB_D03A
+CLOSE AMB_D03B
+HOPEN AMB_D04A
+HCLOSE AMB_D04B
+BUTTON1 GAM_09
+BUTTON2 GAM_03
+BUTTON3 GAM_04
+OPENFAIL AMB_D20
+CLOSEFAIL *
+ITEM_GONE EFF_M02
+SECRET ACT_09
+PICKLOCK AMB_D21D
+PICKFAIL AMB_D21
+13 *
+14 *
+15 *
+16 *
+17 *
+18 *
+19 *
+LIGHTNING1 AMB_E13A
+LIGHTNING2 AMB_E13B
+LIGHTNING3 AMB_E13F
+RAIN AMB_E11
+SNOW AMB_E02B
+SOLD ACT_03D
+STOLEN GAM_36
+DRUNK GAM_07
+DONATE1 ACT_03
+DONATE2 ACT_03E
+IDENTIFY CAS_P04
+GOTXP *
+TOOLTIP G_PAPR1
diff --git a/gemrb/override/iwd2/destruh.pro b/gemrb/unhardcoded/iwd2/destruh.pro
similarity index 100%
rename from gemrb/override/iwd2/destruh.pro
rename to gemrb/unhardcoded/iwd2/destruh.pro
diff --git a/gemrb/unhardcoded/iwd2/detect.spl b/gemrb/unhardcoded/iwd2/detect.spl
new file mode 100644
index 0000000..be497bc
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/detect.spl differ
diff --git a/gemrb/override/iwd2/dfog.pro b/gemrb/unhardcoded/iwd2/dfog.pro
similarity index 100%
rename from gemrb/override/iwd2/dfog.pro
rename to gemrb/unhardcoded/iwd2/dfog.pro
diff --git a/gemrb/unhardcoded/iwd2/dirty.spl b/gemrb/unhardcoded/iwd2/dirty.spl
new file mode 100644
index 0000000..cad9393
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/dirty.spl differ
diff --git a/gemrb/override/iwd2/disint.pro b/gemrb/unhardcoded/iwd2/disint.pro
similarity index 100%
rename from gemrb/override/iwd2/disint.pro
rename to gemrb/unhardcoded/iwd2/disint.pro
diff --git a/gemrb/override/iwd2/disinth.pro b/gemrb/unhardcoded/iwd2/disinth.pro
similarity index 100%
rename from gemrb/override/iwd2/disinth.pro
rename to gemrb/unhardcoded/iwd2/disinth.pro
diff --git a/gemrb/override/iwd2/dispel.pro b/gemrb/unhardcoded/iwd2/dispel.pro
similarity index 100%
rename from gemrb/override/iwd2/dispel.pro
rename to gemrb/unhardcoded/iwd2/dispel.pro
diff --git a/gemrb/override/iwd2/divinh.pro b/gemrb/unhardcoded/iwd2/divinh.pro
similarity index 100%
rename from gemrb/override/iwd2/divinh.pro
rename to gemrb/unhardcoded/iwd2/divinh.pro
diff --git a/gemrb/override/iwd2/divint.pro b/gemrb/unhardcoded/iwd2/divint.pro
similarity index 100%
rename from gemrb/override/iwd2/divint.pro
rename to gemrb/unhardcoded/iwd2/divint.pro
diff --git a/gemrb/unhardcoded/iwd2/dsclass.2da b/gemrb/unhardcoded/iwd2/dsclass.2da
new file mode 100644
index 0000000..a794a55
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/dsclass.2da
@@ -0,0 +1,15 @@
+2DA V1.0
+0
+ CLASS BONUS
+BARBARIAN 1 10
+BARD 2 15
+CLERIC 3 10
+DRUID 4 10
+FIGHTER 5 10
+MONK 6 15
+PALADIN 7 10
+RANGER 8 10
+ROGUE 9 15
+SORCERER 10 5
+WIZARD 11 5
+
diff --git a/gemrb/override/iwd2/dspell.pro b/gemrb/unhardcoded/iwd2/dspell.pro
similarity index 100%
rename from gemrb/override/iwd2/dspell.pro
rename to gemrb/unhardcoded/iwd2/dspell.pro
diff --git a/gemrb/override/iwd2/dspellh.pro b/gemrb/unhardcoded/iwd2/dspellh.pro
similarity index 100%
rename from gemrb/override/iwd2/dspellh.pro
rename to gemrb/unhardcoded/iwd2/dspellh.pro
diff --git a/gemrb/unhardcoded/iwd2/dsrace.2da b/gemrb/unhardcoded/iwd2/dsrace.2da
new file mode 100644
index 0000000..5fb3c47
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/dsrace.2da
@@ -0,0 +1,7 @@
+2DA V1.0
+0
+ RACE BONUS
+ELF 2 20
+DWARF 4 10
+HALFLING 5 5
+
diff --git a/gemrb/unhardcoded/iwd2/dstable.2da b/gemrb/unhardcoded/iwd2/dstable.2da
new file mode 100644
index 0000000..9940319
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/dstable.2da
@@ -0,0 +1,6 @@
+2DA V1.0
+*
+FILE STAT CHECKCOL READCOL
+dsclass CLASS 0 1
+dsrace RACE 0 1
+
diff --git a/gemrb/unhardcoded/iwd2/effects.ids b/gemrb/unhardcoded/iwd2/effects.ids
new file mode 100644
index 0000000..3becf97
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/effects.ids
@@ -0,0 +1,368 @@
+IDS
+0x0 ACVsDamageTypeModifierIWD2
+0x1 AttacksPerRoundModifier
+0x2 Cure:Sleep
+0x3 State:Berserk
+0x4 Cure:Berserk
+0x5 State:Charmed
+0x6 CharismaModifier
+0x7 Color:SetPalette
+0x8 Color:SetRGB
+0x9 Color:PulseRGB
+0xa ConstitutionModifier
+0xb Cure:Poison
+0xc Damage
+0xd Death
+0xe Cure:Defrost
+0xf DexterityModifier
+0x10 State:Hasted
+0x11 CurrentHPModifier
+0x12 MaximumHPModifier
+0x13 IntelligenceModifier
+0x14 State:Invisible
+0x15 LoreModifier
+0x16 LuckModifier
+0x17 MoraleModifier
+0x18 State:Panic
+0x19 State:Poisoned
+0x1a RemoveCurse
+0x1b AcidResistanceModifier
+0x1c ColdResistanceModifier
+0x1d ElectricityResistanceModifier
+0x1e FireResistanceModifier
+0x1f MagicDamageResistanceModifier
+0x20 Cure:Death
+0x21 SaveVsDeathModifier
+0x22 SaveVsWandsModifier
+0x23 SaveVsPolyModifier
+0x24 SaveVsBreathModifier
+0x25 SaveVsSpellsModifier
+0x26 State:Silenced
+0x27 State:Helpless
+0x28 State:Slowed
+0x29 Sparkle
+0x2a WizardSpellSlotsModifier
+0x2b Cure:Petrification
+0x2c StrengthModifier
+0x2d State:Stun
+0x2e Cure:Stun
+0x2f Cure:Invisible
+0x30 Cure:Silence
+0x31 WisdomModifier
+0x32 Color:BriefRGB
+0x33 Color:DarkenRGB
+0x34 Color:GlowRGB
+0x35 AnimationIDModifier
+0x36 ToHitModifier
+0x37 KillCreatureType
+0x38 Alignment:Invert
+0x39 Alignment:Change
+0x3a DispelEffects
+0x3b StealthModifier
+0x3c MiscastMagicModifier
+0x3d AlchemyModifier
+0x3e PriestSpellSlotsModifier
+0x3f State:Infravision
+0x40 Cure:Infravision
+0x41 State:Blur
+0x42 TransparencyModifier
+0x43 SummonCreature
+0x44 UnsummonCreature
+0x45 State:NonDetection
+0x46 Cure:NonDetection
+0x47 SexModifier
+0x48 AIIdentifierModifier
+0x49 DamageBonusModifier2
+0x4a State:Blind
+0x4b Cure:Blind
+0x4c State:Feeblemind
+0x4d Cure:Feeblemind
+0x4e State:Diseased
+0x4f Cure:Disease
+0x50 State:Deafness
+0x51 Cure:Deafness
+0x52 SetAIScript
+0x53 Protection:Projectile
+0x54 MagicalFireResistanceModifier
+0x55 MagicalColdResistanceModifier
+0x56 SlashingResistanceModifier
+0x57 CrushingResistanceModifier
+0x58 PiercingResistanceModifier
+0x59 MissilesResistanceModifier
+0x5a OpenLocksModifier
+0x5b FindTrapsModifier
+0x5c PickPocketsModifier
+0x5d FatigueModifier
+0x5e IntoxicationModifier
+0x5f TrackingModifier
+0x60 LevelModifier
+0x61 StrengthBonusModifier
+0x62 State:Regenerating
+0x63 SpellDurationModifier
+0x64 Protection:Creature
+0x65 Protection:Opcode
+0x66 Protection:SpellLevel
+0x67 ChangeName
+0x68 ExperienceModifier
+0x69 GoldModifier
+0x6a MoraleBreakModifier
+0x6b PortraitChange
+0x6c ReputationModifier
+0x6d State:Hold3
+0x6e RetreatFrom
+0x6f Item:CreateMagic
+0x70 Item:Remove
+0x71 Item:Equip
+0x72 Dither
+0x73 DetectAlignment
+0x74 Cure:Invisible2
+0x75 Reveal:Area
+0x76 Reveal:Creatures
+0x77 MirrorImage
+0x78 Protection:Weapons
+0x79 VisualAnimationEffect
+0x7a Item:CreateInventory
+0x7b Item:RemoveInventory
+0x7c DimensionDoor
+0x7d Unlock
+0x7e MovementRateModifier
+0x7f MonsterSummoning
+0x80 State:Confused
+0x81 AidNonCumulative
+0x82 BlessNonCumulative
+0x83 ChantNonCumulative
+0x84 DrawUponHolyMight
+0x85 LuckCumulative
+0x86 State:Petrification
+0x87 Polymorph
+0x88 ForceVisible
+0x89 ChantBadNonCumulative
+0x8a AnimationStateChange
+0x8b DisplayString
+0x8c CastingGlow
+0x8d VisualSpellHit
+0x8e Icon:Display
+0x8f Item:CreateInSlot
+0x90 DisableButton
+0x91 DisableCasting
+0x92 Spell:Cast
+0x93 Spell:Learn
+0x94 Spell:CastPoint
+0x95 Identify
+0x96 FindTraps
+0x97 ReplaceCreature
+0x98 PlayMovie
+0x99 Overlay:Sanctuary
+0x9a Overlay:Entangle
+0x9b Overlay:MinorGlobe
+0x9c Overlay:ShieldGlobe
+0x9d Overlay:Web
+0x9e Overlay:Grease
+0x9f MirrorImageModifier
+0xa0 Cure:Sanctuary
+0xa1 Cure:Panic
+0xa2 Cure:Hold
+0xa3 FreeAction
+0xa4 Cure:Intoxication
+0xa5 PauseTarget
+0xa6 MagicResistanceModifier
+0xa7 MissileHitModifier
+0xa8 RemoveCreature
+0xa9 Icon:Disable
+0xaa DamageAnimation
+0xab Spell:Add
+0xac Spell:Remove
+0xad PoisonResistanceModifier
+0xae PlaySound
+0xaf State:Hold
+0xb0 MovementRateModifier2
+0xb1 ApplyEffect
+0xb2 ToHitVsCreature
+0xb3 DamageVsCreature
+0xb4 CantUseItem
+0xb5 CantUseItemType
+0xb6 ApplyEffectItem
+0xb7 ApplyEffectItemType
+0xb8 DontJumpModifier
+0xb9 State:Hold2
+0xba MoveToArea
+0xbb Variable:StoreLocalVariable
+0xbc AuraCleansingModifier
+0xbd CastingSpeedModifier
+0xbe AttackSpeedModifier
+0xbf CastingLevelModifier
+0xc0 FindFamiliar
+0xc1 InvisibleDetection
+0xc2 IgnoreDialogPause
+0xc3 FamiliarBond
+0xc4 FamiliarMarker
+0xc5 Bounce:Projectile
+0xc6 Bounce:Opcode
+0xc7 Bounce:SpellLevel
+0xc8 Bounce:SpellLevelDec
+0xc9 Protection:SpellLevelDec
+0xca Bounce:School
+0xcb Bounce:SecondaryType
+0xcc Protection:School
+0xcd Protection:SecondaryType
+0xce Protection:Spell2
+0xcf Bounce:Spell
+0xd0 MinimumHPModifier
+0xd1 PowerWordKill
+0xd2 PowerWordStun
+0xd3 State:Imprisonment
+0xd4 Cure:Imprisonment
+0xd5 Maze
+0xd6 CastFromList
+0xd7 PlayVisualEffect
+0xd8 LevelDrainModifier
+0xd9 PowerWordSleep
+0xda IronSkins
+0xdb ACVsCreatureType
+0xdc DispelSchool
+0xdd DispelSecondaryType
+0xde RandomTeleport
+0xdf Protection:SchoolDec
+0xe0 Cure:LevelDrain
+0xe1 Reveal:Magic
+0xe2 Protection:SecondaryTypeDec
+0xe3 Bounce:SchoolDec
+0xe4 Bounce:SecondaryTypeDec
+0xe5 DispelSchoolOne
+0xe6 DispelSecondaryTypeOne
+0xe7 TimeStop
+0xe8 Color:FadeRGB
+0xe9 IWDVisualSpellHit
+0xea ColdDamage
+0xeb CastingGlow2
+0xec ChillTouchPanic
+0xed CrushingDamage
+0xee SaveBonus
+0xef SlowPoison
+0xf0 IWDMonsterSummoning
+0xf1 VampiricTouch
+0xf2 Overlay
+0xf3 AnimateDead
+0xf4 Prayer2
+0xf5 Curse2
+0xf6 SummonMonster2
+0xf7 BurningBlood
+0xf8 SummonShadowMonster
+0xf9 Recitation
+0xfa RecitationBad
+0xfb State:HoldNoIcon2
+0xfc BlindingOrb
+0xfd ACVsDamageTypeModifier2
+0xfe RemoveEffects
+0xff SalamanderAura
+0x100 UmberHulkGaze
+0x101 ZombieLordAura
+0x102 Protection:Spell
+0x103 SummonCreature2
+0x104 AvatarRemoval
+0x105 Protection:Opcode2
+0x106 SummonPomab
+0x107 ControlUndead
+0x108 StaticCharge
+0x109 CloakOfFear
+0x10a MovementRateModifier3
+0x10b Cure:Confusion
+0x10c EyeOfTheMind
+0x10d EyeOfTheSword
+0x10e EyeOfTheMage
+0x10f EyeOfVenom
+0x110 EyeOfTheSpirit
+0x111 EyeOfFortitude
+0x112 EyeOfStone
+0x113 RemoveSevenEyes
+0x114 RemoveEffect
+0x115 SoulEater
+0x116 ShroudOfFlame
+0x117 AnimalRage
+0x118 TurnUndead
+0x119 VitriolicSphere
+0x11a SuppressHP
+0x11b FloatText
+0x11c MaceOfDisruption
+0x11d State:Sleep
+0x11e Reveal:Tracks
+0x11f Protection:Backstab
+0x120 State:Set
+0x121 Cutscene
+0x122 Protection:Spell3
+0x123 RodOfSmithing
+0x124 MagicalRest
+0x125 BeholderDispelMagic
+0x126 HarpyWail
+0x127 JackalWereGaze
+0x128 ModifyGlobalVariable
+0x129 HideInShadowsModifier
+0x12a UseMagicDeviceModifier
+0x12b AnimalEmpathyModifier
+0x12c BluffModifier
+0x12d ConcentrationModifier
+0x12e DiplomacyModifier
+0x12f IntimidateModifier
+0x130 SearchModifier
+0x131 SpellcraftModifier
+0x132 CriticalHitModifier
+0x133 TurnLevelModifier
+397 SpellResistance
+398 SpellFocus
+399 AlterAnimation
+400 Hopelessness
+401 ProtectionFromEvil
+402 AddEffectsList
+403 ArmorOfFaith
+404 Nausea
+405 Enfeeblement
+406 FireShield
+407 DeathWard
+408 HolyPower
+409 RighteousWrath
+410 SummonAlly
+411 SummonEnemy
+412 Control2
+413 VisualEffectIWD2
+414 ResilientSphere
+415 Barkskin
+416 BleedingWounds
+417 AreaEffect
+418 FreeAction2
+419 Unconsciousness
+420 Death2
+421 EntropyShield
+422 StormShell
+423 ProtectionFromElements
+424 State:HoldNoIcon3
+425 ControlUndead2
+426 Aegis
+427 ExecutionerEyes
+428 Death3
+429 EffectsOnStruck
+430 ProjectileUseEffectList
+431 EnergyDrain
+432 TortoiseShell
+433 Blink
+434 PersistentUseEffectList
+435 DayBlindness
+436 DamageReduction
+437 Disguise
+438 HeroicInspiration
+439 OffscreenAIModifier
+440 BarbarianRage
+441 MovementRateModifier4
+443 MissileDamageReduction
+444 TensersTransformation
+446 SmiteEvil
+447 Restoration
+448 AlicornLance
+449 CallLightning
+450 GlobeInvulnerability
+451 LowerResistance
+452 Bane
+453 PowerAttack
+454 Expertise
+455 ArterialStrike
+456 Hamstring
+457 RapidShot
diff --git a/gemrb/override/iwd2/electrh.pro b/gemrb/unhardcoded/iwd2/electrh.pro
similarity index 100%
rename from gemrb/override/iwd2/electrh.pro
rename to gemrb/unhardcoded/iwd2/electrh.pro
diff --git a/gemrb/unhardcoded/iwd2/electrh.vvc b/gemrb/unhardcoded/iwd2/electrh.vvc
new file mode 100644
index 0000000..7d731f2
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/electrh.vvc differ
diff --git a/gemrb/override/iwd2/emotion.pro b/gemrb/unhardcoded/iwd2/emotion.pro
similarity index 100%
rename from gemrb/override/iwd2/emotion.pro
rename to gemrb/unhardcoded/iwd2/emotion.pro
diff --git a/gemrb/override/iwd2/enchah.pro b/gemrb/unhardcoded/iwd2/enchah.pro
similarity index 100%
rename from gemrb/override/iwd2/enchah.pro
rename to gemrb/unhardcoded/iwd2/enchah.pro
diff --git a/gemrb/override/iwd2/enchan.pro b/gemrb/unhardcoded/iwd2/enchan.pro
similarity index 100%
rename from gemrb/override/iwd2/enchan.pro
rename to gemrb/unhardcoded/iwd2/enchan.pro
diff --git a/gemrb/override/iwd2/enchannp.pro b/gemrb/unhardcoded/iwd2/enchannp.pro
similarity index 100%
rename from gemrb/override/iwd2/enchannp.pro
rename to gemrb/unhardcoded/iwd2/enchannp.pro
diff --git a/gemrb/override/iwd2/enchat.pro b/gemrb/unhardcoded/iwd2/enchat.pro
similarity index 100%
rename from gemrb/override/iwd2/enchat.pro
rename to gemrb/unhardcoded/iwd2/enchat.pro
diff --git a/gemrb/override/iwd2/entangle.pro b/gemrb/unhardcoded/iwd2/entangle.pro
similarity index 100%
rename from gemrb/override/iwd2/entangle.pro
rename to gemrb/unhardcoded/iwd2/entangle.pro
diff --git a/gemrb/override/iwd2/entropy.2da b/gemrb/unhardcoded/iwd2/entropy.2da
similarity index 100%
rename from gemrb/override/iwd2/entropy.2da
rename to gemrb/unhardcoded/iwd2/entropy.2da
diff --git a/gemrb/override/iwd2/equake.pro b/gemrb/unhardcoded/iwd2/equake.pro
similarity index 100%
rename from gemrb/override/iwd2/equake.pro
rename to gemrb/unhardcoded/iwd2/equake.pro
diff --git a/gemrb/override/iwd2/exaltah.pro b/gemrb/unhardcoded/iwd2/exaltah.pro
similarity index 100%
rename from gemrb/override/iwd2/exaltah.pro
rename to gemrb/unhardcoded/iwd2/exaltah.pro
diff --git a/gemrb/override/iwd2/factioh.pro b/gemrb/unhardcoded/iwd2/factioh.pro
similarity index 100%
rename from gemrb/override/iwd2/factioh.pro
rename to gemrb/unhardcoded/iwd2/factioh.pro
diff --git a/gemrb/override/iwd2/fbreath.pro b/gemrb/unhardcoded/iwd2/fbreath.pro
similarity index 100%
rename from gemrb/override/iwd2/fbreath.pro
rename to gemrb/unhardcoded/iwd2/fbreath.pro
diff --git a/gemrb/unhardcoded/iwd2/feat00.spl b/gemrb/unhardcoded/iwd2/feat00.spl
new file mode 100644
index 0000000..e8ad852
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat00.spl differ
diff --git a/gemrb/unhardcoded/iwd2/feat02.spl b/gemrb/unhardcoded/iwd2/feat02.spl
new file mode 100644
index 0000000..45ecbc4
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat02.spl differ
diff --git a/gemrb/unhardcoded/iwd2/feat07.spl b/gemrb/unhardcoded/iwd2/feat07.spl
new file mode 100644
index 0000000..9554335
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat07.spl differ
diff --git a/gemrb/unhardcoded/iwd2/feat09.spl b/gemrb/unhardcoded/iwd2/feat09.spl
new file mode 100644
index 0000000..742bed2
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat09.spl differ
diff --git a/gemrb/unhardcoded/iwd2/feat0a.spl b/gemrb/unhardcoded/iwd2/feat0a.spl
new file mode 100644
index 0000000..d4e15cc
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat0a.spl differ
diff --git a/gemrb/unhardcoded/iwd2/feat0c.spl b/gemrb/unhardcoded/iwd2/feat0c.spl
new file mode 100644
index 0000000..4291368
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat0c.spl differ
diff --git a/gemrb/unhardcoded/iwd2/feat0d.spl b/gemrb/unhardcoded/iwd2/feat0d.spl
new file mode 100644
index 0000000..509ef39
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat0d.spl differ
diff --git a/gemrb/unhardcoded/iwd2/feat0f.spl b/gemrb/unhardcoded/iwd2/feat0f.spl
new file mode 100644
index 0000000..4bd411d
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat0f.spl differ
diff --git a/gemrb/unhardcoded/iwd2/feat10.spl b/gemrb/unhardcoded/iwd2/feat10.spl
new file mode 100644
index 0000000..93f3063
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat10.spl differ
diff --git a/gemrb/unhardcoded/iwd2/feat18.spl b/gemrb/unhardcoded/iwd2/feat18.spl
new file mode 100644
index 0000000..dcbef06
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat18.spl differ
diff --git a/gemrb/unhardcoded/iwd2/feat19.spl b/gemrb/unhardcoded/iwd2/feat19.spl
new file mode 100644
index 0000000..32eaa88
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat19.spl differ
diff --git a/gemrb/unhardcoded/iwd2/feat1a.spl b/gemrb/unhardcoded/iwd2/feat1a.spl
new file mode 100644
index 0000000..98de95c
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat1a.spl differ
diff --git a/gemrb/unhardcoded/iwd2/feat1c.spl b/gemrb/unhardcoded/iwd2/feat1c.spl
new file mode 100644
index 0000000..2db1a0b
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat1c.spl differ
diff --git a/gemrb/unhardcoded/iwd2/feat1c1.eff b/gemrb/unhardcoded/iwd2/feat1c1.eff
new file mode 100644
index 0000000..f441a2c
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat1c1.eff differ
diff --git a/gemrb/unhardcoded/iwd2/feat1c2.eff b/gemrb/unhardcoded/iwd2/feat1c2.eff
new file mode 100644
index 0000000..ed550f9
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat1c2.eff differ
diff --git a/gemrb/unhardcoded/iwd2/feat1d.spl b/gemrb/unhardcoded/iwd2/feat1d.spl
new file mode 100644
index 0000000..e0cf172
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat1d.spl differ
diff --git a/gemrb/unhardcoded/iwd2/feat1e.spl b/gemrb/unhardcoded/iwd2/feat1e.spl
new file mode 100644
index 0000000..28398a8
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat1e.spl differ
diff --git a/gemrb/unhardcoded/iwd2/feat20.spl b/gemrb/unhardcoded/iwd2/feat20.spl
new file mode 100644
index 0000000..18d8bca
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat20.spl differ
diff --git a/gemrb/unhardcoded/iwd2/feat22.spl b/gemrb/unhardcoded/iwd2/feat22.spl
new file mode 100644
index 0000000..707dcf7
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat22.spl differ
diff --git a/gemrb/unhardcoded/iwd2/feat23.spl b/gemrb/unhardcoded/iwd2/feat23.spl
new file mode 100644
index 0000000..3320d5f
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat23.spl differ
diff --git a/gemrb/unhardcoded/iwd2/feat25.spl b/gemrb/unhardcoded/iwd2/feat25.spl
new file mode 100644
index 0000000..5baa480
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat25.spl differ
diff --git a/gemrb/unhardcoded/iwd2/feat32.spl b/gemrb/unhardcoded/iwd2/feat32.spl
new file mode 100644
index 0000000..52232e2
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat32.spl differ
diff --git a/gemrb/unhardcoded/iwd2/feat33.spl b/gemrb/unhardcoded/iwd2/feat33.spl
new file mode 100644
index 0000000..977ae29
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat33.spl differ
diff --git a/gemrb/unhardcoded/iwd2/feat3b.spl b/gemrb/unhardcoded/iwd2/feat3b.spl
new file mode 100644
index 0000000..6b8dfd1
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat3b.spl differ
diff --git a/gemrb/unhardcoded/iwd2/feat41.spl b/gemrb/unhardcoded/iwd2/feat41.spl
new file mode 100644
index 0000000..b4680b2
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/feat41.spl differ
diff --git a/gemrb/unhardcoded/iwd2/featreq.2da b/gemrb/unhardcoded/iwd2/featreq.2da
new file mode 100644
index 0000000..551417a
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/featreq.2da
@@ -0,0 +1,79 @@
+2DA V1.0
+4
+ MULTIPLE MAX_LEVEL A_STAT A_VALUE B_STAT B_VALUE C_STAT C_VALUE D_STAT D_VALUE A_OP B_OP C_OP D_OP
+AEGIS_OF_RIME 0 1 SPELLCRAFT 10 0 0 CLASSLEVELMAGE 7 CLASSLEVELSORCERER 7 * * * *
+AMBIDEXTERITY 0 1 DEX 15 0 0 0 0 0 0 * * * *
+AQUA_MORTIS 0 1 SPELLCRAFT 10 0 0 CLASSLEVELMAGE 7 CLASSLEVELSORCERER 7 * * * *
+ARMOR_PROF FEAT_ARMOUR 3 0 0 0 0 0 0 0 0 * * * *
+ARMORED_ARCANA FEAT_ARMORED_ARCANA 3 CLASSLEVELMAGE 1 CLASSLEVELSORCERER 1 0 0 0 0 * * * *
+ARTERIAL_STRIKE 0 1 CLASSLEVELTHIEF 1 0 0 HITBONUS 4 0 0 * * * *
+BLIND_FIGHT 0 1 0 0 0 0 0 0 0 0 * * * *
+BULLHEADED 0 1 RACE 1 RACE 4 0 0 0 0 1 1 * *
+CLEAVE FEAT_CLEAVE 2 HITBONUS 4 FEAT_CLEAVE 1 FEATS2 32 0 0 * 0 8 *
+COMBAT_CASTING 0 1 0 0 0 0 0 0 0 0 * * * *
+COURTEOUS_MAGOCRACY 0 1 0 0 0 0 0 0 0 0 * * * *
+CRIPPLING_STRIKE 0 1 CLASSLEVELTHIEF 10 0 0 0 0 0 0 * * * *
+DASH 0 1 0 0 0 0 0 0 0 0 * * * *
+DEFLECT_ARROWS 0 1 DEX 13 0 0 0 0 0 0 * * * *
+DIRTY_FIGHTING 0 1 DEX 13 0 0 HITBONUS 2 0 0 * * * *
+DISCIPLINE 0 1 0 0 0 0 0 0 0 0 * * * *
+DODGE 0 1 DEX 13 0 0 0 0 0 0 * * * *
+ENVENOM_WEAPON 0 1 CLASSLEVELTHIEF 1 0 0 ALCHEMY 8 0 0 * * * *
+EXOTIC_BASTARD FEAT_BASTARDSWORD 3 0 0 0 0 0 0 0 0 * * * *
+EXPERTISE 0 1 INT 13 0 0 0 0 0 0 * * * *
+EXTRA_RAGE FEAT_EXTRA_RAGE 3 CLASSLEVELBARBARIAN 1 0 0 0 0 0 0 * * * *
+EXTRA_SHAPESHIFTING FEAT_EXTRA_SHAPE 3 CLASSLEVELDRUID 3 0 0 0 0 0 0 * * * *
+EXTRA_SMITING FEAT_EXTRA_SMITING 3 CLASSLEVELPALADIN 2 0 0 0 0 0 0 * * * *
+EXTRA_TURNING FEAT_EXTRA_TURNING 3 TURNUNDEADLEVEL 1 0 0 0 0 0 0 * * * *
+FIENDSLAYER 0 1 CLASSLEVELPALADIN 8 0 0 FEAT_LARGE_SWORD 2 FEAT_GREAT_SWORD 2 * * * *
+FORESTER 0 1 0 0 0 0 0 0 0 0 * * * *
+GREAT_FORTITUDE 0 1 0 0 0 0 0 0 0 0 * * * *
+HAMSTRING 0 1 CLASSLEVELTHIEF 3 0 0 0 0 0 0 * * * *
+HERETICS_BANE 0 1 CLASSLEVELCLERIC 1 CLASSLEVELPALADIN 3 HITBONUS 4 0 0 * * * *
+HEROIC_INSPIRATION 0 1 AnyOfThreeGE -1 CLASSLEVELPALADIN 1 CLASSLEVELBARBARIAN 1 CLASSLEVELBARD 1 * * * *
+IMPROVED_CRITICAL 0 1 HITBONUS 8 0 0 0 0 0 0 * * * *
+IMPROVED_EVASION 0 1 CLASSLEVELTHIEF 10 0 0 0 0 0 0 * * * *
+IMPROVED_INITIATIVE 0 1 0 0 0 0 0 0 0 0 * * * *
+IMPROVED_TURNING 0 1 TURNUNDEADLEVEL 1 0 0 0 0 0 0 * * * *
+IRON_WILL 0 1 0 0 0 0 0 0 0 0 * * * *
+LIGHTNING_REFLEXES 0 1 0 0 0 0 0 0 0 0 * * * *
+LINGERING_SONG 0 1 CLASSLEVELBARD 1 0 0 0 0 0 0 * * * *
+LUCK_OF_HEROES 0 1 RACE 1 0 0 0 0 0 0 1 * * *
+MARTIAL_AXE FEAT_AXE 3 CLASSLEVELFIGHTER 4 FEAT_AXE 2 0 0 0 0 * 0 * *
+MARTIAL_BOW FEAT_BOW 3 CLASSLEVELFIGHTER 4 FEAT_BOW 2 0 0 0 0 * 0 * *
+MARTIAL_FLAIL FEAT_FLAIL 3 CLASSLEVELFIGHTER 4 FEAT_FLAIL 2 0 0 0 0 * 0 * *
+MARTIAL_GREATSWORD FEAT_GREAT_SWORD 3 CLASSLEVELFIGHTER 4 FEAT_GREAT_SWORD 2 0 0 0 0 * 0 * *
+MARTIAL_HAMMER FEAT_HAMMER 3 CLASSLEVELFIGHTER 4 FEAT_HAMMER 2 0 0 0 0 * 0 * *
+MARTIAL_LARGESWORD FEAT_LARGE_SWORD 3 CLASSLEVELFIGHTER 4 FEAT_LARGE_SWORD 2 0 0 0 0 * 0 * *
+MARTIAL_POLEARM FEAT_POLEARM 3 CLASSLEVELFIGHTER 4 FEAT_POLEARM 2 0 0 0 0 * 0 * *
+MAXIMIZED_ATTACKS 0 1 MaximizedAttacks -1 CONCENTRATION 4 0 0 0 0 * * * *
+MERCANTILE_BACKGROUND 0 1 AnyOfThree -1 SUBRACE 0x40002 SUBRACE 0x60002 RACE 1 * * * *
+POWER_ATTACK 0 1 STR 13 0 0 0 0 0 0 * * * *
+PRECISE_SHOT 0 1 0 0 0 0 0 0 0 0 * * * *
+RAPID_SHOT 0 1 DEX 13 0 0 0 0 0 0 * * * *
+RESIST_POISON 0 1 CLASSLEVELSUM 1 0 0 SUBRACE 0x40002 RACE 7 1 * 1 1
+SCION_OF_STORMS 0 1 SPELLCRAFT 10 0 0 CLASSLEVELMAGE 7 CLASSLEVELSORCERER 7 * * * *
+SHIELD_PROF 0 1 0 0 0 0 0 0 0 0 * * * *
+SIMPLE_CROSSBOW FEAT_CROSSBOW 3 CLASSLEVELFIGHTER 4 FEAT_CROSSBOW 2 0 0 0 0 * 0 * *
+SIMPLE_MACE FEAT_MACE 3 CLASSLEVELFIGHTER 4 FEAT_MACE 2 0 0 0 0 * 0 * *
+SIMPLE_MISSILE FEAT_SLING 3 CLASSLEVELFIGHTER 4 FEAT_SLING 2 0 0 0 0 * 0 * *
+SIMPLE_QUARTERSTAFF FEAT_STAFF 3 CLASSLEVELFIGHTER 4 FEAT_STAFF 2 0 0 0 0 * 0 * *
+SIMPLE_SMALLBLADE FEAT_SMALL_SWORD 3 CLASSLEVELFIGHTER 4 FEAT_SMALL_SWORD 2 0 0 0 0 * 0 * *
+SLIPPERY_MIND 0 1 CLASSLEVELTHIEF 10 0 0 0 0 0 0 * * * *
+SNAKE_BLOOD 0 1 RACE 1 0 0 CLASSLEVELSUM 1 0 0 1 * 1 *
+SPELL_FOCUS_ENCHANTMENT FEAT_ENCHANTMENT 2 0 0 0 0 0 0 0 0 * * * *
+SPELL_FOCUS_EVOCATION FEAT_EVOCATION 2 0 0 0 0 0 0 0 0 * * * *
+SPELL_FOCUS_NECROMANCY FEAT_NECROMANCY 2 0 0 0 0 0 0 0 0 * * * *
+SPELL_FOCUS_TRANSMUTE FEAT_TRANSMUTE 2 0 0 0 0 0 0 0 0 * * * *
+SPELL_PENETRATION FEAT_SPELL_PENETRATION 2 0 0 0 0 0 0 0 0 * * * *
+SPIRIT_OF_FLAME 0 1 SPELLCRAFT 10 0 0 CLASSLEVELMAGE 7 CLASSLEVELSORCERER 7 * * * *
+STRONG_BACK 0 1 0 0 0 0 0 0 0 0 * * * *
+STUNNING_FIST 0 1 AllOfThreeGE -1 DEX 13 WIS 13 HITBONUS 8 * * * *
+SUBVOCAL_CASTING 0 1 IsCaster -1 0 0 0 0 0 0 * * * *
+TOUGHNESS FEAT_TOUGHNESS 5 0 0 0 0 0 0 0 0 * * * *
+TWO_WEAPON_FIGHTING 0 1 0 0 0 0 0 0 0 0 * * * *
+WEAPON_FINESSE 0 1 FEAT_SMALL_SWORD 1 0 0 HITBONUS 1 0 0 * * * *
+WILDSHAPE_BOAR 0 1 CLASSLEVELDRUID 5 0 0 0 0 0 0 * * * *
+WILDSHAPE_PANTHER 0 1 CLASSLEVELDRUID 5 0 0 0 0 0 0 * * * *
+WILDSHAPE_SHAMBLER 0 1 CLASSLEVELDRUID 8 0 0 0 0 0 0 * * * *
+
diff --git a/gemrb/override/iwd2/ffinger.pro b/gemrb/unhardcoded/iwd2/ffinger.pro
similarity index 100%
rename from gemrb/override/iwd2/ffinger.pro
rename to gemrb/unhardcoded/iwd2/ffinger.pro
diff --git a/gemrb/override/iwd2/findtrap.pro b/gemrb/unhardcoded/iwd2/findtrap.pro
similarity index 100%
rename from gemrb/override/iwd2/findtrap.pro
rename to gemrb/unhardcoded/iwd2/findtrap.pro
diff --git a/gemrb/unhardcoded/iwd2/fireball.pro b/gemrb/unhardcoded/iwd2/fireball.pro
new file mode 100644
index 0000000..a68b4ab
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/fireball.pro differ
diff --git a/gemrb/override/iwd2/fireblic.pro b/gemrb/unhardcoded/iwd2/fireblic.pro
similarity index 100%
rename from gemrb/override/iwd2/fireblic.pro
rename to gemrb/unhardcoded/iwd2/fireblic.pro
diff --git a/gemrb/override/iwd2/firebolt.pro b/gemrb/unhardcoded/iwd2/firebolt.pro
similarity index 100%
rename from gemrb/override/iwd2/firebolt.pro
rename to gemrb/unhardcoded/iwd2/firebolt.pro
diff --git a/gemrb/override/iwd2/firebtbl.pro b/gemrb/unhardcoded/iwd2/firebtbl.pro
similarity index 100%
rename from gemrb/override/iwd2/firebtbl.pro
rename to gemrb/unhardcoded/iwd2/firebtbl.pro
diff --git a/gemrb/override/iwd2/fireh.pro b/gemrb/unhardcoded/iwd2/fireh.pro
similarity index 100%
rename from gemrb/override/iwd2/fireh.pro
rename to gemrb/unhardcoded/iwd2/fireh.pro
diff --git a/gemrb/unhardcoded/iwd2/fireh.vvc b/gemrb/unhardcoded/iwd2/fireh.vvc
new file mode 100644
index 0000000..273f592
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/fireh.vvc differ
diff --git a/gemrb/override/iwd2/firestor.pro b/gemrb/unhardcoded/iwd2/firestor.pro
similarity index 100%
rename from gemrb/override/iwd2/firestor.pro
rename to gemrb/unhardcoded/iwd2/firestor.pro
diff --git a/gemrb/unhardcoded/iwd2/fistweap.2da b/gemrb/unhardcoded/iwd2/fistweap.2da
new file mode 100644
index 0000000..3b593d1
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/fistweap.2da
@@ -0,0 +1,4 @@
+2DA V1.0
+00FIST
+ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
+6 00MFIST1 00MFIST1 00MFIST2 00MFIST2 00MFIST2 00MFIST3 00MFIST3 00MFIST3 00MFIST4 00MFIST4 00MFIST4 00MFIST5 00MFIST5 00MFIST5 00MFIST6 00MFIST6 00MFIST6 00MFIST7 00MFIST7 00MFIST7 00MFIST7 00MFIST7 00MFIST7 00MFIST7 00MFIST8 00MFIST8 00MFIST8 00MFIST8 00MFIST8 00MFIST8 00MFIST9
diff --git a/gemrb/override/iwd2/fodeath.pro b/gemrb/unhardcoded/iwd2/fodeath.pro
similarity index 100%
rename from gemrb/override/iwd2/fodeath.pro
rename to gemrb/unhardcoded/iwd2/fodeath.pro
diff --git a/gemrb/unhardcoded/iwd2/fonts.2da b/gemrb/unhardcoded/iwd2/fonts.2da
new file mode 100644
index 0000000..df11966
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/fonts.2da
@@ -0,0 +1,22 @@
+2DA V1.0
+NORMAL
+ RESREF NEED_PALETTE FONT_NAME PT_SIZE STYLE COLOR
+0 NORMAL 1 NORMAL 14 0 0xffffffff
+1 INFOFONT 1 INFOFONT 14 0 0xffffffff
+2 NUMBER 0 NUMBER 14 0 0xffffffff
+3 INITIALS 0 INITIALS 14 0 0xffffffff
+4 NUMBER2 0 NUMBER2 14 0 0xffffffff
+5 NUMBER3 0 NUMBER3 14 0 0xffffffff
+6 NUMFONT 1 NUMFONT 14 0 0xffffffff
+7 REALMS 0 REALMS 14 0 0xffffffff
+8 REALMS2 1 REALMS2 14 0 0xffffffff
+9 STONEBIG 0 STONEBIG 14 0 0xffffffff
+10 STONESM2 0 STONESM2 14 0 0xffffffff
+11 STONESM3 0 STONESM3 14 0 0xffffffff
+12 STONESML 0 STONESML 14 0 0xffffffff
+13 TOOLFONT 1 TOOLFONT 14 0 0xffffffff
+# state "fonts" are the status icons. You probably don't want to edit these.
+14 STATES 0 STATES 14 0 0xffffffff
+15 STATES2 0 STATES2 14 0 0xffffffff
+
+# Customization How To: http://gemrb.sourceforge.net/wiki/doku.php?id=plugins:ttf
diff --git a/gemrb/override/iwd2/formatio.2da b/gemrb/unhardcoded/iwd2/formatio.2da
similarity index 100%
rename from gemrb/override/iwd2/formatio.2da
rename to gemrb/unhardcoded/iwd2/formatio.2da
diff --git a/gemrb/override/iwd2/fseed.pro b/gemrb/unhardcoded/iwd2/fseed.pro
similarity index 100%
rename from gemrb/override/iwd2/fseed.pro
rename to gemrb/unhardcoded/iwd2/fseed.pro
diff --git a/gemrb/override/iwd2/fstrikh.pro b/gemrb/unhardcoded/iwd2/fstrikh.pro
similarity index 100%
rename from gemrb/override/iwd2/fstrikh.pro
rename to gemrb/unhardcoded/iwd2/fstrikh.pro
diff --git a/gemrb/override/iwd2/gabreath.pro b/gemrb/unhardcoded/iwd2/gabreath.pro
similarity index 100%
rename from gemrb/override/iwd2/gabreath.pro
rename to gemrb/unhardcoded/iwd2/gabreath.pro
diff --git a/gemrb/unhardcoded/iwd2/gametime.2da b/gemrb/unhardcoded/iwd2/gametime.2da
new file mode 100644
index 0000000..ba22bbe
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/gametime.2da
@@ -0,0 +1,6 @@
+2DA V1.0
+0
+ DURATION
+ROUND_SECONDS 7
+TURN_SECONDS 70
+ATTACK_ROUND 100
diff --git a/gemrb/override/iwd2/garmorh.pro b/gemrb/unhardcoded/iwd2/garmorh.pro
similarity index 100%
rename from gemrb/override/iwd2/garmorh.pro
rename to gemrb/unhardcoded/iwd2/garmorh.pro
diff --git a/gemrb/override/iwd2/gate.pro b/gemrb/unhardcoded/iwd2/gate.pro
similarity index 100%
rename from gemrb/override/iwd2/gate.pro
rename to gemrb/unhardcoded/iwd2/gate.pro
diff --git a/gemrb/override/iwd2/gaze.pro b/gemrb/unhardcoded/iwd2/gaze.pro
similarity index 100%
rename from gemrb/override/iwd2/gaze.pro
rename to gemrb/unhardcoded/iwd2/gaze.pro
diff --git a/gemrb/override/iwd2/geloopx.pro b/gemrb/unhardcoded/iwd2/geloopx.pro
similarity index 100%
rename from gemrb/override/iwd2/geloopx.pro
rename to gemrb/unhardcoded/iwd2/geloopx.pro
diff --git a/gemrb/override/iwd2/gemprjtl.ids b/gemrb/unhardcoded/iwd2/gemprjtl.ids
similarity index 100%
rename from gemrb/override/iwd2/gemprjtl.ids
rename to gemrb/unhardcoded/iwd2/gemprjtl.ids
diff --git a/gemrb/unhardcoded/iwd2/gemrb.ini b/gemrb/unhardcoded/iwd2/gemrb.ini
new file mode 100644
index 0000000..be58c43
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/gemrb.ini
@@ -0,0 +1,131 @@
+; GemRB - Infinity Engine Emulator
+; Copyright (C) 2003 The GemRB Project
+;
+; This program is free software; you can redistribute it and/or
+; modify it under the terms of the GNU General Public License
+; as published by the Free Software Foundation; either version 2
+; of the License, or (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program; if not, write to the Free Software
+; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+;
+
+
+; gemrb.ini - game type-specific settings for GemRB engine
+
+[resources]
+
+; Bitmap resource for cursors
+CursorBAM = CAROT
+
+; Bitmap resource for scroll cursor arrow
+ScrollCursorBAM = CURSARW
+
+; Bitmap resource for dialog buttons font
+ButtonFont = NORMAL
+
+; Font used to display tooltips
+TooltipFont = TOOLFONT
+
+; Sprite displayed behind the tooltip text, if any
+TooltipBack = TOOLTIP
+
+; Tooltip text color (RGBA)
+TooltipColor = #ffffffff
+
+; Space between tooltip text and sides of TooltipBack (x2)
+TooltipMargin = 2
+#TooltipMargin = 20
+
+; INI file from the original games
+INIConfig = icewind2.ini
+
+; Palette bitmaps in various widths
+Palette16 = MPALETTE
+Palette32 = MPALETTE
+Palette256 = MPAL256
+
+3EdRules = 1
+AllStringsTagged = 1
+AreaVisitedVar = 1
+AreaOverride = 0
+AutomapINI = 0
+AutoSearchHidden = 1
+BiographyIsRes = 1
+BreakableWeapons = 0
+CastingSounds = 1
+ChallengeRating = 1
+CharNameIsGabber = 1
+CheckAbilities = 0
+ClearUnusedArea = 0
+CutsceneAreascripts = 1
+DeathOnZeroStat = 0
+DialogueScrolls = 0
+EnhancedCastingSounds = 0
+EnhancedEffects = 1
+FistStat = 232
+FlexibleWorldmap = 1
+ForceAreaScript = 1
+ForceStereo = 0
+HasBeastsINI = 0
+HasDescIcon = 0
+HasDPLAYER = 1
+HasEXPTABLE = 1
+HasFloatMenu = 0
+HasHideInShadows = 1
+HasKaputz = 0
+HasNoNPCFlag = 0
+HasPartyINI = 1
+HasPickSound = 0
+HasResDataIni = 0
+HasSongList = 0
+HasSoundsIni = 1
+HasSpecificDamageBonus = 1
+HasSpellList = 1
+HasUsePointFlag = 1
+HasWisdomBonusTable = 0
+HealOn100Plus = 0
+IgnoreButtonFrames = 0
+ImplicitAreaAnimBackground = 1
+InPartyAllowsDead = 1
+IWD2DeathVarFormat = 1
+IWD2ScriptName = 1
+IWDMapDimensions = 1
+JournalHasSections = 0
+KnowWorld = 1
+LevelslotPerClass = 1
+LowerLabelText = 0
+MagicBit = 1
+MaximumAbility = 40
+NoDropCanMove = 0
+NoNewVariables = 0
+OneByteAnimationID = 0
+OnScreenText = 0
+NoUndroppable = 1
+OverrideCursorPos = 1
+ProperBackstab = 1
+ProtagonistTalks = 0
+PSTStateFlags = 0
+RareActionSounds = 0
+RedrawTile = 0
+ReverseDoor = 0
+ReverseToHit = 0
+SaveForHalfDamage = 0
+SelectiveMagicRes = 1
+SkipUpdateHack = 1
+SmallFog = 0
+SoundFolders = 1
+SpawnIni = 1
+SpellBookIconHack = 0
+StartActive = 0
+StealIsAttack = 0
+StrrefSaveGame = 1
+TeamMovement = 0
+UpperButtonText = 0
+ZeroTimerIsValid = 1
diff --git a/gemrb/override/iwd2/gender.2da b/gemrb/unhardcoded/iwd2/gender.2da
similarity index 100%
rename from gemrb/override/iwd2/gender.2da
rename to gemrb/unhardcoded/iwd2/gender.2da
diff --git a/gemrb/override/iwd2/golcloud.pro b/gemrb/unhardcoded/iwd2/golcloud.pro
similarity index 100%
rename from gemrb/override/iwd2/golcloud.pro
rename to gemrb/unhardcoded/iwd2/golcloud.pro
diff --git a/gemrb/override/iwd2/grease.pro b/gemrb/unhardcoded/iwd2/grease.pro
similarity index 100%
rename from gemrb/override/iwd2/grease.pro
rename to gemrb/unhardcoded/iwd2/grease.pro
diff --git a/gemrb/override/iwd2/gshout.pro b/gemrb/unhardcoded/iwd2/gshout.pro
similarity index 100%
rename from gemrb/override/iwd2/gshout.pro
rename to gemrb/unhardcoded/iwd2/gshout.pro
diff --git a/gemrb/unhardcoded/iwd2/guibtact.2da b/gemrb/unhardcoded/iwd2/guibtact.2da
new file mode 100644
index 0000000..2902247
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/guibtact.2da
@@ -0,0 +1,93 @@
+2DA V1.0
+guibtact
+ 1 2 3 4 TOOLTIP RESREF
+Stealth 28 29 30 31 4968 guibtact
+Thieving 24 25 26 27 4971 guibtact
+Cast 8 9 10 11 4688 guibtact
+QSpell1 0 1 2 0 4938 guibtbut
+QSpell2 0 1 2 0 4938 guibtbut
+QSpell3 0 1 2 0 4938 guibtbut
+Turn 4 5 6 7 0 guibtact
+Defend 0 1 2 3 15925 guibtact
+UseItem 16 17 18 19 4978 guibtact
+QItem1 0 1 2 0 4937 guibtbut
+QItem4 0 1 2 0 4937 guibtbut
+QItem2 0 1 2 0 4937 guibtbut
+QItem3 0 1 2 0 4937 guibtbut
+Innate 40 41 42 43 4954 guibtact
+Defend 0 1 2 3 15925 guibtact
+Attack 12 13 14 15 4666 guibtact
+QWeapon1 0 1 24 25 4950 guibtbut
+QWeapon2 2 3 26 27 4950 guibtbut
+QWeapon3 4 5 28 29 4950 guibtbut
+QWeapon4 6 7 30 31 4950 guibtbut
+BardSong 20 21 22 23 4918 guibtact
+Stop 44 45 46 47 15924 guibtact
+Search 36 37 38 39 4927 guibtact
+ShapeChange 0 0 0 0 4958 guibtact
+Taming 124 125 126 127 4974 guibtact
+Skills 96 97 98 99 4933 guibtact
+Wilderness 92 93 94 95 32186 guibtact
+27 * * * * * *
+28 * * * * * *
+29 * * * * * *
+30 * * * * * *
+31 * * * * * *
+Left 48 49 50 51 -1 guibtact
+Right 52 53 54 55 -1 guibtact
+34 * * * * * *
+35 * * * * * *
+36 * * * * * *
+37 * * * * * *
+38 * * * * * *
+39 * * * * * *
+BardSpell 56 57 58 59 39709 guibtact
+ClericSpell 60 61 62 63 39710 guibtact
+DruidSpell 64 65 66 67 39711 guibtact
+PaladinSpell 68 69 70 71 39712 guibtact
+RangerSpell 72 73 74 75 39713 guibtact
+SorcererSpell 76 77 78 79 39714 guibtact
+WizardSpell 80 81 82 83 39715 guibtact
+DomainSpell 84 85 86 87 39716 guibtact
+WildShapes 88 89 90 91 39717 guibtact
+49 * * * * 39718 guibtact
+QSpell1 0 1 2 0 4938 guibtbut
+QSpell2 0 1 2 0 4938 guibtbut
+QSpell3 0 1 2 0 4938 guibtbut
+QSpell4 0 1 2 0 4938 guibtbut
+QSpell5 0 1 2 0 4938 guibtbut
+QSpell6 0 1 2 0 4938 guibtbut
+QSpell7 0 1 2 0 4938 guibtbut
+QSpell8 0 1 2 0 4938 guibtbut
+QSpell9 0 1 2 0 4938 guibtbut
+59 * * * * * *
+QItem1 0 1 2 0 4937 guibtbut
+QItem2 0 1 2 0 4937 guibtbut
+QItem3 0 1 2 0 4937 guibtbut
+QItem4 0 1 2 0 4937 guibtbut
+QItem5 0 1 2 0 4937 guibtbut
+QItem6 0 1 2 0 4937 guibtbut
+QItem7 0 1 2 0 4937 guibtbut
+QItem8 0 1 2 0 4937 guibtbut
+QItem9 0 1 2 0 4937 guibtbut
+69 * * * * * *
+QSpec1 0 1 2 0 37435 guibtbut
+QSpec2 0 1 2 0 37435 guibtbut
+QSpec3 0 1 2 0 37435 guibtbut
+QSpec4 0 1 2 0 37435 guibtbut
+QSpec5 0 1 2 0 37435 guibtbut
+QSpec6 0 1 2 0 37435 guibtbut
+QSpec7 0 1 2 0 37435 guibtbut
+QSpec8 0 1 2 0 37435 guibtbut
+QSpec9 0 1 2 0 37435 guibtbut
+79 * * * * * *
+QSong1 0 1 2 0 37436 guibtbut
+QSong2 0 1 2 0 37436 guibtbut
+QSong3 0 1 2 0 37436 guibtbut
+QSong4 0 1 2 0 37436 guibtbut
+QSong5 0 1 2 0 37436 guibtbut
+QSong6 0 1 2 0 37436 guibtbut
+QSong7 0 1 2 0 37436 guibtbut
+QSong8 0 1 2 0 37436 guibtbut
+QSong9 0 1 2 0 37436 guibtbut
+89
diff --git a/gemrb/override/iwd2/guils.chu b/gemrb/unhardcoded/iwd2/guils.chu
similarity index 100%
rename from gemrb/override/iwd2/guils.chu
rename to gemrb/unhardcoded/iwd2/guils.chu
diff --git a/gemrb/unhardcoded/iwd2/hamstr.spl b/gemrb/unhardcoded/iwd2/hamstr.spl
new file mode 100644
index 0000000..bba726e
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/hamstr.spl differ
diff --git a/gemrb/override/iwd2/harmh.pro b/gemrb/unhardcoded/iwd2/harmh.pro
similarity index 100%
rename from gemrb/override/iwd2/harmh.pro
rename to gemrb/unhardcoded/iwd2/harmh.pro
diff --git a/gemrb/override/iwd2/harmony.pro b/gemrb/unhardcoded/iwd2/harmony.pro
similarity index 100%
rename from gemrb/override/iwd2/harmony.pro
rename to gemrb/unhardcoded/iwd2/harmony.pro
diff --git a/gemrb/override/iwd2/haterace.2da b/gemrb/unhardcoded/iwd2/haterace.2da
similarity index 100%
rename from gemrb/override/iwd2/haterace.2da
rename to gemrb/unhardcoded/iwd2/haterace.2da
diff --git a/gemrb/override/iwd2/healh.pro b/gemrb/unhardcoded/iwd2/healh.pro
similarity index 100%
rename from gemrb/override/iwd2/healh.pro
rename to gemrb/unhardcoded/iwd2/healh.pro
diff --git a/gemrb/override/iwd2/hmighth.pro b/gemrb/unhardcoded/iwd2/hmighth.pro
similarity index 100%
rename from gemrb/override/iwd2/hmighth.pro
rename to gemrb/unhardcoded/iwd2/hmighth.pro
diff --git a/gemrb/override/iwd2/hold.pro b/gemrb/unhardcoded/iwd2/hold.pro
similarity index 100%
rename from gemrb/override/iwd2/hold.pro
rename to gemrb/unhardcoded/iwd2/hold.pro
diff --git a/gemrb/override/iwd2/hsmite.pro b/gemrb/unhardcoded/iwd2/hsmite.pro
similarity index 100%
rename from gemrb/override/iwd2/hsmite.pro
rename to gemrb/unhardcoded/iwd2/hsmite.pro
diff --git a/gemrb/override/iwd2/hword.pro b/gemrb/unhardcoded/iwd2/hword.pro
similarity index 100%
rename from gemrb/override/iwd2/hword.pro
rename to gemrb/unhardcoded/iwd2/hword.pro
diff --git a/gemrb/override/iwd2/icelance.pro b/gemrb/unhardcoded/iwd2/icelance.pro
similarity index 100%
rename from gemrb/override/iwd2/icelance.pro
rename to gemrb/unhardcoded/iwd2/icelance.pro
diff --git a/gemrb/override/iwd2/icestorm.pro b/gemrb/unhardcoded/iwd2/icestorm.pro
similarity index 100%
rename from gemrb/override/iwd2/icestorm.pro
rename to gemrb/unhardcoded/iwd2/icestorm.pro
diff --git a/gemrb/override/iwd2/icloud.pro b/gemrb/unhardcoded/iwd2/icloud.pro
similarity index 100%
rename from gemrb/override/iwd2/icloud.pro
rename to gemrb/unhardcoded/iwd2/icloud.pro
diff --git a/gemrb/override/iwd2/iclouda.pro b/gemrb/unhardcoded/iwd2/iclouda.pro
similarity index 100%
rename from gemrb/override/iwd2/iclouda.pro
rename to gemrb/unhardcoded/iwd2/iclouda.pro
diff --git a/gemrb/override/iwd2/icloudb.pro b/gemrb/unhardcoded/iwd2/icloudb.pro
similarity index 100%
rename from gemrb/override/iwd2/icloudb.pro
rename to gemrb/unhardcoded/iwd2/icloudb.pro
diff --git a/gemrb/override/iwd2/illush.pro b/gemrb/unhardcoded/iwd2/illush.pro
similarity index 100%
rename from gemrb/override/iwd2/illush.pro
rename to gemrb/unhardcoded/iwd2/illush.pro
diff --git a/gemrb/override/iwd2/illust.pro b/gemrb/unhardcoded/iwd2/illust.pro
similarity index 100%
rename from gemrb/override/iwd2/illust.pro
rename to gemrb/unhardcoded/iwd2/illust.pro
diff --git a/gemrb/override/iwd2/inarea.pro b/gemrb/unhardcoded/iwd2/inarea.pro
similarity index 100%
rename from gemrb/override/iwd2/inarea.pro
rename to gemrb/unhardcoded/iwd2/inarea.pro
diff --git a/gemrb/override/iwd2/inareanp.pro b/gemrb/unhardcoded/iwd2/inareanp.pro
similarity index 100%
rename from gemrb/override/iwd2/inareanp.pro
rename to gemrb/unhardcoded/iwd2/inareanp.pro
diff --git a/gemrb/unhardcoded/iwd2/inareapa.pro b/gemrb/unhardcoded/iwd2/inareapa.pro
new file mode 100644
index 0000000..fedb699
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/inareapa.pro differ
diff --git a/gemrb/override/iwd2/inareasm.pro b/gemrb/unhardcoded/iwd2/inareasm.pro
similarity index 100%
rename from gemrb/override/iwd2/inareasm.pro
rename to gemrb/unhardcoded/iwd2/inareasm.pro
diff --git a/gemrb/override/iwd2/invoch.pro b/gemrb/unhardcoded/iwd2/invoch.pro
similarity index 100%
rename from gemrb/override/iwd2/invoch.pro
rename to gemrb/unhardcoded/iwd2/invoch.pro
diff --git a/gemrb/override/iwd2/invoct.pro b/gemrb/unhardcoded/iwd2/invoct.pro
similarity index 100%
rename from gemrb/override/iwd2/invoct.pro
rename to gemrb/unhardcoded/iwd2/invoct.pro
diff --git a/gemrb/override/iwd2/iplague.pro b/gemrb/unhardcoded/iwd2/iplague.pro
similarity index 100%
rename from gemrb/override/iwd2/iplague.pro
rename to gemrb/unhardcoded/iwd2/iplague.pro
diff --git a/gemrb/override/iwd2/island00.2da b/gemrb/unhardcoded/iwd2/island00.2da
similarity index 100%
rename from gemrb/override/iwd2/island00.2da
rename to gemrb/unhardcoded/iwd2/island00.2da
diff --git a/gemrb/unhardcoded/iwd2/itemdata.2da b/gemrb/unhardcoded/iwd2/itemdata.2da
new file mode 100644
index 0000000..014cb4b
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/itemdata.2da
@@ -0,0 +1,30 @@
+2DA V1.0
+0
+ ITEMTYPE FAILURE CRITRANGE CRITMULTI SKILL_PENALTY
+LEATHER 60 2 20 0 0
+STUDDED 61 3 20 0 1
+CHAIN 62 6 20 0 5
+SPLINT 63 8 20 0 7
+HALFPLATE 64 8 20 0 7
+FULLPLATE 65 7 20 0 6
+HIDE 66 4 20 0 3
+ROBE 67 0 20 0 0
+SCALE 68 5 20 0 3
+ARROW 5 0 20 3 0
+BOW 15 0 20 3 0
+DAGGER 16 0 19 2 0
+SMSWORD 19 0 19 2 0
+BGSWORD 20 0 19 2 0
+HAMMER 21 0 20 3 0
+FLAIL 23 0 19 2 0
+AXE 25 0 20 3 0
+XBOW 27 0 19 2 0
+SPEAR 29 0 20 3 0
+POLEARM 30 0 20 3 0
+BOLT 31 0 19 2 0
+BUCKLER 41 0 20 0 1
+SSHIELD 53 1 20 0 1
+MSHIELD 49 2 20 0 2
+LSHIELD 47 3 20 0 2
+GTSWORD 57 0 19 2 0
+BTSWORD 69 0 19 2 0
diff --git a/gemrb/unhardcoded/iwd2/itemsnd.2da b/gemrb/unhardcoded/iwd2/itemsnd.2da
new file mode 100644
index 0000000..adffeb0
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/itemsnd.2da
@@ -0,0 +1,81 @@
+2DA V1.0
+*
+ TAKE DROP
+MISC G_BOOK1 G_BOOK2
+AMULET G_NECK1 G_NECK2
+ARMOR G_CLOAK1 G_CLOAK2
+BELT G_BELT1 G_BELT2
+BOOT G_BOOT1 G_BOOT2
+ARROW G_ARRW1 G_ARRW2
+BRACER G_GLOVE1 G_GLOVE2
+HELMET G_HELM1 G_HELM2
+KEY G_KEY1 G_KEY2
+POTION G_POTN1 G_POTN2
+RING G_RING1 G_RING2
+SCROLL G_SCROL1 G_SCROL2
+SHIELD GAM_21A GAM_21B
+FOOD GAM_21A GAM_21B
+BULLET G_BULLT1 G_BULLT2
+BOW G_BOW1 G_BOW2
+DAGGER G_DAGGR1 G_DAGGR2
+MACE G_MACE1 G_MACE2
+SLING G_SLING1 G_SLING2
+SMSWORD G_SMSWD1 G_SMSWD2
+BGSWORD G_LGSWD1 G_LGSWD2
+HAMMER G_HAMMR1 G_HAMMR2
+MSTAR G_MSTAR1 G_MSTAR2
+FLAIL G_FLAIL1 G_FLAIL2
+DART G_DART1 G_DART2
+AXE G_AXE1 G_AXE2
+STAFF G_STAFF1 G_STAFF2
+XBOW G_CROSB1 G_CROSB2
+FIST GAM_21A GAM_21B
+SPEAR G_SPEAR1 G_SPEAR2
+POLEARM G_HALB1 G_HALB2
+BOLT G_BOLT1 G_BOLT2
+CLOAK G_CLOAK1 G_CLOAK2
+COIN G_GOLD1 G_GOLD2
+GEM G_GEM1 G_GEM2
+WAND G_WAND1 G_WAND2
+BROKEN1 G_B_ARM1 G_B_ARM2
+BROKEN2 G_B_SHD1 G_B_SHD2
+BROKEN3 G_B_WPN1 G_B_WPN2
+UNUSED1 GAM_21A GAM_21B
+UNUSED2 G_BROKN1 G_BROKN2
+BUCKLER G_BUCKR1 G_BUCKR2
+CANDLE G_CAND1 G_CAND2
+CBODY G_CHILD1 G_CHILD2
+CLUB G_CLUB1 G_CLUB2
+FBODY G_FEM1 G_FEM2
+KEY2 G_KEYS1 G_KEYS2
+LSHIELD G_LGSLD1 G_LGSLD2
+MBODY G_MALE1 G_MALE2
+MSHIELD G_MDSLD1 G_MDSLD2
+NOTES G_PAPR1 G_PAPR2
+ROD G_ROD1 G_ROD2
+SKULL G_SKULL1 G_SKULL2
+SSHIELD G_SMSLD1 G_SMSLD2
+SPIDER G_SPIDR1 G_SPIDR2
+TELESCOPE G_TELE1 G_TELE2
+DRINK G_WINE1 G_WINE2
+GTSWORD G_LGSWD1 G_LGSWD2
+BAG GAM_21A GAM_21B
+FUR G_LETHR1 G_LETHR2
+LARMOR G_CLOAK1 G_CLOAK2
+SLARMOR G_CLOAK1 G_CLOAK2
+CHARMOR G_CLOAK1 G_CLOAK2
+SPARMOR G_CLOAK1 G_CLOAK2
+HPARMOR G_CLOAK1 G_CLOAK2
+FPARMOR G_CLOAK1 G_CLOAK2
+HARMOR G_CLOAK1 G_CLOAK2
+ROBE G_CLOAK1 G_CLOAK2
+SCALE G_CLOAK1 G_CLOAK2
+BTSWORD G_LGSWD1 G_LGSWD2
+SCARF G_GLOVE1 G_GLOVE2
+FOOD2 G_SLING1 G_SLING2
+HAT G_GLOVE1 G_GLOVE2
+GAUNTLET G_CAND1 G_CAND2
+DEFAULT GAM_21A GAM_21B
+LEATHER G_LETHR1 G_LETHR2
+CHAIN G_Chain1 G_Chain2
+PLATE G_Plate1 G_Plate2
diff --git a/gemrb/unhardcoded/iwd2/itemspec.2da b/gemrb/unhardcoded/iwd2/itemspec.2da
new file mode 100644
index 0000000..e2e588b
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/itemspec.2da
@@ -0,0 +1,4 @@
+2DA V1.0
+*
+ IDENTIFY
+SPWI110Z 1
diff --git a/gemrb/unhardcoded/iwd2/itemtype.2da b/gemrb/unhardcoded/iwd2/itemtype.2da
new file mode 100644
index 0000000..c7292fc
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/itemtype.2da
@@ -0,0 +1,77 @@
+2DA V1.0
+0
+ HELMET ARMOR SHIELD GLOVES RING AMULET BELT BOOTS WEAPON QUIVER CLOAK QUICK SCROLL BAG POTION
+BOOK 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
+AMULET 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
+ARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+BELT 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
+BOOT 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
+ARROW 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
+BRACER 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
+HELMET 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+KEY 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+POTION 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
+RING 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
+SCROLL 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0
+SHIELD 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
+FOOD 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
+BULLET 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
+BOW 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+DAGGER 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+MACE 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+SLING 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+SMSWORD 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+BGSWORD 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+HAMMER 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+MSTAR 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+FLAIL 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+DART 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+AXE 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+STAFF 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+XBOW 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+FIST 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+SPEAR 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+POLEARM 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+BOLT 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
+CLOAK 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
+COIN 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+GEM 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
+WAND 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
+BROKEN1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+BROKEN2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+BROKEN3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+UNUSED1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+UNUSED2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+BUCKLER 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
+CANDLE 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
+CBODY 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+CLUB 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+FBODY 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+KEY2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+LSHIELD 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
+MBODY 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+MSHIELD 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
+NOTES 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ROD 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
+SKULL 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+SSHIELD 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
+SPIDER 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+TELESCOPE 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
+DRINK 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
+GTSWORD 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+BAG 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
+FUR 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+LARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+SLARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+CHARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+SPARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+HPARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+FPARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+HARMOR 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+ROBE 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+SCALE 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+BTSWORD 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+SCARF 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
+FOOD2 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
+HAT 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+GAUNTLET 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
diff --git a/gemrb/override/iwd2/itemuse.2da b/gemrb/unhardcoded/iwd2/itemuse.2da
similarity index 100%
rename from gemrb/override/iwd2/itemuse.2da
rename to gemrb/unhardcoded/iwd2/itemuse.2da
diff --git a/gemrb/override/iwd2/iwdshtab.2da b/gemrb/unhardcoded/iwd2/iwdshtab.2da
similarity index 100%
rename from gemrb/override/iwd2/iwdshtab.2da
rename to gemrb/unhardcoded/iwd2/iwdshtab.2da
diff --git a/gemrb/override/iwd2/lightb.pro b/gemrb/unhardcoded/iwd2/lightb.pro
similarity index 100%
rename from gemrb/override/iwd2/lightb.pro
rename to gemrb/unhardcoded/iwd2/lightb.pro
diff --git a/gemrb/unhardcoded/iwd2/lightbnb.pro b/gemrb/unhardcoded/iwd2/lightbnb.pro
new file mode 100644
index 0000000..94f48ac
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/lightbnb.pro differ
diff --git a/gemrb/override/iwd2/lightsto.pro b/gemrb/unhardcoded/iwd2/lightsto.pro
similarity index 100%
rename from gemrb/override/iwd2/lightsto.pro
rename to gemrb/unhardcoded/iwd2/lightsto.pro
diff --git a/gemrb/override/iwd2/lodisr.pro b/gemrb/unhardcoded/iwd2/lodisr.pro
similarity index 100%
rename from gemrb/override/iwd2/lodisr.pro
rename to gemrb/unhardcoded/iwd2/lodisr.pro
diff --git a/gemrb/unhardcoded/iwd2/magesch.2da b/gemrb/unhardcoded/iwd2/magesch.2da
new file mode 100644
index 0000000..70deb9f
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/magesch.2da
@@ -0,0 +1,12 @@
+2DA V1.0
+-1
+ NAME_REF DESC_REF CAP_REF KIT
+GENERALIST 18039 9563 9987 0x4000
+ABJURER 597 9564 502 0x40
+CONJURER 2179 9565 504 0x80
+DIVINER 2846 9566 2012 0x100
+ENCHANTER 2861 9567 2022 0x200
+ILLUSIONIST 2862 9568 12785 0x400
+INVOKER 3015 9569 12786 0x800
+NECROMANCER 12744 9570 12787 0x1000
+TRANSMUTER 12745 9571 12788 0x2000
diff --git a/gemrb/override/iwd2/magicmis.pro b/gemrb/unhardcoded/iwd2/magicmis.pro
similarity index 100%
rename from gemrb/override/iwd2/magicmis.pro
rename to gemrb/unhardcoded/iwd2/magicmis.pro
diff --git a/gemrb/override/iwd2/malison.pro b/gemrb/unhardcoded/iwd2/malison.pro
similarity index 100%
rename from gemrb/override/iwd2/malison.pro
rename to gemrb/unhardcoded/iwd2/malison.pro
diff --git a/gemrb/unhardcoded/iwd2/mdfeats.2da b/gemrb/unhardcoded/iwd2/mdfeats.2da
new file mode 100644
index 0000000..1e14627
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/mdfeats.2da
@@ -0,0 +1,11 @@
+2DA V1.0
+*
+ SPELL
+ES_0 *
+ES_1 *
+ES_2 *
+EXPERTISE SPIN276
+POWERATK SPIN275
+ARTERIAL SPIN277
+HAMSTRING SPIN278
+RAPIDSHOT SPIN279
diff --git a/gemrb/override/iwd2/mfmiss.pro b/gemrb/unhardcoded/iwd2/mfmiss.pro
similarity index 100%
rename from gemrb/override/iwd2/mfmiss.pro
rename to gemrb/unhardcoded/iwd2/mfmiss.pro
diff --git a/gemrb/override/iwd2/mfmiss2.pro b/gemrb/unhardcoded/iwd2/mfmiss2.pro
similarity index 100%
rename from gemrb/override/iwd2/mfmiss2.pro
rename to gemrb/unhardcoded/iwd2/mfmiss2.pro
diff --git a/gemrb/override/iwd2/mfmissh.pro b/gemrb/unhardcoded/iwd2/mfmissh.pro
similarity index 100%
rename from gemrb/override/iwd2/mfmissh.pro
rename to gemrb/unhardcoded/iwd2/mfmissh.pro
diff --git a/gemrb/override/iwd2/mfog.pro b/gemrb/unhardcoded/iwd2/mfog.pro
similarity index 100%
rename from gemrb/override/iwd2/mfog.pro
rename to gemrb/unhardcoded/iwd2/mfog.pro
diff --git a/gemrb/override/iwd2/mmagich.pro b/gemrb/unhardcoded/iwd2/mmagich.pro
similarity index 100%
rename from gemrb/override/iwd2/mmagich.pro
rename to gemrb/unhardcoded/iwd2/mmagich.pro
diff --git a/gemrb/override/iwd2/mmissile.pro b/gemrb/unhardcoded/iwd2/mmissile.pro
similarity index 100%
rename from gemrb/override/iwd2/mmissile.pro
rename to gemrb/unhardcoded/iwd2/mmissile.pro
diff --git a/gemrb/override/iwd2/modal.2da b/gemrb/unhardcoded/iwd2/modal.2da
similarity index 100%
rename from gemrb/override/iwd2/modal.2da
rename to gemrb/unhardcoded/iwd2/modal.2da
diff --git a/gemrb/override/iwd2/moelda.pro b/gemrb/unhardcoded/iwd2/moelda.pro
similarity index 100%
rename from gemrb/override/iwd2/moelda.pro
rename to gemrb/unhardcoded/iwd2/moelda.pro
diff --git a/gemrb/override/iwd2/mrage.pro b/gemrb/unhardcoded/iwd2/mrage.pro
similarity index 100%
rename from gemrb/override/iwd2/mrage.pro
rename to gemrb/unhardcoded/iwd2/mrage.pro
diff --git a/gemrb/override/iwd2/mrageh.pro b/gemrb/unhardcoded/iwd2/mrageh.pro
similarity index 100%
rename from gemrb/override/iwd2/mrageh.pro
rename to gemrb/unhardcoded/iwd2/mrageh.pro
diff --git a/gemrb/override/iwd2/mspore.pro b/gemrb/unhardcoded/iwd2/mspore.pro
similarity index 100%
rename from gemrb/override/iwd2/mspore.pro
rename to gemrb/unhardcoded/iwd2/mspore.pro
diff --git a/gemrb/override/iwd2/msumm1.pro b/gemrb/unhardcoded/iwd2/msumm1.pro
similarity index 100%
rename from gemrb/override/iwd2/msumm1.pro
rename to gemrb/unhardcoded/iwd2/msumm1.pro
diff --git a/gemrb/override/iwd2/msumm1h.pro b/gemrb/unhardcoded/iwd2/msumm1h.pro
similarity index 100%
rename from gemrb/override/iwd2/msumm1h.pro
rename to gemrb/unhardcoded/iwd2/msumm1h.pro
diff --git a/gemrb/override/iwd2/msumm1x.pro b/gemrb/unhardcoded/iwd2/msumm1x.pro
similarity index 100%
rename from gemrb/override/iwd2/msumm1x.pro
rename to gemrb/unhardcoded/iwd2/msumm1x.pro
diff --git a/gemrb/override/iwd2/msumm2h.pro b/gemrb/unhardcoded/iwd2/msumm2h.pro
similarity index 100%
rename from gemrb/override/iwd2/msumm2h.pro
rename to gemrb/unhardcoded/iwd2/msumm2h.pro
diff --git a/gemrb/override/iwd2/msumm3h.pro b/gemrb/unhardcoded/iwd2/msumm3h.pro
similarity index 100%
rename from gemrb/override/iwd2/msumm3h.pro
rename to gemrb/unhardcoded/iwd2/msumm3h.pro
diff --git a/gemrb/override/iwd2/msumm4h.pro b/gemrb/unhardcoded/iwd2/msumm4h.pro
similarity index 100%
rename from gemrb/override/iwd2/msumm4h.pro
rename to gemrb/unhardcoded/iwd2/msumm4h.pro
diff --git a/gemrb/override/iwd2/msumm5h.pro b/gemrb/unhardcoded/iwd2/msumm5h.pro
similarity index 100%
rename from gemrb/override/iwd2/msumm5h.pro
rename to gemrb/unhardcoded/iwd2/msumm5h.pro
diff --git a/gemrb/override/iwd2/msumm6h.pro b/gemrb/unhardcoded/iwd2/msumm6h.pro
similarity index 100%
rename from gemrb/override/iwd2/msumm6h.pro
rename to gemrb/unhardcoded/iwd2/msumm6h.pro
diff --git a/gemrb/override/iwd2/msumm7h.pro b/gemrb/unhardcoded/iwd2/msumm7h.pro
similarity index 100%
rename from gemrb/override/iwd2/msumm7h.pro
rename to gemrb/unhardcoded/iwd2/msumm7h.pro
diff --git a/gemrb/override/iwd2/mswordh.pro b/gemrb/unhardcoded/iwd2/mswordh.pro
similarity index 100%
rename from gemrb/override/iwd2/mswordh.pro
rename to gemrb/unhardcoded/iwd2/mswordh.pro
diff --git a/gemrb/override/iwd2/mtouchh.pro b/gemrb/unhardcoded/iwd2/mtouchh.pro
similarity index 100%
rename from gemrb/override/iwd2/mtouchh.pro
rename to gemrb/unhardcoded/iwd2/mtouchh.pro
diff --git a/gemrb/override/iwd2/necroh.pro b/gemrb/unhardcoded/iwd2/necroh.pro
similarity index 100%
rename from gemrb/override/iwd2/necroh.pro
rename to gemrb/unhardcoded/iwd2/necroh.pro
diff --git a/gemrb/override/iwd2/necrot.pro b/gemrb/unhardcoded/iwd2/necrot.pro
similarity index 100%
rename from gemrb/override/iwd2/necrot.pro
rename to gemrb/unhardcoded/iwd2/necrot.pro
diff --git a/gemrb/override/iwd2/npoisoh.pro b/gemrb/unhardcoded/iwd2/npoisoh.pro
similarity index 100%
rename from gemrb/override/iwd2/npoisoh.pro
rename to gemrb/unhardcoded/iwd2/npoisoh.pro
diff --git a/gemrb/override/iwd2/ofsphe.pro b/gemrb/unhardcoded/iwd2/ofsphe.pro
similarity index 100%
rename from gemrb/override/iwd2/ofsphe.pro
rename to gemrb/unhardcoded/iwd2/ofsphe.pro
diff --git a/gemrb/override/iwd2/overlay.2da b/gemrb/unhardcoded/iwd2/overlay.2da
similarity index 100%
rename from gemrb/override/iwd2/overlay.2da
rename to gemrb/unhardcoded/iwd2/overlay.2da
diff --git a/gemrb/override/iwd2/paralh.pro b/gemrb/unhardcoded/iwd2/paralh.pro
similarity index 100%
rename from gemrb/override/iwd2/paralh.pro
rename to gemrb/unhardcoded/iwd2/paralh.pro
diff --git a/gemrb/override/how/pathfind.2da b/gemrb/unhardcoded/iwd2/pathfind.2da
similarity index 100%
rename from gemrb/override/how/pathfind.2da
rename to gemrb/unhardcoded/iwd2/pathfind.2da
diff --git a/gemrb/override/iwd2/pfire.pro b/gemrb/unhardcoded/iwd2/pfire.pro
similarity index 100%
rename from gemrb/override/iwd2/pfire.pro
rename to gemrb/unhardcoded/iwd2/pfire.pro
diff --git a/gemrb/override/iwd2/pictures.2da b/gemrb/unhardcoded/iwd2/pictures.2da
similarity index 100%
rename from gemrb/override/iwd2/pictures.2da
rename to gemrb/unhardcoded/iwd2/pictures.2da
diff --git a/gemrb/override/iwd2/poisonh.pro b/gemrb/unhardcoded/iwd2/poisonh.pro
similarity index 100%
rename from gemrb/override/iwd2/poisonh.pro
rename to gemrb/unhardcoded/iwd2/poisonh.pro
diff --git a/gemrb/override/iwd2/polystat.2da b/gemrb/unhardcoded/iwd2/polystat.2da
similarity index 100%
rename from gemrb/override/iwd2/polystat.2da
rename to gemrb/unhardcoded/iwd2/polystat.2da
diff --git a/gemrb/override/iwd2/portal.pro b/gemrb/unhardcoded/iwd2/portal.pro
similarity index 100%
rename from gemrb/override/iwd2/portal.pro
rename to gemrb/unhardcoded/iwd2/portal.pro
diff --git a/gemrb/override/iwd2/prayer.pro b/gemrb/unhardcoded/iwd2/prayer.pro
similarity index 100%
rename from gemrb/override/iwd2/prayer.pro
rename to gemrb/unhardcoded/iwd2/prayer.pro
diff --git a/gemrb/override/iwd2/prayerh.pro b/gemrb/unhardcoded/iwd2/prayerh.pro
similarity index 100%
rename from gemrb/override/iwd2/prayerh.pro
rename to gemrb/unhardcoded/iwd2/prayerh.pro
diff --git a/gemrb/unhardcoded/iwd2/proftype.2da b/gemrb/unhardcoded/iwd2/proftype.2da
new file mode 100644
index 0000000..e353325
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/proftype.2da
@@ -0,0 +1,73 @@
+2DA V1.0
+-1
+ OLD_PROFICIENCY
+0 -2
+1 -1
+2 -1
+3 -1
+4 -1
+5 -1
+6 -1
+7 -1
+8 -1
+9 -1
+10 -1
+11 -1
+12 -1
+13 -1
+14 -1
+15_BOW 0
+16_DAGGER 11
+17_MACE 4
+18_SLING 2
+19_SWORD 11
+20_BIG 10
+21_HAMMER 7
+22_MS 4
+23_FLAIL 5
+24_DART 2
+25_AXE 3
+26_STAFF 8
+27_XBOW 1
+28_HAND -2
+29_SPEAR 6
+30_HALBERD 6
+31 -1
+32 -1
+33 -1
+34 -1
+35 -1
+36 -1
+37 -1
+38 -1
+39 -1
+40 -1
+41 -1
+42 -1
+43 -1
+44_CLUB 4
+45 -1
+46 -1
+47 -1
+48 -1
+49 -1
+50 -1
+51 -1
+52 -1
+53 -1
+54 -1
+55 -1
+56 -1
+57_GREATSWORD 9
+58 -1
+59 -1
+60 -1
+61 -1
+62 -1
+63 -1
+64 -1
+65 -1
+66 -1
+67 -1
+68_BASTARD 25
+
diff --git a/gemrb/override/iwd2/protevil.pro b/gemrb/unhardcoded/iwd2/protevil.pro
similarity index 100%
rename from gemrb/override/iwd2/protevil.pro
rename to gemrb/unhardcoded/iwd2/protevil.pro
diff --git a/gemrb/override/iwd2/prtl_cl.pro b/gemrb/unhardcoded/iwd2/prtl_cl.pro
similarity index 100%
rename from gemrb/override/iwd2/prtl_cl.pro
rename to gemrb/unhardcoded/iwd2/prtl_cl.pro
diff --git a/gemrb/override/iwd2/prtl_op.pro b/gemrb/unhardcoded/iwd2/prtl_op.pro
similarity index 100%
rename from gemrb/override/iwd2/prtl_op.pro
rename to gemrb/unhardcoded/iwd2/prtl_op.pro
diff --git a/gemrb/override/iwd2/pspray.pro b/gemrb/unhardcoded/iwd2/pspray.pro
similarity index 100%
rename from gemrb/override/iwd2/pspray.pro
rename to gemrb/unhardcoded/iwd2/pspray.pro
diff --git a/gemrb/override/iwd2/pwkill.pro b/gemrb/unhardcoded/iwd2/pwkill.pro
similarity index 100%
rename from gemrb/override/iwd2/pwkill.pro
rename to gemrb/unhardcoded/iwd2/pwkill.pro
diff --git a/gemrb/override/iwd2/pwsileh.pro b/gemrb/unhardcoded/iwd2/pwsileh.pro
similarity index 100%
rename from gemrb/override/iwd2/pwsileh.pro
rename to gemrb/unhardcoded/iwd2/pwsileh.pro
diff --git a/gemrb/override/iwd2/pwstun.pro b/gemrb/unhardcoded/iwd2/pwstun.pro
similarity index 100%
rename from gemrb/override/iwd2/pwstun.pro
rename to gemrb/unhardcoded/iwd2/pwstun.pro
diff --git a/gemrb/override/iwd2/pwstunh.pro b/gemrb/unhardcoded/iwd2/pwstunh.pro
similarity index 100%
rename from gemrb/override/iwd2/pwstunh.pro
rename to gemrb/unhardcoded/iwd2/pwstunh.pro
diff --git a/gemrb/unhardcoded/iwd2/raceflag.2da b/gemrb/unhardcoded/iwd2/raceflag.2da
new file mode 100644
index 0000000..eee6a6b
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/raceflag.2da
@@ -0,0 +1,10 @@
+2DA V1.0
+0
+ FLAG AC
+HUMAN_AASIMAR 0x20000 0
+HUMAN_TIEFLING 0x20000 0
+ELF_DROW 0x20000 0
+DWARF 0x20000 0
+GNOME 0x20000 0
+GNOME_DEEP 0x220000 4
+HALFORC 0x20000 0
diff --git a/gemrb/unhardcoded/iwd2/races.2da b/gemrb/unhardcoded/iwd2/races.2da
new file mode 100644
index 0000000..3d87812
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/races.2da
@@ -0,0 +1,19 @@
+2DA V1.0
+-1
+ NAME_REF DESC_REF CAP_REF ID USABILITY HAIR SKIN SKILL_COLUMN FAVORED_CLASS FEATBONUS ECL
+HUMAN 7193 9550 1096 1 0x08000000 HAIRNORM SKINNORM 23 -1 1 0
+DWARF 7182 9551 1100 4 0x01000000 HAIRNORM SKINNORM 29 0x505 0 0
+ELF 7194 9552 1097 2 0x00800000 HAIRNORM SKINNORM 26 0xb0b 0 0
+GNOME 7196 9553 1099 6 0x10000000 HAIRNORM SKINNORM 35 0xb0b 0 0
+HALF_ELF 7197 9555 1098 3 0x02000000 HAIRNORM SKINNORM 37 -1 0 0
+HALF_ORC 22 25 23 7 0x80000000 HAIRNORM SKINNORM 38 0x101 0 0
+HALFLING 7195 9554 5374 5 0x04000000 HAIRNORM SKINNORM 32 0x909 0 0
+HUMAN_AASIMAR 5377 5386 5377 0x10001 0x00000000 HAIRAASM SKINAASM 24 0x707 0 1
+HUMAN_TIEFLING 5378 5388 5378 0x10002 0x00000000 HAIRTIEF SKINTIEF 25 0x909 0 1
+ELF_DROW 5379 5394 5379 0x20001 0x00000000 HAIRDARK SKINDARK 27 0x30b 0 2
+ELF_WILD 5380 5397 5380 0x20002 0x00000000 HAIRWOOD SKINWOOD 28 0xa0a 0 0
+DWARF_GOLD 5381 5413 5381 0x40001 0x00000000 HAIRGOLD SKINGOLD 30 0x505 0 0
+DWARF_GRAY 5382 5416 5382 0x40002 0x00000000 HAIRGRAY SKINGRAY 31 0x505 0 2
+HALFLING_STRONGHEART 5383 5660 5383 0x50001 0x00000000 HAIRNORM SKINNORM 33 0x909 0 0
+HALFLING_GHOSTWISE 5384 5661 5384 0x50002 0x00000000 HAIRNORM SKINNORM 34 0x101 0 0
+GNOME_DEEP 5385 5662 5385 0x60001 0x00000000 HAIRNORM SKINNORM 36 0xb0b 0 3
diff --git a/gemrb/override/iwd2/rad100.pro b/gemrb/unhardcoded/iwd2/rad100.pro
similarity index 100%
rename from gemrb/override/iwd2/rad100.pro
rename to gemrb/unhardcoded/iwd2/rad100.pro
diff --git a/gemrb/override/iwd2/rad250.pro b/gemrb/unhardcoded/iwd2/rad250.pro
similarity index 100%
rename from gemrb/override/iwd2/rad250.pro
rename to gemrb/unhardcoded/iwd2/rad250.pro
diff --git a/gemrb/override/iwd2/rad300.pro b/gemrb/unhardcoded/iwd2/rad300.pro
similarity index 100%
rename from gemrb/override/iwd2/rad300.pro
rename to gemrb/unhardcoded/iwd2/rad300.pro
diff --git a/gemrb/override/iwd2/randitem.2da b/gemrb/unhardcoded/iwd2/randitem.2da
similarity index 100%
rename from gemrb/override/iwd2/randitem.2da
rename to gemrb/unhardcoded/iwd2/randitem.2da
diff --git a/gemrb/override/iwd2/rdeadh.pro b/gemrb/unhardcoded/iwd2/rdeadh.pro
similarity index 100%
rename from gemrb/override/iwd2/rdeadh.pro
rename to gemrb/unhardcoded/iwd2/rdeadh.pro
diff --git a/gemrb/override/iwd2/recitah.pro b/gemrb/unhardcoded/iwd2/recitah.pro
similarity index 100%
rename from gemrb/override/iwd2/recitah.pro
rename to gemrb/unhardcoded/iwd2/recitah.pro
diff --git a/gemrb/override/iwd2/resurrh.pro b/gemrb/unhardcoded/iwd2/resurrh.pro
similarity index 100%
rename from gemrb/override/iwd2/resurrh.pro
rename to gemrb/unhardcoded/iwd2/resurrh.pro
diff --git a/gemrb/override/iwd2/rng450.pro b/gemrb/unhardcoded/iwd2/rng450.pro
similarity index 100%
rename from gemrb/override/iwd2/rng450.pro
rename to gemrb/unhardcoded/iwd2/rng450.pro
diff --git a/gemrb/override/iwd2/rparalh.pro b/gemrb/unhardcoded/iwd2/rparalh.pro
similarity index 100%
rename from gemrb/override/iwd2/rparalh.pro
rename to gemrb/unhardcoded/iwd2/rparalh.pro
diff --git a/gemrb/override/iwd2/rwotfag.pro b/gemrb/unhardcoded/iwd2/rwotfag.pro
similarity index 100%
rename from gemrb/override/iwd2/rwotfag.pro
rename to gemrb/unhardcoded/iwd2/rwotfag.pro
diff --git a/gemrb/override/iwd2/rwotfah.pro b/gemrb/unhardcoded/iwd2/rwotfah.pro
similarity index 100%
rename from gemrb/override/iwd2/rwotfah.pro
rename to gemrb/unhardcoded/iwd2/rwotfah.pro
diff --git a/gemrb/override/iwd2/sarmorh.pro b/gemrb/unhardcoded/iwd2/sarmorh.pro
similarity index 100%
rename from gemrb/override/iwd2/sarmorh.pro
rename to gemrb/unhardcoded/iwd2/sarmorh.pro
diff --git a/gemrb/override/iwd2/savegame.2da b/gemrb/unhardcoded/iwd2/savegame.2da
similarity index 100%
rename from gemrb/override/iwd2/savegame.2da
rename to gemrb/unhardcoded/iwd2/savegame.2da
diff --git a/gemrb/override/iwd2/scharge.pro b/gemrb/unhardcoded/iwd2/scharge.pro
similarity index 100%
rename from gemrb/override/iwd2/scharge.pro
rename to gemrb/unhardcoded/iwd2/scharge.pro
diff --git a/gemrb/override/iwd2/schargh.pro b/gemrb/unhardcoded/iwd2/schargh.pro
similarity index 100%
rename from gemrb/override/iwd2/schargh.pro
rename to gemrb/unhardcoded/iwd2/schargh.pro
diff --git a/gemrb/override/iwd2/script.2da b/gemrb/unhardcoded/iwd2/script.2da
similarity index 100%
rename from gemrb/override/iwd2/script.2da
rename to gemrb/unhardcoded/iwd2/script.2da
diff --git a/gemrb/override/iwd2/seater.pro b/gemrb/unhardcoded/iwd2/seater.pro
similarity index 100%
rename from gemrb/override/iwd2/seater.pro
rename to gemrb/unhardcoded/iwd2/seater.pro
diff --git a/gemrb/override/iwd2/seaterh.pro b/gemrb/unhardcoded/iwd2/seaterh.pro
similarity index 100%
rename from gemrb/override/iwd2/seaterh.pro
rename to gemrb/unhardcoded/iwd2/seaterh.pro
diff --git a/gemrb/override/iwd2/sgrowth.pro b/gemrb/unhardcoded/iwd2/sgrowth.pro
similarity index 100%
rename from gemrb/override/iwd2/sgrowth.pro
rename to gemrb/unhardcoded/iwd2/sgrowth.pro
diff --git a/gemrb/override/iwd2/shout.pro b/gemrb/unhardcoded/iwd2/shout.pro
similarity index 100%
rename from gemrb/override/iwd2/shout.pro
rename to gemrb/unhardcoded/iwd2/shout.pro
diff --git a/gemrb/override/iwd2/shroud.pro b/gemrb/unhardcoded/iwd2/shroud.pro
similarity index 100%
rename from gemrb/override/iwd2/shroud.pro
rename to gemrb/unhardcoded/iwd2/shroud.pro
diff --git a/gemrb/override/iwd2/shtable.2da b/gemrb/unhardcoded/iwd2/shtable.2da
similarity index 100%
rename from gemrb/override/iwd2/shtable.2da
rename to gemrb/unhardcoded/iwd2/shtable.2da
diff --git a/gemrb/override/iwd2/skillsta.2da b/gemrb/unhardcoded/iwd2/skillsta.2da
similarity index 100%
rename from gemrb/override/iwd2/skillsta.2da
rename to gemrb/unhardcoded/iwd2/skillsta.2da
diff --git a/gemrb/override/iwd2/sleep.pro b/gemrb/unhardcoded/iwd2/sleep.pro
similarity index 100%
rename from gemrb/override/iwd2/sleep.pro
rename to gemrb/unhardcoded/iwd2/sleep.pro
diff --git a/gemrb/override/iwd2/slivinh.pro b/gemrb/unhardcoded/iwd2/slivinh.pro
similarity index 100%
rename from gemrb/override/iwd2/slivinh.pro
rename to gemrb/unhardcoded/iwd2/slivinh.pro
diff --git a/gemrb/unhardcoded/iwd2/slottype.2da b/gemrb/unhardcoded/iwd2/slottype.2da
new file mode 100644
index 0000000..970bdca
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/slottype.2da
@@ -0,0 +1,54 @@
+2DA V1.0
+*
+ BITS SCRIPT ICON STRREF EFFECT FLAGS
+10 0 0 * 0 2 0
+6 1 13 STONHELM 11999 7 0
+1 2 11 STONARM 11997 1 0
+9 0 0 * 0 0 0
+5 8 12 STONGLET 11998 1 0
+7 16 22 STONRING 12002 1 1
+8 16 23 STONRING 12003 1 1
+0 32 14 STONAMUL 12000 1 0
+2 64 21 STONBELT 12001 1 0
+3 128 25 STONBOOT 12005 1 0
+43 256 101 STONWEAP 12010 4 1
+44 260 102 STONSHIL 12010 6 0
+45 256 103 STONWEAP 12010 4 1
+46 260 104 STONSHIL 12010 6 0
+47 256 105 STONWEAP 12010 4 1
+48 260 106 STONSHIL 12010 6 0
+49 256 107 STONWEAP 12010 4 1
+50 260 108 STONSHIL 12010 6 0
+11 512 15 STONQUIV 12009 5 1
+12 512 16 STONQUIV 12009 5 1
+13 512 17 STONQUIV 12009 5 1
+14 0 0 * 0 5 0
+4 1024 24 STONCLOK 12004 1 0
+15 2048 5 STONITEM 12012 0 1
+16 2048 6 STONITEM 12012 0 1
+17 2048 7 STONITEM 12012 0 1
+18 -1 30 * 12013 0 1
+19 -1 31 * 12013 0 1
+20 -1 32 * 12013 0 1
+21 -1 33 * 12013 0 1
+22 -1 34 * 12013 0 1
+23 -1 35 * 12013 0 1
+24 -1 36 * 12013 0 1
+25 -1 37 * 12013 0 1
+26 -1 38 * 12013 0 1
+27 -1 39 * 12013 0 1
+28 -1 40 * 12013 0 1
+29 -1 41 * 12013 0 1
+30 -1 42 * 12013 0 1
+31 -1 43 * 12013 0 1
+32 -1 44 * 12013 0 1
+33 -1 45 * 12013 0 1
+34 -1 73 * 12013 0 1
+35 -1 74 * 12013 0 1
+36 -1 75 * 12013 0 1
+37 -1 76 * 12013 0 1
+38 -1 77 * 12013 0 1
+39 -1 78 * 12013 0 1
+40 -1 79 * 12013 0 1
+41 -1 80 * 12013 0 1
+42 0 0 * 0 3 0
diff --git a/gemrb/override/iwd2/soflamh.pro b/gemrb/unhardcoded/iwd2/soflamh.pro
similarity index 100%
rename from gemrb/override/iwd2/soflamh.pro
rename to gemrb/unhardcoded/iwd2/soflamh.pro
diff --git a/gemrb/override/iwd2/sohope.pro b/gemrb/unhardcoded/iwd2/sohope.pro
similarity index 100%
rename from gemrb/override/iwd2/sohope.pro
rename to gemrb/unhardcoded/iwd2/sohope.pro
diff --git a/gemrb/override/iwd2/sooneh.pro b/gemrb/unhardcoded/iwd2/sooneh.pro
similarity index 100%
rename from gemrb/override/iwd2/sooneh.pro
rename to gemrb/unhardcoded/iwd2/sooneh.pro
diff --git a/gemrb/override/iwd2/sopain.pro b/gemrb/unhardcoded/iwd2/sopain.pro
similarity index 100%
rename from gemrb/override/iwd2/sopain.pro
rename to gemrb/unhardcoded/iwd2/sopain.pro
diff --git a/gemrb/override/iwd2/sparbknp.pro b/gemrb/unhardcoded/iwd2/sparbknp.pro
similarity index 100%
rename from gemrb/override/iwd2/sparbknp.pro
rename to gemrb/unhardcoded/iwd2/sparbknp.pro
diff --git a/gemrb/override/iwd2/sparbkpa.pro b/gemrb/unhardcoded/iwd2/sparbkpa.pro
similarity index 100%
rename from gemrb/override/iwd2/sparbkpa.pro
rename to gemrb/unhardcoded/iwd2/sparbkpa.pro
diff --git a/gemrb/override/iwd2/sparblnp.pro b/gemrb/unhardcoded/iwd2/sparblnp.pro
similarity index 100%
rename from gemrb/override/iwd2/sparblnp.pro
rename to gemrb/unhardcoded/iwd2/sparblnp.pro
diff --git a/gemrb/override/iwd2/sparblpa.pro b/gemrb/unhardcoded/iwd2/sparblpa.pro
similarity index 100%
rename from gemrb/override/iwd2/sparblpa.pro
rename to gemrb/unhardcoded/iwd2/sparblpa.pro
diff --git a/gemrb/override/iwd2/sparchnp.pro b/gemrb/unhardcoded/iwd2/sparchnp.pro
similarity index 100%
rename from gemrb/override/iwd2/sparchnp.pro
rename to gemrb/unhardcoded/iwd2/sparchnp.pro
diff --git a/gemrb/override/iwd2/sparchpa.pro b/gemrb/unhardcoded/iwd2/sparchpa.pro
similarity index 100%
rename from gemrb/override/iwd2/sparchpa.pro
rename to gemrb/unhardcoded/iwd2/sparchpa.pro
diff --git a/gemrb/override/iwd2/spargonp.pro b/gemrb/unhardcoded/iwd2/spargonp.pro
similarity index 100%
rename from gemrb/override/iwd2/spargonp.pro
rename to gemrb/unhardcoded/iwd2/spargonp.pro
diff --git a/gemrb/override/iwd2/spargopa.pro b/gemrb/unhardcoded/iwd2/spargopa.pro
similarity index 100%
rename from gemrb/override/iwd2/spargopa.pro
rename to gemrb/unhardcoded/iwd2/spargopa.pro
diff --git a/gemrb/override/iwd2/spargrnp.pro b/gemrb/unhardcoded/iwd2/spargrnp.pro
similarity index 100%
rename from gemrb/override/iwd2/spargrnp.pro
rename to gemrb/unhardcoded/iwd2/spargrnp.pro
diff --git a/gemrb/override/iwd2/spargrpa.pro b/gemrb/unhardcoded/iwd2/spargrpa.pro
similarity index 100%
rename from gemrb/override/iwd2/spargrpa.pro
rename to gemrb/unhardcoded/iwd2/spargrpa.pro
diff --git a/gemrb/override/iwd2/sparicnp.pro b/gemrb/unhardcoded/iwd2/sparicnp.pro
similarity index 100%
rename from gemrb/override/iwd2/sparicnp.pro
rename to gemrb/unhardcoded/iwd2/sparicnp.pro
diff --git a/gemrb/override/iwd2/sparicpa.pro b/gemrb/unhardcoded/iwd2/sparicpa.pro
similarity index 100%
rename from gemrb/override/iwd2/sparicpa.pro
rename to gemrb/unhardcoded/iwd2/sparicpa.pro
diff --git a/gemrb/override/iwd2/sparklbk.pro b/gemrb/unhardcoded/iwd2/sparklbk.pro
similarity index 100%
rename from gemrb/override/iwd2/sparklbk.pro
rename to gemrb/unhardcoded/iwd2/sparklbk.pro
diff --git a/gemrb/override/iwd2/sparklbl.pro b/gemrb/unhardcoded/iwd2/sparklbl.pro
similarity index 100%
rename from gemrb/override/iwd2/sparklbl.pro
rename to gemrb/unhardcoded/iwd2/sparklbl.pro
diff --git a/gemrb/override/iwd2/sparklch.pro b/gemrb/unhardcoded/iwd2/sparklch.pro
similarity index 100%
rename from gemrb/override/iwd2/sparklch.pro
rename to gemrb/unhardcoded/iwd2/sparklch.pro
diff --git a/gemrb/override/iwd2/sparklgo.pro b/gemrb/unhardcoded/iwd2/sparklgo.pro
similarity index 100%
rename from gemrb/override/iwd2/sparklgo.pro
rename to gemrb/unhardcoded/iwd2/sparklgo.pro
diff --git a/gemrb/override/iwd2/sparklgr.pro b/gemrb/unhardcoded/iwd2/sparklgr.pro
similarity index 100%
rename from gemrb/override/iwd2/sparklgr.pro
rename to gemrb/unhardcoded/iwd2/sparklgr.pro
diff --git a/gemrb/override/iwd2/sparklic.pro b/gemrb/unhardcoded/iwd2/sparklic.pro
similarity index 100%
rename from gemrb/override/iwd2/sparklic.pro
rename to gemrb/unhardcoded/iwd2/sparklic.pro
diff --git a/gemrb/override/iwd2/sparklma.pro b/gemrb/unhardcoded/iwd2/sparklma.pro
similarity index 100%
rename from gemrb/override/iwd2/sparklma.pro
rename to gemrb/unhardcoded/iwd2/sparklma.pro
diff --git a/gemrb/override/iwd2/sparklor.pro b/gemrb/unhardcoded/iwd2/sparklor.pro
similarity index 100%
rename from gemrb/override/iwd2/sparklor.pro
rename to gemrb/unhardcoded/iwd2/sparklor.pro
diff --git a/gemrb/override/iwd2/sparklpu.pro b/gemrb/unhardcoded/iwd2/sparklpu.pro
similarity index 100%
rename from gemrb/override/iwd2/sparklpu.pro
rename to gemrb/unhardcoded/iwd2/sparklpu.pro
diff --git a/gemrb/override/iwd2/sparklre.pro b/gemrb/unhardcoded/iwd2/sparklre.pro
similarity index 100%
rename from gemrb/override/iwd2/sparklre.pro
rename to gemrb/unhardcoded/iwd2/sparklre.pro
diff --git a/gemrb/override/iwd2/sparklst.pro b/gemrb/unhardcoded/iwd2/sparklst.pro
similarity index 100%
rename from gemrb/override/iwd2/sparklst.pro
rename to gemrb/unhardcoded/iwd2/sparklst.pro
diff --git a/gemrb/override/iwd2/sparmanp.pro b/gemrb/unhardcoded/iwd2/sparmanp.pro
similarity index 100%
rename from gemrb/override/iwd2/sparmanp.pro
rename to gemrb/unhardcoded/iwd2/sparmanp.pro
diff --git a/gemrb/override/iwd2/sparmapa.pro b/gemrb/unhardcoded/iwd2/sparmapa.pro
similarity index 100%
rename from gemrb/override/iwd2/sparmapa.pro
rename to gemrb/unhardcoded/iwd2/sparmapa.pro
diff --git a/gemrb/override/iwd2/sparornp.pro b/gemrb/unhardcoded/iwd2/sparornp.pro
similarity index 100%
rename from gemrb/override/iwd2/sparornp.pro
rename to gemrb/unhardcoded/iwd2/sparornp.pro
diff --git a/gemrb/override/iwd2/sparorpa.pro b/gemrb/unhardcoded/iwd2/sparorpa.pro
similarity index 100%
rename from gemrb/override/iwd2/sparorpa.pro
rename to gemrb/unhardcoded/iwd2/sparorpa.pro
diff --git a/gemrb/override/iwd2/sparpunp.pro b/gemrb/unhardcoded/iwd2/sparpunp.pro
similarity index 100%
rename from gemrb/override/iwd2/sparpunp.pro
rename to gemrb/unhardcoded/iwd2/sparpunp.pro
diff --git a/gemrb/override/iwd2/sparpupa.pro b/gemrb/unhardcoded/iwd2/sparpupa.pro
similarity index 100%
rename from gemrb/override/iwd2/sparpupa.pro
rename to gemrb/unhardcoded/iwd2/sparpupa.pro
diff --git a/gemrb/override/iwd2/sparrenp.pro b/gemrb/unhardcoded/iwd2/sparrenp.pro
similarity index 100%
rename from gemrb/override/iwd2/sparrenp.pro
rename to gemrb/unhardcoded/iwd2/sparrenp.pro
diff --git a/gemrb/override/iwd2/sparrepa.pro b/gemrb/unhardcoded/iwd2/sparrepa.pro
similarity index 100%
rename from gemrb/override/iwd2/sparrepa.pro
rename to gemrb/unhardcoded/iwd2/sparrepa.pro
diff --git a/gemrb/override/iwd2/sparstnp.pro b/gemrb/unhardcoded/iwd2/sparstnp.pro
similarity index 100%
rename from gemrb/override/iwd2/sparstnp.pro
rename to gemrb/unhardcoded/iwd2/sparstnp.pro
diff --git a/gemrb/override/iwd2/sparstpa.pro b/gemrb/unhardcoded/iwd2/sparstpa.pro
similarity index 100%
rename from gemrb/override/iwd2/sparstpa.pro
rename to gemrb/unhardcoded/iwd2/sparstpa.pro
diff --git a/gemrb/override/iwd2/spbrnhnd.pro b/gemrb/unhardcoded/iwd2/spbrnhnd.pro
similarity index 100%
rename from gemrb/override/iwd2/spbrnhnd.pro
rename to gemrb/unhardcoded/iwd2/spbrnhnd.pro
diff --git a/gemrb/override/iwd2/spear.pro b/gemrb/unhardcoded/iwd2/spear.pro
similarity index 100%
rename from gemrb/override/iwd2/spear.pro
rename to gemrb/unhardcoded/iwd2/spear.pro
diff --git a/gemrb/override/iwd2/spearex.pro b/gemrb/unhardcoded/iwd2/spearex.pro
similarity index 100%
rename from gemrb/override/iwd2/spearex.pro
rename to gemrb/unhardcoded/iwd2/spearex.pro
diff --git a/gemrb/override/iwd2/spfdeath.pro b/gemrb/unhardcoded/iwd2/spfdeath.pro
similarity index 100%
rename from gemrb/override/iwd2/spfdeath.pro
rename to gemrb/unhardcoded/iwd2/spfdeath.pro
diff --git a/gemrb/override/iwd2/spfirebl.pro b/gemrb/unhardcoded/iwd2/spfirebl.pro
similarity index 100%
rename from gemrb/override/iwd2/spfirebl.pro
rename to gemrb/unhardcoded/iwd2/spfirebl.pro
diff --git a/gemrb/unhardcoded/iwd2/spin231r.spl b/gemrb/unhardcoded/iwd2/spin231r.spl
new file mode 100644
index 0000000..8a1e6fa
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/spin231r.spl differ
diff --git a/gemrb/unhardcoded/iwd2/spin232r.spl b/gemrb/unhardcoded/iwd2/spin232r.spl
new file mode 100644
index 0000000..984ff7c
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/spin232r.spl differ
diff --git a/gemrb/unhardcoded/iwd2/spin233r.spl b/gemrb/unhardcoded/iwd2/spin233r.spl
new file mode 100644
index 0000000..cdecdf1
Binary files /dev/null and b/gemrb/unhardcoded/iwd2/spin233r.spl differ
diff --git a/gemrb/override/iwd2/spklarbk.pro b/gemrb/unhardcoded/iwd2/spklarbk.pro
similarity index 100%
rename from gemrb/override/iwd2/spklarbk.pro
rename to gemrb/unhardcoded/iwd2/spklarbk.pro
diff --git a/gemrb/override/iwd2/spklarbl.pro b/gemrb/unhardcoded/iwd2/spklarbl.pro
similarity index 100%
rename from gemrb/override/iwd2/spklarbl.pro
rename to gemrb/unhardcoded/iwd2/spklarbl.pro
diff --git a/gemrb/override/iwd2/spklarch.pro b/gemrb/unhardcoded/iwd2/spklarch.pro
similarity index 100%
rename from gemrb/override/iwd2/spklarch.pro
rename to gemrb/unhardcoded/iwd2/spklarch.pro
diff --git a/gemrb/override/iwd2/spklargo.pro b/gemrb/unhardcoded/iwd2/spklargo.pro
similarity index 100%
rename from gemrb/override/iwd2/spklargo.pro
rename to gemrb/unhardcoded/iwd2/spklargo.pro
diff --git a/gemrb/override/iwd2/spklargr.pro b/gemrb/unhardcoded/iwd2/spklargr.pro
similarity index 100%
rename from gemrb/override/iwd2/spklargr.pro
rename to gemrb/unhardcoded/iwd2/spklargr.pro
diff --git a/gemrb/override/iwd2/spklaric.pro b/gemrb/unhardcoded/iwd2/spklaric.pro
similarity index 100%
rename from gemrb/override/iwd2/spklaric.pro
rename to gemrb/unhardcoded/iwd2/spklaric.pro
diff --git a/gemrb/override/iwd2/spklarma.pro b/gemrb/unhardcoded/iwd2/spklarma.pro
similarity index 100%
rename from gemrb/override/iwd2/spklarma.pro
rename to gemrb/unhardcoded/iwd2/spklarma.pro
diff --git a/gemrb/override/iwd2/spklaror.pro b/gemrb/unhardcoded/iwd2/spklaror.pro
similarity index 100%
rename from gemrb/override/iwd2/spklaror.pro
rename to gemrb/unhardcoded/iwd2/spklaror.pro
diff --git a/gemrb/override/iwd2/spklarpu.pro b/gemrb/unhardcoded/iwd2/spklarpu.pro
similarity index 100%
rename from gemrb/override/iwd2/spklarpu.pro
rename to gemrb/unhardcoded/iwd2/spklarpu.pro
diff --git a/gemrb/override/iwd2/spklarre.pro b/gemrb/unhardcoded/iwd2/spklarre.pro
similarity index 100%
rename from gemrb/override/iwd2/spklarre.pro
rename to gemrb/unhardcoded/iwd2/spklarre.pro
diff --git a/gemrb/override/iwd2/spklarst.pro b/gemrb/unhardcoded/iwd2/spklarst.pro
similarity index 100%
rename from gemrb/override/iwd2/spklarst.pro
rename to gemrb/unhardcoded/iwd2/spklarst.pro
diff --git a/gemrb/unhardcoded/iwd2/splfocus.2da b/gemrb/unhardcoded/iwd2/splfocus.2da
new file mode 100644
index 0000000..2aca389
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/splfocus.2da
@@ -0,0 +1,12 @@
+2DA V1.0
+0
+ STAT SLOT1 SLOT2
+NONE * 2 4
+ABJURER * 2 4
+CONJURER * 2 4
+DIVINER * 2 4
+ENCHANTER FEAT_ENCHANTMENT 2 4
+ILLUSIONIST * 2 4
+EVOKER FEAT_EVOCATION 2 4
+NECROMANCER FEAT_NECROMANCY 2 4
+TRANSMUTER FEAT_TRANSMUTE 2 4
diff --git a/gemrb/unhardcoded/iwd2/splprot.2da b/gemrb/unhardcoded/iwd2/splprot.2da
new file mode 100644
index 0000000..b38e08a
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/splprot.2da
@@ -0,0 +1,105 @@
+2DA V1.0
+0
+ STAT VALUE RELATION COMMENT
+0 EA 0 4 anything
+1 GENERAL 4 1 general/undead
+2 GENERAL 4 5 general/not_undead
+3 RESISTFIRE 100 4 fire_resistance>=100
+4 RESISTFIRE 100 2 fire_resistance<100
+5 GENERAL 1 1 general/humanoid
+6 GENERAL 1 5 general/not_humanoid
+7 GENERAL 2 1 general/animal
+8 GENERAL 2 5 general/not_animal
+9 RACE 152 1 race/elemental
+10 RACE 152 5 race/not_elemental
+11 RACE 159 1 race/fungus
+12 RACE 159 5 race/not_fungus
+13 0x102 3 0 huge_creature
+14 0x102 3 3 not_huge_creature
+15 RACE 2 1 race/elf
+16 RACE 2 5 race/not_elf
+17 RACE 166 1 race/umberhulk
+18 RACE 166 5 race/not_umberhulk
+19 RACE 3 1 race/halfelf
+20 RACE 3 5 race/not_halfelf
+21 0x103 5 7 humanoid_or_animal
+22 0x104 5 7 not_humanoid_or_animal
+23 STATE 0x40000 9 state/blind
+24 STATE 0x40000 8 state/not_blind
+25 RESISTCOLD 100 4 cold_resistance>=100
+26 RESISTCOLD 100 2 cold_resistance<100
+27 RACE 156 1 race/golem
+28 RACE 156 5 race/not_golem
+29 RACE 179 1 race/minotaur
+30 RACE 179 5 race/not_minotaur
+31 0x103 1 11 undead_or_fungus
+32 0x104 1 11 not_undead_or_fungus
+33 ALIGNMENT 2 9 alignment/good
+34 ALIGNMENT 2 8 alignment/not_good
+35 ALIGNMENT 1 9 alignment/neutral
+36 ALIGNMENT 1 8 alignment/not_neutral
+37 ALIGNMENT 3 7 alignment/evil
+38 ALIGNMENT 3 11 alignment/not_evil
+39 CLASS 7 1 class/paladin
+40 CLASS 7 5 class/not_paladin
+41 0x105 217 1 moral_alignment_same
+42 0x105 217 5 moral_alignment_not_same
+43 0x100 * * source
+44 0x101 * * not_source
+45 ? * * water_using-FIXME
+46 ? * * not_water_using-FIXME
+47 0x104 32 27 breathes/not_undead_fungus_golem
+48 0x103 32 27 not_breathes/undead_fungus_or_golem
+49 EA 30 0 allies
+50 EA 30 3 not_allies
+51 EA 200 4 enemies
+52 EA 200 2 not_enemies
+53 0x103 3 25 race/fire_or_cold_using
+54 0x104 3 25 race/not_fire_or_cold_using
+55 ? * * unnatural
+56 ? * * not_unnatural
+57 SEX 1 1 gender/male
+58 SEX 1 5 gender/not_male
+59 ALIGNMENT 0x10 1 alignment/lawful
+60 ALIGNMENT 0x10 5 alignment/not_lawful
+61 ALIGNMENT 0x30 1 alignment/chaotic
+62 ALIGNMENT 0x30 5 alignment/not_chaotic
+63 ? * * evasion_check
+64 RACE 160 1 race/orc
+65 RACE 160 5 race/not_orc
+66 EXTSTATE ? 9 extstate/deaf
+67 EXTSTATE ? 8 extstate/not_deaf
+68 SEX 6 1 gender/summoned
+69 SEX 6 5 gender/not_summoned
+70 RACE 184 1 race/mindflayer
+71 RACE 184 5 race/not_mindflayer
+72 STATE 0x1000 9 state/silenced
+73 STATE 0x1000 8 state/not_silenced
+74 INT -1 4 int/less
+75 INT -1 0 int/greater
+76 INT -1 3 int/less_or_equal
+77 INT -1 2 int/greater_or_equal
+78 CLASS 2 1 class/bard
+79 CLASS 2 5 class/not_bard
+80 0x108 1 * near_enemies
+81 0x108 0 * not_near_enemies
+82 SUBRACE 0x20001 1 subrace/drow
+83 SUBRACE 0x20001 5 subrace/not_drow
+84 SUBRACE 0x40002 1 subrace/gray_dwarf
+85 SUBRACE 0x40002 5 subrace/not_gray_dwarf
+86 0x107 0 0 daytime
+87 0x107 1 3 not_daytime
+88 0x106 1 8 outdoor
+89 0x106 1 9 not_outdoor
+90 RACE 190 1 race/keg
+91 RACE 190 5 race/not_keg
+92 RACE * * outsider
+93 RACE * * not_outsider
+94 RACE 215 1 race/plate
+95 RACE 215 5 race/not_plate
+96 0x103 90 94 race/keg_or_plate
+97 0x104 90 94 race/not_keg_or_plate
+98 RACE 161 1 race/salamander
+99 RACE 161 5 race/not_salamander
+100 RACE 164 1 race/tanari
+101 RACE 164 5 race/not_tanari
diff --git a/gemrb/override/iwd2/splspec.2da b/gemrb/unhardcoded/iwd2/splspec.2da
similarity index 100%
rename from gemrb/override/iwd2/splspec.2da
rename to gemrb/unhardcoded/iwd2/splspec.2da
diff --git a/gemrb/override/iwd2/spoisoh.pro b/gemrb/unhardcoded/iwd2/spoisoh.pro
similarity index 100%
rename from gemrb/override/iwd2/spoisoh.pro
rename to gemrb/unhardcoded/iwd2/spoisoh.pro
diff --git a/gemrb/override/iwd2/spscorch.pro b/gemrb/unhardcoded/iwd2/spscorch.pro
similarity index 100%
rename from gemrb/override/iwd2/spscorch.pro
rename to gemrb/unhardcoded/iwd2/spscorch.pro
diff --git a/gemrb/override/iwd2/spscoric.pro b/gemrb/unhardcoded/iwd2/spscoric.pro
similarity index 100%
rename from gemrb/override/iwd2/spscoric.pro
rename to gemrb/unhardcoded/iwd2/spscoric.pro
diff --git a/gemrb/override/iwd2/spwrath.pro b/gemrb/unhardcoded/iwd2/spwrath.pro
similarity index 100%
rename from gemrb/override/iwd2/spwrath.pro
rename to gemrb/unhardcoded/iwd2/spwrath.pro
diff --git a/gemrb/override/iwd2/ssorbh.pro b/gemrb/unhardcoded/iwd2/ssorbh.pro
similarity index 100%
rename from gemrb/override/iwd2/ssorbh.pro
rename to gemrb/unhardcoded/iwd2/ssorbh.pro
diff --git a/gemrb/override/iwd2/ssswarm.pro b/gemrb/unhardcoded/iwd2/ssswarm.pro
similarity index 100%
rename from gemrb/override/iwd2/ssswarm.pro
rename to gemrb/unhardcoded/iwd2/ssswarm.pro
diff --git a/gemrb/override/iwd2/sstone.pro b/gemrb/unhardcoded/iwd2/sstone.pro
similarity index 100%
rename from gemrb/override/iwd2/sstone.pro
rename to gemrb/unhardcoded/iwd2/sstone.pro
diff --git a/gemrb/override/iwd2/sstoneh.pro b/gemrb/unhardcoded/iwd2/sstoneh.pro
similarity index 100%
rename from gemrb/override/iwd2/sstoneh.pro
rename to gemrb/unhardcoded/iwd2/sstoneh.pro
diff --git a/gemrb/override/iwd2/start.2da b/gemrb/unhardcoded/iwd2/start.2da
similarity index 100%
rename from gemrb/override/iwd2/start.2da
rename to gemrb/unhardcoded/iwd2/start.2da
diff --git a/gemrb/override/iwd2/stone.pro b/gemrb/unhardcoded/iwd2/stone.pro
similarity index 100%
rename from gemrb/override/iwd2/stone.pro
rename to gemrb/unhardcoded/iwd2/stone.pro
diff --git a/gemrb/override/iwd2/strengh.pro b/gemrb/unhardcoded/iwd2/strengh.pro
similarity index 100%
rename from gemrb/override/iwd2/strengh.pro
rename to gemrb/unhardcoded/iwd2/strengh.pro
diff --git a/gemrb/unhardcoded/iwd2/strings.2da b/gemrb/unhardcoded/iwd2/strings.2da
new file mode 100644
index 0000000..f15bca5
--- /dev/null
+++ b/gemrb/unhardcoded/iwd2/strings.2da
@@ -0,0 +1,187 @@
+2DA V1.0
+-1
+ STRREF
+SCATTERED 16457
+WHOLEPARTY 16484
+DOORLOCKED 16485
+MAGICTRAP 16486
+NORMALTRAP 16487
+TRAP 16488
+CANNOTGO 16489
+TRAPREMOVED 16490
+OVERSTOCKED 16491
+SLEEP 16492
+AMBUSH 16493
+CONTLOCKED 16494
+NOMONEY 16495
+CURSED 16304
+SPELLDISRUPT 16497
+DIED 16498
+MAYNOTREST 16499
+CANTRESTMONS 16500
+CANTSAVEMONS 16501
+CANTSAVE 16502
+NODIALOG 10945
+CANTSAVEDIALOG 19253
+CANTSAVEDIALOG2 19254
+CANTSAVEMOVIE 19255
+TARGETBUSY -1
+CANTTALKTRANS -1
+GOTGOLD 17572
+LOSTGOLD 17573
+GOTXP 17574
+LOSTXP 17575
+GOTITEM 17576
+LOSTITEM 17577
+GOTREP 19686
+LOSTREP 19687
+GOTABILITY 10514
+GOTSPELL 10514
+GOTSONG 26320
+NOTHINGTOSAY -1
+JOURNALCHANGE 11359
+WORLDMAPCHANGE 11360
+PAUSED 16321
+UNPAUSED 16322
+SCRIPTPAUSED 7666
+AP_UNUSABLE 17113
+AP_ATTACKED 17114
+AP_HIT 17115
+AP_WOUNDED 17116
+AP_DEAD 17117
+AP_NOTARGET 17118
+AP_ENDROUND 10014
+AP_ENEMY 23511
+AP_TRAP -1
+AP_SPELLCAST -1
+AP_GENERIC 17166
+AP_RESERVED1 -1
+AP_RESERVED2 -1
+AP_RESERVED3 -1
+CHARMED 14672
+DIRECHARMED 14780
+CONTROLLED -1
+EVIL 16505
+GNE_NEUTRAL 16504
+GOOD 16503
+STR_LAWFUL -1
+LNC_NEUTRAL -1
+CHAOTIC -1
+ACTION_CAST 16464
+ACTION_ATTACK 16465
+ACTION_TURN 16466
+ACTION_SONG 16467
+ACTION_FINDTRAP 16468
+MAGICWEAPON 10141
+OFFHAND_USED 9380
+TWOHANDED_USED 9381
+CANNOT_USE_ITEM 9382
+CANT_DROP_ITEM 25697
+NOT_IN_OFFHAND 26342
+ITEM_IS_CURSED 16304
+NO_CRITICAL 20696
+TRACKING -1
+TRACKINGFAILED 19534
+DOOR_NOPICK 23169
+CONT_NOPICK 23169
+CANTSAVECOMBAT -1
+CANTSAVENOCTRL -1
+LOCKPICK_DONE 16517
+LOCKPICK_FAILED 16518
+STATIC_DISSIPATE 26518
+LIGHTNING_DISSIPATE 41008
+HAS_NO_ABILITY 17317
+NEEDS_IDENTIFY 17316
+WRONG_ITEMTYPE 9375
+HAS_ITEMEXCL 20685
+PICKPOCKET_DONE 10072
+PICKPOCKET_NONE 18297
+PICKPOCKET_FAIL 10069
+PICKPOCKET_EVIL 10068
+PICKPOCKET_ARMOR 10067
+USING_FEAT 39823
+STOPPED_FEAT 39853
+DISARM_DONE 16520
+DISARM_FAIL 1608
+DOORBASH_DONE 9915
+DOORBASH_FAIL 9913
+CONTBASH_DONE 9916
+CONTBASH_FAIL 9914
+MAYNOTSETTRAP -1
+SNAREFAILED -1
+SNARESUCCEED -1
+NOMORETRAP -1
+DISABLEDMAGE -1
+SAVESUCCEED 1682
+QSAVESUCCEED 10237
+UNINJURED 2943
+INJURED1 2944
+INJURED2 2945
+INJURED3 2946
+INJURED4 2947
+HOURS 10700
+HOUR 10701
+DAYS 10697
+DAY 10698
+REST 10690
+JOURNEY 10689
+SUMMONINGLIMIT -1
+INVFULL 17999
+TOOFARAWAY 18002
+DAMAGE_IMMUNITY 25038
+DAMAGE_STR1 25028
+DAMAGE_STR2 25017
+DAMAGE_STR3 26223
+DMG_POISON 25018
+DMG_MAGIC 25019
+DMG_MISSILE 25020
+DMG_SLASHING 25021
+DMG_PIERCING 25022
+DMG_CRUSHING 25023
+DMG_FIRE 25024
+DMG_ELECTRIC 25025
+DMG_COLD 25026
+DMG_ACID 25027
+DMG_OTHER 0
+GOTQUESTXP -1
+LEVELUP 17119
+INVFULL_ITEMDROP 32879
+CONT_DUP 32876
+CONT_TRIG -1
+CONT_FAIL -1
+SEQ_DUP -1
+CRITICAL_HIT 16462
+CRITICAL_MISS 16463
+DEATH 14026
+BACKSTAB 12128
+BACKSTAB_BAD 10013
+BACKSTAB_FAIL 121
+CASTER_LVL_INC -1
+CASTER_LVL_DEC -1
+CHARS_EXPORTED 26827
+PALADIN_FALL 19620
+RANGER_FALL 19621
+RES_RESISTED 26818
+DEADMAGIC_FAIL -1
+MISCASTMAGIC -1
+WILDSURGE -1
+FAMBLOCK 8537
+FAMPROTAGONIST 8538
+MAGIC_RESISTED 19224
+CANTSAVESTORE 10841
+NOSEE_NOCAST -1
+AURACLEANSED 23797
+INDOOR_FAIL 9744
+SPELL_DISRUPTED 14796
+CHAOSSHIELD -1
+RAPIDSHOT 35796
+HAMSTRING 35787
+ARTERIAL 35774
+EXPERTISE 35785
+POWERATTACK 35794
+CLEAVE 39846
+HELD 14102
+SLOWED 19503
+CANTMOVE 19504
+CASTS 16464
+WEAPONINEFFECTIVE -1
diff --git a/gemrb/override/iwd2/suffoc.pro b/gemrb/unhardcoded/iwd2/suffoc.pro
similarity index 100%
rename from gemrb/override/iwd2/suffoc.pro
rename to gemrb/unhardcoded/iwd2/suffoc.pro
diff --git a/gemrb/override/iwd2/suffoch.pro b/gemrb/unhardcoded/iwd2/suffoch.pro
similarity index 100%
rename from gemrb/override/iwd2/suffoch.pro
rename to gemrb/unhardcoded/iwd2/suffoch.pro
diff --git a/gemrb/override/iwd2/sunfire.pro b/gemrb/unhardcoded/iwd2/sunfire.pro
similarity index 100%
rename from gemrb/override/iwd2/sunfire.pro
rename to gemrb/unhardcoded/iwd2/sunfire.pro
diff --git a/gemrb/override/iwd2/sunray.pro b/gemrb/unhardcoded/iwd2/sunray.pro
similarity index 100%
rename from gemrb/override/iwd2/sunray.pro
rename to gemrb/unhardcoded/iwd2/sunray.pro
diff --git a/gemrb/override/iwd2/sunscoh.pro b/gemrb/unhardcoded/iwd2/sunscoh.pro
similarity index 100%
rename from gemrb/override/iwd2/sunscoh.pro
rename to gemrb/unhardcoded/iwd2/sunscoh.pro
diff --git a/gemrb/override/iwd2/swave.pro b/gemrb/unhardcoded/iwd2/swave.pro
similarity index 100%
rename from gemrb/override/iwd2/swave.pro
rename to gemrb/unhardcoded/iwd2/swave.pro
diff --git a/gemrb/override/iwd2/swaveh.pro b/gemrb/unhardcoded/iwd2/swaveh.pro
similarity index 100%
rename from gemrb/override/iwd2/swaveh.pro
rename to gemrb/unhardcoded/iwd2/swaveh.pro
diff --git a/gemrb/override/iwd2/topics.2da b/gemrb/unhardcoded/iwd2/topics.2da
similarity index 100%
rename from gemrb/override/iwd2/topics.2da
rename to gemrb/unhardcoded/iwd2/topics.2da
diff --git a/gemrb/override/iwd2/trap.pro b/gemrb/unhardcoded/iwd2/trap.pro
similarity index 100%
rename from gemrb/override/iwd2/trap.pro
rename to gemrb/unhardcoded/iwd2/trap.pro
diff --git a/gemrb/override/iwd2/trapglyp.pro b/gemrb/unhardcoded/iwd2/trapglyp.pro
similarity index 100%
rename from gemrb/override/iwd2/trapglyp.pro
rename to gemrb/unhardcoded/iwd2/trapglyp.pro
diff --git a/gemrb/override/iwd2/trapskul.pro b/gemrb/unhardcoded/iwd2/trapskul.pro
similarity index 100%
rename from gemrb/override/iwd2/trapskul.pro
rename to gemrb/unhardcoded/iwd2/trapskul.pro
diff --git a/gemrb/override/iwd2/tspray.pro b/gemrb/unhardcoded/iwd2/tspray.pro
similarity index 100%
rename from gemrb/override/iwd2/tspray.pro
rename to gemrb/unhardcoded/iwd2/tspray.pro
diff --git a/gemrb/override/iwd2/turn.spl b/gemrb/unhardcoded/iwd2/turn.spl
similarity index 100%
rename from gemrb/override/iwd2/turn.spl
rename to gemrb/unhardcoded/iwd2/turn.spl
diff --git a/gemrb/override/iwd2/ublight.pro b/gemrb/unhardcoded/iwd2/ublight.pro
similarity index 100%
rename from gemrb/override/iwd2/ublight.pro
rename to gemrb/unhardcoded/iwd2/ublight.pro
diff --git a/gemrb/override/iwd2/uhold.pro b/gemrb/unhardcoded/iwd2/uhold.pro
similarity index 100%
rename from gemrb/override/iwd2/uhold.pro
rename to gemrb/unhardcoded/iwd2/uhold.pro
diff --git a/gemrb/override/iwd2/uward.pro b/gemrb/unhardcoded/iwd2/uward.pro
similarity index 100%
rename from gemrb/override/iwd2/uward.pro
rename to gemrb/unhardcoded/iwd2/uward.pro
diff --git a/gemrb/override/iwd2/uwardh.pro b/gemrb/unhardcoded/iwd2/uwardh.pro
similarity index 100%
rename from gemrb/override/iwd2/uwardh.pro
rename to gemrb/unhardcoded/iwd2/uwardh.pro
diff --git a/gemrb/override/iwd2/vspherh.pro b/gemrb/unhardcoded/iwd2/vspherh.pro
similarity index 100%
rename from gemrb/override/iwd2/vspherh.pro
rename to gemrb/unhardcoded/iwd2/vspherh.pro
diff --git a/gemrb/override/iwd2/wdeath1.pro b/gemrb/unhardcoded/iwd2/wdeath1.pro
similarity index 100%
rename from gemrb/override/iwd2/wdeath1.pro
rename to gemrb/unhardcoded/iwd2/wdeath1.pro
diff --git a/gemrb/override/iwd2/wdeath2.pro b/gemrb/unhardcoded/iwd2/wdeath2.pro
similarity index 100%
rename from gemrb/override/iwd2/wdeath2.pro
rename to gemrb/unhardcoded/iwd2/wdeath2.pro
diff --git a/gemrb/override/iwd2/web.pro b/gemrb/unhardcoded/iwd2/web.pro
similarity index 100%
rename from gemrb/override/iwd2/web.pro
rename to gemrb/unhardcoded/iwd2/web.pro
diff --git a/gemrb/override/iwd2/whirlw.pro b/gemrb/unhardcoded/iwd2/whirlw.pro
similarity index 100%
rename from gemrb/override/iwd2/whirlw.pro
rename to gemrb/unhardcoded/iwd2/whirlw.pro
diff --git a/gemrb/override/iwd2/wofire.pro b/gemrb/unhardcoded/iwd2/wofire.pro
similarity index 100%
rename from gemrb/override/iwd2/wofire.pro
rename to gemrb/unhardcoded/iwd2/wofire.pro
diff --git a/gemrb/override/iwd2/womoon.pro b/gemrb/unhardcoded/iwd2/womoon.pro
similarity index 100%
rename from gemrb/override/iwd2/womoon.pro
rename to gemrb/unhardcoded/iwd2/womoon.pro
diff --git a/gemrb/override/iwd2/womoonx.pro b/gemrb/unhardcoded/iwd2/womoonx.pro
similarity index 100%
rename from gemrb/override/iwd2/womoonx.pro
rename to gemrb/unhardcoded/iwd2/womoonx.pro
diff --git a/gemrb/override/iwd2/wowisp.pro b/gemrb/unhardcoded/iwd2/wowisp.pro
similarity index 100%
rename from gemrb/override/iwd2/wowisp.pro
rename to gemrb/unhardcoded/iwd2/wowisp.pro
diff --git a/gemrb/override/iwd2/wvdeath.pro b/gemrb/unhardcoded/iwd2/wvdeath.pro
similarity index 100%
rename from gemrb/override/iwd2/wvdeath.pro
rename to gemrb/unhardcoded/iwd2/wvdeath.pro
diff --git a/gemrb/override/iwd2/wvhith.pro b/gemrb/unhardcoded/iwd2/wvhith.pro
similarity index 100%
rename from gemrb/override/iwd2/wvhith.pro
rename to gemrb/unhardcoded/iwd2/wvhith.pro
diff --git a/gemrb/override/iwd2/wwolf.pro b/gemrb/unhardcoded/iwd2/wwolf.pro
similarity index 100%
rename from gemrb/override/iwd2/wwolf.pro
rename to gemrb/unhardcoded/iwd2/wwolf.pro
diff --git a/gemrb/override/iwd2/zlaura.pro b/gemrb/unhardcoded/iwd2/zlaura.pro
similarity index 100%
rename from gemrb/override/iwd2/zlaura.pro
rename to gemrb/unhardcoded/iwd2/zlaura.pro
diff --git a/gemrb/override/pst/MPALETTE.bmp b/gemrb/unhardcoded/pst/MPALETTE.bmp
similarity index 100%
rename from gemrb/override/pst/MPALETTE.bmp
rename to gemrb/unhardcoded/pst/MPALETTE.bmp
diff --git a/gemrb/unhardcoded/pst/Makefile.am b/gemrb/unhardcoded/pst/Makefile.am
new file mode 100644
index 0000000..87d2444
--- /dev/null
+++ b/gemrb/unhardcoded/pst/Makefile.am
@@ -0,0 +1,3 @@
+pstunhardcoded_DATA = *.2da *.bmp *.ini *.chu *.ids *.pro *.spl *.vvc *.mos *.eff
+pstunhardcodeddir = $(moddir)/unhardcoded/pst/
+EXTRA_DIST = *.2da *.bmp *.ini *.chu *.ids *.pro *.spl *.vvc *.mos *.eff
diff --git a/gemrb/override/pst/abcomm.2da b/gemrb/unhardcoded/pst/abcomm.2da
similarity index 100%
rename from gemrb/override/pst/abcomm.2da
rename to gemrb/unhardcoded/pst/abcomm.2da
diff --git a/gemrb/override/pst/acidblgr.pro b/gemrb/unhardcoded/pst/acidblgr.pro
similarity index 100%
rename from gemrb/override/pst/acidblgr.pro
rename to gemrb/unhardcoded/pst/acidblgr.pro
diff --git a/gemrb/override/pst/acidblmu.pro b/gemrb/unhardcoded/pst/acidblmu.pro
similarity index 100%
rename from gemrb/override/pst/acidblmu.pro
rename to gemrb/unhardcoded/pst/acidblmu.pro
diff --git a/gemrb/override/pst/acidblob.pro b/gemrb/unhardcoded/pst/acidblob.pro
similarity index 100%
rename from gemrb/override/pst/acidblob.pro
rename to gemrb/unhardcoded/pst/acidblob.pro
diff --git a/gemrb/override/pst/acidbloc.pro b/gemrb/unhardcoded/pst/acidbloc.pro
similarity index 100%
rename from gemrb/override/pst/acidbloc.pro
rename to gemrb/unhardcoded/pst/acidbloc.pro
diff --git a/gemrb/unhardcoded/pst/adder.spl b/gemrb/unhardcoded/pst/adder.spl
new file mode 100644
index 0000000..012185e
Binary files /dev/null and b/gemrb/unhardcoded/pst/adder.spl differ
diff --git a/gemrb/override/pst/aligns.2da b/gemrb/unhardcoded/pst/aligns.2da
similarity index 100%
rename from gemrb/override/pst/aligns.2da
rename to gemrb/unhardcoded/pst/aligns.2da
diff --git a/gemrb/override/pst/amiss.pro b/gemrb/unhardcoded/pst/amiss.pro
similarity index 100%
rename from gemrb/override/pst/amiss.pro
rename to gemrb/unhardcoded/pst/amiss.pro
diff --git a/gemrb/override/pst/amiss2.pro b/gemrb/unhardcoded/pst/amiss2.pro
similarity index 100%
rename from gemrb/override/pst/amiss2.pro
rename to gemrb/unhardcoded/pst/amiss2.pro
diff --git a/gemrb/override/pst/anims.2da b/gemrb/unhardcoded/pst/anims.2da
similarity index 100%
rename from gemrb/override/pst/anims.2da
rename to gemrb/unhardcoded/pst/anims.2da
diff --git a/gemrb/override/pst/aotorm.pro b/gemrb/unhardcoded/pst/aotorm.pro
similarity index 100%
rename from gemrb/override/pst/aotorm.pro
rename to gemrb/unhardcoded/pst/aotorm.pro
diff --git a/gemrb/override/pst/areapro.2da b/gemrb/unhardcoded/pst/areapro.2da
similarity index 100%
rename from gemrb/override/pst/areapro.2da
rename to gemrb/unhardcoded/pst/areapro.2da
diff --git a/gemrb/override/pst/arrow.pro b/gemrb/unhardcoded/pst/arrow.pro
similarity index 100%
rename from gemrb/override/pst/arrow.pro
rename to gemrb/unhardcoded/pst/arrow.pro
diff --git a/gemrb/override/pst/arrowex.pro b/gemrb/unhardcoded/pst/arrowex.pro
similarity index 100%
rename from gemrb/override/pst/arrowex.pro
rename to gemrb/unhardcoded/pst/arrowex.pro
diff --git a/gemrb/override/pst/arrowflb.pro b/gemrb/unhardcoded/pst/arrowflb.pro
similarity index 100%
rename from gemrb/override/pst/arrowflb.pro
rename to gemrb/unhardcoded/pst/arrowflb.pro
diff --git a/gemrb/override/pst/arrowflg.pro b/gemrb/unhardcoded/pst/arrowflg.pro
similarity index 100%
rename from gemrb/override/pst/arrowflg.pro
rename to gemrb/unhardcoded/pst/arrowflg.pro
diff --git a/gemrb/override/pst/arrowfli.pro b/gemrb/unhardcoded/pst/arrowfli.pro
similarity index 100%
rename from gemrb/override/pst/arrowfli.pro
rename to gemrb/unhardcoded/pst/arrowfli.pro
diff --git a/gemrb/override/pst/arrowflm.pro b/gemrb/unhardcoded/pst/arrowflm.pro
similarity index 100%
rename from gemrb/override/pst/arrowflm.pro
rename to gemrb/unhardcoded/pst/arrowflm.pro
diff --git a/gemrb/override/pst/arrowhvy.pro b/gemrb/unhardcoded/pst/arrowhvy.pro
similarity index 100%
rename from gemrb/override/pst/arrowhvy.pro
rename to gemrb/unhardcoded/pst/arrowhvy.pro
diff --git a/gemrb/override/pst/astorm.pro b/gemrb/unhardcoded/pst/astorm.pro
similarity index 100%
rename from gemrb/override/pst/astorm.pro
rename to gemrb/unhardcoded/pst/astorm.pro
diff --git a/gemrb/override/pst/astorm.spl b/gemrb/unhardcoded/pst/astorm.spl
similarity index 100%
rename from gemrb/override/pst/astorm.spl
rename to gemrb/unhardcoded/pst/astorm.spl
diff --git a/gemrb/override/pst/avatars.2da b/gemrb/unhardcoded/pst/avatars.2da
similarity index 100%
rename from gemrb/override/pst/avatars.2da
rename to gemrb/unhardcoded/pst/avatars.2da
diff --git a/gemrb/override/pst/avprefix.2da b/gemrb/unhardcoded/pst/avprefix.2da
similarity index 100%
rename from gemrb/override/pst/avprefix.2da
rename to gemrb/unhardcoded/pst/avprefix.2da
diff --git a/gemrb/override/pst/avslots.2da b/gemrb/unhardcoded/pst/avslots.2da
similarity index 100%
rename from gemrb/override/pst/avslots.2da
rename to gemrb/unhardcoded/pst/avslots.2da
diff --git a/gemrb/override/pst/axe.pro b/gemrb/unhardcoded/pst/axe.pro
similarity index 100%
rename from gemrb/override/pst/axe.pro
rename to gemrb/unhardcoded/pst/axe.pro
diff --git a/gemrb/override/pst/axeex.pro b/gemrb/unhardcoded/pst/axeex.pro
similarity index 100%
rename from gemrb/override/pst/axeex.pro
rename to gemrb/unhardcoded/pst/axeex.pro
diff --git a/gemrb/override/pst/axoft.spl b/gemrb/unhardcoded/pst/axoft.spl
similarity index 100%
rename from gemrb/override/pst/axoft.spl
rename to gemrb/unhardcoded/pst/axoft.spl
diff --git a/gemrb/unhardcoded/pst/ball.spl b/gemrb/unhardcoded/pst/ball.spl
new file mode 100644
index 0000000..dc8f87d
Binary files /dev/null and b/gemrb/unhardcoded/pst/ball.spl differ
diff --git a/gemrb/override/pst/bbridge.pro b/gemrb/unhardcoded/pst/bbridge.pro
similarity index 100%
rename from gemrb/override/pst/bbridge.pro
rename to gemrb/unhardcoded/pst/bbridge.pro
diff --git a/gemrb/override/pst/bbridge.spl b/gemrb/unhardcoded/pst/bbridge.spl
similarity index 100%
rename from gemrb/override/pst/bbridge.spl
rename to gemrb/unhardcoded/pst/bbridge.spl
diff --git a/gemrb/override/pst/bios.2da b/gemrb/unhardcoded/pst/bios.2da
similarity index 100%
rename from gemrb/override/pst/bios.2da
rename to gemrb/unhardcoded/pst/bios.2da
diff --git a/gemrb/override/pst/blessed.pro b/gemrb/unhardcoded/pst/blessed.pro
similarity index 100%
rename from gemrb/override/pst/blessed.pro
rename to gemrb/unhardcoded/pst/blessed.pro
diff --git a/gemrb/unhardcoded/pst/blight.pro b/gemrb/unhardcoded/pst/blight.pro
new file mode 100644
index 0000000..31aa2d5
Binary files /dev/null and b/gemrb/unhardcoded/pst/blight.pro differ
diff --git a/gemrb/unhardcoded/pst/blight2.pro b/gemrb/unhardcoded/pst/blight2.pro
new file mode 100644
index 0000000..7f4595d
Binary files /dev/null and b/gemrb/unhardcoded/pst/blight2.pro differ
diff --git a/gemrb/override/pst/bluetint.spl b/gemrb/unhardcoded/pst/bluetint.spl
similarity index 100%
rename from gemrb/override/pst/bluetint.spl
rename to gemrb/unhardcoded/pst/bluetint.spl
diff --git a/gemrb/override/pst/bolt.pro b/gemrb/unhardcoded/pst/bolt.pro
similarity index 100%
rename from gemrb/override/pst/bolt.pro
rename to gemrb/unhardcoded/pst/bolt.pro
diff --git a/gemrb/override/pst/boltex.pro b/gemrb/unhardcoded/pst/boltex.pro
similarity index 100%
rename from gemrb/override/pst/boltex.pro
rename to gemrb/unhardcoded/pst/boltex.pro
diff --git a/gemrb/override/pst/bstorm.pro b/gemrb/unhardcoded/pst/bstorm.pro
similarity index 100%
rename from gemrb/override/pst/bstorm.pro
rename to gemrb/unhardcoded/pst/bstorm.pro
diff --git a/gemrb/override/pst/bstorm.spl b/gemrb/unhardcoded/pst/bstorm.spl
similarity index 100%
rename from gemrb/override/pst/bstorm.spl
rename to gemrb/unhardcoded/pst/bstorm.spl
diff --git a/gemrb/override/pst/bstorm2.pro b/gemrb/unhardcoded/pst/bstorm2.pro
similarity index 100%
rename from gemrb/override/pst/bstorm2.pro
rename to gemrb/unhardcoded/pst/bstorm2.pro
diff --git a/gemrb/override/pst/bstorm2.spl b/gemrb/unhardcoded/pst/bstorm2.spl
similarity index 100%
rename from gemrb/override/pst/bstorm2.spl
rename to gemrb/unhardcoded/pst/bstorm2.spl
diff --git a/gemrb/override/pst/bullet.pro b/gemrb/unhardcoded/pst/bullet.pro
similarity index 100%
rename from gemrb/override/pst/bullet.pro
rename to gemrb/unhardcoded/pst/bullet.pro
diff --git a/gemrb/override/pst/bulletex.pro b/gemrb/unhardcoded/pst/bulletex.pro
similarity index 100%
rename from gemrb/override/pst/bulletex.pro
rename to gemrb/unhardcoded/pst/bulletex.pro
diff --git a/gemrb/override/pst/callih.pro b/gemrb/unhardcoded/pst/callih.pro
similarity index 100%
rename from gemrb/override/pst/callih.pro
rename to gemrb/unhardcoded/pst/callih.pro
diff --git a/gemrb/override/pst/chost.2da b/gemrb/unhardcoded/pst/chost.2da
similarity index 100%
rename from gemrb/override/pst/chost.2da
rename to gemrb/unhardcoded/pst/chost.2da
diff --git a/gemrb/unhardcoded/pst/chost.pro b/gemrb/unhardcoded/pst/chost.pro
new file mode 100644
index 0000000..7bf61b9
Binary files /dev/null and b/gemrb/unhardcoded/pst/chost.pro differ
diff --git a/gemrb/override/pst/chost.spl b/gemrb/unhardcoded/pst/chost.spl
similarity index 100%
rename from gemrb/override/pst/chost.spl
rename to gemrb/unhardcoded/pst/chost.spl
diff --git a/gemrb/override/pst/chromorb.pro b/gemrb/unhardcoded/pst/chromorb.pro
similarity index 100%
rename from gemrb/override/pst/chromorb.pro
rename to gemrb/unhardcoded/pst/chromorb.pro
diff --git a/gemrb/override/pst/classes.2da b/gemrb/unhardcoded/pst/classes.2da
similarity index 100%
rename from gemrb/override/pst/classes.2da
rename to gemrb/unhardcoded/pst/classes.2da
diff --git a/gemrb/override/pst/cloud.pro b/gemrb/unhardcoded/pst/cloud.pro
similarity index 100%
rename from gemrb/override/pst/cloud.pro
rename to gemrb/unhardcoded/pst/cloud.pro
diff --git a/gemrb/unhardcoded/pst/cloudkil.pro b/gemrb/unhardcoded/pst/cloudkil.pro
new file mode 100644
index 0000000..62f6355
Binary files /dev/null and b/gemrb/unhardcoded/pst/cloudkil.pro differ
diff --git a/gemrb/unhardcoded/pst/clskills.2da b/gemrb/unhardcoded/pst/clskills.2da
new file mode 100644
index 0000000..6bdce26
--- /dev/null
+++ b/gemrb/unhardcoded/pst/clskills.2da
@@ -0,0 +1,13 @@
+2DA V1.0
+*
+ HATERACE CLERICSPELL MAGESPELL STARTXP BARD THIEF LAYHANDS TURNLEVEL BOOKTYPE SAVEBONUS
+UNUSED * * * * * * * 0 0 0
+MAGE * * MXSPLWIZ 0 * * * 0 1 0
+FIGHTER * * * 0 * * * 0 0 0
+CLERIC * MXSPLPRS * 0 * * * 1 1 0
+THIEF * * * 0 * SKILLS * 0 0 0
+BARD * * MXSPLBRD 0 * * * 0 1 0
+PALADIN * MXSPLPAL * 0 * * PALADIN 5 1 2
+FIGHTER_MAGE * * MXSPLWIZ 0 * * * 0 1 0
+FIGHTER_CLERIC * MXSPLPRS * 0 * * * 0 1 0
+FIGHTER_THIEF * * * 0 * SKILLS * 0 0 0
diff --git a/gemrb/override/pst/clssplab.2da b/gemrb/unhardcoded/pst/clssplab.2da
similarity index 100%
rename from gemrb/override/pst/clssplab.2da
rename to gemrb/unhardcoded/pst/clssplab.2da
diff --git a/gemrb/override/pst/cocold.pro b/gemrb/unhardcoded/pst/cocold.pro
similarity index 100%
rename from gemrb/override/pst/cocold.pro
rename to gemrb/unhardcoded/pst/cocold.pro
diff --git a/gemrb/override/pst/colrspry.pro b/gemrb/unhardcoded/pst/colrspry.pro
similarity index 100%
rename from gemrb/override/pst/colrspry.pro
rename to gemrb/unhardcoded/pst/colrspry.pro
diff --git a/gemrb/unhardcoded/pst/comment.2da b/gemrb/unhardcoded/pst/comment.2da
new file mode 100644
index 0000000..7e95b03
--- /dev/null
+++ b/gemrb/unhardcoded/pst/comment.2da
@@ -0,0 +1,12 @@
+2DA V1.0
+-1
+ AREAFLAG VC SWITCH
+RAVEL 0x10 21 0
+BAATOR 0x20 23 0
+CLERKS 4 22 0
+HIVE 1 24 1
+FORTRESS 0x80 70 0
+CARCERI 0x200 71 0
+CURST 0x100 72 0
+LIMBO 0x40 73 0
+LOWER 2 74 0
diff --git a/gemrb/override/pst/conflag.pro b/gemrb/unhardcoded/pst/conflag.pro
similarity index 100%
rename from gemrb/override/pst/conflag.pro
rename to gemrb/unhardcoded/pst/conflag.pro
diff --git a/gemrb/override/pst/conflag.spl b/gemrb/unhardcoded/pst/conflag.spl
similarity index 100%
rename from gemrb/override/pst/conflag.spl
rename to gemrb/unhardcoded/pst/conflag.spl
diff --git a/gemrb/override/pst/confus.pro b/gemrb/unhardcoded/pst/confus.pro
similarity index 100%
rename from gemrb/override/pst/confus.pro
rename to gemrb/unhardcoded/pst/confus.pro
diff --git a/gemrb/unhardcoded/pst/crits.2da b/gemrb/unhardcoded/pst/crits.2da
new file mode 100644
index 0000000..48a5e0a
--- /dev/null
+++ b/gemrb/unhardcoded/pst/crits.2da
@@ -0,0 +1,13 @@
+2DA V1.0
+0
+ ANIMATION ID
+0 bloodcr 0
+1 bloodcr 0
+2 ch01nuke 1
+3 critvlor 16
+4 critnord 8
+5 critigns 128
+6 critffgc 4
+7 critdakk 64
+8 critanna 2
+9 critmort 32
diff --git a/gemrb/override/pst/cursed.pro b/gemrb/unhardcoded/pst/cursed.pro
similarity index 100%
rename from gemrb/override/pst/cursed.pro
rename to gemrb/unhardcoded/pst/cursed.pro
diff --git a/gemrb/override/pst/dagger.pro b/gemrb/unhardcoded/pst/dagger.pro
similarity index 100%
rename from gemrb/override/pst/dagger.pro
rename to gemrb/unhardcoded/pst/dagger.pro
diff --git a/gemrb/override/pst/daggerex.pro b/gemrb/unhardcoded/pst/daggerex.pro
similarity index 100%
rename from gemrb/override/pst/daggerex.pro
rename to gemrb/unhardcoded/pst/daggerex.pro
diff --git a/gemrb/unhardcoded/pst/damage.2da b/gemrb/unhardcoded/pst/damage.2da
new file mode 100644
index 0000000..297faca
--- /dev/null
+++ b/gemrb/unhardcoded/pst/damage.2da
@@ -0,0 +1,16 @@
+2DA V1.0
+*
+ MAIN SPARKS GRADIENT
+CRIT BLOODCR * 47
+SMALL BLOODS * 47
+MEDIUM BLOODM * 47
+LARGE BLOODL * 47
+FIRES FIRIMP SPBURN 19
+FIREM FIRIMP SPBURN 19
+FIREL FIRIMP SPBURN 19
+SPARKS DMGSPARK * -1
+SPARKM DMGSPARK * -1
+SPARKL DMGSPARK * -1
+ICES D005DICE * -1
+ICEM D005DICE * -1
+ICEL D005DICE * -1
diff --git a/gemrb/override/pst/dart.pro b/gemrb/unhardcoded/pst/dart.pro
similarity index 100%
rename from gemrb/override/pst/dart.pro
rename to gemrb/unhardcoded/pst/dart.pro
diff --git a/gemrb/override/pst/dartex.pro b/gemrb/unhardcoded/pst/dartex.pro
similarity index 100%
rename from gemrb/override/pst/dartex.pro
rename to gemrb/unhardcoded/pst/dartex.pro
diff --git a/gemrb/override/pst/dbolt.pro b/gemrb/unhardcoded/pst/dbolt.pro
similarity index 100%
rename from gemrb/override/pst/dbolt.pro
rename to gemrb/unhardcoded/pst/dbolt.pro
diff --git a/gemrb/override/pst/dbolt.spl b/gemrb/unhardcoded/pst/dbolt.spl
similarity index 100%
rename from gemrb/override/pst/dbolt.spl
rename to gemrb/unhardcoded/pst/dbolt.spl
diff --git a/gemrb/unhardcoded/pst/defsound.2da b/gemrb/unhardcoded/pst/defsound.2da
new file mode 100644
index 0000000..ea63466
--- /dev/null
+++ b/gemrb/unhardcoded/pst/defsound.2da
@@ -0,0 +1,36 @@
+2DA V1.0
+*
+ RESREF
+OPEN *
+CLOSE *
+HOPEN *
+HCLOSE *
+BUTTON1 INT_09
+BUTTON2 INT_03
+BUTTON3 INT_04
+OPENFAIL *
+CLOSEFAIL *
+ITEM_GONE INT_11
+SECRET *
+PICKLOCK *
+12 *
+13 *
+14 *
+15 *
+16 *
+17 *
+18 *
+19 *
+LIGHTNING1 AMB_E13A
+LIGHTNING2 AMB_E13B
+LIGHTNING3 AMB_E13F
+RAIN AMB_E11
+SNOW AMB_E02B
+SOLD Z_COIN1
+STOLEN *
+DRUNK ITE_02
+DONATE1 Z_COIN1
+DONATE2 Z_COIN2
+IDENTIFY *
+GOTXP SPTR_02
+TOOLTIP *
diff --git a/gemrb/override/pst/dhell.pro b/gemrb/unhardcoded/pst/dhell.pro
similarity index 100%
rename from gemrb/override/pst/dhell.pro
rename to gemrb/unhardcoded/pst/dhell.pro
diff --git a/gemrb/override/pst/dhell.spl b/gemrb/unhardcoded/pst/dhell.spl
similarity index 100%
rename from gemrb/override/pst/dhell.spl
rename to gemrb/unhardcoded/pst/dhell.spl
diff --git a/gemrb/unhardcoded/pst/dstable.2da b/gemrb/unhardcoded/pst/dstable.2da
new file mode 100644
index 0000000..3f05e84
--- /dev/null
+++ b/gemrb/unhardcoded/pst/dstable.2da
@@ -0,0 +1,3 @@
+2DA V1.0
+*
+FILE STAT
diff --git a/gemrb/override/pst/easymaze.2da b/gemrb/unhardcoded/pst/easymaze.2da
similarity index 100%
rename from gemrb/override/pst/easymaze.2da
rename to gemrb/unhardcoded/pst/easymaze.2da
diff --git a/gemrb/override/pst/ebomb.pro b/gemrb/unhardcoded/pst/ebomb.pro
similarity index 100%
rename from gemrb/override/pst/ebomb.pro
rename to gemrb/unhardcoded/pst/ebomb.pro
diff --git a/gemrb/override/pst/effects.ids b/gemrb/unhardcoded/pst/effects.ids
similarity index 100%
rename from gemrb/override/pst/effects.ids
rename to gemrb/unhardcoded/pst/effects.ids
diff --git a/gemrb/override/pst/elyfire.pro b/gemrb/unhardcoded/pst/elyfire.pro
similarity index 100%
rename from gemrb/override/pst/elyfire.pro
rename to gemrb/unhardcoded/pst/elyfire.pro
diff --git a/gemrb/override/pst/elytear.pro b/gemrb/unhardcoded/pst/elytear.pro
similarity index 100%
rename from gemrb/override/pst/elytear.pro
rename to gemrb/unhardcoded/pst/elytear.pro
diff --git a/gemrb/override/pst/embalm.pro b/gemrb/unhardcoded/pst/embalm.pro
similarity index 100%
rename from gemrb/override/pst/embalm.pro
rename to gemrb/unhardcoded/pst/embalm.pro
diff --git a/gemrb/override/pst/estrike.pro b/gemrb/unhardcoded/pst/estrike.pro
similarity index 100%
rename from gemrb/override/pst/estrike.pro
rename to gemrb/unhardcoded/pst/estrike.pro
diff --git a/gemrb/override/pst/factions.2da b/gemrb/unhardcoded/pst/factions.2da
similarity index 100%
rename from gemrb/override/pst/factions.2da
rename to gemrb/unhardcoded/pst/factions.2da
diff --git a/gemrb/override/pst/faerie.spl b/gemrb/unhardcoded/pst/faerie.spl
similarity index 100%
rename from gemrb/override/pst/faerie.spl
rename to gemrb/unhardcoded/pst/faerie.spl
diff --git a/gemrb/override/pst/fbomb.pro b/gemrb/unhardcoded/pst/fbomb.pro
similarity index 100%
rename from gemrb/override/pst/fbomb.pro
rename to gemrb/unhardcoded/pst/fbomb.pro
diff --git a/gemrb/override/pst/fbyello.pro b/gemrb/unhardcoded/pst/fbyello.pro
similarity index 100%
rename from gemrb/override/pst/fbyello.pro
rename to gemrb/unhardcoded/pst/fbyello.pro
diff --git a/gemrb/override/pst/fearaura.pro b/gemrb/unhardcoded/pst/fearaura.pro
similarity index 100%
rename from gemrb/override/pst/fearaura.pro
rename to gemrb/unhardcoded/pst/fearaura.pro
diff --git a/gemrb/override/pst/ffire.pro b/gemrb/unhardcoded/pst/ffire.pro
similarity index 100%
rename from gemrb/override/pst/ffire.pro
rename to gemrb/unhardcoded/pst/ffire.pro
diff --git a/gemrb/override/pst/fireball.pro b/gemrb/unhardcoded/pst/fireball.pro
similarity index 100%
rename from gemrb/override/pst/fireball.pro
rename to gemrb/unhardcoded/pst/fireball.pro
diff --git a/gemrb/override/pst/firebolt.pro b/gemrb/unhardcoded/pst/firebolt.pro
similarity index 100%
rename from gemrb/override/pst/firebolt.pro
rename to gemrb/unhardcoded/pst/firebolt.pro
diff --git a/gemrb/override/pst/firebtbl.pro b/gemrb/unhardcoded/pst/firebtbl.pro
similarity index 100%
rename from gemrb/override/pst/firebtbl.pro
rename to gemrb/unhardcoded/pst/firebtbl.pro
diff --git a/gemrb/override/pst/fireice.pro b/gemrb/unhardcoded/pst/fireice.pro
similarity index 100%
rename from gemrb/override/pst/fireice.pro
rename to gemrb/unhardcoded/pst/fireice.pro
diff --git a/gemrb/override/pst/fireice.spl b/gemrb/unhardcoded/pst/fireice.spl
similarity index 100%
rename from gemrb/override/pst/fireice.spl
rename to gemrb/unhardcoded/pst/fireice.spl
diff --git a/gemrb/override/pst/firestor.pro b/gemrb/unhardcoded/pst/firestor.pro
similarity index 100%
rename from gemrb/override/pst/firestor.pro
rename to gemrb/unhardcoded/pst/firestor.pro
diff --git a/gemrb/override/pst/fistweap.2da b/gemrb/unhardcoded/pst/fistweap.2da
similarity index 100%
rename from gemrb/override/pst/fistweap.2da
rename to gemrb/unhardcoded/pst/fistweap.2da
diff --git a/gemrb/override/pst/fizzle.spl b/gemrb/unhardcoded/pst/fizzle.spl
similarity index 100%
copy from gemrb/override/pst/fizzle.spl
copy to gemrb/unhardcoded/pst/fizzle.spl
diff --git a/gemrb/override/pst/fmiss.pro b/gemrb/unhardcoded/pst/fmiss.pro
similarity index 100%
rename from gemrb/override/pst/fmiss.pro
rename to gemrb/unhardcoded/pst/fmiss.pro
diff --git a/gemrb/unhardcoded/pst/fonts.2da b/gemrb/unhardcoded/pst/fonts.2da
new file mode 100644
index 0000000..70798e1
--- /dev/null
+++ b/gemrb/unhardcoded/pst/fonts.2da
@@ -0,0 +1,14 @@
+2DA V1.0
+FONTDLG
+ RESREF NEED_PALETTE FONT_NAME PT_SIZE STYLE COLOR
+0 FONTDLG 1 FONTDLG 14 0 0xffffffff
+1 TRMTFONT 1 TRMTFONT 14 0 0xffffffff
+2 EXOFONT 1 EXOFONT 14 0 0xffffffff
+3 POSTANT 1 POSTANT 14 0 0xffffffff
+4 NUMBER 0 NUMBER 14 0 0xffffffff
+5 NUMBER2 0 NUMBER2 14 0 0xffffffff
+6 NUMBER3 0 NUMBER3 14 0 0xffffffff
+7 SYSFONT 1 SYSFONT 14 0 0xffffffff
+8 FONTDLG 1 FONTDLG 14 0 0xffffffff
+
+# Customization How To: http://gemrb.sourceforge.net/wiki/doku.php?id=plugins:ttf
diff --git a/gemrb/override/pst/formatio.2da b/gemrb/unhardcoded/pst/formatio.2da
similarity index 100%
rename from gemrb/override/pst/formatio.2da
rename to gemrb/unhardcoded/pst/formatio.2da
diff --git a/gemrb/unhardcoded/pst/foundry.2da b/gemrb/unhardcoded/pst/foundry.2da
new file mode 100644
index 0000000..7c95612
--- /dev/null
+++ b/gemrb/unhardcoded/pst/foundry.2da
@@ -0,0 +1,4 @@
+2DA V1.0
+0
+ AREA REGION
+1 AR0502 to0512
diff --git a/gemrb/override/pst/frain.pro b/gemrb/unhardcoded/pst/frain.pro
similarity index 100%
rename from gemrb/override/pst/frain.pro
rename to gemrb/unhardcoded/pst/frain.pro
diff --git a/gemrb/unhardcoded/pst/gametime.2da b/gemrb/unhardcoded/pst/gametime.2da
new file mode 100644
index 0000000..22f0480
--- /dev/null
+++ b/gemrb/unhardcoded/pst/gametime.2da
@@ -0,0 +1,6 @@
+2DA V1.0
+0
+ DURATION
+ROUND_SECONDS 5
+TURN_SECONDS 50
+ATTACK_ROUND 50
diff --git a/gemrb/override/pst/gaze.pro b/gemrb/unhardcoded/pst/gaze.pro
similarity index 100%
rename from gemrb/override/pst/gaze.pro
rename to gemrb/unhardcoded/pst/gaze.pro
diff --git a/gemrb/unhardcoded/pst/gemprjtl.ids b/gemrb/unhardcoded/pst/gemprjtl.ids
new file mode 100644
index 0000000..aa58497
--- /dev/null
+++ b/gemrb/unhardcoded/pst/gemprjtl.ids
@@ -0,0 +1,292 @@
+IDS V1.0
+1 ARROW
+2 ARROWEX
+3 ARROWFLM
+4 ARROWHVY
+5 ARROW
+6 AXE
+7 AXEEX
+8 AXEFLM
+9 AXE
+10 AXE
+11 BOLT
+12 BOLTEX
+13 ARROWHVY
+14 BOLT
+15 BOLT
+16 BULLET
+17 BULLETEX
+18 <flamingbullet>
+19 BULLET
+20 BULLET
+21 SPBRNHND
+22 SKYBOLT
+23 CHROMORB
+24 SPCONECO
+25 SPCONEFI
+26 DAGGER
+27 DAGGEREX
+28 <flamingdagger>
+29 DAGGER
+30 DAGGER
+31 DART
+32 DARTEX
+33 <flamingdart>
+34 DART
+35 DART
+36 MAGICMIS
+37 FIREBALL
+38 ICE
+39 LIGHTB
+40 STONE
+41 SLEEP
+42 HOPAND2
+43 SPSMPUFF
+44 SPSMKJET
+45 SPSMOLD
+46 SPARKLBL
+47 SPARKLGO
+48 SPARKLPU
+49 SPARKLIC
+50 SPARKLST
+51 SPARKLBK
+52 SPARKLCH
+53 SPARKLRE
+54 SPARKLGR
+55 SPEAR
+56 SPEAREX
+57 <flamingspear>
+58 SPEAR
+59 SPEAR
+60 <starsprite>
+61 <stoned>
+62 <webtravel>
+63 WEB
+64 GAZE
+65 HLYMITE
+66 FLMSTRK
+67 MAGICMIS
+68 SPMAGMIS
+69 SPMAGMIS
+70 SPMAGMIS
+71 SPMAGMIS
+72 SPMAGMIS
+73 SPMAGMIS
+74 SPMAGMIS
+75 SPMAGMIS
+76 SPMAGMIS
+77 SPMAGMIS
+78 INVTRAV
+79 FIREBOLT
+80 SKYBOLT
+81 SKYBOLT2
+82 SKYBOLT2
+83 SKYBOLT2
+84 SKYBOLT2
+85 SKYBOLT2
+86 SKYBOLT2
+87 SKYBOLT2
+88 SKYBOLT2
+89 SKYBOLT2
+90 SKYBOLT2
+91 FIRESTOR
+92 LIGHTSTO
+93 INAREA
+94 CLOUD
+95 TRAPSKUL
+96 COLRSPRY
+97 ICESTORM
+98 SPFIREWL
+99 TRAPGLYP
+100 GREASE
+101 ARROWFLG
+102 ARROWFLB
+103 FIREBLGR
+104 FIREBTBL
+105 <potion>
+106 <potionexplode>
+107 ACIDBLOB
+108 SPSCORCH
+109 SPDIMDR
+110 CGNECROM
+111 CGALTERA
+112 CGENCHAN
+113 CGABJURA
+114 CGILLUSI
+115 CGCONJUR
+116 CGINVOCA
+117 CGDIVINA
+118 SHAIR
+119 SHEARTH
+120 SHWATER
+121 SHAIR1
+122 SHEARTH1
+123 SHWATER1
+124 SHAIR2
+125 SHEARTH2
+126 SHWATER2
+127 SHAIR3
+128 SHEARTH3
+129 SHWATER3
+130 SHAIR4
+131 SHEARTH4
+132 SHWATER4
+133 SHAIR5
+134 SHEARTH5
+135 SHWATER5
+136 SHAIR6
+137 SHEARTH6
+138 SHWATER6
+139 SHAIR7
+140 SHEARTH7
+141 SHWATER7
+142 SPBOOM1
+143 SPBOOM2
+144 SPBOOM3
+145 FLMSTRK
+146 HLYMITE
+147 SHAIR7
+148 SPKLARBL
+149 SPKLARGO
+150 SPKLARPU
+151 SPKLARIC
+152 SPKLARST
+153 SPKLARBK
+154 SPKLARCH
+155 SPKLARRE
+156 SPKLARGR
+157 INAREAPA
+158 INAREANP
+159 SPARBLPA
+160 SPARGOPA
+161 SPARPUPA
+162 SPARICPA
+163 SPARSTPA
+164 SPARBKPA
+165 SPARCHPA
+166 SPARREPA
+167 SPARGRPA
+168 SPARBLNP
+169 SPARGONP
+170 SPARPUNP
+171 SPARICNP
+172 SPARSTNP
+173 SPARBKNP
+174 SPARCHNP
+175 SPARRENP
+176 SPARGRNP
+177 SPARMANP
+178 SPARORNP
+179 SPARMAPA
+180 SPARORPA
+181 SPKLARMA
+182 SPKLAROR
+183 SPARKLMA
+184 SPARKLOR
+185 INAREANS
+186 CLOUDKIL
+187 ARROWFLI
+188 COW
+189 HOLD
+190 SPSCORIC
+191 ACIDBLMU
+192 ACIDBLGR
+193 ACIDBLOC
+194 REDHOLY
+195 SHAREA
+196 SHAREA1
+197 SHAREA
+198 SHAREA2
+199 SHAREA3
+200 SHAREA4
+201 SHAREA5
+202 SHAREA6
+203 LITANY
+204 STORIES
+205 MMISS
+206 MMISS2
+207 MMISS2
+208 MMISS2
+209 MMISS2
+210 MMISS2
+211 MMISS2
+212 MMISS2
+213 MMISS2
+214 MMISS2
+215 SKMOB
+216 SKMOB2
+217 ISWARM
+218 ISWARM2
+219 ADDER
+220 IKNIFE
+221 PACIFY
+222 STRENGTH
+223 BLIGHT
+224 BLIGHT2
+225 BBRIDGE
+226 FMISS
+227 ISTR
+228 SSHADOW
+229 CLOUDKIL
+230 HOPAND
+231 BSTORM
+232 ELYFIRE
+233 FURY
+234 HORROR
+235 KNOCK
+236 HOLDUND
+237 LMISS
+238 ELYTEAR
+239 TLAUGH
+240 AOTORM
+241 BSPHERE
+242 COCOLD
+243 DHELL
+244 FIREICE
+245 LSTORM
+246 ASTORM
+247 ISTORM
+248 MSWARM
+249 DBOLT
+250 IFURY
+251 PWBLIND
+252 MCANNON
+253 CHOST
+254 ROTORM
+255 BLESSED
+256 CURSED
+258 FFIRE
+259 SHAMMER
+260 CALLIH
+262 VTOUCH
+263 CONFUS
+264 PWKILL
+265 GOINVUL
+266 NBOLT
+267 RDEAD
+268 FEARAURA
+269 CONFLAG
+271 FBYELLO
+272 IMISS
+273 IMISS2
+274 IMISS2
+275 IMISS2
+276 IMISS2
+277 ITERROR
+278 IGNUSORB
+279 FRAIN
+280 ESTRIKE
+281 AMISS
+282 AMISS2
+283 AMISS2
+284 AMISS2
+285 AMISS2
+286 POONE
+287 KISS
+288 EMBALM
+289 FBOMB
+290 EBOMB
+291 RUNE
+292 LSTORM2
+293 CHOST2
+294 BSTORM2
diff --git a/gemrb/unhardcoded/pst/gemrb.ini b/gemrb/unhardcoded/pst/gemrb.ini
new file mode 100644
index 0000000..bc62a01
--- /dev/null
+++ b/gemrb/unhardcoded/pst/gemrb.ini
@@ -0,0 +1,126 @@
+; GemRB - Infinity Engine Emulator
+; Copyright (C) 2003 The GemRB Project
+;
+; This program is free software; you can redistribute it and/or
+; modify it under the terms of the GNU General Public License
+; as published by the Free Software Foundation; either version 2
+; of the License, or (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program; if not, write to the Free Software
+; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+;
+
+
+; gemrb.ini - game type-specific settings for GemRB engine
+
+[resources]
+
+; Bitmap resource for cursors
+CursorBAM = CARET
+
+; Bitmap resource for scroll cursor arrow
+ScrollCursorBAM = CURSARW
+
+; Bitmap resource for dialog buttons font
+ButtonFont = FONTDLG
+
+; Font used to display tooltips
+TooltipFont = TRMTFONT
+
+; Bitmap resource for ground circles
+GroundCircleBAM1 = WMPICKL/3
+GroundCircleBAM2 = WMPICKR
+GroundCircleBAM3 = WMPICKL
+NoteString = NOTE:
+
+; INI file from the original games
+INIConfig = torment.ini
+
+; Palette bitmaps in various widths
+Palette16 = MPALETTE
+Palette32 = PAL32
+Palette256 = MPAL256
+
+3EdRules = 0
+AllStringsTagged = 1
+AreaOverride = 1
+AutomapINI = 1
+AutoSearchHidden = 1
+BiographyIsRes = 0
+BreakableWeapons = 0
+CastingSounds = 0
+ChallengeRating = 0
+CharNameIsGabber = 0
+CheckAbilities = 0
+ClearUnusedArea = 0
+CutsceneAreascripts = 1
+DeathOnZeroStat = 0
+DialogueScrolls = 1
+EnhancedCastingSounds = 0
+EnhancedEffects = 0
+FistStat = 235
+FlexibleWorldmap = 0
+ForceAreaScript = 0
+ForceStereo = 1
+HasBeastsINI = 1
+HasDescIcon = 0
+HasDPLAYER = 0
+HasEXPTABLE = 0
+HasFloatMenu = 1
+HasHideInShadows = 0
+HasKaputz = 1
+HasNoNPCFlag = 0
+HasPartyINI = 0
+HasPickSound = 1
+HasResDataIni = 1
+HasSongList = 0
+HasSoundsIni = 0
+HasSpecificDamageBonus = 0
+HasSpellList = 0
+HasUsePointFlag = 0
+HasWisdomBonusTable = 1
+HealOn100Plus = 1
+IgnoreButtonFrames = 1
+ImplicitAreaAnimBackground = 0
+InPartyAllowsDead = 1
+IWD2DeathVarFormat = 0
+IWD2ScriptName = 0
+IWDMapDimensions = 0
+JournalHasSections = 0
+KnowWorld = 0
+LevelslotPerClass = 0
+LowerLabelText = 0
+MagicBit = 0
+MaximumAbility = 25
+NoDropCanMove = 1
+NoNewVariables = 1
+NoUndroppable = 0
+OneByteAnimationID = 1
+OnScreenText = 1
+OverrideCursorPos = 1
+ProperBackstab = 0
+ProtagonistTalks = 1
+PSTStateFlags = 1
+RareActionSounds = 1
+RedrawTile = 0
+ReverseDoor = 1
+ReverseToHit = 1
+SaveForHalfDamage = 1
+SelectiveMagicRes = 0
+SkipUpdateHack = 0
+SmallFog = 1
+SoundFolders = 0
+SpawnIni = 1
+SpellBookIconHack = 0
+StartActive = 0
+StealIsAttack = 0
+StrrefSaveGame = 0
+TeamMovement = 1
+UpperButtonText = 0
+ZeroTimerIsValid = 0
diff --git a/gemrb/override/pst/genders.2da b/gemrb/unhardcoded/pst/genders.2da
similarity index 100%
rename from gemrb/override/pst/genders.2da
rename to gemrb/unhardcoded/pst/genders.2da
diff --git a/gemrb/override/pst/goinvul.pro b/gemrb/unhardcoded/pst/goinvul.pro
similarity index 100%
rename from gemrb/override/pst/goinvul.pro
rename to gemrb/unhardcoded/pst/goinvul.pro
diff --git a/gemrb/override/pst/goinvul.spl b/gemrb/unhardcoded/pst/goinvul.spl
similarity index 100%
rename from gemrb/override/pst/goinvul.spl
rename to gemrb/unhardcoded/pst/goinvul.spl
diff --git a/gemrb/override/pst/grease.pro b/gemrb/unhardcoded/pst/grease.pro
similarity index 100%
rename from gemrb/override/pst/grease.pro
rename to gemrb/unhardcoded/pst/grease.pro
diff --git a/gemrb/override/pst/guibtact.2da b/gemrb/unhardcoded/pst/guibtact.2da
similarity index 100%
rename from gemrb/override/pst/guibtact.2da
rename to gemrb/unhardcoded/pst/guibtact.2da
diff --git a/gemrb/override/pst/guiid.chu b/gemrb/unhardcoded/pst/guiid.chu
similarity index 100%
rename from gemrb/override/pst/guiid.chu
rename to gemrb/unhardcoded/pst/guiid.chu
diff --git a/gemrb/override/pst/guils.chu b/gemrb/unhardcoded/pst/guils.chu
similarity index 100%
rename from gemrb/override/pst/guils.chu
rename to gemrb/unhardcoded/pst/guils.chu
diff --git a/gemrb/override/pst/guiw08.chu b/gemrb/unhardcoded/pst/guiw08.chu
similarity index 100%
rename from gemrb/override/pst/guiw08.chu
rename to gemrb/unhardcoded/pst/guiw08.chu
diff --git a/gemrb/override/bg2/hlymite.pro b/gemrb/unhardcoded/pst/hlymite.pro
similarity index 100%
rename from gemrb/override/bg2/hlymite.pro
rename to gemrb/unhardcoded/pst/hlymite.pro
diff --git a/gemrb/override/pst/hold.pro b/gemrb/unhardcoded/pst/hold.pro
similarity index 100%
rename from gemrb/override/pst/hold.pro
rename to gemrb/unhardcoded/pst/hold.pro
diff --git a/gemrb/override/pst/holdund.pro b/gemrb/unhardcoded/pst/holdund.pro
similarity index 100%
rename from gemrb/override/pst/holdund.pro
rename to gemrb/unhardcoded/pst/holdund.pro
diff --git a/gemrb/override/pst/holdund.spl b/gemrb/unhardcoded/pst/holdund.spl
similarity index 100%
rename from gemrb/override/pst/holdund.spl
rename to gemrb/unhardcoded/pst/holdund.spl
diff --git a/gemrb/unhardcoded/pst/hopand.pro b/gemrb/unhardcoded/pst/hopand.pro
new file mode 100644
index 0000000..93c4cd9
Binary files /dev/null and b/gemrb/unhardcoded/pst/hopand.pro differ
diff --git a/gemrb/unhardcoded/pst/hopand2.pro b/gemrb/unhardcoded/pst/hopand2.pro
new file mode 100644
index 0000000..d3c2d17
Binary files /dev/null and b/gemrb/unhardcoded/pst/hopand2.pro differ
diff --git a/gemrb/override/pst/horror.pro b/gemrb/unhardcoded/pst/horror.pro
similarity index 100%
rename from gemrb/override/pst/horror.pro
rename to gemrb/unhardcoded/pst/horror.pro
diff --git a/gemrb/unhardcoded/pst/howl.spl b/gemrb/unhardcoded/pst/howl.spl
new file mode 100644
index 0000000..543bdce
Binary files /dev/null and b/gemrb/unhardcoded/pst/howl.spl differ
diff --git a/gemrb/override/pst/ice.pro b/gemrb/unhardcoded/pst/ice.pro
similarity index 100%
rename from gemrb/override/pst/ice.pro
rename to gemrb/unhardcoded/pst/ice.pro
diff --git a/gemrb/override/pst/ice.spl b/gemrb/unhardcoded/pst/ice.spl
similarity index 100%
rename from gemrb/override/pst/ice.spl
rename to gemrb/unhardcoded/pst/ice.spl
diff --git a/gemrb/override/pst/icestorm.pro b/gemrb/unhardcoded/pst/icestorm.pro
similarity index 100%
rename from gemrb/override/pst/icestorm.pro
rename to gemrb/unhardcoded/pst/icestorm.pro
diff --git a/gemrb/override/pst/ifury.pro b/gemrb/unhardcoded/pst/ifury.pro
similarity index 100%
rename from gemrb/override/pst/ifury.pro
rename to gemrb/unhardcoded/pst/ifury.pro
diff --git a/gemrb/override/pst/ifury.spl b/gemrb/unhardcoded/pst/ifury.spl
similarity index 100%
rename from gemrb/override/pst/ifury.spl
rename to gemrb/unhardcoded/pst/ifury.spl
diff --git a/gemrb/override/pst/ignusorb.pro b/gemrb/unhardcoded/pst/ignusorb.pro
similarity index 100%
rename from gemrb/override/pst/ignusorb.pro
rename to gemrb/unhardcoded/pst/ignusorb.pro
diff --git a/gemrb/override/pst/ignusorb.vvc b/gemrb/unhardcoded/pst/ignusorb.vvc
similarity index 100%
rename from gemrb/override/pst/ignusorb.vvc
rename to gemrb/unhardcoded/pst/ignusorb.vvc
diff --git a/gemrb/override/pst/iknife.pro b/gemrb/unhardcoded/pst/iknife.pro
similarity index 100%
rename from gemrb/override/pst/iknife.pro
rename to gemrb/unhardcoded/pst/iknife.pro
diff --git a/gemrb/override/pst/imiss.pro b/gemrb/unhardcoded/pst/imiss.pro
similarity index 100%
rename from gemrb/override/pst/imiss.pro
rename to gemrb/unhardcoded/pst/imiss.pro
diff --git a/gemrb/override/pst/imiss2.pro b/gemrb/unhardcoded/pst/imiss2.pro
similarity index 100%
rename from gemrb/override/pst/imiss2.pro
rename to gemrb/unhardcoded/pst/imiss2.pro
diff --git a/gemrb/override/pst/impstr.spl b/gemrb/unhardcoded/pst/impstr.spl
similarity index 100%
rename from gemrb/override/pst/impstr.spl
rename to gemrb/unhardcoded/pst/impstr.spl
diff --git a/gemrb/override/pst/inarea.pro b/gemrb/unhardcoded/pst/inarea.pro
similarity index 100%
rename from gemrb/override/pst/inarea.pro
rename to gemrb/unhardcoded/pst/inarea.pro
diff --git a/gemrb/override/how/inareanp.pro b/gemrb/unhardcoded/pst/inareanp.pro
similarity index 100%
rename from gemrb/override/how/inareanp.pro
rename to gemrb/unhardcoded/pst/inareanp.pro
diff --git a/gemrb/unhardcoded/pst/inareapa.pro b/gemrb/unhardcoded/pst/inareapa.pro
new file mode 100644
index 0000000..fedb699
Binary files /dev/null and b/gemrb/unhardcoded/pst/inareapa.pro differ
diff --git a/gemrb/override/bg1/inareasm.pro b/gemrb/unhardcoded/pst/inareasm.pro
similarity index 100%
rename from gemrb/override/bg1/inareasm.pro
rename to gemrb/unhardcoded/pst/inareasm.pro
diff --git a/gemrb/override/pst/istorm.pro b/gemrb/unhardcoded/pst/istorm.pro
similarity index 100%
rename from gemrb/override/pst/istorm.pro
rename to gemrb/unhardcoded/pst/istorm.pro
diff --git a/gemrb/override/pst/istorm.spl b/gemrb/unhardcoded/pst/istorm.spl
similarity index 100%
rename from gemrb/override/pst/istorm.spl
rename to gemrb/unhardcoded/pst/istorm.spl
diff --git a/gemrb/override/pst/istr.pro b/gemrb/unhardcoded/pst/istr.pro
similarity index 100%
rename from gemrb/override/pst/istr.pro
rename to gemrb/unhardcoded/pst/istr.pro
diff --git a/gemrb/override/pst/iswarm.pro b/gemrb/unhardcoded/pst/iswarm.pro
similarity index 100%
rename from gemrb/override/pst/iswarm.pro
rename to gemrb/unhardcoded/pst/iswarm.pro
diff --git a/gemrb/override/pst/iswarm.spl b/gemrb/unhardcoded/pst/iswarm.spl
similarity index 100%
rename from gemrb/override/pst/iswarm.spl
rename to gemrb/unhardcoded/pst/iswarm.spl
diff --git a/gemrb/override/pst/item_use.2da b/gemrb/unhardcoded/pst/item_use.2da
similarity index 100%
rename from gemrb/override/pst/item_use.2da
rename to gemrb/unhardcoded/pst/item_use.2da
diff --git a/gemrb/override/pst/itemsnd.2da b/gemrb/unhardcoded/pst/itemsnd.2da
similarity index 100%
rename from gemrb/override/pst/itemsnd.2da
rename to gemrb/unhardcoded/pst/itemsnd.2da
diff --git a/gemrb/override/pst/itemtype.2da b/gemrb/unhardcoded/pst/itemtype.2da
similarity index 100%
rename from gemrb/override/pst/itemtype.2da
rename to gemrb/unhardcoded/pst/itemtype.2da
diff --git a/gemrb/override/pst/itemuse.2da b/gemrb/unhardcoded/pst/itemuse.2da
similarity index 100%
rename from gemrb/override/pst/itemuse.2da
rename to gemrb/unhardcoded/pst/itemuse.2da
diff --git a/gemrb/override/pst/iterror.pro b/gemrb/unhardcoded/pst/iterror.pro
similarity index 100%
rename from gemrb/override/pst/iterror.pro
rename to gemrb/unhardcoded/pst/iterror.pro
diff --git a/gemrb/override/pst/kiss.pro b/gemrb/unhardcoded/pst/kiss.pro
similarity index 100%
rename from gemrb/override/pst/kiss.pro
rename to gemrb/unhardcoded/pst/kiss.pro
diff --git a/gemrb/override/pst/kitlist.2da b/gemrb/unhardcoded/pst/kitlist.2da
similarity index 100%
rename from gemrb/override/pst/kitlist.2da
rename to gemrb/unhardcoded/pst/kitlist.2da
diff --git a/gemrb/override/pst/knock.pro b/gemrb/unhardcoded/pst/knock.pro
similarity index 100%
rename from gemrb/override/pst/knock.pro
rename to gemrb/unhardcoded/pst/knock.pro
diff --git a/gemrb/override/pst/lightb.pro b/gemrb/unhardcoded/pst/lightb.pro
similarity index 100%
rename from gemrb/override/pst/lightb.pro
rename to gemrb/unhardcoded/pst/lightb.pro
diff --git a/gemrb/override/pst/lightnin.spl b/gemrb/unhardcoded/pst/lightnin.spl
similarity index 100%
rename from gemrb/override/pst/lightnin.spl
rename to gemrb/unhardcoded/pst/lightnin.spl
diff --git a/gemrb/override/pst/lightsto.pro b/gemrb/unhardcoded/pst/lightsto.pro
similarity index 100%
rename from gemrb/override/pst/lightsto.pro
rename to gemrb/unhardcoded/pst/lightsto.pro
diff --git a/gemrb/override/pst/litany.pro b/gemrb/unhardcoded/pst/litany.pro
similarity index 100%
rename from gemrb/override/pst/litany.pro
rename to gemrb/unhardcoded/pst/litany.pro
diff --git a/gemrb/override/pst/litany.spl b/gemrb/unhardcoded/pst/litany.spl
similarity index 100%
rename from gemrb/override/pst/litany.spl
rename to gemrb/unhardcoded/pst/litany.spl
diff --git a/gemrb/override/pst/lmiss.pro b/gemrb/unhardcoded/pst/lmiss.pro
similarity index 100%
rename from gemrb/override/pst/lmiss.pro
rename to gemrb/unhardcoded/pst/lmiss.pro
diff --git a/gemrb/override/pst/lstorm.2da b/gemrb/unhardcoded/pst/lstorm.2da
similarity index 100%
rename from gemrb/override/pst/lstorm.2da
rename to gemrb/unhardcoded/pst/lstorm.2da
diff --git a/gemrb/override/pst/lstorm.pro b/gemrb/unhardcoded/pst/lstorm.pro
similarity index 100%
rename from gemrb/override/pst/lstorm.pro
rename to gemrb/unhardcoded/pst/lstorm.pro
diff --git a/gemrb/override/pst/fizzle.spl b/gemrb/unhardcoded/pst/lstorm.spl
similarity index 100%
rename from gemrb/override/pst/fizzle.spl
rename to gemrb/unhardcoded/pst/lstorm.spl
diff --git a/gemrb/override/pst/lstorm2.pro b/gemrb/unhardcoded/pst/lstorm2.pro
similarity index 100%
rename from gemrb/override/pst/lstorm2.pro
rename to gemrb/unhardcoded/pst/lstorm2.pro
diff --git a/gemrb/override/pst/lstorm2.spl b/gemrb/unhardcoded/pst/lstorm2.spl
similarity index 100%
rename from gemrb/override/pst/lstorm2.spl
rename to gemrb/unhardcoded/pst/lstorm2.spl
diff --git a/gemrb/override/pst/magicmis.pro b/gemrb/unhardcoded/pst/magicmis.pro
similarity index 100%
rename from gemrb/override/pst/magicmis.pro
rename to gemrb/unhardcoded/pst/magicmis.pro
diff --git a/gemrb/override/pst/mcannon.pro b/gemrb/unhardcoded/pst/mcannon.pro
similarity index 100%
rename from gemrb/override/pst/mcannon.pro
rename to gemrb/unhardcoded/pst/mcannon.pro
diff --git a/gemrb/override/pst/mcannon.spl b/gemrb/unhardcoded/pst/mcannon.spl
similarity index 100%
rename from gemrb/override/pst/mcannon.spl
rename to gemrb/unhardcoded/pst/mcannon.spl
diff --git a/gemrb/override/pst/mmiss.pro b/gemrb/unhardcoded/pst/mmiss.pro
similarity index 100%
rename from gemrb/override/pst/mmiss.pro
rename to gemrb/unhardcoded/pst/mmiss.pro
diff --git a/gemrb/override/pst/mmiss2.pro b/gemrb/unhardcoded/pst/mmiss2.pro
similarity index 100%
rename from gemrb/override/pst/mmiss2.pro
rename to gemrb/unhardcoded/pst/mmiss2.pro
diff --git a/gemrb/override/pst/modal.2da b/gemrb/unhardcoded/pst/modal.2da
similarity index 100%
rename from gemrb/override/pst/modal.2da
rename to gemrb/unhardcoded/pst/modal.2da
diff --git a/gemrb/override/pst/mpal256.bmp b/gemrb/unhardcoded/pst/mpal256.bmp
similarity index 100%
rename from gemrb/override/pst/mpal256.bmp
rename to gemrb/unhardcoded/pst/mpal256.bmp
diff --git a/gemrb/override/pst/mswarm.pro b/gemrb/unhardcoded/pst/mswarm.pro
similarity index 100%
rename from gemrb/override/pst/mswarm.pro
rename to gemrb/unhardcoded/pst/mswarm.pro
diff --git a/gemrb/override/pst/mswarm.spl b/gemrb/unhardcoded/pst/mswarm.spl
similarity index 100%
rename from gemrb/override/pst/mswarm.spl
rename to gemrb/unhardcoded/pst/mswarm.spl
diff --git a/gemrb/override/pst/music.2da b/gemrb/unhardcoded/pst/music.2da
similarity index 100%
rename from gemrb/override/pst/music.2da
rename to gemrb/unhardcoded/pst/music.2da
diff --git a/gemrb/override/pst/nbolt.pro b/gemrb/unhardcoded/pst/nbolt.pro
similarity index 100%
rename from gemrb/override/pst/nbolt.pro
rename to gemrb/unhardcoded/pst/nbolt.pro
diff --git a/gemrb/override/pst/orb.spl b/gemrb/unhardcoded/pst/orb.spl
similarity index 100%
rename from gemrb/override/pst/orb.spl
rename to gemrb/unhardcoded/pst/orb.spl
diff --git a/gemrb/override/pst/orngtint.spl b/gemrb/unhardcoded/pst/orngtint.spl
similarity index 100%
rename from gemrb/override/pst/orngtint.spl
rename to gemrb/unhardcoded/pst/orngtint.spl
diff --git a/gemrb/unhardcoded/pst/overlay.2da b/gemrb/unhardcoded/pst/overlay.2da
new file mode 100644
index 0000000..b00a969
--- /dev/null
+++ b/gemrb/unhardcoded/pst/overlay.2da
@@ -0,0 +1,35 @@
+2DA V1.0
+*
+ VVC UNDER FLAGS
+SANCTUARY SANCTRY 0 1
+ENTANGLE WEBENTD 1 0
+WISP WISP 0 0
+SHIELDGLOBE SPSHIELD 0 1
+GREASE GREASED 1 0
+WEB WEBENTD 1 0
+MINORGLOBE MINORGLB 0 1
+GLOBE GOINVUC 0 1
+FLAMESHROUD SOFLAMC 0 0
+ANTIMAGIC AMSHELC 0 0
+RESILIENT ORSPHEC 0 0
+PROTFROMMISS PFNMISC 0 0
+CLOAKOFFEAR COFEARC 0 0
+ENTROPY ESHIELC 0 0
+FIREAURA FIAURAC 0 0
+FROSTAURA FRAURAC 0 0
+INSECT IPLAGUC 0 0
+STORMSHELL SSHELLC 0 0
+LATHANDER1 SOLATC1 0 0
+LATHANDER2 SOLATC2 1 0
+GLATHANDER1 GSOLAC1 0 0
+GLATHANDER2 GSOLAC2 1 0
+SEVENEYES1 SEYESC1 0 0
+SEVENEYES2 SEYESC2 1 0
+BOUNCE SPTURNI2 1 0
+BOUNCE2 SPSTURNI 1 0
+FIRESHIELD1 FSHIRC1 0 0
+FIRESHIELD2 FSHIRC2 1 0
+ICESHIELD1 FSHIBC1 0 0
+ICESHIELD2 FSHIBC2 1 0
+TORTOISE TSHELLC 0 0
+DEATHARMOR DARMORC 0 0
diff --git a/gemrb/override/pst/pacify.pro b/gemrb/unhardcoded/pst/pacify.pro
similarity index 100%
rename from gemrb/override/pst/pacify.pro
rename to gemrb/unhardcoded/pst/pacify.pro
diff --git a/gemrb/override/pst/pacify.spl b/gemrb/unhardcoded/pst/pacify.spl
similarity index 100%
rename from gemrb/override/pst/pacify.spl
rename to gemrb/unhardcoded/pst/pacify.spl
diff --git a/gemrb/override/iwd2/pathfind.2da b/gemrb/unhardcoded/pst/pathfind.2da
similarity index 100%
rename from gemrb/override/iwd2/pathfind.2da
rename to gemrb/unhardcoded/pst/pathfind.2da
diff --git a/gemrb/override/pst/pdolls.2da b/gemrb/unhardcoded/pst/pdolls.2da
similarity index 100%
rename from gemrb/override/pst/pdolls.2da
rename to gemrb/unhardcoded/pst/pdolls.2da
diff --git a/gemrb/override/pst/poo.spl b/gemrb/unhardcoded/pst/poo.spl
similarity index 100%
rename from gemrb/override/pst/poo.spl
rename to gemrb/unhardcoded/pst/poo.spl
diff --git a/gemrb/override/pst/poone.pro b/gemrb/unhardcoded/pst/poone.pro
similarity index 100%
rename from gemrb/override/pst/poone.pro
rename to gemrb/unhardcoded/pst/poone.pro
diff --git a/gemrb/unhardcoded/pst/proftype.2da b/gemrb/unhardcoded/pst/proftype.2da
new file mode 100644
index 0000000..ba02e94
--- /dev/null
+++ b/gemrb/unhardcoded/pst/proftype.2da
@@ -0,0 +1,45 @@
+2DA V1.0
+-1
+ OLD_PROFICIENCY
+0 -1
+1 -1
+2 -1
+3 -1
+4 -1
+5 -1
+6 -1
+7 -1
+8 -1
+9 -1
+10 -1
+11 -1
+12 -1
+13 -1
+14 -1
+15_BOW 5
+16_DAGGER 1
+17_MACE 4
+18_SLING -1
+19_SWORD 1
+20_BIG 1
+21_HAMMER 2
+22_MS -1
+23_FLAIL -1
+24_DART -1
+25_AXE 3
+26_STAFF 4
+27_XBOW 5
+28_HAND 0
+29_SPEAR -1
+30_HALBERD -1
+31 -1
+32 -1
+33 -1
+34 -1
+35 -1
+36 -1
+37 -1
+38 -1
+39 -1
+40 -1
+41_TEETH 0
diff --git a/gemrb/override/pst/pwb.spl b/gemrb/unhardcoded/pst/pwb.spl
similarity index 100%
rename from gemrb/override/pst/pwb.spl
rename to gemrb/unhardcoded/pst/pwb.spl
diff --git a/gemrb/override/pst/pwblind.pro b/gemrb/unhardcoded/pst/pwblind.pro
similarity index 100%
rename from gemrb/override/pst/pwblind.pro
rename to gemrb/unhardcoded/pst/pwblind.pro
diff --git a/gemrb/override/pst/pwk.spl b/gemrb/unhardcoded/pst/pwk.spl
similarity index 100%
rename from gemrb/override/pst/pwk.spl
rename to gemrb/unhardcoded/pst/pwk.spl
diff --git a/gemrb/override/pst/pwkill.pro b/gemrb/unhardcoded/pst/pwkill.pro
similarity index 100%
rename from gemrb/override/pst/pwkill.pro
rename to gemrb/unhardcoded/pst/pwkill.pro
diff --git a/gemrb/override/pst/races.2da b/gemrb/unhardcoded/pst/races.2da
similarity index 100%
rename from gemrb/override/pst/races.2da
rename to gemrb/unhardcoded/pst/races.2da
diff --git a/gemrb/override/pst/randitem.2da b/gemrb/unhardcoded/pst/randitem.2da
similarity index 100%
rename from gemrb/override/pst/randitem.2da
rename to gemrb/unhardcoded/pst/randitem.2da
diff --git a/gemrb/override/pst/rdead.pro b/gemrb/unhardcoded/pst/rdead.pro
similarity index 100%
rename from gemrb/override/pst/rdead.pro
rename to gemrb/unhardcoded/pst/rdead.pro
diff --git a/gemrb/override/pst/rdead.spl b/gemrb/unhardcoded/pst/rdead.spl
similarity index 100%
rename from gemrb/override/pst/rdead.spl
rename to gemrb/unhardcoded/pst/rdead.spl
diff --git a/gemrb/override/pst/rock.pro b/gemrb/unhardcoded/pst/rock.pro
similarity index 100%
rename from gemrb/override/pst/rock.pro
rename to gemrb/unhardcoded/pst/rock.pro
diff --git a/gemrb/override/pst/rotorm.pro b/gemrb/unhardcoded/pst/rotorm.pro
similarity index 100%
rename from gemrb/override/pst/rotorm.pro
rename to gemrb/unhardcoded/pst/rotorm.pro
diff --git a/gemrb/override/pst/rune.2da b/gemrb/unhardcoded/pst/rune.2da
similarity index 100%
rename from gemrb/override/pst/rune.2da
rename to gemrb/unhardcoded/pst/rune.2da
diff --git a/gemrb/override/pst/rune.pro b/gemrb/unhardcoded/pst/rune.pro
similarity index 100%
rename from gemrb/override/pst/rune.pro
rename to gemrb/unhardcoded/pst/rune.pro
diff --git a/gemrb/override/pst/rune.spl b/gemrb/unhardcoded/pst/rune.spl
similarity index 100%
rename from gemrb/override/pst/rune.spl
rename to gemrb/unhardcoded/pst/rune.spl
diff --git a/gemrb/override/pst/s015hwav.vvc b/gemrb/unhardcoded/pst/s015hwav.vvc
similarity index 100%
rename from gemrb/override/pst/s015hwav.vvc
rename to gemrb/unhardcoded/pst/s015hwav.vvc
diff --git a/gemrb/override/pst/s025melt.vvc b/gemrb/unhardcoded/pst/s025melt.vvc
similarity index 100%
rename from gemrb/override/pst/s025melt.vvc
rename to gemrb/unhardcoded/pst/s025melt.vvc
diff --git a/gemrb/override/pst/s046ist2.vvc b/gemrb/unhardcoded/pst/s046ist2.vvc
similarity index 100%
rename from gemrb/override/pst/s046ist2.vvc
rename to gemrb/unhardcoded/pst/s046ist2.vvc
diff --git a/gemrb/override/pst/s046istm.vvc b/gemrb/unhardcoded/pst/s046istm.vvc
similarity index 100%
rename from gemrb/override/pst/s046istm.vvc
rename to gemrb/unhardcoded/pst/s046istm.vvc
diff --git a/gemrb/override/pst/s052cone.vvc b/gemrb/unhardcoded/pst/s052cone.vvc
similarity index 100%
rename from gemrb/override/pst/s052cone.vvc
rename to gemrb/unhardcoded/pst/s052cone.vvc
diff --git a/gemrb/override/pst/s056itrl.vvc b/gemrb/unhardcoded/pst/s056itrl.vvc
similarity index 100%
rename from gemrb/override/pst/s056itrl.vvc
rename to gemrb/unhardcoded/pst/s056itrl.vvc
diff --git a/gemrb/override/pst/s061beam.vvc b/gemrb/unhardcoded/pst/s061beam.vvc
similarity index 100%
rename from gemrb/override/pst/s061beam.vvc
rename to gemrb/unhardcoded/pst/s061beam.vvc
diff --git a/gemrb/unhardcoded/pst/s061glwb.vvc b/gemrb/unhardcoded/pst/s061glwb.vvc
new file mode 100644
index 0000000..c7d1e66
Binary files /dev/null and b/gemrb/unhardcoded/pst/s061glwb.vvc differ
diff --git a/gemrb/unhardcoded/pst/s061shll.vvc b/gemrb/unhardcoded/pst/s061shll.vvc
new file mode 100644
index 0000000..272c5df
Binary files /dev/null and b/gemrb/unhardcoded/pst/s061shll.vvc differ
diff --git a/gemrb/override/pst/s064bglt.vvc b/gemrb/unhardcoded/pst/s064bglt.vvc
similarity index 100%
rename from gemrb/override/pst/s064bglt.vvc
rename to gemrb/unhardcoded/pst/s064bglt.vvc
diff --git a/gemrb/override/pst/s064hglt.vvc b/gemrb/unhardcoded/pst/s064hglt.vvc
similarity index 100%
rename from gemrb/override/pst/s064hglt.vvc
rename to gemrb/unhardcoded/pst/s064hglt.vvc
diff --git a/gemrb/override/pst/s064lort.vvc b/gemrb/unhardcoded/pst/s064lort.vvc
similarity index 100%
rename from gemrb/override/pst/s064lort.vvc
rename to gemrb/unhardcoded/pst/s064lort.vvc
diff --git a/gemrb/override/pst/s064uplt.vvc b/gemrb/unhardcoded/pst/s064uplt.vvc
similarity index 100%
rename from gemrb/override/pst/s064uplt.vvc
rename to gemrb/unhardcoded/pst/s064uplt.vvc
diff --git a/gemrb/override/pst/s070boom.vvc b/gemrb/unhardcoded/pst/s070boom.vvc
similarity index 100%
rename from gemrb/override/pst/s070boom.vvc
rename to gemrb/unhardcoded/pst/s070boom.vvc
diff --git a/gemrb/override/pst/s075wdsh.vvc b/gemrb/unhardcoded/pst/s075wdsh.vvc
similarity index 100%
rename from gemrb/override/pst/s075wdsh.vvc
rename to gemrb/unhardcoded/pst/s075wdsh.vvc
diff --git a/gemrb/override/pst/s914bgbl.vvc b/gemrb/unhardcoded/pst/s914bgbl.vvc
similarity index 100%
rename from gemrb/override/pst/s914bgbl.vvc
rename to gemrb/unhardcoded/pst/s914bgbl.vvc
diff --git a/gemrb/override/pst/s914hgbl.vvc b/gemrb/unhardcoded/pst/s914hgbl.vvc
similarity index 100%
rename from gemrb/override/pst/s914hgbl.vvc
rename to gemrb/unhardcoded/pst/s914hgbl.vvc
diff --git a/gemrb/override/pst/s914rune.vvc b/gemrb/unhardcoded/pst/s914rune.vvc
similarity index 100%
rename from gemrb/override/pst/s914rune.vvc
rename to gemrb/unhardcoded/pst/s914rune.vvc
diff --git a/gemrb/override/pst/savegame.2da b/gemrb/unhardcoded/pst/savegame.2da
similarity index 100%
rename from gemrb/override/pst/savegame.2da
rename to gemrb/unhardcoded/pst/savegame.2da
diff --git a/gemrb/override/pst/script.2da b/gemrb/unhardcoded/pst/script.2da
similarity index 100%
rename from gemrb/override/pst/script.2da
rename to gemrb/unhardcoded/pst/script.2da
diff --git a/gemrb/override/pst/shammer.pro b/gemrb/unhardcoded/pst/shammer.pro
similarity index 100%
rename from gemrb/override/pst/shammer.pro
rename to gemrb/unhardcoded/pst/shammer.pro
diff --git a/gemrb/override/pst/shammer.spl b/gemrb/unhardcoded/pst/shammer.spl
similarity index 100%
rename from gemrb/override/pst/shammer.spl
rename to gemrb/unhardcoded/pst/shammer.spl
diff --git a/gemrb/unhardcoded/pst/sigil.2da b/gemrb/unhardcoded/pst/sigil.2da
new file mode 100644
index 0000000..6061ee9
--- /dev/null
+++ b/gemrb/unhardcoded/pst/sigil.2da
@@ -0,0 +1,20 @@
+2DA V1.0
+0
+ AREA REGION
+1 AR0100 to0101
+2 AR0100 to0200
+3 AR0100 to0300
+4 AR0101 to0100
+5 AR0200 to0100
+6 AR0200 to0301
+7 AR0200 to0400
+8 AR0300 to0100
+9 AR0300 to0301
+a AR0300 to0400
+b AR0301 to0200
+c AR0301 to0300
+d AR0400 to0200
+e AR0400 to0300
+f AR0500 to0600
+g AR0500 to0405
+h AR0600 to0500
diff --git a/gemrb/override/pst/skmob.pro b/gemrb/unhardcoded/pst/skmob.pro
similarity index 100%
rename from gemrb/override/pst/skmob.pro
rename to gemrb/unhardcoded/pst/skmob.pro
diff --git a/gemrb/override/pst/skmob.spl b/gemrb/unhardcoded/pst/skmob.spl
similarity index 100%
rename from gemrb/override/pst/skmob.spl
rename to gemrb/unhardcoded/pst/skmob.spl
diff --git a/gemrb/override/pst/skmob2.pro b/gemrb/unhardcoded/pst/skmob2.pro
similarity index 100%
rename from gemrb/override/pst/skmob2.pro
rename to gemrb/unhardcoded/pst/skmob2.pro
diff --git a/gemrb/override/pst/sleep.pro b/gemrb/unhardcoded/pst/sleep.pro
similarity index 100%
rename from gemrb/override/pst/sleep.pro
rename to gemrb/unhardcoded/pst/sleep.pro
diff --git a/gemrb/override/pst/slots.ids b/gemrb/unhardcoded/pst/slots.ids
similarity index 100%
rename from gemrb/override/pst/slots.ids
rename to gemrb/unhardcoded/pst/slots.ids
diff --git a/gemrb/override/pst/slottype.2da b/gemrb/unhardcoded/pst/slottype.2da
similarity index 100%
rename from gemrb/override/pst/slottype.2da
rename to gemrb/unhardcoded/pst/slottype.2da
diff --git a/gemrb/unhardcoded/pst/source/baldur.baf b/gemrb/unhardcoded/pst/source/baldur.baf
new file mode 100644
index 0000000..bd2b993
--- /dev/null
+++ b/gemrb/unhardcoded/pst/source/baldur.baf
@@ -0,0 +1,157 @@
+IF
+ !Faction(Protagonist,ANARCHIST)
+ Global("JOIN_ANARCHISTS","GLOBAL",1)
+THEN
+ RESPONSE #100
+ ChangeFaction(Protagonist,ANARCHIST)
+END
+
+IF
+ !Faction(Protagonist,SENSATE)
+ Global("JOIN_SENSATES","GLOBAL",1)
+ !Global("JOIN_ANARCHISTS","GLOBAL",1)
+THEN
+ RESPONSE #100
+ ChangeFaction(Protagonist,SENSATE)
+END
+
+IF
+ !Faction(Protagonist,DUSTMEN)
+ Global("JOIN_DUSTMEN","GLOBAL",1)
+ !Global("JOIN_ANARCHISTS","GLOBAL",1)
+THEN
+ RESPONSE #100
+ ChangeFaction(Protagonist,DUSTMEN)
+END
+
+IF
+ !Faction(Protagonist,GODSMAN)
+ Global("JOIN_GODSMEN","GLOBAL",6)
+ !Global("JOIN_ANARCHISTS","GLOBAL",1)
+THEN
+ RESPONSE #100
+ ChangeFaction(Protagonist,GODSMAN)
+END
+
+IF
+ !Faction(Protagonist,XAOSITECT)
+ Global("JOIN_CHAOSMEN","GLOBAL",1)
+ !Global("JOIN_ANARCHISTS","GLOBAL",1)
+THEN
+ RESPONSE #100
+ ChangeFaction(Protagonist,XAOSITECT)
+END
+
+IF
+ Global("game_over","GLOBAL",1)
+THEN
+ RESPONSE #100
+ GlobalSet("game_over","GLOBAL",0)
+ QuitGame(0,0,44963)
+END
+
+IF
+ Global("game_over","GLOBAL",2)
+THEN
+ RESPONSE #100
+ GlobalSet("game_over","GLOBAL",0)
+ QuitGame(0,0,48153)
+END
+
+IF
+ Global("game_over","GLOBAL",3)
+THEN
+ RESPONSE #100
+ GlobalSet("game_over","GLOBAL",0)
+ QuitGame(0,0,48154)
+END
+
+IF
+ Global("game_over","GLOBAL",4)
+THEN
+ RESPONSE #100
+ GlobalSet("game_over","GLOBAL",0)
+ QuitGame(0,0,48155)
+END
+
+IF
+ Global("game_over","GLOBAL",5)
+THEN
+ RESPONSE #100
+ GlobalSet("game_over","GLOBAL",0)
+ QuitGame(0,0,41656)
+END
+
+IF
+ Global("game_over","GLOBAL",6)
+THEN
+ RESPONSE #100
+ GlobalSet("game_over","GLOBAL",0)
+ QuitGame(0,0,67295)
+END
+
+IF
+ Global("AR0200_Visited","GLOBAL",1)
+ Global("Played_Shadow_Movie","GLOBAL",0)
+THEN
+ RESPONSE #100
+ GlobalSet("Played_Shadow_Movie","GLOBAL",1)
+ StartMovie("SS_MSLAB")
+END
+
+IF
+ Global("AR0206_Visited","GLOBAL",1)
+ Global("Played_Shadow_Movie","GLOBAL",0)
+THEN
+ RESPONSE #100
+ GlobalSet("Played_Shadow_Movie","GLOBAL",1)
+ StartMovie("SS_MSLAB")
+END
+
+IF
+ Global("AR0200_Visited","GLOBAL",1)
+ Global("Played_Sigil_Movie","GLOBAL",0)
+THEN
+ RESPONSE #100
+ GlobalSet("Played_Sigil_Movie","GLOBAL",1)
+ StartMovie("SIGIL")
+END
+
+IF
+ GlobalGT("lady","GLOBAL",49)
+ Global("ar1900_visited","GLOBAL",0)
+ UsedExit("sigil",Protagonist)
+ !CreatureInArea("ar1900")
+THEN
+ RESPONSE #100
+ ClearAllActions()
+ ActionOverride(Player6,LeaveParty())
+ ActionOverride(Player5,LeaveParty())
+ ActionOverride(Player4,LeaveParty())
+ ActionOverride(Player3,LeaveParty())
+ ActionOverride(Player2,LeaveParty())
+ //should be the position of mazeentr in ar1900
+ TeleportParty("ar1900",[2559.1895],0)
+END
+
+IF
+ Global("sabotage","GLOBAL",5)
+ CreatureInArea("ar0512")
+ UsedExit("foundry",[PC])
+THEN
+ RESPONSE #100
+ ClearAllActions()
+ TeleportParty("ar0513",[1078.892],0)
+END
+
+IF
+ Global("sabotage","GLOBAL",7)
+ CreatureInArea("ar0512")
+ UsedExit("foundry",[PC])
+THEN
+ RESPONSE #100
+ ClearAllActions()
+ TeleportParty("ar0513",[1078.892],0)
+END
+
+
diff --git a/gemrb/override/pst/sparbknp.pro b/gemrb/unhardcoded/pst/sparbknp.pro
similarity index 100%
rename from gemrb/override/pst/sparbknp.pro
rename to gemrb/unhardcoded/pst/sparbknp.pro
diff --git a/gemrb/override/pst/sparbkpa.pro b/gemrb/unhardcoded/pst/sparbkpa.pro
similarity index 100%
rename from gemrb/override/pst/sparbkpa.pro
rename to gemrb/unhardcoded/pst/sparbkpa.pro
diff --git a/gemrb/override/pst/sparblnp.pro b/gemrb/unhardcoded/pst/sparblnp.pro
similarity index 100%
rename from gemrb/override/pst/sparblnp.pro
rename to gemrb/unhardcoded/pst/sparblnp.pro
diff --git a/gemrb/override/pst/sparblpa.pro b/gemrb/unhardcoded/pst/sparblpa.pro
similarity index 100%
rename from gemrb/override/pst/sparblpa.pro
rename to gemrb/unhardcoded/pst/sparblpa.pro
diff --git a/gemrb/override/pst/sparchnp.pro b/gemrb/unhardcoded/pst/sparchnp.pro
similarity index 100%
rename from gemrb/override/pst/sparchnp.pro
rename to gemrb/unhardcoded/pst/sparchnp.pro
diff --git a/gemrb/override/pst/sparchpa.pro b/gemrb/unhardcoded/pst/sparchpa.pro
similarity index 100%
rename from gemrb/override/pst/sparchpa.pro
rename to gemrb/unhardcoded/pst/sparchpa.pro
diff --git a/gemrb/override/pst/spargonp.pro b/gemrb/unhardcoded/pst/spargonp.pro
similarity index 100%
rename from gemrb/override/pst/spargonp.pro
rename to gemrb/unhardcoded/pst/spargonp.pro
diff --git a/gemrb/override/pst/spargopa.pro b/gemrb/unhardcoded/pst/spargopa.pro
similarity index 100%
rename from gemrb/override/pst/spargopa.pro
rename to gemrb/unhardcoded/pst/spargopa.pro
diff --git a/gemrb/override/pst/spargrnp.pro b/gemrb/unhardcoded/pst/spargrnp.pro
similarity index 100%
rename from gemrb/override/pst/spargrnp.pro
rename to gemrb/unhardcoded/pst/spargrnp.pro
diff --git a/gemrb/override/pst/spargrpa.pro b/gemrb/unhardcoded/pst/spargrpa.pro
similarity index 100%
rename from gemrb/override/pst/spargrpa.pro
rename to gemrb/unhardcoded/pst/spargrpa.pro
diff --git a/gemrb/override/pst/sparicnp.pro b/gemrb/unhardcoded/pst/sparicnp.pro
similarity index 100%
rename from gemrb/override/pst/sparicnp.pro
rename to gemrb/unhardcoded/pst/sparicnp.pro
diff --git a/gemrb/override/pst/sparicpa.pro b/gemrb/unhardcoded/pst/sparicpa.pro
similarity index 100%
rename from gemrb/override/pst/sparicpa.pro
rename to gemrb/unhardcoded/pst/sparicpa.pro
diff --git a/gemrb/override/pst/sparklbk.pro b/gemrb/unhardcoded/pst/sparklbk.pro
similarity index 100%
rename from gemrb/override/pst/sparklbk.pro
rename to gemrb/unhardcoded/pst/sparklbk.pro
diff --git a/gemrb/override/pst/sparklbl.pro b/gemrb/unhardcoded/pst/sparklbl.pro
similarity index 100%
rename from gemrb/override/pst/sparklbl.pro
rename to gemrb/unhardcoded/pst/sparklbl.pro
diff --git a/gemrb/override/pst/sparklch.pro b/gemrb/unhardcoded/pst/sparklch.pro
similarity index 100%
rename from gemrb/override/pst/sparklch.pro
rename to gemrb/unhardcoded/pst/sparklch.pro
diff --git a/gemrb/override/pst/sparklgo.pro b/gemrb/unhardcoded/pst/sparklgo.pro
similarity index 100%
rename from gemrb/override/pst/sparklgo.pro
rename to gemrb/unhardcoded/pst/sparklgo.pro
diff --git a/gemrb/override/pst/sparklgr.pro b/gemrb/unhardcoded/pst/sparklgr.pro
similarity index 100%
rename from gemrb/override/pst/sparklgr.pro
rename to gemrb/unhardcoded/pst/sparklgr.pro
diff --git a/gemrb/override/pst/sparklic.pro b/gemrb/unhardcoded/pst/sparklic.pro
similarity index 100%
rename from gemrb/override/pst/sparklic.pro
rename to gemrb/unhardcoded/pst/sparklic.pro
diff --git a/gemrb/override/pst/sparklma.pro b/gemrb/unhardcoded/pst/sparklma.pro
similarity index 100%
rename from gemrb/override/pst/sparklma.pro
rename to gemrb/unhardcoded/pst/sparklma.pro
diff --git a/gemrb/override/pst/sparklor.pro b/gemrb/unhardcoded/pst/sparklor.pro
similarity index 100%
rename from gemrb/override/pst/sparklor.pro
rename to gemrb/unhardcoded/pst/sparklor.pro
diff --git a/gemrb/override/pst/sparklpu.pro b/gemrb/unhardcoded/pst/sparklpu.pro
similarity index 100%
rename from gemrb/override/pst/sparklpu.pro
rename to gemrb/unhardcoded/pst/sparklpu.pro
diff --git a/gemrb/override/pst/sparklre.pro b/gemrb/unhardcoded/pst/sparklre.pro
similarity index 100%
rename from gemrb/override/pst/sparklre.pro
rename to gemrb/unhardcoded/pst/sparklre.pro
diff --git a/gemrb/override/pst/sparklst.pro b/gemrb/unhardcoded/pst/sparklst.pro
similarity index 100%
rename from gemrb/override/pst/sparklst.pro
rename to gemrb/unhardcoded/pst/sparklst.pro
diff --git a/gemrb/override/pst/sparmanp.pro b/gemrb/unhardcoded/pst/sparmanp.pro
similarity index 100%
rename from gemrb/override/pst/sparmanp.pro
rename to gemrb/unhardcoded/pst/sparmanp.pro
diff --git a/gemrb/override/pst/sparmapa.pro b/gemrb/unhardcoded/pst/sparmapa.pro
similarity index 100%
rename from gemrb/override/pst/sparmapa.pro
rename to gemrb/unhardcoded/pst/sparmapa.pro
diff --git a/gemrb/override/pst/sparornp.pro b/gemrb/unhardcoded/pst/sparornp.pro
similarity index 100%
rename from gemrb/override/pst/sparornp.pro
rename to gemrb/unhardcoded/pst/sparornp.pro
diff --git a/gemrb/override/pst/sparorpa.pro b/gemrb/unhardcoded/pst/sparorpa.pro
similarity index 100%
rename from gemrb/override/pst/sparorpa.pro
rename to gemrb/unhardcoded/pst/sparorpa.pro
diff --git a/gemrb/override/pst/sparpunp.pro b/gemrb/unhardcoded/pst/sparpunp.pro
similarity index 100%
rename from gemrb/override/pst/sparpunp.pro
rename to gemrb/unhardcoded/pst/sparpunp.pro
diff --git a/gemrb/override/pst/sparpupa.pro b/gemrb/unhardcoded/pst/sparpupa.pro
similarity index 100%
rename from gemrb/override/pst/sparpupa.pro
rename to gemrb/unhardcoded/pst/sparpupa.pro
diff --git a/gemrb/override/pst/sparrenp.pro b/gemrb/unhardcoded/pst/sparrenp.pro
similarity index 100%
rename from gemrb/override/pst/sparrenp.pro
rename to gemrb/unhardcoded/pst/sparrenp.pro
diff --git a/gemrb/override/pst/sparrepa.pro b/gemrb/unhardcoded/pst/sparrepa.pro
similarity index 100%
rename from gemrb/override/pst/sparrepa.pro
rename to gemrb/unhardcoded/pst/sparrepa.pro
diff --git a/gemrb/override/pst/sparstnp.pro b/gemrb/unhardcoded/pst/sparstnp.pro
similarity index 100%
rename from gemrb/override/pst/sparstnp.pro
rename to gemrb/unhardcoded/pst/sparstnp.pro
diff --git a/gemrb/override/pst/sparstpa.pro b/gemrb/unhardcoded/pst/sparstpa.pro
similarity index 100%
rename from gemrb/override/pst/sparstpa.pro
rename to gemrb/unhardcoded/pst/sparstpa.pro
diff --git a/gemrb/override/pst/speak.eff b/gemrb/unhardcoded/pst/speak.eff
similarity index 100%
rename from gemrb/override/pst/speak.eff
rename to gemrb/unhardcoded/pst/speak.eff
diff --git a/gemrb/override/pst/spear.pro b/gemrb/unhardcoded/pst/spear.pro
similarity index 100%
rename from gemrb/override/pst/spear.pro
rename to gemrb/unhardcoded/pst/spear.pro
diff --git a/gemrb/override/pst/spearex.pro b/gemrb/unhardcoded/pst/spearex.pro
similarity index 100%
rename from gemrb/override/pst/spearex.pro
rename to gemrb/unhardcoded/pst/spearex.pro
diff --git a/gemrb/override/pst/spfirebl.pro b/gemrb/unhardcoded/pst/spfirebl.pro
similarity index 100%
rename from gemrb/override/pst/spfirebl.pro
rename to gemrb/unhardcoded/pst/spfirebl.pro
diff --git a/gemrb/override/pst/spklarbk.pro b/gemrb/unhardcoded/pst/spklarbk.pro
similarity index 100%
rename from gemrb/override/pst/spklarbk.pro
rename to gemrb/unhardcoded/pst/spklarbk.pro
diff --git a/gemrb/override/pst/spklarbl.pro b/gemrb/unhardcoded/pst/spklarbl.pro
similarity index 100%
rename from gemrb/override/pst/spklarbl.pro
rename to gemrb/unhardcoded/pst/spklarbl.pro
diff --git a/gemrb/override/pst/spklarch.pro b/gemrb/unhardcoded/pst/spklarch.pro
similarity index 100%
rename from gemrb/override/pst/spklarch.pro
rename to gemrb/unhardcoded/pst/spklarch.pro
diff --git a/gemrb/override/pst/spklargo.pro b/gemrb/unhardcoded/pst/spklargo.pro
similarity index 100%
rename from gemrb/override/pst/spklargo.pro
rename to gemrb/unhardcoded/pst/spklargo.pro
diff --git a/gemrb/override/pst/spklargr.pro b/gemrb/unhardcoded/pst/spklargr.pro
similarity index 100%
rename from gemrb/override/pst/spklargr.pro
rename to gemrb/unhardcoded/pst/spklargr.pro
diff --git a/gemrb/override/pst/spklaric.pro b/gemrb/unhardcoded/pst/spklaric.pro
similarity index 100%
rename from gemrb/override/pst/spklaric.pro
rename to gemrb/unhardcoded/pst/spklaric.pro
diff --git a/gemrb/override/pst/spklarma.pro b/gemrb/unhardcoded/pst/spklarma.pro
similarity index 100%
rename from gemrb/override/pst/spklarma.pro
rename to gemrb/unhardcoded/pst/spklarma.pro
diff --git a/gemrb/override/pst/spklaror.pro b/gemrb/unhardcoded/pst/spklaror.pro
similarity index 100%
rename from gemrb/override/pst/spklaror.pro
rename to gemrb/unhardcoded/pst/spklaror.pro
diff --git a/gemrb/override/pst/spklarpu.pro b/gemrb/unhardcoded/pst/spklarpu.pro
similarity index 100%
rename from gemrb/override/pst/spklarpu.pro
rename to gemrb/unhardcoded/pst/spklarpu.pro
diff --git a/gemrb/override/pst/spklarre.pro b/gemrb/unhardcoded/pst/spklarre.pro
similarity index 100%
rename from gemrb/override/pst/spklarre.pro
rename to gemrb/unhardcoded/pst/spklarre.pro
diff --git a/gemrb/override/pst/spklarst.pro b/gemrb/unhardcoded/pst/spklarst.pro
similarity index 100%
rename from gemrb/override/pst/spklarst.pro
rename to gemrb/unhardcoded/pst/spklarst.pro
diff --git a/gemrb/override/pst/splspec.2da b/gemrb/unhardcoded/pst/splspec.2da
similarity index 100%
rename from gemrb/override/pst/splspec.2da
rename to gemrb/unhardcoded/pst/splspec.2da
diff --git a/gemrb/override/pst/spscorch.pro b/gemrb/unhardcoded/pst/spscorch.pro
similarity index 100%
rename from gemrb/override/pst/spscorch.pro
rename to gemrb/unhardcoded/pst/spscorch.pro
diff --git a/gemrb/override/pst/spscoric.pro b/gemrb/unhardcoded/pst/spscoric.pro
similarity index 100%
rename from gemrb/override/pst/spscoric.pro
rename to gemrb/unhardcoded/pst/spscoric.pro
diff --git a/gemrb/unhardcoded/pst/sshadow.pro b/gemrb/unhardcoded/pst/sshadow.pro
new file mode 100644
index 0000000..21293c7
Binary files /dev/null and b/gemrb/unhardcoded/pst/sshadow.pro differ
diff --git a/gemrb/unhardcoded/pst/sshadow.spl b/gemrb/unhardcoded/pst/sshadow.spl
new file mode 100644
index 0000000..de2fb90
Binary files /dev/null and b/gemrb/unhardcoded/pst/sshadow.spl differ
diff --git a/gemrb/override/bg1/start.2da b/gemrb/unhardcoded/pst/start.2da
similarity index 100%
rename from gemrb/override/bg1/start.2da
rename to gemrb/unhardcoded/pst/start.2da
diff --git a/gemrb/override/pst/states.2da b/gemrb/unhardcoded/pst/states.2da
similarity index 100%
rename from gemrb/override/pst/states.2da
rename to gemrb/unhardcoded/pst/states.2da
diff --git a/gemrb/override/pst/stone.pro b/gemrb/unhardcoded/pst/stone.pro
similarity index 100%
rename from gemrb/override/pst/stone.pro
rename to gemrb/unhardcoded/pst/stone.pro
diff --git a/gemrb/override/pst/stories.pro b/gemrb/unhardcoded/pst/stories.pro
similarity index 100%
rename from gemrb/override/pst/stories.pro
rename to gemrb/unhardcoded/pst/stories.pro
diff --git a/gemrb/override/pst/stories.spl b/gemrb/unhardcoded/pst/stories.spl
similarity index 100%
rename from gemrb/override/pst/stories.spl
rename to gemrb/unhardcoded/pst/stories.spl
diff --git a/gemrb/override/pst/str.spl b/gemrb/unhardcoded/pst/str.spl
similarity index 100%
rename from gemrb/override/pst/str.spl
rename to gemrb/unhardcoded/pst/str.spl
diff --git a/gemrb/override/pst/strength.pro b/gemrb/unhardcoded/pst/strength.pro
similarity index 100%
rename from gemrb/override/pst/strength.pro
rename to gemrb/unhardcoded/pst/strength.pro
diff --git a/gemrb/unhardcoded/pst/strings.2da b/gemrb/unhardcoded/pst/strings.2da
new file mode 100644
index 0000000..0e50bb2
--- /dev/null
+++ b/gemrb/unhardcoded/pst/strings.2da
@@ -0,0 +1,187 @@
+2DA V1.0
+-1
+ STRREF
+SCATTERED 55021
+WHOLEPARTY -1
+DOORLOCKED 19309
+MAGICTRAP 19289
+NORMALTRAP 19289
+TRAP -1
+CANNOTGO -1
+TRAPREMOVED 19287
+OVERSTOCKED 19283
+SLEEP -1
+AMBUSH -1
+CONTLOCKED 22031
+NOMONEY -1
+CURSED 50538
+SPELLDISRUPT -1
+DIED -1
+MAYNOTREST 34599
+CANTRESTMONS 34600
+CANTSAVEMONS 34598
+CANTSAVE 34592
+NODIALOG -1
+CANTSAVEDIALOG 34593
+CANTSAVEDIALOG2 -1
+CANTSAVEMOVIE 34594
+TARGETBUSY -1
+CANTTALKTRANS -1
+GOTGOLD 19252
+LOSTGOLD 19253
+GOTXP 19254
+LOSTXP 19255
+GOTITEM 19256
+LOSTITEM 19258
+GOTREP 19259
+LOSTREP 19260
+GOTABILITY 19307
+GOTSPELL -1
+GOTSONG -1
+NOTHINGTOSAY -1
+JOURNALCHANGE 37096
+WORLDMAPCHANGE 19264
+PAUSED 39436
+UNPAUSED -1
+SCRIPTPAUSED 39436
+AP_UNUSABLE 39436
+AP_ATTACKED 39436
+AP_HIT 39436
+AP_WOUNDED 39436
+AP_DEAD 39436
+AP_NOTARGET 39436
+AP_ENDROUND 39436
+AP_ENEMY 39436
+AP_TRAP 39436
+AP_SPELLCAST 39436
+AP_GENERIC 39436
+AP_RESERVED1 39436
+AP_RESERVED2 39436
+AP_RESERVED3 39436
+CHARMED -1
+DIRECHARMED -1
+CONTROLLED -1
+EVIL -1
+GNE_NEUTRAL -1
+GOOD -1
+STR_LAWFUL -1
+LNC_NEUTRAL -1
+CHAOTIC -1
+ACTION_CAST -1
+ACTION_ATTACK -1
+ACTION_TURN -1
+ACTION_SONG -1
+ACTION_FINDTRAP -1
+MAGICWEAPON -1
+OFFHAND_USED -1
+TWOHANDED_USED -1
+CANNOT_USE_ITEM 50532
+CANT_DROP_ITEM 50569
+NOT_IN_OFFHAND -1
+ITEM_IS_CURSED 50538
+NO_CRITICAL 19273
+TRACKING -1
+TRACKINGFAILED -1
+DOOR_NOPICK 23169
+CONT_NOPICK 23169
+CANTSAVECOMBAT -1
+CANTSAVENOCTRL -1
+LOCKPICK_DONE 19281
+LOCKPICK_FAILED 19282
+STATIC_DISSIPATE -1
+LIGHTNING_DISSIPATE -1
+HAS_NO_ABILITY 50545
+NEEDS_IDENTIFY 50544
+WRONG_ITEMTYPE 50537
+HAS_ITEMEXCL -1
+PICKPOCKET_DONE -1
+PICKPOCKET_NONE 19304
+PICKPOCKET_FAIL 19303
+PICKPOCKET_EVIL 19302
+PICKPOCKET_ARMOR 19301
+USING_FEAT -1
+STOPPED_FEAT -1
+DISARM_DONE 16520
+DISARM_FAIL 1608
+DOORBASH_DONE -1
+DOORBASH_FAIL -1
+CONTBASH_DONE -1
+CONTBASH_FAIL -1
+MAYNOTSETTRAP -1
+SNAREFAILED -1
+SNARESUCCEED -1
+NOMORETRAP -1
+DISABLEDMAGE -1
+SAVESUCCEED 28646
+QSAVESUCCEED 50461
+UNINJURED -1
+INJURED1 -1
+INJURED2 -1
+INJURED3 -1
+INJURED4 -1
+HOURS 19313
+HOUR 19312
+DAYS -1
+DAY -1
+REST 19262
+JOURNEY -1
+SUMMONINGLIMIT -1
+INVFULL 19257
+TOOFARAWAY 4276
+DAMAGE_IMMUNITY -1
+DAMAGE_STR1 -1
+DAMAGE_STR2 -1
+DAMAGE_STR3 -1
+DMG_POISON -1
+DMG_MAGIC -1
+DMG_MISSILE -1
+DMG_SLASHING -1
+DMG_PIERCING -1
+DMG_CRUSHING -1
+DMG_FIRE -1
+DMG_ELECTRIC -1
+DMG_COLD -1
+DMG_ACID -1
+DMG_OTHER -1
+GOTQUESTXP -1
+LEVELUP 4246
+INVFULL_ITEMDROP 37079
+CONT_DUP -1
+CONT_TRIG -1
+CONT_FAIL -1
+SEQ_DUP -1
+CRITICAL_HIT 19272
+CRITICAL_MISS 19274
+DEATH -1
+BACKSTAB 12128
+BACKSTAB_BAD 19271
+BACKSTAB_FAIL -1
+CASTER_LVL_INC -1
+CASTER_LVL_DEC -1
+CHARS_EXPORTED -1
+PALADIN_FALL -1
+RANGER_FALL -1
+RES_RESISTED -1
+DEADMAGIC_FAIL -1
+MISCASTMAGIC -1
+WILDSURGE -1
+FAMBLOCK -1
+FAMPROTAGONIST -1
+MAGIC_RESISTED -1
+CANTSAVESTORE -1
+NOSEE_NOCAST -1
+AURACLEANSED -1
+INDOOR_FAIL -1
+SPELL_DISRUPTED -1
+CHAOSSHIELD -1
+RAPIDSHOT -1
+HAMSTRING -1
+ARTERIAL -1
+EXPERTISE -1
+POWERATTACK -1
+CLEAVE -1
+HELD -1
+SLOWED 36999
+CANTMOVE 37007
+CASTS -1
+WEAPONINEFFECTIVE -1
diff --git a/gemrb/override/pst/tlaugh.pro b/gemrb/unhardcoded/pst/tlaugh.pro
similarity index 100%
rename from gemrb/override/pst/tlaugh.pro
rename to gemrb/unhardcoded/pst/tlaugh.pro
diff --git a/gemrb/override/pst/trapglyp.pro b/gemrb/unhardcoded/pst/trapglyp.pro
similarity index 100%
rename from gemrb/override/pst/trapglyp.pro
rename to gemrb/unhardcoded/pst/trapglyp.pro
diff --git a/gemrb/override/pst/trapskul.pro b/gemrb/unhardcoded/pst/trapskul.pro
similarity index 100%
rename from gemrb/override/pst/trapskul.pro
rename to gemrb/unhardcoded/pst/trapskul.pro
diff --git a/gemrb/override/pst/vtouch.pro b/gemrb/unhardcoded/pst/vtouch.pro
similarity index 100%
rename from gemrb/override/pst/vtouch.pro
rename to gemrb/unhardcoded/pst/vtouch.pro
diff --git a/gemrb/override/pst/weapprof.2da b/gemrb/unhardcoded/pst/weapprof.2da
similarity index 100%
rename from gemrb/override/pst/weapprof.2da
rename to gemrb/unhardcoded/pst/weapprof.2da
diff --git a/gemrb/override/pst/web.pro b/gemrb/unhardcoded/pst/web.pro
similarity index 100%
rename from gemrb/override/pst/web.pro
rename to gemrb/unhardcoded/pst/web.pro
diff --git a/gemrb/override/pst/wmmos2b.mos b/gemrb/unhardcoded/pst/wmmos2b.mos
similarity index 100%
rename from gemrb/override/pst/wmmos2b.mos
rename to gemrb/unhardcoded/pst/wmmos2b.mos
diff --git a/gemrb/unhardcoded/shared/Makefile.am b/gemrb/unhardcoded/shared/Makefile.am
new file mode 100644
index 0000000..bc41e17
--- /dev/null
+++ b/gemrb/unhardcoded/shared/Makefile.am
@@ -0,0 +1,3 @@
+sharedunhardcoded_DATA = *.2da *.ids *.spl *.pro *.chu *.ini *.vvc
+sharedunhardcodeddir = $(moddir)/unhardcoded/shared/
+EXTRA_DIST = *.2da *.ids *.spl *.pro *.chu *.ini *.vvc
diff --git a/gemrb/override/shared/avprefg.2da b/gemrb/unhardcoded/shared/avprefg.2da
similarity index 100%
rename from gemrb/override/shared/avprefg.2da
rename to gemrb/unhardcoded/shared/avprefg.2da
diff --git a/gemrb/override/shared/avprefix.2da b/gemrb/unhardcoded/shared/avprefix.2da
similarity index 100%
rename from gemrb/override/shared/avprefix.2da
rename to gemrb/unhardcoded/shared/avprefix.2da
diff --git a/gemrb/override/shared/axeflm.pro b/gemrb/unhardcoded/shared/axeflm.pro
similarity index 100%
rename from gemrb/override/shared/axeflm.pro
rename to gemrb/unhardcoded/shared/axeflm.pro
diff --git a/gemrb/unhardcoded/shared/bardsong.spl b/gemrb/unhardcoded/shared/bardsong.spl
new file mode 100644
index 0000000..8c51a75
Binary files /dev/null and b/gemrb/unhardcoded/shared/bardsong.spl differ
diff --git a/gemrb/unhardcoded/shared/chinese.ini b/gemrb/unhardcoded/shared/chinese.ini
new file mode 100644
index 0000000..bf8c7b8
--- /dev/null
+++ b/gemrb/unhardcoded/shared/chinese.ini
@@ -0,0 +1,3 @@
+[encoding]
+TLKEncoding = GBK
+#TLKEncoding = BIG5
diff --git a/gemrb/unhardcoded/shared/comment.2da b/gemrb/unhardcoded/shared/comment.2da
new file mode 100644
index 0000000..1a73bf0
--- /dev/null
+++ b/gemrb/unhardcoded/shared/comment.2da
@@ -0,0 +1,8 @@
+2DA V1.0
+-1
+ AREAFLAG VC SWITCH
+FOREST 0x10 21 0
+DUNGEON 0x20 23 0
+CITY 8 22 0
+DAY 2 24 1
+
diff --git a/gemrb/override/shared/containr.2da b/gemrb/unhardcoded/shared/containr.2da
similarity index 100%
rename from gemrb/override/shared/containr.2da
rename to gemrb/unhardcoded/shared/containr.2da
diff --git a/gemrb/override/shared/cow.pro b/gemrb/unhardcoded/shared/cow.pro
similarity index 100%
rename from gemrb/override/shared/cow.pro
rename to gemrb/unhardcoded/shared/cow.pro
diff --git a/gemrb/unhardcoded/shared/czech.ini b/gemrb/unhardcoded/shared/czech.ini
new file mode 100644
index 0000000..696f339
--- /dev/null
+++ b/gemrb/unhardcoded/shared/czech.ini
@@ -0,0 +1,39 @@
+[charset]
+CharCount = 35
+
+# Characters left from the original encoding, plus glyphs changed in Czech
+Letter1 = 138,154 # Sv
+Letter2 = 140,156 # OE
+Letter3 = 141,157 ### Tv
+Letter4 = 142,158 ### Zv
+Letter5 = 159,255 # Y:
+Letter6 = 192,224 # A`
+Letter7 = 193,225 # A'
+Letter8 = 194,226 # A^
+Letter9 = 195,227 # A~
+Letter10 = 196,228 # A:
+Letter11 = 197,229 # Ao
+Letter12 = 198,230 # AE
+Letter13 = 199,231 # C,
+Letter14 = 200,232 ### Cv
+Letter15 = 201,233 # E'
+Letter16 = 202,234 # E^
+Letter17 = 203,235 # E:
+Letter18 = 204,236 ### Ev
+Letter19 = 205,237 # I'
+Letter20 = 206,238 # I^
+Letter21 = 207,239 ### Dv
+Letter22 = 208,240 # D-
+Letter23 = 209,241 # N~
+Letter24 = 210,242 ### Nv
+Letter25 = 211,243 # O'
+Letter26 = 212,244 # O^
+Letter27 = 213,245 # O~
+Letter28 = 214,246 # O:
+Letter29 = 216,248 ### Rv
+Letter30 = 217,249 ### Uo
+Letter31 = 218,250 # U'
+Letter32 = 219,251 # U^
+Letter33 = 220,252 # U:
+Letter34 = 221,253 # Y'
+Letter35 = 222,254 # Thorn
diff --git a/gemrb/unhardcoded/shared/default.ini b/gemrb/unhardcoded/shared/default.ini
new file mode 100644
index 0000000..1f5febd
--- /dev/null
+++ b/gemrb/unhardcoded/shared/default.ini
@@ -0,0 +1,39 @@
+[charset]
+CharCount = 35
+
+Letter1 = 138,154 # Sv
+Letter2 = 140,156 # OE
+Letter3 = 141,157 #
+Letter4 = 142,158 #
+Letter5 = 159,255 # Y: - inconsistent between fonts
+#Letter5 = 223,255 # SS - inconsistent between fonts
+Letter6 = 192,224 # A`
+Letter7 = 193,225 # A'
+Letter8 = 194,226 # A^
+Letter9 = 195,227 # A~
+Letter10 = 196,228 # A:
+Letter11 = 197,229 # Ao
+Letter12 = 198,230 # AE
+Letter13 = 199,231 # C,
+Letter14 = 200,232 # E`
+Letter15 = 201,233 # E'
+Letter16 = 202,234 # E^
+Letter17 = 203,235 # E:
+Letter18 = 204,236 # I`
+Letter19 = 205,237 # I'
+Letter20 = 206,238 # I^
+Letter21 = 207,239 # I:
+Letter22 = 208,240 # D-
+Letter23 = 209,241 # N~
+Letter24 = 210,242 # O`
+Letter25 = 211,243 # O'
+Letter26 = 212,244 # O^
+Letter27 = 213,245 # O~
+Letter28 = 214,246 # O:
+Letter29 = 216,248 # O/ - actually swapped in STONESML
+Letter30 = 217,249 # U`
+Letter31 = 218,250 # U'
+Letter32 = 219,251 # U^
+Letter33 = 220,252 # U:
+Letter34 = 221,253 # Y'
+Letter35 = 222,254 # Thorn
diff --git a/gemrb/unhardcoded/shared/defaults.ini b/gemrb/unhardcoded/shared/defaults.ini
new file mode 100644
index 0000000..07ea720
--- /dev/null
+++ b/gemrb/unhardcoded/shared/defaults.ini
@@ -0,0 +1,61 @@
+; TODO: some games have special options not applicable to others.
+; consider making game specific copies of this file
+
+[Program Options]
+3D Acceleration = 0
+BitsPerPixel = 16
+Brightness Correction = 0
+Display Movie Subtitles = 0 ; identical to Display Subtitles
+Display Subtitles = 0 ; identical to Display Movie Subtitles
+EnableRollFeedback = 0 ; hidden iwd2 setting for extra roll messages
+Full Screen = 0
+Gamma Correction = 0
+SoftBlt = 0 ; unused
+SoftMirrorBlt = 0 ; unused
+SoftSrcKeyBlt = 0 ; unused
+Strref On = 0
+Tooltips = 50
+Translucent Shadows = 0
+; Program Options - Audio
+Volume Ambients = 100
+Volume Movie = 100
+Volume Music = 100
+Volume SFX = 100
+Volume Voices = 100
+Debug Mode = 0 ; not used. should be implemented. (for logging especially)
+
+[Game Options]
+Always Dither = 0
+Always Run = 0
+Auto Pause Center = 1
+Auto Pause State = 0
+Bored Timeout = 0
+Cheats = 1
+Command Sounds Frequency = 0
+Critical Hit Screen Shake = 1
+Darkvision = 1 ; iwd2; treating as replacement for infravision
+Difficulty Level = 0
+Duplicate Floating Text = 0
+Environmental Audio = 0 ; TODO: Creative's EAX
+Footsteps = 1
+Gore = 0 ; unused
+GUI Feedback Level = 0
+Heal Party on Rest = 0 ; TODO: see Game::RestParty
+Hotkeys On Tooltips = 1 ; not used. should be implemented.
+HP Over Head = 0
+Infravision = 1
+Keyboard Scroll Speed = 64
+Locator Feedback Level = 0
+Maximum HP = 0
+Mouse Scroll Speed = 0
+Music Processing = 1 ; TODO: turned music off completely for performance
+Nightmare Mode = 0
+Old Portrait Health = 0
+Selection Sounds Frequency = 0
+Sound Processing = 1 ; TODO: turned sound off completely for performance
+Subtitles = 0 ; not identical to the above; used for displaying verbal constants
+Suppress Extra Difficulty Damage = 0
+Weather = 1
+
+[Multiplayer] ; all are unused
+Last Protocol Used = 0
diff --git a/gemrb/unhardcoded/shared/demoend.chu b/gemrb/unhardcoded/shared/demoend.chu
new file mode 100644
index 0000000..77bf3f7
Binary files /dev/null and b/gemrb/unhardcoded/shared/demoend.chu differ
diff --git a/gemrb/override/shared/detect.spl b/gemrb/unhardcoded/shared/detect.spl
similarity index 100%
rename from gemrb/override/shared/detect.spl
rename to gemrb/unhardcoded/shared/detect.spl
diff --git a/gemrb/unhardcoded/shared/difflvls.2da b/gemrb/unhardcoded/shared/difflvls.2da
new file mode 100644
index 0000000..36115bb
--- /dev/null
+++ b/gemrb/unhardcoded/shared/difflvls.2da
@@ -0,0 +1,5 @@
+2DA V1.0
+0
+ DEFAULT EASY NORMAL CORE HARD NIGHTMARE
+DMG 0 -50 -25 0 50 100
+XP 0 0 0 0 0 0
diff --git a/gemrb/unhardcoded/shared/dmgtypes.2da b/gemrb/unhardcoded/shared/dmgtypes.2da
new file mode 100644
index 0000000..1f259e5
--- /dev/null
+++ b/gemrb/unhardcoded/shared/dmgtypes.2da
@@ -0,0 +1,22 @@
+2DA V1.0
+-1
+ LOWER RESIST_STAT VALUE IWDMOD REDUCTION
+DAMAGE_CRUSHING 136 RESISTCRUSHING 0 9 1
+DAMAGE_ACID 140 RESISTACID 1 4 0
+DAMAGE_COLD 139 RESISTCOLD 2 2 0
+DAMAGE_ELECTRICITY 138 RESISTELECTRICITY 4 3 0
+DAMAGE_FIRE 137 RESISTFIRE 8 1 0
+DAMAGE_PIERCING 135 RESISTPIERCING 0x10 8 1
+DAMAGE_POISON 131 RESISTPOISON 0x20 6 0
+DAMAGE_MAGIC 132 MAGICDAMAGERESISTANCE 0x40 5 0
+DAMAGE_MISSILE 133 RESISTMISSILE 0x80 10 1
+DAMAGE_SLASHING 134 RESISTSLASHING 0x100 7 1
+DAMAGE_MAGICFIRE 137 RESISTMAGICFIRE 0x200 -1 0
+DAMAGE_PIERCINGMISSILE 133 RESISTMISSILE 0x80 -1 1
+DAMAGE_MAGICCOLD 139 RESISTMAGICCOLD 0x400 -1 0
+DAMAGE_CRUSHINGMISSILE 133 RESISTMISSILE 0x80 -1 1
+DAMAGE_STUNNING 141 0 0x800 -1 0
+DAMAGE_SOULEATER 132 0 0x1000 -1 0
+DAMAGE_DISEASE 141 0 0x4000 -1 0
+DAMAGE_CHUNKING 141 0 0x8000 -1 0
+ 0
diff --git a/gemrb/override/shared/dummy.spl b/gemrb/unhardcoded/shared/dummy.spl
similarity index 100%
rename from gemrb/override/shared/dummy.spl
rename to gemrb/unhardcoded/shared/dummy.spl
diff --git a/gemrb/unhardcoded/shared/fatigue.2da b/gemrb/unhardcoded/shared/fatigue.2da
new file mode 100644
index 0000000..d0fe65d
--- /dev/null
+++ b/gemrb/unhardcoded/shared/fatigue.2da
@@ -0,0 +1,5 @@
+2DA V1.0
+*
+FILE STAT CHECKCOL READCOL
+fatigmod FATIGUE -1 0
+
diff --git a/gemrb/override/shared/findtrap.spl b/gemrb/unhardcoded/shared/findtrap.spl
similarity index 100%
rename from gemrb/override/shared/findtrap.spl
rename to gemrb/unhardcoded/shared/findtrap.spl
diff --git a/gemrb/override/shared/flmstrk.pro b/gemrb/unhardcoded/shared/flmstrk.pro
similarity index 100%
rename from gemrb/override/shared/flmstrk.pro
rename to gemrb/unhardcoded/shared/flmstrk.pro
diff --git a/gemrb/unhardcoded/shared/gemact.ids b/gemrb/unhardcoded/shared/gemact.ids
new file mode 100644
index 0000000..92bf08e
--- /dev/null
+++ b/gemrb/unhardcoded/shared/gemact.ids
@@ -0,0 +1,13 @@
+IDS
+399 ApplySpellPoint(P:Target*,I:Spell*Spell)
+399 ApplySpellPointRES(P:Target*,S:SpellName*)
+398 ChangeDestination(O:Object*,S:Destination*)
+397 UnmakeGlobal(O:Object*)
+396 SetToken2DA(S:ResRef*)
+395 StartDialogOverride(S:DialogFile*,O:Target*,I:Unused,I:Unused,I:ConverseAsItem)
+394 SetTrackString(I:StrRef, I:Flags, I:Difficulty)
+393 AdvanceTime(I:Seconds*)
+168 Interact(O:Object*)
+148 BashDoor(O:Object)
+112 UseContainer()
+93 LeaveAreaName(O:Target*)
diff --git a/gemrb/unhardcoded/shared/gemtrig.ids b/gemrb/unhardcoded/shared/gemtrig.ids
new file mode 100644
index 0000000..6fb9f68
--- /dev/null
+++ b/gemrb/unhardcoded/shared/gemtrig.ids
@@ -0,0 +1,2 @@
+IDS
+0x40ff UsedExit(S:ResRef*,O:Actor*)
diff --git a/gemrb/override/shared/invtrav.pro b/gemrb/unhardcoded/shared/invtrav.pro
similarity index 100%
rename from gemrb/override/shared/invtrav.pro
rename to gemrb/unhardcoded/shared/invtrav.pro
diff --git a/gemrb/override/shared/itemspec.2da b/gemrb/unhardcoded/shared/itemspec.2da
similarity index 100%
rename from gemrb/override/shared/itemspec.2da
rename to gemrb/unhardcoded/shared/itemspec.2da
diff --git a/gemrb/unhardcoded/shared/japanese.ini b/gemrb/unhardcoded/shared/japanese.ini
new file mode 100644
index 0000000..6ce52e2
--- /dev/null
+++ b/gemrb/unhardcoded/shared/japanese.ini
@@ -0,0 +1,2 @@
+[encoding]
+TLKEncoding = SJIS
diff --git a/gemrb/unhardcoded/shared/keymap.2da b/gemrb/unhardcoded/shared/keymap.2da
new file mode 100644
index 0000000..c712519
--- /dev/null
+++ b/gemrb/unhardcoded/shared/keymap.2da
@@ -0,0 +1,71 @@
+2DA V1.0
+*
+ MODULE FUNCTION GROUP
+Inventory GUIINV OpenInventoryWindow 0
+Character_Record GUIREC OpenRecordsWindow 0
+Return_To_Game GUICommonWindows ReturnToGame 0
+Journal GUIJRNL OpenJournalWindow 0
+Map GUIMA OpenMapWindow 0
+Wizard_Spells GUIMG OpenMageWindow 0
+Priest_Spells GUIPR OpenPriestWindow 0
+Spellbook GUISPL OpenSpellBookWindow 0
+Options GUIOPT OpenOptionsWindow 0
+Character_Arbitration GUIMP *
+Guard_/_Protect GUICommonWindows ActionDefendPressed 0
+Turn_Undead GUICommonWindows ActionTurnPressed 0
+Battle_Song GUICommonWindows ActionBardSongPressed 0
+Cast_Spell GUICommonWindows ActionCastPressed 0
+Use_Item GUICommonWindows ActionUseItemPressed 0
+Dialog GUICommonWindows ActionTalkPressed 0
+Thieving GUICommonWindows ActionThievingPressed 0
+Stealth GUICommonWindows ActionStealthPressed 0
+Trap_Detection GUICommonWindows ActionSearchPressed 0
+Group_Stop GUICommonWindows ActionStopPressed 0
+Group_Attack GUICommonWindows ActionAttackPressed 0
+Special_Abilities GUICommonWindows ActionInnatePressed 0
+Equip_Melee_Weapon GUICommonWindows ActionMeleePressed 0
+Equip_Range_Weapon GUICommonWindows ActionRangePressed 0
+Quick_Load GUILOAD QuickLoadPressed 0
+Quick_Save GUISAVE QuickSavePressed 0
+Rest GUICommonWindows RestPress 0
+Hide_Interface GUICommonWindows HideInterface 0
+Right_Interface GUICommonWindows PortraitPress 0
+Left_Interface GUICommonWindows OptionsPress 0
+Toggle_AI GUICommonWindows AIPress 0
+Hard_Pause GUICommonWindows HardPausePressed 0
+Location GUICommon LocationPressed 0
+Chat_Window GUIMP *
+Spell_Slot_1 GUICommonWindows ActionQSpell1Pressed 0
+Spell_Slot_2 GUICommonWindows ActionQSpell2Pressed 0
+Spell_Slot_3 GUICommonWindows ActionQSpell3Pressed 0
+Weapon_Slot_1 GUICommonWindows ActionQWeapon1Pressed 0
+Weapon_Slot_2 GUICommonWindows ActionQWeapon2Pressed 0
+Weapon_Slot_3 GUICommonWindows ActionQWeapon3Pressed 0
+Weapon_Slot_4 GUICommonWindows ActionQWeapon4Pressed 0
+Item_Slot_1 GUICommonWindows ActionQItem1Pressed 0
+Item_Slot_2 GUICommonWindows ActionQItem2Pressed 0
+Item_Slot_3 GUICommonWindows ActionQItem3Pressed 0
+Item_Slot_4 GUICommonWindows ActionQItem4Pressed 0
+Item_Slot_5 GUICommonWindows ActionQItem5Pressed 0
+# pst has quick weapons and items under different names
+Quick_Weapon_Slot1 GUICommonWindows ActionQWeapon1Pressed 0
+Quick_Weapon_Slot2 GUICommonWindows ActionQWeapon2Pressed 0
+Quick_Weapon_Slot3 GUICommonWindows ActionQWeapon3Pressed 0
+Quick_Weapon_Slot4 GUICommonWindows ActionQWeapon4Pressed 0
+Quick_Item_Slot1 GUICommonWindows ActionQItem1Pressed 0
+Quick_Item_Slot2 GUICommonWindows ActionQItem2Pressed 0
+Quick_Item_Slot3 GUICommonWindows ActionQItem3Pressed 0
+Quick_Item_Slot4 GUICommonWindows ActionQItem4Pressed 0
+Quick_Item_Slot5 GUICommonWindows ActionQItem5Pressed 0
+Action_Menu FloatMenuWindow OpenFloatMenuWindow 0
+Action_Menu_-_Previous FloatMenuWindow FloatMenuSelectPreviousPC 0
+Action_Menu_-_Next FloatMenuWindow FloatMenuSelectNextPC 0
+Attack FloatMenuWindow FloatMenuSelectWeapons 0
+# these are duplicates and require the window to be set up first
+#Use_Item FloatMenuWindow FloatMenuSelectItems 0
+#Cast_Spell FloatMenuWindow FloatMenuSelectSpells 0
+#Dialog FloatMenuWindow FloatMenuSelectDialog 0
+Special_Abilities FloatMenuWindow FloatMenuSelectAbilities 0
+Toggle_Always_Run GUICommonWindows ToggleAlwaysRun 0
+Default GUICommon ResolveKey 0
+
diff --git a/gemrb/unhardcoded/shared/korean.ini b/gemrb/unhardcoded/shared/korean.ini
new file mode 100644
index 0000000..ba18591
--- /dev/null
+++ b/gemrb/unhardcoded/shared/korean.ini
@@ -0,0 +1,2 @@
+[encoding]
+TLKEncoding = EUCKR
diff --git a/gemrb/override/shared/modal.2da b/gemrb/unhardcoded/shared/modal.2da
similarity index 100%
rename from gemrb/override/shared/modal.2da
rename to gemrb/unhardcoded/shared/modal.2da
diff --git a/gemrb/override/shared/panic.spl b/gemrb/unhardcoded/shared/panic.spl
similarity index 100%
rename from gemrb/override/shared/panic.spl
rename to gemrb/unhardcoded/shared/panic.spl
diff --git a/gemrb/override/shared/polystat.2da b/gemrb/unhardcoded/shared/polystat.2da
similarity index 100%
rename from gemrb/override/shared/polystat.2da
rename to gemrb/unhardcoded/shared/polystat.2da
diff --git a/gemrb/override/shared/redholy.pro b/gemrb/unhardcoded/shared/redholy.pro
similarity index 100%
rename from gemrb/override/shared/redholy.pro
rename to gemrb/unhardcoded/shared/redholy.pro
diff --git a/gemrb/override/shared/sanctuc.vvc b/gemrb/unhardcoded/shared/sanctuc.vvc
similarity index 100%
rename from gemrb/override/shared/sanctuc.vvc
rename to gemrb/unhardcoded/shared/sanctuc.vvc
diff --git a/gemrb/override/shared/shair.pro b/gemrb/unhardcoded/shared/shair.pro
similarity index 100%
rename from gemrb/override/shared/shair.pro
rename to gemrb/unhardcoded/shared/shair.pro
diff --git a/gemrb/override/shared/shair1.pro b/gemrb/unhardcoded/shared/shair1.pro
similarity index 100%
rename from gemrb/override/shared/shair1.pro
rename to gemrb/unhardcoded/shared/shair1.pro
diff --git a/gemrb/override/shared/shair2.pro b/gemrb/unhardcoded/shared/shair2.pro
similarity index 100%
rename from gemrb/override/shared/shair2.pro
rename to gemrb/unhardcoded/shared/shair2.pro
diff --git a/gemrb/override/shared/shair3.pro b/gemrb/unhardcoded/shared/shair3.pro
similarity index 100%
rename from gemrb/override/shared/shair3.pro
rename to gemrb/unhardcoded/shared/shair3.pro
diff --git a/gemrb/override/shared/shair4.pro b/gemrb/unhardcoded/shared/shair4.pro
similarity index 100%
rename from gemrb/override/shared/shair4.pro
rename to gemrb/unhardcoded/shared/shair4.pro
diff --git a/gemrb/override/shared/shair5.pro b/gemrb/unhardcoded/shared/shair5.pro
similarity index 100%
rename from gemrb/override/shared/shair5.pro
rename to gemrb/unhardcoded/shared/shair5.pro
diff --git a/gemrb/override/shared/shair6.pro b/gemrb/unhardcoded/shared/shair6.pro
similarity index 100%
rename from gemrb/override/shared/shair6.pro
rename to gemrb/unhardcoded/shared/shair6.pro
diff --git a/gemrb/override/shared/shair7.pro b/gemrb/unhardcoded/shared/shair7.pro
similarity index 100%
rename from gemrb/override/shared/shair7.pro
rename to gemrb/unhardcoded/shared/shair7.pro
diff --git a/gemrb/override/shared/sharea.pro b/gemrb/unhardcoded/shared/sharea.pro
similarity index 100%
rename from gemrb/override/shared/sharea.pro
rename to gemrb/unhardcoded/shared/sharea.pro
diff --git a/gemrb/override/shared/sharea1.pro b/gemrb/unhardcoded/shared/sharea1.pro
similarity index 100%
rename from gemrb/override/shared/sharea1.pro
rename to gemrb/unhardcoded/shared/sharea1.pro
diff --git a/gemrb/override/shared/sharea2.pro b/gemrb/unhardcoded/shared/sharea2.pro
similarity index 100%
rename from gemrb/override/shared/sharea2.pro
rename to gemrb/unhardcoded/shared/sharea2.pro
diff --git a/gemrb/override/shared/sharea3.pro b/gemrb/unhardcoded/shared/sharea3.pro
similarity index 100%
rename from gemrb/override/shared/sharea3.pro
rename to gemrb/unhardcoded/shared/sharea3.pro
diff --git a/gemrb/override/shared/sharea4.pro b/gemrb/unhardcoded/shared/sharea4.pro
similarity index 100%
rename from gemrb/override/shared/sharea4.pro
rename to gemrb/unhardcoded/shared/sharea4.pro
diff --git a/gemrb/override/shared/sharea5.pro b/gemrb/unhardcoded/shared/sharea5.pro
similarity index 100%
rename from gemrb/override/shared/sharea5.pro
rename to gemrb/unhardcoded/shared/sharea5.pro
diff --git a/gemrb/override/shared/sharea6.pro b/gemrb/unhardcoded/shared/sharea6.pro
similarity index 100%
rename from gemrb/override/shared/sharea6.pro
rename to gemrb/unhardcoded/shared/sharea6.pro
diff --git a/gemrb/override/shared/shearth.pro b/gemrb/unhardcoded/shared/shearth.pro
similarity index 100%
rename from gemrb/override/shared/shearth.pro
rename to gemrb/unhardcoded/shared/shearth.pro
diff --git a/gemrb/override/shared/shearth1.pro b/gemrb/unhardcoded/shared/shearth1.pro
similarity index 100%
rename from gemrb/override/shared/shearth1.pro
rename to gemrb/unhardcoded/shared/shearth1.pro
diff --git a/gemrb/override/shared/shearth2.pro b/gemrb/unhardcoded/shared/shearth2.pro
similarity index 100%
rename from gemrb/override/shared/shearth2.pro
rename to gemrb/unhardcoded/shared/shearth2.pro
diff --git a/gemrb/override/shared/shearth3.pro b/gemrb/unhardcoded/shared/shearth3.pro
similarity index 100%
rename from gemrb/override/shared/shearth3.pro
rename to gemrb/unhardcoded/shared/shearth3.pro
diff --git a/gemrb/override/shared/shearth4.pro b/gemrb/unhardcoded/shared/shearth4.pro
similarity index 100%
rename from gemrb/override/shared/shearth4.pro
rename to gemrb/unhardcoded/shared/shearth4.pro
diff --git a/gemrb/override/shared/shearth5.pro b/gemrb/unhardcoded/shared/shearth5.pro
similarity index 100%
rename from gemrb/override/shared/shearth5.pro
rename to gemrb/unhardcoded/shared/shearth5.pro
diff --git a/gemrb/override/shared/shearth6.pro b/gemrb/unhardcoded/shared/shearth6.pro
similarity index 100%
rename from gemrb/override/shared/shearth6.pro
rename to gemrb/unhardcoded/shared/shearth6.pro
diff --git a/gemrb/override/shared/shearth7.pro b/gemrb/unhardcoded/shared/shearth7.pro
similarity index 100%
rename from gemrb/override/shared/shearth7.pro
rename to gemrb/unhardcoded/shared/shearth7.pro
diff --git a/gemrb/override/shared/shwater.pro b/gemrb/unhardcoded/shared/shwater.pro
similarity index 100%
rename from gemrb/override/shared/shwater.pro
rename to gemrb/unhardcoded/shared/shwater.pro
diff --git a/gemrb/override/shared/shwater1.pro b/gemrb/unhardcoded/shared/shwater1.pro
similarity index 100%
rename from gemrb/override/shared/shwater1.pro
rename to gemrb/unhardcoded/shared/shwater1.pro
diff --git a/gemrb/override/shared/shwater2.pro b/gemrb/unhardcoded/shared/shwater2.pro
similarity index 100%
rename from gemrb/override/shared/shwater2.pro
rename to gemrb/unhardcoded/shared/shwater2.pro
diff --git a/gemrb/override/shared/shwater3.pro b/gemrb/unhardcoded/shared/shwater3.pro
similarity index 100%
rename from gemrb/override/shared/shwater3.pro
rename to gemrb/unhardcoded/shared/shwater3.pro
diff --git a/gemrb/override/shared/shwater4.pro b/gemrb/unhardcoded/shared/shwater4.pro
similarity index 100%
rename from gemrb/override/shared/shwater4.pro
rename to gemrb/unhardcoded/shared/shwater4.pro
diff --git a/gemrb/override/shared/shwater5.pro b/gemrb/unhardcoded/shared/shwater5.pro
similarity index 100%
rename from gemrb/override/shared/shwater5.pro
rename to gemrb/unhardcoded/shared/shwater5.pro
diff --git a/gemrb/override/shared/shwater6.pro b/gemrb/unhardcoded/shared/shwater6.pro
similarity index 100%
rename from gemrb/override/shared/shwater6.pro
rename to gemrb/unhardcoded/shared/shwater6.pro
diff --git a/gemrb/override/shared/shwater7.pro b/gemrb/unhardcoded/shared/shwater7.pro
similarity index 100%
rename from gemrb/override/shared/shwater7.pro
rename to gemrb/unhardcoded/shared/shwater7.pro
diff --git a/gemrb/override/shared/skybolt.pro b/gemrb/unhardcoded/shared/skybolt.pro
similarity index 100%
rename from gemrb/override/shared/skybolt.pro
rename to gemrb/unhardcoded/shared/skybolt.pro
diff --git a/gemrb/override/shared/sneak.spl b/gemrb/unhardcoded/shared/sneak.spl
similarity index 100%
rename from gemrb/override/shared/sneak.spl
rename to gemrb/unhardcoded/shared/sneak.spl
diff --git a/gemrb/override/shared/souleatr.2da b/gemrb/unhardcoded/shared/souleatr.2da
similarity index 100%
rename from gemrb/override/shared/souleatr.2da
rename to gemrb/unhardcoded/shared/souleatr.2da
diff --git a/gemrb/override/shared/spboom1.pro b/gemrb/unhardcoded/shared/spboom1.pro
similarity index 100%
rename from gemrb/override/shared/spboom1.pro
rename to gemrb/unhardcoded/shared/spboom1.pro
diff --git a/gemrb/override/shared/spboom2.pro b/gemrb/unhardcoded/shared/spboom2.pro
similarity index 100%
rename from gemrb/override/shared/spboom2.pro
rename to gemrb/unhardcoded/shared/spboom2.pro
diff --git a/gemrb/override/shared/spboom3.pro b/gemrb/unhardcoded/shared/spboom3.pro
similarity index 100%
rename from gemrb/override/shared/spboom3.pro
rename to gemrb/unhardcoded/shared/spboom3.pro
diff --git a/gemrb/override/shared/spdimdr.pro b/gemrb/unhardcoded/shared/spdimdr.pro
similarity index 100%
rename from gemrb/override/shared/spdimdr.pro
rename to gemrb/unhardcoded/shared/spdimdr.pro
diff --git a/gemrb/unhardcoded/shared/spldisp.2da b/gemrb/unhardcoded/shared/spldisp.2da
new file mode 100644
index 0000000..5a986de
--- /dev/null
+++ b/gemrb/unhardcoded/shared/spldisp.2da
@@ -0,0 +1,18 @@
+2DA V1.0
+0
+ ROWS AS_COL KEY1 KEY2 KEY3
+DESCENDING 0
+USE_ROW 2
+DEFAULT 1 0 0 0 0
+TYPELEVEL 1 0 SpellType SpellLevel 0
+HOSTLEVELTYPE 1 0 NonHostile SpellLevel SpellType
+SPHERETYPELEVEL 2 0 BookType SpellType SpellLevel
+VERTLEVELS 9 1 SpellLevel SpellSchool 0
+
+# DESCENDING: set ROWS to 1 to sort the spell list in the opposite order
+# USE_ROW dictates which table row to use (counting from 2 - DEFAULT)
+# keys can be any index that GemRB_GetSpell provides plus BookType (mage vs priest)
+# NOTE: most of these are 0 in bg1
+# NOTE: SpellName is a number (strref)
+
+# TODO: if ascol and rows >1, key1 will be used to make groups; rows > 1 a grid
diff --git a/gemrb/override/shared/spmagmis.pro b/gemrb/unhardcoded/shared/spmagmis.pro
similarity index 100%
rename from gemrb/override/shared/spmagmis.pro
rename to gemrb/unhardcoded/shared/spmagmis.pro
diff --git a/gemrb/override/shared/spsmkjet.pro b/gemrb/unhardcoded/shared/spsmkjet.pro
similarity index 100%
rename from gemrb/override/shared/spsmkjet.pro
rename to gemrb/unhardcoded/shared/spsmkjet.pro
diff --git a/gemrb/override/shared/spsmold.pro b/gemrb/unhardcoded/shared/spsmold.pro
similarity index 100%
rename from gemrb/override/shared/spsmold.pro
rename to gemrb/unhardcoded/shared/spsmold.pro
diff --git a/gemrb/override/shared/spsmpuff.pro b/gemrb/unhardcoded/shared/spsmpuff.pro
similarity index 100%
rename from gemrb/override/shared/spsmpuff.pro
rename to gemrb/unhardcoded/shared/spsmpuff.pro
diff --git a/gemrb/unhardcoded/shared/storespl.2da b/gemrb/unhardcoded/shared/storespl.2da
new file mode 100644
index 0000000..a3c6d86
--- /dev/null
+++ b/gemrb/unhardcoded/shared/storespl.2da
@@ -0,0 +1,13 @@
+2DA V1.0
+EFF_P26
+ SOUND
+SPPR712 EFF_P18
+SPPR504 EFF_P18
+SPPR404 EFF_P17
+SPPR212 EFF_P17
+SPPR713 EFF_M10
+SPPR417 EFF_M10
+SPPR307 EFF_M10
+SPPR303 EFF_M10
+SPPR103 EFF_P26
+SPPR401 EFF_P26
diff --git a/gemrb/override/shared/turn.spl b/gemrb/unhardcoded/shared/turn.spl
similarity index 100%
rename from gemrb/override/shared/turn.spl
rename to gemrb/unhardcoded/shared/turn.spl
diff --git a/testing/python.supp b/testing/python.supp
new file mode 100644
index 0000000..87d71f5
--- /dev/null
+++ b/testing/python.supp
@@ -0,0 +1,106 @@
+{
+ Suppress_Python1
+ Memcheck:Addr4
+ fun:PyObject_Free
+}
+
+{
+ Suppress_Python2
+ Memcheck:Addr8
+ fun:PyObject_Realloc
+}
+
+{
+ Suppress_Python3
+ Memcheck:Cond
+ fun:PyObject_Free
+}
+
+{
+ Suppress_Python4
+ Memcheck:Cond
+ fun:PyObject_Realloc
+}
+
+{
+ Suppress_Python5
+ Memcheck:Value8
+ fun:PyObject_Free
+}
+
+{
+ Suppress_Python6
+ Memcheck:Value8
+ fun:PyObject_Realloc
+}
+
+{
+ Suppress_Python7
+ Memcheck:Addr4
+ fun:PyObject_Realloc
+}
+
+{
+ Suppress_Python_initposix
+ Memcheck:Leak
+ ...
+ fun:_PyObject_GC_Malloc
+ ...
+ fun:initposix
+}
+
+{
+ Suppress_Python_initzipimport
+ Memcheck:Leak
+ ...
+ fun:_PyObject_GC_Malloc
+ ...
+ fun:initzipimport
+}
+
+{
+ Suppress_Python_PyInitializeEx
+ Memcheck:Leak
+ ...
+ fun:_PyObject_GC_Malloc
+ ...
+ fun:Py_InitializeEx
+}
+
+{
+ Suppress_SDL1
+ Memcheck:Addr8
+ fun:SDL_LoadFunction
+}
+
+{
+ Suppress_SDL2
+ Memcheck:Value4
+ fun:SDL_LoadFunction
+}
+
+{
+ Suppress_SDL3
+ Memcheck:Cond
+ obj:/lib/ld-2.7.so
+}
+
+{
+ Suppress_libc
+ Memcheck:Addr8
+ obj:/lib/ld-2.7.so
+}
+
+{
+ Suppress_libX11_1
+ Memcheck:Leak
+ ...
+ fun:XSetLocaleModifiers
+}
+
+{
+ Suppress_libX11_2
+ Memcheck:Leak
+ ...
+ fun:XCreateIC
+}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/gemrb.git
More information about the Pkg-games-commits
mailing list