[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&parameters->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&parameters->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 &current, 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 &current, 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, &param1, &param2, &resref1, &resref2, &resref3, &source)) {
+	if (!PyArg_ParseTuple( args, "isii|ssssi", &globalID, &opcodename, &param1, &param2, &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, &param1, &param2, &resref)) {
+	if (!PyArg_ParseTuple( args, "isii|s", &globalID, &opcodename, &param1, &param2, &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(&currentEvent)) {
+		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