diff --git a/project/jni/application/gemrb/AndroidAppSettings.cfg b/project/jni/application/gemrb/AndroidAppSettings.cfg index 3889d0934..8d40b05fc 100644 --- a/project/jni/application/gemrb/AndroidAppSettings.cfg +++ b/project/jni/application/gemrb/AndroidAppSettings.cfg @@ -5,7 +5,7 @@ AppName="GemRB" AppFullName=net.sourceforge.gemrb ScreenOrientation=h InhibitSuspend=n -AppDataDownloadUrl="Baldur's gate 2 demo|http://sourceforge.net/projects/libsdl-android/files/gemrb/bg2demo.zip/download^!GemRB data(override)|override2.zip^!GemRB data(scripts)|scripts2.zip" +AppDataDownloadUrl="Baldur's gate 2 demo|http://sourceforge.net/projects/libsdl-android/files/gemrb/bg2demo.zip/download^!GemRB data(override)|override4.zip^!GemRB data(scripts)|scripts4.zip" SdlVideoResize=y SdlVideoResizeKeepAspect=y NeedDepthBuffer=n @@ -18,16 +18,18 @@ AppUsesJoystick=n AppHandlesJoystickSensitivity=n AppUsesMultitouch=n NonBlockingSwapBuffers=n -RedefinedKeys="LCTRL c p o e" +RedefinedKeys="LCTRL c NO_REMAP NO_REMAP e" AppTouchscreenKeyboardKeysAmount=0 AppTouchscreenKeyboardKeysAmountAutoFire=0 -RedefinedKeysScreenKb="LCTRL c p o e" +RedefinedKeysScreenKb="LCTRL c NO_REMAP NO_REMAP e" +StartupMenuButtonTimeout=2000 +HiddenMenuOptions='' MultiABI=y -AppVersionCode=0641 -AppVersionName="0.6.4.1" +AppVersionCode=0643 +AppVersionName="0.6.4.3" CompiledLibraries="sdl_mixer ogg vorbis openal png python" CustomBuildScript=n -AppCflags='-fexceptions -finline-functions -O3 -DSTATIC_LINK=Yes -DHAVE_SNPRINTF -DTOUCHSCREEN' +AppCflags='-fexceptions -finline-functions -O3 -DSTATIC_LINK=Yes -DHAVE_SNPRINTF' AppLdflags='' AppSubdirsBuild='' AppCmdline='GemRB' diff --git a/project/jni/application/gemrb/AndroidData/override4.zip b/project/jni/application/gemrb/AndroidData/override4.zip new file mode 100644 index 000000000..8c8645b43 Binary files /dev/null and b/project/jni/application/gemrb/AndroidData/override4.zip differ diff --git a/project/jni/application/gemrb/AndroidData/scripts4.zip b/project/jni/application/gemrb/AndroidData/scripts4.zip new file mode 100644 index 000000000..542fce81c Binary files /dev/null and b/project/jni/application/gemrb/AndroidData/scripts4.zip differ diff --git a/project/jni/application/gemrb/gemrb/GemRB.cpp b/project/jni/application/gemrb/gemrb/GemRB.cpp index dc688302e..104171d7e 100644 --- a/project/jni/application/gemrb/gemrb/GemRB.cpp +++ b/project/jni/application/gemrb/gemrb/GemRB.cpp @@ -22,10 +22,14 @@ #include "win32def.h" // logging -#include - #include "Interface.h" +#ifdef HAVE_MALLOC_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif //this supposed to convince SDL to work on OS/X //WARNING: commenting this out will cause SDL 1.2.x to crash @@ -35,28 +39,43 @@ #ifdef ANDROID #include -#include "Audio.h" +#include "audio.h" // pause audio playing if app goes in background static void appPutToBackground() { - core->GetAudioDrv()->Pause(); + core->GetAudioDrv()->Pause(); } // resume audio playing if app return to foreground static void appPutToForeground() { - core->GetAudioDrv()->Resume(); + core->GetAudioDrv()->Resume(); } #endif int main(int argc, char* argv[]) { +#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) { delete( core ); - printf("Press enter to continue..."); + print("Press enter to continue..."); textcolor(DEFAULT); getc(stdin); return -1; diff --git a/project/jni/application/gemrb/gemrb/core/ActorMgr.h b/project/jni/application/gemrb/gemrb/core/ActorMgr.h index 7afcfbaf8..e072defc5 100644 --- a/project/jni/application/gemrb/gemrb/core/ActorMgr.h +++ b/project/jni/application/gemrb/gemrb/core/ActorMgr.h @@ -22,14 +22,15 @@ #define ACTORMGR_H #include "Plugin.h" -#include "Scriptable/Actor.h" -#include "System/DataStream.h" + +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; //returns saved size, updates internal offsets before save diff --git a/project/jni/application/gemrb/gemrb/core/Animation.cpp b/project/jni/application/gemrb/gemrb/core/Animation.cpp index 6ec1caa1f..4d58f1fdc 100644 --- a/project/jni/application/gemrb/gemrb/core/Animation.cpp +++ b/project/jni/application/gemrb/gemrb/core/Animation.cpp @@ -25,6 +25,7 @@ #include "Game.h" #include "Interface.h" #include "Map.h" +#include "Sprite2D.h" #include "Video.h" Animation::Animation(int count) @@ -71,8 +72,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; @@ -107,13 +107,13 @@ unsigned int Animation::GetCurrentFrame() const Sprite2D* Animation::LastFrame(void) { if (!Flags&A_ANI_ACTIVE) { - printf("Frame fetched while animation is inactive!\n"); + print("Frame fetched while animation is inactive!\n"); return NULL; } if (gameAnimation) { starttime = core->GetGame()->Ticks; } else { - GetTime( starttime ); + starttime = GetTickCount(); } Sprite2D* ret; if (playReversed) @@ -126,14 +126,14 @@ Sprite2D* Animation::LastFrame(void) Sprite2D* Animation::NextFrame(void) { if (!Flags&A_ANI_ACTIVE) { - printf("Frame fetched while animation is inactive!\n"); + print("Frame fetched while animation is inactive!\n"); return NULL; } if (starttime == 0) { if (gameAnimation) { starttime = core->GetGame()->Ticks; } else { - GetTime( starttime ); + starttime = GetTickCount(); } } Sprite2D* ret; @@ -149,7 +149,7 @@ Sprite2D* Animation::NextFrame(void) 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 @@ -180,7 +180,7 @@ Sprite2D* Animation::NextFrame(void) Sprite2D* Animation::GetSyncedNextFrame(Animation* master) { if (!Flags&A_ANI_ACTIVE) { - printf("Frame fetched while animation is inactive!\n"); + print("Frame fetched while animation is inactive!\n"); return NULL; } Sprite2D* ret; diff --git a/project/jni/application/gemrb/gemrb/core/Animation.h b/project/jni/application/gemrb/gemrb/core/Animation.h index fcf9a7d13..5c32424cf 100644 --- a/project/jni/application/gemrb/gemrb/core/Animation.h +++ b/project/jni/application/gemrb/gemrb/core/Animation.h @@ -26,10 +26,11 @@ #include "globals.h" #include "Region.h" -#include "Sprite2D.h" #include +class Sprite2D; + class GEM_EXPORT Animation { private: Sprite2D **frames; diff --git a/project/jni/application/gemrb/gemrb/core/AnimationFactory.cpp b/project/jni/application/gemrb/gemrb/core/AnimationFactory.cpp index e6637394c..941e963a1 100644 --- a/project/jni/application/gemrb/gemrb/core/AnimationFactory.cpp +++ b/project/jni/application/gemrb/gemrb/core/AnimationFactory.cpp @@ -23,6 +23,7 @@ #include "win32def.h" #include "Interface.h" +#include "Sprite2D.h" #include "Video.h" AnimationFactory::AnimationFactory(const char* ResRef) diff --git a/project/jni/application/gemrb/gemrb/core/AnimationFactory.h b/project/jni/application/gemrb/gemrb/core/AnimationFactory.h index b385362eb..2da099b39 100644 --- a/project/jni/application/gemrb/gemrb/core/AnimationFactory.h +++ b/project/jni/application/gemrb/gemrb/core/AnimationFactory.h @@ -25,6 +25,7 @@ #include "globals.h" #include "Animation.h" +#include "AnimStructures.h" #include "FactoryObject.h" class GEM_EXPORT AnimationFactory : public FactoryObject { diff --git a/project/jni/application/gemrb/gemrb/core/AnimationMgr.h b/project/jni/application/gemrb/gemrb/core/AnimationMgr.h index d161aff4b..4bf90c61d 100644 --- a/project/jni/application/gemrb/gemrb/core/AnimationMgr.h +++ b/project/jni/application/gemrb/gemrb/core/AnimationMgr.h @@ -25,14 +25,15 @@ #include "Animation.h" #include "AnimationFactory.h" -#include "Font.h" #include "Plugin.h" +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; diff --git a/project/jni/application/gemrb/gemrb/core/ArchiveImporter.h b/project/jni/application/gemrb/gemrb/core/ArchiveImporter.h index 076d6795c..fe464cb25 100644 --- a/project/jni/application/gemrb/gemrb/core/ArchiveImporter.h +++ b/project/jni/application/gemrb/gemrb/core/ArchiveImporter.h @@ -29,12 +29,10 @@ 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/project/jni/application/gemrb/gemrb/core/CMakeLists.txt b/project/jni/application/gemrb/gemrb/core/CMakeLists.txt index 767e0332f..2d6c8dec1 100644 --- a/project/jni/application/gemrb/gemrb/core/CMakeLists.txt +++ b/project/jni/application/gemrb/gemrb/core/CMakeLists.txt @@ -1,6 +1,92 @@ ADD_DEFINITIONS(-DGEM_BUILD_DLL) -FILE(GLOB gemrb_core_LIB_SRCS "*.cpp" +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 + Game.cpp + GameData.cpp + GlobalTimer.cpp + Image.cpp + ImageFactory.cpp + ImageMgr.cpp + ImageWriter.cpp + IndexedArchive.cpp + IniSpawn.cpp + Interface.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 @@ -27,12 +113,13 @@ FILE(GLOB gemrb_core_LIB_SRCS "*.cpp" Scriptable/InfoPoint.cpp Scriptable/Scriptable.cpp Scriptable/PCStatStruct.cpp - System/CachedFileStream.cpp System/DataStream.cpp System/FileStream.cpp System/MemoryStream.cpp + System/Logging.cpp + System/SlicedStream.cpp + System/String.cpp System/VFS.cpp - System/snprintf.cpp ) if (STATIC_LINK) diff --git a/project/jni/application/gemrb/gemrb/core/Cache.cpp b/project/jni/application/gemrb/gemrb/core/Cache.cpp index 647b0cb93..4c11ebabc 100644 --- a/project/jni/application/gemrb/gemrb/core/Cache.cpp +++ b/project/jni/application/gemrb/gemrb/core/Cache.cpp @@ -20,6 +20,7 @@ #include "Cache.h" +#include #include // private inlines diff --git a/project/jni/application/gemrb/gemrb/core/CharAnimations.cpp b/project/jni/application/gemrb/gemrb/core/CharAnimations.cpp index 66dc4b1eb..aa4519042 100644 --- a/project/jni/application/gemrb/gemrb/core/CharAnimations.cpp +++ b/project/jni/application/gemrb/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" @@ -448,8 +450,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; @@ -511,8 +512,8 @@ void CharAnimations::InitAvatarsTable() 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); + printMessage("CharAnimations", "bloodclr entry: %02x %04x-%04x ", LIGHT_RED, + (unsigned int) value, (unsigned int) rmin, (unsigned int) rmax); printStatus("Invalid value!", LIGHT_RED); continue; } @@ -609,8 +610,7 @@ CharAnimations::CharAnimations(unsigned int AnimID, ieDword ArmourLevel) } } ResRef[0]=0; - printMessage("CharAnimations", " ", LIGHT_RED); - printf("Invalid or nonexistent avatar entry:%04X\n", AnimID); + printMessage("CharAnimations", "Invalid or nonexistent avatar entry:%04X\n", LIGHT_RED, AnimID); } //we have to drop them when armourlevel changes @@ -782,8 +782,7 @@ 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 @@ -864,7 +863,7 @@ Animation** CharAnimations::GetAnimation(unsigned char Stance, unsigned char Ori autoSwitchOnEnd = true; break; default: - printf ("Invalid Stance: %d\n", StanceID); + print ("Invalid Stance: %d\n", StanceID); break; } Animation** anims = Anims[StanceID][Orient]; @@ -931,10 +930,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); + printMessage("CharAnimations", "Couldn't create animationfactory: %s (%04x)\n", + LIGHT_RED, NewResRef, GetAnimationID());; for (int i = 0; i < part; ++i) delete anims[i]; delete[] anims; @@ -951,11 +948,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", + printMessage("CharAnimations", "Couldn't load animation: %s, cycle %d\n", LIGHT_RED, NewResRef, Cycle); - printMessage("CharAnimations",warnbuf,LIGHT_RED); for (int i = 0; i < part; ++i) delete anims[i]; delete[] anims; @@ -1100,8 +1094,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 +1108,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()) { @@ -1203,9 +1195,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 +1214,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; } } @@ -1379,9 +1368,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 +1451,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; } } @@ -1521,8 +1512,7 @@ void CharAnimations::AddFFSuffix(char* ResRef, unsigned char StanceID, 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 +1653,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 +1721,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 +1776,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 +1898,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 +2005,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) { @@ -2101,8 +2088,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 +2161,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 +2235,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 +2321,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) { diff --git a/project/jni/application/gemrb/gemrb/core/Compressor.cpp b/project/jni/application/gemrb/gemrb/core/Compressor.cpp index e7a675be3..187c160b0 100644 --- a/project/jni/application/gemrb/gemrb/core/Compressor.cpp +++ b/project/jni/application/gemrb/gemrb/core/Compressor.cpp @@ -29,9 +29,3 @@ Compressor::Compressor(void) 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/project/jni/application/gemrb/gemrb/core/Compressor.h b/project/jni/application/gemrb/gemrb/core/Compressor.h index 3409f8019..dcc1ce409 100644 --- a/project/jni/application/gemrb/gemrb/core/Compressor.h +++ b/project/jni/application/gemrb/gemrb/core/Compressor.h @@ -24,16 +24,12 @@ #include "Plugin.h" #include "System/DataStream.h" -#include - 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; }; diff --git a/project/jni/application/gemrb/gemrb/core/ControlAnimation.cpp b/project/jni/application/gemrb/gemrb/core/ControlAnimation.cpp index 6e618844a..7e228f6ea 100644 --- a/project/jni/application/gemrb/gemrb/core/ControlAnimation.cpp +++ b/project/jni/application/gemrb/gemrb/core/ControlAnimation.cpp @@ -22,7 +22,9 @@ #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 */ @@ -45,6 +47,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 @@ -108,6 +111,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 +126,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 +150,7 @@ void ControlAnimation::SetPaletteGradients(ieDword *col) has_palette = true; } +void ControlAnimation::SetBlend(bool b) +{ + is_blended = b; +} diff --git a/project/jni/application/gemrb/gemrb/core/ControlAnimation.h b/project/jni/application/gemrb/gemrb/core/ControlAnimation.h index c85870f67..bb7a86d28 100644 --- a/project/jni/application/gemrb/gemrb/core/ControlAnimation.h +++ b/project/jni/application/gemrb/gemrb/core/ControlAnimation.h @@ -23,13 +23,13 @@ #include "RGBAColor.h" #include "exports.h" - -#include "AnimationFactory.h" -#include "Sprite2D.h" -#include "GUI/Control.h" +#include "globals.h" #include +class AnimationFactory; +class Control; + class GEM_EXPORT ControlAnimation { private: AnimationFactory* bam; @@ -38,6 +38,7 @@ 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); @@ -46,6 +47,7 @@ public: //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/project/jni/application/gemrb/gemrb/core/Core.cpp b/project/jni/application/gemrb/gemrb/core/Core.cpp index 5fd0b66e6..05d0911e4 100644 --- a/project/jni/application/gemrb/gemrb/core/Core.cpp +++ b/project/jni/application/gemrb/gemrb/core/Core.cpp @@ -48,65 +48,6 @@ BOOL WINAPI DllEntryPoint(HINSTANCE /*hinstDLL*/, DWORD /*fdwReason*/, //// 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; - } - } -} - -#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 - static const unsigned char orientations[25]={ 6,7,8,9,10, 5,6,8,10,11, @@ -269,55 +210,3 @@ 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) -{ - 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/project/jni/application/gemrb/gemrb/core/DataFileMgr.h b/project/jni/application/gemrb/gemrb/core/DataFileMgr.h index 8773767b7..8df95ae7e 100644 --- a/project/jni/application/gemrb/gemrb/core/DataFileMgr.h +++ b/project/jni/application/gemrb/gemrb/core/DataFileMgr.h @@ -40,7 +40,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; diff --git a/project/jni/application/gemrb/gemrb/core/DialogHandler.cpp b/project/jni/application/gemrb/gemrb/core/DialogHandler.cpp index 0be1070b5..c2877defb 100644 --- a/project/jni/application/gemrb/gemrb/core/DialogHandler.cpp +++ b/project/jni/application/gemrb/gemrb/core/DialogHandler.cpp @@ -25,10 +25,14 @@ #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" //translate section values (journal, solved, unsolved, user) static int sectionMap[4]={4,1,2,0}; @@ -56,7 +60,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 +68,12 @@ int DialogHandler::InitDialog(Scriptable* spk, Scriptable* tgt, const char* dlgr } PluginHolder 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; + printMessage("GameControl", "Cannot start dialog: %s\n", LIGHT_RED, dlgref); + return false; } strnlwrcpy(dlg->ResRef, dlgref, 8); //this isn't handled by GetDialog??? @@ -85,8 +88,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 +98,16 @@ int DialogHandler::InitDialog(Scriptable* spk, Scriptable* tgt, const char* dlgr GameControl *gc = core->GetGameControl(); if (!gc) - return -1; + return false; //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 @@ -134,7 +138,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*/ @@ -348,16 +352,15 @@ 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); 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(); diff --git a/project/jni/application/gemrb/gemrb/core/DialogHandler.h b/project/jni/application/gemrb/gemrb/core/DialogHandler.h index 499fb0dea..8f80d147d 100644 --- a/project/jni/application/gemrb/gemrb/core/DialogHandler.h +++ b/project/jni/application/gemrb/gemrb/core/DialogHandler.h @@ -43,7 +43,7 @@ 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); }; diff --git a/project/jni/application/gemrb/gemrb/core/DialogMgr.h b/project/jni/application/gemrb/gemrb/core/DialogMgr.h index 125ae52a0..be4128b31 100644 --- a/project/jni/application/gemrb/gemrb/core/DialogMgr.h +++ b/project/jni/application/gemrb/gemrb/core/DialogMgr.h @@ -29,7 +29,7 @@ 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; }; diff --git a/project/jni/application/gemrb/gemrb/core/DisplayMessage.cpp b/project/jni/application/gemrb/gemrb/core/DisplayMessage.cpp index ceecd6bb9..26b016f20 100644 --- a/project/jni/application/gemrb/gemrb/core/DisplayMessage.cpp +++ b/project/jni/application/gemrb/gemrb/core/DisplayMessage.cpp @@ -26,6 +26,7 @@ #include "TableMgr.h" #include "GUI/Label.h" #include "GUI/TextArea.h" +#include "Scriptable/Actor.h" GEM_EXPORT DisplayMessage * displaymsg; @@ -33,11 +34,11 @@ 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,7 +62,7 @@ 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) { @@ -161,7 +162,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 ); diff --git a/project/jni/application/gemrb/gemrb/core/DisplayMessage.h b/project/jni/application/gemrb/gemrb/core/DisplayMessage.h index 9fc781b5d..02a6d48ab 100644 --- a/project/jni/application/gemrb/gemrb/core/DisplayMessage.h +++ b/project/jni/application/gemrb/gemrb/core/DisplayMessage.h @@ -28,8 +28,11 @@ #define DISPLAYMESSAGE_H #include "exports.h" +#include "ie_types.h" -#include "ActorMgr.h" +#include + +class Scriptable; class GEM_EXPORT DisplayMessage { diff --git a/project/jni/application/gemrb/gemrb/core/EffectQueue.cpp b/project/jni/application/gemrb/gemrb/core/EffectQueue.cpp index ca980d686..878ee02c5 100644 --- a/project/jni/application/gemrb/gemrb/core/EffectQueue.cpp +++ b/project/jni/application/gemrb/gemrb/core/EffectQueue.cpp @@ -28,6 +28,7 @@ #include "SymbolMgr.h" #include "Scriptable/Actor.h" #include "Spell.h" //needs for the source flags bitfield +#include "TableMgr.h" #include @@ -97,7 +98,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 +106,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 +115,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 +129,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 +138,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]; @@ -157,18 +158,18 @@ 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 +181,14 @@ 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 ); + printMessage("EffectQueue", "Couldn't assign effect: %s\n", YELLOW, 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); @@ -250,12 +250,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\n", i, effectname); } core->DelSymbol( eT ); @@ -485,6 +484,7 @@ 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; switch (fx->Target) { case FX_TARGET_ORIGINAL: @@ -509,6 +509,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 +518,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 +537,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 +545,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 +563,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,14 +571,16 @@ 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: @@ -587,54 +596,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); + print( "Unknown FX target type: %d\n", fx->Target); flg = FX_ABORT; break; } @@ -681,7 +699,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 @@ -729,7 +747,7 @@ 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 @@ -773,7 +791,7 @@ static EffectRef fx_secondary_type_bounce_dec_ref = { "Bounce:SecondaryTypeDec", static EffectRef fx_spelltrap = { "SpellTrap", -1 }; //this is for whole spell immunity/bounce -inline static void DecreaseEffect(Effect *efx) +static inline void DecreaseEffect(Effect *efx) { efx->Parameter1--; if( (int) efx->Parameter1<1) { @@ -950,11 +968,11 @@ static bool check_resistance(Actor* actor, Effect* fx) //opcode immunity if( actor->fxqueue.HasEffectWithParam(fx_opcode_immunity_ref, fx->Opcode) ) { - printf ("immune to effect: %s\n", (char*) Opcodes[fx->Opcode].Name); + print ("immune to effect: %s\n", (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); + print ("immune2 to effect: %s\n", (char*) Opcodes[fx->Opcode].Name); return true; } @@ -984,10 +1002,10 @@ static bool check_resistance(Actor* actor, Effect* fx) //magic immunity ieDword val = actor->GetStat(IE_RESISTMAGIC); - if( fx->random_value < val) { + if( (signed) fx->random_value < (signed) 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); + print ("effect resisted: %s\n", (char*) Opcodes[fx->Opcode].Name); return true; } } @@ -1006,7 +1024,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); + print ("%s saved against effect: %s\n", actor->GetName(1), (char*) Opcodes[fx->Opcode].Name); return true; } } @@ -1025,7 +1043,7 @@ 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)\n", fx->Opcode, effectnames[fx->Opcode].Name, fx->Parameter1, fx->Parameter2 ); if( fx->Opcode >= MAX_EFFECTS) { fx->TimingMode = FX_DURATION_JUST_EXPIRED; return FX_NOT_APPLIED; @@ -1110,15 +1128,14 @@ 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->OpcodeOpcode].Function; if (!(target || (Opcodes[fx->Opcode].Flags & EFFECT_NO_ACTOR))) { - printf("targetless opcode without EFFECT_NO_ACTOR: %d, skipping\n", fx->Opcode); + print("targetless opcode without EFFECT_NO_ACTOR: %d, skipping\n", fx->Opcode); return FX_NOT_APPLIED; } } @@ -1152,7 +1169,7 @@ 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; @@ -1179,7 +1196,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]; @@ -1727,7 +1744,7 @@ bool EffectQueue::HasAnyDispellableEffect() const void EffectQueue::dump() const { - printf( "EFFECT QUEUE:\n" ); + print( "EFFECT QUEUE:\n" ); int i = 0; std::list< Effect* >::const_iterator f; for ( f = effects.begin(); f != effects.end(); f++ ) { @@ -1737,7 +1754,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 ); + print( " %2d: 0x%02x: %s (%d, %d) S:%s\n", i++, fx->Opcode, Name, fx->Parameter1, fx->Parameter2, fx->Source ); } } } @@ -1766,12 +1783,13 @@ bool EffectQueue::HasDuration(Effect *fx) 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) { diff --git a/project/jni/application/gemrb/gemrb/core/EffectQueue.h b/project/jni/application/gemrb/gemrb/core/EffectQueue.h index 1380c394a..0f4aed862 100644 --- a/project/jni/application/gemrb/gemrb/core/EffectQueue.h +++ b/project/jni/application/gemrb/gemrb/core/EffectQueue.h @@ -33,6 +33,7 @@ #include "Effect.h" #include "Region.h" +#include #include class Actor; diff --git a/project/jni/application/gemrb/gemrb/core/FileCache.cpp b/project/jni/application/gemrb/gemrb/core/FileCache.cpp new file mode 100644 index 000000000..3da6ea27a --- /dev/null +++ b/project/jni/application/gemrb/gemrb/core/FileCache.cpp @@ -0,0 +1,87 @@ +/* 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" + +DataStream* CacheCompressedStream(DataStream *stream, const char* filename, int length, bool overwrite) +{ + if (!core->IsAvailable(PLUGIN_COMPRESSION_ZLIB)) { + print( "No Compression Manager Available.\nCannot Load Compressed File.\n" ); + 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)) { + printMessage("FileCache", "Cannot write %s.\n", RED, path); + return NULL; + } + + PluginHolder 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); +} + +DataStream* CacheFile(const char* path) +{ + if (!core->GameOnCD) + return FileStream::OpenFile(path); + + char filename[_MAX_PATH]; + char cachedfile[_MAX_PATH]; + ExtractFileFromPath(filename, path); + PathJoin(cachedfile, core->CachePath, filename, NULL); + + if (!file_exists(cachedfile)) { // File was not found in cache + FileStream* src = FileStream::OpenFile(path); + FileStream* dest = FileStream::OpenFile(cachedfile); + if (!src || !dest) { + error("Cache", "CachedFile failed to write to cached file '%s' (from '%s')\n", cachedfile, path); + } + + size_t blockSize = 1024 * 1000; + char buff[1024 * 1000]; + do { + if (blockSize > src->Remains()) + blockSize = src->Remains(); + size_t len = src->Read(buff, blockSize); + size_t c = dest->Write(buff, len); + if (c != len) { + error("Cache", "CacheFile failed to write to cached file '%s' (from '%s')\n", cachedfile, path); + } + } while (src->Remains()); + delete src; + delete dest; + } + return FileStream::OpenFile(cachedfile); +} diff --git a/project/jni/application/gemrb/gemrb/core/FileCache.h b/project/jni/application/gemrb/gemrb/core/FileCache.h new file mode 100644 index 000000000..1345a4aa1 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/core/FileCache.h @@ -0,0 +1,27 @@ +/* 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" + +GEM_EXPORT DataStream* CacheCompressedStream(DataStream *stream, const char* filename, int length = 0, bool overwrite = false); +GEM_EXPORT DataStream* CacheFile(const char* path); + +#endif diff --git a/project/jni/application/gemrb/gemrb/core/Font.cpp b/project/jni/application/gemrb/gemrb/core/Font.cpp index 72c7b888f..7cb1bec4a 100644 --- a/project/jni/application/gemrb/gemrb/core/Font.cpp +++ b/project/jni/application/gemrb/gemrb/core/Font.cpp @@ -28,6 +28,7 @@ #include "GameData.h" #include "Interface.h" #include "Palette.h" +#include "Sprite2D.h" #include "Video.h" #include @@ -146,7 +147,7 @@ void Font::PrintFromLine(int startrow, Region rgn, const unsigned char* string, size_t len = strlen( ( char* ) string ); char* tmp = ( char* ) malloc( len + 1 ); memcpy( tmp, ( char * ) string, len + 1 ); - SetupString( tmp, rgn.w, NoColor ); + SetupString( tmp, rgn.w, NoColor, initials, enablecap ); int ystep = 0; if (Alignment & IE_FONT_SINGLE_LINE) { for (size_t i = 0; i < len; i++) { @@ -320,7 +321,7 @@ void Font::Print(Region cliprgn, Region rgn, const unsigned char* string, len--; } - SetupString( tmp, rgn.w, NoColor ); + SetupString( tmp, rgn.w, NoColor, initials, capital ); int ystep = 0; if (Alignment & IE_FONT_SINGLE_LINE) { @@ -454,39 +455,36 @@ int Font::CalcStringWidth(const char* string, bool NoColor) const size_t ret = 0, len = strlen( 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++]; + while(i 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,9 +493,14 @@ 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; @@ -515,6 +518,14 @@ 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; @@ -531,6 +542,14 @@ void Font::SetupString(char* string, unsigned int width, bool NoColor) const } wx += size[( unsigned char ) string[pos] - 1].w; + if (initials && enablecap) { + wx += initials->size[(unsigned char) string[pos] - 1].w; + enablecap=false; + initials_x = wx; + //how many more lines to be indented (one was already indented) + initials_rows = (initials->maxHeight-1)/maxHeight; + continue; + } if (( string[pos] == ' ' ) || ( string[pos] == '-' )) { x += wx; wx = 0; diff --git a/project/jni/application/gemrb/gemrb/core/Font.h b/project/jni/application/gemrb/gemrb/core/Font.h index 240bdf436..df2f06f38 100644 --- a/project/jni/application/gemrb/gemrb/core/Font.h +++ b/project/jni/application/gemrb/gemrb/core/Font.h @@ -33,6 +33,7 @@ #include class Palette; +class Sprite2D; struct StringList { Sprite2D*** strings; @@ -99,7 +100,7 @@ public: 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; + void SetupString(char* string, unsigned int width, bool NoColor = false, Font *initials = NULL, bool enablecap = 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); diff --git a/project/jni/application/gemrb/gemrb/core/GUI/Button.cpp b/project/jni/application/gemrb/gemrb/core/GUI/Button.cpp index 941cdd474..c2d4efa17 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/Button.cpp +++ b/project/jni/application/gemrb/gemrb/core/GUI/Button.cpp @@ -21,6 +21,9 @@ #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" @@ -125,7 +128,7 @@ void Button::CloseUpColor() unsigned long newtime; Changed = true; - GetTime( newtime ); + newtime = GetTickCount(); if (newtime #include @@ -92,6 +97,10 @@ void Control::ResetEventHandler(EventHandler handler) handler = NULL; } +void Control::SetText(const char* /*string*/) +{ +} + int Control::RunEventHandler(EventHandler handler) { if (InHandler) { @@ -121,67 +130,33 @@ int Control::RunEventHandler(EventHandler handler) } /** Key Press Event */ -void Control::OnKeyPress(unsigned char Key, unsigned short /*Mod*/) +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 + //print("OnKeyPress: CtrlID = 0x%08X, Key = %c (0x%02hX)\n", (unsigned int) ControlID, Key, Key); } /** 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 ); + //print( "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); +// print("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); +// print("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); + //print("OnMouseOver: CtrlID = 0x%08X, x = %hd, y = %hd\n", (unsigned int) ControlID, x, y); } /** Mouse Button Down */ @@ -200,7 +175,7 @@ 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\n", (unsigned int) ControlID, x, y, Button, Mod); } /** Special Key Press */ diff --git a/project/jni/application/gemrb/gemrb/core/GUI/Control.h b/project/jni/application/gemrb/gemrb/core/GUI/Control.h index 50a5ad2d4..bfd6862d0 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/Control.h +++ b/project/jni/application/gemrb/gemrb/core/GUI/Control.h @@ -67,7 +67,7 @@ public: /** 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 */ diff --git a/project/jni/application/gemrb/gemrb/core/GUI/EventMgr.cpp b/project/jni/application/gemrb/gemrb/core/GUI/EventMgr.cpp index 41e22b2b0..bae164a47 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/EventMgr.cpp +++ b/project/jni/application/gemrb/gemrb/core/GUI/EventMgr.cpp @@ -26,6 +26,7 @@ #include "Interface.h" #include "Video.h" +#include "GUI/Window.h" EventMgr::EventMgr(void) { @@ -236,7 +237,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; diff --git a/project/jni/application/gemrb/gemrb/core/GUI/EventMgr.h b/project/jni/application/gemrb/gemrb/core/GUI/EventMgr.h index bda4ae8b8..938525c2e 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/EventMgr.h +++ b/project/jni/application/gemrb/gemrb/core/GUI/EventMgr.h @@ -28,14 +28,13 @@ #ifndef EVENTMGR_H #define EVENTMGR_H -#include "GUI/Control.h" - #include "exports.h" -#include "WindowMgr.h" - #include +class Control; +class Window; + #define GEM_LEFT 0x81 #define GEM_RIGHT 0x82 #define GEM_UP 0x83 diff --git a/project/jni/application/gemrb/gemrb/core/GUI/GameControl.cpp b/project/jni/application/gemrb/gemrb/core/GUI/GameControl.cpp index 0794c0837..dafdd4b31 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/GameControl.cpp +++ b/project/jni/application/gemrb/gemrb/core/GUI/GameControl.cpp @@ -25,17 +25,25 @@ #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 "KeyMap.h" +#include "PathFinder.h" #include "SaveGameIterator.h" #include "ScriptEngine.h" +#include "TableMgr.h" +#include "TextArea.h" #include "TileMap.h" #include "Video.h" #include "damages.h" #include "GameScript/GSUtils.h" +#include "GUI/EventMgr.h" +#include "GUI/Window.h" #include "Scriptable/Container.h" #include "Scriptable/Door.h" #include "Scriptable/InfoPoint.h" @@ -47,11 +55,7 @@ #define DEBUG_SHOW_DOORS DEBUG_SHOW_CONTAINERS #define DEBUG_SHOW_LIGHTMAP 0x08 -#ifdef TOUCHSCREEN -# define SCROLL_BORDER 32 -#else -# define SCROLL_BORDER 5 -#endif +#define SCROLL_BORDER 5 static const Color cyan = { 0x00, 0xff, 0xff, 0xff @@ -132,9 +136,7 @@ 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; @@ -149,6 +151,12 @@ GameControl::GameControl(void) } else { ScreenFlags = SF_CENTERONACTOR; } + core->GetDictionary()->Lookup("TouchScrollAreas",tmp); + if (tmp) { + touchScrollAreasEnabled = true; + touched = false; + scrollAreasWidth = 32; + } LeftCount = 0; BottomCount = 0; RightCount = 0; @@ -271,7 +279,8 @@ void GameControl::CreateMovement(Actor *actor, const Point &p) actor->AddAction( action ); // force action so that we get target recticles immediately - actor->ProcessActions(true); + // FIXME + actor->ProcessActions(); } GameControl::~GameControl(void) @@ -587,30 +596,24 @@ 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 */ @@ -663,10 +666,6 @@ void GameControl::OnKeyPress(unsigned char Key, unsigned short /*Mod*/) SelectActor(pc+1, true); break; #ifdef ANDROID - case 'o': - case 'p': - Control::OnKeyPress(Key, 0); - break; case 'c': // show containers in ANDROID, GEM_ALT is not possible to use DebugFlags |= DEBUG_SHOW_CONTAINERS; return; @@ -881,7 +880,7 @@ void GameControl::OnKeyRelease(unsigned char Key, unsigned short Mod) area->MoveVisibleGroundPiles(p); break; case 'x': // shows coordinates on the map - printf( "%s [%d.%d]\n", area->GetScriptName(), p.x, p.y ); + print( "%s [%d.%d]\n", area->GetScriptName(), p.x, p.y ); break; case 'g'://shows loaded areas and other game information game->DebugDump(); @@ -997,22 +996,22 @@ 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"); + print("Show traps and infopoints %s\n", 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"); + print("Show lightmap %s\n", 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"); + print("Show Fog-Of-War: %s\n", 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"); + print("Show searchmap %s\n", core->FogOfWar & FOG_DRAWSEARCHMAP ? "ON" : "OFF"); break; default: - printf( "KeyRelease:%d - %d\n", Key, Mod ); + print( "KeyRelease:%d - %d\n", Key, Mod ); break; } return; //return from cheatkeys @@ -1030,6 +1029,7 @@ void GameControl::OnKeyRelease(unsigned char Key, unsigned short Mod) displaymsg->DisplayConstantString(STR_UNPAUSED,0xff0000); } break; +/* case 'm': core->GetGUIScriptEngine()->RunFunction("GUIMA","OpenMapWindow"); break; @@ -1042,6 +1042,13 @@ void GameControl::OnKeyRelease(unsigned char Key, unsigned short Mod) case 'r': core->GetGUIScriptEngine()->RunFunction("GUIREC","OpenRecordsWindow"); break; + case 'p': + core->GetGUIScriptEngine()->RunFunction("GUIPR","OpenPriestWindow"); + break; + case 'w': + core->GetGUIScriptEngine()->RunFunction("GUIMG","OpenMageWindow"); + break; +*/ case 'q': //quicksave QuickSave(); break; @@ -1052,6 +1059,7 @@ void GameControl::OnKeyRelease(unsigned char Key, unsigned short Mod) DebugFlags &= ~DEBUG_SHOW_CONTAINERS; break; default: + core->GetKeyMap()->ResolveKey(Key,0); break; } } @@ -1062,8 +1070,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; @@ -1230,61 +1237,61 @@ 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 { + if (touchScrollAreasEnabled) { + int mousescrollspd = core->GetMouseScrollSpeed(); + Region region; + Map* map; + Point mapsize; + Region viewport = core->GetVideoDriver()->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) { + scrolling = true; + return; + } else { + moveX = 0; + moveY = 0; + scrolling = false; + Video* video = core->GetVideoDriver(); + video->SetDragCursor(NULL); + } } -#endif lastMouseX = x; lastMouseY = y; @@ -1461,38 +1468,35 @@ void GameControl::OnGlobalMouseMove(unsigned short x, unsigned short y) return; } -#ifndef TOUCHSCREEN - int mousescrollspd = core->GetMouseScrollSpeed(); + if (!touchScrollAreasEnabled) { + 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 (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 (moveX != 0 || moveY != 0) { - scrolling = true; - } else if (scrolling) { - scrolling = false; + if (moveX != 0 || moveY != 0) { + scrolling = true; + } else if (scrolling) { + scrolling = false; - Video* video = core->GetVideoDriver(); - video->SetDragCursor(NULL); + Video* video = core->GetVideoDriver(); + video->SetDragCursor(NULL); + } } -#else -(void)x; -(void)y; -#endif } void GameControl::UpdateScrolling() { @@ -1738,7 +1742,7 @@ void GameControl::HandleContainer(Container *container, Actor *actor) return; } - if ((target_mode == TARGET_MODE_PICK)) { + if (target_mode == TARGET_MODE_PICK) { TryToPick(actor, container); return; } @@ -1798,14 +1802,16 @@ 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())); + // exit usage is handled by caller for now + // actor->UseExit(trap->GetGlobalID()); return false; case ST_TRIGGER: //the importer shouldn't load the script @@ -1816,16 +1822,12 @@ 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; - //} + //trap->Scripts[0]->Update(); + // FIXME + trap->ExecuteScript(1); + trap->ProcessActions(); } } else { if (trap->overHeadText) { @@ -1875,9 +1877,7 @@ 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; } } @@ -1902,33 +1902,33 @@ 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) { + 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 ); + } } + free( ab ); + DrawSelectionRect = false; } - free( ab ); - DrawSelectionRect = false; + return; } - return; } -#endif if (DrawSelectionRect) { Actor** ab; unsigned int count = area->GetActorInRect( ab, SelectionRect,true ); @@ -1999,11 +1999,10 @@ void GameControl::OnMouseUp(unsigned short x, unsigned short y, unsigned short B while(i--) { game->selected[i]->UseExit(exitID); } - } else { - if (HandleActiveRegion(overInfoPoint, pc, p)) { - core->SetEventFlag(EF_RESETTARGET); - return; - } + } + if (HandleActiveRegion(overInfoPoint, pc, p)) { + core->SetEventFlag(EF_RESETTARGET); + return; } } @@ -2387,8 +2386,8 @@ void GameControl::HandleWindowHide(const char *WindowName, const char *WindowPos } return; } - printMessage("GameControl", "Invalid Window Index: ", LIGHT_RED); - printf("%s:%u\n",WindowName, index); + printMessage("GameControl", "Invalid Window Index: %s:%u\n", LIGHT_RED, + WindowName, index); } } } @@ -2440,8 +2439,8 @@ void GameControl::HandleWindowReveal(const char *WindowName, const char *WindowP } return; } - printMessage("GameControl", "Invalid Window Index ", LIGHT_RED); - printf("%s:%u\n",WindowName, index); + printMessage("GameControl", "Invalid Window Index %s:%u\n", LIGHT_RED, + WindowName, index); } } } @@ -2695,7 +2694,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 +2707,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 ); diff --git a/project/jni/application/gemrb/gemrb/core/GUI/GameControl.h b/project/jni/application/gemrb/gemrb/core/GUI/GameControl.h index 0ff21d3e1..8e5bf14cc 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/GameControl.h +++ b/project/jni/application/gemrb/gemrb/core/GUI/GameControl.h @@ -96,8 +96,6 @@ 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); /** Sets multiple quicksaves flag*/ static void MultipleQuickSaves(int arg); void SetTracker(Actor *actor, ieDword dist); @@ -112,9 +110,12 @@ private: Region SelectionRect; 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; diff --git a/project/jni/application/gemrb/gemrb/core/GUI/Label.cpp b/project/jni/application/gemrb/gemrb/core/GUI/Label.cpp index 4d67af4aa..6579e61f3 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/Label.cpp +++ b/project/jni/application/gemrb/gemrb/core/GUI/Label.cpp @@ -25,8 +25,10 @@ #include "GameData.h" #include "Interface.h" #include "Palette.h" +#include "Sprite2D.h" #include "Variables.h" #include "Video.h" +#include "GUI/Window.h" Label::Label(Font* font) { @@ -71,7 +73,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 +97,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) @@ -119,7 +120,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\n" ); if (( x <= Width ) && ( y <= Height )) { if (VarName[0] != 0) { core->GetDictionary()->SetAt( VarName, Value ); diff --git a/project/jni/application/gemrb/gemrb/core/GUI/Label.h b/project/jni/application/gemrb/gemrb/core/GUI/Label.h index b0a841dfc..20ef5f9fc 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/Label.h +++ b/project/jni/application/gemrb/gemrb/core/GUI/Label.h @@ -51,7 +51,7 @@ 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); /** Sets the Alignment of Text */ diff --git a/project/jni/application/gemrb/gemrb/core/GUI/MapControl.cpp b/project/jni/application/gemrb/gemrb/core/GUI/MapControl.cpp index 4abd158ad..459c438e4 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/MapControl.cpp +++ b/project/jni/application/gemrb/gemrb/core/GUI/MapControl.cpp @@ -22,9 +22,14 @@ #include "win32def.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" #define MAP_NO_NOTES 0 #define MAP_VIEW_NOTES 1 @@ -224,6 +229,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 @@ -269,18 +279,8 @@ void MapControl::Draw(unsigned short XWin, unsigned short YWin) } /** Key Press Event */ -void MapControl::OnKeyPress(unsigned char Key, unsigned short /*Mod*/) +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 */ @@ -289,7 +289,7 @@ void MapControl::OnKeyRelease(unsigned char Key, unsigned short Mod) switch (Key) { case '\t': //not GEM_TAB - printf( "TAB released\n" ); + print( "TAB released\n" ); return; case 'f': if (Mod & GEM_MOD_CTRL) @@ -471,7 +471,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); @@ -499,10 +499,10 @@ void MapControl::OnSpecialKeyPress(unsigned char Key) ScrollY += 64; break; case GEM_ALT: - printf( "ALT pressed\n" ); + print( "ALT pressed\n" ); break; case GEM_TAB: - printf( "TAB pressed\n" ); + print( "TAB pressed\n" ); break; default: break; diff --git a/project/jni/application/gemrb/gemrb/core/GUI/MapControl.h b/project/jni/application/gemrb/gemrb/core/GUI/MapControl.h index 1154bf8c1..44ecec887 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/MapControl.h +++ b/project/jni/application/gemrb/gemrb/core/GUI/MapControl.h @@ -79,8 +79,6 @@ public: 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); diff --git a/project/jni/application/gemrb/gemrb/core/GUI/Progressbar.cpp b/project/jni/application/gemrb/gemrb/core/GUI/Progressbar.cpp index d31f58958..1c09586d1 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/Progressbar.cpp +++ b/project/jni/application/gemrb/gemrb/core/GUI/Progressbar.cpp @@ -24,6 +24,7 @@ #include "Interface.h" #include "Video.h" +#include "GUI/Window.h" #include @@ -162,12 +163,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; diff --git a/project/jni/application/gemrb/gemrb/core/GUI/Progressbar.h b/project/jni/application/gemrb/gemrb/core/GUI/Progressbar.h index 411ae5510..6a777c42f 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/Progressbar.h +++ b/project/jni/application/gemrb/gemrb/core/GUI/Progressbar.h @@ -60,8 +60,6 @@ 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); /** Set handler for specified event */ diff --git a/project/jni/application/gemrb/gemrb/core/GUI/ScrollBar.cpp b/project/jni/application/gemrb/gemrb/core/GUI/ScrollBar.cpp index aea1b9833..3893c684f 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/ScrollBar.cpp +++ b/project/jni/application/gemrb/gemrb/core/GUI/ScrollBar.cpp @@ -25,6 +25,8 @@ #include "Interface.h" #include "Variables.h" #include "Video.h" +#include "GUI/EventMgr.h" +#include "GUI/Window.h" ScrollBar::ScrollBar(void) { @@ -263,12 +265,6 @@ void ScrollBar::OnMouseOver(unsigned short /*x*/, unsigned short y) } } -/** Sets the Text of the current control */ -int ScrollBar::SetText(const char* /*string*/, int /*pos*/) -{ - return 0; -} - /** Sets the Maximum Value of the ScrollBar */ void ScrollBar::SetMax(unsigned short Max) { diff --git a/project/jni/application/gemrb/gemrb/core/GUI/ScrollBar.h b/project/jni/application/gemrb/gemrb/core/GUI/ScrollBar.h index 4a2d172ac..3effd49c2 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/ScrollBar.h +++ b/project/jni/application/gemrb/gemrb/core/GUI/ScrollBar.h @@ -77,8 +77,6 @@ private: //Private attributes unsigned short Pos; /** Scroll Bar Status */ unsigned short State; - /** Sets the Text of the current control */ - int SetText(const char* string, int pos = 0); public: void SetImage(unsigned char type, Sprite2D* img); /** Sets the Maximum Value of the ScrollBar */ diff --git a/project/jni/application/gemrb/gemrb/core/GUI/Slider.cpp b/project/jni/application/gemrb/gemrb/core/GUI/Slider.cpp index 09812ab3c..d9e24e2dd 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/Slider.cpp +++ b/project/jni/application/gemrb/gemrb/core/GUI/Slider.cpp @@ -25,6 +25,7 @@ #include "Interface.h" #include "Variables.h" #include "Video.h" +#include "GUI/Window.h" #include @@ -273,12 +274,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) { diff --git a/project/jni/application/gemrb/gemrb/core/GUI/Slider.h b/project/jni/application/gemrb/gemrb/core/GUI/Slider.h index 66f26ae0a..30636082a 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/Slider.h +++ b/project/jni/application/gemrb/gemrb/core/GUI/Slider.h @@ -60,8 +60,6 @@ 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 */ diff --git a/project/jni/application/gemrb/gemrb/core/GUI/TextArea.cpp b/project/jni/application/gemrb/gemrb/core/GUI/TextArea.cpp index b19ad5770..9f97eef79 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/TextArea.cpp +++ b/project/jni/application/gemrb/gemrb/core/GUI/TextArea.cpp @@ -32,6 +32,8 @@ #include "Palette.h" #include "Variables.h" #include "Video.h" +#include "GUI/EventMgr.h" +#include "GUI/Window.h" #include "Scriptable/Actor.h" #include @@ -126,7 +128,7 @@ void TextArea::Draw(unsigned short x, unsigned short y) { unsigned long thisTime; - GetTime( thisTime); + thisTime = GetTickCount(); if (thisTime>starttime) { starttime = thisTime+ticks; smooth--; @@ -297,36 +299,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 (!text[0]) { + Clear(); + } - if (lines.size() == 0) { - pos = -1; - } - } - if (pos >= ( int ) lines.size()) { - return -1; - } 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) @@ -479,7 +471,7 @@ void TextArea::OnKeyPress(unsigned char Key, unsigned short /*Mod*/) Owner->Invalidate(); Changed = true; int len = GetRowLength(CurLine); - //printf("len: %d Before: %s\n",len, lines[CurLine]); + //print("len: %d Before: %s\n",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,7 +479,7 @@ 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\n",CurPos, lines[CurLine]); CalcRowCount(); RunEventHandler( TextAreaOnChange ); } @@ -577,7 +569,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\n",len, lines[CurLine]); if (CurPos>=len) { //TODO: merge next line break; @@ -586,12 +578,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\n",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\n",len, lines[CurLine]); if (len<1) { break; } @@ -601,15 +593,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\n",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\n",old, lines[CurLine]); + //print("len: %d Before: %s\n",len, lines[oldline]); lines[CurLine] = (char *) realloc (lines[CurLine], len+old); memcpy(lines[CurLine]+old, lines[oldline],len); free(lines[oldline]); @@ -617,13 +609,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\n",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\n",CurPos, lines[CurLine]); lrows.insert(lrows.begin()+CurLine, 0); len = GetRowLength(CurLine); //copy the text after the cursor into the new line @@ -637,8 +629,8 @@ 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\n",GetRowLength(CurLine-1), lines[CurLine-1]); + //print("len: %d After: %s\n",GetRowLength(CurLine), lines[CurLine]); break; } CalcRowCount(); @@ -780,7 +772,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\n", ControlID, i, rows, row, r); return; } } @@ -788,7 +780,7 @@ 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\n", ControlID, seltext, rows, row, r); } /** Mouse Button Up */ @@ -822,13 +814,25 @@ 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& 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) @@ -939,7 +943,7 @@ void TextArea::SetupScroll(unsigned long tck) } i = (unsigned int) lines.size(); Flags |= IE_GUI_TEXTAREA_SMOOTHSCROLL; - GetTime( starttime ); + starttime = GetTickCount(); if (RunEventHandler( TextAreaOutOfText )) { //event handler destructed this object? return; diff --git a/project/jni/application/gemrb/gemrb/core/GUI/TextArea.h b/project/jni/application/gemrb/gemrb/core/GUI/TextArea.h index 2ba24a496..fe42f3d2c 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/TextArea.h +++ b/project/jni/application/gemrb/gemrb/core/GUI/TextArea.h @@ -71,7 +71,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& text); /** Clears the textarea */ void Clear(); /** Discards scrolled out lines from the textarea */ diff --git a/project/jni/application/gemrb/gemrb/core/GUI/TextEdit.cpp b/project/jni/application/gemrb/gemrb/core/GUI/TextEdit.cpp index 969ea88f0..00a884dcc 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/TextEdit.cpp +++ b/project/jni/application/gemrb/gemrb/core/GUI/TextEdit.cpp @@ -25,6 +25,12 @@ #include "Interface.h" #include "Palette.h" #include "Video.h" +#include "GUI/EventMgr.h" +#include "GUI/Window.h" + +#if TARGET_OS_IPHONE +# include "SDL_uikitkeyboard.h" +#endif TextEdit::TextEdit(unsigned short maxLength, unsigned short px, unsigned short py) { @@ -71,6 +77,9 @@ void TextEdit::Draw(unsigned short x, unsigned short y) //The aligning of textedit fields is done by absolute positioning (FontPosX, FontPosY) if (hasFocus) { +#if TARGET_OS_IPHONE + SDL_iPhoneKeyboardShow(SDL_GetWindowFromID(1)); +#endif font->Print( Region( x + XPos + FontPosX, y + YPos + FontPosY, Width, Height ), Buffer, palette, IE_FONT_ALIGN_LEFT | IE_FONT_ALIGN_TOP, true, NULL, Cursor, CurPos ); @@ -184,7 +193,7 @@ void TextEdit::OnSpecialKeyPress(unsigned char Key) } /** 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; @@ -192,7 +201,6 @@ int TextEdit::SetText(const char* string, int /*pos*/) if (Owner) { Owner->Invalidate(); } - return 0; } void TextEdit::SetBufferLength(ieWord buflen) diff --git a/project/jni/application/gemrb/gemrb/core/GUI/TextEdit.h b/project/jni/application/gemrb/gemrb/core/GUI/TextEdit.h index f92e91370..697b3062c 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/TextEdit.h +++ b/project/jni/application/gemrb/gemrb/core/GUI/TextEdit.h @@ -63,7 +63,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); /** Sets the Text of the current control */ const char* QueryText(); /** Sets the buffer length */ diff --git a/project/jni/application/gemrb/gemrb/core/GUI/Window.cpp b/project/jni/application/gemrb/gemrb/core/GUI/Window.cpp index ed1395aaf..504bc1e19 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/Window.cpp +++ b/project/jni/application/gemrb/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" diff --git a/project/jni/application/gemrb/gemrb/core/GUI/Window.h b/project/jni/application/gemrb/gemrb/core/GUI/Window.h index a4798ddee..450bc05cf 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/Window.h +++ b/project/jni/application/gemrb/gemrb/core/GUI/Window.h @@ -29,15 +29,13 @@ #define WINDOW_H #include "GUI/Control.h" -#include "GUI/ScrollBar.h" -#include "GUI/TextArea.h" #include "exports.h" -#include "Sprite2D.h" - #include +class Sprite2D; + // Window Flags #define WF_CHANGED 1 //window changed #define WF_FRAME 2 //window has frame diff --git a/project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.cpp b/project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.cpp index cca132fc9..f13b74aa7 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.cpp +++ b/project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.cpp @@ -21,11 +21,14 @@ #include "win32def.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" #define MAP_TO_SCREENX(x) XWin + XPos - ScrollX + (x) #define MAP_TO_SCREENY(y) YWin + YPos - ScrollY + (y) @@ -341,10 +344,10 @@ void WorldMapControl::OnSpecialKeyPress(unsigned char Key) ScrollY += 64; break; case GEM_ALT: - printf( "ALT pressed\n" ); + print( "ALT pressed\n" ); break; case GEM_TAB: - printf( "TAB pressed\n" ); + print( "TAB pressed\n" ); break; } diff --git a/project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.h b/project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.h index c02cef7f5..e0c08ad7c 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.h +++ b/project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.h @@ -66,8 +66,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; diff --git a/project/jni/application/gemrb/gemrb/core/Game.cpp b/project/jni/application/gemrb/gemrb/core/Game.cpp index 00009c481..d9903603b 100644 --- a/project/jni/application/gemrb/gemrb/core/Game.cpp +++ b/project/jni/application/gemrb/gemrb/core/Game.cpp @@ -29,10 +29,13 @@ #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" @@ -149,7 +152,7 @@ Game::~Game(void) } } -bool IsAlive(Actor *pc) +static bool IsAlive(Actor *pc) { if (pc->GetStat(IE_STATE_ID)&STATE_DEAD) { return false; @@ -312,6 +315,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); } } @@ -369,8 +374,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; @@ -475,7 +479,7 @@ void Game::SetHotKey(unsigned long Key) Actor *actor = *m; if (actor->IsSelected()) { - actor->HotKey = (ieDword) Key; + actor->AddTrigger(TriggerEntry(trigger_hotkey, (ieDword) Key)); } } } @@ -769,7 +773,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()); @@ -1021,7 +1025,7 @@ int Game::GetXPFromCR(int cr) if (cr>=MAX_CRLEVEL) { cr=MAX_CRLEVEL-1; } - printf("Challenge Rating: %d, party level: %d ", cr, level); + print("Challenge Rating: %d, party level: %d ", cr, level); return crtable[level][cr]; } printMessage("Game","Cannot find moncrate.2da!\n", LIGHT_RED); @@ -1097,7 +1101,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); + print("Actor %s is not near!\n", PCs[i]->LongName); return false; } } @@ -1124,17 +1128,6 @@ void Game::PartyMemberDied(Actor *actor) } } -//reports if someone died -int Game::PartyMemberDied() const -{ - for (unsigned int i=0; iGetInternalFlag()&IF_JUSTDIED) { - return i; - } - } - return -1; -} - void Game::IncrementChapter() { //chapter first set to 0 (prologue) @@ -1285,8 +1278,7 @@ bool Game::EveryoneDead() const void Game::UpdateScripts() { - ExecuteScript( 1 ); - ProcessActions(false); + Update(); size_t idx; PartyAttack = false; @@ -1524,7 +1516,19 @@ void Game::RestParty(int checks, int dream, int hp) 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 @@ -1549,7 +1553,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 @@ -1558,9 +1561,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) { @@ -1617,7 +1617,7 @@ void Game::ChangeSong(bool always, bool force) } /* 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) { @@ -1717,21 +1717,21 @@ void Game::DebugDump() { size_t idx; - printf("Currently loaded areas:\n"); + print("Currently loaded areas:\n"); for(idx=0;idxGetScriptName()); + print("%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); + print("Current area: %s Previous area: %s\n", CurrentArea, PreviousArea); + print("Global script: %s\n", Scripts[0]->GetName()); + print("CombatCounter: %d\n", (int) CombatCounter); - printf("Party size: %d\n", (int) PCs.size()); + print("Party size: %d\n", (int) PCs.size()); for(idx=0;idxShortName, actor->InParty, actor->Selected?"x":"-"); + print("Name: %s Order %d %s\n",actor->ShortName, actor->InParty, actor->Selected?"x":"-"); } } @@ -1755,3 +1755,7 @@ ieByte *Game::AllocateMazeData() return mazedata; } +bool Game::IsTimestopActive() +{ + return timestop_end > GameTime; +} diff --git a/project/jni/application/gemrb/gemrb/core/Game.h b/project/jni/application/gemrb/gemrb/core/Game.h index 5ed080447..851d28d72 100644 --- a/project/jni/application/gemrb/gemrb/core/Game.h +++ b/project/jni/application/gemrb/gemrb/core/Game.h @@ -34,13 +34,16 @@ 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 +class Actor; +class Map; class Particles; +class TableMgr; //the size of the bestiary register #define BESTIARY_SIZE 260 @@ -420,8 +423,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 */ @@ -449,6 +450,8 @@ public: void 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, @@ -468,6 +471,8 @@ public: Actor *GetActorByGlobalID(ieDword objectID); /** Allocates maze data */ ieByte *AllocateMazeData(); + /** Checks if any timestop effects are active */ + bool IsTimestopActive(); private: bool DetermineStartPosType(const TableMgr *strta); ieResRef *GetDream(Map *area); diff --git a/project/jni/application/gemrb/gemrb/core/GameData.cpp b/project/jni/application/gemrb/gemrb/core/GameData.cpp index 038711cbd..f4c82b53f 100644 --- a/project/jni/application/gemrb/gemrb/core/GameData.cpp +++ b/project/jni/application/gemrb/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,9 +35,12 @@ #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" @@ -90,7 +96,7 @@ Actor *GameData::GetCreature(const char* ResRef, unsigned int PartySlot) return 0; PluginHolder actormgr(IE_CRE_CLASS_ID); - if (!actormgr->Open( ds, true )) { + if (!actormgr->Open(ds)) { return 0; } Actor* actor = actormgr->GetActor(PartySlot); @@ -106,11 +112,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(IE_CRE_CLASS_ID); - if (!actormgr->Open( stream, true )) { + if (!actormgr->Open(stream)) { return -1; } actor = actormgr->GetActor(PartySlot); @@ -151,7 +155,7 @@ int GameData::LoadTable(const ieResRef ResRef) tables[ind].refcount++; return ind; } - //printf("(%s) Table not found... Loading from file\n", ResRef); + //print("(%s) Table not found... Loading from file\n", ResRef); DataStream* str = GetResource( ResRef, IE_2DA_CLASS_ID ); if (!str) { return -1; @@ -161,7 +165,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 +261,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 +269,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(); @@ -293,7 +293,7 @@ Item* GameData::GetItem(const ieResRef resname) delete ( str ); return NULL; } - if (!sm->Open( str, true )) { + if (!sm->Open(str)) { return NULL; } @@ -316,9 +316,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 +334,7 @@ Spell* GameData::GetSpell(const ieResRef resname, bool silent) delete ( str ); return NULL; } - if (!sm->Open( str, true )) { + if (!sm->Open(str)) { return NULL; } @@ -358,8 +356,8 @@ void GameData::FreeSpell(Spell *spl, const ieResRef name, bool free) 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); + printMessage("Core", "Corrupted Spell cache encountered (reference count went below zero), Spell name is: %.8s or %.8s\n", LIGHT_RED, + name, spl->Name); abort(); } if (res) return; @@ -378,7 +376,7 @@ Effect* GameData::GetEffect(const ieResRef resname) delete ( str ); return NULL; } - if (!em->Open( str, true )) { + if (!em->Open(str)) { return NULL; } @@ -397,9 +395,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; @@ -413,7 +409,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 ); @@ -463,7 +459,8 @@ void* GameData::GetFactoryResource(const char* resname, SClass_ID type, PluginHolder 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; @@ -482,9 +479,71 @@ 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 ) ); + print( "\n" ); + printMessage("KEYImporter", "%s files are not supported.\n", WHITE, + 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 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 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/project/jni/application/gemrb/gemrb/core/GameData.h b/project/jni/application/gemrb/gemrb/core/GameData.h index e61a65eb0..30c9aaf68 100644 --- a/project/jni/application/gemrb/gemrb/core/GameData.h +++ b/project/jni/application/gemrb/gemrb/core/GameData.h @@ -24,11 +24,19 @@ #include "SClassID.h" #include "exports.h" #include "ie_types.h" +#include "iless.h" #include "Cache.h" #include "Holder.h" #include "ResourceManager.h" +#include +#include + +#ifdef _MSC_VER // No SFINAE +#include "TableMgr.h" +#endif + class Actor; struct Effect; class Factory; @@ -38,6 +46,7 @@ class ScriptedAnimation; class Spell; class Sprite2D; class TableMgr; +class Store; struct Table { Holder tm; @@ -90,6 +99,12 @@ public: /** 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; @@ -97,6 +112,8 @@ private: Cache PaletteCache; Factory* factory; std::vector tables; + typedef std::map StoreMap; + StoreMap stores; }; extern GEM_EXPORT GameData * gamedata; diff --git a/project/jni/application/gemrb/gemrb/core/GameScript/Actions.cpp b/project/jni/application/gemrb/gemrb/core/GameScript/Actions.cpp index fb34e6c63..89c11ddf6 100644 --- a/project/jni/application/gemrb/gemrb/core/GameScript/Actions.cpp +++ b/project/jni/application/gemrb/gemrb/core/GameScript/Actions.cpp @@ -27,11 +27,14 @@ #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,6 +44,7 @@ #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" @@ -457,7 +461,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); + print("Script error: No Trigger Named \"%s\"\n", parameters->objects[1]->objectName); return; } InfoPoint *trigger = (InfoPoint *) ip; @@ -578,7 +582,7 @@ void GameScript::ExitPocketPlane(Scriptable* /*Sender*/, Action* /*parameters*/) if (act) { if (game->GetPlaneLocationCount() <= (unsigned int)i) { // what are we meant to do here? - printf("argh, couldn't restore party member %d!", i + 1); + print("argh, couldn't restore party member %d!", i + 1); continue; } GAMLocationEntry *gle = game->GetPlaneLocationEntry(i); @@ -678,7 +682,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 @@ -1126,13 +1130,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) @@ -1308,7 +1309,7 @@ void GameScript::RestorePartyLocation(Scriptable* /*Sender*/, Action* /*paramete if (act) { if (game->GetSavedLocationCount() <= (unsigned int)i) { // what are we meant to do here? - printf("argh, couldn't restore party member %d!", i + 1); + print("argh, couldn't restore party member %d!", i + 1); continue; } GAMLocationEntry *gle = game->GetSavedLocationEntry(i); @@ -1523,7 +1524,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"); + print("DisplayStringHead/FloatMessage got no target, assuming Sender!\n"); } DisplayStringCore(target, parameters->int0Parameter, DS_CONSOLE|DS_HEAD|DS_SPEECH ); @@ -1556,7 +1557,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"); + print("DisplayStringHead/FloatMessage got no target, assuming Sender!\n"); } DisplayStringCore(target, parameters->int0Parameter, DS_CONSOLE|DS_HEAD); @@ -1567,7 +1568,7 @@ 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"); + print("DisplayStringHead/FloatMessage got no target, assuming Sender!\n"); } SrcVector *rndstr=LoadSrc(parameters->string0Parameter); @@ -1584,7 +1585,7 @@ 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"); + print("DisplayStringHead/FloatMessage got no target, assuming Sender!\n"); } SrcVector *rndstr=LoadSrc(parameters->string0Parameter); @@ -1770,20 +1771,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 ); + print( "PlaySound(%s)\n", 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 ); + print( "PlaySound(%s)\n", 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 ); + print( "PlaySound(%s)\n", parameters->string0Parameter ); core->GetAudioDrv()->Play( parameters->string0Parameter, 0, 0); } @@ -1903,7 +1904,7 @@ void GameScript::AmbientActivate(Scriptable* Sender, Action* parameters) anim = Sender->GetCurrentArea( )->GetAnimation( parameters->objects[1]->objectName ); } if (!anim) { - printf( "Script error: No Animation Named \"%s\" or \"%s\"\n", + print( "Script error: No Animation Named \"%s\" or \"%s\"\n", parameters->string0Parameter,parameters->objects[1]->objectName ); return; } @@ -1934,7 +1935,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", + print( "Script error: No Animation Named \"%s\"\n", parameters->objects[1]->objectName ); return; } @@ -1945,7 +1946,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", + print( "Script error: No Animation Named \"%s\"\n", parameters->objects[1]->objectName ); return; } @@ -1956,7 +1957,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", + print( "Script error: No Animation Named \"%s\"\n", parameters->objects[1]->objectName ); return; } @@ -2146,7 +2147,7 @@ void GameScript::NIDSpecial2(Scriptable* Sender, Action* /*parameters*/) } //travel direction passed to guiscript int direction = Sender->GetCurrentArea()->WhichEdge(actor->Pos); - printf("Travel direction returned: %d\n", direction); + print("Travel direction returned: %d\n", direction); if (direction==-1) { Sender->ReleaseCurrentAction(); return; @@ -2565,16 +2566,16 @@ void GameScript::Spell(Scriptable* Sender, Action* parameters) 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); + if (Sender->CurrentActionState) { + if (Sender->LastTarget) { + //if target was set, fire spell + Sender->CastSpellEnd(0); + } else if(!Sender->LastTargetPos.isempty()) { + //the target was converted to a point + Sender->CastSpellPointEnd(0); + } else { + printMessage("GameScript", "Spell lost target somewhere!", LIGHT_RED); + } Sender->ReleaseCurrentAction(); return; } @@ -2613,6 +2614,7 @@ void GameScript::Spell(Scriptable* Sender, Action* parameters) //stop doing anything else act->SetModal(MS_NONE); } + Sender->CurrentActionState = 1; int duration = Sender->CastSpell( spellres, tar, true ); if (duration != -1) Sender->SetWait(duration); @@ -2634,9 +2636,13 @@ void GameScript::SpellPoint(Scriptable* Sender, Action* parameters) return; } - //if target was set, fire spell - if (!Sender->LastTargetPos.isempty()) { - Sender->CastSpellPointEnd(0); + if (Sender->CurrentActionState) { + if(!Sender->LastTargetPos.isempty()) { + //if target was set, fire spell + Sender->CastSpellPointEnd(0); + } else { + printMessage("GameScript", "SpellPoint lost target somewhere!", LIGHT_RED); + } Sender->ReleaseCurrentAction(); return; } @@ -2657,6 +2663,7 @@ void GameScript::SpellPoint(Scriptable* Sender, Action* parameters) act->SetModal(MS_NONE); } + Sender->CurrentActionState = 1; int duration = Sender->CastSpellPoint( spellres, parameters->pointParameter, true ); if (duration != -1) Sender->SetWait(duration); @@ -2683,16 +2690,16 @@ void GameScript::SpellNoDec(Scriptable* Sender, Action* parameters) } } - //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); + if (Sender->CurrentActionState) { + if (Sender->LastTarget) { + //if target was set, fire spell + Sender->CastSpellEnd(0); + } else if(!Sender->LastTargetPos.isempty()) { + //the target was converted to a point + Sender->CastSpellPointEnd(0); + } else { + printMessage("GameScript", "SpellNoDec lost target somewhere!", LIGHT_RED); + } Sender->ReleaseCurrentAction(); return; } @@ -2714,6 +2721,7 @@ void GameScript::SpellNoDec(Scriptable* Sender, Action* parameters) //stop doing anything else act->SetModal(MS_NONE); } + Sender->CurrentActionState = 1; int duration = Sender->CastSpell( spellres, tar, false ); if (duration != -1) Sender->SetWait(duration); @@ -2740,9 +2748,13 @@ void GameScript::SpellPointNoDec(Scriptable* Sender, Action* parameters) } } - //if target was set, fire spell - if (!Sender->LastTargetPos.isempty()) { - Sender->CastSpellPointEnd(0); + if (Sender->CurrentActionState) { + if(!Sender->LastTargetPos.isempty()) { + //if target was set, fire spell + Sender->CastSpellPointEnd(0); + } else { + printMessage("GameScript", "SpellPointNoDec lost target somewhere!", LIGHT_RED); + } Sender->ReleaseCurrentAction(); return; } @@ -2756,6 +2768,7 @@ void GameScript::SpellPointNoDec(Scriptable* Sender, Action* parameters) act->SetModal(MS_NONE); } + Sender->CurrentActionState = 1; int duration = Sender->CastSpellPoint( spellres, parameters->pointParameter, false ); if (duration != -1) Sender->SetWait(duration); @@ -2782,16 +2795,16 @@ void GameScript::ForceSpell(Scriptable* Sender, Action* parameters) } } - //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); + if (Sender->CurrentActionState) { + if (Sender->LastTarget) { + //if target was set, fire spell + Sender->CastSpellEnd(0); + } else if(!Sender->LastTargetPos.isempty()) { + //the target was converted to a point + Sender->CastSpellPointEnd(0); + } else { + printMessage("GameScript", "ForceSpell lost target somewhere!", LIGHT_RED); + } Sender->ReleaseCurrentAction(); return; } @@ -2813,6 +2826,7 @@ void GameScript::ForceSpell(Scriptable* Sender, Action* parameters) //stop doing anything else act->SetModal(MS_NONE); } + Sender->CurrentActionState = 1; int duration = Sender->CastSpell (spellres, tar, false); if (duration != -1) Sender->SetWait(duration); @@ -2838,9 +2852,13 @@ void GameScript::ForceSpellPoint(Scriptable* Sender, Action* parameters) } } - //if target was set, fire spell - if (!Sender->LastTargetPos.isempty()) { - Sender->CastSpellPointEnd(0); + if (Sender->CurrentActionState) { + if(!Sender->LastTargetPos.isempty()) { + //if target was set, fire spell + Sender->CastSpellPointEnd(0); + } else { + printMessage("GameScript", "ForceSpellPoint lost target somewhere!", LIGHT_RED); + } Sender->ReleaseCurrentAction(); return; } @@ -2854,6 +2872,7 @@ void GameScript::ForceSpellPoint(Scriptable* Sender, Action* parameters) act->SetModal(MS_NONE); } + Sender->CurrentActionState = 1; int duration = Sender->CastSpellPoint (spellres, parameters->pointParameter, false); if (duration != -1) Sender->SetWait(duration); @@ -2975,9 +2994,9 @@ void GameScript::ReallyForceSpellDead(Scriptable* Sender, Action* parameters) level = parameters->int1Parameter; } if (tar->Type==ST_ACTOR) { - Sender->CastSpellEnd(parameters->int1Parameter); + Sender->CastSpellEnd(level); } else { - Sender->CastSpellPointEnd(parameters->int1Parameter); + Sender->CastSpellPointEnd(level); } Sender->ReleaseCurrentAction(); } @@ -3387,18 +3406,18 @@ 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(); + } + actor->CurrentActionState--; } void GameScript::PlayDeadInterruptable(Scriptable* Sender, Action* parameters) @@ -3408,17 +3427,17 @@ 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(); + } + actor->CurrentActionState--; } /* this may not be correct, just a placeholder you can fix */ @@ -3863,7 +3882,7 @@ void GameScript::MakeUnselectable(Scriptable* Sender, Action* parameters) void GameScript::Debug(Scriptable* /*Sender*/, Action* parameters) { InDebug=parameters->int0Parameter; - printMessage("GameScript",parameters->string0Parameter,YELLOW); + printMessage("GameScript","%s",YELLOW,parameters->string0Parameter); } void GameScript::IncrementProficiency(Scriptable* Sender, Action* parameters) @@ -4269,7 +4288,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 { @@ -4300,7 +4322,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 { @@ -4328,7 +4353,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); @@ -4600,10 +4628,11 @@ void GameScript::PickPockets(Scriptable *Sender, Action* parameters) //noticed attempt displaymsg->DisplayConstantString(STR_PICKPOCKET_FAIL,0xffffff); if (core->HasFeature(GF_STEAL_IS_ATTACK) ) { - tar->LastAttacker = snd->GetGlobalID(); + tar->AddTrigger(TriggerEntry(trigger_attackedby, snd->GetGlobalID())); + tar->LastAttacker = snd->GetGlobalID(); // FIXME } else { //pickpocket failed trigger - tar->LastOpenFailed = snd->GetGlobalID(); + tar->AddTrigger(TriggerEntry(trigger_pickpocketfailed, snd->GetGlobalID())); } Sender->ReleaseCurrentAction(); return; @@ -4635,7 +4664,9 @@ void GameScript::PickPockets(Scriptable *Sender, Action* parameters) return; } CREItem *item = new CREItem(); - CreateItemCore(item, core->GoldResRef, money, 0, 0); + if (!CreateItemCore(item, core->GoldResRef, money, 0, 0)) { + abort(); + } if ( ASI_SUCCESS == snd->inventory.AddSlotItem(item, SLOT_ONLYINVENTORY)) { scr->SetBase(IE_GOLD,scr->GetBase(IE_GOLD)-money); } else { @@ -4763,6 +4794,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) { @@ -4886,8 +4927,7 @@ 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); @@ -4898,8 +4938,7 @@ 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 +4950,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 +4996,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)); } } @@ -5865,7 +5903,7 @@ void GameScript::SaveGame(Scriptable* /*Sender*/, Action* parameters) void GameScript::EscapeArea(Scriptable* Sender, Action* parameters) { if (InDebug&ID_ACTIONS) { - printf("EscapeArea/EscapeAreaMove\n"); + print("EscapeArea/EscapeAreaMove\n"); } if (Sender->Type!=ST_ACTOR) { Sender->ReleaseCurrentAction(); @@ -5893,7 +5931,7 @@ void GameScript::EscapeArea(Scriptable* Sender, Action* parameters) void GameScript::EscapeAreaNoSee(Scriptable* Sender, Action* parameters) { if (InDebug&ID_ACTIONS) { - printf("EscapeAreaNoSee\n"); + print("EscapeAreaNoSee\n"); } if (Sender->Type!=ST_ACTOR) { Sender->ReleaseCurrentAction(); @@ -6224,12 +6262,13 @@ 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); + print("Script error: No Trigger Named \"%s\"\n", parameters->objects[1]->objectName); return; } - ip->LastEntered = 0; + // FIXME: what does this do? clear triggers? + /*ip->LastEntered = 0; ip->LastTrigger = 0; - ip->LastTriggerObject = 0; + ip->LastTriggerObject = 0;*/ } void GameScript::UseDoor(Scriptable* Sender, Action* parameters) @@ -6348,7 +6387,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 ); } } @@ -6794,7 +6834,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; @@ -7148,7 +7189,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); + print( "Cannot find %s.2da.\n", parameters->string0Parameter); return; } diff --git a/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.cpp b/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.cpp index 9fe3c6c31..26fa7fc43 100644 --- a/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.cpp +++ b/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.cpp @@ -25,15 +25,18 @@ #include "defsounds.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 "GUI/GameControl.h" @@ -239,24 +242,9 @@ 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); return false; @@ -267,12 +255,7 @@ 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; } @@ -368,7 +351,7 @@ void DisplayStringCore(Scriptable* Sender, int Strref, int flags) memset(&sb,0,sizeof(sb)); Sound[0]=0; - printf( "Displaying string on: %s\n", Sender->GetScriptName() ); + print( "Displaying string on: %s\n", Sender->GetScriptName() ); if (flags & DS_CONST) { if (Sender->Type!=ST_ACTOR) { printMessage("GameScript","Verbal constant not supported for non actors!\n", LIGHT_RED); @@ -599,8 +582,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); + printMessage("GameScript", "Failed to create creature! (missing creature file %s?)\n", LIGHT_RED, + parameters->string0Parameter); // maybe this should abort()? return; } @@ -725,7 +708,7 @@ void EscapeAreaCore(Scriptable* Sender, const Point &p, const char* area, const //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"); + if (!Sender->InMove()) print("At least it said so...\n"); return; } } @@ -737,13 +720,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); + printMessage("GSUtils", "Executing %s in EscapeAreaCore\n", WHITE, 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)\n", wait); Sender->SetWait(wait); } Sender->ReleaseCurrentAction(); @@ -825,7 +807,7 @@ void BeginDialog(Scriptable* Sender, Action* parameters, int Flags) int seeflag = GA_NO_DEAD; if (InDebug&ID_VARIABLES) { - printf("BeginDialog core\n"); + print("BeginDialog core\n"); } if (Flags & BD_OWN) { tar = GetStoredActorFromObject( Sender, parameters->objects[1], seeflag); @@ -835,23 +817,23 @@ 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); + printMessage("GameScript", "Speaker for dialog couldn't be found (Sender: %s, Type: %d) Flags:%d.\n", LIGHT_RED, + 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); + printMessage("GameScript", "Target for dialog couldn't be found (Sender: %s, Type: %d).\n", LIGHT_RED, + Sender->GetScriptName(), Sender->Type); if (Sender->Type == ST_ACTOR) { ((Actor *) Sender)->DebugDump(); } - printf ("Target object: "); + print ("Target object: "); if (parameters->objects[1]) { parameters->objects[1]->Dump(); } else { - printf("\n"); + print("\n"); } Sender->ReleaseCurrentAction(); return; @@ -862,8 +844,8 @@ 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); + printMessage("GameScript", "CanSee returned false! Speaker (%s, type %d) and target are:\n", LIGHT_RED, + scr->GetScriptName(), scr->Type); if (scr->Type == ST_ACTOR) { ((Actor *) scr)->DebugDump(); } @@ -876,7 +858,7 @@ void BeginDialog(Scriptable* Sender, Action* parameters, int Flags) 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"); + print("Speaker is dead, cannot start dialogue. Speaker and target are:\n"); speaker->DebugDump(); target->DebugDump(); Sender->ReleaseCurrentAction(); @@ -1032,7 +1014,7 @@ void BeginDialog(Scriptable* Sender, Action* parameters, int Flags) } } - int ret; + bool ret; if (Dialog[0]) { //increasing NumTimesTalkedTo or NumTimesInteracted @@ -1046,28 +1028,24 @@ 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); return; } - - //this is a bit fishy - Sender->SetWait(1); - Sender->ReleaseCurrentAction(); - } 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); + printMessage("GameScript", "MoveBetweenAreas: %s to %s [%d.%d] face: %d\n", WHITE, + actor->GetName(0), area,position.x,position.y, face); Map* map2; Game* game = core->GetGame(); if (area[0]) { //do we need to switch area? @@ -1139,11 +1117,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,6 +1139,7 @@ void CreateItemCore(CREItem *item, const char *resref, int a, int b, int c) item->Usages[2]=(ieWord) c; } item->Flags=0; + return true; } //It is possible to attack CONTAINERS/DOORS as well!!! @@ -1264,8 +1244,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); + printMessage("GameScript", "Missing IDS file %s for symbol %s!\n", LIGHT_RED, + idsname, symbol); } return -1; } @@ -1363,11 +1343,11 @@ Action* GenerateActionCore(const char *src, const char *str, unsigned short acti //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); + print("Warning, parser was sidetracked: %s\n",str); } switch (*str) { default: - printf("Invalid type: %s\n",str); + print("Invalid type: %s\n",str); //str++; delete newAction; return NULL; @@ -1460,7 +1440,7 @@ Action* GenerateActionCore(const char *src, const char *str, unsigned short acti case 'o': //Object if (objectCount==3) { - printf("Invalid object count!\n"); + print("Invalid object count!\n"); //abort(); delete newAction; return NULL; @@ -1514,7 +1494,7 @@ Action* GenerateActionCore(const char *src, const char *str, unsigned short acti if (mergestrings) { str++; if (*str!='s') { - printf("Invalid mergestrings:%s\n",str); + print("Invalid mergestrings:%s\n",str); //abort(); delete newAction; return NULL; @@ -1644,9 +1624,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 +1711,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); + print("Warning, parser was sidetracked: %s\n",str); } switch (*str) { default: - printf("Invalid type: %s\n",str); + print("Invalid type: %s\n",str); //str++; delete newTrigger; return NULL; @@ -1833,7 +1811,7 @@ Trigger *GenerateTriggerCore(const char *src, const char *str, int trIndex, int if (mergestrings) { str++; if (*str!='s') { - printf("Invalid mergestrings:%s\n",str); + print("Invalid mergestrings:%s\n",str); //abort(); delete newTrigger; return NULL; @@ -1880,7 +1858,7 @@ 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, + print( "Setting variable(\"%s%s\", %d)\n", Context, VarName, value ); } @@ -1906,8 +1884,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); + printMessage("GameScript", "Invalid variable %s %s in setvariable\n", YELLOW, + Context, VarName); } } else { @@ -1927,7 +1905,7 @@ void SetVariable(Scriptable* Sender, const char* VarName, ieDword value) } if (InDebug&ID_VARIABLES) { - printf( "Setting variable(\"%s\", %d)\n", VarName, value ); + print( "Setting variable(\"%s\", %d)\n", VarName, value ); } strncpy( newVarName, VarName, 6 ); newVarName[6]=0; @@ -1950,8 +1928,8 @@ void SetVariable(Scriptable* Sender, const char* VarName, ieDword value) map->locals->SetAt( poi, value, NoCreate); } else if (InDebug&ID_VARIABLES) { - printMessage("GameScript"," ",YELLOW); - printf("Invalid variable %s in setvariable\n",VarName); + printMessage("GameScript", "Invalid variable %s in setvariable\n", YELLOW, + VarName); } } else { @@ -1976,14 +1954,14 @@ ieDword CheckVariable(Scriptable* Sender, const char* VarName, bool *valid) if (strnicmp( newVarName, "MYAREA", 6 ) == 0) { Sender->GetCurrentArea()->locals->Lookup( poi, value ); if (InDebug&ID_VARIABLES) { - printf("CheckVariable %s: %d\n",VarName, value); + print("CheckVariable %s: %d\n",VarName, value); } return value; } if (strnicmp( newVarName, "LOCALS", 6 ) == 0) { Sender->locals->Lookup( poi, value ); if (InDebug&ID_VARIABLES) { - printf("CheckVariable %s: %d\n",VarName, value); + print("CheckVariable %s: %d\n",VarName, value); } return value; } @@ -1991,7 +1969,7 @@ ieDword CheckVariable(Scriptable* Sender, const char* VarName, bool *valid) if (HasKaputz && !strnicmp(newVarName,"KAPUTZ",6) ) { game->kaputz->Lookup( poi, value ); if (InDebug&ID_VARIABLES) { - printf("CheckVariable %s: %d\n",VarName, value); + print("CheckVariable %s: %d\n",VarName, value); } return value; } @@ -2004,15 +1982,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); + printMessage("GameScript", "Invalid variable %s in checkvariable\n", YELLOW, + VarName); } } } else { game->locals->Lookup( poi, value ); } if (InDebug&ID_VARIABLES) { - printf("CheckVariable %s: %d\n",VarName, value); + print("CheckVariable %s: %d\n",VarName, value); } return value; } @@ -2027,14 +2005,14 @@ ieDword CheckVariable(Scriptable* Sender, const char* VarName, const char* Conte if (strnicmp( newVarName, "MYAREA", 6 ) == 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\n",Context, VarName, value); } return value; } if (strnicmp( newVarName, "LOCALS", 6 ) == 0) { Sender->locals->Lookup( VarName, value ); if (InDebug&ID_VARIABLES) { - printf("CheckVariable %s%s: %d\n",Context, VarName, value); + print("CheckVariable %s%s: %d\n",Context, VarName, value); } return value; } @@ -2042,7 +2020,7 @@ ieDword CheckVariable(Scriptable* Sender, const char* VarName, const char* Conte if (HasKaputz && !strnicmp(newVarName,"KAPUTZ",6) ) { game->kaputz->Lookup( VarName, value ); if (InDebug&ID_VARIABLES) { - printf("CheckVariable %s%s: %d\n",Context, VarName, value); + print("CheckVariable %s%s: %d\n",Context, VarName, value); } return value; } @@ -2055,15 +2033,15 @@ 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); + printMessage("GameScript", "Invalid variable %s %s in checkvariable\n", YELLOW, + 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\n",Context, VarName, value); } return value; } @@ -2172,8 +2150,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); + printMessage("GameScript", "Spell couldn't be found:%.8s.\n", LIGHT_RED, spellres); return 0; } dist = spl->GetCastingDistance(Sender); @@ -2195,8 +2172,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); + printMessage("GameScript", "Item couldn't be found:%.8s.\n", LIGHT_RED, itemres); return 0; } dist=itm->GetCastingDistance(header); @@ -2224,7 +2200,7 @@ void SetupWishCore(Scriptable *Sender, int column, int picks) AutoTable tm("wish"); if (!tm) { printStatus( "ERROR", LIGHT_RED ); - printf( "Cannot find wish.2da.\n"); + print( "Cannot find wish.2da.\n"); return; } diff --git a/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.h b/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.h index fe3a9bfd0..1bcffd738 100644 --- a/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.h +++ b/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.h @@ -80,7 +80,7 @@ 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); 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); diff --git a/project/jni/application/gemrb/gemrb/core/GameScript/GameScript.cpp b/project/jni/application/gemrb/gemrb/core/GameScript/GameScript.cpp index 9c15f1b68..55ea267fc 100644 --- a/project/jni/application/gemrb/gemrb/core/GameScript/GameScript.cpp +++ b/project/jni/application/gemrb/gemrb/core/GameScript/GameScript.cpp @@ -29,6 +29,7 @@ #include "GameData.h" #include "Interface.h" #include "PluginMgr.h" +#include "TableMgr.h" //debug flags // 1 - cache @@ -225,6 +226,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}, @@ -506,7 +508,7 @@ 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}, @@ -1133,8 +1135,8 @@ static const IDSLink* FindIdentifier(const char* idsname) } } - printMessage( "GameScript"," ", YELLOW ); - printf( "Couldn't assign ids target: %.*s\n", len, idsname ); + printMessage("GameScript", "Couldn't assign ids target: %.*s\n", YELLOW, + len, idsname ); return NULL; } @@ -1271,9 +1273,9 @@ void printFunction(Holder table, int index) int len = strchr(str,'(')-str; if (len<0) { - printf("%d %s\n", value, str); + print("%d %s\n", value, str); } else { - printf("%d %.*s\n", value, len, str); + print("%d %.*s\n", value, len, str); } } @@ -1296,16 +1298,14 @@ void InitializeIEScript() int gaT = core->LoadSymbol( "gemact" ); 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 ); 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 +1314,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 +1332,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 ) ); @@ -1355,31 +1353,32 @@ void InitializeIEScript() while (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 ) ); + printMessage("GameScript", "trigger %d (%s) is too high, ignoring\n", RED, + 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 ) ); + printMessage("GameScript", "%s is in collision with ", YELLOW, + triggersTable->GetStringIndex( j ) ); printFunction(triggersTable,triggersTable->FindValue(triggersTable->GetValueIndex( j ))); - //printFunction(triggersTable->GetStringIndex(triggersTable->FindValue(triggersTable->GetValueIndex( j )) )); } else { if (InDebug&ID_TRIGGERS) { - printMessage("GameScript"," ", WHITE); - printf("%s is a synonym of ", triggersTable->GetStringIndex( j ) ); + printMessage("GameScript", "%s is a synonym of ", WHITE, + triggersTable->GetStringIndex( j ) ); printFunction(triggersTable,triggersTable->FindValue(triggersTable->GetValueIndex( j ))); - //printFunction(triggersTable->GetStringIndex(triggersTable->FindValue(triggersTable->GetValueIndex( j ) ) ) ); } } 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 +1386,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,38 +1403,38 @@ 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 ); + printMessage("GameScript", "%s is a synonym of %s\n", WHITE, + triggersTable->GetStringIndex( j ), triggernames[i].Name ); break; } } } continue; } + printMessage("GameScript","Couldn't assign function to trigger: ", YELLOW); printFunction(triggersTable,j); -//->GetStringIndex(j) ); } j = actionsTable->GetSize(); while (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 ) ); + printMessage("GameScript", "action %d (%s) is too high, ignoring\n", RED, + 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 ) ); + printMessage("GameScript", "%s is in collision with ", YELLOW, + actionsTable->GetStringIndex( j ) ); printFunction(actionsTable, actionsTable->FindValue(actionsTable->GetValueIndex(j))); //->GetStringIndex(actionsTable->FindValue(actionsTable->GetValueIndex( j )) ) ); } else { if (InDebug&ID_ACTIONS) { - printMessage("GameScript"," ", WHITE); - printf("%s is a synonym of ", actionsTable->GetStringIndex( j ) ); + printMessage("GameScript", "%s is a synonym of ", WHITE, + actionsTable->GetStringIndex( j ) ); printFunction(actionsTable, actionsTable->FindValue(actionsTable->GetValueIndex( j ))); //actionsTable->GetStringIndex(actionsTable->FindValue(actionsTable->GetValueIndex( j )) ) ); } @@ -1459,8 +1460,8 @@ void InitializeIEScript() while (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 ) ); + printMessage("GameScript", "action %d (%s) is too high, ignoring\n", RED, + i, overrideActionsTable->GetStringIndex( j ) ); continue; } const ActionLink *poi = FindAction( overrideActionsTable->GetStringIndex( j )); @@ -1468,8 +1469,8 @@ void InitializeIEScript() continue; } if (actions[i]) { - printMessage("GameScript"," ", WHITE); - printf("%s overrides existing action ", overrideActionsTable->GetStringIndex( j ) ); + printMessage("GameScript", "%s overrides existing action ", WHITE, + overrideActionsTable->GetStringIndex( j ) ); printFunction( actionsTable, actionsTable->FindValue(overrideActionsTable->GetValueIndex( j ))); //printFunction( actionsTable->GetStringIndex(actionsTable->FindValue(overrideActionsTable->GetValueIndex( j )) ) ); } @@ -1491,8 +1492,8 @@ 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 ); + printMessage("GameScript", "%s is a synonym of %s\n", WHITE, + actionsTable->GetStringIndex( j ), actionnames[i].Name ); break; } } @@ -1508,20 +1509,20 @@ void InitializeIEScript() 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 ) ); + printMessage("GameScript", "object %d (%s) is too high, ignoring\n", RED, + 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 ) ); + printMessage("GameScript", "%s is in collision with ", YELLOW, + objectsTable->GetStringIndex( j ) ); printFunction(objectsTable,objectsTable->FindValue(objectsTable->GetValueIndex( j ))); //printFunction(objectsTable->GetStringIndex(objectsTable->FindValue(objectsTable->GetValueIndex( j )) ) ); } else { - printMessage("GameScript"," ", WHITE); - printf("%s is a synonym of ", objectsTable->GetStringIndex( j ) ); + printMessage("GameScript", "%s is a synonym of ", WHITE, + objectsTable->GetStringIndex( j ) ); printFunction(objectsTable, objectsTable->FindValue(objectsTable->GetValueIndex( j ))); //printFunction(objectsTable->GetStringIndex(objectsTable->FindValue(objectsTable->GetValueIndex( j )) ) ); } @@ -1547,8 +1548,8 @@ 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 ); + printMessage("GameScript", "%s is a synonym of %s\n", WHITE, + objectsTable->GetStringIndex( j ), objectnames[i].Name ); break; } } @@ -1561,29 +1562,54 @@ void InitializeIEScript() int instantTableIndex = core->LoadSymbol("instant"); if (instantTableIndex < 0) { - printMessage("GameScript", "Couldn't find instant symbols!\n", LIGHT_RED); - abort(); + error("GameScript", "Couldn't find instant symbols!\n"); } Holder instantTable = core->GetSymbol(instantTableIndex); if (!instantTable) { - printMessage("GameScript", "Couldn't load instant symbols!\n", LIGHT_RED); - abort(); + error("GameScript", "Couldn't load instant symbols!\n"); } 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 ) ); + printMessage("GameScript", "instant action %d (%s) is too high, ignoring\n", RED, + i, instantTable->GetStringIndex( j ) ); continue; } if (!actions[i]) { - printMessage("GameScript"," ", YELLOW); - printf("instant action %d (%s) doesn't exist, ignoring\n", i, instantTable->GetStringIndex( j ) ); + printMessage("GameScript", "instant action %d (%s) doesn't exist, ignoring\n", YELLOW, + i, instantTable->GetStringIndex( j ) ); continue; } actionflags[i] |= AF_INSTANT; } + + int savedTriggersIndex = core->LoadSymbol("svtriobj"); + if (savedTriggersIndex < 0) { + // leaving this as not strictly necessary, for now + printMessage("GameScript", "Couldn't find saved trigger symbols!\n", YELLOW); + } else { + Holder savedTriggersTable = core->GetSymbol(savedTriggersIndex); + if (!savedTriggersTable) { + error("GameScript", "Couldn't laod saved trigger symbols!\n"); + } + j = savedTriggersTable->GetSize(); + while (j--) { + i = savedTriggersTable->GetValueIndex( j ); + i &= 0x3fff; + if (i >= MAX_ACTIONS) { + printMessage("GameScript", "saved trigger %d (%s) is too high, ignoring\n", RED, + i, savedTriggersTable->GetStringIndex( j ) ); + continue; + } + if (!triggers[i]) { + printMessage("GameScript", "saved trigger %d (%s) doesn't exist, ignoring\n", YELLOW, + i, savedTriggersTable->GetStringIndex( j ) ); + continue; + } + triggerflags[i] |= TF_SAVED; + } + } } /********************** GameScript *******************************/ @@ -1605,17 +1631,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) ); + print("One instance of %s is dropped from %d.\n", 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.\n", Name); script->Release(); } script = NULL; @@ -1631,7 +1655,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) ); + print("Caching %s for the %d. time\n", ResRef, BcsCache.RefCount(ResRef) ); } return newScript; } @@ -1649,7 +1673,7 @@ Script* GameScript::CacheScript(ieResRef ResRef, bool AIScript) newScript = new Script( ); BcsCache.SetAt( ResRef, (void *) newScript ); if (InDebug&ID_REFERENCE) { - printf("Caching %s for the %d. time\n", ResRef, BcsCache.RefCount(ResRef) ); + print("Caching %s for the %d. time\n", ResRef, BcsCache.RefCount(ResRef) ); } while (true) { @@ -1725,8 +1749,7 @@ 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); + printMessage("GameScript", "Got confused parsing object line: %s\n", YELLOW, origline); } //let the object realize it has no future (in case of null objects) if (oB->isNull()) { @@ -1807,7 +1830,7 @@ bool GameScript::Update(bool *continuing, bool *done) //lastRunTime = thisTime; if(!(MySelf->GetInternalFlag()&IF_ACTIVE) ) { - return true; + return false; } bool continueExecution = false; @@ -1825,7 +1848,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) { @@ -1834,7 +1857,7 @@ bool GameScript::Update(bool *continuing, bool *done) // interactions with Continue() (lastAction here is always // the first block encountered), needs more testing //if (done) *done = true; - return true; + return false; } //movetoobjectfollow would break if this isn't called @@ -1852,11 +1875,11 @@ bool GameScript::Update(bool *continuing, bool *done) if (continuing) *continuing = continueExecution; if (!continueExecution) { if (done) *done = true; - break; + return true; } } } - return true; + return continueExecution; } //IE simply takes the first action's object for cutscene object @@ -1901,7 +1924,7 @@ 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) { + } else if ((InDebug&ID_CUTSCENE) || !action->objects[1]) { printMessage("GameScript","Failed to find CutSceneID target!\n",YELLOW); if (action->objects[1]) { action->objects[1]->Dump(); @@ -1957,14 +1980,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 ); @@ -2078,13 +2101,13 @@ int Trigger::Evaluate(Scriptable* Sender) if (!func) { triggers[triggerID] = GameScript::False; printMessage("GameScript"," ",YELLOW); - printf("Unhandled trigger code: 0x%04x %s\n", + print("Unhandled trigger code: 0x%04x %s\n", triggerID, tmpstr ); return 0; } if (InDebug&ID_TRIGGERS) { printMessage("GameScript"," ",YELLOW); - printf( "Executing trigger code: 0x%04x %s\n", + print( "Executing trigger code: 0x%04x %s\n", triggerID, tmpstr ); } int ret = func( Sender, this ); @@ -2156,7 +2179,7 @@ int Response::Execute(Scriptable* Sender) void PrintAction(int actionID) { - printf("Action: %d %s\n", actionID , actionsTable->GetValue(actionID) ); + print("Action: %d %s\n", actionID , actionsTable->GetValue(actionID) ); } void GameScript::ExecuteAction(Scriptable* Sender, Action* aC) @@ -2171,8 +2194,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() ); + printMessage("GameScript", "Sender: %s-->override: %s\n", YELLOW, + Sender->GetScriptName(), scr->GetScriptName() ); } scr->ReleaseCurrentAction(); scr->AddAction(ParamCopyNoOverride(aC)); @@ -2196,7 +2219,7 @@ void GameScript::ExecuteAction(Scriptable* Sender, Action* aC) if (InDebug&ID_ACTIONS) { printMessage("GameScript"," ",YELLOW); PrintAction(actionID); - printf("Sender: %s\n",Sender->GetScriptName() ); + print("Sender: %s\n",Sender->GetScriptName() ); } ActionFunction func = actions[actionID]; if (func) { @@ -2227,7 +2250,7 @@ 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"); + print("Immediate action got queued!\n"); PrintAction(actionID); abort(); } @@ -2246,8 +2269,7 @@ Trigger* GenerateTrigger(char* String) { strlwr( String ); if (InDebug&ID_TRIGGERS) { - printMessage("GameScript"," ",YELLOW); - printf("Compiling:%s\n",String); + printMessage("GameScript", "Compiling:%s\n", YELLOW, String); } int negate = 0; if (*String == '!') { @@ -2257,16 +2279,14 @@ Trigger* GenerateTrigger(char* String) 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); + printMessage("GameScript", "Invalid scripting trigger: %s\n", LIGHT_RED, 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); + printMessage("GameScript", "Malformed scripting trigger: %s\n", LIGHT_RED, String); return NULL; } return trigger; @@ -2276,8 +2296,7 @@ Action* GenerateAction(char* String) { strlwr( String ); if (InDebug&ID_ACTIONS) { - printMessage("GameScript"," ",YELLOW); - printf("Compiling:%s\n",String); + printMessage("GameScript", "Compiling:%s\n", YELLOW, String); } int len = strlench(String,'(')+1; //including ( char *src = String+len; @@ -2294,8 +2313,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); + printMessage("GameScript", "Invalid scripting action: %s\n", LIGHT_RED, String); return NULL; } str = actionsTable->GetStringIndex( i )+len; @@ -2303,8 +2321,7 @@ Action* GenerateAction(char* String) } Action *action = GenerateActionCore( src, str, actionID); if (!action) { - printMessage("GameScript"," ",LIGHT_RED); - printf("Malformed scripting action: %s\n", String); + printMessage("GameScript", "Malformed scripting action: %s\n", LIGHT_RED, String); return NULL; } return action; diff --git a/project/jni/application/gemrb/gemrb/core/GameScript/GameScript.h b/project/jni/application/gemrb/gemrb/core/GameScript/GameScript.h index 874aa00e5..a98282b4b 100644 --- a/project/jni/application/gemrb/gemrb/core/GameScript/GameScript.h +++ b/project/jni/application/gemrb/gemrb/core/GameScript/GameScript.h @@ -106,7 +106,7 @@ class GameScript; #define GSASSERT(f,c) \ if(!(f)) \ { \ - printf("Assertion failed: %s [0x%08lX] Line %d",#f, c, __LINE__); \ + print("Assertion failed: %s [0x%08lX] Line %d",#f, c, __LINE__); \ abort(); \ } @@ -146,7 +146,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 ) ); @@ -171,19 +171,19 @@ public: GSASSERT( canary == (unsigned long) 0xdeadbeef, canary ); if(objectName[0]) { - printf("Object: %s\n",objectName); + print("Object: %s\n",objectName); return; } - printf("IDS Targeting: "); + print("IDS Targeting: "); for(i=0;iDump(); } else { - printf("No object\n"); + print("No object\n"); } - printf("\n"); + print("\n"); } void Release() @@ -290,8 +292,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; @@ -334,25 +336,25 @@ public: 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:"", string1Parameter?string1Parameter:""); + print("Int0: %d, Int1: %d, Int2: %d\n",int0Parameter, int1Parameter, int2Parameter); + print("String0: %s, String1: %s\n", string0Parameter?string0Parameter:"", string1Parameter?string1Parameter:""); for (i=0;i<3;i++) { if (objects[i]) { - printf( "%d. ",i+1); + print( "%d. ",i+1); objects[i]->Dump(); } else { - printf( "%d. Object - NULL\n",i+1); + print( "%d. Object - NULL\n",i+1); } } - printf("RefCount: %d\n", RefCount); + print("RefCount: %d\n", RefCount); } void Release() { GSASSERT( canary == (unsigned long) 0xdeadbeef, canary ); if (!RefCount) { - printf( "WARNING!!! Double Freeing in %s: Line %d\n", __FILE__, + print( "WARNING!!! Double Freeing in %s: Line %d\n", __FILE__, __LINE__ ); abort(); } @@ -367,7 +369,7 @@ public: GSASSERT( canary == (unsigned long) 0xdeadbeef, canary ); RefCount++; if (RefCount >= 65536) { - printf( "Refcount increased to: %d in action %d\n", RefCount, + print( "Refcount increased to: %d in action %d\n", RefCount, actionID ); abort(); } @@ -386,7 +388,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\n", actions[c]->actionID, actions[c]->GetRef()); } actions[c]->Release(); actions[c] = NULL; @@ -503,6 +505,7 @@ typedef int (* IDSFunction)(Actor *, int parameter); #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 { @@ -786,6 +789,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); @@ -1037,6 +1041,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); diff --git a/project/jni/application/gemrb/gemrb/core/GameScript/Matching.cpp b/project/jni/application/gemrb/gemrb/core/GameScript/Matching.cpp index be43aff7d..78ddc6a91 100644 --- a/project/jni/application/gemrb/gemrb/core/GameScript/Matching.cpp +++ b/project/jni/application/gemrb/gemrb/core/GameScript/Matching.cpp @@ -24,13 +24,14 @@ #include "Interface.h" #include "Game.h" +#include "Map.h" #include "TileMap.h" #include "Scriptable/Container.h" #include "Scriptable/Door.h" #include "Scriptable/InfoPoint.h" /* 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 +40,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 +48,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); + printMessage("GameScript", "Unimplemented IDS targeting opcode: %d\n", YELLOW, j); continue; } if (!func( ac, oC->objectFields[j] ) ) { @@ -59,15 +59,15 @@ 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) { for (int i = 0; i < MaxObjectNesting; i++) { int filterid = oC->objectFilters[i]; if (!filterid) break; ObjectFunction func = objects[filterid]; if (!func) { - printMessage("GameScript"," ", YELLOW); - printf("Unknown object filter: %d %s\n", filterid, objectsTable->GetValue(filterid)); + printMessage("GameScript", "Unknown object filter: %d %s\n", YELLOW, + filterid, objectsTable->GetValue(filterid)); continue; } @@ -82,7 +82,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); diff --git a/project/jni/application/gemrb/gemrb/core/GameScript/Matching.h b/project/jni/application/gemrb/gemrb/core/GameScript/Matching.h index a01fa2253..f069d6bb9 100644 --- a/project/jni/application/gemrb/gemrb/core/GameScript/Matching.h +++ b/project/jni/application/gemrb/gemrb/core/GameScript/Matching.h @@ -24,6 +24,8 @@ #include "exports.h" +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); diff --git a/project/jni/application/gemrb/gemrb/core/GameScript/Objects.cpp b/project/jni/application/gemrb/gemrb/core/GameScript/Objects.cpp index 2cc9b3b31..05beeba7f 100644 --- a/project/jni/application/gemrb/gemrb/core/GameScript/Objects.cpp +++ b/project/jni/application/gemrb/gemrb/core/GameScript/Objects.cpp @@ -137,8 +137,8 @@ Targets *GameScript::Gabber(Scriptable* /*Sender*/, Targets *parameters, int ga_ Targets *GameScript::LastTrigger(Scriptable *Sender, Targets *parameters, int ga_flags) { parameters->Clear(); - if (Sender->LastTriggerObject) { - Actor *target = Sender->GetCurrentArea()->GetActorByGlobalID(Sender->LastTriggerObject); + if (Sender->LastTrigger) { + Actor *target = Sender->GetCurrentArea()->GetActorByGlobalID(Sender->LastTrigger); parameters->AddTarget(target, 0, ga_flags); } return parameters; @@ -252,7 +252,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 +262,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 +282,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 +331,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 +385,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); } diff --git a/project/jni/application/gemrb/gemrb/core/GameScript/Triggers.cpp b/project/jni/application/gemrb/gemrb/core/GameScript/Triggers.cpp index da8f35ee6..4f8f79e1e 100644 --- a/project/jni/application/gemrb/gemrb/core/GameScript/Triggers.cpp +++ b/project/jni/application/gemrb/gemrb/core/GameScript/Triggers.cpp @@ -29,6 +29,7 @@ #include "DialogHandler.h" #include "Game.h" #include "GameData.h" +#include "Polygon.h" #include "Video.h" #include "GUI/GameControl.h" #include "math.h" //needs for acos @@ -811,20 +812,12 @@ int GameScript::GlobalTimerStarted(Scriptable* Sender, Trigger* parameters) 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 0; + return Sender->MatchTrigger(trigger_oncreation); } int GameScript::NumItemsParty(Scriptable* /*Sender*/, Trigger* parameters) @@ -1549,16 +1542,12 @@ 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); + /*Actor *target = Sender->GetCurrentArea()->GetActorByGlobalID(Sender->LastTrigger); if (!target) { return 0; } @@ -1575,293 +1564,72 @@ int GameScript::WalkedToTrigger(Scriptable* Sender, Trigger* parameters) Sender->AddTrigger (&Sender->LastTrigger); return 1; } - return 0; + 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) 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; - } - - 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_opened, parameters->objectParameter); } //closed for doors (using lastTrigger) int GameScript::Closed(Scriptable* Sender, Trigger* parameters) { - if (Sender->Type != ST_DOOR) { - return 0; - } - Door *door = (Door *) Sender; - if (door->IsOpen()) { - return 0; - } - - 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_closed, 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) @@ -1944,68 +1712,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) @@ -2450,6 +2182,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 +2430,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:""); - printf("Sender: %s\n", Sender->GetScriptName() ); + printMessage("GameScript", "Couldn't find door/container:%s\n", LIGHT_RED, + parameters->objectParameter? parameters->objectParameter->objectName:""); + print("Sender: %s\n", Sender->GetScriptName() ); } return 0; } @@ -2716,8 +2449,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()); + printMessage("GameScript", "Not a door/container:%s\n", LIGHT_RED, + tar->GetScriptName()); return 0; } @@ -2725,9 +2458,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:""); - printf("Sender: %s\n", Sender->GetScriptName() ); + printMessage("GameScript", "Couldn't find door/container:%s\n", LIGHT_RED, + parameters->objectParameter? parameters->objectParameter->objectName:""); + print("Sender: %s\n", Sender->GetScriptName() ); return 0; } switch(tar->Type) { @@ -2743,8 +2476,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()); + printMessage("GameScript", "Not a door/container:%s\n", LIGHT_RED, + tar->GetScriptName()); return 0; } @@ -3397,18 +3130,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 +3150,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 +3182,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,7 +3234,8 @@ int GameScript::IsFacingObject(Scriptable* Sender, Trigger* parameters) int GameScript::AttackedBy(Scriptable* Sender, Trigger* parameters) { - if (Sender->Type!=ST_ACTOR) { + return Sender->MatchTriggerWithObject(trigger_attackedby, parameters->objectParameter, parameters->int0Parameter); + /*if (Sender->Type!=ST_ACTOR) { return 0; } Actor *scr = (Actor *) Sender; @@ -3550,12 +3260,13 @@ int GameScript::AttackedBy(Scriptable* Sender, Trigger* parameters) } } delete tgts; - return ret; + return ret;*/ } int GameScript::TookDamage(Scriptable* Sender, Trigger* /*parameters*/) { - if (Sender->Type!=ST_ACTOR) { + return Sender->MatchTrigger(trigger_tookdamage); + /*if (Sender->Type!=ST_ACTOR) { return 0; } Actor* actor = ( Actor* ) Sender; @@ -3564,43 +3275,17 @@ int GameScript::TookDamage(Scriptable* Sender, Trigger* /*parameters*/) Sender->AddTrigger(&actor->LastHitter); return 1; } - return 0; + return 0;*/ } 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_attackedby, 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::LastMarkedObject_Trigger(Scriptable* Sender, Trigger* parameters) @@ -3645,7 +3330,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,30 +3339,18 @@ 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 Sender->MatchTriggerWithObject(trigger_joins, parameters->objectParameter); + /*if(Sender->Type!=ST_ACTOR) { return 0; } Actor * actor = ( Actor* ) Sender; @@ -3688,12 +3362,13 @@ int GameScript::Joins(Scriptable* Sender, Trigger* parameters) Sender->AddTrigger(&actor->PCStats->LastJoined); return 1; } - return 0; + return 0;*/ } int GameScript::Leaves(Scriptable* Sender, Trigger* parameters) { - if(Sender->Type!=ST_ACTOR) { + return Sender->MatchTriggerWithObject(trigger_leaves, parameters->objectParameter); + /*if(Sender->Type!=ST_ACTOR) { return 0; } Actor * actor = ( Actor* ) Sender; @@ -3705,7 +3380,7 @@ int GameScript::Leaves(Scriptable* Sender, Trigger* parameters) Sender->AddTrigger(&actor->PCStats->LastLeft); return 1; } - return 0; + return 0;*/ } int GameScript::FallenPaladin(Scriptable* Sender, Trigger* /*parameters*/) @@ -4115,13 +3790,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 +3834,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) @@ -4344,7 +4010,8 @@ int GameScript::SystemVariable_Trigger(Scriptable* Sender, Trigger* parameters) int GameScript::SpellCast(Scriptable* Sender, Trigger* parameters) { - if(parameters->int0Parameter) { + return Sender->MatchTriggerWithObject(trigger_spellcast, parameters->objectParameter, parameters->int0Parameter); + /*if(parameters->int0Parameter) { unsigned int param = 2000+parameters->int0Parameter%1000; if (param!=Sender->LastSpellSeen) { return 0; @@ -4354,12 +4021,13 @@ int GameScript::SpellCast(Scriptable* Sender, Trigger* parameters) Sender->AddTrigger(&Sender->LastCasterSeen); return 1; } - return 0; + return 0;*/ } int GameScript::SpellCastPriest(Scriptable* Sender, Trigger* parameters) { - if(parameters->int0Parameter) { + return Sender->MatchTriggerWithObject(trigger_spellcastpriest, parameters->objectParameter, parameters->int0Parameter); + /*if(parameters->int0Parameter) { unsigned int param = 1000+parameters->int0Parameter%1000; if (param!=Sender->LastSpellSeen) { return 0; @@ -4369,12 +4037,13 @@ int GameScript::SpellCastPriest(Scriptable* Sender, Trigger* parameters) Sender->AddTrigger(&Sender->LastCasterSeen); return 1; } - return 0; + return 0;*/ } int GameScript::SpellCastInnate(Scriptable* Sender, Trigger* parameters) { - if(parameters->int0Parameter) { + return Sender->MatchTriggerWithObject(trigger_spellcastinnate, parameters->objectParameter, parameters->int0Parameter); + /*if(parameters->int0Parameter) { unsigned int param = 3000+parameters->int0Parameter%1000; if (param!=Sender->LastSpellSeen) { return 0; @@ -4384,12 +4053,13 @@ int GameScript::SpellCastInnate(Scriptable* Sender, Trigger* parameters) Sender->AddTrigger(&Sender->LastCasterSeen); return 1; } - return 0; + return 0;*/ } int GameScript::SpellCastOnMe(Scriptable* Sender, Trigger* parameters) { - if(parameters->int0Parameter) { + return Sender->MatchTriggerWithObject(trigger_spellcastonme, parameters->objectParameter, parameters->int0Parameter); + /*if(parameters->int0Parameter) { if ((ieDword) parameters->int0Parameter!=Sender->LastSpellOnMe) { return 0; } @@ -4398,7 +4068,7 @@ int GameScript::SpellCastOnMe(Scriptable* Sender, Trigger* parameters) Sender->AddTrigger(&Sender->LastCasterOnMe); return 1; } - return 0; + return 0;*/ } int GameScript::CalendarDay(Scriptable* /*Sender*/, Trigger* parameters) @@ -4429,15 +4099,7 @@ 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 0; - } - Actor* actor = ( Actor* ) Sender; - if (MatchActor(Sender, actor->LastTurner, NULL)) { - Sender->AddTrigger(&actor->LastTurner); - return 1; - } - return 0; + return Sender->MatchTriggerWithObject(trigger_turnedby, parameters->objectParameter); } diff --git a/project/jni/application/gemrb/gemrb/core/GlobalTimer.cpp b/project/jni/application/gemrb/gemrb/core/GlobalTimer.cpp index 64d2c74b7..1319d68b3 100644 --- a/project/jni/application/gemrb/gemrb/core/GlobalTimer.cpp +++ b/project/jni/application/gemrb/gemrb/core/GlobalTimer.cpp @@ -59,7 +59,7 @@ void GlobalTimer::Freeze() unsigned long thisTime; unsigned long advance; - GetTime( thisTime ); + thisTime = GetTickCount(); advance = thisTime - startTime; if ( advance < interval) { return; @@ -155,7 +155,7 @@ bool GlobalTimer::Update() UpdateAnimations(); - GetTime( thisTime ); + thisTime = GetTickCount(); if (!startTime) { startTime = thisTime; @@ -265,7 +265,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, @@ -309,7 +309,7 @@ void GlobalTimer::RemoveAnimation(ControlAnimation* ctlanim) void GlobalTimer::UpdateAnimations() { unsigned long thisTime; - GetTime( thisTime ); + thisTime = GetTickCount(); while (animations.begin() + first_animation != animations.end()) { AnimationRef* anim = animations[first_animation]; if (anim->ctlanim == NULL) { diff --git a/project/jni/application/gemrb/gemrb/core/ImageMgr.cpp b/project/jni/application/gemrb/gemrb/core/ImageMgr.cpp index c38c4866f..3275d3e13 100644 --- a/project/jni/application/gemrb/gemrb/core/ImageMgr.cpp +++ b/project/jni/application/gemrb/gemrb/core/ImageMgr.cpp @@ -42,8 +42,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 ); + printMessage("ImageMgr", "Don't know how to handle 24bit bitmap from %s...", WHITE, + str->filename ); printStatus( "ERROR", LIGHT_RED ); Sprite2D *spr = GetSprite2D(); @@ -80,8 +80,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); + printMessage("ImageMgr", "Can't get non-existant palette from %s... ", WHITE, + str->filename); printStatus("ERROR", LIGHT_RED); } diff --git a/project/jni/application/gemrb/gemrb/core/IndexedArchive.cpp b/project/jni/application/gemrb/gemrb/core/IndexedArchive.cpp new file mode 100644 index 000000000..e39eb6891 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/core/IndexedArchive.cpp @@ -0,0 +1,29 @@ +/* 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" + +IndexedArchive::IndexedArchive(void) +{ +} + +IndexedArchive::~IndexedArchive(void) +{ +} diff --git a/project/jni/application/gemrb/gemrb/core/IndexedArchive.h b/project/jni/application/gemrb/gemrb/core/IndexedArchive.h new file mode 100644 index 000000000..3938ceee9 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/core/IndexedArchive.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 INDEXEDARCHIVE_H +#define INDEXEDARCHIVE_H + +#include "globals.h" + +#include "Plugin.h" + +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/project/jni/application/gemrb/gemrb/core/IniSpawn.cpp b/project/jni/application/gemrb/gemrb/core/IniSpawn.cpp index b7c1ee4d6..374ecc956 100644 --- a/project/jni/application/gemrb/gemrb/core/IniSpawn.cpp +++ b/project/jni/application/gemrb/gemrb/core/IniSpawn.cpp @@ -25,10 +25,12 @@ #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" @@ -58,7 +60,7 @@ IniSpawn::~IniSpawn() } } -Holder GetIniFile(const ieResRef DefaultArea) +static Holder 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)) { @@ -76,13 +78,13 @@ Holder GetIniFile(const ieResRef DefaultArea) } PluginHolder 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 +94,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 +112,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; @@ -205,8 +207,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); + printMessage("IniSpawn", "Invalid spawn entry: %s\n", LIGHT_RED, crittername); } s = inifile->GetKeyAsString(crittername,"point_select",NULL); diff --git a/project/jni/application/gemrb/gemrb/core/Interface.cpp b/project/jni/application/gemrb/gemrb/core/Interface.cpp index 2f85d9cc2..36643353f 100644 --- a/project/jni/application/gemrb/gemrb/core/Interface.cpp +++ b/project/jni/application/gemrb/gemrb/core/Interface.cpp @@ -44,13 +44,15 @@ #include "Factory.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,13 +66,16 @@ #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" @@ -114,7 +119,7 @@ Interface::Interface(int iargc, char* iargv[]) hConsole = GetStdHandle( STD_OUTPUT_HANDLE ); #endif textcolor( LIGHT_WHITE ); - printf( "GemRB Core Version v%s Loading...\n", VERSION_GEMRB ); + print( "GemRB Core Version v%s Loading...\n", 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; @@ -184,6 +190,7 @@ Interface::Interface(int iargc, char* iargv[]) SkipIntroVideos = false; DrawFPS = false; KeepCache = false; + TouchScrollAreas = false; TooltipDelay = 100; IgnoreOriginalINI = 0; FullScreen = 0; @@ -269,7 +276,7 @@ static void ReleaseItemList(void *poi) delete ((ItemList *) poi); } -void FreeAbilityTables() +static void FreeAbilityTables() { if (strmod) { free(strmod); @@ -335,6 +342,7 @@ Interface::~Interface(void) delete game; delete calendar; delete worldmap; + delete keymap; FreeAbilityTables(); @@ -358,7 +366,6 @@ Interface::~Interface(void) ReleaseMemoryActor(); EffectQueue_ReleaseMemory(); CharAnimations::ReleaseMemory(); - delete CurrentStore; FreeResRefTable(DefSound, DSCount); @@ -659,7 +666,7 @@ void Interface::HandleFlags() } } -bool GenerateAbilityTables() +static bool GenerateAbilityTables() { FreeAbilityTables(); @@ -1106,7 +1113,7 @@ 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 { @@ -1122,10 +1129,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; @@ -1154,7 +1161,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 ); + print( "Cannot find %s.2da.\n",tablename ); return 0; } count = tm->GetRowCount(); @@ -1174,7 +1181,7 @@ int Interface::LoadSprites() ieDword i; int size; if (!IsAvailable( IE_2DA_CLASS_ID )) { - printf( "No 2DA Importer Available.\nTermination in Progress...\n" ); + print( "No 2DA Importer Available.\nTermination in Progress...\n" ); return GEM_ERROR; } @@ -1305,13 +1312,13 @@ int Interface::LoadSprites() AutoTable tab("fonts"); if (!tab) { printStatus( "ERROR", LIGHT_RED ); - printf( "Cannot find fonts.2da.\nTermination in Progress...\n" ); + print( "Cannot find fonts.2da.\nTermination in Progress...\n" ); return GEM_ERROR; } else { PluginHolder bamint(IE_BAM_CLASS_ID); if (!bamint) { printStatus( "ERROR", LIGHT_RED ); - printf( "No BAM Importer Available.\nTermination in Progress...\n" ); + print( "No BAM Importer Available.\nTermination in Progress...\n" ); return GEM_ERROR; } DataStream* str = NULL; @@ -1322,7 +1329,7 @@ int Interface::LoadSprites() 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 )) { + if (!bamint->Open(str)) { continue; } Font* fnt = bamint->GetFont(); @@ -1357,18 +1364,18 @@ int Interface::LoadSprites() return GEM_ERROR; } if (GetFont( ButtonFont ) == NULL) { - printMessage( "Core", "ButtonFont not loaded: ", WHITE ); - printf("%s ", ButtonFont); + printMessage("Core", "ButtonFont not loaded: %s ", WHITE, + ButtonFont); printStatus( "WARNING", YELLOW ); } if (GetFont( MovieFont ) == NULL) { - printMessage( "Core", "MovieFont not loaded: ", WHITE ); - printf("%s ", MovieFont); + printMessage("Core", "MovieFont not loaded: %s ", WHITE, + MovieFont); printStatus( "WARNING", YELLOW ); } if (GetFont( TooltipFont ) == NULL) { - printMessage( "Core", "TooltipFont not loaded: ", WHITE ); - printf("%s ", TooltipFont); + printMessage("Core", "TooltipFont not loaded: %s ", WHITE, + TooltipFont); printStatus( "WARNING", YELLOW ); } } @@ -1433,7 +1440,7 @@ int Interface::Init() } printMessage( "Core", "Starting Plugin Manager...\n", WHITE ); PluginMgr *plugin = PluginMgr::Get(); - plugin->LoadPlugins(PluginsPath); + LoadPlugins(PluginsPath); if (plugin && plugin->GetPluginCount()) { printMessage( "Core", "Plugin Loading Complete...", WHITE ); printStatus( "OK", LIGHT_GREEN ); @@ -1449,7 +1456,6 @@ int Interface::Init() srand( ( unsigned int ) t ); #ifdef _DEBUG FileStreamPtrCount = 0; - CachedFileStreamPtrCount = 0; #endif printMessage( "Core", "GemRB Core Initialization...\n", WHITE ); printStatus( "OK", LIGHT_GREEN ); @@ -1457,12 +1463,12 @@ int Interface::Init() 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" ); + print( "No Video Driver Available.\nTermination in Progress...\n" ); return GEM_ERROR; } if (video->Init() == GEM_ERROR) { printStatus( "ERROR", LIGHT_RED ); - printf( "Cannot Initialize Video Driver.\nTermination in Progress...\n" ); + print( "Cannot Initialize Video Driver.\nTermination in Progress...\n" ); return GEM_ERROR; } Color defcolor={255,255,255,200}; @@ -1472,7 +1478,7 @@ int Interface::Init() { printMessage( "Core", "Initializing Search Path...", WHITE ); if (!IsAvailable( PLUGIN_RESOURCE_DIRECTORY )) { - printf( "no DirectoryImporter! " ); + print( "no DirectoryImporter! " ); printStatus( "ERROR", LIGHT_RED ); return GEM_ERROR; } @@ -1483,29 +1489,29 @@ int Interface::Init() gamedata->AddSource(path, "Cache", PLUGIN_RESOURCE_DIRECTORY); PathJoin( path, GemRBOverridePath, "override", GameType, NULL); - gamedata->AddSource(path, "GemRB Override", PLUGIN_RESOURCE_DIRECTORY); + gamedata->AddSource(path, "GemRB Override", PLUGIN_RESOURCE_CACHEDDIRECTORY); 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", "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); PathJoin( path, GamePath, GameSoundsPath, NULL); - gamedata->AddSource(path, "Sounds", PLUGIN_RESOURCE_DIRECTORY); + gamedata->AddSource(path, "Sounds", PLUGIN_RESOURCE_CACHEDDIRECTORY); 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"); @@ -1513,7 +1519,7 @@ int Interface::Init() for (size_t j=0;jAddSource(path, description, PLUGIN_RESOURCE_DIRECTORY); + gamedata->AddSource(path, description, PLUGIN_RESOURCE_CACHEDDIRECTORY); } } free(description); @@ -1549,12 +1555,12 @@ int Interface::Init() // 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); } printMessage( "Core", "Reading Game Options...\n", WHITE ); if (!LoadGemRBINI()) { - printf( "Cannot Load INI\nTermination in Progress...\n" ); + print( "Cannot Load INI\nTermination in Progress...\n" ); return GEM_ERROR; } @@ -1577,13 +1583,13 @@ int Interface::Init() projserv = new ProjectileServer(); if (!projserv->GetHighestProjectileNumber()) { printStatus( "ERROR", LIGHT_RED ); - printf( "No projectiles are available...\n" ); + print( "No projectiles are available...\n" ); } printMessage( "Core", "Checking for Dialogue Manager...", WHITE ); if (!IsAvailable( IE_TLK_CLASS_ID )) { printStatus( "ERROR", LIGHT_RED ); - printf( "No TLK Importer Available.\nTermination in Progress...\n" ); + print( "No TLK Importer Available.\nTermination in Progress...\n" ); return GEM_ERROR; } printStatus( "OK", LIGHT_GREEN ); @@ -1591,15 +1597,14 @@ int Interface::Init() printMessage( "Core", "Loading Dialog.tlk file...", WHITE ); char strpath[_MAX_PATH]; PathJoin( strpath, GamePath, dialogtlk, NULL ); - FileStream* fs = new FileStream(); - if (!fs->Open( strpath, true )) { + FileStream* fs = FileStream::OpenFile(strpath); + if (!fs) { printStatus( "ERROR", LIGHT_RED ); - printf( "Cannot find Dialog.tlk.\nTermination in Progress...\n" ); - delete fs; + print( "Cannot find Dialog.tlk.\nTermination in Progress...\n" ); return GEM_ERROR; } printStatus( "OK", LIGHT_GREEN ); - strings->Open( fs, true ); + strings->Open(fs); { printMessage( "Core", "Loading Palettes...\n", WHITE ); @@ -1621,7 +1626,7 @@ int Interface::Init() if (!IsAvailable( IE_BAM_CLASS_ID )) { printStatus( "ERROR", LIGHT_RED ); - printf( "No BAM Importer Available.\nTermination in Progress...\n" ); + print( "No BAM Importer Available.\nTermination in Progress...\n" ); return GEM_ERROR; } @@ -1629,7 +1634,7 @@ int Interface::Init() DSCount = ReadResRefTable ("defsound", DefSound); if (DSCount == 0) { printStatus( "ERROR", LIGHT_RED ); - printf( "Cannot find defsound.2da.\nTermination in Progress...\n" ); + print( "Cannot find defsound.2da.\nTermination in Progress...\n" ); return GEM_ERROR; } @@ -1690,6 +1695,7 @@ int Interface::Init() //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 ); tokens = new Variables(); @@ -1727,7 +1733,7 @@ int Interface::Init() printMessage( "Core", "Loading resource data File...", WHITE ); INIresdata = PluginHolder(IE_INI_CLASS_ID); DataStream* ds = gamedata->GetResource("resdata", IE_INI_CLASS_ID); - if (!INIresdata->Open( ds, true )) { + if (!INIresdata->Open(ds)) { printStatus( "ERROR", LIGHT_RED ); } else { printStatus( "OK", LIGHT_GREEN ); @@ -1735,14 +1741,12 @@ int Interface::Init() } if (HasFeature( GF_HAS_PARTY_INI )) { - printMessage( "Core", "Loading precreated teams setup...\n", - WHITE ); + printMessage( "Core", "Loading precreated teams setup...\n", WHITE ); INIparty = PluginHolder(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 )) { + FileStream* fs = FileStream::OpenFile( tINIparty ); + if (!INIparty->Open(fs)) { printStatus( "ERROR", LIGHT_RED ); } else { printStatus( "OK", LIGHT_GREEN ); @@ -1754,29 +1758,25 @@ int Interface::Init() } if (HasFeature( GF_HAS_BEASTS_INI )) { - printMessage( "Core", "Loading beasts definition File...\n", - WHITE ); + printMessage( "Core", "Loading beasts definition File...\n", WHITE ); INIbeasts = PluginHolder(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 )) { + FileStream* fs = FileStream::OpenFile( tINIbeasts ); + if (!INIbeasts->Open(fs)) { printStatus( "ERROR", LIGHT_RED ); } else { printStatus( "OK", LIGHT_GREEN ); } - printMessage( "Core", "Loading quests definition File...\n", - WHITE ); + printMessage( "Core", "Loading quests definition File...\n", WHITE ); INIquests = PluginHolder(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 )) { + FileStream* fs2 = FileStream::OpenFile( tINIquests ); + if (!INIquests->Open(fs2)) { printStatus( "ERROR", LIGHT_RED ); } else { printStatus( "OK", LIGHT_GREEN ); @@ -1784,6 +1784,7 @@ int Interface::Init() } game = NULL; calendar = NULL; + keymap = NULL; timer = new GlobalTimer(); printMessage( "Core", "Bringing up the Global Timer...", WHITE ); @@ -1898,6 +1899,14 @@ int Interface::Init() InitializeIEScript(); printStatus( "OK", LIGHT_GREEN ); + printMessage( "Core", "Initializing keymap tables...", WHITE); + keymap = new KeyMap(); + ret = keymap->InitializeKeyMap("keymap.ini", "keymap"); + if (!ret) { + printStatus( "ERROR", LIGHT_RED ); + } else { + printStatus( "OK", LIGHT_GREEN ); + } printMessage( "Core", "Core Initialization Complete!\n", WHITE ); return GEM_OK; @@ -1932,124 +1941,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; } @@ -2138,16 +2147,14 @@ bool Interface::LoadConfig(void) return true; } - PathJoin( path, UserDir, name, NULL ); - strcat( path, ".cfg" ); + PathJoinExt( path, UserDir, name, "cfg" ); if (LoadConfig( path )) { return true; } #ifdef SYSCONFDIR - PathJoin( path, SYSCONFDIR, name, NULL ); - strcat( path, ".cfg" ); + PathJoinExt( path, SYSCONFDIR, name, "cfg" ); if (LoadConfig( path )) { return true; @@ -2159,16 +2166,14 @@ bool Interface::LoadConfig(void) return false; } - PathJoin( path, UserDir, PACKAGE, NULL ); - strcat( path, ".cfg" ); + PathJoinExt( path, UserDir, PACKAGE, "cfg" ); if (LoadConfig( path )) { return true; } #ifdef SYSCONFDIR - PathJoin( path, SYSCONFDIR, PACKAGE, NULL ); - strcat( path, ".cfg" ); + PathJoinExt( path, SYSCONFDIR, PACKAGE, "cfg" ); if (LoadConfig( path )) { return true; @@ -2189,26 +2194,26 @@ bool Interface::LoadConfig(void) 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" ); + print("%s ", filename); + FileStream* config = FileStream::OpenFile(filename); if (config == NULL) { printStatus("NOT FOUND", YELLOW); return false; } - char line[1024]; - char *name, *nameend, *value, *valueend; //once GemRB own format is working well, this might be set to 0 SaveAsOriginal = 1; int lineno = 0; - while (!feof( config )) { - if (! fgets( line, sizeof(line), config )) { // also if len == size(line) + while (config->Remains()) { + char line[1024]; + char *name, *nameend, *value, *valueend; + + if (config->ReadLine(line, _MAX_PATH) == -1) { break; } lineno++; @@ -2224,7 +2229,7 @@ bool Interface::LoadConfig(const char* filename) value = strchr( name, '=' ); if (!value || value == name) { - printf( "Invalid line %d\n", lineno ); + print( "Invalid line %d\n", lineno ); continue; } @@ -2268,6 +2273,7 @@ bool Interface::LoadConfig(const char* filename) CONFIG_INT("TooltipDelay", TooltipDelay = ); CONFIG_INT("Width", Width = ); CONFIG_INT("IgnoreOriginalINI", IgnoreOriginalINI = ); + CONFIG_INT("TouchScrollAreas", TouchScrollAreas = ); #undef CONFIG_INT #define CONFIG_STRING(str, var) \ } else if (stricmp(name, str) == 0) { \ @@ -2321,7 +2327,7 @@ bool Interface::LoadConfig(const char* filename) } } } - fclose( config ); + delete config; // WARNING: Don't move ResolveFilePath into the loop // Otherwise, it won't obey CaseSensitive set at the end @@ -2408,13 +2414,13 @@ bool Interface::LoadConfig(const char* filename) } //FixPath( SavePath, false ); - //mkdir( SavePath, S_IREAD|S_IWRITE|S_IEXEC ); - //chmod( SavePath, S_IREAD|S_IWRITE|S_IEXEC ); + //MakeDirectory(SavePath); FixPath( SavePath, true ); FixPath( CachePath, false ); - mkdir( CachePath, S_IREAD|S_IWRITE|S_IEXEC ); - chmod( CachePath, S_IREAD|S_IWRITE|S_IEXEC ); + if (!MakeDirectory(CachePath)) { + error("Core", "Unable to create cache directory '%s'", CachePath); + } printStatus( "OK", LIGHT_GREEN ); @@ -2425,8 +2431,7 @@ bool Interface::LoadConfig(const char* filename) } if ( StupidityDetector( CachePath )) { - printMessage("Core"," ",LIGHT_RED); - printf( "Cache path %s doesn't exist, not a folder or contains alien files!\n", CachePath ); + printMessage("Core", "Cache path %s doesn't exist, not a folder or contains alien files!\n", LIGHT_RED, CachePath ); return false; } if (!KeepCache) DelTree((const char *) CachePath, false); @@ -2435,12 +2440,6 @@ bool Interface::LoadConfig(const char* filename) 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 @@ -2516,16 +2515,16 @@ bool Interface::LoadGemRBINI() return false; } - printMessage( "Core", "Loading game type-specific GemRB setup...\n", WHITE ); - printf( "%s",inifile->originalfile); + printMessage("Core", "Loading game type-specific GemRB setup...\n%s", WHITE, + inifile->originalfile); if (!IsAvailable( IE_INI_CLASS_ID )) { printStatus( "ERROR", LIGHT_RED ); - printf( "[Core]: No INI Importer Available.\n" ); + print( "[Core]: No INI Importer Available.\n" ); return false; } PluginHolder ini(IE_INI_CLASS_ID); - ini->Open( inifile, true ); //autofree + ini->Open(inifile); printStatus( "OK", LIGHT_GREEN ); @@ -2620,7 +2619,10 @@ 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; } } } @@ -2631,12 +2633,11 @@ bool Interface::LoadGemRBINI() for (i=0;iGetKeyAsInt( "resources", game_flags[i], 0 ), i ); //printMessage("Option", "", GREEN); - //printf("%s = %s\n", game_flags[i], HasFeature(i)?"yes":"no"); + //print("%s = %s\n", game_flags[i], HasFeature(i)?"yes":"no"); } ForceStereo = ini->GetKeyAsInt( "resources", "ForceStereo", 0 ); @@ -2871,13 +2872,11 @@ 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 ); + printMessage("Interface", "Error: Cannot find %s.chu\n", LIGHT_RED, name ); return false; } - if (!GetWindowMgr()->Open( stream, true )) { - printMessage( "Interface", "Error: Cannot Load ", LIGHT_RED ); - printf( "%s.chu\n", name ); + if (!GetWindowMgr()->Open(stream)) { + printMessage("Interface", "Error: Cannot Load %s.chu\n", LIGHT_RED, name ); return false; } @@ -2950,8 +2949,6 @@ int Interface::CreateWindow(unsigned short WindowID, int XPos, int YPos, unsigne ResourceHolder mos(Background); if (mos != NULL) { win->SetBackGround( mos->GetSprite2D(), true ); - } else { - printf( "[Core]: Cannot Load BackGround, skipping\n" ); } } @@ -3055,23 +3052,6 @@ 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) @@ -3242,12 +3222,12 @@ void Interface::GameLoop(void) update_scripts = !(gc->GetDialogueFlags() & DF_FREEZE_SCRIPTS); } - update_scripts = GSUpdate(update_scripts); + bool do_update = GSUpdate(update_scripts); //i'm not sure if this should be here //in multi player (if we ever get to it), only the server must call this - if (update_scripts) { + if (do_update) { if ( game->selected.size() > 0 ) { gc->ChangeMap(GetFirstSelectedPC(true), false); } @@ -3316,7 +3296,7 @@ void Interface::HandleGUIBehaviour(void) } } -void Interface::DrawWindows(void) +void Interface::DrawWindows(bool allow_delete) { //here comes the REAL drawing of windows if (ModalWindow) { @@ -3334,10 +3314,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(); } @@ -3548,7 +3530,7 @@ int Interface::LoadSymbol(const char* ResRef) delete str; return -1; } - if (!sm->Open( str, true )) { + if (!sm->Open(str)) { return -1; } Symbol s; @@ -3719,7 +3701,7 @@ int Interface::GetPortraits(TextArea* ta, bool smallorlarge) if (!dir) { return -1; } - printf( "Looking in %s\n", Path ); + print( "Looking in %s\n", Path ); do { char *name = dir.GetName(); if (name[0] == '.') @@ -3751,7 +3733,7 @@ int Interface::GetCharSounds(TextArea* ta) if (!dir) { return -1; } - printf( "Looking in %s\n", Path ); + print( "Looking in %s\n", Path ); do { char *name = dir.GetName(); if (name[0] == '.') @@ -3780,7 +3762,7 @@ int Interface::GetCharacters(TextArea* ta) if (!dir) { return -1; } - printf( "Looking in %s\n", Path ); + print( "Looking in %s\n", Path ); do { char *name = dir.GetName(); if (name[0] == '.') @@ -3799,45 +3781,36 @@ int Interface::GetCharacters(TextArea* ta) bool Interface::LoadINI(const char* filename) { - FILE* config; - config = fopen( filename, "rb" ); + FileStream* config = FileStream::OpenFile(filename); if (config == NULL) { return false; } char name[65], value[_MAX_PATH + 3]; - while (!feof( config )) { - name[0] = 0; - value[0] = 0; - char rem; + while (config->Remains()) { + char line[_MAX_PATH]; - if (fread( &rem, 1, 1, config ) != 1) + if (config->ReadLine(line, _MAX_PATH) == -1) break; - if (( rem == '#' ) || - ( rem == '[' ) || - ( rem == '\r' ) || - ( rem == '\n' ) || - ( rem == ';' )) { - if (rem == '\r') { - fgetc( config ); - continue; - } else if (rem == '\n') - continue; - - //it should always return zero - if (fscanf( config, "%*[^\r\n]%*[\r\n]" )!=0) - break; + if ((line[0] == '#') || + ( line[0] == '[' ) || + ( line[0] == '\r' ) || + ( line[0] == '\n' ) || + ( line[0] == ';' )) { continue; } - fseek( config, -1, SEEK_CUR ); + + name[0] = 0; + value[0] = 0; + //the * element is not counted - if (fscanf( config, "%[^=]=%[^\r\n]%*[\r\n]", name, value )!=2) + if (sscanf( line, "%[^=]=%[^\r\n]", name, value )!=2) continue; if (( value[0] >= '0' ) && ( value[0] <= '9' )) { vars->SetAt( name, atoi( value ) ); } } - fclose( config ); + delete config; return true; } @@ -3848,7 +3821,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 ); @@ -3939,6 +3912,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 @@ -3989,7 +3963,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); @@ -4002,7 +3976,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( ); @@ -4013,7 +3987,7 @@ void Interface::LoadGame(SaveGame *sg, int ver_override) LoadProgress(20); // Unpack SAV (archive) file to Cache dir if (sav_str) { - PluginHolder ai(IE_BIF_CLASS_ID); + PluginHolder ai(IE_SAV_CLASS_ID); if (ai) { if (ai->DecompressSaveGame(sav_str) != GEM_OK) { goto cleanup; @@ -4061,7 +4035,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; } @@ -4442,7 +4416,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); } @@ -4455,7 +4429,7 @@ bool Interface::StupidityDetector(const char* Pt) strcpy( Path, Pt ); DirectoryIterator dir(Path); if (!dir) { - printf("\n**cannot open**\n"); + print("\n**cannot open**\n"); return true; } do { @@ -4467,11 +4441,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**\n"); return true; //a directory in there??? } if (ProtectedExtension(name) ) { - printf("\n**contains alien files**\n"); + print("\n**contains alien files**\n"); return true; //an executable file in there??? } } while (++dir); @@ -4662,6 +4636,10 @@ bool Interface::ResolveRandomItem(CREItem *itm) void* lookup; if ( !RtRows->Lookup( itm->ItemResRef, lookup ) ) { + if (!gamedata->Exists(itm->ItemResRef, IE_ITM_CLASS_ID)) { + printMessage("Interface", "Nonexistent random item (bad table entry) detected: %s\n", LIGHT_RED, itm->ItemResRef); + return false; + } return true; } ItemList *itemlist = (ItemList*)lookup; @@ -4696,8 +4674,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); + printMessage("Interface", "Loop detected while generating random item:%s\n", LIGHT_RED, + itm->ItemResRef); return false; } @@ -4785,43 +4763,16 @@ Store *Interface::GetCurrentStore() return CurrentStore; } -int Interface::CloseCurrentStore() +void Interface::CloseCurrentStore() { - if ( !CurrentStore ) { - return -1; - } - PluginHolder 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; } @@ -4829,25 +4780,10 @@ Store *Interface::SetCurrentStore(const ieResRef resname, ieDword owner) CloseCurrentStore(); } - DataStream* str = gamedata->GetResource( resname, IE_STO_CLASS_ID ); - PluginHolder 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); } @@ -4865,12 +4801,11 @@ int Interface::GetMouseScrollSpeed() { ieStrRef Interface::GetRumour(const ieResRef dlgref) { PluginHolder 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 ); + printMessage("Interface", "Cannot load dialog: %s\n", LIGHT_RED, dlgref); return (ieStrRef) -1; } Scriptable *pc=game->GetPC( game->GetSelectedPCSingle(), false ); @@ -4884,24 +4819,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;sizeItemsCount;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) { @@ -5080,13 +4997,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()); + printMessage("Core", "Area removed: %s\n", YELLOW, + map->GetScriptName()); RemoveFromCache(map->GetScriptName(), IE_ARE_CLASS_ID); } } else { - printMessage("Core"," ", YELLOW); - printf("Area removed: %s\n", map->GetScriptName()); + printMessage("Core", "Area removed: %s\n", YELLOW, + map->GetScriptName()); RemoveFromCache(map->GetScriptName(), IE_ARE_CLASS_ID); } //make sure the stream isn't connected to sm, or it will be double freed @@ -5115,8 +5032,7 @@ int Interface::WriteCharacter(const char *name, Actor *actor) int ret = gm->PutActor(&str, actor, true); if (ret <0) { - printMessage("Core"," ", YELLOW); - printf("Character cannot be saved: %s\n", name); + printMessage("Core", "Character cannot be saved: %s\n", YELLOW, name); return -1; } } @@ -5150,13 +5066,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); + printMessage("Core", "Game cannot be saved: %s\n", YELLOW, folder); return -1; } } else { - printMessage("Core"," ", YELLOW); - printf("Internal error, game cannot be saved: %s\n", folder); + printMessage("Core", "Internal error, game cannot be saved: %s\n", YELLOW, folder); return -1; } return 0; @@ -5197,8 +5111,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); + printMessage("Core", "Internal error, worldmap cannot be saved: %s\n", YELLOW, folder); return -1; } return 0; @@ -5213,8 +5126,7 @@ int Interface::CompressSave(const char *folder) if (!dir) { return -1; } - //BIF and SAV are the same - PluginHolder ai(IE_BIF_CLASS_ID); + PluginHolder ai(IE_SAV_CLASS_ID); ai->CreateArchive( &str); //.tot and .toh should be saved last, because they are updated when an .are is saved @@ -5230,7 +5142,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); @@ -5464,8 +5376,7 @@ ieDword Interface::TranslateStat(const char *stat_name) Holder sym = GetSymbol( symbol ); ieDword stat = (ieDword) sym->GetValue( stat_name ); if (stat==(ieDword) ~0) { - printMessage("Core"," ",YELLOW); - printf("Cannot translate symbol: %s\n", stat_name); + printMessage("Core", "Cannot translate symbol: %s\n", YELLOW, stat_name); } return stat; } @@ -5513,7 +5424,6 @@ void Interface::SetNextScript(const char *script) 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/project/jni/application/gemrb/gemrb/core/Interface.h b/project/jni/application/gemrb/gemrb/core/Interface.h index 2e6180174..f8d86189f 100644 --- a/project/jni/application/gemrb/gemrb/core/Interface.h +++ b/project/jni/application/gemrb/gemrb/core/Interface.h @@ -26,19 +26,16 @@ #ifndef INTERFACE_H #define INTERFACE_H -//skip messy warnings in MSVC6 -#include "win32def.h" - #include "SClassID.h" #include "exports.h" #include "Cache.h" #include "Callback.h" -#include "GlobalTimer.h" #include "Holder.h" #include #include +#include #ifdef _MSC_VER // No SFINAE #include "Audio.h" @@ -49,6 +46,7 @@ #include "StringMgr.h" #include "SymbolMgr.h" #include "Video.h" +#include "WindowMgr.h" #endif class Actor; @@ -67,9 +65,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 +82,7 @@ class SaveGameIterator; class ScriptEngine; class ScriptedAnimation; class Spell; +class Sprite2D; class Store; class StringMgr; class SymbolMgr; @@ -349,6 +350,7 @@ private: EventHandler TickHook; int SpecialSpellsCount; SpellDescType *SpecialSpells; + KeyMap *keymap; public: Holder strings; GlobalTimer * timer; @@ -432,8 +434,6 @@ 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); /** sets tooltip to be displayed */ @@ -524,6 +524,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); @@ -587,7 +593,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(); @@ -601,7 +607,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 @@ -745,7 +750,7 @@ public: unsigned int TooltipDelay; int IgnoreOriginalINI; unsigned int FogOfWar; - bool CaseSensitive, GameOnCD, SkipIntroVideos, DrawFPS; + bool CaseSensitive, GameOnCD, SkipIntroVideos, DrawFPS, TouchScrollAreas; bool GUIEnhancements; bool KeepCache; Variables *plugin_flags; @@ -754,7 +759,7 @@ public: /** returns true if the game is paused */ bool IsFreezed(); /** Draws the Visible windows in the Windows Array */ - void DrawWindows(void); + void DrawWindows(bool allow_delete = false); /** Sends a termination signal to the Video Driver */ bool Quit(void); /** CheatKey support */ @@ -794,7 +799,6 @@ public: #ifdef _DEBUG int FileStreamPtrCount; - int CachedFileStreamPtrCount; #endif }; diff --git a/project/jni/application/gemrb/gemrb/core/Inventory.cpp b/project/jni/application/gemrb/gemrb/core/Inventory.cpp index 087943737..8025f263d 100644 --- a/project/jni/application/gemrb/gemrb/core/Inventory.cpp +++ b/project/jni/application/gemrb/gemrb/core/Inventory.cpp @@ -26,11 +26,13 @@ #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" @@ -55,9 +57,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. @@ -154,7 +154,7 @@ CREItem *Inventory::GetItem(unsigned int slot) //This hack sets the charge counters for non-rechargeable items, //if their charge is zero -inline void HackCharges(CREItem *item) +static inline void HackCharges(CREItem *item) { Item *itm = gamedata->GetItem( item->ItemResRef ); if (itm) { @@ -228,24 +228,24 @@ void Inventory::CalculateWeight() } //if item is stacked mark it as so - if (itm->StackAmount) { + if (itm->MaxStackAmount) { slot->Flags |= IE_INV_ITEM_STACKED; } slot->Weight = itm->Weight; - slot->StackAmount = itm->StackAmount; + slot->MaxStackAmount = itm->MaxStackAmount; gamedata->FreeItem( itm, slot->ItemResRef, false ); } else { - printMessage( "Inventory", " ", LIGHT_RED); - printf("Invalid item: %s!\n", slot->ItemResRef); + printMessage("Inventory", "Invalid item: %s!\n", LIGHT_RED, + 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 > 1) ? slot->Usages[0] : 1); } } Changed = false; @@ -303,7 +303,7 @@ void Inventory::SetInventoryType(int arg) void Inventory::SetSlotCount(unsigned int size) { if (Slots.size()) { - printf("Inventory size changed???\n"); + print("Inventory size changed???\n"); //we don't allow reassignment, //if you want this, delete the previous Slots here abort(); @@ -350,7 +350,7 @@ 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) ) { @@ -638,17 +638,16 @@ int Inventory::AddSlotItem(CREItem* item, int slot, int slottype) } CREItem *myslot = Slots[slot]; - if (ItemsAreCompatible( myslot, item )) { + if (myslot->MaxStackAmount > 1 && 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 (myslot->Usages[0] + chunk > myslot->MaxStackAmount) { + chunk = myslot->MaxStackAmount - myslot->Usages[0]; } if (!chunk) { - return -1; + return ASI_FAILED; } + assert(chunk > 0); myslot->Flags |= IE_INV_ITEM_ACQUIRED; myslot->Usages[0] = (ieWord) (myslot->Usages[0] + chunk); item->Usages[0] = (ieWord) (item->Usages[0] - chunk); @@ -745,6 +744,7 @@ int Inventory::AddStoreItem(STOItem* item, int action) } item->PurchasedAmount--; } + CalculateWeight(); return ret; } @@ -970,7 +970,7 @@ bool Inventory::EquipItem(unsigned int slot) int effect = core->QuerySlotEffects( slot ); Item *itm = gamedata->GetItem(item->ItemResRef); if (!itm) { - printf("Invalid item Equipped: %s Slot: %d\n", item->ItemResRef, slot); + print("Invalid item Equipped: %s Slot: %d\n", item->ItemResRef, slot); return false; } switch (effect) { @@ -1381,7 +1381,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]StackAmount) { + if (item->Usages[0]MaxStackAmount) { return (int) i; } } @@ -1398,7 +1398,7 @@ 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)) { + if (core->ResolveRandomItem(TmpItem)) { AddSlotItem( TmpItem, SlotID ); } else { delete TmpItem; @@ -1416,7 +1416,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; @@ -1448,7 +1448,7 @@ void Inventory::BreakItemSlot(ieDword slot) void Inventory::dump() { - printf( "INVENTORY:\n" ); + print( "INVENTORY:\n" ); for (unsigned int i = 0; i < Slots.size(); i++) { CREItem* itm = Slots[i]; @@ -1456,13 +1456,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 ); + print ( "%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 ); + print( "Equipped: %d\n", Equipped ); Changed = true; CalculateWeight(); - printf( "Total weight: %d\n", Weight ); + print( "Total weight: %d\n", Weight ); } void Inventory::EquipBestWeapon(int flags) @@ -1795,7 +1795,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 +1804,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\n", slot, inc); //as the unsigned value underflows, it will be greater than Slots.size() for(;slotRange; diff --git a/project/jni/application/gemrb/gemrb/core/Item.h b/project/jni/application/gemrb/gemrb/core/Item.h index d3952689d..31f5fe935 100644 --- a/project/jni/application/gemrb/gemrb/core/Item.h +++ b/project/jni/application/gemrb/gemrb/core/Item.h @@ -180,7 +180,7 @@ public: ieByte unknown3; ieDword KitUsability; ieDword Price; - ieWord StackAmount; + ieWord MaxStackAmount; ieResRef ItemIcon; ieWord LoreToID; ieResRef GroundIcon; diff --git a/project/jni/application/gemrb/gemrb/core/ItemMgr.h b/project/jni/application/gemrb/gemrb/core/ItemMgr.h index 10136897d..7bcfbc70e 100644 --- a/project/jni/application/gemrb/gemrb/core/ItemMgr.h +++ b/project/jni/application/gemrb/gemrb/core/ItemMgr.h @@ -41,7 +41,7 @@ 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; }; diff --git a/project/jni/application/gemrb/gemrb/core/KeyMap.cpp b/project/jni/application/gemrb/gemrb/core/KeyMap.cpp new file mode 100644 index 000000000..814ee56ba --- /dev/null +++ b/project/jni/application/gemrb/gemrb/core/KeyMap.cpp @@ -0,0 +1,157 @@ +/* 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" + +#define KEYLENGTH 64 + +Function::Function(const char *m, const char *f, int g) +{ + strncpy(module, m, sizeof(module)); + strncpy(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) { + printMessage("KeyMap","There is no '%s' file...\n", YELLOW, 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;c1 || keymap.Lookup(value, tmp) ) { + print("Ignoring key %s\n", 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"); + } + fun = new Function(module, function, atoi(group)); + keymap.SetAt(value, fun); + print("Adding key %s with function %s::%s\n", value, module, function); + } + delete config; + return true; +} + +//group can be: +//main gamecontrol +void KeyMap::ResolveKey(int key, int group) +{ + Function *fun; + void *tmp; + char keystr[2]; + + keystr[0]=(char) key; + keystr[1]=0; + + print("Looking up key: %c (%s) \n", key, keystr); + + if (!keymap.Lookup(keystr, tmp) ) { + return; + } + fun = (Function *) tmp; + + if (fun->group!=group) { + return; + } + + printMessage("KeyMap", " ", WHITE); + print("RunFunction(%s::%s)\n",fun->module, fun->function); + core->GetGUIScriptEngine()->RunFunction(fun->module, fun->function); +} + diff --git a/project/jni/application/gemrb/gemrb/core/KeyMap.h b/project/jni/application/gemrb/gemrb/core/KeyMap.h new file mode 100644 index 000000000..816796358 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/core/KeyMap.h @@ -0,0 +1,48 @@ +/* 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" + +class Variables; + +class GEM_EXPORT KeyMap { +private: + Variables keymap; +public: + KeyMap(); + ~KeyMap(); + bool InitializeKeyMap(const char *inifile, const char *keyfile); + void ResolveKey(int key, int group); +}; + +class Function { +public: + char module[16]; + char function[32]; + int group; + + Function(const char *m, const char *f, int g); +}; + +#endif diff --git a/project/jni/application/gemrb/gemrb/core/Makefile.am b/project/jni/application/gemrb/gemrb/core/Makefile.am index 26bea7942..72897f446 100644 --- a/project/jni/application/gemrb/gemrb/core/Makefile.am +++ b/project/jni/application/gemrb/gemrb/core/Makefile.am @@ -51,15 +51,18 @@ 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 \ Inventory.cpp \ Item.cpp \ ItemMgr.cpp \ + KeyMap.cpp \ LRUCache.cpp \ Map.cpp \ MapMgr.cpp \ @@ -69,6 +72,7 @@ libgemrb_core_la_SOURCES = \ PalettedImageMgr.cpp \ Particles.cpp \ Plugin.cpp \ + PluginLoader.cpp \ PluginMgr.cpp \ Polygon.cpp \ Projectile.cpp \ @@ -99,10 +103,12 @@ libgemrb_core_la_SOURCES = \ StoreMgr.cpp \ StringMgr.cpp \ SymbolMgr.cpp \ - System/CachedFileStream.cpp \ System/DataStream.cpp \ System/FileStream.cpp \ + System/Logging.cpp \ System/MemoryStream.cpp \ + System/SlicedStream.cpp \ + System/String.cpp \ System/VFS.cpp \ TableMgr.cpp \ Tile.cpp \ diff --git a/project/jni/application/gemrb/gemrb/core/Map.cpp b/project/jni/application/gemrb/gemrb/core/Map.cpp index f89036c80..4610c7c4a 100644 --- a/project/jni/application/gemrb/gemrb/core/Map.cpp +++ b/project/jni/application/gemrb/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,6 +38,7 @@ #include "Palette.h" #include "Particles.h" #include "PathFinder.h" +#include "PluginMgr.h" #include "Projectile.h" #include "ScriptedAnimation.h" #include "TileMap.h" @@ -45,6 +47,7 @@ #include "strrefs.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" @@ -73,7 +76,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 +98,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 +151,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,7 +162,7 @@ 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; @@ -193,7 +196,7 @@ void InitSpawnGroups() } //Preload the searchmap configuration -void InitPathFinder() +static void InitPathFinder() { PathFinderInited = true; tsndcount = 0; @@ -229,7 +232,7 @@ void InitPathFinder() } } -void AddLOS(int destx, int desty, int slot) +static void AddLOS(int destx, int desty, int slot) { for (int i=0;iHasFeature(GF_SMALL_FOG); @@ -466,8 +469,7 @@ void Map::MoveToNewArea(const char *area, const char *entrance, unsigned int dir } Map* map = game->GetMap(area, false); if (!map) { - printMessage("Map", " ", LIGHT_RED); - printf("Invalid map: %s\n",area); + printMessage("Map", "Invalid map: %s\n", LIGHT_RED, area); command[0]=0; return; } @@ -494,8 +496,8 @@ void Map::MoveToNewArea(const char *area, const char *entrance, unsigned int dir 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 ); + printMessage("Map", "WARNING!!! EntryPoint '%s' does not exist and direction %d is invalid\n", YELLOW, + entrance, direction); X = map->TMap->XCellCount * 64; Y = map->TMap->YCellCount * 64; } @@ -516,7 +518,7 @@ void Map::MoveToNewArea(const char *area, const char *entrance, unsigned int dir pc->ClearPath(); pc->ClearActions(); pc->AddAction( GenerateAction( command ) ); - pc->ProcessActions(true); + pc->ProcessActions(); } } return; @@ -534,7 +536,7 @@ void Map::MoveToNewArea(const char *area, const char *entrance, unsigned int dir pc->ClearPath(); pc->ClearActions(); pc->AddAction( GenerateAction( command ) ); - pc->ProcessActions(true); + pc->ProcessActions(); } } return; @@ -543,7 +545,7 @@ void Map::MoveToNewArea(const char *area, const char *entrance, unsigned int dir actor->ClearPath(); actor->ClearActions(); actor->AddAction( GenerateAction( command ) ); - actor->ProcessActions(true); + actor->ProcessActions(); } void Map::UseExit(Actor *actor, InfoPoint *ip) @@ -572,9 +574,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(); } } @@ -626,19 +629,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 +654,11 @@ void Map::UpdateScripts() int q=Qcount[PR_SCRIPT]; Game *game = core->GetGame(); + bool timestop = game->IsTimestopActive(); + if (!timestop) { + game->timestop_owner = NULL; + } Actor *timestop_owner = game->timestop_owner; - bool timestop = game->timestop_end>game->GameTime; while (q--) { Actor* actor = queue[PR_SCRIPT][q]; @@ -660,8 +667,9 @@ void Map::UpdateScripts() actor->no_more_steps = true; continue; } - if (timestop && actor!=timestop_owner && actor->Modified[IE_DISABLETIMESTOP] ) { + if (timestop && actor!=timestop_owner && actor->Modified[IE_DISABLETIMESTOP] == 0) { actor->no_more_steps = true; + actor->ClearPath(); //HACK: prevents jumping when timestop ends continue; } @@ -679,6 +687,9 @@ void Map::UpdateScripts() } } 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 +702,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,8 +718,6 @@ 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(); @@ -731,7 +740,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!\n", actor->BaseStats[IE_ANIMATION_ID]); } } } @@ -767,10 +776,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 +785,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 +802,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; } @@ -844,14 +839,12 @@ void Map::UpdateScripts() } if (wasActive) { - ip->ExecuteScript( 1 ); //Play the PST specific enter sound if (wasActive&TRAP_USEPOINT) { core->GetAudioDrv()->Play(ip->EnterWav, ip->TrapLaunch.x, ip->TrapLaunch.y); } + ip->Update(); } - //Execute Pending Actions - ip->ProcessActions(false); } } @@ -862,7 +855,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) { @@ -1069,7 +1062,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,13 +1078,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(); @@ -1261,11 +1261,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()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(); } } @@ -2122,30 +2122,30 @@ void Map::DebugDump(bool show_actors) const { size_t i; - printf( "DebugDump of Area %s:\n", scriptName ); - printf ("Scripts:"); + print( "DebugDump of Area %s:\n", scriptName ); + print ("Scripts:"); for (i = 0; i < MAX_SCRIPTS; i++) { const char* poi = ""; if (Scripts[i]) { poi = Scripts[i]->GetName(); } - printf( " %.8s", poi ); + print( " %.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) ); + print( "Area Global ID: %d\n", GetGlobalID()); + print( "OutDoor: %s\n", YESNO(AreaType & AT_OUTDOOR ) ); + print( "Day/Night: %s\n", YESNO(AreaType & AT_DAYNIGHT ) ); + print( "Extended night: %s\n", YESNO(AreaType & AT_EXTENDED_NIGHT ) ); + print( "Weather: %s\n", YESNO(AreaType & AT_WEATHER ) ); + print( "Area Type: %d\n", AreaType & (AT_CITY|AT_FOREST|AT_DUNGEON) ); + print( "Can rest: %s\n", YESNO(AreaType & AT_CAN_REST) ); if (show_actors) { - printf("\n"); + print("\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); + print("Actor: %s at %d.%d\n", actors[i]->GetName(1), actors[i]->Pos.x, actors[i]->Pos.y); } } } @@ -2326,7 +2326,7 @@ 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"); + //print("Path not found!\n"); break; } SetupNode( x - 1, y - 1, size, Cost ); @@ -2669,12 +2669,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!!!\n"); break; } unsigned int Cost = MapSet[y * Width + x] + NormalCost; if (Cost > 65500) { - //printf("Path not found!\n"); + //print("Path not found!\n"); break; } SetupNode( x - 1, y - 1, size, Cost ); @@ -2828,8 +2828,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); + printMessage("Map", "This isn't a travel region [%d.%d]?\n", YELLOW, + sX, sY); return -1; } sX*=Height; @@ -3498,7 +3498,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\n", BAM); return NULL; } //this will make the animation stop when the game is stopped @@ -3520,7 +3520,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\n", BAM); return; } @@ -3664,15 +3664,20 @@ 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)); } } } diff --git a/project/jni/application/gemrb/gemrb/core/Map.h b/project/jni/application/gemrb/gemrb/core/Map.h index 7e830c6f0..68e24634c 100644 --- a/project/jni/application/gemrb/gemrb/core/Map.h +++ b/project/jni/application/gemrb/gemrb/core/Map.h @@ -26,10 +26,6 @@ class Map; #include "exports.h" #include "globals.h" -#include "Bitmap.h" -#include "Image.h" -#include "IniSpawn.h" -#include "SpriteCover.h" #include "Scriptable/Scriptable.h" #include @@ -38,11 +34,17 @@ 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; diff --git a/project/jni/application/gemrb/gemrb/core/MapMgr.h b/project/jni/application/gemrb/gemrb/core/MapMgr.h index c709e707f..a6d5fd63f 100644 --- a/project/jni/application/gemrb/gemrb/core/MapMgr.h +++ b/project/jni/application/gemrb/gemrb/core/MapMgr.h @@ -27,10 +27,10 @@ #ifndef MAPMGR_H #define MAPMGR_H -#include "Map.h" #include "Plugin.h" -#include "Scriptable/Scriptable.h" -#include "System/DataStream.h" + +class DataStream; +class Map; /** * @class MapMgr @@ -41,7 +41,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; diff --git a/project/jni/application/gemrb/gemrb/core/Palette.cpp b/project/jni/application/gemrb/gemrb/core/Palette.cpp index 11690f119..62f5e8299 100644 --- a/project/jni/application/gemrb/gemrb/core/Palette.cpp +++ b/project/jni/application/gemrb/gemrb/core/Palette.cpp @@ -46,6 +46,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() { diff --git a/project/jni/application/gemrb/gemrb/core/Palette.h b/project/jni/application/gemrb/gemrb/core/Palette.h index ba857d173..c610d34fb 100644 --- a/project/jni/application/gemrb/gemrb/core/Palette.h +++ b/project/jni/application/gemrb/gemrb/core/Palette.h @@ -85,6 +85,7 @@ public: } void CreateShadedAlphaChannel(); + void Brighten(); void SetupPaperdollColours(const ieDword* Colors, unsigned int type); void SetupRGBModification(const Palette* src, const RGBModifier* mods, diff --git a/project/jni/application/gemrb/gemrb/core/Particles.cpp b/project/jni/application/gemrb/gemrb/core/Particles.cpp index ce3195fbe..0b804e397 100644 --- a/project/jni/application/gemrb/gemrb/core/Particles.cpp +++ b/project/jni/application/gemrb/gemrb/core/Particles.cpp @@ -20,9 +20,11 @@ #include "Particles.h" -#include "Interface.h" -#include "Video.h" +#include "CharAnimations.h" #include "Game.h" +#include "Interface.h" +#include "TableMgr.h" +#include "Video.h" Color sparkcolors[MAX_SPARK_COLOR][MAX_SPARK_PHASE]; bool inited = false; @@ -31,7 +33,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 +52,7 @@ void TranslateColor(const char *value, Color &color) color.b=b; } -void InitSparks() +static void InitSparks() { int i,j; AutoTable tab("sprklclr"); diff --git a/project/jni/application/gemrb/gemrb/core/Plugin.h b/project/jni/application/gemrb/gemrb/core/Plugin.h index 12121035c..b565ddd89 100644 --- a/project/jni/application/gemrb/gemrb/core/Plugin.h +++ b/project/jni/application/gemrb/gemrb/core/Plugin.h @@ -31,7 +31,6 @@ #include "exports.h" #include "Holder.h" -#include "PluginMgr.h" #include "TypeID.h" #include @@ -47,19 +46,4 @@ public: virtual ~Plugin(void); }; -template -class PluginHolder : public Holder { -public: - PluginHolder() - { - } - PluginHolder(PluginID id) - : Holder(static_cast(PluginMgr::Get()->GetPlugin(id))) - { - } - ~PluginHolder() - { - } -}; - #endif diff --git a/project/jni/application/gemrb/gemrb/core/PluginLoader.cpp b/project/jni/application/gemrb/gemrb/core/PluginLoader.cpp new file mode 100644 index 000000000..e6d8ac358 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/core/PluginLoader.cpp @@ -0,0 +1,239 @@ +/* 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 +#include +#include +#include + +#ifdef WIN32 +#include +#include +#else +#include +#include +#include +#include +#endif + +#ifdef WIN32 +typedef HMODULE LibHandle; +#else +typedef void *LibHandle; +#endif + +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 +#include +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 print( "%s\n", dlerror() ) +#endif + +/** Return names of all *.so or *.dll files in the given directory */ +#ifdef WIN32 +static bool FindFiles( char* path, std::list &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 &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 libs; + + printMessage("PluginMgr", "Loading Plugins from %s\n", WHITE, 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 ); + print( ": Loading: " ); + textcolor( LIGHT_WHITE ); + print( "%s", path ); + textcolor( WHITE ); + print( "..." ); + + + 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 ); + print( "\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 ); + print( "Invalid Plug-in, Skipping...\n" ); + FREE_PLUGIN( hMod ); + continue; + } + if (strcmp(LibVersion(), VERSION_GEMRB) ) { + printStatus( "ERROR", LIGHT_RED ); + print( "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 ); + print( " " ); + textcolor( LIGHT_WHITE ); + print( "%s", desc.Description ); + textcolor( WHITE ); + print( "..." ); + 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(PluginMgr::Get())) { + printMessage( "PluginMgr", "Plug-in Registration Failed! Perhaps a duplicate? ", WHITE ); + printStatus( "SKIPPING", YELLOW ); + FREE_PLUGIN( hMod ); + } + } + libs.insert(desc.ID); + } +} diff --git a/project/jni/application/gemrb/gemrb/core/PluginLoader.h b/project/jni/application/gemrb/gemrb/core/PluginLoader.h new file mode 100644 index 000000000..f68fbc705 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/core/PluginLoader.h @@ -0,0 +1,32 @@ +/* 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 + +/** + * 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/project/jni/application/gemrb/gemrb/core/PluginMgr.cpp b/project/jni/application/gemrb/gemrb/core/PluginMgr.cpp index 8b31b1551..19d183053 100644 --- a/project/jni/application/gemrb/gemrb/core/PluginMgr.cpp +++ b/project/jni/application/gemrb/gemrb/core/PluginMgr.cpp @@ -14,60 +14,14 @@ * You should have received a copy of the GNU General Public 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 -#include -#ifdef WIN32 -#include -#include -#else -#include -#include -#include -#include -#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 -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 PluginMgr *PluginMgr::Get() { @@ -79,172 +33,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 &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 &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 { diff --git a/project/jni/application/gemrb/gemrb/core/PluginMgr.h b/project/jni/application/gemrb/gemrb/core/PluginMgr.h index ff0d88cf7..8142d00bf 100644 --- a/project/jni/application/gemrb/gemrb/core/PluginMgr.h +++ b/project/jni/application/gemrb/gemrb/core/PluginMgr.h @@ -32,6 +32,7 @@ #include "globals.h" #include "iless.h" #include "win32def.h" +#include "Holder.h" #include "ResourceDesc.h" @@ -40,12 +41,6 @@ #include #include -#ifdef WIN32 -typedef HINSTANCE LibHandle; -#else -typedef void *LibHandle; -#endif - class Plugin; class Resource; class TypeID; @@ -64,19 +59,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 > resources; /** Array of initializer functions */ @@ -86,12 +73,10 @@ private: typedef std::map driver_map; std::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 +135,19 @@ public: Plugin* GetDriver(const TypeID* type, const char* name); }; +template +class PluginHolder : public Holder { +public: + PluginHolder() + { + } + PluginHolder(PluginID id) + : Holder(static_cast(PluginMgr::Get()->GetPlugin(id))) + { + } + ~PluginHolder() + { + } +}; + #endif diff --git a/project/jni/application/gemrb/gemrb/core/Polygon.cpp b/project/jni/application/gemrb/gemrb/core/Polygon.cpp index 2128a1d22..860e521be 100644 --- a/project/jni/application/gemrb/gemrb/core/Polygon.cpp +++ b/project/jni/application/gemrb/gemrb/core/Polygon.cpp @@ -123,20 +123,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 +219,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(); diff --git a/project/jni/application/gemrb/gemrb/core/Projectile.cpp b/project/jni/application/gemrb/gemrb/core/Projectile.cpp index b63f075d8..3d3f3dcb9 100644 --- a/project/jni/application/gemrb/gemrb/core/Projectile.cpp +++ b/project/jni/application/gemrb/gemrb/core/Projectile.cpp @@ -22,12 +22,17 @@ #include "win32def.h" +#include "AnimationFactory.h" #include "Audio.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 @@ -250,14 +255,17 @@ void Projectile::GetPaletteCopy(Animation *anim[], Palette *&pal) } } -void Projectile::SetBlend() +void Projectile::SetBlend(int brighten) { GetPaletteCopy(travel, palette); if (!palette) return; if (!palette->alpha) { palette->CreateShadedAlphaChannel(); - } + } + if (brighten) { + palette->Brighten(); + } } //create another projectile with type-1 (iterate magic missiles and call lightning) @@ -409,8 +417,8 @@ 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; } diff --git a/project/jni/application/gemrb/gemrb/core/Projectile.h b/project/jni/application/gemrb/gemrb/core/Projectile.h index 16e899d13..19cd794fc 100644 --- a/project/jni/application/gemrb/gemrb/core/Projectile.h +++ b/project/jni/application/gemrb/gemrb/core/Projectile.h @@ -32,6 +32,7 @@ #include "ie_types.h" #include "CharAnimations.h" //contains MAX_ORIENT +#include "EffectQueue.h" #include "Map.h" #include "Palette.h" #include "PathFinder.h" @@ -67,7 +68,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 +361,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(); diff --git a/project/jni/application/gemrb/gemrb/core/ProjectileMgr.h b/project/jni/application/gemrb/gemrb/core/ProjectileMgr.h index 2233d1fc4..848e0a59b 100644 --- a/project/jni/application/gemrb/gemrb/core/ProjectileMgr.h +++ b/project/jni/application/gemrb/gemrb/core/ProjectileMgr.h @@ -29,7 +29,7 @@ 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; }; diff --git a/project/jni/application/gemrb/gemrb/core/ProjectileServer.cpp b/project/jni/application/gemrb/gemrb/core/ProjectileServer.cpp index c3a2e807f..c08349578 100644 --- a/project/jni/application/gemrb/gemrb/core/ProjectileServer.cpp +++ b/project/jni/application/gemrb/gemrb/core/ProjectileServer.cpp @@ -22,6 +22,7 @@ #include "GameData.h" #include "Interface.h" +#include "PluginMgr.h" #include "ProjectileMgr.h" #include "SymbolMgr.h" @@ -121,7 +122,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(); @@ -238,8 +239,7 @@ void ProjectileServer::AddSymbols(Holder 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); } diff --git a/project/jni/application/gemrb/gemrb/core/ProjectileServer.h b/project/jni/application/gemrb/gemrb/core/ProjectileServer.h index d53f99c12..23212de3c 100644 --- a/project/jni/application/gemrb/gemrb/core/ProjectileServer.h +++ b/project/jni/application/gemrb/gemrb/core/ProjectileServer.h @@ -23,7 +23,6 @@ #include "exports.h" -#include "PluginMgr.h" #include "Projectile.h" class SymbolMgr; diff --git a/project/jni/application/gemrb/gemrb/core/Region.cpp b/project/jni/application/gemrb/gemrb/core/Region.cpp index 0ab46be6b..6bf88e391 100644 --- a/project/jni/application/gemrb/gemrb/core/Region.cpp +++ b/project/jni/application/gemrb/gemrb/core/Region.cpp @@ -27,25 +27,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 +94,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 )) { diff --git a/project/jni/application/gemrb/gemrb/core/Region.h b/project/jni/application/gemrb/gemrb/core/Region.h index 675663b00..759aa8de0 100644 --- a/project/jni/application/gemrb/gemrb/core/Region.h +++ b/project/jni/application/gemrb/gemrb/core/Region.h @@ -39,11 +39,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 +73,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); diff --git a/project/jni/application/gemrb/gemrb/core/ResourceManager.cpp b/project/jni/application/gemrb/gemrb/core/ResourceManager.cpp index 95c131e58..47aa5277b 100644 --- a/project/jni/application/gemrb/gemrb/core/ResourceManager.cpp +++ b/project/jni/application/gemrb/gemrb/core/ResourceManager.cpp @@ -59,7 +59,7 @@ static void PrintPossibleFiles(const char* ResRef, const TypeID *type) { const std::vector& types = PluginMgr::Get()->GetResourceDesc(type); for (size_t j = 0; j < types.size(); j++) { - printf("%s%s ", ResRef, types[j].GetExt()); + print("%s.%s ", ResRef, types[j].GetExt()); } } @@ -74,8 +74,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 ) ); + printMessage("ResourceManager", "Searching for %s.%s...", WHITE, + ResRef, core->TypeExt(type)); printStatus( "NOT FOUND", YELLOW ); } return false; @@ -95,9 +95,8 @@ bool ResourceManager::Exists(const char *ResRef, const TypeID *type, bool silent } } if (!silent) { - printMessage( "ResourceManager", "Searching for ", WHITE ); - printf( "%s... ", ResRef ); - printf("Tried "); + printMessage("ResourceManager", "Searching for %s... ", WHITE, ResRef); + print("Tried "); PrintPossibleFiles(ResRef,type); printStatus( "NOT FOUND", YELLOW ); } @@ -109,8 +108,8 @@ 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 ) ); + printMessage("ResourceManager", "Searching for %s.%s...", WHITE, + ResRef, core->TypeExt(type)); } for (size_t i = 0; i < searchPath.size(); i++) { DataStream *ds = searchPath[i]->GetResource(ResRef, type); @@ -132,8 +131,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 ); + printMessage("ResourceManager", "Searching for %s... ", WHITE, ResRef); } const std::vector &types = PluginMgr::Get()->GetResourceDesc(type); for (size_t j = 0; j < types.size(); j++) { @@ -143,7 +141,7 @@ 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() ); + print( "%s.%s...", ResRef, types[j].GetExt() ); printStatus( searchPath[i]->GetDescription(), GREEN ); } return res; @@ -152,7 +150,7 @@ Resource* ResourceManager::GetResource(const char* ResRef, const TypeID *type, b } } if (!silent) { - printf("Tried "); + print("Tried "); PrintPossibleFiles(ResRef,type); printStatus( "ERROR", LIGHT_RED ); } diff --git a/project/jni/application/gemrb/gemrb/core/SaveGame.h b/project/jni/application/gemrb/gemrb/core/SaveGame.h index ce7460d0d..b92190338 100644 --- a/project/jni/application/gemrb/gemrb/core/SaveGame.h +++ b/project/jni/application/gemrb/gemrb/core/SaveGame.h @@ -25,9 +25,10 @@ #include "Holder.h" #include "ResourceManager.h" -#include "System/FileStream.h" +#include "System/VFS.h" class ImageMgr; +class Sprite2D; class GEM_EXPORT SaveGame : public Held { public: diff --git a/project/jni/application/gemrb/gemrb/core/SaveGameIterator.cpp b/project/jni/application/gemrb/gemrb/core/SaveGameIterator.cpp index ced734a6b..f2406c6c9 100644 --- a/project/jni/application/gemrb/gemrb/core/SaveGameIterator.cpp +++ b/project/jni/application/gemrb/gemrb/core/SaveGameIterator.cpp @@ -29,9 +29,14 @@ #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__) #include @@ -227,8 +232,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 ); + printMessage("SaveGameIterator", "Invalid savegame directory '%s' in %s.\n", LIGHT_RED, + slotname, Path); return false; } @@ -240,23 +245,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); + printMessage("SaveGameIterator", "Ignoring slot %s because of no appropriate preview!\n", YELLOW, 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); + printMessage("SaveGameIterator", "Ignoring slot %s because of no appropriate worldmap!\n", YELLOW, 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); + printMessage("SaveGameIterator", "Ignoring slot %s because of no appropriate worldmap!\n", YELLOW, dtmp); return false; } */ @@ -275,8 +277,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 (!MakeDirectory(Path)) { + printMessage("SaveGameIterator", "Unable to create save game directory '%s'", RED, Path); + return false; + } dir.Rewind(); } if (!dir) { //If we cannot open the Directory @@ -334,7 +338,7 @@ Holder 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 ); + print( "Invalid savegame directory '%s' in %s.\n", slotname, Path ); return NULL; } @@ -405,6 +409,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)) { @@ -448,7 +454,7 @@ 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(); @@ -502,13 +508,16 @@ int CanSave() 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)) { + printMessage("SaveGameIterator", "Unable to create save game directory '%s'", RED, Path); + return false; + } //keep the first part we already determined existing char dir[_MAX_PATH]; @@ -516,8 +525,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)) { + printMessage("SaveGameIterator", "Unable to create save game directory '%s'", RED, Path); + return false; + } + return true; } int SaveGameIterator::CreateSaveGame(int index, bool mqs) @@ -548,9 +560,16 @@ 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, 0xbcefbc); + if (gc) { + gc->SetDisplayText(STR_CANTSAVE, 30); + } + return -1; + } + if (!DoSaveGame(Path)) { displaymsg->DisplayConstantString(STR_CANTSAVE, 0xbcefbc); if (gc) { @@ -605,7 +624,13 @@ int SaveGameIterator::CreateSaveGame(Holder save, const char *slotname } char Path[_MAX_PATH]; - CreateSavePath(Path, index, slotname); + if (!CreateSavePath(Path, index, slotname)) { + displaymsg->DisplayConstantString(STR_CANTSAVE, 0xbcefbc); + if (gc) { + gc->SetDisplayText(STR_CANTSAVE, 30); + } + return -1; + } if (!DoSaveGame(Path)) { displaymsg->DisplayConstantString(STR_CANTSAVE, 0xbcefbc); diff --git a/project/jni/application/gemrb/gemrb/core/SaveGameMgr.h b/project/jni/application/gemrb/gemrb/core/SaveGameMgr.h index 20cb91124..b0e2894a6 100644 --- a/project/jni/application/gemrb/gemrb/core/SaveGameMgr.h +++ b/project/jni/application/gemrb/gemrb/core/SaveGameMgr.h @@ -28,7 +28,7 @@ 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; diff --git a/project/jni/application/gemrb/gemrb/core/ScriptEngine.h b/project/jni/application/gemrb/gemrb/core/ScriptEngine.h index 94ec6b64f..44dabd5e7 100644 --- a/project/jni/application/gemrb/gemrb/core/ScriptEngine.h +++ b/project/jni/application/gemrb/gemrb/core/ScriptEngine.h @@ -32,7 +32,7 @@ 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; /** Exec a single String */ virtual void ExecString(const char* string) = 0; }; diff --git a/project/jni/application/gemrb/gemrb/core/Scriptable/Actor.cpp b/project/jni/application/gemrb/gemrb/core/Scriptable/Actor.cpp index 61f8a9a19..afd5c1e1d 100644 --- a/project/jni/application/gemrb/gemrb/core/Scriptable/Actor.cpp +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/Actor.cpp @@ -31,10 +31,14 @@ #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,6 +46,7 @@ #include "ProjectileServer.h" #include "ScriptEngine.h" #include "Spell.h" +#include "Sprite2D.h" #include "TableMgr.h" #include "Video.h" #include "damages.h" @@ -333,22 +338,10 @@ Actor::Actor() LongStrRef = (ieStrRef) -1; ShortStrRef = (ieStrRef) -1; - LastProtected = 0; - LastFollowed = 0; - LastCommander = 0; - LastHelp = 0; - LastSeen = 0; - LastMarked = 0; - LastMarkedSpell = 0; - LastHeard = 0; PCStats = NULL; - LastCommand = 0; //used by order - LastShout = 0; //used by heard - LastDamage = 0; + //LastDamage = 0; LastDamageType = 0; - LastTurner = 0; LastExit = 0; - HotKey = 0; attackcount = 0; secondround = 0; attacksperround = 0; @@ -510,8 +503,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); + printMessage("Actor", "Animation ID %x is supposed to be real colored (no recoloring), patched creature\n", YELLOW, AnimID); } BaseStats[IE_COLORCOUNT]=0; } @@ -520,8 +512,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); + printMessage("Actor", "Missing animation for %s\n", LIGHT_RED, LongName); return; } anims->SetOffhandRef(ShieldRef); @@ -552,8 +543,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); + printMessage("Actor", "Unable to determine movement rate for animation %04x!\n", YELLOW, AnimID); } } @@ -616,6 +606,7 @@ void Actor::SetCircleSize() case EA_ENEMY: case EA_GOODBUTRED: case EA_EVILCUTOFF: + case EA_CHARMEDPC: color = &red; color_index = 1; break; @@ -1649,7 +1640,7 @@ static void InitActorTables() if (tm && !core->HasFeature(GF_LEVELSLOT_PER_CLASS)) { AutoTable hptm; //iwd2 just uses levelslotsiwd2 instead - printf("Examining classes.2da\n"); + print("Examining classes.2da\n"); //when searching the levelslots, you must search for //levelslots[BaseStats[IE_CLASS]-1] as there is no class id of 0 @@ -1664,16 +1655,16 @@ static void InitActorTables() continue; tmpindex--; - printf("\tID: %d ", tmpindex); + print("\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"); + print ("Already Found!\n"); continue; } const char* classname = tm->GetRowName(i); - printf("Name: %s ", classname); + print("Name: %s ", classname); int classis = 0; //default all levelslots to 0 levelslots[tmpindex] = (int *) calloc(ISCLASSES, sizeof(int)); @@ -1683,7 +1674,7 @@ static void InitActorTables() if (!tmpclass) { classis = IsClassFromName(classname); if (classis>=0) { - printf("Classis: %d ", classis); + print("Classis: %d ", classis); levelslots[tmpindex][classis] = IE_LEVEL; //get the max hp con bonus hptm.load(tm->QueryField(i, 6)); @@ -1692,7 +1683,7 @@ static void InitActorTables() int rollscolumn = hptm->GetColumnIndex("ROLLS"); while (atoi(hptm->QueryField(tmphp, rollscolumn))) tmphp++; - printf("TmpHP: %d ", tmphp); + print("TmpHP: %d ", tmphp); if (tmphp) maxhpconbon[tmpindex] = tmphp; } } @@ -1732,7 +1723,7 @@ static void InitActorTables() levelslots[tmpindex][classis] = tmplevel; } } - printf("Classis: %d ", classis); + print("Classis: %d ", classis); //warrior take presedence if (!foundwarrior) { @@ -1771,8 +1762,8 @@ static void InitActorTables() free(classnames); classnames = NULL; } - printf("HPCON: %d ", maxhpconbon[tmpindex]); - printf("DS: %d\n", dualswap[tmpindex]); + print("HPCON: %d ", maxhpconbon[tmpindex]); + print("DS: %d\n", dualswap[tmpindex]); } /*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 +1773,7 @@ static void InitActorTables() } }*/ } - printf("Finished examining classes.2da\n"); + print("Finished examining classes.2da\n"); //pre-cache hit/damage/speed bonuses for weapons tm.load("wspecial"); @@ -1921,20 +1912,20 @@ 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"); + 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)); + } + } + } } void Actor::SetLockedPalette(const ieDword *gradients) @@ -1973,7 +1964,7 @@ void Actor::PlayDamageAnimation(int type, bool hit) { int i; - printf("Damage animation type: %d\n", type); + print("Damage animation type: %d\n", type); switch(type) { case 0: case 1: case 2: case 3: //blood @@ -2246,8 +2237,12 @@ void Actor::RefreshEffects(EffectQueue *fx) //move this further down if needed PrevStats = NULL; + for (std::list::iterator m = triggers.begin(); m != triggers.end (); m++) { + m->flags |= TEF_PROCESSED_EFFECTS; + } + // 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;iType==ST_ACTOR) { + AddTrigger(TriggerEntry(trigger_hitby, hitter->GetGlobalID())); LastHitter=hitter->GetGlobalID(); } else { //Maybe it should be something impossible like 0xffff, and use 'Someone' @@ -2719,6 +2718,12 @@ int Actor::Damage(int damage, int damagetype, Scriptable *hitter, int modtype) DisplayCombatFeedback(damage, resisted, damagetype, hitter); + // instant chunky death if the actor is petrified or frozen + if (Modified[IE_STATE_ID] & (STATE_FROZEN|STATE_PETRIFIED) && !Modified[IE_DISABLECHUNKING]) { + 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) { @@ -2749,6 +2754,7 @@ int Actor::Damage(int damage, int damagetype, Scriptable *hitter, int modtype) if (Modified[IE_CLASS] == CLASS_INNOCENT) { Actor *act=NULL; if (!hitter) { + // TODO: check this hitter = area->GetActorByGlobalID(LastHitter); } @@ -2764,10 +2770,10 @@ int Actor::Damage(int damage, int damagetype, Scriptable *hitter, int modtype) } } - LastDamage=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 { @@ -2820,8 +2826,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); + printMessage("Actor", "%d damage taken.\n", GREEN, damage); if (detailed) { // 3 choices depending on resistance and boni @@ -2846,7 +2851,7 @@ void Actor::DisplayCombatFeedback (unsigned int damage, int resisted, int damage displaymsg->DisplayConstantStringName(STR_DAMAGE1, 0xffffff, this); } } else if (core->HasFeature(GF_ONSCREEN_TEXT) ) { - if(0) printf("TODO: pst floating text\n"); + if(0) print("TODO: pst floating text\n"); } else if (!displaymsg->HasStringReference(STR_DAMAGE2) || !hitter || hitter->Type != ST_ACTOR) { // bg1 and iwd // or any traps or self-infliction (also for bg1) @@ -2865,8 +2870,7 @@ void Actor::DisplayCombatFeedback (unsigned int damage, int resisted, int damage } } else { if (resisted == DR_IMMUNE) { - printMessage("Actor", " ", GREEN); - printf("is immune to damage type: %s.\n", type_name); + printMessage("Actor", "is immune to damage type: %s.\n", GREEN, type_name); if (hitter && hitter->Type == ST_ACTOR) { if (detailed) { // was immune to my damage @@ -2897,13 +2901,13 @@ void Actor::PlayWalkSound() ieDword thisTime; ieResRef Sound; - GetTime(thisTime); + thisTime = GetTickCount(); if (thisTimeGetWalkSoundCount(); 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); @@ -2954,7 +2958,7 @@ void Actor::DumpMaxValues() SymbolMgr *sym = core->GetSymbol( symbol ); for(int i=0;iGetValue(i), maximum_values[i]); + print("%d (%s) %d\n", i, sym->GetValue(i), maximum_values[i]); } } #endif @@ -2963,46 +2967,46 @@ void Actor::DebugDump() { unsigned int i; - printf( "Debugdump of Actor %s (%s, %s):\n", LongName, ShortName, GetName(-1) ); - printf ("Scripts:"); + print( "Debugdump of Actor %s (%s, %s):\n", LongName, ShortName, GetName(-1) ); + print ("Scripts:"); for (i = 0; i < MAX_SCRIPTS; i++) { const char* poi = ""; if (Scripts[i]) { poi = Scripts[i]->GetName(); } - printf( " %.8s", poi ); + print( " %.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: "); + print( "\nArea: %.8s ", Area ); + print( "Dialog: %.8s\n", Dialog ); + print( "Global ID: %d PartySlot: %d\n", GetGlobalID(), InParty); + print( "Script name:%.32s Current action: %d\n", scriptName, CurrentAction ? CurrentAction->actionID : -1); + print( "TalkCount: %d ", TalkCount ); + print( "Allegiance: %d current allegiance:%d\n", BaseStats[IE_EA], Modified[IE_EA] ); + print( "Class: %d current class:%d\n", BaseStats[IE_CLASS], Modified[IE_CLASS] ); + print( "Race: %d current race:%d\n", BaseStats[IE_RACE], Modified[IE_RACE] ); + print( "Gender: %d current gender:%d\n", BaseStats[IE_SEX], Modified[IE_SEX] ); + print( "Specifics: %d current specifics:%d\n", BaseStats[IE_SPECIFIC], Modified[IE_SPECIFIC] ); + print( "Alignment: %x current alignment:%x\n", BaseStats[IE_ALIGNMENT], Modified[IE_ALIGNMENT] ); + print( "Morale: %d current morale:%d\n", BaseStats[IE_MORALE], Modified[IE_MORALE] ); + print( "Moralebreak:%d Morale recovery:%d\n", Modified[IE_MORALEBREAK], Modified[IE_MORALERECOVERYTIME] ); + print( "Visualrange:%d (Explorer: %d)\n", Modified[IE_VISUALRANGE], Modified[IE_EXPLORE] ); + print( "Levels: %d/%d/%d (average %d)\n", Modified[IE_LEVEL], Modified[IE_LEVEL2], Modified[IE_LEVEL3], GetXPLevel(true) ); + print( "current HP:%d\n", BaseStats[IE_HITPOINTS] ); + print( "Mod[IE_ANIMATION_ID]: 0x%04X\n", Modified[IE_ANIMATION_ID] ); + print( "Colors: "); if (core->HasFeature(GF_ONE_BYTE_ANIMID) ) { for(i=0;iGetGlobalID(); + 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!\n"); Panic(cleric, PANIC_RUNAWAY); } } @@ -3246,7 +3250,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 +3271,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!\n"); Panic(cleric, PANIC_RUNAWAY); } } @@ -3349,13 +3353,15 @@ 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 ); + AddTrigger(TriggerEntry(trigger_die)); Actor *act=NULL; if (!killer) { + // TODO: is this right? killer = area->GetActorByGlobalID(LastHitter); } @@ -3549,10 +3555,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; @@ -3795,9 +3800,11 @@ void Actor::InitStatsOnLoad() } inventory.CalculateWeight(); CreateDerivedStats(); - Modified[IE_CON]=BaseStats[IE_CON]; // used by GetHpAdjustment - ieDword hp = BaseStats[IE_HITPOINTS] + GetHpAdjustment(GetXPLevel(false)); - BaseStats[IE_HITPOINTS]=hp; + if (BaseStats[IE_CLASS] > 0 && BaseStats[IE_CLASS] <= (ieDword)classcount) { + 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)); @@ -3847,7 +3854,7 @@ bool Actor::ValidTarget(int ga_flags) const 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) { @@ -3877,7 +3884,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\n", NewAnimID); SetBase( IE_ANIMATION_ID, NewAnimID); } @@ -3887,7 +3894,7 @@ void Actor::GetPrevAnimation() if (RowNum>=CharAnimations::GetAvatarsCount() ) RowNum = 0; int NewAnimID = CharAnimations::GetAvatarStruct(RowNum)->AnimID; - printf ("AnimID: %04X\n", NewAnimID); + print ("AnimID: %04X\n", NewAnimID); SetBase( IE_ANIMATION_ID, NewAnimID); } @@ -3995,7 +4002,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\n", Stance); SetStance( Stance ); } @@ -4165,6 +4172,7 @@ int Actor::GetAttackStyle() const void Actor::AttackedBy( Actor *attacker) { + AddTrigger(TriggerEntry(trigger_attackedby, attacker->GetGlobalID())); LastAttacker = attacker->GetGlobalID(); } @@ -4183,7 +4191,7 @@ void Actor::StopAttack() { SetStance(IE_ANI_READY); secondround = 0; - InternalFlags|=IF_TARGETGONE; //this is for the trigger! + //InternalFlags|=IF_TARGETGONE; //this is for the trigger! if (InParty) { core->Autopause(AP_NOTARGET); } @@ -4200,6 +4208,10 @@ 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; } @@ -4238,8 +4250,8 @@ 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); + printMessage("InitRound", "Name: %s | Attacks: %d | Start: %d\n", WHITE, + ShortName, attacksperround, gameTime); // this might not be the right place, but let's give it a go if (attacksperround && InParty) { @@ -4568,7 +4580,7 @@ void Actor::PerformAttack(ieDword gameTime) return; } - printf("Performattack for %s, target is: %s\n", ShortName, target->ShortName); + print("Performattack for %s, target is: %s\n", ShortName, target->ShortName); //which hand is used //we do apr - attacksleft so we always use the main hand first @@ -4629,15 +4641,15 @@ void Actor::PerformAttack(ieDword gameTime) printMessage("Attack","(Main) ", GREEN); } if (attacksperround) { - printf("Left: %d | ", attackcount); - printf("Next: %d ", nextattack); + print("Left: %d | ", attackcount); + print("Next: %d ", nextattack); } int roll = LuckyRoll(1, ATTACKROLL, 0); if (roll==1) { //critical failure printBracket("Critical Miss", RED); - printf("\n"); + print("\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! @@ -4662,16 +4674,16 @@ void Actor::PerformAttack(ieDword gameTime) 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); + print("| Damage %dd%d%+d = %d ",hittingheader->DiceThrown, hittingheader->DiceSides, DamageBonus, damage); } else { - printf("| No Damage"); + print("| No Damage"); damage = 0; } if (roll >= (ATTACKROLL - (int) GetStat(IE_CRITICALHITBONUS) - CriticalBonus)) { //critical success printBracket("Critical Hit", GREEN); - printf("\n"); + print("\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); @@ -4699,11 +4711,11 @@ void Actor::PerformAttack(ieDword gameTime) } ResetState(); printBracket("Missed", LIGHT_RED); - printf("\n"); + print("\n"); return; } printBracket("Hit", GREEN); - printf("\n"); + print("\n"); ModifyDamage (target, this, damage, resisted, weapon_damagetype[damagetype], &wi, false); UseItem(wi.slot, Flags&WEAPON_RANGED?-2:-1, target, 0, damage); ResetState(); @@ -4789,7 +4801,7 @@ void Actor::ModifyDamage(Actor *target, Scriptable *hitter, int &damage, int &re std::multimap::iterator it; it = core->DamageInfoMap.find(damagetype); if (it == core->DamageInfoMap.end()) { - printf("Unhandled damagetype:%d\n", damagetype); + print("Unhandled damagetype:%d\n", damagetype); } else if (it->second.resist_stat == 0) { // damage type without a resistance stat } else { @@ -4800,11 +4812,11 @@ void Actor::ModifyDamage(Actor *target, Scriptable *hitter, int &damage, int &re int bonus = ((Actor *)hitter)->fxqueue.SpecificDamageBonus(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); + print("Bonus damage of %d (%+d%%), neto: %d\n", int (damage * bonus / 100.0), bonus, -resisted); } } damage -= resisted; - printf("Resisted %d of %d at %d%% resistance to %d\n", resisted, damage+resisted, target->GetSafeStat(it->second.resist_stat), damagetype); + print("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; } } @@ -4867,9 +4879,6 @@ 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; - // handle lingering modal spells like bardsong in iwd2 if (modalSpellLingering && LingeringModalSpell[0]) { modalSpellLingering--; @@ -4883,6 +4892,16 @@ 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 + ieDword state = Modified[IE_STATE_ID]; + 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); ModalSpell[0]='*'; @@ -5111,6 +5130,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); @@ -5133,10 +5159,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); } @@ -5155,7 +5177,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; @@ -5617,12 +5639,11 @@ void Actor::GetSoundFrom2DA(ieResRef Sound, unsigned int index) const index = 36; break; default: - printMessage("Actor","TODO:", YELLOW); - printf("Cannot determine 2DA rowcount for index: %d\n", index); + printMessage("Actor", "TODO:Cannot determine 2DA rowcount for index: %d\n", YELLOW, index); return; } - printMessage("Actor"," ", WHITE); - printf("Getting sound 2da %.8s entry: %s\n", anims->ResRef, tab->GetRowName(index) ); + printMessage("Actor", "Getting sound 2da %.8s entry: %s\n", WHITE, + anims->ResRef, tab->GetRowName(index) ); int col = core->Roll(1,tab->GetColumnCount(index),-1); strnlwrcpy(Sound, tab->QueryField (index, col), 8); } @@ -5758,7 +5779,7 @@ 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")) { file[5] = '\0'; @@ -6320,7 +6341,7 @@ int Actor::CheckUsability(Item *item) const } stat = ResolveTableValue(itemuse[i].table, stat, mcol, itemuse[i].vcol); 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\n", itemvalue, itemuse[i].stat, stat); return STR_CANNOT_USE_ITEM; } } @@ -6540,7 +6561,7 @@ void Actor::CreateDerivedStatsBG() } else { backstabdamagemultiplier = (backstabdamagemultiplier+7)/4; } - printf("\n"); + print("\n"); if (backstabdamagemultiplier>7) backstabdamagemultiplier=7; } } @@ -6576,7 +6597,7 @@ void Actor::CreateDerivedStatsIWD2() } else { backstabdamagemultiplier = (BaseStats[IE_LEVELTHIEF]+1)/2; } - printf("\n"); + print("\n"); if (backstabdamagemultiplier>7) backstabdamagemultiplier=7; } @@ -6878,7 +6899,7 @@ void Actor::CureInvisibility() //not sure, but better than nothing if (! (Modified[IE_STATE_ID]&state_invisible)) { - InternalFlags|=IF_BECAMEVISIBLE; + AddTrigger(TriggerEntry(trigger_becamevisible)); } } } diff --git a/project/jni/application/gemrb/gemrb/core/Scriptable/Actor.h b/project/jni/application/gemrb/gemrb/core/Scriptable/Actor.h index 5b54b5bf1..32bde7ca1 100644 --- a/project/jni/application/gemrb/gemrb/core/Scriptable/Actor.h +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/Actor.h @@ -28,15 +28,16 @@ #include "exports.h" #include "ie_types.h" -#include "Animation.h" #include "Audio.h" -#include "CharAnimations.h" #include "EffectQueue.h" -#include "ScriptedAnimation.h" +#include "Palette.h" #include #include +class Animation; +class CharAnimations; +class DataFileMgr; class Map; class ScriptedAnimation; struct PolymorphCache; @@ -275,25 +276,6 @@ public: ieDword ModalState; int PathTries; //the # of previous tries to pick up a new walkpath 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 char ShieldRef[2]; char HelmetRef[2]; @@ -303,11 +285,7 @@ public: bool GotLUFeedback; int WMLevelMod; - int LastCommand; //lastcommander - int LastShout; //lastheard - int LastDamage; //lasthitter - int LastDamageType;//lasthitter - ieDword LastTurner; + int LastDamageType; Point FollowOffset;//follow lastfollowed at this offset Point HomeLocation;//spawnpoint, return here after rest diff --git a/project/jni/application/gemrb/gemrb/core/Scriptable/Container.cpp b/project/jni/application/gemrb/gemrb/core/Scriptable/Container.cpp index e2f675774..f547a5d46 100644 --- a/project/jni/application/gemrb/gemrb/core/Scriptable/Container.cpp +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/Container.cpp @@ -31,6 +31,7 @@ #include "Map.h" #include "Projectile.h" #include "Spell.h" +#include "Sprite2D.h" #include "SpriteCover.h" #include "TileMap.h" #include "Video.h" @@ -196,6 +197,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 ); @@ -224,6 +226,7 @@ int Container::IsOpen() const void Container::TryPickLock(Actor *actor) { + core->PlaySound(DS_PICKLOCK); if (LockDifficulty == 100) { if (OpenFail != (ieDword)-1) { displaymsg->DisplayStringName(OpenFail, 0xbcefbc, actor, IE_STR_SOUND|IE_STR_SPEECH); @@ -234,12 +237,12 @@ void Container::TryPickLock(Actor *actor) } if (actor->GetStat(IE_LOCKPICKING)DisplayConstantStringName(STR_LOCKPICK_FAILED, 0xbcefbc, actor); - LastPickLockFailed = actor->GetGlobalID(); + AddTrigger(TriggerEntry(trigger_picklockfailed, actor->GetGlobalID())); return; } SetContainerLocked(false); displaymsg->DisplayConstantStringName(STR_LOCKPICK_DONE, 0xd7d7be, actor); - LastUnlocked = actor->GetGlobalID(); + AddTrigger(TriggerEntry(trigger_unlocked, actor->GetGlobalID())); ImmediateEvent(); int xp = actor->CalculateExperience(XP_LOCKPICK, actor->GetXPLevel(1)); Game *game = core->GetGame(); @@ -262,24 +265,24 @@ void Container::TryBashLock(Actor *actor) displaymsg->DisplayConstantStringName(STR_CONTBASH_DONE, 0xd7d7be, actor); SetContainerLocked(false); //Is this really useful ? - LastUnlocked = actor->GetGlobalID(); + AddTrigger(TriggerEntry(trigger_unlocked, actor->GetGlobalID())); ImmediateEvent(); } void Container::DebugDump() 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, + print( "Debugdump of Container %s\n", GetScriptName() ); + print( "Container Global ID: %d\n", GetGlobalID()); + print( "Position: %d.%d\n", Pos.x, Pos.y); + print( "Type: %d, Locked: %s, LockDifficulty: %d\n", Type, YESNO(Flags&CONT_LOCKED), LockDifficulty ); + print( "Flags: %d, Trapped: %s, Detected: %d\n", Flags, YESNO(Trapped), TrapDetected ); + print( "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 ); + print( "Script: %s, Key: %s\n", name, KeyResRef ); // FIXME: const_cast const_cast(inventory).dump(); } diff --git a/project/jni/application/gemrb/gemrb/core/Scriptable/Container.h b/project/jni/application/gemrb/gemrb/core/Scriptable/Container.h index 39fd7bb01..c581bfd30 100644 --- a/project/jni/application/gemrb/gemrb/core/Scriptable/Container.h +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/Container.h @@ -21,6 +21,7 @@ #ifndef CONTAINER_H #define CONTAINER_H +#include "Inventory.h" #include "Scriptable.h" //container flags diff --git a/project/jni/application/gemrb/gemrb/core/Scriptable/Door.cpp b/project/jni/application/gemrb/gemrb/core/Scriptable/Door.cpp index 33df7bdaf..18118d59c 100644 --- a/project/jni/application/gemrb/gemrb/core/Scriptable/Door.cpp +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/Door.cpp @@ -105,23 +105,23 @@ 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; + 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 +252,14 @@ void Door::SetDoorOpen(int Open, int playsound, ieDword ID) area->JumpActors(true); } if (Open) { - LastEntered = ID; //used as lastOpener + AddTrigger(TriggerEntry(trigger_opened, 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 + AddTrigger(TriggerEntry(trigger_closed, ID)); } ToggleTiles(Open, playsound); //synchronising other data with the door state @@ -325,11 +325,10 @@ void Highlightable::TryDisarm(Actor *actor) { if (!Trapped || !TrapDetected) return; - LastTriggerObject = LastTrigger = actor->GetGlobalID(); int skill = actor->GetStat(IE_TRAPS); if (skill/2+core->Roll(1,skill/2,0)>TrapRemovalDiff) { - LastDisarmed = actor->GetGlobalID(); + AddTrigger(TriggerEntry(trigger_disarmed, actor->GetGlobalID())); //trap removed Trapped = 0; displaymsg->DisplayConstantStringName(STR_DISARM_DONE, 0xd7d7be, actor); @@ -338,13 +337,14 @@ void Highlightable::TryDisarm(Actor *actor) game->ShareXP(xp, SX_DIVIDE); } else { displaymsg->DisplayConstantStringName(STR_DISARM_FAIL, 0xd7d7be, actor); - TriggerTrap(skill, LastTrigger); + TriggerTrap(skill, actor->GetGlobalID()); } ImmediateEvent(); } void Door::TryPickLock(Actor *actor) { + core->PlaySound(DS_PICKLOCK); if (LockDifficulty == 100) { if (OpenStrRef != (ieDword)-1) { displaymsg->DisplayStringName(OpenStrRef, 0xbcefbc, actor, IE_STR_SOUND|IE_STR_SPEECH); @@ -355,12 +355,12 @@ void Door::TryPickLock(Actor *actor) } if (actor->GetStat(IE_LOCKPICKING)DisplayConstantStringName(STR_LOCKPICK_FAILED, 0xbcefbc, actor); - LastPickLockFailed = actor->GetGlobalID(); + AddTrigger(TriggerEntry(trigger_picklockfailed, actor->GetGlobalID())); return; } SetDoorLocked( false, true); displaymsg->DisplayConstantStringName(STR_LOCKPICK_DONE, 0xd7d7be, actor); - LastUnlocked = actor->GetGlobalID(); + AddTrigger(TriggerEntry(trigger_unlocked, actor->GetGlobalID())); ImmediateEvent(); int xp = actor->CalculateExperience(XP_LOCKPICK, actor->GetXPLevel(1)); Game *game = core->GetGame(); @@ -383,27 +383,27 @@ void Door::TryBashLock(Actor *actor) displaymsg->DisplayConstantStringName(STR_DOORBASH_DONE, 0xd7d7be, actor); SetDoorLocked(false, true); //Is this really useful ? - LastUnlocked = actor->GetGlobalID(); + AddTrigger(TriggerEntry(trigger_unlocked, actor->GetGlobalID())); ImmediateEvent(); } void Door::DebugDump() 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)); + print( "Debugdump of Door %s:\n", GetScriptName() ); + print( "Door Global ID: %d\n", GetGlobalID()); + print( "Position: %d.%d\n", Pos.x, Pos.y); + print( "Door Open: %s\n", YESNO(IsOpen())); + print( "Door Locked: %s\n", YESNO(Flags&DOOR_LOCKED)); + print( "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) ); + print( "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)); + print( "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 ); + print( "Script: %s, Key (%s) removed: %s, Dialog: %s\n", name, Key?Key:"NONE", YESNO(Flags&DOOR_KEY), Dialog ); } diff --git a/project/jni/application/gemrb/gemrb/core/Scriptable/Door.h b/project/jni/application/gemrb/gemrb/core/Scriptable/Door.h index 5d6e4db82..c0c51b69a 100644 --- a/project/jni/application/gemrb/gemrb/core/Scriptable/Door.h +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/Door.h @@ -23,6 +23,8 @@ #include "Scriptable.h" +class TileOverlay; + //door flags #define DOOR_OPEN 1 #define DOOR_LOCKED 2 diff --git a/project/jni/application/gemrb/gemrb/core/Scriptable/InfoPoint.cpp b/project/jni/application/gemrb/gemrb/core/Scriptable/InfoPoint.cpp index 0199bc7d0..832f672ff 100644 --- a/project/jni/application/gemrb/gemrb/core/Scriptable/InfoPoint.cpp +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/InfoPoint.cpp @@ -36,6 +36,7 @@ #include "Video.h" #include "GameScript/GSUtils.h" #include "GUI/GameControl.h" +#include "GUI/Window.h" #include #include @@ -52,7 +53,6 @@ InfoPoint::InfoPoint(void) TrapRemovalDiff = 0; TrapDetected = 0; TrapLaunch.empty(); - EnterWav[0] = 0; } InfoPoint::~InfoPoint(void) @@ -88,23 +88,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 { @@ -141,24 +124,6 @@ bool Highlightable::VisibleTrap(int see_all) const return false; } -//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) { @@ -170,7 +135,8 @@ 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_entered, ID)); return true; } else if (Highlightable::TriggerTrap(skill, ID)) { if (!Trapped) { @@ -234,31 +200,31 @@ void InfoPoint::DebugDump() const { switch (Type) { case ST_TRIGGER: - printf( "Debugdump of InfoPoint Region %s:\n", GetScriptName() ); + print( "Debugdump of InfoPoint Region %s:\n", GetScriptName() ); break; case ST_PROXIMITY: - printf( "Debugdump of Trap Region %s:\n", GetScriptName() ); + print( "Debugdump of Trap Region %s:\n", GetScriptName() ); break; case ST_TRAVEL: - printf( "Debugdump of Travel Region %s:\n", GetScriptName() ); + print( "Debugdump of Travel Region %s:\n", GetScriptName() ); break; default: - printf( "Debugdump of Unsupported Region %s:\n", GetScriptName() ); + print( "Debugdump of Unsupported Region %s:\n", GetScriptName() ); break; } - printf( "Region Global ID: %d\n", GetGlobalID()); - printf( "Position: %d.%d\n", Pos.x, Pos.y); + print( "Region Global ID: %d\n", GetGlobalID()); + print( "Position: %d.%d\n", Pos.x, Pos.y); switch(Type) { case ST_TRAVEL: - printf( "Destination Area: %s Entrance: %s\n", Destination, EntranceName); + print( "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, + print( "TrapDetected: %d, Trapped: %s\n", TrapDetected, YESNO(Trapped)); + print( "Trap detection: %d%%, Trap removal: %d%%\n", TrapDetectionDiff, TrapRemovalDiff ); break; case ST_TRIGGER: - printf ( "InfoString: %s\n", overHeadText ); + print ( "InfoString: %s\n", overHeadText ); break; default:; } @@ -266,7 +232,8 @@ 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)); + print( "Script: %s, Key: %s, Dialog: %s\n", name, KeyResRef, Dialog ); + print( "Deactivated: %s\n", YESNO(Flags&TRAP_DEACTIVATED)); + print( "Active: %s\n", YESNO(InternalFlags&IF_ACTIVE)); } diff --git a/project/jni/application/gemrb/gemrb/core/Scriptable/InfoPoint.h b/project/jni/application/gemrb/gemrb/core/Scriptable/InfoPoint.h index 0eb628278..6ef5b904a 100644 --- a/project/jni/application/gemrb/gemrb/core/Scriptable/InfoPoint.h +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/InfoPoint.h @@ -62,7 +62,6 @@ public: ieStrRef StrRef; Point UsePoint; Point TalkPos; - }; #endif diff --git a/project/jni/application/gemrb/gemrb/core/Scriptable/Scriptable.cpp b/project/jni/application/gemrb/gemrb/core/Scriptable/Scriptable.cpp index e1bd727eb..07878f6cb 100644 --- a/project/jni/application/gemrb/gemrb/core/Scriptable/Scriptable.cpp +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/Scriptable.cpp @@ -28,6 +28,7 @@ #include "GameData.h" #include "Interface.h" #include "Item.h" +#include "Font.h" #include "Map.h" #include "Projectile.h" #include "Spell.h" @@ -35,7 +36,9 @@ #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 @@ -60,49 +63,59 @@ 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; + TriggerCountdown = 0; Dialog[0] = 0; globalID = ++globalActorCounter; - interval = ( 1000 / AI_UPDATE_TIME ); WaitCounter = 0; if (Type == ST_ACTOR) { - InternalFlags = IF_VISIBLE | IF_ONCREATION | IF_USEDSAVE; + InternalFlags = IF_VISIBLE | IF_USEDSAVE; } 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; + LastTarget = 0; LastTargetPos.empty(); locals = new Variables(); locals->SetType( GEM_VARIABLES_INT ); locals->ParseKey( 1 ); InitTriggers(); + AddTrigger(TriggerEntry(trigger_oncreation)); memset( script_timers,0, sizeof(script_timers)); } @@ -157,8 +170,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 +181,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]; @@ -270,12 +281,13 @@ void Scriptable::DrawOverheadText(const Region &screen) void Scriptable::DelayedEvent() { - lastRunTime = core->GetGame()->Ticks; + // FIXME: do we need this? + // lastRunTime = core->GetGame()->Ticks; } void Scriptable::ImmediateEvent() { - lastRunTime = 0; + InternalFlags |= IF_FORCEUPDATE; } bool Scriptable::IsPC() const @@ -288,6 +300,62 @@ bool Scriptable::IsPC() const return false; } +void Scriptable::Update() +{ + Ticks++; + AdjustedTicks++; + + TickScripting(); + + ProcessActions(); +} + +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 ((actorState & STATE_DEAD) && !(InternalFlags & IF_JUSTDIED)) + 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) @@ -309,21 +377,8 @@ void Scriptable::ExecuteScript(int scriptCount) 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; - } - - lastDelay = lastRunTime; - lastRunTime = thisTime; - // 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; @@ -339,6 +394,8 @@ void Scriptable::ExecuteScript(int scriptCount) /* scripts are not concurrent, see WAITPC override script for example */ if (done) break; } + + // FIXME: completely wrong place for this! if (changed && UnselectableTimer) { UnselectableTimer--; if (!UnselectableTimer) { @@ -355,7 +412,7 @@ void Scriptable::ExecuteScript(int scriptCount) void Scriptable::AddAction(Action* aC) { if (!aC) { - printf( "[GameScript]: NULL action encountered for %s!\n",scriptName ); + print( "[GameScript]: NULL action encountered for %s!\n",scriptName ); return; } @@ -378,7 +435,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!\n",scriptName ); return; } InternalFlags|=IF_ACTIVE; @@ -433,16 +490,11 @@ 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; @@ -452,6 +504,8 @@ void Scriptable::ProcessActions(bool force) CurrentActionInterruptable = true; if (!CurrentAction) { CurrentAction = PopNextAction(); + } else { + CurrentActionTicks++; } if (!CurrentAction) { ClearActions(); @@ -472,9 +526,10 @@ void Scriptable::ProcessActions(bool force) break; } } - if (InternalFlags&IF_IDLE) { + // FIXME + /*if (InternalFlags&IF_IDLE) { Deactivate(); - } + }*/ } bool Scriptable::InMove() const @@ -498,7 +553,7 @@ unsigned long Scriptable::GetWait() const void Scriptable::LeaveDialog() { - InternalFlags |=IF_WASINDIALOG; + AddTrigger(TriggerEntry(trigger_wasindialog)); } void Scriptable::Hide() @@ -538,7 +593,8 @@ void Scriptable::Activate() void Scriptable::PartyRested() { - InternalFlags |=IF_PARTYRESTED; + //InternalFlags |=IF_PARTYRESTED; + AddTrigger(TriggerEntry(trigger_partyrested)); } ieDword Scriptable::GetInternalFlag() @@ -548,13 +604,14 @@ ieDword Scriptable::GetInternalFlag() void Scriptable::InitTriggers() { - tolist.clear(); - bittriggers = 0; + //tolist.clear(); + //bittriggers = 0; + triggers.clear(); } void Scriptable::ClearTriggers() { - for (TriggerObjects::iterator m = tolist.begin(); m != tolist.end (); m++) { + /*for (TriggerObjects::iterator m = tolist.begin(); m != tolist.end (); m++) { *(*m) = 0; } if (!bittriggers) { @@ -577,18 +634,64 @@ void Scriptable::ClearTriggers() } if (bittriggers & BT_PARTYRESTED) { InternalFlags &= ~IF_PARTYRESTED; - } + }*/ InitTriggers(); } -void Scriptable::SetBitTrigger(ieDword bittrigger) +/*void Scriptable::SetBitTrigger(ieDword bittrigger) { bittriggers |= bittrigger; +}*/ + +void Scriptable::AddTrigger(TriggerEntry trigger) +{ + triggers.push_back(trigger); + ImmediateEvent(); + + assert(trigger.triggerID < MAX_TRIGGERS); + if (triggerflags[trigger.triggerID] & TF_SAVED) + LastTrigger = trigger.param1; } -void Scriptable::AddTrigger(ieDword *actorref) -{ - tolist.push_back(actorref); +bool Scriptable::MatchTrigger(unsigned short id, ieDword param) { + for (std::list::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; +} + +bool Scriptable::MatchTriggerWithObject(unsigned short id, class Object *obj, ieDword param) { + for (std::list::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; +} + +const TriggerEntry *Scriptable::GetMatchingTrigger(unsigned short id, unsigned int notflags) { + for (std::list::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; } static EffectRef fx_set_invisible_state_ref = { "State:Invisible", -1 }; @@ -742,7 +845,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); } @@ -758,10 +861,10 @@ void Scriptable::CreateProjectile(const ieResRef SpellResRef, ieDword tgt, int l 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 (tgt) { + target = area->GetActorByGlobalID(tgt); if (!target) { - target=core->GetGame()->GetActorByGlobalID(LastTarget); + target=core->GetGame()->GetActorByGlobalID(tgt); } } if (stricmp(spell, "")) { @@ -773,22 +876,25 @@ void Scriptable::CreateProjectile(const ieResRef SpellResRef, ieDword tgt, int l displaymsg->DisplayStringName(tmp, 0xffffff, this); } - if(LastTarget) { + if (tgt) { if (target && (Type==ST_ACTOR) ) { + target->AddTrigger(TriggerEntry(trigger_spellcastonme, caster->GetGlobalID(), spellnum)); 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; + SPLExtHeader *seh = spl->GetExtHeader(SpellHeader); + if (seh) { + for (unsigned int i=0; i < seh->FeatureCount; i++) { + if (seh->features[i].Opcode == opcode) { + invis = true; + break; + } } } - if (invis && spl->GetExtHeader(SpellHeader)->Target == TARGET_SELF) { + if (invis && seh && seh->Target == TARGET_SELF) { //pass } else { caster->CureInvisibility(); @@ -1283,8 +1389,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); + printMessage("Scriptable", "Timer id %d exceeded MAX_TIMER %d\n", RED, + ID, MAX_TIMER); return; } script_timers[ID]= core->GetGame()->GameTime + expiration*AI_UPDATE_TIME; @@ -1348,7 +1454,7 @@ 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 = GetTickCount(); step = tp_steps [(step >> 6) & 7]; mix.a = overColor.a; mix.r = (overColor.r*step+selectedColor.r*(8-step))/8; @@ -1452,6 +1558,7 @@ Highlightable::Highlightable(ScriptableType type) Highlight = false; Cursor = IE_CURSOR_NORMAL; KeyResRef[0] = 0; + EnterWav[0] = 0; } Highlightable::~Highlightable(void) @@ -1482,6 +1589,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; @@ -1521,6 +1645,23 @@ 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) +{ + 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(); +} /***************** * Movable Class * @@ -1625,7 +1766,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)\n", arg); } } @@ -1684,7 +1825,7 @@ 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\n", step->orient); step = step->Next; timeStartStep = timeStartStep + walk_speed; } @@ -1902,7 +2043,7 @@ void Movable::DrawTargetPoint(const Region &vp) // generates "step" from sequence 3 2 1 0 1 2 3 4 // updated each 1/15 sec unsigned long step; - GetTime( step ); + step = GetTickCount(); step = tp_steps [(step >> 6) & 7]; step = step + 1; diff --git a/project/jni/application/gemrb/gemrb/core/Scriptable/Scriptable.h b/project/jni/application/gemrb/gemrb/core/Scriptable/Scriptable.h index 0e5a0c991..788f4d165 100644 --- a/project/jni/application/gemrb/gemrb/core/Scriptable/Scriptable.h +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/Scriptable.h @@ -23,11 +23,6 @@ #include "exports.h" -#include "CharAnimations.h" -#include "Inventory.h" -#include "PathFinder.h" -#include "Sprite2D.h" -#include "TileOverlay.h" #include "Variables.h" #include @@ -40,10 +35,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 @@ -93,20 +91,21 @@ class SpriteCover; #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_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_TARGETGONE 0x800 //actor's target is gone (trigger event) #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) @@ -135,7 +134,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 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 TriggerObjects; //#define SEA_RESET 0x00000002 //#define SEA_PARTY_REQUIRED 0x00000004 @@ -145,16 +217,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 triggers; Map *area; ieVariable scriptName; ieDword InternalFlags; //for triggers @@ -166,18 +235,24 @@ public: int CurrentActionState; ieDword CurrentActionTarget; bool CurrentActionInterruptable; + ieDword CurrentActionTicks; - // Timing state for ExecuteScript. - ieDword lastDelay; - ieDword lastRunTime; + // 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 countdown for forced activation by triggers. + ieDword TriggerCountdown; Variables* locals; ScriptableType Type; Point Pos; ieStrRef DialogName; - //play this wav file when stepping on the trap - ieResRef EnterWav; GameScript* Scripts[MAX_SCRIPTS]; @@ -190,22 +265,27 @@ public: ieDword UnselectableTimer; // Stored objects. - 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; - 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 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 LastTarget; Point LastTargetPos; int SpellHeader; ieResRef SpellResRef; @@ -241,7 +321,9 @@ public: //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; } @@ -250,13 +332,15 @@ public: void ClearActions(); 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); /* re/draws overhead text on the map screen */ void DrawOverheadText(const Region &screen); /* check if casting is allowed at all */ @@ -334,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; diff --git a/project/jni/application/gemrb/gemrb/core/ScriptedAnimation.cpp b/project/jni/application/gemrb/gemrb/core/ScriptedAnimation.cpp index f1c9d9e16..9586840ea 100644 --- a/project/jni/application/gemrb/gemrb/core/ScriptedAnimation.cpp +++ b/project/jni/application/gemrb/gemrb/core/ScriptedAnimation.cpp @@ -25,10 +25,14 @@ #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" #define ILLEGAL 0 // @@ -226,7 +230,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 +241,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\n" ); + delete stream; return; } ieResRef Anim1ResRef; @@ -383,9 +386,7 @@ ScriptedAnimation::ScriptedAnimation(DataStream* stream, bool autoFree) SetPhase(P_ONSET); - if (autoFree) { - delete( stream ); - } + delete stream; } ScriptedAnimation::~ScriptedAnimation(void) diff --git a/project/jni/application/gemrb/gemrb/core/ScriptedAnimation.h b/project/jni/application/gemrb/gemrb/core/ScriptedAnimation.h index 088a8bf8b..69fe14a5f 100644 --- a/project/jni/application/gemrb/gemrb/core/ScriptedAnimation.h +++ b/project/jni/application/gemrb/gemrb/core/ScriptedAnimation.h @@ -22,12 +22,15 @@ #include "exports.h" -#include "AnimationFactory.h" #include "Audio.h" -#include "Map.h" #include "Palette.h" #include "SpriteCover.h" -#include "System/DataStream.h" + +class Animation; +class AnimationFactory; +class DataStream; +class Map; +class Sprite2D; //scripted animation flags #define S_ANI_PLAYONCE 8 //(same as area animation) @@ -72,7 +75,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); diff --git a/project/jni/application/gemrb/gemrb/core/Spell.cpp b/project/jni/application/gemrb/gemrb/core/Spell.cpp index 06512ebf1..69aeea51e 100644 --- a/project/jni/application/gemrb/gemrb/core/Spell.cpp +++ b/project/jni/application/gemrb/gemrb/core/Spell.cpp @@ -196,8 +196,8 @@ Projectile *Spell::GetProjectile(Scriptable *self, int header, const Point &targ { SPLExtHeader *seh = GetExtHeader(header); if (!seh) { - printMessage("Spell", "Cannot retrieve spell header!!! ",RED); - printf("required header: %d, maximum: %d\n", header, (int) ExtHeaderCount); + printMessage("Spell", "Cannot retrieve spell header!!! required header: %d, maximum: %d\n", RED, + header, (int) ExtHeaderCount); return NULL; } Projectile *pro = core->GetProjectileServer()->GetProjectileByIndex(seh->ProjectileAnimation); @@ -225,8 +225,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); + printMessage("Spell", "Cannot retrieve spell header!!! required header: %d, maximum: %d\n", RED, + idx, (int) ExtHeaderCount); return 0; } diff --git a/project/jni/application/gemrb/gemrb/core/SpellMgr.h b/project/jni/application/gemrb/gemrb/core/SpellMgr.h index 44c10325f..15fbaba59 100644 --- a/project/jni/application/gemrb/gemrb/core/SpellMgr.h +++ b/project/jni/application/gemrb/gemrb/core/SpellMgr.h @@ -40,7 +40,7 @@ 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; }; diff --git a/project/jni/application/gemrb/gemrb/core/Spellbook.cpp b/project/jni/application/gemrb/gemrb/core/Spellbook.cpp index b910faf67..9c2f0ddcb 100644 --- a/project/jni/application/gemrb/gemrb/core/Spellbook.cpp +++ b/project/jni/application/gemrb/gemrb/core/Spellbook.cpp @@ -164,7 +164,7 @@ bool Spellbook::HaveSpell(int spellid, ieDword flags) if (atoi(ms->SpellResRef+4)==spellid) { if (flags&HS_DEPLETE) { if (DepleteSpell(ms) && (sorcerer & (1<SpellResRef); } } return true; @@ -231,7 +231,7 @@ bool Spellbook::HaveSpell(const char *resref, ieDword flags) } if (flags&HS_DEPLETE) { if (DepleteSpell(ms) && (sorcerer & (1<SpellResRef); } } return true; @@ -285,7 +285,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; @@ -470,25 +470,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()) @@ -755,7 +799,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<memorized_spells[k]->SpellResRef); } return true; } @@ -764,19 +808,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 +847,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<SpellResRef); } return ret; @@ -878,6 +926,20 @@ unsigned int Spellbook::GetSpellInfoSize(int type) return count; } +bool Spellbook::FindSpellInfo(SpellExtHeader *array, ieResRef spellname) +{ + memset(array, 0, sizeof(SpellExtHeader) ); + if (spellinfo.size() == 0) { + GenerateSpellInfo(); + } + for (unsigned int i = 0; ispellname, spellname, sizeof(ieResRef) ) ) continue; + memcpy(array, spellinfo[i], sizeof(SpellExtHeader)); + return true; + } + return false; +} + SpellExtHeader *Spellbook::FindSpellInfo(unsigned int level, unsigned int type, const ieResRef spellname) { size_t i = spellinfo.size(); @@ -908,16 +970,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 (levelext_headers[ehc+1].RequiredLevel) { break; } } - + SPLExtHeader *ext_header = spl->ext_headers+ehc; seh->headerindex = ehc; seh->level = sm_level; @@ -989,27 +1051,27 @@ void Spellbook::dump() { unsigned int k; - printf( "SPELLBOOK:\n" ); + print( "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" ); + print( " 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 ); + print ( " %2d: %8s L: %d T: %d\n", k, spl->SpellResRef, spl->Level, spl->Type ); } if (sm->memorized_spells.size()) - printf( " Memorized spells:\n" ); + print( " 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 ); + print ( " %2u: %8s %x\n", k, spl->SpellResRef, spl->Flags ); } } } diff --git a/project/jni/application/gemrb/gemrb/core/Spellbook.h b/project/jni/application/gemrb/gemrb/core/Spellbook.h index 97c962e1c..4feeba153 100644 --- a/project/jni/application/gemrb/gemrb/core/Spellbook.h +++ b/project/jni/application/gemrb/gemrb/core/Spellbook.h @@ -138,7 +138,7 @@ private: /** 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 */ @@ -195,8 +195,9 @@ public: /** adds a spell to the book, returns experience if learned */ int LearnSpell(Spell *spell, int memo); 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; @@ -241,6 +242,10 @@ public: /** lists spells of a type */ bool GetSpellInfo(SpellExtHeader *array, int type, int startindex, int count); + + /** find the first spell matching resref */ + bool FindSpellInfo(SpellExtHeader *array, ieResRef spellname); + /** Dumps spellbook to stdout for debugging */ void dump(); }; diff --git a/project/jni/application/gemrb/gemrb/core/Store.cpp b/project/jni/application/gemrb/gemrb/core/Store.cpp index 5d60994b6..a61568110 100644 --- a/project/jni/application/gemrb/gemrb/core/Store.cpp +++ b/project/jni/application/gemrb/gemrb/core/Store.cpp @@ -197,12 +197,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 < 2 && memcmp(temp->Usages, item->Usages, sizeof(item->Usages))) { continue; } } @@ -245,7 +246,21 @@ void Store::AddItem(CREItem *item) if (temp) { if (temp->InfiniteSupply!=-1) { - temp->StackAmount++; + if (item->MaxStackAmount > 1) { + // Stacked, so increase usages. + ieDword newAmount = 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 +270,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 > 1 && 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 +283,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; diff --git a/project/jni/application/gemrb/gemrb/core/Store.h b/project/jni/application/gemrb/gemrb/core/Store.h index aaabd35a8..776bf9876 100644 --- a/project/jni/application/gemrb/gemrb/core/Store.h +++ b/project/jni/application/gemrb/gemrb/core/Store.h @@ -69,7 +69,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 diff --git a/project/jni/application/gemrb/gemrb/core/StoreMgr.h b/project/jni/application/gemrb/gemrb/core/StoreMgr.h index 16a7070bc..b83b732aa 100644 --- a/project/jni/application/gemrb/gemrb/core/StoreMgr.h +++ b/project/jni/application/gemrb/gemrb/core/StoreMgr.h @@ -41,11 +41,10 @@ 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/project/jni/application/gemrb/gemrb/core/StringMgr.h b/project/jni/application/gemrb/gemrb/core/StringMgr.h index be18bd1e3..a7713406d 100644 --- a/project/jni/application/gemrb/gemrb/core/StringMgr.h +++ b/project/jni/application/gemrb/gemrb/core/StringMgr.h @@ -52,7 +52,7 @@ 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; diff --git a/project/jni/application/gemrb/gemrb/core/SymbolMgr.h b/project/jni/application/gemrb/gemrb/core/SymbolMgr.h index ebf339912..d45bd3b00 100644 --- a/project/jni/application/gemrb/gemrb/core/SymbolMgr.h +++ b/project/jni/application/gemrb/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,13 +22,9 @@ * @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" @@ -43,7 +37,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; diff --git a/project/jni/application/gemrb/gemrb/core/System/DataStream.cpp b/project/jni/application/gemrb/gemrb/core/System/DataStream.cpp index 71c0f193b..473aa1e0f 100644 --- a/project/jni/application/gemrb/gemrb/core/System/DataStream.cpp +++ b/project/jni/application/gemrb/gemrb/core/System/DataStream.cpp @@ -24,6 +24,8 @@ #include +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 +51,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 +185,36 @@ 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; + 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/project/jni/application/gemrb/gemrb/core/System/DataStream.h b/project/jni/application/gemrb/gemrb/core/System/DataStream.h index e20c1183e..2321a7fb4 100644 --- a/project/jni/application/gemrb/gemrb/core/System/DataStream.h +++ b/project/jni/application/gemrb/gemrb/core/System/DataStream.h @@ -68,10 +68,17 @@ 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/project/jni/application/gemrb/gemrb/core/System/FileStream.cpp b/project/jni/application/gemrb/gemrb/core/System/FileStream.cpp index eeeabc103..d24ee0bdf 100644 --- a/project/jni/application/gemrb/gemrb/core/System/FileStream.cpp +++ b/project/jni/application/gemrb/gemrb/core/System/FileStream.cpp @@ -24,147 +24,226 @@ #include "Interface.h" +#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, + 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--; #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++; #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; 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++; #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 ); - 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 ); + strncpy(originalfile, path, _MAX_PATH); + + if (!str->OpenNew(originalfile)) { return false; } opened = true; created = true; Pos = 0; size = 0; - startpos = 0; return true; } @@ -178,7 +257,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 +275,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 +293,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 +310,18 @@ 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)\n",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; -unsigned long FileStream::GetStartPos() const -{ - return startpos; + delete fs; + return NULL; } diff --git a/project/jni/application/gemrb/gemrb/core/System/FileStream.h b/project/jni/application/gemrb/gemrb/core/System/FileStream.h index 8c8a28a33..d225d0457 100644 --- a/project/jni/application/gemrb/gemrb/core/System/FileStream.h +++ b/project/jni/application/gemrb/gemrb/core/System/FileStream.h @@ -40,24 +40,31 @@ class GEM_EXPORT FileStream : public DataStream { private: - bool autoFree; - unsigned long startpos; - _FILE* str; + 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); +public: + /** Opens the specifed file. + * + * Returns NULL, if the file can't be opened. + */ + static FileStream* OpenFile(const char* filename); +private: + void FindLength(); + void Close(); }; #endif // ! FILESTREAM_H diff --git a/project/jni/application/gemrb/gemrb/core/System/Logging.cpp b/project/jni/application/gemrb/gemrb/core/System/Logging.cpp new file mode 100644 index 000000000..ed86c27f7 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/core/System/Logging.cpp @@ -0,0 +1,187 @@ +/* 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 +#include + +#ifdef ANDROID +#include +#endif + +#ifdef WIN32 +# define ADV_TEXT +# include +#endif + +void vprint(const char *message, va_list ap) +{ +#if (!defined(WIN32) || defined(__MINGW32__)) +# ifdef ANDROID + __android_log_vprint(ANDROID_LOG_INFO, "printf:", message, ap); +# else + vprintf(message, ap); +# endif +#else + // 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 + char buff[_MAX_PATH]; + vsnprintf(buff, _MAX_PATH, message, ap); + cprintf("%s", buff); +#endif +} + +void print(const char *message, ...) +{ + va_list ap; + + va_start(ap, message); + vprint(message, ap); + va_end(ap); +} + +#ifndef NOCOLOR +#ifdef WIN32 +static int colors[] = { + 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, + (RED | FOREGROUND_INTENSITY), + (GREEN | FOREGROUND_INTENSITY), + (GREEN | RED | FOREGROUND_INTENSITY), + (BLUE | FOREGROUND_INTENSITY), + (MAGENTA | FOREGROUND_INTENSITY), + (CYAN | FOREGROUND_INTENSITY), + (WHITE | FOREGROUND_INTENSITY), + WHITE +}; +#else +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" +}; +#endif +#endif + + +void textcolor(log_color c) +{ +#ifdef NOCOLOR + if (c) while (0) ; +#else +#ifdef WIN32 + SetConsoleTextAttribute(hConsole, colors[c]); +#else + print("%s", colors[c]); +#endif +#endif +} + +#ifndef ANDROID +void printBracket(const char* status, log_color color) +{ + textcolor(WHITE); + print("["); + textcolor(color); + print("%s", status); + textcolor(WHITE); + print("]"); +} + +void printStatus(const char* status, log_color color) +{ + printBracket(status, color); + print("\n"); +} + +void printMessage(const char* owner, const char* message, log_color color, ...) +{ + printBracket(owner, LIGHT_WHITE); + print(": "); + textcolor(color); + va_list ap; + + va_start(ap, color); + vprint(message, ap); + va_end(ap); +} + +void error(const char* owner, const char* message, ...) +{ + // FIXME: Merge with printMessage? + printBracket(owner, LIGHT_WHITE); + print(": "); + textcolor(LIGHT_RED); + va_list ap; + + va_start(ap, message); + vprint(message, ap); + va_end(ap); + + exit(1); +} +#else /* !ANDROID */ +void printBracket(const char* status, log_color color) +{ +} + +void printStatus(const char* status, log_color color) +{ + __android_log_print(ANDROID_LOG_INFO, "GemRB", "[%s]", status); +} + +void printMessage(const char* owner, const char* message, log_color color, ...) +{ + // FIXME: We drop owner on the floor. + va_list ap; + va_start(ap, message); + __android_log_vprint(ANDROID_LOG_INFO, "GemRB", message, ap); + va_end(ap); +} + +void error(const char* owner, const char* message, ...) +{ + // FIXME: We drop owner on the floor. + va_list ap; + va_start(ap, message); + __android_log_vprint(ANDROID_LOG_INFO, "GemRB", message, ap); + va_end(ap); + exit(1); +}; +#endif diff --git a/project/jni/application/gemrb/gemrb/core/System/Logging.h b/project/jni/application/gemrb/gemrb/core/System/Logging.h new file mode 100644 index 000000000..72cb0f427 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/core/System/Logging.h @@ -0,0 +1,92 @@ +/* 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" + +#if defined(ANDROID) +# include +// FIXME: Are these include necesary? +# include +# include +#elif defined(WIN32) +extern GEM_EXPORT HANDLE hConsole; +#else //WIN32 +# include +# include +# include +#endif + +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 +}; + + +GEM_EXPORT void print(const char* message, ...) +#if defined(__GNUC__) + __attribute__ ((format(printf, 1, 2))) +#endif + ; +GEM_EXPORT void textcolor(log_color); +GEM_EXPORT void printBracket(const char *status, log_color color); +GEM_EXPORT void printStatus(const char* status, log_color color); +GEM_EXPORT void printMessage(const char* owner, const char* message, log_color color, ...) +#if defined(__GNUC__) + __attribute__ ((format(printf, 2, 4))) +#endif + ; + +GEM_EXPORT void error(const char* owner, const char* message, ...) +#if defined(__GNUC__) + __attribute__ ((format(printf, 2, 3), noreturn)) +#endif + ; + +// 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 print instead."))); +#elif __GNUC__ >= 4 +extern "C" int printf(const char* message, ...) __attribute__ ((deprecated)); +#endif + +#endif diff --git a/project/jni/application/gemrb/gemrb/core/System/MemoryStream.cpp b/project/jni/application/gemrb/gemrb/core/System/MemoryStream.cpp index 1ce9656f5..eed152cd7 100644 --- a/project/jni/application/gemrb/gemrb/core/System/MemoryStream.cpp +++ b/project/jni/application/gemrb/gemrb/core/System/MemoryStream.cpp @@ -21,90 +21,78 @@ #include "System/MemoryStream.h" #include "win32def.h" +#include "errors.h" -#include +#include "Interface.h" -MemoryStream::MemoryStream(void* buffer, int length, bool autoFree) +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); + strncpy(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)\n", 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/project/jni/application/gemrb/gemrb/core/System/MemoryStream.h b/project/jni/application/gemrb/gemrb/core/System/MemoryStream.h index adda37f19..43b2e21bd 100644 --- a/project/jni/application/gemrb/gemrb/core/System/MemoryStream.h +++ b/project/jni/application/gemrb/gemrb/core/System/MemoryStream.h @@ -18,41 +18,25 @@ * */ -/** - * @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. - */ - -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/project/jni/application/gemrb/gemrb/core/System/SlicedStream.cpp b/project/jni/application/gemrb/gemrb/core/System/SlicedStream.cpp new file mode 100644 index 000000000..64d201409 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/core/System/SlicedStream.cpp @@ -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. + * + * + */ + +#include "System/SlicedStream.h" + +#include "System/MemoryStream.h" + +#include "win32def.h" +#include "errors.h" + +#include "Interface.h" + +SlicedStream::SlicedStream(DataStream* str, int startpos, int size) +{ + this->str = str->Clone(); + assert(this->str); + this->size = size; + this->startpos = startpos; + strncpy(originalfile, str->originalfile, _MAX_PATH); + strncpy(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)\n",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/project/jni/application/gemrb/gemrb/core/System/SlicedStream.h b/project/jni/application/gemrb/gemrb/core/System/SlicedStream.h new file mode 100644 index 000000000..df11ec487 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/core/System/SlicedStream.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 SLICEDSTREAM_H +#define SLICEDSTREAM_H + +#include "System/DataStream.h" + +#include "exports.h" + +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/project/jni/application/gemrb/gemrb/core/System/String.cpp b/project/jni/application/gemrb/gemrb/core/System/String.cpp new file mode 100644 index 000000000..a209cf35e --- /dev/null +++ b/project/jni/application/gemrb/gemrb/core/System/String.cpp @@ -0,0 +1,145 @@ +/* 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 +#ifdef WIN32 +#include "win32def.h" +#ifdef _DEBUG +#include +#include +#endif +#endif + +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; + } + } +} + +#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 + +/** 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) +{ + 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/project/jni/application/gemrb/gemrb/core/System/String.h b/project/jni/application/gemrb/gemrb/core/System/String.h new file mode 100644 index 000000000..af2a187d4 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/core/System/String.h @@ -0,0 +1,56 @@ +/* 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 + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifndef WIN32 +# define stricmp strcasecmp +# define strnicmp strncasecmp +#endif + +/* 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); +#ifndef HAVE_STRNLEN +GEM_EXPORT int strnlen(const char* string, int maxlen); +#endif +GEM_EXPORT int strlench(const char* string, char ch); +#ifndef HAVE_STRNDUP +GEM_EXPORT char* strndup(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/project/jni/application/gemrb/gemrb/core/System/VFS.cpp b/project/jni/application/gemrb/gemrb/core/System/VFS.cpp index 4e6d34894..c316716e1 100644 --- a/project/jni/application/gemrb/gemrb/core/System/VFS.cpp +++ b/project/jni/application/gemrb/gemrb/core/System/VFS.cpp @@ -33,6 +33,7 @@ #include #include +#include #ifndef WIN32 #include @@ -62,7 +63,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 +74,7 @@ DIR* opendir(const char* filename) return dirp; } -dirent* readdir(DIR* dirp) +static dirent* readdir(DIR* dirp) { struct _finddata_t c_file; @@ -93,154 +94,12 @@ dirent* readdir(DIR* dirp) return &de; } -void closedir(DIR* dirp) +static void closedir(DIR* dirp) { _findclose( dirp->hFile ); free( dirp ); } - -_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) -{ - if (!stream) { - return ( size_t ) 1; - } - unsigned long method; - switch (whence) { - case SEEK_SET: - method = FILE_BEGIN; - break; - case SEEK_CUR: - method = FILE_CURRENT; - break; - case SEEK_END: - method = FILE_END; - break; - 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; - } - if (!CloseHandle( stream->hFile )) { - return EOF; - } - free( stream ); - return 0; -} - #endif // WIN32 @@ -289,13 +148,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 +195,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 +227,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 +270,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!='?') { @@ -489,6 +357,24 @@ void ExtractFileFromPath(char *file, const char *full_path) strcpy(file, full_path); } +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 +} + DirectoryIterator::DirectoryIterator(const char *path) : Directory(NULL), Entry(NULL), Path(path) { @@ -504,10 +390,8 @@ DirectoryIterator::~DirectoryIterator() bool DirectoryIterator::IsDirectory() { char dtmp[_MAX_PATH]; - struct stat fst; GetFullPath(dtmp); - stat( dtmp, &fst ); - return S_ISDIR( fst.st_mode ); + return dir_exists(dtmp); } char* DirectoryIterator::GetName() @@ -536,3 +420,4 @@ void DirectoryIterator::Rewind() else Entry = readdir(static_cast(Directory)); } + diff --git a/project/jni/application/gemrb/gemrb/core/System/VFS.h b/project/jni/application/gemrb/gemrb/core/System/VFS.h index d78cb2828..94e83d7d7 100644 --- a/project/jni/application/gemrb/gemrb/core/System/VFS.h +++ b/project/jni/application/gemrb/gemrb/core/System/VFS.h @@ -53,34 +53,10 @@ #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 - /** Handle ~ -> $HOME mapping and do initial case-sensitity check */ GEM_EXPORT void ResolveFilePath(char* FilePath); GEM_EXPORT void ResolveFilePath(std::string& FilePath); @@ -125,12 +101,16 @@ 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 MakeDirectory(const char* path) WARN_UNUSED; + class GEM_EXPORT DirectoryIterator { public: /** diff --git a/project/jni/application/gemrb/gemrb/core/TableMgr.h b/project/jni/application/gemrb/gemrb/core/TableMgr.h index 5e38557b2..18054e6d5 100644 --- a/project/jni/application/gemrb/gemrb/core/TableMgr.h +++ b/project/jni/application/gemrb/gemrb/core/TableMgr.h @@ -65,7 +65,7 @@ public: virtual int FindTableValue(unsigned int 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; }; /** diff --git a/project/jni/application/gemrb/gemrb/core/TileMap.cpp b/project/jni/application/gemrb/gemrb/core/TileMap.cpp index ae2fc7a22..62716de9f 100644 --- a/project/jni/application/gemrb/gemrb/core/TileMap.cpp +++ b/project/jni/application/gemrb/gemrb/core/TileMap.cpp @@ -205,12 +205,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 +513,8 @@ int TileMap::CleanupContainer(Container *container) return 1; } } - printMessage("TileMap", " ", LIGHT_RED); - printf("Invalid container cleanup: %s\n", container->GetScriptName()); + printMessage("TileMap", "Invalid container cleanup: %s\n", LIGHT_RED, + container->GetScriptName()); return 1; } diff --git a/project/jni/application/gemrb/gemrb/core/TileMap.h b/project/jni/application/gemrb/gemrb/core/TileMap.h index ad97d10c7..b02c43390 100644 --- a/project/jni/application/gemrb/gemrb/core/TileMap.h +++ b/project/jni/application/gemrb/gemrb/core/TileMap.h @@ -90,7 +90,7 @@ 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: diff --git a/project/jni/application/gemrb/gemrb/core/TileMapMgr.h b/project/jni/application/gemrb/gemrb/core/TileMapMgr.h index 433377507..f32f44272 100644 --- a/project/jni/application/gemrb/gemrb/core/TileMapMgr.h +++ b/project/jni/application/gemrb/gemrb/core/TileMapMgr.h @@ -29,7 +29,7 @@ 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; diff --git a/project/jni/application/gemrb/gemrb/core/TileOverlay.cpp b/project/jni/application/gemrb/gemrb/core/TileOverlay.cpp index 475192e7f..303ea0ea1 100644 --- a/project/jni/application/gemrb/gemrb/core/TileOverlay.cpp +++ b/project/jni/application/gemrb/gemrb/core/TileOverlay.cpp @@ -20,6 +20,8 @@ #include "TileOverlay.h" +//#include "Game.h" // needed only for TILE_GREY below +#include "GlobalTimer.h" #include "Interface.h" #include "Video.h" @@ -72,7 +74,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 +97,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 +114,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 +123,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 ); } } } diff --git a/project/jni/application/gemrb/gemrb/core/TileOverlay.h b/project/jni/application/gemrb/gemrb/core/TileOverlay.h index 642f1d39a..681c2c30c 100644 --- a/project/jni/application/gemrb/gemrb/core/TileOverlay.h +++ b/project/jni/application/gemrb/gemrb/core/TileOverlay.h @@ -39,7 +39,7 @@ 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); }; diff --git a/project/jni/application/gemrb/gemrb/core/TileSetMgr.h b/project/jni/application/gemrb/gemrb/core/TileSetMgr.h index 0cc21dc85..a909da975 100644 --- a/project/jni/application/gemrb/gemrb/core/TileSetMgr.h +++ b/project/jni/application/gemrb/gemrb/core/TileSetMgr.h @@ -29,7 +29,7 @@ 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; }; diff --git a/project/jni/application/gemrb/gemrb/core/Variables.cpp b/project/jni/application/gemrb/gemrb/core/Variables.cpp index 9be058f16..802b64686 100644 --- a/project/jni/application/gemrb/gemrb/core/Variables.cpp +++ b/project/jni/application/gemrb/gemrb/core/Variables.cpp @@ -426,8 +426,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); + printMessage("Variables", "Cannot create new variable: %s\n", YELLOW, key); return; } @@ -480,7 +479,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 +499,8 @@ 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); } } diff --git a/project/jni/application/gemrb/gemrb/core/Variables.h b/project/jni/application/gemrb/gemrb/core/Variables.h index db392a8f3..d3a59e083 100644 --- a/project/jni/application/gemrb/gemrb/core/Variables.h +++ b/project/jni/application/gemrb/gemrb/core/Variables.h @@ -27,6 +27,8 @@ #include "globals.h" #include "win32def.h" +#include + #ifndef ReleaseFun typedef void (*ReleaseFun)(void *); #endif diff --git a/project/jni/application/gemrb/gemrb/core/Video.cpp b/project/jni/application/gemrb/gemrb/core/Video.cpp index 22eeb17c0..d056070e4 100644 --- a/project/jni/application/gemrb/gemrb/core/Video.cpp +++ b/project/jni/application/gemrb/gemrb/core/Video.cpp @@ -25,6 +25,7 @@ #include "Audio.h" #include "Interface.h" #include "Palette.h" +#include "Sprite2D.h" #include @@ -45,6 +46,11 @@ Video::~Video(void) { } +bool Video::ToggleFullscreenMode() +{ + return SetFullscreenMode(!fullscreen); +} + /** Set Event Manager */ void Video::SetEventMgr(EventMgr* evnt) { diff --git a/project/jni/application/gemrb/gemrb/core/Video.h b/project/jni/application/gemrb/gemrb/core/Video.h index 1560e5e89..e080cbd7e 100644 --- a/project/jni/application/gemrb/gemrb/core/Video.h +++ b/project/jni/application/gemrb/gemrb/core/Video.h @@ -29,18 +29,19 @@ #include "globals.h" -#include "Animation.h" #include "Plugin.h" -#include "Polygon.h" #include "ScriptedAnimation.h" -#include "GUI/EventMgr.h" 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_RED enum SpriteBlitFlags { BLIT_HALFTRANS = IE_VVC_TRANSPARENT, // 2 BLIT_BLENDED = IE_VVC_BLENDED, // 8; not implemented in SDLVideo yet @@ -56,6 +57,13 @@ enum SpriteBlitFlags { // 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 +}; + //disable mouse flags #define MOUSE_DISABLED 1 #define MOUSE_GRAYED 2 @@ -79,9 +87,9 @@ public: 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; + /** 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 */ @@ -106,7 +114,7 @@ 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; diff --git a/project/jni/application/gemrb/gemrb/core/WindowMgr.h b/project/jni/application/gemrb/gemrb/core/WindowMgr.h index 61a3a377d..17b82c46b 100644 --- a/project/jni/application/gemrb/gemrb/core/WindowMgr.h +++ b/project/jni/application/gemrb/gemrb/core/WindowMgr.h @@ -28,8 +28,9 @@ #define WINDOWMGR_H #include "Plugin.h" -#include "GUI/Window.h" -#include "System/DataStream.h" + +class DataStream; +class Window; /** * @class WindowMgr @@ -42,7 +43,7 @@ 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 */ diff --git a/project/jni/application/gemrb/gemrb/core/WorldMap.cpp b/project/jni/application/gemrb/gemrb/core/WorldMap.cpp index c2face07e..012a61581 100644 --- a/project/jni/application/gemrb/gemrb/core/WorldMap.cpp +++ b/project/jni/application/gemrb/gemrb/core/WorldMap.cpp @@ -24,6 +24,7 @@ #include "Game.h" #include "Interface.h" +#include "TableMgr.h" #include "Video.h" #include @@ -105,7 +106,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\n", frame, IconSeq); return NULL; } if (color>=0) { @@ -302,15 +303,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); + printMessage("WorldMap", "CalculateDistances for invalid direction: %s\n", LIGHT_RED, AreaName); return -1; } unsigned int i; if (!GetArea(AreaName, i)) { - printMessage("WorldMap","", LIGHT_RED); - printf("CalculateDistances for invalid Area: %s\n", AreaName); + printMessage("WorldMap", "CalculateDistances for invalid Area: %s\n", LIGHT_RED, AreaName); return -1; } if (Distances) { @@ -320,8 +319,7 @@ int WorldMap::CalculateDistances(const ieResRef AreaName, int direction) free(GotHereFrom); } - printMessage("WorldMap","", GREEN); - printf("CalculateDistances for Area: %s\n", AreaName); + printMessage("WorldMap", "CalculateDistances for Area: %s\n", GREEN, AreaName); size_t memsize =sizeof(int) * area_entries.size(); Distances = (int *) malloc( memsize ); @@ -345,8 +343,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); + printMessage("WorldMap", "The worldmap file is corrupted... and it would crash right now!\nEntry #: %d Direction: %d\n", RED, + i, d); break; } for(;j walkpath; - printf("Gathering path information for: %s\n", AreaName); + print("Gathering path information for: %s\n", AreaName); while (GotHereFrom[i]!=-1) { - printf("Adding path to %d\n", i); + print("Adding path to %d\n", 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\n",(int) walkpath.size()); if (!walkpath.size()) { return NULL; } @@ -488,7 +484,7 @@ 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, and visible)\n", AreaName); ae->SetAreaStatus(WMP_ENTRY_VISITED|WMP_ENTRY_VISIBLE, BM_OR); if (direction<0 || direction>3) @@ -498,7 +494,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)\n", ae2->AreaName); ae2->SetAreaStatus(WMP_ENTRY_VISIBLE|WMP_ENTRY_ACCESSIBLE, BM_OR); } } diff --git a/project/jni/application/gemrb/gemrb/core/WorldMap.h b/project/jni/application/gemrb/gemrb/core/WorldMap.h index f8cce256f..556a41b7a 100644 --- a/project/jni/application/gemrb/gemrb/core/WorldMap.h +++ b/project/jni/application/gemrb/gemrb/core/WorldMap.h @@ -83,7 +83,7 @@ private: public: ieResRef AreaName; ieResRef AreaResRef; - char AreaLongName[32]; + ieVariable AreaLongName; ieDword IconSeq; ieDword X; ieDword Y; @@ -101,7 +101,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]; diff --git a/project/jni/application/gemrb/gemrb/core/WorldMapMgr.h b/project/jni/application/gemrb/gemrb/core/WorldMapMgr.h index 80eed4c42..e66f6adfe 100644 --- a/project/jni/application/gemrb/gemrb/core/WorldMapMgr.h +++ b/project/jni/application/gemrb/gemrb/core/WorldMapMgr.h @@ -40,7 +40,7 @@ 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; diff --git a/project/jni/application/gemrb/gemrb/includes/HashMap.h b/project/jni/application/gemrb/gemrb/includes/HashMap.h new file mode 100644 index 000000000..573064421 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/includes/HashMap.h @@ -0,0 +1,455 @@ +/* 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 +#include +#include + +#include "System/Logging.h" + +// dumps stats upon destruction +//#define HASHMAP_DEBUG + +template +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::hash(const T &key) \ + { \ + return static_cast(key); \ + } \ + template<> \ + inline bool HashKey::equals(const T &a, const T &b) \ + { \ + return a == b; \ + } \ + template<> \ + inline void HashKey::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 > +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 _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 +HashMap::HashMap() : + _tableSize(0), + _blockSize(0), + _blocks(), + _buckets(NULL), + _available(NULL) +{ +#ifdef HASHMAP_DEBUG + memset(&_debug, 0, sizeof(_debug)); +#endif +} + +template +HashMap::~HashMap() +{ + clear(); +} + +template +void HashMap::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 +bool HashMap::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 +const Value *HashMap::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 +bool HashMap::has(const Key &key) const +{ + return get(key) != NULL; +} + +template +inline bool HashMap::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 +void HashMap::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 +bool inline HashMap::isInitialized() const +{ + return _buckets != NULL; +} + +template +inline typename HashMap::Entry *HashMap::popAvailable() +{ + if (!_available) + allocBlock(); + + Entry *e = _available; + _available = e->next; + + e->next = NULL; + + return e; +} + +template +inline void HashMap::pushAvailable(Entry *e) { + e->next = _available; + _available = e; +} + +template +inline unsigned int HashMap::getMapPosByHash(unsigned int hash) const +{ + return hash % _tableSize; +} + +template +inline unsigned int HashMap::getMapPosByKey(const Key &key) const +{ + return getMapPosByHash(Hash::hash(key)); +} + +template +inline typename HashMap::Entry *HashMap::getBucketByHash(unsigned int hash) const +{ + return _buckets[getMapPosByHash(hash)]; +} + +template +inline typename HashMap::Entry *HashMap::getBucketByKey(const Key &key) const +{ + return _buckets[getMapPosByKey(key)]; +} + +template +inline typename HashMap::Entry *HashMap::findPredecessor(const Key &key, Entry *e) const +{ + for (; e->next; e = e->next) + if (Hash::equals(e->next->key, key)) + break; + + return e; +} + +template +inline void HashMap::incAccesses() const +{ +#ifdef HASHMAP_DEBUG + _debug.accesses++; +#endif +} + +template +void HashMap::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 +void HashMap::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; + + printMessage("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", + DEFAULT, 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/project/jni/application/gemrb/gemrb/includes/SClassID.h b/project/jni/application/gemrb/gemrb/includes/SClassID.h index b82d71ce9..776dbca79 100644 --- a/project/jni/application/gemrb/gemrb/includes/SClassID.h +++ b/project/jni/application/gemrb/gemrb/includes/SClassID.h @@ -82,6 +82,7 @@ enum { PLUGIN_OPCODES_TORMENT, PLUGIN_RESOURCE_KEY, PLUGIN_RESOURCE_DIRECTORY, + PLUGIN_RESOURCE_CACHEDDIRECTORY, PLUGIN_IMAGE_WRITER_BMP, PLUGIN_COMPRESSION_ZLIB }; diff --git a/project/jni/application/gemrb/gemrb/includes/StringMap.h b/project/jni/application/gemrb/gemrb/includes/StringMap.h new file mode 100644 index 000000000..4805e1e16 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/includes/StringMap.h @@ -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. + * + * + */ + +#ifndef STRINGMAP_H +#define STRINGMAP_H + +#include + +#include "ie_types.h" + +#include "System/String.h" +#include "HashMap.h" + +// 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 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 { + // 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 { +public: + // lookup without std::string construction + const std::string *get(const char *key) const + { + if (!isInitialized()) + return NULL; + + incAccesses(); + + for (Entry *e = getBucketByHash(HashKey::hash(key)); e; e = e->next) + if (HashKey::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 +struct HashKey { + 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/project/jni/application/gemrb/gemrb/includes/defsounds.h b/project/jni/application/gemrb/gemrb/includes/defsounds.h index 7ce8dc042..76e8288bb 100644 --- a/project/jni/application/gemrb/gemrb/includes/defsounds.h +++ b/project/jni/application/gemrb/gemrb/includes/defsounds.h @@ -39,6 +39,7 @@ #define DS_CLOSE_FAIL 8 #define DS_ITEM_GONE 9 #define DS_FOUNDSECRET 10 +#define DS_PICKLOCK 11 #define DS_RAIN 20 #define DS_SNOW 21 diff --git a/project/jni/application/gemrb/gemrb/includes/exports.h b/project/jni/application/gemrb/gemrb/includes/exports.h index 0faa7f12a..6b40d6ea4 100644 --- a/project/jni/application/gemrb/gemrb/includes/exports.h +++ b/project/jni/application/gemrb/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,37 @@ #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 +#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/project/jni/application/gemrb/gemrb/includes/globals.h b/project/jni/application/gemrb/gemrb/includes/globals.h index a34c470ff..62197de89 100644 --- a/project/jni/application/gemrb/gemrb/includes/globals.h +++ b/project/jni/application/gemrb/gemrb/includes/globals.h @@ -52,10 +52,9 @@ #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 #include @@ -82,10 +81,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 @@ -166,17 +161,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,27 +173,15 @@ 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 #ifndef WIN32 -GEM_EXPORT char* strupr(char* string); -GEM_EXPORT char* strlwr(char* string); -#endif - -#ifdef WIN32 -#define GetTime(store) store = GetTickCount() -#else #include -#define GetTime(store) \ - { \ - struct timeval tv; \ - gettimeofday(&tv, NULL); \ - store = (tv.tv_usec/1000) + (tv.tv_sec*1000); \ - } +inline unsigned long GetTickCount() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return (tv.tv_usec/1000) + (tv.tv_sec*1000); +} #endif inline int MIN(int a, int b) diff --git a/project/jni/application/gemrb/gemrb/includes/plugindef.h b/project/jni/application/gemrb/gemrb/includes/plugindef.h index 72a74e75e..6d9caba9f 100644 --- a/project/jni/application/gemrb/gemrb/includes/plugindef.h +++ b/project/jni/application/gemrb/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 * diff --git a/project/jni/application/gemrb/gemrb/includes/win32def.h b/project/jni/application/gemrb/gemrb/includes/win32def.h index 5b676e090..7c0fbdabc 100644 --- a/project/jni/application/gemrb/gemrb/includes/win32def.h +++ b/project/jni/application/gemrb/gemrb/includes/win32def.h @@ -30,43 +30,24 @@ #include "exports.h" +#include "System/String.h" + #ifdef WIN32 # define WIN32_LEAN_AND_MEAN # include -# 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 # include # endif # include # include -# include -# 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/project/jni/application/gemrb/gemrb/plugins/2DAImporter/2DAImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/2DAImporter/2DAImporter.cpp index fcb046ffa..74e372f0d 100644 --- a/project/jni/application/gemrb/gemrb/plugins/2DAImporter/2DAImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/2DAImporter/2DAImporter.cpp @@ -30,30 +30,20 @@ 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(); @@ -110,6 +100,7 @@ bool p2DAImporter::Open(DataStream* stream, bool autoFree) row++; } } + delete str; return true; } diff --git a/project/jni/application/gemrb/gemrb/plugins/2DAImporter/2DAImporter.h b/project/jni/application/gemrb/gemrb/plugins/2DAImporter/2DAImporter.h index 0e83b5c42..360418db8 100644 --- a/project/jni/application/gemrb/gemrb/plugins/2DAImporter/2DAImporter.h +++ b/project/jni/application/gemrb/gemrb/plugins/2DAImporter/2DAImporter.h @@ -26,13 +26,13 @@ #include "globals.h" #include +#include 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 +41,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 { diff --git a/project/jni/application/gemrb/gemrb/plugins/ACMReader/ACMReader.cpp b/project/jni/application/gemrb/gemrb/plugins/ACMReader/ACMReader.cpp index f0c5f9cf5..252c24240 100644 --- a/project/jni/application/gemrb/gemrb/plugins/ACMReader/ACMReader.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/ACMReader/ACMReader.cpp @@ -112,6 +112,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/project/jni/application/gemrb/gemrb/plugins/AREImporter/AREImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/AREImporter/AREImporter.cpp index 45e1a81ad..ff29eff11 100644 --- a/project/jni/application/gemrb/gemrb/plugins/AREImporter/AREImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/AREImporter/AREImporter.cpp @@ -33,15 +33,17 @@ #include "ImageMgr.h" #include "Interface.h" #include "Palette.h" +#include "PluginMgr.h" #include "ProjectileServer.h" #include "TileMapMgr.h" #include "Video.h" #include "GameScript/GameScript.h" +#include "GUI/Window.h" #include "Scriptable/Container.h" #include "Scriptable/Door.h" #include "Scriptable/InfoPoint.h" -#include "System/CachedFileStream.h" #include "System/FileStream.h" +#include "System/SlicedStream.h" #define DEF_OPEN 0 #define DEF_CLOSE 1 @@ -70,7 +72,7 @@ Holder INInote; ResRefToStrRef *tracks = NULL; int trackcount = 0; -void ReleaseMemory() +static void ReleaseMemory() { INInote.release(); @@ -78,17 +80,16 @@ void ReleaseMemory() tracks = NULL; } -void ReadAutonoteINI() +static void ReadAutonoteINI() { INInote = PluginHolder(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); @@ -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,7 +248,7 @@ 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.\n" ); return false; } @@ -273,7 +268,7 @@ bool AREImporter::ChangeMap(Map *map, bool day_or_night) ResourceHolder lm(TmpResRef); if (!lm) { - printf( "[AREImporter]: No lightmap available.\n" ); + print( "[AREImporter]: No lightmap available.\n" ); return false; } @@ -292,8 +287,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 +315,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.\n" ); return NULL; } ieResRef TmpResRef; @@ -339,7 +333,7 @@ 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.\n" ); return NULL; } @@ -368,7 +362,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) ResourceHolder lm(TmpResRef); if (!lm) { - printf( "[AREImporter]: No lightmap available.\n" ); + print( "[AREImporter]: No lightmap available.\n" ); return NULL; } @@ -376,7 +370,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) ResourceHolder sr(TmpResRef); if (!sr) { - printf( "[AREImporter]: No searchmap available.\n" ); + print( "[AREImporter]: No searchmap available.\n" ); return NULL; } @@ -384,7 +378,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) ResourceHolder hm(TmpResRef); if (!hm) { - printf( "[AREImporter]: No heightmap available.\n" ); + print( "[AREImporter]: No heightmap available.\n" ); return NULL; } @@ -415,7 +409,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\n" ); core->LoadProgress(70); //Loading InfoPoints for (i = 0; i < InfoPointsCount; i++) { @@ -523,7 +517,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) } } - printf( "Loading containers\n" ); + print( "Loading containers\n" ); //Loading Containers for (i = 0; i < ContainersCount; i++) { str->Seek( ContainersOffset + ( i * 0xC0 ), GEM_STREAM_START ); @@ -630,7 +624,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) c->OpenFail = OpenFail; } - printf( "Loading doors\n" ); + print( "Loading doors\n" ); //Loading Doors for (i = 0; i < DoorsCount; i++) { str->Seek( DoorsOffset + ( i * 0xc8 ), GEM_STREAM_START ); @@ -833,7 +827,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) door->SetDialog(Dialog); } - printf( "Loading spawnpoints\n" ); + print( "Loading spawnpoints\n" ); //Loading SpawnPoints for (i = 0; i < SpawnCount; i++) { str->Seek( SpawnOffset + (i*0xc8), GEM_STREAM_START ); @@ -888,11 +882,11 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) } core->LoadProgress(75); - printf( "Loading actors\n" ); + print( "Loading actors\n" ); //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\n" ); } else { PluginHolder actmgr(IE_CRE_CLASS_ID); for (i = 0; i < ActorCount; i++) { @@ -943,13 +937,12 @@ 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!\n", CreResRef); continue; } ab = actmgr->GetActor(0); @@ -984,11 +977,11 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) } core->LoadProgress(90); - printf( "Loading animations\n" ); + print( "Loading animations\n" ); //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\n" ); } else { for (i = 0; i < AnimCount; i++) { AreaAnimation* anim = new AreaAnimation(); @@ -1023,7 +1016,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) } } - printf( "Loading entrances\n" ); + print( "Loading entrances\n" ); //Loading Entrances str->Seek( EntrancesOffset, GEM_STREAM_START ); for (i = 0; i < EntrancesCount; i++) { @@ -1038,7 +1031,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) map->AddEntrance( Name, XPos, YPos, Face ); } - printf( "Loading variables\n" ); + print( "Loading variables\n" ); map->locals->LoadInitialValues(ResRef); //Loading Variables str->Seek( VariablesOffset, GEM_STREAM_START ); @@ -1053,7 +1046,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) map->locals->SetAt( Name, Value ); } - printf( "Loading ambients\n" ); + print( "Loading ambients\n" ); str->Seek( AmbiOffset, GEM_STREAM_START ); for (i = 0; i < AmbiCount; i++) { int j; @@ -1093,7 +1086,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) map->AddAmbient(ambi); } - printf( "Loading automap notes\n" ); + print( "Loading automap notes\n" ); str->Seek( NoteOffset, GEM_STREAM_START ); //this feature exists in all blackisle games but not in bioware games @@ -1168,7 +1161,7 @@ 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\n" ); for (i = 0; i < TrapCount; i++) { ieResRef TrapResRef; ieDword TrapEffOffset; @@ -1193,8 +1186,8 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) 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); + printMessage("AREImporter", "TrapEffectSize in game: %d != %d. Clearing it\n", LIGHT_RED, + TrapSize, TrapEffectCount*0x108); continue; } //The projectile is always created, the worst that can happen @@ -1205,7 +1198,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,7 +1211,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) map->AddProjectile( pro, pos, pos); } - printf( "Loading tiles\n" ); + print( "Loading tiles\n" ); //Loading Tiled objects (if any) str->Seek( TileOffset, GEM_STREAM_START ); for (i = 0; i < TileCount; i++) { @@ -1241,7 +1234,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) map->TMap->AddTile( ID, Name, Flags, NULL,0, NULL, 0 ); } - printf( "Loading explored bitmap\n" ); + print( "Loading explored bitmap\n" ); i = map->GetExploredMapSize(); if (ExploredBitmapSize==i) { map->ExploredBitmap = (ieByte *) malloc(i); @@ -1250,15 +1243,15 @@ 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); + printMessage("AREImporter", "ExploredBitmapSize in game: %d != %d. Clearing it\n", LIGHT_RED, + ExploredBitmapSize, i); } ExploredBitmapSize = i; map->ExploredBitmap = (ieByte *) calloc(i, 1); } map->VisibleBitmap = (ieByte *) calloc(i, 1); - printf( "Loading wallgroups\n"); + print( "Loading wallgroups\n"); map->SetWallGroups( tmm->GetPolygonsCount(),tmm->GetWallGroups() ); //setting up doors for (i=0;i eM(IE_EFF_CLASS_ID); - eM->Open( ds, true ); + eM->Open(ds); for (i = 0; i < EffectsCount; i++) { Effect fx; diff --git a/project/jni/application/gemrb/gemrb/plugins/AREImporter/AREImporter.h b/project/jni/application/gemrb/gemrb/plugins/AREImporter/AREImporter.h index db801547a..d5fbdd3c0 100644 --- a/project/jni/application/gemrb/gemrb/plugins/AREImporter/AREImporter.h +++ b/project/jni/application/gemrb/gemrb/plugins/AREImporter/AREImporter.h @@ -23,13 +23,14 @@ #include "MapMgr.h" +#include "Map.h" // proIterator class Animation; class AnimationFactory; +class EffectQueue; class AREImporter : public MapMgr { private: DataStream* str; - bool autoFree; int bigheader; ieResRef WEDResRef; ieDword LastSave; @@ -57,7 +58,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); diff --git a/project/jni/application/gemrb/gemrb/plugins/BAMImporter/BAMImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/BAMImporter/BAMImporter.cpp index 853115866..f5b374725 100644 --- a/project/jni/application/gemrb/gemrb/plugins/BAMImporter/BAMImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/BAMImporter/BAMImporter.cpp @@ -30,17 +30,18 @@ #include "win32def.h" -#include "Compressor.h" +#include "FileCache.h" +#include "Font.h" #include "GameData.h" #include "Interface.h" #include "Palette.h" +#include "Sprite2D.h" #include "Video.h" #include "System/FileStream.h" BAMImporter::BAMImporter(void) { str = NULL; - autoFree = false; frames = NULL; cycles = NULL; palette = NULL; @@ -50,72 +51,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 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; @@ -244,7 +208,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\n", findex); } else { memset( &Buffer[i], CompressedColorIndex, ( *p ) + 1 ); } diff --git a/project/jni/application/gemrb/gemrb/plugins/BAMImporter/BAMImporter.h b/project/jni/application/gemrb/gemrb/plugins/BAMImporter/BAMImporter.h index be59c3560..dc2ada4ea 100644 --- a/project/jni/application/gemrb/gemrb/plugins/BAMImporter/BAMImporter.h +++ b/project/jni/application/gemrb/gemrb/plugins/BAMImporter/BAMImporter.h @@ -39,7 +39,6 @@ class Palette; class BAMImporter : public AnimationMgr { private: DataStream* str; - bool autoFree; FrameEntry* frames; CycleEntry* cycles; ieWord FramesCount; @@ -57,7 +56,7 @@ 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); diff --git a/project/jni/application/gemrb/gemrb/plugins/BIFImporter/BIFImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/BIFImporter/BIFImporter.cpp index ccee8596c..4f92c0446 100644 --- a/project/jni/application/gemrb/gemrb/plugins/BIFImporter/BIFImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/BIFImporter/BIFImporter.cpp @@ -23,8 +23,10 @@ #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" BIFImporter::BIFImporter(void) @@ -47,91 +49,46 @@ BIFImporter::~BIFImporter(void) } } -int BIFImporter::DecompressSaveGame(DataStream *compressed) +bool BIFImporter::DecompressBIF(DataStream* compressed, const char* path) { - char Signature[8]; - compressed->Read( Signature, 8 ); - if (strncmp( Signature, "SAV V1.0", 8 ) ) { - return GEM_ERROR; + print( "Decompressing\n" ); + if (!core->IsAvailable( PLUGIN_COMPRESSION_ZLIB )) + return false; + PluginHolder comp(PLUGIN_COMPRESSION_ZLIB); + ieDword unCompBifSize; + compressed->ReadDword( &unCompBifSize ); + print( "\nDecompressing file: [..........]" ); + fflush(stdout); + FileStream out; + if (!out.Create(path)) { + printMessage("BIFImporter", "Cannot write %s.\n", RED, path); + return false; } - 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); + 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 false; } - PluginHolder 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; -} - -int BIFImporter::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 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; + print( "\n" ); + return true; } int BIFImporter::OpenArchive(const char* filename) @@ -140,19 +97,21 @@ int BIFImporter::OpenArchive(const char* filename) delete( stream ); stream = NULL; } - FILE* in_cache = fopen( filename, "rb" ); - if( !in_cache) { + FileStream* file = FileStream::OpenFile(filename); + if( !file) { return GEM_ERROR; } char Signature[8]; - if (fread( &Signature, 1, 8, in_cache ) != 8) { - fclose ( in_cache ); + if (file->Read(Signature, 8) == GEM_ERROR) { + delete file; return GEM_ERROR; } - fclose( in_cache ); + delete file; //normal bif, not in cache if (strncmp( Signature, "BIFFV1 ", 8 ) == 0) { - stream = new CachedFileStream( filename ); + stream = CacheFile( filename ); + if (!stream) + return GEM_ERROR; stream->Read( Signature, 8 ); strcpy( path, filename ); ReadBIF(); @@ -160,8 +119,9 @@ int BIFImporter::OpenArchive(const char* filename) } //not found as normal bif //checking compression type - FileStream* compressed = new FileStream(); - compressed->Open( filename, true ); + FileStream* compressed = FileStream::OpenFile( filename ); + if (!compressed) + return GEM_ERROR; compressed->Read( Signature, 8 ); if (strncmp( Signature, "BIF V1.0", 8 ) == 0) { ieDword fnlen, complen, declen; @@ -171,39 +131,12 @@ int BIFImporter::OpenArchive(const char* filename) strlwr(fname); compressed->ReadDword( &declen ); compressed->ReadDword( &complen ); - PathJoin( path, core->CachePath, fname, NULL ); + print( "Decompressing\n" ); + stream = CacheCompressedStream(compressed, fname, complen); 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); - return GEM_ERROR; - } - in_cache = fopen( path, "wb" ); - if (!in_cache) { - printMessage("BIFImporter", " ", RED); - printf( "Cannot write %s.\n", path ); - return GEM_ERROR; - } - PluginHolder comp(PLUGIN_COMPRESSION_ZLIB); - if (comp->Decompress( in_cache, compressed, complen ) != GEM_OK) { - return GEM_ERROR; - } - fclose( in_cache ); delete( compressed ); - stream = new CachedFileStream( path ); + if (!stream) + return GEM_ERROR; stream->Read( Signature, 8 ); if (strncmp( Signature, "BIFFV1 ", 8 ) == 0) ReadBIF(); @@ -213,62 +146,29 @@ int BIFImporter::OpenArchive(const char* filename) } if (strncmp( Signature, "BIFCV1.0", 8 ) == 0) { - //printf("'BIFCV1.0' Compressed File Found\n"); + //print("'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 ); + if (file_exists(path)) { + //print("Found in Cache\n"); delete( compressed ); - stream = new CachedFileStream( path ); + stream = FileStream::OpenFile(path); + if (!stream) + return GEM_ERROR; stream->Read( Signature, 8 ); if (strncmp( Signature, "BIFFV1 ", 8 ) == 0) { - ReadBIF(); + ReadBIF(); } else return GEM_ERROR; return GEM_OK; } - printf( "Decompressing\n" ); - if (!core->IsAvailable( PLUGIN_COMPRESSION_ZLIB )) - return GEM_ERROR; - PluginHolder 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 ); + if (!DecompressBIF(compressed, path)) { + delete( compressed ); 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; - - 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 = FileStream::OpenFile(path); + if (!stream) + return GEM_ERROR; stream->Read( Signature, 8 ); if (strncmp( Signature, "BIFFV1 ", 8 ) == 0) ReadBIF(); @@ -286,7 +186,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 +194,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/project/jni/application/gemrb/gemrb/plugins/BIFImporter/BIFImporter.h b/project/jni/application/gemrb/gemrb/plugins/BIFImporter/BIFImporter.h index eaabc321e..e7ca29a9a 100644 --- a/project/jni/application/gemrb/gemrb/plugins/BIFImporter/BIFImporter.h +++ b/project/jni/application/gemrb/gemrb/plugins/BIFImporter/BIFImporter.h @@ -21,11 +21,11 @@ #ifndef BIFIMPORTER_H #define BIFIMPORTER_H -#include "ArchiveImporter.h" +#include "IndexedArchive.h" #include "globals.h" -#include "System/CachedFileStream.h" +#include "System/DataStream.h" struct FileEntry { ieDword resLocator; @@ -44,22 +44,20 @@ 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 bool DecompressBIF(DataStream* compressed, const char* path); void ReadBIF(void); }; diff --git a/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/BIKPlayer.cpp b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/BIKPlayer.cpp index 5a7da6e9e..071edce8e 100644 --- a/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/BIKPlayer.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/BIKPlayer.cpp @@ -1503,7 +1503,7 @@ int BIKPlayer::DecodeVideoFrame(void *data, int data_size) } break; default: - printf("Incorrect 16x16 block type!\n"); + print("Incorrect 16x16 block type!\n"); return -1; } bx++; @@ -1586,7 +1586,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!\n"); return -1; } } @@ -1613,5 +1613,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/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/GetBitContext.cpp b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/GetBitContext.cpp index 5ef416a47..bbaa2738a 100644 --- a/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/GetBitContext.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/GetBitContext.cpp @@ -158,7 +158,7 @@ void GetBitContext::merge( uint8_t *dst, uint8_t *src, int size) void GetBitContext::debug(const char *prefix) { - printf("%s: %d\n", prefix, index); + print("%s: %d\n", prefix, index); } //VLC specific code from bitstream.c diff --git a/project/jni/application/gemrb/gemrb/plugins/BMPImporter/BMPImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/BMPImporter/BMPImporter.cpp index 284aa00c7..d82c90333 100644 --- a/project/jni/application/gemrb/gemrb/plugins/BMPImporter/BMPImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/BMPImporter/BMPImporter.cpp @@ -93,8 +93,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 ); + printMessage("BMPImporter", "Compressed %d-bits Image, not supported.\n", LIGHT_RED, BitCount); return false; } //COLORTABLE @@ -136,8 +135,7 @@ bool BMPImporter::Open(DataStream* stream) PaddedRowLength = ( Width >> 1 ); break; default: - printMessage( "BMPImporter"," ", LIGHT_RED); - printf( "BitCount %d is not supported.\n", BitCount ); + printMessage("BMPImporter", "BitCount %d is not supported.\n", LIGHT_RED, BitCount); return false; } //if(BitCount!=4) @@ -274,8 +272,7 @@ Bitmap* BMPImporter::GetBitmap() } break; case 24: - printMessage("BMPImporter", "Don't know how to handle 24bit bitmap from ", WHITE); - printf( "%s...", str->filename ); + printMessage("BMPImporter", "Don't know how to handle 24bit bitmap from %s...", WHITE, str->filename); printStatus( "ERROR", LIGHT_RED ); for (y = 0; y < Height; y++) { for (unsigned int x = 0; x < Width; x++) { @@ -288,8 +285,36 @@ Bitmap* BMPImporter::GetBitmap() return data; } +Image* BMPImporter::GetImage() +{ + Image *data = new Image(Width,Height); + + unsigned char *p = ( unsigned char * ) pixels; + switch (BitCount) { + case 8: + 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 24: + for (y = 0; y < Height; y++) { + for (unsigned int x = 0; x < Width; x++) { + unsigned idx = 3*(y*Width + x); + Color c = {p[idx+2], p[idx+1], p[idx+0], 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/project/jni/application/gemrb/gemrb/plugins/BMPImporter/BMPImporter.h b/project/jni/application/gemrb/gemrb/plugins/BMPImporter/BMPImporter.h index 2470a3556..94028a491 100644 --- a/project/jni/application/gemrb/gemrb/plugins/BMPImporter/BMPImporter.h +++ b/project/jni/application/gemrb/gemrb/plugins/BMPImporter/BMPImporter.h @@ -44,6 +44,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; } diff --git a/project/jni/application/gemrb/gemrb/plugins/CHUImporter/CHUImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/CHUImporter/CHUImporter.cpp index 4d9609d04..5cdc488b2 100644 --- a/project/jni/application/gemrb/gemrb/plugins/CHUImporter/CHUImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/CHUImporter/CHUImporter.cpp @@ -34,31 +34,26 @@ #include "GUI/Slider.h" #include "GUI/TextArea.h" #include "GUI/TextEdit.h" +#include "GUI/Window.h" 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) { @@ -106,8 +101,7 @@ Window* CHUImporter::GetWindow(unsigned int wid) ResourceHolder 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 ); diff --git a/project/jni/application/gemrb/gemrb/plugins/CHUImporter/CHUImporter.h b/project/jni/application/gemrb/gemrb/plugins/CHUImporter/CHUImporter.h index 512bb7397..e8b577f3d 100644 --- a/project/jni/application/gemrb/gemrb/plugins/CHUImporter/CHUImporter.h +++ b/project/jni/application/gemrb/gemrb/plugins/CHUImporter/CHUImporter.h @@ -42,7 +42,7 @@ 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/project/jni/application/gemrb/gemrb/plugins/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/CMakeLists.txt index 6c48216d3..ce29b3a23 100644 --- a/project/jni/application/gemrb/gemrb/plugins/CMakeLists.txt +++ b/project/jni/application/gemrb/gemrb/plugins/CMakeLists.txt @@ -29,6 +29,7 @@ ADD_SUBDIRECTORY( PLTImporter ) ADD_SUBDIRECTORY( PNGImporter ) ADD_SUBDIRECTORY( PROImporter ) ADD_SUBDIRECTORY( PSTOpcodes ) +ADD_SUBDIRECTORY( SAVImporter ) ADD_SUBDIRECTORY( SDLAudio ) ADD_SUBDIRECTORY( SDLVideo ) ADD_SUBDIRECTORY( SPLImporter ) diff --git a/project/jni/application/gemrb/gemrb/plugins/CREImporter/CREImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/CREImporter/CREImporter.cpp index a28e3010b..d41b7b38b 100644 --- a/project/jni/application/gemrb/gemrb/plugins/CREImporter/CREImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/CREImporter/CREImporter.cpp @@ -26,6 +26,8 @@ #include "EffectMgr.h" #include "GameData.h" #include "Interface.h" +#include "PluginMgr.h" +#include "TableMgr.h" #include "GameScript/GameScript.h" #include @@ -170,7 +172,7 @@ int ResolveSpellName(ieResRef name, int level, ieIWD2SpellType type) } //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; @@ -231,7 +233,7 @@ const ieResRef *ResolveSpellIndex(int index, int level, ieIWD2SpellType type, in return NULL; } -void ReleaseMemoryCRE() +static void ReleaseMemoryCRE() { if (randcolors) { delete [] randcolors; @@ -338,7 +340,6 @@ static void InitSpellbook() CREImporter::CREImporter(void) { str = NULL; - autoFree = false; TotSCEFF = 0xff; CREVersion = 0xff; InitSpellbook(); @@ -346,21 +347,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 +390,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 ); + printMessage("CREImporter", "Not a CRE File or File Version not supported: %8.8s\n", LIGHT_RED, Signature); return false; } @@ -794,9 +789,7 @@ Actor* CREImporter::GetActor(unsigned char is_in_party) break; default: Inventory_Size=0; - printMessage("CREImporter","Unknown creature signature: ", RED); - printf("%d\n", CREVersion); - abort(); + error("CREImporter", "Unknown creature signature: %d\n", CREVersion); } // Read saved effects @@ -1056,8 +1049,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); + printMessage("CREImporter", "Invalid item index (%d) in creature!\n", LIGHT_RED, index); continue; } //20 is the size of CREItem on disc (8+2+3x2+4) @@ -1068,8 +1060,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); + printMessage("CREImporter", "Invalid item index (%d) in creature!\n", LIGHT_RED, index); } } } @@ -1114,15 +1105,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); + print("[CREImporter]: Duplicate memorized spell (%d) in creature!\n", k); } } i=KnownSpellsCount; while(i--) { if (known_spells[i]) { - printMessage("CREImporter"," ", YELLOW); - printf("Dangling spell in creature: %s!\n", known_spells[i]->SpellResRef); + printMessage("CREImporter", "Dangling spell in creature: %s!\n", YELLOW, + known_spells[i]->SpellResRef); delete known_spells[i]; } } @@ -1131,8 +1122,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); + printMessage("CREImporter", "Dangling spell in creature: %s!\n", YELLOW, + memorized_spells[i]->SpellResRef); delete memorized_spells[i]; } } @@ -1467,8 +1458,8 @@ 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); + printMessage("CREImporter", "Unresolved spell index: %d level:%d, type: %d\n", LIGHT_RED, + spellindex, level+1, type); } } str->ReadDword(&tmpDword); @@ -2691,7 +2682,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 +2696,7 @@ int CREImporter::PutMemorizedSpells(DataStream *stream, Actor *actor) for (int i=0;ispellbook.GetSpellLevelCount(i); for (unsigned int j=0;jspellbook.GetMemorizedSpellsCount(i,j); + unsigned int count = actor->spellbook.GetMemorizedSpellsCount(i,j, false); for (unsigned int k=0;kspellbook.GetMemorizedSpell(i,j,k); diff --git a/project/jni/application/gemrb/gemrb/plugins/CREImporter/CREImporter.h b/project/jni/application/gemrb/gemrb/plugins/CREImporter/CREImporter.h index a0417e15b..1ac0086de 100644 --- a/project/jni/application/gemrb/gemrb/plugins/CREImporter/CREImporter.h +++ b/project/jni/application/gemrb/gemrb/plugins/CREImporter/CREImporter.h @@ -22,6 +22,10 @@ #define CREIMPORTER_H #include "ActorMgr.h" +#include "Spellbook.h" + +class CREItem; +struct Effect; #define IE_CRE_GEMRB 0 #define IE_CRE_V1_0 10 //bg1 @@ -33,7 +37,6 @@ class CREImporter : public ActorMgr { private: DataStream* str; - bool autoFree; unsigned char CREVersion; ieDword KnownSpellsOffset; ieDword KnownSpellsCount; @@ -61,7 +64,7 @@ private: public: CREImporter(void); ~CREImporter(void); - bool Open(DataStream* stream, bool autoFree = true); + bool Open(DataStream* stream); Actor* GetActor(unsigned char is_in_party); //returns saved size, updates internal offsets before save diff --git a/project/jni/application/gemrb/gemrb/plugins/DLGImporter/DLGImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/DLGImporter/DLGImporter.cpp index 576831bfb..55a3a0023 100644 --- a/project/jni/application/gemrb/gemrb/plugins/DLGImporter/DLGImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/DLGImporter/DLGImporter.cpp @@ -29,27 +29,21 @@ 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) { @@ -166,7 +160,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 ); @@ -175,13 +169,13 @@ Condition* GetCondition(char* string) Trigger *trigger = GenerateTrigger(lines[i]); if (!trigger) { printMessage( "DLGImporter", "Can't compile trigger: " ,YELLOW); - printf("%s\n", lines[i]); + print("%s\n", 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; } @@ -248,17 +242,19 @@ std::vector DLGImporter::GetAction(unsigned int index) const Action *action = GenerateAction(lines[i]); if (!action) { printMessage( "DLGImporter", "Can't compile action: " ,YELLOW); - printf("%s\n", lines[i]); + print("%s\n", 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 +299,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/project/jni/application/gemrb/gemrb/plugins/DLGImporter/DLGImporter.h b/project/jni/application/gemrb/gemrb/plugins/DLGImporter/DLGImporter.h index 10cade568..8a0b7fc25 100644 --- a/project/jni/application/gemrb/gemrb/plugins/DLGImporter/DLGImporter.h +++ b/project/jni/application/gemrb/gemrb/plugins/DLGImporter/DLGImporter.h @@ -53,7 +53,6 @@ struct VarOffset { class DLGImporter : public DialogMgr { private: DataStream* str; - bool autoFree; ieDword StatesCount; ieDword StatesOffset; ieDword TransitionsCount; @@ -70,7 +69,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; diff --git a/project/jni/application/gemrb/gemrb/plugins/DirectoryImporter/DirectoryImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/DirectoryImporter/DirectoryImporter.cpp index 9a4ba399c..d2a448289 100644 --- a/project/jni/application/gemrb/gemrb/plugins/DirectoryImporter/DirectoryImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/DirectoryImporter/DirectoryImporter.cpp @@ -37,6 +37,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 +50,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 +87,93 @@ 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; + + char buf[_MAX_PATH]; + do { + if (it.IsDirectory()) + continue; + const char *name = it.GetName(); + strnlwrcpy(buf, name, _MAX_PATH, false); + if (cache.find(buf) != cache.end()) { + printMessage("CachedDirectoryImporter", "Duplicate '%s' files in '%s' directory", LIGHT_RED, buf, path); + } + cache[buf] = name; + } 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.find(filename) != cache.end()); +} + +bool CachedDirectoryImporter::HasResource(const char* resname, const ResourceDesc &type) +{ + const char* filename = ConstructFilename(resname, type.GetExt()); + return (cache.find(filename) != cache.end()); +} + +DataStream* CachedDirectoryImporter::GetResource(const char* resname, SClass_ID type) +{ + const char* filename = ConstructFilename(resname, core->TypeExt(type)); + std::map::const_iterator it = cache.find(filename); + if (it == cache.end()) + return NULL; + char buf[_MAX_PATH]; + strcpy(buf, path); + PathAppend(buf, it->second.c_str()); + return FileStream::OpenFile(buf); +} + +DataStream* CachedDirectoryImporter::GetResource(const char* resname, const ResourceDesc &type) +{ + const char* filename = ConstructFilename(resname, type.GetExt()); + std::map::const_iterator it = cache.find(filename); + if (it == cache.end()) + return NULL; + char buf[_MAX_PATH]; + strcpy(buf, path); + PathAppend(buf, it->second.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/project/jni/application/gemrb/gemrb/plugins/DirectoryImporter/DirectoryImporter.h b/project/jni/application/gemrb/gemrb/plugins/DirectoryImporter/DirectoryImporter.h index 46a0c8475..fde1e4d9b 100644 --- a/project/jni/application/gemrb/gemrb/plugins/DirectoryImporter/DirectoryImporter.h +++ b/project/jni/application/gemrb/gemrb/plugins/DirectoryImporter/DirectoryImporter.h @@ -29,8 +29,9 @@ class Resource; class ResourceDesc; class DirectoryImporter : public ResourceSource { -private: +protected: char path[_MAX_PATH]; + public: DirectoryImporter(void); ~DirectoryImporter(void); @@ -43,4 +44,23 @@ public: DataStream* GetResource(const char* resname, const ResourceDesc &type); }; +class CachedDirectoryImporter : public DirectoryImporter { +protected: + std::map 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/project/jni/application/gemrb/gemrb/plugins/EFFImporter/EFFImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/EFFImporter/EFFImporter.cpp index 5da8be8a6..5fa273749 100644 --- a/project/jni/application/gemrb/gemrb/plugins/EFFImporter/EFFImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/EFFImporter/EFFImporter.cpp @@ -63,7 +63,7 @@ bool EFFImporter::Open(DataStream* stream, bool autoFree) //if level>than maximum affected or levelDiceSides > 0 || fx->DiceThrown > 0) { fx->MinAffectedLevel = fx->DiceThrown; fx->MaxAffectedLevel = fx->DiceSides; @@ -197,23 +197,25 @@ void EFFImporter::PutEffectV2(DataStream *stream, const Effect *fx) { stream->WriteDword( &fx->Duration); stream->WriteWord( &fx->Probability1); stream->WriteWord( &fx->Probability2); - stream->WriteResRef(fx->Resource); + 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 ); 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 +233,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/project/jni/application/gemrb/gemrb/plugins/EFFImporter/EFFImporter.h b/project/jni/application/gemrb/gemrb/plugins/EFFImporter/EFFImporter.h index b97825761..ef5b5e44f 100644 --- a/project/jni/application/gemrb/gemrb/plugins/EFFImporter/EFFImporter.h +++ b/project/jni/application/gemrb/gemrb/plugins/EFFImporter/EFFImporter.h @@ -36,6 +36,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); diff --git a/project/jni/application/gemrb/gemrb/plugins/FXOpcodes/FXOpcodes.cpp b/project/jni/application/gemrb/gemrb/plugins/FXOpcodes/FXOpcodes.cpp index ee921da60..256eecf76 100644 --- a/project/jni/application/gemrb/gemrb/plugins/FXOpcodes/FXOpcodes.cpp +++ b/project/jni/application/gemrb/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" @@ -65,6 +67,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 @@ -435,7 +438,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 }, @@ -884,7 +887,7 @@ inline void HandlePercentageDamage(Effect *fx, Actor *target) { // 0x00 ACVsDamageTypeModifier 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 ); + if (0) print( "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(); @@ -930,7 +933,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); int tmp = (signed) fx->Parameter1; if (fx->Parameter2!=2) { if (tmp>10) tmp=10; @@ -957,7 +960,7 @@ 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\n", 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 +971,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\n", 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; @@ -1018,7 +1021,7 @@ 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\n", 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 +1031,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //blood rage berserking gives immunity to charm (in iwd2) if (target->HasSpellState(SS_BLOODRAGE)) { @@ -1127,7 +1130,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) { BASE_MOD( IE_CHR ); @@ -1141,7 +1144,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); EffectQueue::HackColorEffects(target, fx); target->SetColor( fx->Parameter2, fx->Parameter1 ); return FX_APPLIED; @@ -1150,7 +1153,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\n", 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 +1164,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); target->SetColorMod(0xff, RGBModifier::ADD, -1, fx->Parameter1 >> 8, fx->Parameter1 >> 16, fx->Parameter1 >> 24); @@ -1172,7 +1175,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); EffectQueue::HackColorEffects(target, fx); ieDword location = fx->Parameter2 & 0xff; int speed = (fx->Parameter2 >> 16) & 0xFF; @@ -1186,7 +1189,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); int speed = (fx->Parameter2 >> 16) & 0xFF; target->SetColorMod(0xff, RGBModifier::ADD, speed, @@ -1199,7 +1202,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) { BASE_MOD( IE_CON ); @@ -1214,7 +1217,7 @@ 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\n", 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 +1229,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //save for half damage type ieDword damagetype = fx->Parameter2>>16; ieDword modtype = fx->Parameter2&3; @@ -1243,7 +1246,7 @@ int fx_damage (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 0x0d Death 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); ieDword damagetype = 0; switch (fx->Parameter2) { case 1: @@ -1296,7 +1299,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); BASE_STATE_CURE( STATE_FROZEN ); return FX_NOT_APPLIED; } @@ -1335,7 +1338,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); ////how cat's grace: value is based on class if (fx->Parameter2==3) { @@ -1356,7 +1359,7 @@ static EffectRef fx_set_slow_state_ref = { "State:Slowed", -1 }; // 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\n", 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) { @@ -1397,7 +1400,7 @@ int fx_set_hasted_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 0x11 CurrentHPModifier 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (fx->Parameter2&0x10000) { Point p(fx->PosX, fx->PosY); @@ -1429,7 +1432,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\n", 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 +1499,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) { BASE_MOD( IE_INT ); @@ -1549,7 +1552,7 @@ int fx_set_invisible_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_LORE ); return FX_APPLIED; @@ -1558,7 +1561,7 @@ int fx_lore_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_LUCK ); STAT_MOD( IE_DAMAGELUCK ); @@ -1568,7 +1571,7 @@ int fx_luck_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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\n", 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 +1581,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)\n", fx->Opcode ); if (target->HasSpellState(SS_BLOODRAGE)) { return FX_NOT_APPLIED; @@ -1598,7 +1601,13 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); + + 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; @@ -1649,7 +1658,7 @@ 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\n", fx->Opcode, fx->Resource, fx->Parameter2 ); switch(fx->Parameter2) { @@ -1691,7 +1700,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_RESISTACID ); return FX_APPLIED; @@ -1700,7 +1709,7 @@ int fx_acid_resistance_modifier (Scriptable* /*Owner*/, Actor* target, Effect* f // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_RESISTCOLD ); return FX_APPLIED; @@ -1709,7 +1718,7 @@ int fx_cold_resistance_modifier (Scriptable* /*Owner*/, Actor* target, Effect* f // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_RESISTELECTRICITY ); return FX_APPLIED; @@ -1718,7 +1727,7 @@ int fx_electricity_resistance_modifier (Scriptable* /*Owner*/, Actor* target, Ef // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_RESISTFIRE ); return FX_APPLIED; @@ -1727,7 +1736,7 @@ int fx_fire_resistance_modifier (Scriptable* /*Owner*/, Actor* target, Effect* f // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_MAGICDAMAGERESISTANCE ); return FX_APPLIED; @@ -1736,7 +1745,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\n", 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,7 +1757,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); HandleBonus( target, IE_SAVEVSDEATH, fx->Parameter1, fx->TimingMode ); return FX_APPLIED; @@ -1757,7 +1766,7 @@ int fx_save_vs_death_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); HandleBonus( target, IE_SAVEVSWANDS, fx->Parameter1, fx->TimingMode ); return FX_APPLIED; @@ -1766,7 +1775,7 @@ int fx_save_vs_wands_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); HandleBonus( target, IE_SAVEVSPOLY, fx->Parameter1, fx->TimingMode ); return FX_APPLIED; @@ -1775,7 +1784,7 @@ int fx_save_vs_poly_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); HandleBonus( target, IE_SAVEVSBREATH, fx->Parameter1, fx->TimingMode ); return FX_APPLIED; @@ -1784,7 +1793,7 @@ int fx_save_vs_breath_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); HandleBonus( target, IE_SAVEVSSPELL, fx->Parameter1, fx->TimingMode ); return FX_APPLIED; @@ -1793,7 +1802,7 @@ int fx_save_vs_spell_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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 ); + if (0) print( "fx_set_silenced_state (%2d)\n", fx->Opcode ); STATE_SET( STATE_SILENCED ); return FX_APPLIED; } @@ -1805,7 +1814,7 @@ static EffectRef fx_animation_stance_ref = { "AnimationStateChange", -1 }; // 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\n", fx->Opcode, fx->Parameter2 ); if (target->HasSpellState(SS_BLOODRAGE)) { return FX_NOT_APPLIED; @@ -1838,7 +1847,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //iwd2 free action or aegis disables this effect if (target->HasSpellState(SS_FREEACTION)) return FX_NOT_APPLIED; @@ -1861,7 +1870,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (!target) { return FX_NOT_APPLIED; } @@ -1879,7 +1888,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); int i=1; //if param2 is 0, then double spells up to param1 @@ -1910,7 +1919,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); BASE_STATE_CURE( STATE_PETRIFIED ); return FX_NOT_APPLIED; } @@ -1918,7 +1927,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); ////how strength: value is based on class ////pst power of one also depends on this! @@ -1955,7 +1964,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //actually the original engine just skips this effect if the target is dead if ( STATE_GET(STATE_DEAD) ) { @@ -1987,7 +1996,7 @@ 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\n", 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); @@ -2002,7 +2011,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (!STATE_GET(STATE_NONDET)) { if (pstflags) { BASE_STATE_CURE( STATE_PST_INVIS ); @@ -2019,7 +2028,7 @@ 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\n", 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 +2037,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) { BASE_MOD( IE_WIS ); @@ -2041,7 +2050,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); int speed = (fx->Parameter2 >> 16) & 0xff; target->SetColorMod(0xff, RGBModifier::ADD, speed, @@ -2054,7 +2063,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\n", 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 +2074,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); EffectQueue::HackColorEffects(target, fx); ieDword location = fx->Parameter2 & 0xff; target->SetColorMod(location, RGBModifier::BRIGHTEN, -1, @@ -2080,7 +2089,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); switch (fx->Parameter2) { case 0: //non permanent animation change @@ -2100,7 +2109,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); HandleBonus( target, IE_TOHIT, fx->Parameter1, fx->TimingMode ); return FX_APPLIED; @@ -2111,7 +2120,7 @@ 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\n", 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); @@ -2137,7 +2146,7 @@ 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}; 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)\n", fx->Opcode ); register ieDword newalign = target->GetStat( IE_ALIGNMENT ); //compress the values. GNE is the first 2 bits originally //LNC is the 4/5. bits. @@ -2160,7 +2169,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\n", fx->Opcode, fx->Parameter2 ); STAT_SET( IE_ALIGNMENT, fx->Parameter2 ); return FX_APPLIED; } @@ -2168,7 +2177,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); ieResRef Removed; ieDword level; @@ -2196,7 +2205,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_STEALTH ); return FX_APPLIED; @@ -2205,7 +2214,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); switch (fx->Parameter2) { case 3: @@ -2234,7 +2243,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); switch(fx->Parameter2) { case 0: @@ -2253,7 +2262,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); int i=1; //if param2 is 0, then double spells up to param1 @@ -2284,7 +2293,7 @@ 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 ); + if (0) print( "fx_set_infravision_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STATE_SET( STATE_INFRA ); return FX_APPLIED; } @@ -2294,7 +2303,7 @@ 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\n", 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 +2312,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)\n", fx->Opcode ); //death stops this effect if (STATE_GET( STATE_DEAD) ) { return FX_NOT_APPLIED; @@ -2323,7 +2332,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //maybe this needs some timing switch (fx->Parameter2) { @@ -2352,7 +2361,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\n", fx->Opcode, fx->Resource, fx->Resource2, fx->Parameter2 ); //summon creature (resource), play vvc (resource2) //creature's lastsummoner is Owner @@ -2375,7 +2384,7 @@ 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)\n", fx->Opcode ); //to be compatible with the original engine, unsummon doesn't work with PC's //but it works on anything else @@ -2396,7 +2405,7 @@ int fx_unsummon_creature (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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 ); + if (0) print( "fx_set_nondetection_state (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STATE_SET( STATE_NONDET ); return FX_APPLIED; } @@ -2406,7 +2415,7 @@ 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\n", 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 +2424,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); ieDword value; if (fx->Parameter2) { value = fx->Parameter1; @@ -2438,7 +2447,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); switch (fx->Parameter2) { case 0: STAT_SET(IE_EA, fx->Parameter1); @@ -2471,7 +2480,7 @@ int fx_ids_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_DAMAGEBONUS ); return FX_APPLIED; @@ -2480,7 +2489,7 @@ int fx_damage_bonus_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //pst power word blind projectile support if (fx->Parameter2==1) { @@ -2513,7 +2522,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); BASE_STATE_CURE( STATE_BLIND ); target->fxqueue.RemoveAllEffects(fx_set_blind_state_ref); return FX_NOT_APPLIED; @@ -2522,7 +2531,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STATE_SET( STATE_FEEBLE ); STAT_SET( IE_INT, 3); if (enhanced_effects) { @@ -2536,7 +2545,7 @@ 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\n", 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); @@ -2544,13 +2553,19 @@ int fx_cure_feebleminded_state (Scriptable* /*Owner*/, Actor* target, Effect* fx } // 0x4e State:Diseased +static EffectRef fx_diseased_state_ref = { "State:Diseased", -1 }; 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\n", 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; @@ -2612,11 +2627,9 @@ int fx_set_diseased_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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\n", 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; @@ -2627,7 +2640,7 @@ int fx_cure_diseased_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //gemrb fix if (target->SetSpellState(SS_DEAF)) return FX_APPLIED; @@ -2649,7 +2662,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //gemrb fix if (target->SetSpellState(SS_DEAF)) return FX_APPLIED; @@ -2675,7 +2688,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); target->fxqueue.RemoveAllEffects(fx_deaf_state_ref); target->fxqueue.RemoveAllEffects(fx_deaf_state_iwd2_ref); @@ -2685,7 +2698,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\n", fx->Opcode, fx->Resource, fx->Parameter2 ); target->SetScript (fx->Resource, fx->Parameter2); return FX_NOT_APPLIED; } @@ -2693,7 +2706,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\n", fx->Opcode, fx->Parameter2 ); STAT_BIT_OR( IE_IMMUNITY, IMM_PROJECTILE); return FX_APPLIED; } @@ -2701,7 +2714,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_RESISTMAGICFIRE ); return FX_APPLIED; @@ -2710,7 +2723,7 @@ int fx_magical_fire_resistance_modifier (Scriptable* /*Owner*/, Actor* target, E // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_RESISTMAGICCOLD ); return FX_APPLIED; @@ -2719,7 +2732,7 @@ int fx_magical_cold_resistance_modifier (Scriptable* /*Owner*/, Actor* target, E // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_RESISTSLASHING ); return FX_APPLIED; @@ -2728,7 +2741,7 @@ int fx_slashing_resistance_modifier (Scriptable* /*Owner*/, Actor* target, Effec // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_RESISTCRUSHING ); return FX_APPLIED; @@ -2737,7 +2750,7 @@ int fx_crushing_resistance_modifier (Scriptable* /*Owner*/, Actor* target, Effec // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_RESISTPIERCING ); return FX_APPLIED; @@ -2746,7 +2759,7 @@ int fx_piercing_resistance_modifier (Scriptable* /*Owner*/, Actor* target, Effec // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_RESISTMISSILE ); return FX_APPLIED; @@ -2755,7 +2768,7 @@ int fx_missiles_resistance_modifier (Scriptable* /*Owner*/, Actor* target, Effec // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_LOCKPICKING ); return FX_APPLIED; @@ -2764,7 +2777,7 @@ int fx_open_locks_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_TRAPS ); return FX_APPLIED; @@ -2773,7 +2786,7 @@ int fx_find_traps_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_PICKPOCKET ); return FX_APPLIED; @@ -2782,7 +2795,7 @@ int fx_pick_pockets_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_FATIGUE ); // TODO: fatigue has a negative effect on luck -> add fatigmod.2da support @@ -2792,7 +2805,7 @@ int fx_fatigue_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_INTOXICATION ); return FX_APPLIED; @@ -2801,7 +2814,7 @@ int fx_intoxication_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_TRACKING ); return FX_APPLIED; @@ -2810,7 +2823,7 @@ int fx_tracking_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_LEVEL ); return FX_APPLIED; @@ -2819,7 +2832,7 @@ int fx_level_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_STREXTRA ); return FX_APPLIED; @@ -2828,23 +2841,20 @@ int fx_strength_bonus_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx // 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\n", 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 our first call gets through } 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,16 +2865,16 @@ 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; } @@ -2878,7 +2888,7 @@ int fx_set_regenerating_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); switch (fx->Parameter2) { case 0: @@ -2895,14 +2905,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\n", 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\n", fx->Opcode, fx->Parameter2 ); STAT_BIT_OR(IE_IMMUNITY, IMM_OPCODE); return FX_APPLIED; } @@ -2910,7 +2920,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\n", fx->Opcode, fx->Parameter1); int value = fx->Parameter1; if (value<9) { @@ -2924,7 +2934,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\n", fx->Opcode, fx->Parameter1 ); //this also changes the base stat target->SetName(fx->Parameter1, 0); return FX_NOT_APPLIED; @@ -2933,7 +2943,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //FIXME: this has mode too //target->AddExperience (fx->Parameter1); STAT_MOD( IE_XP ); @@ -2945,7 +2955,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (!target->InParty) { STAT_MOD( IE_GOLD ); return FX_NOT_APPLIED; @@ -2974,7 +2984,7 @@ 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 ); + if (0) print( "fx_morale_break_modifier (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD(IE_MORALEBREAK); return FX_PERMANENT; //permanent morale break doesn't stick } @@ -2982,7 +2992,7 @@ int fx_morale_break_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 0x6b PortraitChange 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 ); + if (0) print( "fx_portrait_change (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); target->SetPortrait( fx->Resource, fx->Parameter2); return FX_NOT_APPLIED; } @@ -2990,7 +3000,7 @@ int fx_portrait_change (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD(IE_REPUTATION); return FX_NOT_APPLIED; //needs testing } @@ -3049,7 +3059,7 @@ 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 ); + if (0) print( "fx_dither (%2d): Value: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //this effect doesn't work in any engine versions return FX_NOT_APPLIED; } @@ -3122,7 +3132,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); Map *map = NULL; if (target) { @@ -3146,7 +3156,7 @@ 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 ); + if (0) print( "fx_reveal_creatures (%2d): Value: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //reveals creatures (not working in original IE) return FX_NOT_APPLIED; } @@ -3156,7 +3166,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); ieDword images; if (fx->Parameter2) { @@ -3192,7 +3202,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (!fx->FirstApply) return FX_APPLIED; int level; @@ -3258,7 +3268,7 @@ int fx_immune_to_weapon (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx) 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 ); + if (0) print( "fx_visual_animation_effect (%2d)\n", fx->Opcode ); return FX_NOT_APPLIED; } @@ -3267,7 +3277,7 @@ 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)\n", 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,7 +3292,7 @@ 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)\n", 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); @@ -3293,7 +3303,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\n", fx->Opcode, fx->Parameter2 ); Point p; switch(fx->Parameter2) @@ -3330,17 +3340,17 @@ 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]\n", 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); +print("KNOCK Pos: %d.%d\n", fx->PosX, fx->PosY); Door *door = map->TMap->GetDoorByPosition(p); if (door) { -printf("Got a door\n"); +print("Got a door\n"); if (door->LockDifficulty<100) { door->SetDoorLocked(false, true); } @@ -3348,7 +3358,7 @@ printf("Got a door\n"); } Container *container = map->TMap->GetContainerByPosition(p); if (container) { -printf("Got a container\n"); +print("Got a container\n"); if(container->LockDifficulty<100) { container->SetContainerLocked(false); } @@ -3361,7 +3371,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //iwd2 freeaction disables only 0xb0, who cares if (target->HasSpellState(SS_FREEACTION)) return FX_NOT_APPLIED; @@ -3380,7 +3390,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //check the summoning limit? if (!Owner) { return FX_NOT_APPLIED; @@ -3445,7 +3455,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (target->HasSpellState(SS_BLOODRAGE)) { return FX_NOT_APPLIED; @@ -3469,7 +3479,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (!fx->Parameter2) { fx->Parameter2=core->Roll(fx->Parameter1,8,0); } @@ -3503,7 +3513,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (STATE_GET (STATE_BLESS) ) //bless is non cumulative return FX_NOT_APPLIED; @@ -3524,7 +3534,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (STATE_GET (STATE_CHANT) ) //chant is non cumulative return FX_NOT_APPLIED; @@ -3537,7 +3547,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\n", fx->Opcode, fx->Parameter1 ); if (STATE_GET (STATE_HOLY) ) //holy power is non cumulative return FX_NOT_APPLIED; @@ -3557,7 +3567,7 @@ 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\n", fx->Opcode, fx->Parameter1); if (STATE_GET (STATE_LUCK) ) //this luck is non cumulative return FX_NOT_APPLIED; @@ -3571,7 +3581,7 @@ int fx_luck_non_cumulative (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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\n", fx->Opcode, fx->Parameter1); target->SetSpellState(SS_LUCK); STAT_ADD( IE_LUCK, fx->Parameter1 ); @@ -3582,7 +3592,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); BASE_STATE_SET( STATE_PETRIFIED ); return FX_NOT_APPLIED; //permanent effect @@ -3622,7 +3632,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (!gamedata->Exists(fx->Resource,IE_CRE_CLASS_ID)) { //kill all polymorph effects @@ -3675,7 +3685,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (pstflags) { BASE_STATE_CURE(STATE_PST_INVIS); @@ -3690,7 +3700,7 @@ int fx_force_visible (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (STATE_GET (STATE_CHANTBAD) ) //chant is non cumulative return FX_NOT_APPLIED; @@ -3703,7 +3713,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\n", fx->Opcode, fx->Parameter2 ); //this effect works only on living actors if ( !STATE_GET(STATE_DEAD) ) { @@ -3719,7 +3729,7 @@ static EffectRef fx_protection_from_display_string_ref = { "Protection:String", 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\n", fx->Opcode, fx->Parameter1 ); if(fx->Resource[0]) { //TODO: create a single list reader that handles src and 2da too SrcVector *rndstr=LoadSrc(fx->Resource); @@ -3751,7 +3761,7 @@ static const int xpos_by_direction[16]={0,-10,-12,-14,-16,-14,-12,-10,0,10,12,14 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\n", fx->Opcode, fx->Parameter2 ); if (cgcount<0) { cgcount = core->ReadResRefTable("cgtable",casting_glows); } @@ -3788,7 +3798,7 @@ int fx_casting_glow (Scriptable* /*Owner*/, Actor* target, Effect* fx) //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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (shcount<0) { shcount = core->ReadResRefTable("shtable",spell_hits); } @@ -3820,7 +3830,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\n", fx->Parameter2); } return FX_NOT_APPLIED; } @@ -3828,7 +3838,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\n", fx->Opcode, fx->Parameter2 ); target->AddPortraitIcon(fx->Parameter2); return FX_APPLIED; } @@ -3836,7 +3846,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\n", 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 +3862,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\n", 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_*) @@ -3885,7 +3895,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\n", fx->Opcode, fx->Parameter2 ); bool display_warning = false; ieDword tmp = fx->Parameter2+1; @@ -3913,7 +3923,7 @@ 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] ); } } @@ -3927,7 +3937,7 @@ 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 (0) print( "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); @@ -3956,7 +3966,7 @@ int fx_cast_spell (Scriptable* Owner, Actor* target, Effect* fx) // 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 Mode: %d\n", fx->Opcode, fx->Resource, 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 @@ -3967,7 +3977,7 @@ int fx_learn_spell (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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\n", 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)); @@ -3983,7 +3993,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\n", fx->Opcode, fx->Resource, fx->Parameter2 ); if (target->InParty) { BASE_SET (IE_IDENTIFYMODE, 1); core->SetEventFlag(EF_IDENTIFY); @@ -4000,7 +4010,7 @@ 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)\n", fx->Opcode ); //reveal trapped containers, doors, triggers that are in the visible range ieDword range = target->GetStat(IE_VISUALRANGE)*10; ieDword skill; @@ -4072,7 +4082,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\n", fx->Opcode, fx->Resource ); //this safeguard exists in the original engine too if (!gamedata->Exists(fx->Resource,IE_CRE_CLASS_ID)) { @@ -4107,7 +4117,7 @@ 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\n", fx->Opcode, fx->Resource ); core->PlayMovie (fx->Resource); return FX_NOT_APPLIED; } @@ -4119,7 +4129,7 @@ static const ieDword fullwhite[7]={ICE_GRADIENT,ICE_GRADIENT,ICE_GRADIENT,ICE_GR 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 (0) print( "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 (!fx->Parameter2) { fx->Parameter2=1; @@ -4138,7 +4148,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //iwd2 effects that disable entangle if (target->HasSpellState(SS_FREEACTION)) return FX_NOT_APPLIED; @@ -4154,7 +4164,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //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 +4174,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //the shield vanishes on dead if (STATE_GET(STATE_DEAD) ) { return FX_NOT_APPLIED; @@ -4176,7 +4186,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //iwd2 effects that disable web if (target->HasSpellState(SS_FREEACTION)) return FX_NOT_APPLIED; @@ -4192,7 +4202,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //iwd2 effects that disable grease if (target->HasSpellState(SS_FREEACTION)) return FX_NOT_APPLIED; @@ -4207,7 +4217,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\n", fx->Opcode, fx->Parameter1 ); if (STATE_GET(STATE_DEAD) ) { return FX_NOT_APPLIED; } @@ -4235,7 +4245,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_SET( IE_SANCTUARY, 0); target->fxqueue.RemoveAllEffects(fx_sanctuary_state_ref); return FX_NOT_APPLIED; @@ -4246,7 +4256,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); BASE_STATE_CURE( STATE_PANIC ); target->fxqueue.RemoveAllEffects(fx_set_panic_state_ref); return FX_NOT_APPLIED; @@ -4257,7 +4267,7 @@ 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\n", 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); @@ -4270,7 +4280,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); target->fxqueue.RemoveAllEffects( fx_movement_modifier_ref ); // STATE_CURE( STATE_SLOWED ); return FX_NOT_APPLIED; @@ -4281,7 +4291,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); target->fxqueue.RemoveAllEffects( fx_intoxication_ref ); BASE_SET(IE_INTOXICATION,0); return FX_NOT_APPLIED; @@ -4290,7 +4300,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_CASTERHOLD ); return FX_PERMANENT; } @@ -4298,7 +4308,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_RESISTMAGIC ); return FX_APPLIED; @@ -4307,7 +4317,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_MISSILEHITBONUS ); return FX_APPLIED; @@ -4318,7 +4328,7 @@ 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)\n", fx->Opcode); Map *map = NULL; @@ -4345,7 +4355,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\n", fx->Opcode, fx->Parameter2 ); target->DisablePortraitIcon(fx->Parameter2); return FX_APPLIED; } @@ -4353,7 +4363,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //Parameter1 is a gemrb extension target->PlayDamageAnimation(fx->Parameter2, !fx->Parameter1); @@ -4363,7 +4373,7 @@ 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 ); + if (0) print( "fx_add_innate (%2d): Resource: %s Mode: %d\n", fx->Opcode, fx->Resource, fx->Parameter2 ); target->LearnSpell(fx->Resource, fx->Parameter2^LS_MEMO); //this is an instant, so it shouldn't stick return FX_NOT_APPLIED; @@ -4373,7 +4383,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\n", fx->Opcode, fx->Resource, fx->Parameter2); switch (fx->Parameter2) { default: target->spellbook.RemoveSpell(fx->Resource); @@ -4394,7 +4404,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_RESISTPOISON ); return FX_APPLIED; @@ -4403,7 +4413,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 +4428,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\n", 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 +4449,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\n", 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 +4473,44 @@ 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; - } - //newfx is a borrowed reference don't delete it + 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) { + 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 +4522,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)\n", 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 +4533,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\n", fx->Opcode, fx->Parameter2); if (target->inventory.HasItemType(fx->Parameter2) ) { core->ApplySpell(fx->Resource, target, Owner, fx->Parameter1); return FX_NOT_APPLIED; @@ -4527,7 +4544,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\n", fx->Opcode, fx->Parameter2 ); STAT_SET( IE_DONOTJUMP, fx->Parameter2 ); return FX_APPLIED; } @@ -4537,7 +4554,7 @@ 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 ); + if (0) print( "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(); @@ -4555,7 +4572,7 @@ int fx_move_to_area (Scriptable* /*Owner*/, Actor* target, Effect* fx) 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 +4581,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\n", fx->Opcode, fx->Parameter2 ); STAT_SET( IE_AURACLEANSING, fx->Parameter2 ); return FX_APPLIED; } @@ -4572,7 +4589,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\n", fx->Opcode, fx->Parameter2 ); STAT_MOD( IE_MENTALSPEED ); return FX_APPLIED; } @@ -4580,7 +4597,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\n", fx->Opcode, fx->Parameter2 ); STAT_MOD( IE_PHYSICALSPEED ); return FX_APPLIED; } @@ -4589,7 +4606,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]) { @@ -4624,7 +4641,7 @@ static EffectRef fx_maximum_hp_modifier_ref = { "MaximumHPModifier", -1 }; 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\n", fx->Opcode, fx->Parameter2 ); if (!target) { return FX_NOT_APPLIED; @@ -4716,7 +4733,7 @@ int fx_find_familiar (Scriptable* Owner, Actor* target, Effect* fx) // 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\n", fx->Opcode, fx->Parameter2 ); STAT_SET( IE_SEEINVISIBLE, fx->Parameter2 ); return FX_APPLIED; } @@ -4724,7 +4741,7 @@ 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\n", fx->Opcode, fx->Parameter2 ); STAT_SET( IE_IGNOREDIALOGPAUSE, fx->Parameter2 ); return FX_APPLIED; } @@ -4736,7 +4753,7 @@ 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\n", fx->Opcode,(signed) fx->Parameter1 ); if (! (STAT_GET(IE_STATE_ID)&STATE_NOSAVE)) { return FX_APPLIED; } @@ -4766,7 +4783,7 @@ 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)\n", fx->Opcode ); if (! (STAT_GET(IE_STATE_ID)&STATE_NOSAVE)) { core->GetGame()->familiarBlock=true; return FX_APPLIED; @@ -4778,7 +4795,7 @@ int fx_familiar_marker (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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 ); + if (0) print( "fx_bounce_projectile (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 ); STAT_BIT_OR( IE_BOUNCE, BNC_PROJECTILE ); return FX_APPLIED; } @@ -4786,7 +4803,7 @@ int fx_bounce_projectile (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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 ); + if (0) print( "fx_bounce_opcode (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 ); STAT_BIT_OR( IE_BOUNCE, BNC_OPCODE ); target->AddPortraitIcon(PI_BOUNCE2); return FX_APPLIED; @@ -4795,7 +4812,7 @@ 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 ); + if (0) print( "fx_bounce_spellevel (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 ); STAT_BIT_OR( IE_BOUNCE, BNC_LEVEL ); target->AddPortraitIcon(PI_BOUNCE2); return FX_APPLIED; @@ -4804,7 +4821,7 @@ 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 ); + if (0) print( "fx_bounce_spellevel_dec (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 ); STAT_BIT_OR( IE_BOUNCE, BNC_LEVEL_DEC ); target->AddPortraitIcon(PI_BOUNCE); return FX_APPLIED; @@ -4813,7 +4830,7 @@ 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\n", fx->Opcode, fx->Parameter2 ); STAT_BIT_OR( IE_IMMUNITY, IMM_LEVEL_DEC ); target->AddPortraitIcon(PI_BOUNCE2); return FX_APPLIED; @@ -4822,7 +4839,7 @@ 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 ); + if (0) print( "fx_bounce_school (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 ); STAT_BIT_OR( IE_BOUNCE, BNC_SCHOOL ); target->AddPortraitIcon(PI_BOUNCE2); return FX_APPLIED; @@ -4831,7 +4848,7 @@ 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 ); + if (0) print( "fx_bounce_secondary_type (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 ); STAT_BIT_OR( IE_BOUNCE, BNC_SECTYPE ); target->AddPortraitIcon(PI_BOUNCE2); return FX_APPLIED; @@ -4840,7 +4857,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\n", fx->Opcode, fx->Parameter2 ); STAT_BIT_OR( IE_IMMUNITY, IMM_SCHOOL); return FX_APPLIED; } @@ -4848,7 +4865,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\n", fx->Opcode, fx->Parameter2 ); STAT_BIT_OR( IE_IMMUNITY, IMM_SECTYPE); return FX_APPLIED; } @@ -4856,7 +4873,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\n", fx->Opcode, fx->Resource ); if (strnicmp(fx->Resource,fx->Source,sizeof(fx->Resource)) ) { STAT_BIT_OR( IE_IMMUNITY, IMM_RESOURCE); return FX_APPLIED; @@ -4868,7 +4885,7 @@ int fx_resist_spell (Scriptable* /*Owner*/, Actor* target, Effect *fx) // ??? Protection:SpellDec 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\n", fx->Opcode, fx->Resource ); if (strnicmp(fx->Resource,fx->Source,sizeof(fx->Resource)) ) { STAT_BIT_OR( IE_IMMUNITY, IMM_RESOURCE_DEC); return FX_APPLIED; @@ -4880,7 +4897,7 @@ 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 ); + if (0) print( "fx_bounce_spell (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 ); STAT_BIT_OR( IE_BOUNCE, BNC_RESOURCE ); return FX_APPLIED; } @@ -4888,7 +4905,7 @@ int fx_bounce_spell (Scriptable* /*Owner*/, Actor* target, Effect* fx) // ??? Bounce:SpellDec 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 ); + if (0) print( "fx_bounce_spell (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 ); STAT_BIT_OR( IE_BOUNCE, BNC_RESOURCE_DEC ); return FX_APPLIED; } @@ -4898,7 +4915,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_MINHITPOINTS ); return FX_APPLIED; @@ -4907,7 +4924,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); ieDword limit = 60; if (fx->Parameter1) { @@ -4926,7 +4943,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); ieDword limit = 90; if (fx->Parameter1) { @@ -4954,7 +4971,7 @@ 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 ); + if (0) print( "fx_imprisonment (%2d)\n", fx->Opcode ); target->SetMCFlag(MC_HIDDEN, BM_OR); target->AddPortraitIcon(PI_PRISON); return FX_APPLIED; @@ -4966,7 +4983,7 @@ 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)\n", fx->Opcode ); target->fxqueue.RemoveAllEffects( fx_imprisonment_ref ); target->fxqueue.RemoveAllEffects( fx_maze_ref ); return FX_NOT_APPLIED; @@ -4975,7 +4992,7 @@ 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 (0) print( "fx_maze (%2d)\n", fx->Opcode ); if (!fx->Parameter2 && fx->FirstApply) { //get the maze dice number (column 3) int stat = target->GetSafeStat(IE_INT); @@ -4992,7 +5009,7 @@ 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\n", fx->Opcode, fx->Parameter2 ); Spellbook *sb = &target->spellbook; if(fx->Parameter2) { //all known spells, no need to memorize @@ -5019,7 +5036,7 @@ int fx_select_spell (Scriptable* /*Owner*/, Actor* target, Effect* fx) 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\n", fx->Opcode, fx->Resource, fx->Parameter2 ); //this is in the original engine (dead actors lose this effect) if (STATE_GET( STATE_DEAD) ) { @@ -5084,7 +5101,7 @@ static EffectRef fx_leveldrain_ref = { "LevelDrainModifier", -1 }; // 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\n", fx->Opcode, fx->Parameter1 ); //never subtract more than the maximum hitpoints ieDword x = STAT_GET(IE_MAXHITPOINTS)-1; @@ -5113,7 +5130,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); ieDword limit = 20; if (fx->Parameter1) { @@ -5139,7 +5156,7 @@ int fx_power_word_sleep (Scriptable* Owner, Actor* target, Effect* fx) // 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\n", fx->Opcode, fx->Parameter1 ); if (!fx->Parameter1) { return FX_NOT_APPLIED; } @@ -5169,7 +5186,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); target->fxqueue.RemoveLevelEffects(Removed, fx->Parameter1, RL_MATCHSCHOOL, fx->Parameter2); return FX_NOT_APPLIED; } @@ -5178,7 +5195,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); target->fxqueue.RemoveLevelEffects(Removed, fx->Parameter1, RL_MATCHSECTYPE, fx->Parameter2); return FX_NOT_APPLIED; } @@ -5186,7 +5203,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\n", fx->Opcode, fx->Parameter1 ); Map *map = target->GetCurrentArea(); if (!map) { @@ -5203,7 +5220,7 @@ 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 (0) print( "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; @@ -5215,7 +5232,7 @@ int fx_protection_school_dec (Scriptable* /*Owner*/, Actor* target, Effect* fx) 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)\n", 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 +5243,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)\n", fx->Opcode ); if (target->fxqueue.HasAnyDispellableEffect()) { if (!fx->Parameter1) { fx->Parameter1=0xff00; //blue @@ -5244,7 +5261,7 @@ 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 (0) print( "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; @@ -5255,7 +5272,7 @@ int fx_protection_secondary_type_dec (Scriptable* /*Owner*/, Actor* target, Effe //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 ); + if (0) print( "fx_bounce_school_dec (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 ); STAT_BIT_OR( IE_BOUNCE, BNC_SCHOOL_DEC ); target->AddPortraitIcon(PI_BOUNCE2); return FX_APPLIED; @@ -5264,7 +5281,7 @@ 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 ); + if (0) print( "fx_bounce_secondary_type_dec (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 ); STAT_BIT_OR( IE_BOUNCE, BNC_SECTYPE_DEC ); target->AddPortraitIcon(PI_BOUNCE2); return FX_APPLIED; @@ -5275,7 +5292,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); target->fxqueue.RemoveLevelEffects(Removed, fx->Parameter1, RL_MATCHSCHOOL|RL_REMOVEFIRST, fx->Parameter2); return FX_NOT_APPLIED; } @@ -5285,7 +5302,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); target->fxqueue.RemoveLevelEffects(Removed, fx->Parameter1, RL_MATCHSECTYPE|RL_REMOVEFIRST, fx->Parameter2); return FX_NOT_APPLIED; } @@ -5293,7 +5310,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)\n", fx->Opcode); core->GetGame()->TimeStop(target, fx->Duration); return FX_NOT_APPLIED; } @@ -5301,92 +5318,159 @@ 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\n", 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; + 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)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)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)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) { + // The trigger was evaluated as true, cast the spells now. + // TODO: fail remaining spells if an earlier one fails? 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); + 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (fx->Parameter2>=MAX_STATS) return FX_NOT_APPLIED; @@ -5402,7 +5486,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (target->fxqueue.HasEffectWithSource(fx_contingency_ref, fx->Source)) { displaymsg->DisplayConstantStringName(STR_CONTDUP, 0xf0f0f0, target); @@ -5429,7 +5513,7 @@ int fx_create_contingency (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 0xeb WingBuffet 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 ); + if (0) print( "fx_wing_buffet (%2d): Value: %d, Stat: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //create movement in actor ieDword dir; @@ -5465,7 +5549,7 @@ 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 ); + if (0) print( "fx_puppet_master (%2d): Value: %d, Stat: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_SET (IE_PUPPETMASTERTYPE, fx->Parameter1); //copyself doesn't copy scripts, so the script clearing code is not needed @@ -5529,7 +5613,7 @@ 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 ); + if (0) print( "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 @@ -5540,7 +5624,7 @@ int fx_puppet_marker (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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\n", 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); @@ -5564,7 +5648,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); Map *map = target->GetCurrentArea(); if (!map) { return FX_APPLIED; @@ -5601,7 +5685,7 @@ 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\n", fx->Opcode, fx->Parameter2 ); target->fxqueue.RemoveAllEffectsWithParam( fx_display_portrait_icon_ref, fx->Parameter2 ); return FX_NOT_APPLIED; } @@ -5612,7 +5696,7 @@ 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\n", 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 +5714,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); ieDword i=fx->Parameter1; while (i--) { //deplete magic item = 0 @@ -5642,7 +5726,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); ieDword i=fx->Parameter1; if (fx->Parameter2) { while(i--) { @@ -5662,21 +5746,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\n", 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\n", 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_SET( IE_BERSERKSTAGE2, fx->Parameter2 ); STATE_SET (STATE_BERSERK); return FX_APPLIED; @@ -5693,7 +5777,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_DAMAGELUCK ); return FX_APPLIED; } @@ -5702,7 +5786,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\n", fx->Opcode, fx->Resource); memcpy(target->BardSong, fx->Resource, 8); return FX_APPLIED; } @@ -5710,7 +5794,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); ieDword skill, roll; Map *map; @@ -5771,7 +5855,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); Scriptable *marker = target?target:Owner; Map *map = marker->GetCurrentArea(); if (!map) return FX_APPLIED; //delay effect @@ -5784,7 +5868,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)\n", fx->Opcode); Scriptable *marker = target?target:Owner; Map *map = marker->GetCurrentArea(); if (!map) return FX_APPLIED; //delay effect @@ -5796,7 +5880,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)\n", 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 +5898,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)\n", fx->Opcode ); //just display the spell sequencer portrait icon target->AddPortraitIcon(PI_SEQUENCER); if (fx->FirstApply && fx->Parameter3) { @@ -5831,7 +5915,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (target->fxqueue.HasEffectWithSource(fx_spell_sequencer_active_ref, fx->Source)) { displaymsg->DisplayConstantStringName(STR_SEQDUP, 0xf0f0f0, target); return FX_NOT_APPLIED; @@ -5852,7 +5936,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\n", fx->Opcode, fx->Resource ); if (Owner->Type!=ST_ACTOR) { return FX_NOT_APPLIED; } @@ -5873,7 +5957,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (fx->Parameter3) { target->RestoreSpellLevel(fx->Parameter3, 0); fx->Parameter3=0; @@ -5891,21 +5975,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\n", 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\n", 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_VISUALRANGE ); return FX_APPLIED; } @@ -5913,7 +5997,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\n", 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 +6047,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\n", fx->Opcode, fx->Resource, fx->Parameter1, fx->Parameter2 ); if (fx->Parameter2) { ieDword var = 0; //use resource memory area as variable name @@ -5979,7 +6063,7 @@ static EffectRef immunity_effect_ref = { "Protection:Spell", -1 }; int fx_remove_immunity(Scriptable* /*Owner*/, Actor* target, Effect* fx) { - if (0) printf( "fx_remove_immunity (%2d): %s\n", fx->Opcode, fx->Resource ); + if (0) print( "fx_remove_immunity (%2d): %s\n", fx->Opcode, fx->Resource ); target->fxqueue.RemoveAllEffectsWithResource(immunity_effect_ref, fx->Resource); return FX_NOT_APPLIED; } @@ -5988,7 +6072,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)\n", fx->Opcode ); if (fx->Parameter2) { //gemrb modifier STAT_SET (IE_EXPLORE, fx->Parameter1); @@ -6000,7 +6084,7 @@ 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 ); + if (0) print( "fx_screenshake (%2d): Strength: %d\n", fx->Opcode, fx->Parameter1 ); core->timer->SetScreenShake( fx->Parameter1, fx->Parameter1, fx->Parameter1); return FX_APPLIED; } @@ -6010,7 +6094,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); target->fxqueue.RemoveAllEffects(fx_pause_caster_modifier_ref); return FX_NOT_APPLIED; } @@ -6018,7 +6102,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_SET(IE_SUMMONDISABLE, 1); STAT_SET(IE_CASTERHOLD, 1); if (fx->Parameter2==1) { @@ -6038,7 +6122,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); Point p(fx->PosX, fx->PosY); Effect *newfx = core->GetEffect(fx->Resource, fx->Power, p); @@ -6068,12 +6152,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;iParameter3;i++) { core->ApplyEffect(newfx, target, Owner); } @@ -6090,7 +6174,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (!target) return FX_NOT_APPLIED; Map *area = target->GetCurrentArea(); @@ -6140,7 +6224,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (STATE_GET(STATE_DEAD)) { return FX_NOT_APPLIED; } @@ -6164,7 +6248,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_HIDEINSHADOWS ); return FX_APPLIED; } @@ -6172,7 +6256,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_DETECTILLUSIONS ); return FX_APPLIED; } @@ -6180,14 +6264,14 @@ 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\n", 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); HandleBonus( target, IE_HITBONUS, fx->Parameter1, fx->TimingMode ); return FX_APPLIED; } @@ -6198,7 +6282,7 @@ 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 ); + if (0) print( "fx_renable_button (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 ); target->fxqueue.RemoveAllEffectsWithParam( fx_disable_button_ref, fx->Parameter2 ); return FX_NOT_APPLIED; } @@ -6206,7 +6290,7 @@ int fx_renable_button (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD_VAR( IE_FORCESURGE, MOD_ABSOLUTE ); return FX_APPLIED; } @@ -6214,7 +6298,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_SURGEMOD ); return FX_APPLIED; } @@ -6222,7 +6306,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\n", 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 +6321,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\n", 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 +6356,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_MELEETOHIT ); return FX_APPLIED; } @@ -6280,7 +6364,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_MELEEDAMAGE ); return FX_APPLIED; } @@ -6288,7 +6372,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_MISSILEDAMAGE ); return FX_APPLIED; } @@ -6296,7 +6380,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_missile_damage_modifier (%2d)\n", fx->Opcode); STAT_SET( IE_NOCIRCLE, 1 ); return FX_APPLIED; } @@ -6304,7 +6388,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_FISTHIT ); return FX_APPLIED; } @@ -6312,14 +6396,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\n", 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (fx->Parameter2) { STAT_SET( IE_TITLE2, fx->Parameter1 ); } else { @@ -6333,7 +6417,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_SET( IE_DISABLEOVERLAY, fx->Parameter1 ); return FX_APPLIED; } @@ -6342,7 +6426,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //bg2 STAT_SET( IE_DISABLEBACKSTAB, fx->Parameter1 ); //how @@ -6354,7 +6438,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_SET( IE_ENABLEOFFSCREENAI, fx->Parameter1 ); target->Activate(); return FX_APPLIED; @@ -6362,14 +6446,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\n", 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_SET( IE_DISABLECHUNKING, fx->Parameter1 ); return FX_APPLIED; } @@ -6378,7 +6462,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //remove vvc from actor if active target->RemoveVVCell(fx->Resource, false); return FX_APPLIED; @@ -6388,7 +6472,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_SET( IE_NOTURNABLE, fx->Parameter1 ); return FX_APPLIED; } @@ -6399,7 +6483,7 @@ int fx_cutscene2 (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx) Game *game; ieResRef resref; - if (0) printf( "fx_cutscene2 (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 ); + if (0) print( "fx_cutscene2 (%2d): Type: %d\n", fx->Opcode, fx->Parameter2 ); if (core->InCutSceneMode()) return FX_NOT_APPLIED; game = core->GetGame(); if (!game) return FX_NOT_APPLIED; @@ -6431,7 +6515,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_ADD( IE_CHAOSSHIELD, fx->Parameter1 ); if (fx->Parameter2) { target->AddPortraitIcon(PI_CSHIELD); //162 @@ -6443,7 +6527,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //unknown effect, but known stat position STAT_MOD( IE_NPCBUMP ); return FX_APPLIED; @@ -6451,14 +6535,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\n", 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\n", fx->Opcode, fx->Parameter2 ); STAT_SET( IE_CANUSEANYITEM, fx->Parameter2 ); return FX_APPLIED; @@ -6467,7 +6551,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\n", fx->Opcode, fx->Parameter2 ); STAT_SET( IE_ALWAYSBACKSTAB, fx->Parameter2 ); return FX_APPLIED; @@ -6476,7 +6560,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)\n", fx->Opcode ); Game *game=core->GetGame(); @@ -6492,7 +6576,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_HITBONUSLEFT ); return FX_APPLIED; @@ -6501,7 +6585,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_HITBONUSRIGHT ); return FX_APPLIED; @@ -6510,7 +6594,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\n", fx->Opcode, fx->Parameter1 ); Map *map = target->GetCurrentArea(); if (!map) return FX_APPLIED; if (!fx->Parameter2) { @@ -6531,7 +6615,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_NOTRACKING ); //highlight creature??? return FX_APPLIED; @@ -6549,7 +6633,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\n", fx->Opcode, fx->Resource, fx->Parameter2 ); if (fx->Parameter2) { ieDword var = 0; //use resource memory area as variable name @@ -6564,7 +6648,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\n", fx->Opcode, fx->Parameter2 ); STAT_SET(IE_DISABLETIMESTOP, fx->Parameter2); return FX_APPLIED; } @@ -6575,7 +6659,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\n", fx->Opcode, fx->Parameter2 ); if (!fx->Parameter2) { fx->Parameter2=IE_WIS; } @@ -6609,7 +6693,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\n", 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,7 +6703,7 @@ 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\n", fx->Opcode, fx->Parameter1 ); if (!fx->Parameter1) { return FX_NOT_APPLIED; } @@ -6636,7 +6720,7 @@ int fx_golem_stoneskin_modifier (Scriptable* /*Owner*/, Actor* target, Effect* f // 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\n", fx->Opcode, fx->Parameter2 ); STAT_SET(IE_AVATARREMOVAL, fx->Parameter2); return FX_APPLIED; } @@ -6644,7 +6728,7 @@ 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)\n", fx->Opcode ); //instant, full rest target->Rest(0); target->fxqueue.RemoveAllEffectsWithParam(fx_display_portrait_icon_ref, PI_FATIGUE); @@ -6661,7 +6745,7 @@ 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\n", fx->Opcode, fx->Parameter1 ); core->GetGame()->StartRainOrSnow(false, fx->Parameter1 & WB_MASK); @@ -6671,7 +6755,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2, fx->Resource ); return FX_NOT_APPLIED; } diff --git a/project/jni/application/gemrb/gemrb/plugins/GAMImporter/GAMImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/GAMImporter/GAMImporter.cpp index b04942be8..59c23f7af 100644 --- a/project/jni/application/gemrb/gemrb/plugins/GAMImporter/GAMImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/GAMImporter/GAMImporter.cpp @@ -27,7 +27,10 @@ #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 @@ -38,17 +41,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 +57,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) { @@ -319,15 +318,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); + printMessage("GAMImporter", "Invalid Slot Enabler caught: %s!\n", LIGHT_RED, message); b=0; } } @@ -468,17 +466,11 @@ Actor* GAMImporter::GetActor(Holder 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 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); } } diff --git a/project/jni/application/gemrb/gemrb/plugins/GAMImporter/GAMImporter.h b/project/jni/application/gemrb/gemrb/plugins/GAMImporter/GAMImporter.h index fba05f0fe..d0dd5e61c 100644 --- a/project/jni/application/gemrb/gemrb/plugins/GAMImporter/GAMImporter.h +++ b/project/jni/application/gemrb/gemrb/plugins/GAMImporter/GAMImporter.h @@ -36,7 +36,6 @@ class GAMImporter : public SaveGameMgr { private: DataStream* str; - bool autoFree; int version; unsigned int PCSize; ieDword PCOffset, PCCount; @@ -51,7 +50,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); diff --git a/project/jni/application/gemrb/gemrb/plugins/GUIScript/GUIScript.cpp b/project/jni/application/gemrb/gemrb/plugins/GUIScript/GUIScript.cpp index d912e6ea4..4b699def6 100644 --- a/project/jni/application/gemrb/gemrb/plugins/GUIScript/GUIScript.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/GUIScript/GUIScript.cpp @@ -41,19 +41,24 @@ #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/VFS.h" #include @@ -102,7 +107,7 @@ struct UsedItemType { typedef char EventNameType[17]; #define IS_DROP 0 -#define IS_GET 1 +#define IS_GET 1 typedef ieResRef ResRefPairs[2]; @@ -340,7 +345,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 */ @@ -620,8 +625,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); + printMessage("GUIScript", "Screen is too small!\nThis window requires %d x %d resolution.\n", LIGHT_RED, + width, height); return RuntimeError("Please change your settings."); } Py_INCREF( Py_None ); @@ -1393,7 +1398,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 +1412,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, @@ -3394,8 +3398,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); + printMessage("GUISCript", "PLT/BAM not found for ref: %s\n", YELLOW, + ResRef); textcolor(WHITE); if (type == 0) return NULL; @@ -3407,13 +3411,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\n"); return NULL; } } else { Picture = im->GetSprite2D(type, col); if (Picture == NULL) { - printf ("Picture == NULL\n"); + print ("Picture == NULL\n"); return NULL; } } @@ -3526,7 +3530,7 @@ static PyObject* GemRB_Control_SetAnimationPalette(PyObject * /*self*/, PyObject } 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 +3538,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 +3553,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,6 +3570,9 @@ static PyObject* GemRB_Control_SetAnimation(PyObject * /*self*/, PyObject* args) ControlAnimation* anim = new ControlAnimation( ctl, ResRef, Cycle ); + if (Blend) { + anim->SetBlend(true); + } anim->UpdateAnimation(); Py_INCREF( Py_None ); @@ -3814,8 +3823,8 @@ static PyObject* GemRB_CheckVar(PyObject * /*self*/, PyObject* args) return NULL; } long value =(long) CheckVariable(Sender, Variable, Context); - printMessage("GUISCript"," ",YELLOW); - printf("%s %s=%ld\n",Context, Variable, value); + printMessage("GUISCript", "%s %s=%ld\n", YELLOW, + Context, Variable, value); textcolor(WHITE); return PyInt_FromLong( value ); } @@ -5215,9 +5224,12 @@ static PyObject* GemRB_FillPlayerInfo(PyObject * /*self*/, PyObject* args) } int mastertable = gamedata->LoadTable( "avprefix" ); Holder mtm = gamedata->GetTable( mastertable ); + if (!mtm) { + return RuntimeError("Couldn't load avprefix table."); + } int count = mtm->GetRowCount(); if (count< 1 || count>8) { - return RuntimeError("Table is invalid." ); + return RuntimeError("avprefix table contains no entries." ); } const char *poi = mtm->QueryField( 0 ); // the base animation id @@ -5227,6 +5239,9 @@ static PyObject* GemRB_FillPlayerInfo(PyObject * /*self*/, PyObject* args) poi = mtm->QueryField( i ); int table = gamedata->LoadTable( poi ); Holder tm = gamedata->GetTable( table ); + if (!tm) { + return RuntimeError("Couldn't load an avprefix table."); + } int StatID = atoi( tm->QueryField() ); StatID = MyActor->GetBase( StatID ); poi = tm->QueryField( StatID ); @@ -5266,8 +5281,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 ); + printMessage("GUIScript", "Spell not found :%.8s", LIGHT_RED, + SpellResRef); //no incref here! return Py_None; } @@ -5485,9 +5500,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 ); @@ -5593,6 +5606,10 @@ static PyObject* GemRB_GetContainerItem(PyObject * /*self*/, PyObject* args) PyDict_SetItemString(dict, "Flags", PyInt_FromLong (ci->Flags)); Item *item = gamedata->GetItem( ci->ItemResRef ); + if (!item) { + 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 )) ); @@ -5860,8 +5877,8 @@ static PyObject* GemRB_IsValidStoreItem(PyObject * /*self*/, PyObject* args) } Item *item = gamedata->GetItem( ItemResRef ); if (!item) { - printMessage("GUIScript", " ", LIGHT_RED); - printf("Invalid resource reference: %s\n", ItemResRef); + printMessage("GUIScript", "Invalid resource reference: %s\n", LIGHT_RED, + ItemResRef); return PyInt_FromLong(0); } @@ -6069,8 +6086,6 @@ 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; res = ASI_SUCCESS; @@ -6139,7 +6154,7 @@ static PyObject* GemRB_GetStoreItem(PyObject * /*self*/, PyObject* args) //calculate depreciation too //store->DepreciationRate, mount - if (item->StackAmount>1) { + if (item->MaxStackAmount>1) { price *= si->Usages[0]; } //is this correct? @@ -6336,9 +6351,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\n", String ); } else { - printf( "%s returned False\n", String ); + print( "%s returned False\n", String ); } Py_INCREF( Py_None ); return Py_None; @@ -6487,14 +6502,19 @@ PyDoc_STRVAR( GemRB_GetKnownSpell__doc, static PyObject* GemRB_GetKnownSpell(PyObject * /*self*/, PyObject* args) { - int PartyID, SpellType, Level, Index; + int PartyID, SpellType, Level, Index, global = 0; - if (!PyArg_ParseTuple( args, "iiii", &PartyID, &SpellType, &Level, &Index )) { + if (!PyArg_ParseTuple( args, "iiii|i", &PartyID, &SpellType, &Level, &Index, &global )) { return AttributeError( GemRB_GetKnownSpell__doc ); } GET_GAME(); - Actor* actor = game->FindPC( PartyID ); + Actor* actor; + if (global) { + actor = game->GetActorByGlobalID( PartyID ); + } else { + actor = game->FindPC( PartyID ); + } if (!actor) { return RuntimeError( "Actor not found!\n" ); } @@ -6513,7 +6533,7 @@ 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[, global])=>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."); @@ -6522,8 +6542,9 @@ static PyObject* GemRB_GetMemorizedSpellsCount(PyObject * /*self*/, PyObject* ar { int PartyID, SpellType, Level = -1; int global = 0; + bool castable; - if (!PyArg_ParseTuple( args, "ii|ii", &PartyID, &SpellType, &Level, &global )) { + if (!PyArg_ParseTuple( args, "iiii|i", &PartyID, &SpellType, &Level, &castable, &global )) { return AttributeError( GemRB_GetMemorizedSpellsCount__doc ); } GET_GAME(); @@ -6539,9 +6560,13 @@ static PyObject* GemRB_GetMemorizedSpellsCount(PyObject * /*self*/, PyObject* ar } 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 ) ); } } @@ -7020,7 +7045,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)); @@ -7383,17 +7408,8 @@ static PyObject* GemRB_DropDraggedItem(PyObject * /*self*/, PyObject* args) //release it only when fully placed if (res==ASI_SUCCESS) { 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) @@ -7600,7 +7616,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!" ); @@ -8227,6 +8243,10 @@ static PyObject* GemRB_Window_SetupEquipmentIcons(PyObject * /*self*/, PyObject* if (item->UseIcon[0]) { Picture = gamedata->GetBAMSprite(item->UseIcon, 1, 0); + // 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); } if (!Picture) { @@ -8282,6 +8302,9 @@ PyDoc_STRVAR( GemRB_Window_SetupSpellIcons__doc, "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."); +//order is: mage, cleric, innate, class, song, (defaults to 1, item) +static int sections[]={2,4,8,16,16}; + static PyObject* GemRB_Window_SetupSpellIcons(PyObject * /*self*/, PyObject* args) { int wi, slot, Type; @@ -8341,6 +8364,7 @@ static PyObject* GemRB_Window_SetupSpellIcons(PyObject * /*self*/, PyObject* arg // but only if there are any spells of that type to disable int disabled_spellcasting = actor->GetStat(IE_CASTING); +//print("disable bits: %d\n", disabled_spellcasting); for (i=0;ispellname)/1000; - if (core->CheckSpecialSpell(spell->spellname, actor) || (disabled_spellcasting&(1<type>4?1:sections[spell->type]; + +//print("%s %d %d %s\n", spell->spellname, spell->type, type, (disabled_spellcasting&type) ? "disabled":"enabled" ); + if (core->CheckSpecialSpell(spell->spellname, actor) || (disabled_spellcasting&type) ) { btn->SetState(IE_GUI_BUTTON_DISABLED); btn->EnableBorder(1, IE_GUI_BUTTON_DISABLED); PyObject *Function = PyDict_GetItemString(dict, "UpdateActionsWindow"); @@ -8468,7 +8494,7 @@ static PyObject* GemRB_Window_SetupControls(PyObject * /*self*/, PyObject* args) for (int i=0;iGetControl(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\n", i+Start, wi); return RuntimeError ("No such control!\n"); } int action = myrow[i]; @@ -8495,7 +8521,7 @@ static PyObject* GemRB_Window_SetupControls(PyObject * /*self*/, PyObject* args) } else { type = IE_SPELL_TYPE_INNATE; } - if (!actor->spellbook.GetMemorizedSpellsCount(type)) { + if (!actor->spellbook.GetMemorizedSpellsCount(type, true)) { state = IE_GUI_BUTTON_DISABLED; } break; @@ -8618,6 +8644,11 @@ static PyObject* GemRB_Window_SetupControls(PyObject * /*self*/, PyObject* args) ieResRef *poi = &actor->PCStats->QuickSpells[action-ACT_QSPELL1]; 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; @@ -8734,6 +8765,53 @@ static PyObject* GemRB_SetDefaultActions(PyObject * /*self*/, PyObject* args) return Py_None; } + +PyDoc_STRVAR( GemRB_SetupQuickSpell__doc, +"SetupQuickSpell(PartyID, spellslot, spellindex, type[, global])=>int\n\n" +"Set up a quick spell slot of a PC.\n\n" +"If global is set, the actor will be looked up by its global ID instead of party slot." +"It also returns the target type of the selected spell."); + +static PyObject* GemRB_SetupQuickSpell(PyObject * /*self*/, PyObject* args) +{ + SpellExtHeader spelldata; + int PartyID, which, slot, type; + int global = 0; + + if (!PyArg_ParseTuple( args, "iiii|i", &PartyID, &slot, &which, &type, &global )) { + return AttributeError( GemRB_SetupQuickSpell__doc ); + } + + GET_GAME(); + + Actor* actor; + if (global) { + actor = game->GetActorByGlobalID( PartyID ); + } else { + actor = game->FindPC( PartyID ); + } + if (!actor) { + return RuntimeError( "Actor not found!\n" ); + } + + 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!\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" "Set up a quick slot or weapon slot of a PC to use a weapon ability.\n\n" @@ -8950,17 +9028,30 @@ 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; + } + //quick spell type is available in actor->PCStats->QuickSpellClasses, if needed + actor->spellbook.FindSpellInfo(&spelldata, actor->PCStats->QuickSpells[spell]); + } else { + actor->spellbook.GetSpellInfo(&spelldata, type, spell, 1); + } + + print("Cast spell: %s\n", spelldata.spellname); + print("Slot: %d\n", spelldata.slot); + print("Type: %d\n", 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\n", tmp); core->FreeString(tmp); - printf("Target: %d\n", spelldata.Target); - printf("Range: %d\n", spelldata.Range); + print("Target: %d\n", spelldata.Target); + print("Range: %d\n", spelldata.Range); if(! (1<GetVideoDriver()->ToggleFullscreenMode(fullscreen); + core->GetVideoDriver()->SetFullscreenMode(fullscreen); Py_INCREF( Py_None ); return Py_None; } @@ -9463,7 +9554,8 @@ 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(); + owner->AddTrigger(TriggerEntry(trigger_stealfailed, attacker->GetGlobalID())); Py_INCREF( Py_None ); return Py_None; } @@ -10140,6 +10232,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), @@ -10349,7 +10442,7 @@ bool GUIScript::Init(void) sprintf( string, "import sys" ); if (PyRun_SimpleString( string ) == -1) { - printMessage( "GUIScript", string, RED ); + printMessage( "GUIScript", "%s", RED, string ); return false; } @@ -10366,20 +10459,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 ); + printMessage( "GUIScript", "%s", RED, string ); return false; } sprintf( string, "import GemRB\n"); if (PyRun_SimpleString( "import GemRB" ) == -1) { - printMessage( "GUIScript", string, RED ); + printMessage( "GUIScript", "%s", RED, 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 ); + printMessage( "GUIScript", "%s", RED, string ); return false; } @@ -10396,15 +10489,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 ); + printMessage( "GUIScript", "%s", RED, string ); return false; } sprintf( string, "GemRB.GameType = \"%s\"", core->GameType); if (PyRun_SimpleString( string ) == -1) { - printMessage( "GUIScript", string, RED ); + printMessage( "GUIScript", "%s", RED, string ); return false; } @@ -10416,20 +10509,18 @@ bool GUIScript::Init(void) #endif if (PyRun_SimpleString( "from GUIDefines import *" ) == -1) { - printMessage( "GUIScript", " ", RED ); - printf("Check if %s/GUIDefines.py exists! ", path); + printMessage("GUIScript", "Check if %s/GUIDefines.py exists! ", RED, path); return false; } if (PyRun_SimpleString( "from GUIClasses import *" ) == -1) { - printMessage( "GUIScript", " ", RED ); - printf("Check if %s/GUIClasses.py exists! ", path); + printMessage("GUIScript", "Check if %s/GUIClasses.py exists! ", RED, path); return false; } if (PyRun_SimpleString( "from GemRB import *" ) == -1) { printMessage( "GUIScript", " ", RED ); - printf("builtin GemRB module failed to load!!! "); + print("builtin GemRB module failed to load!!! "); return false; } @@ -10469,7 +10560,7 @@ bool GUIScript::Autodetect(void) const char *dirent = iter.GetName(); char module[_MAX_PATH]; - //printf("DE: %s\n", dirent); + //print("DE: %s\n", dirent); if (iter.IsDirectory() && dirent[0] != '.') { // NOTE: these methods subtly differ in sys.path content, need for __init__.py files ... // Method1: @@ -10498,8 +10589,7 @@ bool GUIScript::LoadScript(const char* filename) if (!Py_IsInitialized()) { return false; } - printMessage( "GUIScript", "Loading Script ", WHITE ); - printf( "%s...", filename ); + printMessage("GUIScript", "Loading Script %s...", WHITE, filename); char path[_MAX_PATH]; strcpy( path, filename ); @@ -10544,8 +10634,7 @@ PyObject *GUIScript::CallbackFunction(const char* fname, PyObject* pArgs) 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); + printMessage("GUIScript", "%s is not callable!\n", LIGHT_RED, fname); return NULL; } PyObject *pValue = PyObject_CallObject( pFunc, pArgs ); @@ -10580,8 +10669,7 @@ bool GUIScript::RunFunction(const char *ModuleName, const char* FunctionName, bo /* pFunc: Borrowed reference */ if (( !pFunc ) || ( !PyCallable_Check( pFunc ) )) { if (error) { - printMessage( "GUIScript", "Missing function:", LIGHT_RED ); - printf("%s\n", FunctionName); + printMessage("GUIScript", "Missing function:%s\n", LIGHT_RED, FunctionName); } Py_DECREF(module); return false; @@ -10609,7 +10697,7 @@ bool GUIScript::RunFunction(const char *ModuleName, const char* FunctionName, bo void GUIScript::ExecFile(const char* file) { FileStream fs; - if (!fs.Open(file, true)) + if (!fs.Open(file)) return; int len = fs.Remains(); @@ -10677,3 +10765,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/project/jni/application/gemrb/gemrb/plugins/GUIScript/GUIScript.h b/project/jni/application/gemrb/gemrb/plugins/GUIScript/GUIScript.h index 05d8bfdfa..4ea183b3f 100644 --- a/project/jni/application/gemrb/gemrb/plugins/GUIScript/GUIScript.h +++ b/project/jni/application/gemrb/gemrb/plugins/GUIScript/GUIScript.h @@ -52,7 +52,7 @@ 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); /** Exec a single File */ void ExecFile(const char* file); /** Exec a single String */ diff --git a/project/jni/application/gemrb/gemrb/plugins/IDSImporter/IDSImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/IDSImporter/IDSImporter.cpp index 254582b62..e22815eb8 100644 --- a/project/jni/application/gemrb/gemrb/plugins/IDSImporter/IDSImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/IDSImporter/IDSImporter.cpp @@ -29,31 +29,20 @@ 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) { + if (str == NULL) { return false; } - if (str) { - return false; - } - str = stream; - this->autoFree = autoFree; str->CheckEncrypted(); char tmp[11]; @@ -89,6 +78,7 @@ bool IDSImporter::Open(DataStream* stream, bool autoFree) } } + delete str; return true; } diff --git a/project/jni/application/gemrb/gemrb/plugins/IDSImporter/IDSImporter.h b/project/jni/application/gemrb/gemrb/plugins/IDSImporter/IDSImporter.h index d91daf238..815117331 100644 --- a/project/jni/application/gemrb/gemrb/plugins/IDSImporter/IDSImporter.h +++ b/project/jni/application/gemrb/gemrb/plugins/IDSImporter/IDSImporter.h @@ -23,6 +23,8 @@ #include "SymbolMgr.h" +#include + struct Pair { int val; char* str; @@ -30,16 +32,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; diff --git a/project/jni/application/gemrb/gemrb/plugins/IDSImporter/IDSImporterDefs.h b/project/jni/application/gemrb/gemrb/plugins/IDSImporter/IDSImporterDefs.h index 68e4af858..450325e59 100644 --- a/project/jni/application/gemrb/gemrb/plugins/IDSImporter/IDSImporterDefs.h +++ b/project/jni/application/gemrb/gemrb/plugins/IDSImporter/IDSImporterDefs.h @@ -29,9 +29,3 @@ #define HEADER_BLANK 3 #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/project/jni/application/gemrb/gemrb/plugins/INIImporter/INIImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/INIImporter/INIImporter.cpp index e2b252a16..c73a376e0 100644 --- a/project/jni/application/gemrb/gemrb/plugins/INIImporter/INIImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/INIImporter/INIImporter.cpp @@ -26,29 +26,19 @@ 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 +69,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); + printMessage("INIImporter", "Bad Line in file: %s, Section: [%s], Entry: '%s'\n", LIGHT_RED, + str->filename, lastTag->GetTagName(), strbuf); } } while (true); free( strbuf ); + delete str; return true; } diff --git a/project/jni/application/gemrb/gemrb/plugins/INIImporter/INIImporter.h b/project/jni/application/gemrb/gemrb/plugins/INIImporter/INIImporter.h index 46c03206f..1fb8a6dc2 100644 --- a/project/jni/application/gemrb/gemrb/plugins/INIImporter/INIImporter.h +++ b/project/jni/application/gemrb/gemrb/plugins/INIImporter/INIImporter.h @@ -26,6 +26,7 @@ #include "globals.h" #include +#include struct INIPair { char* Name, * Value; @@ -180,14 +181,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(); diff --git a/project/jni/application/gemrb/gemrb/plugins/ITMImporter/ITMImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/ITMImporter/ITMImporter.cpp index 742528a5a..66e22cdd9 100644 --- a/project/jni/application/gemrb/gemrb/plugins/ITMImporter/ITMImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/ITMImporter/ITMImporter.cpp @@ -24,31 +24,26 @@ #include "EffectMgr.h" #include "Interface.h" +#include "PluginMgr.h" 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 +53,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\n" ); return false; } @@ -103,7 +98,7 @@ Item* ITMImporter::GetItem(Item *s) str->Read( &s->MinCharisma, 1 ); str->Read( &s->unknown3, 1 ); str->ReadDword( &s->Price ); - str->ReadWord( &s->StackAmount ); + str->ReadWord( &s->MaxStackAmount ); str->ReadResRef( s->ItemIcon ); str->ReadWord( &s->LoreToID ); str->ReadResRef( s->GroundIcon ); @@ -162,7 +157,7 @@ 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.\n" ); return NULL; } return s; diff --git a/project/jni/application/gemrb/gemrb/plugins/ITMImporter/ITMImporter.h b/project/jni/application/gemrb/gemrb/plugins/ITMImporter/ITMImporter.h index c188a5cc4..d1572493c 100644 --- a/project/jni/application/gemrb/gemrb/plugins/ITMImporter/ITMImporter.h +++ b/project/jni/application/gemrb/gemrb/plugins/ITMImporter/ITMImporter.h @@ -34,13 +34,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); diff --git a/project/jni/application/gemrb/gemrb/plugins/IWDOpcodes/IWDOpcodes.cpp b/project/jni/application/gemrb/gemrb/plugins/IWDOpcodes/IWDOpcodes.cpp index e55f6364a..59c80ee25 100644 --- a/project/jni/application/gemrb/gemrb/plugins/IWDOpcodes/IWDOpcodes.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/IWDOpcodes/IWDOpcodes.cpp @@ -551,7 +551,7 @@ static inline void HandleBonus(Actor *target, int stat, int mod, int mode) // fx_ac_vs_damage_type_modifier_iwd2 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 ); + if (0) print( "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(); @@ -601,7 +601,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); switch (fx->Parameter2) { case 0: @@ -631,7 +631,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (target->SetSpellState( SS_HOLYMIGHT)) return FX_NOT_APPLIED; STAT_ADD( IE_STR, fx->Parameter1); @@ -676,7 +676,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\n", fx->Opcode, fx->Parameter1 ); int speed = (fx->Parameter2 >> 16) & 0xFF; target->SetColorMod(0xff, RGBModifier::ADD, speed, @@ -689,7 +689,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\n", fx->Opcode, fx->Parameter2 ); if (!Owner) { return FX_NOT_APPLIED; } @@ -713,7 +713,7 @@ 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 ); + if (0) print( "fx_cold_damage (%2d): Damage %d\n", fx->Opcode, fx->Parameter1 ); target->Damage(fx->Parameter1, DAMAGE_COLD, Owner); return FX_NOT_APPLIED; } @@ -725,7 +725,7 @@ 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); + if (0) print( "fx_chill_touch (%2d)\n", fx->Opcode); target->Damage(fx->Parameter1, DAMAGE_COLD, Owner); if (STAT_GET(IE_GENERAL)==GEN_UNDEAD) { target->Panic(Owner, PANIC_RUNAWAY); @@ -737,7 +737,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)\n", fx->Opcode); ieDword state; if (fx->Parameter2) { @@ -760,7 +760,7 @@ 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 ); + if (0) print( "fx_crushing_damage (%2d): Damage %d\n", fx->Opcode, fx->Parameter1 ); target->Damage(fx->Parameter1, DAMAGE_CRUSHING, Owner); return FX_NOT_APPLIED; } @@ -768,7 +768,7 @@ int fx_crushing_damage (Scriptable* Owner, Actor* target, Effect* fx) //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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_SAVEVSDEATH ); STAT_MOD( IE_SAVEVSWANDS ); STAT_MOD( IE_SAVEVSPOLY ); @@ -787,7 +787,7 @@ 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\n", fx->Opcode, fx->Parameter1 ); std::list< Effect* >::const_iterator f=target->fxqueue.GetFirstEffect(); Effect *poison; //this is intentionally an assignment @@ -827,7 +827,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\n", fx->Opcode, fx->Resource, fx->Resource2, fx->Parameter2 ); //check the summoning limit? @@ -851,7 +851,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\n", fx->Opcode, fx->Resource, fx->Parameter2 ); if (Owner->Type!=ST_ACTOR) { return FX_NOT_APPLIED; } @@ -882,7 +882,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\n", fx->Opcode, fx->Resource, fx->Parameter2 ); //check the summoning limit? if (!target) { return FX_NOT_APPLIED; @@ -911,7 +911,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\n", fx->Opcode, fx->Parameter2 ); ieDword value; if (fx->Parameter2) @@ -939,7 +939,7 @@ 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\n", fx->Opcode, fx->Parameter2 ); if (target->SetSpellState(SS_BADPRAYER)) return FX_NOT_APPLIED; EXTSTATE_SET(EXTSTATE_PRAYER_BAD); STAT_ADD( IE_TOHIT, -1); @@ -959,7 +959,7 @@ 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\n", fx->Opcode, fx->Resource, fx->Parameter2 ); ieResRef monster; ieResRef hit; @@ -981,7 +981,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\n", fx->Opcode, fx->Parameter2 ); //if the target is dead, this effect ceases to exist if (STATE_GET(STATE_DEAD|STATE_PETRIFIED|STATE_FROZEN) ) { @@ -1003,7 +1003,7 @@ int fx_burning_blood (Scriptable* Owner, Actor* target, Effect* fx) //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\n", 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) ) { @@ -1039,7 +1039,7 @@ 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\n", fx->Opcode, fx->Resource, fx->Parameter2 ); ieResRef monster; ieResRef hit; @@ -1060,7 +1060,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\n", fx->Opcode, fx->Parameter2 ); ieDword value; if (fx->Parameter2) @@ -1088,7 +1088,7 @@ 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\n", fx->Opcode, fx->Parameter2 ); if (target->SetSpellState(SS_BADRECIT)) return FX_NOT_APPLIED; EXTSTATE_SET(EXTSTATE_REC_BAD); STAT_ADD( IE_TOHIT, -2); @@ -1106,7 +1106,7 @@ 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\n", fx->Opcode, fx->Parameter2 ); if (STAT_GET(IE_GENERAL)==GEN_UNDEAD) { return FX_NOT_APPLIED; } @@ -1153,7 +1153,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\n", fx->Opcode, fx->Resource, fx->Parameter2 ); switch(fx->Parameter2) { case 1: @@ -1171,7 +1171,7 @@ 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\n", 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 @@ -1205,14 +1205,14 @@ 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\n", 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; @@ -1265,14 +1265,14 @@ 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\n", 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; @@ -1321,7 +1321,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\n", fx->Opcode, fx->Resource, fx->Resource2, fx->Parameter2 ); if (!target) { return FX_NOT_APPLIED; @@ -1360,7 +1360,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\n", fx->Opcode, fx->Resource, fx->Resource2, fx->Parameter2 ); if (!target) { return FX_NOT_APPLIED; @@ -1403,7 +1403,7 @@ int fx_summon_pomab (Scriptable* Owner, Actor* target, Effect* fx) //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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (fx->Parameter1 && (STAT_GET(IE_GENERAL)!=fx->Parameter1)) { return FX_NOT_APPLIED; } @@ -1451,7 +1451,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 \n", fx->Opcode, fx->Parameter1 ); //if the target is dead, this effect ceases to exist if (STATE_GET(STATE_DEAD|STATE_PETRIFIED|STATE_FROZEN) ) { @@ -1466,7 +1466,7 @@ int fx_static_charge(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--; //iwd2 style @@ -1487,7 +1487,7 @@ 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 \n", 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 +1500,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 +1535,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)\n", fx->Opcode ); if (target->SetSpellState( SS_EYEMIND)) return FX_APPLIED; EXTSTATE_SET(EXTSTATE_EYE_MIND); @@ -1547,7 +1547,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)\n", fx->Opcode ); if (target->SetSpellState( SS_EYESWORD)) return FX_APPLIED; EXTSTATE_SET(EXTSTATE_EYE_SWORD); @@ -1560,7 +1560,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)\n", fx->Opcode ); if (target->SetSpellState( SS_EYEMAGE)) return FX_APPLIED; EXTSTATE_SET(EXTSTATE_EYE_MAGE); @@ -1573,7 +1573,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)\n", fx->Opcode ); if (target->SetSpellState( SS_EYEVENOM)) return FX_APPLIED; EXTSTATE_SET(EXTSTATE_EYE_VENOM); @@ -1586,7 +1586,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)\n", fx->Opcode ); if (target->SetSpellState( SS_EYESPIRIT)) return FX_APPLIED; EXTSTATE_SET(EXTSTATE_EYE_SPIRIT); @@ -1599,7 +1599,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)\n", fx->Opcode ); if (target->SetSpellState( SS_EYEFORTITUDE)) return FX_APPLIED; EXTSTATE_SET(EXTSTATE_EYE_FORT); @@ -1612,7 +1612,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)\n", fx->Opcode ); if (target->SetSpellState( SS_EYESTONE)) return FX_APPLIED; EXTSTATE_SET(EXTSTATE_EYE_STONE); @@ -1626,7 +1626,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\n", fx->Opcode, fx->Parameter2 ); target->spellbook.RemoveSpell(SevenEyes[EYE_MIND]); target->spellbook.RemoveSpell(SevenEyes[EYE_SWORD]); target->spellbook.RemoveSpell(SevenEyes[EYE_MAGE]); @@ -1640,7 +1640,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\n", fx->Opcode, fx->Parameter2 ); if (fx->Resource[0]) { target->fxqueue.RemoveAllEffectsWithResource(fx->Parameter2, fx->Resource); @@ -1659,7 +1659,7 @@ 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\n", 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; @@ -1703,7 +1703,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\n", fx->Opcode, fx->Parameter2 ); //if the target is dead, this effect ceases to exist if (STATE_GET(STATE_DEAD|STATE_PETRIFIED|STATE_FROZEN) ) { @@ -1749,7 +1749,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)\n", fx->Opcode ); //if the target is dead, this effect ceases to exist if (STATE_GET(STATE_DEAD|STATE_PETRIFIED|STATE_FROZEN) ) { @@ -1789,7 +1789,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\n", fx->Opcode, fx->Parameter2 ); //param2==1 sets only the spell state if (fx->Parameter2) { @@ -1844,7 +1844,7 @@ int fx_animal_rage (Scriptable* /*Owner*/, Actor* target, Effect* fx) //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 (0) print( "fx_turn_undead (%2d): Level %d\n", fx->Opcode, fx->Parameter1 ); if (fx->Parameter1) { target->Turn(Owner, fx->Parameter1); } else { @@ -1859,26 +1859,26 @@ int fx_turn_undead (Scriptable* Owner, Actor* target, Effect* fx) //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\n", 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(); 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,7 +1898,7 @@ 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\n", fx->Opcode, fx->Parameter1 ); //timing if (core->GetGame()->GameTime%6) { return FX_APPLIED; @@ -1916,7 +1916,7 @@ int fx_vitriolic_sphere (Scriptable* Owner, Actor* target, Effect* fx) //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)\n", fx->Opcode); if (target->SetSpellState( SS_NOHPINFO)) return FX_APPLIED; EXTSTATE_SET(EXTSTATE_NO_HP); return FX_APPLIED; @@ -1925,7 +1925,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); switch (fx->Parameter2) { case 1: @@ -1969,7 +1969,7 @@ 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\n", fx->Opcode, fx->Resource, fx->Resource2, fx->Parameter2 ); ieDword race = STAT_GET(IE_RACE); //golem / outer planar gets hit int chance = 0; @@ -2031,7 +2031,7 @@ 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\n", 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) @@ -2047,7 +2047,7 @@ 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)\n", fx->Opcode ); Game *game = core->GetGame(); game->locals->SetAt("GEM_ACTIVE", 1); return FX_NOT_APPLIED; @@ -2113,7 +2113,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\n", fx->Opcode, fx->Resource, fx->Resource2, fx->Parameter2 ); int damage = 0; int five_percent = core->Roll(1,100,0)<5; @@ -2152,7 +2152,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\n", fx->Opcode, fx->Resource ); if (!fx->Resource[0]) { strcpy(fx->Resource,"SPIN164"); } @@ -2180,7 +2180,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\n", fx->Opcode, fx->Resource ); if (!fx->Resource[0]) { strcpy(fx->Resource,"SPIN166"); } @@ -2212,7 +2212,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\n", fx->Opcode, fx->Resource ); if (!fx->Resource[0]) { strcpy(fx->Resource,"SPIN179"); } @@ -2241,7 +2241,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); STAT_MOD( IE_MAGICDEVICE ); return FX_APPLIED; } @@ -2263,7 +2263,7 @@ int fx_use_magic_device_modifier (Scriptable* /*Owner*/, Actor* target, Effect* //Create the effect which will contain the spell hit projectile and the cycle change command 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)\n", fx->Opcode); Map *map = Owner->GetCurrentArea(); if (!map) { return FX_NOT_APPLIED; @@ -2308,7 +2308,7 @@ int fx_alter_animation (Scriptable* Owner, Actor* /*target*/, Effect* fx) //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)\n", fx->Opcode); if (target->HasSpellState(SS_BLOODRAGE)) { return FX_NOT_APPLIED; @@ -2323,7 +2323,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)\n", fx->Opcode); // if (target->SetSpellState( SS_PROTFROMEVIL)) return FX_APPLIED; target->AddPortraitIcon(PI_PROTFROMEVIL); @@ -2352,7 +2352,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\n", fx->Opcode, fx->Parameter1); if (target->SetSpellState( SS_ARMOROFFAITH)) return FX_APPLIED; if (!fx->Parameter1) { fx->Parameter1=1; @@ -2378,7 +2378,7 @@ 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)\n", fx->Opcode); //FIXME: i'm not sure if this part is there //create the sleep effect only once? if (!fx->Parameter3 && Owner) { @@ -2401,7 +2401,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)\n", fx->Opcode); if (target->SetSpellState( SS_ENFEEBLED)) return FX_APPLIED; target->AddPortraitIcon(PI_ENFEEBLEMENT); STAT_ADD(IE_STR, -15); @@ -2411,7 +2411,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\n", fx->Opcode, fx->Parameter2); if (fx->Parameter2) { if (target->SetSpellState( SS_ICESHIELD)) return FX_APPLIED; target->AddPortraitIcon(PI_ICESHIELD); @@ -2426,7 +2426,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)\n", fx->Opcode); if (target->SetSpellState( SS_DEATHWARD)) return FX_APPLIED; target->AddPortraitIcon(PI_DEATHWARD); // is it ok? @@ -2436,7 +2436,7 @@ 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)\n", fx->Opcode); if (target->SetSpellState( SS_HOLYPOWER)) return FX_APPLIED; if (enhanced_effects) { @@ -2449,7 +2449,7 @@ int fx_holy_power (Scriptable* /*Owner*/, Actor* target, Effect* fx) //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\n", fx->Opcode, fx->Parameter2); if (fx->Parameter2) { if (target->SetSpellState( SS_RIGHTEOUS2)) return FX_APPLIED; @@ -2496,7 +2496,7 @@ 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); + if (0) print( "fx_control (%2d)\n", fx->Opcode); bool enemyally = true; if (Owner->Type==ST_ACTOR) { enemyally = ((Actor *) Owner)->GetStat(IE_EA)>EA_GOODCUTOFF; //or evilcutoff? @@ -2527,7 +2527,7 @@ int fx_control (Scriptable* Owner, Actor* target, Effect* fx) 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\n", fx->Opcode, fx->Parameter2); unsigned int type = fx->Parameter2; if (type<32) { switch(type) { @@ -2560,7 +2560,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)\n", fx->Opcode); target->SetSpellState(SS_HELD|SS_RESILIENT); STATE_SET(STATE_HELPLESS); if (enhanced_effects) { @@ -2573,7 +2573,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)\n", fx->Opcode); if (target->SetSpellState( SS_BARKSKIN)) return FX_APPLIED; int bonus; @@ -2597,7 +2597,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); //also this effect is executed every update ieDword damage; @@ -2639,7 +2639,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2); //this effect ceases to affect dead targets (probably on frozen and stoned too) Game *game = core->GetGame(); @@ -2691,7 +2691,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)\n", fx->Opcode); if (target->SetSpellState( SS_FREEACTION)) return FX_APPLIED; // immunity to the following effects, coded in the effects: @@ -2712,7 +2712,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\n", fx->Opcode, fx->Parameter2); STATE_SET(STATE_HELPLESS|STATE_SLEEP); if (fx->Parameter2) { target->SetSpellState(SS_NOAWAKE); @@ -2729,7 +2729,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)\n", fx->Opcode); if (target->SetSpellState( SS_ENTROPY)) return FX_APPLIED; if (!fx->Resource[0]) { strnuprcpy(fx->Resource, "entropy", sizeof(ieResRef)-1); @@ -2754,7 +2754,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)\n", fx->Opcode); if (target->SetSpellState(SS_STORMSHELL)) return FX_APPLIED; STAT_ADD(IE_RESISTFIRE, 15); STAT_ADD(IE_RESISTCOLD, 15); @@ -2769,7 +2769,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)\n", fx->Opcode); if (target->SetSpellState( SS_ELEMPROT)) return FX_APPLIED; target->AddPortraitIcon(PI_ELEMPROT); STAT_ADD(IE_RESISTFIRE, 15); @@ -2793,7 +2793,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)\n", fx->Opcode); //gives immunity against: //0xda stoneskin //0x9a entangle @@ -2844,7 +2844,7 @@ 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)\n", fx->Opcode); if (target->SetSpellState( SS_EXECUTIONER)) return FX_APPLIED; STAT_ADD(IE_CRITICALHITBONUS, 4); @@ -2864,7 +2864,7 @@ int fx_executioner_eyes (Scriptable* /*Owner*/, Actor* target, Effect* fx) //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\n", fx->Opcode, fx->Parameter2, fx->Resource); if (!Owner) { return FX_NOT_APPLIED; @@ -2897,7 +2897,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\n", fx->Opcode, fx->Parameter1); if (!fx->Parameter1) { return FX_NOT_APPLIED; } @@ -2922,7 +2922,7 @@ 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) Type: %d\n", fx->Opcode, fx->Parameter2); if (target->SetSpellState( SS_TORTOISE)) return FX_NOT_APPLIED; if (enhanced_effects) { target->AddPortraitIcon(PI_TORTOISE); @@ -2934,7 +2934,7 @@ int fx_tortoise_shell (Scriptable* /*Owner*/, Actor* target, Effect* fx) //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\n", fx->Opcode, fx->Parameter2); if (target->SetSpellState( SS_BLINK)) return FX_APPLIED; @@ -2968,7 +2968,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\n", fx->Opcode, fx->Parameter1, fx->Resource); if (fx->Parameter3) { fx->Parameter3--; } else { @@ -2981,7 +2981,7 @@ int fx_persistent_use_effect_list (Scriptable* Owner, Actor* target, Effect* fx) //435 DayBlindness 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 (0) print( "fx_day_blindness (%2d) Amount: %d\n", fx->Opcode, fx->Parameter2); if (target->SetSpellState(SS_DAYBLINDNESS)) return FX_NOT_APPLIED; // medium hack (better than original) // the original used explicit race/subrace values @@ -3005,7 +3005,7 @@ int fx_day_blindness (Scriptable* Owner, Actor* target, Effect* fx) //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); + if (0) print( "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); @@ -3016,7 +3016,7 @@ 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\n", fx->Opcode, fx->Parameter2); ieDword anim = BASE_GET(IE_ANIMATION_ID); if (anim>=0x6000 || anim<=0x6fff) { STAT_SET(IE_ANIMATION_ID, anim&0x600f); @@ -3034,7 +3034,7 @@ 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)\n", fx->Opcode); //+1 to all saves STAT_ADD( IE_SAVEFORTITUDE, 1); @@ -3052,7 +3052,7 @@ 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\n", fx->Opcode, fx->Parameter1); //TODO: implement this return FX_APPLIED; } @@ -3064,7 +3064,7 @@ int fx_barbarian_rage (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx) //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); + if (0) print( "fx_missile_damage_reduction (%2d) Amount:%d\n", fx->Opcode, fx->Parameter1); STAT_SET(IE_RESISTMISSILE, fx->Parameter1); //TODO: didn't set the pluses return FX_APPLIED; @@ -3073,7 +3073,7 @@ int fx_missile_damage_reduction (Scriptable* /*Owner*/, Actor* target, Effect* f //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)\n", fx->Opcode); if (target->SetSpellState( SS_TENSER)) return FX_APPLIED; STAT_SUB(IE_ARMORCLASS, 2); @@ -3088,7 +3088,7 @@ int fx_tenser_transformation (Scriptable* /*Owner*/, Actor* target, Effect* fx) //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)\n", fx->Opcode); target->SetSpellState(SS_SMITEEVIL); return FX_NOT_APPLIED; } @@ -3102,7 +3102,7 @@ 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)\n", fx->Opcode); target->fxqueue.RemoveAllEffectsWithParam(fx_disease_ref, 4); target->fxqueue.RemoveAllEffectsWithParam(fx_disease_ref, 5); target->fxqueue.RemoveAllEffectsWithParam(fx_disease_ref, 6); @@ -3125,7 +3125,7 @@ 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)\n", fx->Opcode); if (target->SetSpellState( SS_ALICORNLANCE)) return FX_APPLIED; ////target->AddPortraitIcon(PI_ALICORN); //no portrait icon STAT_SUB(IE_ARMORCLASS, 2); @@ -3184,7 +3184,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)\n", fx->Opcode); //this effect ceases to affect dead targets (probably on frozen and stoned too) if (STATE_GET(STATE_DEAD)) { @@ -3201,7 +3201,7 @@ 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) @@ -3225,7 +3225,7 @@ int fx_call_lightning (Scriptable* /*Owner*/, Actor* target, Effect* fx) //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)\n", fx->Opcode); int state; int icon; int value; @@ -3255,7 +3255,7 @@ int fx_globe_invulnerability (Scriptable* /*Owner*/, Actor* target, Effect* fx) //451 LowerResistance int fx_lower_resistance (Scriptable* /*Owner*/, Actor* target, Effect* fx) { - if (0) printf( "fx_lower_resistance (%2d)\n", fx->Opcode); + if (0) print( "fx_lower_resistance (%2d)\n", fx->Opcode); if (target->SetSpellState( SS_LOWERRESIST)) return FX_APPLIED; STAT_SUB(IE_RESISTMAGIC, 15); @@ -3267,7 +3267,7 @@ 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)\n", fx->Opcode); if (target->SetSpellState( SS_BANE)) return FX_NOT_APPLIED; //do this once @@ -3287,7 +3287,7 @@ 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)\n", fx->Opcode); if (fx->FirstApply) { if (target->HasSpellState(SS_EXPERTISE)) { @@ -3317,7 +3317,7 @@ 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 (0) print( "fx_expertise (%2d)\n", fx->Opcode); if (fx->FirstApply) { if (target->HasSpellState(SS_POWERATTACK)) { target->fxqueue.RemoveAllEffects(fx_powerattack_ref); @@ -3343,7 +3343,7 @@ static EffectRef fx_hamstring_ref = { "HamString", -1 }; int fx_arterial_strike (Scriptable* /*Owner*/, Actor* target, Effect* fx) { - if (0) printf( "fx_arterial_strike (%2d)\n", fx->Opcode); + if (0) print( "fx_arterial_strike (%2d)\n", fx->Opcode); if (fx->FirstApply) { if (target->HasSpellState(SS_HAMSTRING)) { target->fxqueue.RemoveAllEffects(fx_hamstring_ref); @@ -3361,7 +3361,7 @@ static EffectRef fx_arterialstrike_ref = { "ArterialStrike", -1 }; int fx_hamstring (Scriptable* /*Owner*/, Actor* target, Effect* fx) { - if (0) printf( "fx_hamstring (%2d)\n", fx->Opcode); + if (0) print( "fx_hamstring (%2d)\n", fx->Opcode); if (fx->FirstApply) { if (target->HasSpellState(SS_ARTERIAL)) { target->fxqueue.RemoveAllEffects(fx_arterialstrike_ref); @@ -3377,7 +3377,7 @@ int fx_hamstring (Scriptable* /*Owner*/, Actor* target, Effect* fx) //457 RapidShot int fx_rapid_shot (Scriptable* /*Owner*/, Actor* target, Effect* fx) { - if (0) printf( "fx_rapid_shot (%2d)\n", fx->Opcode); + if (0) print( "fx_rapid_shot (%2d)\n", fx->Opcode); if (target->SetSpellState( SS_RAPIDSHOT)) return FX_APPLIED; //TODO: return FX_APPLIED; diff --git a/project/jni/application/gemrb/gemrb/plugins/KEYImporter/Dictionary.cpp b/project/jni/application/gemrb/gemrb/plugins/KEYImporter/Dictionary.cpp index 73be141cc..34da66c45 100644 --- a/project/jni/application/gemrb/gemrb/plugins/KEYImporter/Dictionary.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/KEYImporter/Dictionary.cpp @@ -23,6 +23,7 @@ #include "globals.h" #include "win32def.h" +#include #include ///////////////////////////////////////////////////////////////////////////// diff --git a/project/jni/application/gemrb/gemrb/plugins/KEYImporter/KEYImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/KEYImporter/KEYImporter.cpp index a444a492f..657938886 100644 --- a/project/jni/application/gemrb/gemrb/plugins/KEYImporter/KEYImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/KEYImporter/KEYImporter.cpp @@ -23,7 +23,7 @@ #include "win32def.h" #include "globals.h" -#include "ArchiveImporter.h" +#include "IndexedArchive.h" #include "Interface.h" #include "ResourceDesc.h" #include "System/FileStream.h" @@ -102,7 +102,7 @@ static void FindBIF(BIFEntry *entry) if (!entry->cd) { printStatus( "ERROR", LIGHT_RED ); - printf( "Cannot find %s... Resource unavailable.\n", + print( "Cannot find %s... Resource unavailable.\n", entry->name ); entry->found = false; return; @@ -118,8 +118,7 @@ static void FindBIF(BIFEntry *entry) } } - printMessage( "KEYImporter", " ", WHITE ); - printf( "Cannot find %s...", entry->name ); + printMessage("KEYImporter", "Cannot find %s...", WHITE, entry->name); printStatus( "ERROR", LIGHT_RED ); } @@ -128,24 +127,22 @@ 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" ); + print( "[ERROR]\nAn Archive Plug-in is not Available\n" ); 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 )) { + printMessage("KEYImporter", "Opening %s...", WHITE, 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! " ); + print("%s", "\nEscaped 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 ); return false; } printStatus( "OK", LIGHT_GREEN ); @@ -154,8 +151,7 @@ bool KEYImporter::Open(const char *resfile, const char *desc) 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 ); + printMessage( "KEYImporter", "File has an Invalid Signature.\n", LIGHT_RED ); textcolor( WHITE ); delete( f ); return false; @@ -168,10 +164,10 @@ bool KEYImporter::Open(const char *resfile, const char *desc) f->ReadDword( &BifOffset ); f->ReadDword( &ResOffset ); printMessage( "KEYImporter", " ", WHITE ); - printf( "BIF Files Count: %d (Starting at %d Bytes)\n", BifCount, + print( "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 ); + printMessage("KEYImporter", "RES Count: %d (Starting at %d Bytes)\n", WHITE, + ResCount, ResOffset); f->Seek( BifOffset, GEM_STREAM_START ); ieDword BifLen, ASCIIZOffset; ieWord ASCIIZLen; @@ -190,14 +186,6 @@ 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 ); } @@ -246,24 +234,25 @@ DataStream* KEYImporter::GetStream(const char *resname, ieWord type) if (type == 0) return NULL; if (resources.Lookup( resname, type, ResLocator )) { - int bifnum = ( ResLocator & 0xFFF00000 ) >> 20; + unsigned 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", + print( "Cannot find %s... Resource unavailable.\n", biffiles[bifnum].name ); return NULL; } - PluginHolder ai(IE_BIF_CLASS_ID); + PluginHolder ai(IE_BIF_CLASS_ID); if (ai->OpenArchive( biffiles[bifnum].path ) == GEM_ERROR) { - printf("Cannot open archive %s\n", biffiles[bifnum].path ); + print("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, "." ); strcat( ret->filename, core->TypeExt( type ) ); return ret; } diff --git a/project/jni/application/gemrb/gemrb/plugins/KEYImporter/KEYImporter.h b/project/jni/application/gemrb/gemrb/plugins/KEYImporter/KEYImporter.h index 4ea85f996..ec44820db 100644 --- a/project/jni/application/gemrb/gemrb/plugins/KEYImporter/KEYImporter.h +++ b/project/jni/application/gemrb/gemrb/plugins/KEYImporter/KEYImporter.h @@ -23,6 +23,9 @@ #include "ResourceSource.h" +#include "IndexedArchive.h" +#include "PluginMgr.h" + #include "Dictionary.h" #include @@ -45,7 +48,6 @@ struct BIFEntry { bool found; }; - class KEYImporter : public ResourceSource { private: std::vector< BIFEntry> biffiles; diff --git a/project/jni/application/gemrb/gemrb/plugins/MOSImporter/MOSImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/MOSImporter/MOSImporter.cpp index 660e1f97c..6fd379b0d 100644 --- a/project/jni/application/gemrb/gemrb/plugins/MOSImporter/MOSImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/MOSImporter/MOSImporter.cpp @@ -23,11 +23,9 @@ #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; @@ -52,36 +50,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 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; @@ -151,5 +126,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/project/jni/application/gemrb/gemrb/plugins/MUSImporter/MUSImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/MUSImporter/MUSImporter.cpp index 1bb6b1c2d..d440ec792 100644 --- a/project/jni/application/gemrb/gemrb/plugins/MUSImporter/MUSImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/MUSImporter/MUSImporter.cpp @@ -74,9 +74,8 @@ 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 )) { + printMessage("MUSImporter", "Loading %s...", WHITE, path); + if (!str->Open(path)) { printStatus("NOT FOUND", LIGHT_RED ); return false; } @@ -318,7 +317,7 @@ void MUSImporter::PlayMusic(char* name) } else { core->GetAudioDrv()->Stop(); } - printf( "Playing: %s\n", FName ); + print( "Playing: %s\n", FName ); } bool MUSImporter::CurrentPlayList(const char* name) { diff --git a/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/MVEPlayer.cpp b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/MVEPlayer.cpp index 6ff83ca0f..750fe8a4f 100644 --- a/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/MVEPlayer.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/MVEPlayer.cpp @@ -104,7 +104,7 @@ int MVEPlay::doPlay() player.video_init(w, h); if (!player.start_playback()) { - printf("Failed to decode movie!\n"); + print("Failed to decode movie!\n"); return 1; } @@ -183,5 +183,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/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/gstmvedemux.h b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/gstmvedemux.h index c8908c297..c34b711fc 100644 --- a/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/gstmvedemux.h +++ b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/gstmvedemux.h @@ -26,8 +26,8 @@ #include "globals.h" #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/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/mve_player.cpp b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/mve_player.cpp index b8edf7d11..79376a3b6 100644 --- a/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/mve_player.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/mve_player.cpp @@ -80,7 +80,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).\n", video_skippedframes); } /* @@ -103,7 +103,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.\n"); return false; } @@ -147,7 +147,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\n"); return false; } return true; @@ -173,7 +173,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\n"); return false; } @@ -228,7 +228,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); + print("Warning: Skipping unknown segment type 0x%02x", type); } return true; @@ -297,8 +297,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 +341,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 +364,7 @@ void MVEPlayer::segment_video_compressedpalette() { } } } +#endif } void MVEPlayer::segment_video_codemap(unsigned short size) { @@ -419,7 +424,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.\n"); playsound = false; return; } @@ -442,7 +447,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\n", audio_sample_rate, audio_num_channels, audio_sample_size, min_buffer_len, audio_compressed ? "compressed" : "uncompressed");*/ } diff --git a/project/jni/application/gemrb/gemrb/plugins/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/Makefile.am index b5a736140..2b03970d0 100644 --- a/project/jni/application/gemrb/gemrb/plugins/Makefile.am +++ b/project/jni/application/gemrb/gemrb/plugins/Makefile.am @@ -30,6 +30,7 @@ SUBDIRS = \ PNGImporter \ PROImporter \ PSTOpcodes \ + SAVImporter \ SDLVideo \ SPLImporter \ STOImporter \ diff --git a/project/jni/application/gemrb/gemrb/plugins/OGGReader/OGGReader.cpp b/project/jni/application/gemrb/gemrb/plugins/OGGReader/OGGReader.cpp index 762ccfe8e..437dbd075 100644 --- a/project/jni/application/gemrb/gemrb/plugins/OGGReader/OGGReader.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/OGGReader/OGGReader.cpp @@ -124,5 +124,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/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/AmbientMgrAL.cpp b/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/AmbientMgrAL.cpp index c5c6c53c3..7cd0ee348 100644 --- a/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/AmbientMgrAL.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/AmbientMgrAL.cpp @@ -269,7 +269,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\n", (void*)this, soundrefs[index], index, soundrefs.size(), stream); return core->GetAudioDrv()->QueueAmbient(stream, soundrefs[index]); } diff --git a/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/OpenALAudio.cpp b/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/OpenALAudio.cpp index 4634342e9..883e4cdff 100644 --- a/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/OpenALAudio.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/OpenALAudio.cpp @@ -28,8 +28,8 @@ bool checkALError(const char* msg, const char* status) { int error = alGetError(); if (error != AL_NO_ERROR) { - printMessage("OpenAL", msg, WHITE ); - printf (": 0x%x ", error); + printMessage("OpenAL", "%s", WHITE, msg); + print (": 0x%x ", error); printStatus(status, YELLOW); return true; } @@ -38,9 +38,9 @@ bool checkALError(const char* msg, const char* status) { void showALCError(const char* msg, const char* status, ALCdevice *device) { int error = alcGetError(device); - printMessage("OpenAL", msg, WHITE ); + printMessage("OpenAL", "%s", WHITE, msg ); if (error != AL_NO_ERROR) { - printf (": 0x%x ", error); + print (": 0x%x ", error); } printStatus(status, YELLOW); } @@ -171,11 +171,8 @@ 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 ); + printMessage( "OpenAL", "Allocated %d streams.%s", WHITE, + num_streams, (num_streams < MAX_STREAMS ? " (Fewer than desired.)" : "" )); stayAlive = true; musicThread = SDL_CreateThread( MusicManager, this ); @@ -298,7 +295,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\n", ResRef, e->Buffer, buffercache.GetCount()); if (buffercache.GetCount() > BUFFER_CACHE_SIZE) { evictBuffer(); @@ -361,7 +358,7 @@ Holder OpenALAudioDriver::Play(const char* ResRef, int XPos, int YP 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); + print("speech.free: %d source:%d\n", speech.free,speech.Source); core->GetDictionary()->Lookup( "Volume Voices", volume ); alSourcef( speech.Source, AL_GAIN, 0.01f * volume ); @@ -508,7 +505,6 @@ bool OpenALAudioDriver::Stop() bool OpenALAudioDriver::Pause() { - ambim->deactivate(); SDL_mutexP( musicMutex ); if (!alIsSource( MusicSource )) { SDL_mutexV( musicMutex ); @@ -518,6 +514,7 @@ bool OpenALAudioDriver::Pause() checkALError("Unable to pause music source", "WARNING"); MusicPlaying = false; SDL_mutexV( musicMutex ); + ((AmbientMgrAL*) ambim)->deactivate(); #ifdef ANDROID al_android_pause_playback(); //call AudioTrack.pause() from JNI #endif @@ -529,7 +526,6 @@ bool OpenALAudioDriver::Resume() #ifdef ANDROID al_android_resume_playback(); //call AudioTrack.play() from JNI #endif - ambim->activate(); SDL_mutexP( musicMutex ); if (!alIsSource( MusicSource )) { SDL_mutexV( musicMutex ); @@ -539,6 +535,7 @@ bool OpenALAudioDriver::Resume() checkALError("Unable to resume music source", "WARNING"); MusicPlaying = true; SDL_mutexV( musicMutex ); + ((AmbientMgrAL*) ambim)->activate(); return true; } @@ -729,7 +726,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\n", k); break; } ++n; diff --git a/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/OpenALAudio.cpp.old b/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/OpenALAudio.cpp.old new file mode 100644 index 000000000..3b3ad1a35 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/OpenALAudio.cpp.old @@ -0,0 +1,924 @@ +/* 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. + * + * + */ + +#include "OpenALAudio.h" + +#include "GameData.h" + +#include +#include + +bool checkALError(const char* msg, const char* status) { + int error = alGetError(); + if (error != AL_NO_ERROR) { + printMessage("OpenAL", msg, WHITE ); + printf (": 0x%x ", error); + printStatus(status, YELLOW); + return true; + } + return false; +} + +void showALCError(const char* msg, const char* status, ALCdevice *device) { + int error = alcGetError(device); + printMessage("OpenAL", msg, WHITE ); + if (error != AL_NO_ERROR) { + printf (": 0x%x ", error); + } + printStatus(status, YELLOW); +} + +void OpenALSoundHandle::SetPos(int XPos, int YPos) { + if (!parent) return; + + ALfloat SourcePos[] = { + (float) XPos, (float) YPos, 0.0f + }; + + alSourcefv(parent->Source, AL_POSITION, SourcePos); +} + +bool OpenALSoundHandle::Playing() { + if (!parent) return false; + + parent->ClearIfStopped(); + return parent != 0; +} + +void OpenALSoundHandle::Stop() { + if (!parent) return; + + parent->ForceClear(); +} + +void OpenALSoundHandle::StopLooping() { + if (!parent) return; + + alSourcei(parent->Source, AL_LOOPING, 0); +} + +void AudioStream::ClearProcessedBuffers() +{ + ALint processed = 0; + alGetSourcei( Source, AL_BUFFERS_PROCESSED, &processed ); + + 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"); + + if (delete_buffers) { + alDeleteBuffers(processed, b); + checkALError("Failed to delete buffers", "WARNING"); + } + + delete[] b; + } + +} + +void AudioStream::ClearIfStopped() +{ + if (free || locked) return; + + if (!alIsSource(Source)) return; + + ALint state; + alGetSourcei( Source, AL_SOURCE_STATE, &state ); + if (!checkALError("Failed to check source state", "WARNING") && + state == AL_STOPPED) + { + ClearProcessedBuffers(); + alDeleteSources( 1, &Source ); + checkALError("Failed to delete source", "WARNING"); + Source = 0; + Buffer = 0; + free = true; + if (handle) { handle->Invalidate(); handle.release(); } + ambient = false; + locked = false; + delete_buffers = false; + } +} + +void AudioStream::ForceClear() +{ + if (!alIsSource(Source)) return; + + alSourceStop(Source); + checkALError("Failed to stop source", "WARNING"); + ClearProcessedBuffers(); + ClearIfStopped(); +} + +OpenALAudioDriver::OpenALAudioDriver(void) +{ + alutContext = NULL; + MusicPlaying = false; + music_memory = (short*) malloc(ACM_BUFFERSIZE); + MusicSource = 0; + memset(MusicBuffer, 0, MUSICBUFFERS*sizeof(ALuint)); + musicMutex = SDL_CreateMutex(); + ambim = NULL; +} + +bool OpenALAudioDriver::Init(void) +{ + ALCdevice *device; + ALCcontext *context; + + device = alcOpenDevice (NULL); + if (device == NULL) { + showALCError("Failed to open device", "ERROR", device); + return false; + } + + context = alcCreateContext (device, NULL); + if (context == NULL) { + showALCError("Failed to create context", "ERROR", device); + alcCloseDevice (device); + return false; + } + + if (!alcMakeContextCurrent (context)) { + showALCError("Failed to select context", "ERROR", device); + alcDestroyContext (context); + alcCloseDevice (device); + return false; + } + alutContext = context; + + //1 for speech + 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 ); + + stayAlive = true; + musicThread = SDL_CreateThread( MusicManager, this ); + + ambim = new AmbientMgrAL; + speech.free = true; + speech.ambient = false; + return true; +} + +int OpenALAudioDriver::CountAvailableSources(int limit) +{ + ALuint* src = new ALuint[limit+2]; + int i; + for (i = 0; i < limit+2; ++i) { + alGenSources(1, &src[i]); + if (alGetError() != AL_NO_ERROR) + break; + } + if (i > 0) + alDeleteSources(i, src); + delete[] src; + + // Leave two sources free for internal OpenAL usage + // (Might not be strictly necessary...) + i -= 2; + + checkALError("Error while auto-detecting number of sources", "WARNING"); + + // Return number of succesfully allocated sources + return i; +} + +OpenALAudioDriver::~OpenALAudioDriver(void) +{ + if (!ambim) { + // initialisation must have failed + return; + } + + for(int i =0; iLength; + return e->Buffer; + } + + //no cache entry... + alGenBuffers(1, &Buffer); + if (checkALError("Unable to create sound buffer", "ERROR")) { + return 0; + } + + ResourceHolder acm(ResRef); + if (!acm) { + alDeleteBuffers( 1, &Buffer ); + return 0; + } + int cnt = acm->get_length(); + int riff_chans = acm->get_channels(); + int samplerate = acm->get_samplerate(); + //multiply always by 2 because it is in 16 bits + int rawsize = cnt * 2; + short* memory = (short*) malloc(rawsize); + //multiply always with 2 because it is in 16 bits + int cnt1 = acm->read_samples( memory, cnt ) * 2; + //Sound Length in milliseconds + time_length = ((cnt / riff_chans) * 1000) / samplerate; + //it is always reading the stuff into 16 bits + alBufferData( Buffer, GetFormatEnum( riff_chans, 16 ), memory, cnt1, samplerate ); + free(memory); + + if (checkALError("Unable to fill buffer", "ERROR")) { + alDeleteBuffers( 1, &Buffer ); + checkALError("Error deleting buffer", "WARNING"); + return 0; + } + + e = new CacheEntry; + e->Buffer = Buffer; + 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()); + + if (buffercache.GetCount() > BUFFER_CACHE_SIZE) { + evictBuffer(); + } + return Buffer; +} + +Holder OpenALAudioDriver::Play(const char* ResRef, int XPos, int YPos, unsigned int flags, unsigned int *length) +{ + ALuint Buffer; + unsigned int time_length; + + if(ResRef == NULL) { + if((flags & GEM_SND_SPEECH) && alIsSource(speech.Source)) { + //So we want him to be quiet... + alSourceStop( speech.Source ); + checkALError("Unable to stop speech", "WARNING"); + speech.ClearProcessedBuffers(); + } + return Holder(); + } + + Buffer = loadSound( ResRef, time_length ); + if (Buffer == 0) { + return Holder(); + } + + if (length) { + *length = time_length; + } + + ALuint Source; + ALfloat SourcePos[] = { + (float) XPos, (float) YPos, 0.0f + }; + ALfloat SourceVel[] = { + 0.0f, 0.0f, 0.0f + }; + + ieDword volume = 100; + + 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(); + } + if(!alIsSource(speech.Source)) { + alGenSources( 1, &speech.Source ); + if (checkALError("Error creating source for speech", "ERROR")) { + return Holder(); + } + } + + 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 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")) { + return Holder(); + } + 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; + } + } + + if (stream == -1) { + // Failed to assign new sound. + // The buffercache will handle deleting Buffer. + return Holder(); + } + + // not speech + alGenSources( 1, &Source ); + if (checkALError("Unable to create source", "ERROR")) { + return Holder(); + } + + alSourcef( Source, AL_PITCH, 1.0f ); + alSourcefv( Source, AL_VELOCITY, SourceVel ); + alSourcei( Source, AL_LOOPING, (flags & GEM_SND_LOOPING ? 1 : 0) ); + 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 ); + + if (checkALError("Unable to set sound parameters", "ERROR")) { + return Holder(); + } + + streams[stream].Buffer = Buffer; + streams[stream].Source = Source; + streams[stream].free = false; + alSourcePlay( Source ); + + if (checkALError("Unable to play sound", "ERROR")) { + return Holder(); + } + + streams[stream].handle = new OpenALSoundHandle(&streams[stream]); + return streams[stream].handle.get(); +} + +bool OpenALAudioDriver::IsSpeaking() +{ + speech.ClearIfStopped(); + return !speech.free; +} + +void OpenALAudioDriver::UpdateVolume(unsigned int flags) +{ + ieDword volume; + + if (flags & GEM_SND_VOL_MUSIC) { + SDL_mutexP( musicMutex ); + core->GetDictionary()->Lookup("Volume Music", volume); + if (alIsSource(MusicSource)) + alSourcef(MusicSource, AL_GAIN, volume * 0.01f); + SDL_mutexV(musicMutex); + } + + if (flags & GEM_SND_VOL_AMBIENTS) { + core->GetDictionary()->Lookup("Volume Ambients", volume); + ((AmbientMgrAL*) ambim)->UpdateVolume(volume); + } +} + +bool OpenALAudioDriver::CanPlay() +{ + return true; +} + +void OpenALAudioDriver::ResetMusics() +{ + MusicPlaying = false; + SDL_mutexP( musicMutex ); + if (alIsSource(MusicSource)) { + alSourceStop(MusicSource); + checkALError("Unable to stop music source", "WARNING"); + alDeleteSources(1, &MusicSource ); + checkALError("Unable to delete music source", "WARNING"); + MusicSource = 0; + for (int i=0; ideactivate(); + SDL_mutexP( musicMutex ); + if (!alIsSource( MusicSource )) { + SDL_mutexV( musicMutex ); + return false; + } + alSourcePause(MusicSource); + checkALError("Unable to pause music source", "WARNING"); + MusicPlaying = false; + SDL_mutexV( musicMutex ); +#ifdef ANDROID + al_android_pause_playback(); //call AudioTrack.pause() from JNI +#endif + return true; +} + +bool OpenALAudioDriver::Resume() +{ +#ifdef ANDROID + al_android_resume_playback(); //call AudioTrack.play() from JNI +#endif + ((AmbientMgrAL*) ambim)->activate(); + SDL_mutexP( musicMutex ); + if (!alIsSource( MusicSource )) { + SDL_mutexV( musicMutex ); + return false; + } + alSourcePlay(MusicSource); + checkALError("Unable to resume music source", "WARNING"); + MusicPlaying = true; + SDL_mutexV( musicMutex ); + return true; +} + +int OpenALAudioDriver::CreateStream(Holder newMusic) +{ + StackLock l(musicMutex, "musicMutex in CreateStream()"); + + // Free old MusicReader + MusicReader = newMusic; + if (!MusicReader) { + MusicPlaying = false; + } + + if (MusicBuffer[0] == 0) { + alGenBuffers( MUSICBUFFERS, MusicBuffer ); + if (checkALError("Unable to create music buffers", "ERROR")) { + return -1; + } + } + + if (MusicSource == 0) { + alGenSources( 1, &MusicSource ); + if (checkALError("Unable to create music source", "ERROR")) { + return -1; + } + + ALfloat SourcePos[] = { + 0.0f, 0.0f, 0.0f + }; + ALfloat SourceVel[] = { + 0.0f, 0.0f, 0.0f + }; + + ieDword volume; + core->GetDictionary()->Lookup( "Volume Music", volume ); + alSourcef( MusicSource, AL_PITCH, 1.0f ); + alSourcef( MusicSource, AL_GAIN, 0.01f * volume ); + alSourcei( MusicSource, AL_SOURCE_RELATIVE, 1 ); + alSourcefv( MusicSource, AL_POSITION, SourcePos ); + alSourcefv( MusicSource, AL_VELOCITY, SourceVel ); + alSourcei( MusicSource, AL_LOOPING, 0 ); + checkALError("Unable to set music parameters", "WARNING"); + } + + return 0; +} + +void OpenALAudioDriver::UpdateListenerPos(int XPos, int YPos ) +{ + alListener3f( AL_POSITION, (float) XPos, (float) YPos, 0.0f ); +} + +void OpenALAudioDriver::GetListenerPos(int &XPos, int &YPos ) +{ + ALfloat listen[3]; + alGetListenerfv( AL_POSITION, listen ); + if (checkALError("Unable to get listener pos", "ERROR")) return; + XPos = (int) listen[0]; + YPos = (int) listen[1]; +} + +bool OpenALAudioDriver::ReleaseStream(int stream, bool HardStop) +{ + if (streams[stream].free || !streams[stream].locked) + return false; + streams[stream].locked = false; + if (!HardStop) { + // it's now unlocked, so it will automatically be reclaimed when needed + return true; + } + + ALuint Source = streams[stream].Source; + alSourceStop(Source); + checkALError("Unable to stop source", "WARNING"); + streams[stream].ClearIfStopped(); + + return true; +} + +//This one is used for movies and ambients. +int OpenALAudioDriver::SetupNewStream( ieWord x, ieWord y, ieWord z, + ieWord gain, bool point, bool Ambient ) +{ + // Find a free (or finished) stream for this sound + int stream = -1; + for (int i = 0; i < num_streams; i++) { + streams[i].ClearIfStopped(); + if (streams[i].free) { + stream = i; + break; + } + } + if (stream == -1) return -1; + + ALuint source; + alGenSources(1, &source); + if (checkALError("Unable to create new source", "ERROR")) { + return -1; + } + + ALfloat position[] = { (float) x, (float) y, (float) z }; + alSourcef( source, AL_PITCH, 1.0f ); + alSourcefv( source, AL_POSITION, position ); + alSourcef( source, AL_GAIN, 0.01f * gain ); + 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"); + + streams[stream].Buffer = 0; + streams[stream].Source = source; + streams[stream].free = false; + streams[stream].ambient = Ambient; + streams[stream].locked = true; + + return stream; +} + +int OpenALAudioDriver::QueueAmbient(int stream, const char* sound) +{ + if (streams[stream].free || !streams[stream].ambient) + return -1; + + ALuint source = streams[stream].Source; + + // first dequeue any processed buffers + streams[stream].ClearProcessedBuffers(); + + if (sound == 0) + return 0; + + unsigned int time_length; + ALuint Buffer = loadSound(sound, time_length); + if (0 == Buffer) { + return -1; + } + + 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; + } + + return time_length; +} + +void OpenALAudioDriver::SetAmbientStreamVolume(int stream, int volume) +{ + if (streams[stream].free || !streams[stream].ambient) + return; + + ALuint source = streams[stream].Source; + alSourcef( source, AL_GAIN, 0.01f * volume ); + checkALError("Unable to set ambient volume", "WARNING"); +} + +bool OpenALAudioDriver::evictBuffer() +{ + // Note: this function assumes the caller holds bufferMutex + + // Room for optimization: this is O(n^2) in the number of buffers + // at the tail that are used. It can be O(n) if LRUCache supports it. + + unsigned int n = 0; + void* p; + const char* k; + bool res; + + while ((res = buffercache.getLRU(n, k, p)) == true) { + CacheEntry* e = (CacheEntry*)p; + alDeleteBuffers(1, &e->Buffer); + if (alGetError() == AL_NO_ERROR) { + // Buffer was unused. An error would have indicated + // the buffer was still attached to a source. + + delete e; + buffercache.Remove(k); + + //printf("Removed buffer %s from ACMImp cache\n", k); + break; + } + ++n; + } + + return res; +} + +void OpenALAudioDriver::clearBufferCache(bool force) +{ + // Room for optimization: any method of iterating over the buffers + // would suffice. It doesn't have to be in LRU-order. + void* p; + const char* k; + int n = 0; + while (buffercache.getLRU(n, k, p)) { + CacheEntry* e = (CacheEntry*)p; + alDeleteBuffers(1, &e->Buffer); + if (force || alGetError() == AL_NO_ERROR) { + delete e; + buffercache.Remove(k); + } else + ++n; + } +} + +ALenum OpenALAudioDriver::GetFormatEnum(int channels, int bits) +{ + switch (channels) { + case 1: + if (bits == 8) + return AL_FORMAT_MONO8; + else + return AL_FORMAT_MONO16; + break; + + case 2: + if (bits == 8) + return AL_FORMAT_STEREO8; + else + return AL_FORMAT_STEREO16; + break; + } + return AL_FORMAT_MONO8; +} + +int OpenALAudioDriver::MusicManager(void* arg) +{ + OpenALAudioDriver* driver = (OpenALAudioDriver*) arg; + ALuint buffersreturned = 0; + ALboolean bFinished = AL_FALSE; + while (driver->stayAlive) { + SDL_Delay(30); + StackLock l(driver->musicMutex, "musicMutex in PlayListManager()"); + if (driver->MusicPlaying) { + ALint state; + alGetSourcei( driver->MusicSource, AL_SOURCE_STATE, &state ); + 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); + driver->MusicPlaying = false; + return -1; + case AL_INITIAL: + { + printMessage("OPENAL", "Music in INITIAL State. AutoStarting\n", WHITE ); + 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() ); + } + alSourceQueueBuffers( driver->MusicSource, MUSICBUFFERS, driver->MusicBuffer ); + if (alIsSource( driver->MusicSource )) { + alSourcePlay( driver->MusicSource ); + checkALError("Error playing music source", "ERROR"); + } + bFinished = AL_FALSE; + } + break; + case AL_STOPPED: + printMessage("OpenAL", "WARNING: Buffer Underrun. AutoRestarting Stream Playback\n", WHITE ); + if (alIsSource( driver->MusicSource )) { + alSourcePlay( driver->MusicSource ); + checkALError("Error playing music source", "ERROR"); + } + break; + case AL_PLAYING: + break; + } + ALint processed; + alGetSourcei( driver->MusicSource, AL_BUFFERS_PROCESSED, &processed ); + if (checkALError("Unable to query music source state", "ERROR")) { + driver->MusicPlaying = false; + return -1; + } + if (processed > 0) { + buffersreturned += processed; + while (processed) { + ALuint BufferID; + alSourceUnqueueBuffers( driver->MusicSource, 1, &BufferID ); + if (checkALError("Unable to unqueue music buffers", "ERROR")) { + driver->MusicPlaying = false; + return -1; + } + if (bFinished == AL_FALSE) { + int size = ACM_BUFFERSIZE; + int cnt = driver->MusicReader->read_samples( driver->music_memory, ACM_BUFFERSIZE >> 1 ); + size -= ( cnt * 2 ); + if (size != 0) + bFinished = AL_TRUE; + if (bFinished) { + printMessage("OpenAL", "Playing Next Music\n", WHITE ); + core->GetMusicMgr()->PlayNext(); + if (driver->MusicPlaying) { + printMessage( "OpenAL", "Queuing New Music\n", WHITE ); + driver->MusicReader->read_samples( ( driver->music_memory + cnt ), size >> 1 ); + bFinished = AL_FALSE; + } else { + printMessage( "OpenAL", "No Other Music to play\n", WHITE ); + 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")) { + driver->MusicPlaying = false; + return -1; + } + alSourceQueueBuffers( driver->MusicSource, 1, &BufferID ); + if (checkALError("Unable to queue music buffers", "ERROR")) { + driver->MusicPlaying = false; + return -1; + } + processed--; + } + } + } + } + } + return 0; +} + +//This one is used for movies, might be useful for others ? +void OpenALAudioDriver::QueueBuffer(int stream, unsigned short bits, + int channels, short* memory, + int size, int samplerate) +{ + ALuint Buffer; + + alGenBuffers(1, &Buffer); + if (checkALError("Unable to create buffer", "ERROR")) { + return; + } + + alBufferData(Buffer, GetFormatEnum(channels, bits), memory, size, samplerate); + 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; + } + + ALenum state; + alGetSourcei(streams[stream].Source, AL_SOURCE_STATE, &state); + if (checkALError("Unable to query source state", "ERROR")) { + return; + } + + if (state != AL_PLAYING ) { + alSourcePlay(streams[stream].Source); + checkALError("Unable to play source", "ERROR"); + } + + return; +} + +#include "plugindef.h" + +GEMRB_PLUGIN(0x27DD67E0, "OpenAL Audio Driver") +PLUGIN_DRIVER(OpenALAudioDriver, "openal") +END_PLUGIN() diff --git a/project/jni/application/gemrb/gemrb/plugins/PLTImporter/PLTImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/PLTImporter/PLTImporter.cpp index c7ec0da6f..cc996bd99 100644 --- a/project/jni/application/gemrb/gemrb/plugins/PLTImporter/PLTImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/PLTImporter/PLTImporter.cpp @@ -49,16 +49,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.\n" ); return false; } @@ -68,7 +70,7 @@ bool PLTImporter::Open(DataStream* stream) pixels = malloc( Width * Height * 2 ); str->Read( pixels, Width * Height * 2 ); - + delete str; return true; } @@ -106,5 +108,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/project/jni/application/gemrb/gemrb/plugins/PNGImporter/PNGImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/PNGImporter/PNGImporter.cpp index 30afe7481..f39ff02bd 100644 --- a/project/jni/application/gemrb/gemrb/plugins/PNGImporter/PNGImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/PNGImporter/PNGImporter.cpp @@ -213,5 +213,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/project/jni/application/gemrb/gemrb/plugins/PROImporter/PROImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/PROImporter/PROImporter.cpp index 013cc75e0..481b90a44 100644 --- a/project/jni/application/gemrb/gemrb/plugins/PROImporter/PROImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/PROImporter/PROImporter.cpp @@ -28,33 +28,27 @@ 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\n" ); return false; } diff --git a/project/jni/application/gemrb/gemrb/plugins/PROImporter/PROImporter.h b/project/jni/application/gemrb/gemrb/plugins/PROImporter/PROImporter.h index d6c7b91c1..7c22587e8 100644 --- a/project/jni/application/gemrb/gemrb/plugins/PROImporter/PROImporter.h +++ b/project/jni/application/gemrb/gemrb/plugins/PROImporter/PROImporter.h @@ -31,13 +31,12 @@ 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); diff --git a/project/jni/application/gemrb/gemrb/plugins/PSTOpcodes/PSTOpcodes.cpp b/project/jni/application/gemrb/gemrb/plugins/PSTOpcodes/PSTOpcodes.cpp index 477894e55..a11598eee 100644 --- a/project/jni/application/gemrb/gemrb/plugins/PSTOpcodes/PSTOpcodes.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/PSTOpcodes/PSTOpcodes.cpp @@ -24,7 +24,10 @@ #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" @@ -94,7 +97,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); if (!Owner) { return FX_NOT_APPLIED; @@ -125,7 +128,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\n", fx->Opcode, fx->Parameter2 ); if (fx->Parameter1) { if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) { BASE_STATE_SET (fx->Parameter2); @@ -149,7 +152,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\n", fx->Opcode, fx->Parameter2 ); if (!Owner) Owner = target; if (!Owner) @@ -226,7 +229,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\n", fx->Opcode, fx->Parameter2 ); if (!Owner) Owner = target; if (!Owner) @@ -332,7 +335,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\n", fx->Opcode, fx->Parameter2 ); if (Owner->Type!=ST_ACTOR) { return FX_NOT_APPLIED; } @@ -383,7 +386,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\n", 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 +397,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\n", fx->Opcode, fx->Parameter2 ); int fromTime = fx->DiceSides; int toTime = fx->DiceSides; switch(fx->Parameter2&6) { @@ -410,7 +413,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\n", 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 @@ -439,7 +442,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\n", fx->Opcode, fx->Parameter2 ); Map *area = Owner->GetCurrentArea(); if (!area) @@ -474,7 +477,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\n", fx->Opcode, fx->Parameter2 ); Map *map = core->GetGame()->GetCurrentArea(); if (map) { map->SetBackground(fx->Resource, fx->Duration); @@ -486,7 +489,7 @@ int fx_change_background (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx) //0xc9 fx_overlay int fx_overlay (Scriptable* /*Owner*/, Actor* target, Effect* fx) { - if (0) printf( "fx_overlay (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 ); + if (0) print( "fx_overlay (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 ); target->AddAnimation(fx->Resource,-1,0,true); //special effects based on fx_param2 return FX_NOT_APPLIED; @@ -499,7 +502,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\n", 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 @@ -522,7 +525,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\n", 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 @@ -545,7 +548,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\n", fx->Opcode, fx->Parameter1 ); int ea = target->GetStat(IE_EA); int type; if (ea>EA_EVILCUTOFF) type = 1; @@ -576,7 +579,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\n", fx->Opcode, fx->Parameter1 ); Map *map = core->GetGame()->GetCurrentArea(); if (map) { core->timer->SetMoveViewPort( fx->PosX, fx->PosY, fx->Parameter1, true); @@ -587,7 +590,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\n", fx->Opcode, fx->Parameter2 ); if (STATE_GET (STATE_EMBALM) ) //embalm is non cumulative return FX_NOT_APPLIED; STATE_SET( STATE_EMBALM ); @@ -610,7 +613,7 @@ int fx_embalm (Scriptable* /*Owner*/, Actor* target, Effect* fx) //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\n", fx->Opcode, fx->Parameter2 ); if (fx->Parameter2) { core->GetGame()->TimeStop(NULL, 0xffffffff); } else { @@ -625,7 +628,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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); switch (fx->Parameter2) { case 0: p1 = 3; p2 = 6; break; @@ -641,7 +644,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); return FX_NOT_APPLIED; } @@ -650,7 +653,7 @@ 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\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); ieDword type = fx->Parameter2; //default is alignment/evil/speed 30/range 10 if (!type) type = 0x08031e0a; @@ -677,7 +680,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)\n", fx->Opcode ); if (STATE_GET( STATE_DEAD) ) { return FX_NOT_APPLIED; @@ -709,7 +712,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)\n", fx->Opcode ); if (!STATE_GET( STATE_DEAD) ) { return FX_NOT_APPLIED; } diff --git a/project/jni/application/gemrb/gemrb/plugins/SAVImporter/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/SAVImporter/CMakeLists.txt new file mode 100644 index 000000000..e99bef02f --- /dev/null +++ b/project/jni/application/gemrb/gemrb/plugins/SAVImporter/CMakeLists.txt @@ -0,0 +1 @@ +ADD_GEMRB_PLUGIN (SAVImporter SAVImporter.cpp) diff --git a/project/jni/application/gemrb/gemrb/plugins/SAVImporter/Makefile.am b/project/jni/application/gemrb/gemrb/plugins/SAVImporter/Makefile.am new file mode 100644 index 000000000..825d8d923 --- /dev/null +++ b/project/jni/application/gemrb/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/project/jni/application/gemrb/gemrb/plugins/SAVImporter/SAVImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/SAVImporter/SAVImporter.cpp new file mode 100644 index 000000000..2c53d81b3 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/plugins/SAVImporter/SAVImporter.cpp @@ -0,0 +1,122 @@ +/* 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" + +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) { + printMessage("SAVImporter", "Corrupt Save Detected\n", RED); + return GEM_ERROR; + } + char* fname = ( char* ) malloc( fnlen ); + compressed->Read( fname, fnlen ); + strlwr(fname); + compressed->ReadDword( &declen ); + compressed->ReadDword( &complen ); + print( "Decompressing %s\n", 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 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/project/jni/application/gemrb/gemrb/plugins/SAVImporter/SAVImporter.h b/project/jni/application/gemrb/gemrb/plugins/SAVImporter/SAVImporter.h new file mode 100644 index 000000000..9f9404c29 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/plugins/SAVImporter/SAVImporter.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 SAVIMPORTER_H +#define SAVIMPORTER_H + +#include "ArchiveImporter.h" + +#include "globals.h" + +#include "System/DataStream.h" + +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/project/jni/application/gemrb/gemrb/plugins/SDLAudio/SDLAudio.cpp b/project/jni/application/gemrb/gemrb/plugins/SDLAudio/SDLAudio.cpp index d3075529b..43e79f165 100644 --- a/project/jni/application/gemrb/gemrb/plugins/SDLAudio/SDLAudio.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/SDLAudio/SDLAudio.cpp @@ -138,7 +138,7 @@ Holder SDLAudio::Play(const char* ResRef, int XPos, int YPos, unsig // TODO: move this loading code somewhere central ResourceHolder acm(ResRef); if (!acm) { - printf("failed acm load\n"); + print("failed acm load\n"); return Holder(); } int cnt = acm->get_length(); @@ -170,7 +170,7 @@ Holder 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\n"); return Holder(); } @@ -183,7 +183,7 @@ Holder 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\n"); return Holder(); } @@ -197,7 +197,7 @@ Holder SDLAudio::Play(const char* ResRef, int XPos, int YPos, unsig int SDLAudio::CreateStream(Holder newMusic) { - printf("SDLAudio setting new music\n"); + print("SDLAudio setting new music\n"); MusicReader = newMusic; // TODO @@ -295,7 +295,7 @@ int SDLAudio::SetupNewStream(ieWord x, ieWord y, ieWord z, (void)gain; (void)point; - printf("SDLAudio allocating stream\n"); + print("SDLAudio allocating stream\n"); // TODO: buggy MusicPlaying = false; @@ -316,7 +316,7 @@ bool SDLAudio::ReleaseStream(int stream, bool HardStop) return false; } - printf("SDLAudio releasing stream\n"); + print("SDLAudio releasing stream\n"); (void)HardStop; @@ -359,8 +359,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); + printMessage("SDLAudio", "Couldn't convert video stream!\ntrying to convert %d bits, %d channels, %d rate\n", RED, + bits, channels, samplerate); return; } cvt.buf = (Uint8*)malloc(size*cvt.len_mult); diff --git a/project/jni/application/gemrb/gemrb/plugins/SDLVideo/SDLVideo.cpp b/project/jni/application/gemrb/gemrb/plugins/SDLVideo/SDLVideo.cpp index be87bcfc3..21a9696d2 100644 --- a/project/jni/application/gemrb/gemrb/plugins/SDLVideo/SDLVideo.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/SDLVideo/SDLVideo.cpp @@ -28,8 +28,11 @@ #include "GameData.h" #include "Interface.h" #include "Palette.h" +#include "Polygon.h" #include "SpriteCover.h" #include "GUI/Console.h" +#include "GUI/EventMgr.h" +#include "GUI/Window.h" #include #include @@ -47,7 +50,7 @@ SDLVideoDriver::SDLVideoDriver(void) xCorr = 0; yCorr = 0; lastTime = 0; - GetTime( lastMouseTime ); + lastMouseTime = GetTickCount(); backBuf=NULL; extra=NULL; subtitlestrref = 0; @@ -73,12 +76,12 @@ SDLVideoDriver::~SDLVideoDriver(void) int SDLVideoDriver::Init(void) { - //printf("[SDLVideoDriver]: Init..."); + //print("[SDLVideoDriver]: Init..."); if (SDL_InitSubSystem( SDL_INIT_VIDEO ) == -1) { - //printf("[ERROR]\n"); + //print("[ERROR]\n"); return GEM_ERROR; } - //printf("[OK]\n"); + //print("[OK]\n"); SDL_EnableUNICODE( 1 ); SDL_EnableKeyRepeat( 500, 50 ); SDL_ShowCursor( SDL_DISABLE ); @@ -141,13 +144,10 @@ void SDLVideoDriver::SetDisplayTitle(char* title, char* icon) SDL_WM_SetCaption( title, icon ); } -bool SDLVideoDriver::ToggleFullscreenMode(int set_reset) +bool SDLVideoDriver::SetFullscreenMode(bool set) { - if (set_reset==-1) { - set_reset=!fullscreen; - } - if (fullscreen != set_reset) { - fullscreen=set_reset; + if (fullscreen != set) { + fullscreen=set; SDL_WM_ToggleFullScreen( disp ); //readjust mouse to original position MoveMouse(CursorPos.x, CursorPos.y); @@ -171,10 +171,10 @@ 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; @@ -214,7 +214,7 @@ int SDLVideoDriver::SwapBuffers(void) unsigned int delay = core->TooltipDelay; // The multiplication by 10 is there since the last, disabling slider position is the eleventh if (!ConsolePopped && (delay delay) { if (Evnt) @@ -266,7 +266,7 @@ int SDLVideoDriver::PollEvents() { break; case SDLK_f: if (modstate & GEM_MOD_CTRL) { - ToggleFullscreenMode(-1); + ToggleFullscreenMode(); } break; default: @@ -308,12 +308,16 @@ int SDLVideoDriver::PollEvents() { case SDLK_RIGHT: key = GEM_RIGHT; break; + case SDLK_DELETE: +#ifndef TARGET_OS_IPHONE + //iOS currently doesnt have a backspace so we use delete. + //This change should be future proof in the event they change delete + key = GEM_DELETE; + break; +#endif case SDLK_BACKSPACE: key = GEM_BACKSP; break; - case SDLK_DELETE: - key = GEM_DELETE; - break; case SDLK_RETURN: case SDLK_KP_ENTER: key = GEM_RETURN; @@ -816,7 +820,7 @@ void SDLVideoDriver::BlitSpriteRegion(const Sprite2D* spr, const Region& size, i } } -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 ); @@ -866,7 +870,7 @@ void SDLVideoDriver::BlitTile(const Sprite2D* spr, const Sprite2D* mask, int x, } 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 +886,58 @@ void SDLVideoDriver::BlitTile(const Sprite2D* spr, const Sprite2D* mask, int x, else \ BlitTile_internal(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 if (flags & TILE_SEPIA) { + + if (flags & TILE_HALFTRANS) { + TRBlender_HalfTrans B(backBuf->format); + + TRTinter_Sepia T(tintcol); + DO_BLIT + } else { + TRBlender_Opaque B(backBuf->format); + + TRTinter_Sepia T(tintcol); + DO_BLIT + } + } else { - TRBlender_Opaque B(backBuf->format); - if (tint) { - TRTinter_Tint T(tintcol); - DO_BLIT + if (flags & TILE_HALFTRANS) { + TRBlender_HalfTrans B(backBuf->format); + + if (tint) { + TRTinter_Tint T(tintcol); + DO_BLIT + } else { + TRTinter_NoTint T; + DO_BLIT + } } else { - TRTinter_NoTint T; - DO_BLIT + TRBlender_Opaque B(backBuf->format); + + if (tint) { + TRTinter_Tint T(tintcol); + DO_BLIT + } else { + TRTinter_NoTint T; + DO_BLIT + } } + } #undef DO_BLIT @@ -1309,7 +1344,7 @@ void SDLVideoDriver::BlitGameSprite(const Sprite2D* spr, int x, int y, // tinted // covered -// printf("Unoptimized blit: %04X\n", flags); +// print("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 @@ -1439,7 +1474,7 @@ void SDLVideoDriver::BlitGameSprite(const Sprite2D* spr, int x, int y, // transshadow (impossible with 32bpp) // palettealpha (always set) -// printf("Unoptimized blit: %04X\n", flags); +// print("Unoptimized blit: %04X\n", flags); #define SPECIALPIXEL int ia=0; if ((remflags & BLIT_HALFTRANS)) ia = 1; if (p == 1 && (remflags & BLIT_NOSHADOW)) { } else @@ -1555,8 +1590,8 @@ void SDLVideoDriver::SetDragCursor(Sprite2D* drag) Sprite2D* SDLVideoDriver::GetScreenshot( Region r ) { - int Width = r.w ? r.w : disp->w; - int Height = r.h ? r.h : disp->h; + unsigned int Width = r.w ? r.w : disp->w; + unsigned int Height = r.h ? r.h : disp->h; SDL_Rect src = {r.x, r.y, r.w, r.h}; @@ -1564,7 +1599,8 @@ Sprite2D* SDLVideoDriver::GetScreenshot( Region r ) 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 ); + for (unsigned int y = 0; y < Height; y++) + memcpy( (char*)pixels+(Width * y * 3), (char*)surf->pixels+(surf->pitch * y), Width * 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); @@ -1696,7 +1732,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\n", x, y, xCorr, yCorr, Viewport.x, Viewport.y, Viewport.w, Viewport.h); if (clipped) { x += xCorr; y += yCorr; @@ -2333,7 +2369,7 @@ void SDLVideoDriver::GetMousePos(int &x, int &y) void SDLVideoDriver::MouseMovement(int x, int y) { - GetTime( lastMouseTime ); + lastMouseTime = GetTickCount(); if (DisableMouse&MOUSE_DISABLED) return; CursorPos.x = x; // - mouseAdjustX[CursorIndex]; @@ -2414,8 +2450,7 @@ void SDLVideoDriver::showFrame(unsigned char* buf, unsigned int bufw, 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 ); + 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; @@ -2494,7 +2529,7 @@ int SDLVideoDriver::PollMovieEvents() case SDLK_q: return 1; case SDLK_f: - ToggleFullscreenMode(-1); + ToggleFullscreenMode(); break; default: break; diff --git a/project/jni/application/gemrb/gemrb/plugins/SDLVideo/SDLVideo.h b/project/jni/application/gemrb/gemrb/plugins/SDLVideo/SDLVideo.h index e24ad9f85..b67fa17d4 100644 --- a/project/jni/application/gemrb/gemrb/plugins/SDLVideo/SDLVideo.h +++ b/project/jni/application/gemrb/gemrb/plugins/SDLVideo/SDLVideo.h @@ -25,6 +25,7 @@ #include "win32def.h" +#include #include class SDLVideoDriver : public Video { @@ -55,7 +56,7 @@ public: 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); + bool SetFullscreenMode(bool set); int SwapBuffers(void); int PollEvents(); bool ToggleGrabInput(); @@ -82,7 +83,7 @@ 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, diff --git a/project/jni/application/gemrb/gemrb/plugins/SDLVideo/TileRenderer.inl b/project/jni/application/gemrb/gemrb/plugins/SDLVideo/TileRenderer.inl index 21825e091..86a8bccbd 100644 --- a/project/jni/application/gemrb/gemrb/plugins/SDLVideo/TileRenderer.inl +++ b/project/jni/application/gemrb/gemrb/plugins/SDLVideo/TileRenderer.inl @@ -20,17 +20,46 @@ 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 +106,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; diff --git a/project/jni/application/gemrb/gemrb/plugins/SPLImporter/SPLImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/SPLImporter/SPLImporter.cpp index c8c9bfe01..6f6505798 100644 --- a/project/jni/application/gemrb/gemrb/plugins/SPLImporter/SPLImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/SPLImporter/SPLImporter.cpp @@ -24,13 +24,14 @@ #include "EffectMgr.h" #include "Interface.h" +#include "PluginMgr.h" #include "TableMgr.h" //needed for autotable 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); @@ -40,7 +41,7 @@ void Initializer() AutoTable tm("cgtable"); if (!tm) { printStatus( "ERROR", LIGHT_RED ); - printf( "Cannot find cgtable.2da.\n"); + print( "Cannot find cgtable.2da.\n"); return; } cgcount = tm->GetRowCount(); @@ -50,14 +51,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 +80,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 +101,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\n" ); return false; } diff --git a/project/jni/application/gemrb/gemrb/plugins/SPLImporter/SPLImporter.h b/project/jni/application/gemrb/gemrb/plugins/SPLImporter/SPLImporter.h index 2b355bbc4..f4d0caa60 100644 --- a/project/jni/application/gemrb/gemrb/plugins/SPLImporter/SPLImporter.h +++ b/project/jni/application/gemrb/gemrb/plugins/SPLImporter/SPLImporter.h @@ -31,13 +31,12 @@ 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); diff --git a/project/jni/application/gemrb/gemrb/plugins/STOImporter/STOImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/STOImporter/STOImporter.cpp index 14dabd0b5..ae2fd76af 100644 --- a/project/jni/application/gemrb/gemrb/plugins/STOImporter/STOImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/STOImporter/STOImporter.cpp @@ -30,26 +30,20 @@ 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 +56,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\n" ); return false; } @@ -119,10 +113,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;sizeItemsCount;size++) { + STOItem *si = new STOItem(); + memset(si, 0, sizeof(STOItem) ); + s->items.push_back( si ); + } str->Seek( s->PurchasedCategoriesOffset, GEM_STREAM_START ); GetPurchasedCategories( s ); @@ -166,9 +170,12 @@ 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) { + it->MaxStackAmount = item->MaxStackAmount; + //another hack-fix if (!item->LoreToID) { it->Flags |= IE_INV_ITEM_IDENTIFIED; } @@ -221,7 +228,7 @@ 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; @@ -257,19 +264,16 @@ int STOImporter::GetStoredFileSize(Store *s) //items s->ItemsOffset = headersize; headersize += s->ItemsCount * itemsize; - - return headersize; } -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 +325,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;icItemsCount;ic++) { STOItem *it = store->items[ic]; @@ -344,20 +347,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;iCuresCount;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;iDrinksCount;i++) { STODrink *d = s->drinks+i; @@ -366,41 +367,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; + return false; } - ret = PutHeader( stream, store); - if (ret) { - return ret; - } + CalculateStoredFileSize(store); + PutHeader(stream, store); + PutDrinks(stream, store); + PutCures(stream, store); + PutPurchasedCategories(stream, store); + PutItems(stream, store); - ret = PutDrinks( stream, store); - if (ret) { - return ret; - } - - ret = PutCures( stream, store); - if (ret) { - return ret; - } - - ret = PutPurchasedCategories (stream, store); - if (ret) { - return ret; - } - - ret = PutItems( stream, store); - - return ret; + return true; } #include "plugindef.h" diff --git a/project/jni/application/gemrb/gemrb/plugins/STOImporter/STOImporter.h b/project/jni/application/gemrb/gemrb/plugins/STOImporter/STOImporter.h index c5c20250c..069813b4d 100644 --- a/project/jni/application/gemrb/gemrb/plugins/STOImporter/STOImporter.h +++ b/project/jni/application/gemrb/gemrb/plugins/STOImporter/STOImporter.h @@ -31,19 +31,18 @@ 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); @@ -51,11 +50,11 @@ private: 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); }; diff --git a/project/jni/application/gemrb/gemrb/plugins/TISImporter/TISImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/TISImporter/TISImporter.cpp index 3a5cb1934..dfda94201 100644 --- a/project/jni/application/gemrb/gemrb/plugins/TISImporter/TISImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/TISImporter/TISImporter.cpp @@ -24,37 +24,32 @@ #include "win32def.h" #include "Interface.h" +#include "Sprite2D.h" #include "Video.h" 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.\n" ); return false; } str->ReadDword( &TilesCount ); @@ -98,11 +93,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\n",index); + print("FileSize: %ld\n", str->Size() ); + print("Position: %ld\n", pos); + print("Shift: %d\n", headerShift);*/ + print("Corrupt WED file encountered; couldn't find any more tiles at tile %d\n", index); last_corrupt = this; } diff --git a/project/jni/application/gemrb/gemrb/plugins/TISImporter/TISImporter.h b/project/jni/application/gemrb/gemrb/plugins/TISImporter/TISImporter.h index 0c049d9d6..db6436f9d 100644 --- a/project/jni/application/gemrb/gemrb/plugins/TISImporter/TISImporter.h +++ b/project/jni/application/gemrb/gemrb/plugins/TISImporter/TISImporter.h @@ -26,13 +26,12 @@ 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); diff --git a/project/jni/application/gemrb/gemrb/plugins/TLKImporter/TLKImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/TLKImporter/TLKImporter.cpp index ed5732fee..4377bf067 100644 --- a/project/jni/application/gemrb/gemrb/plugins/TLKImporter/TLKImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/TLKImporter/TLKImporter.cpp @@ -27,7 +27,9 @@ #include "DialogHandler.h" #include "Game.h" #include "Interface.h" +#include "TableMgr.h" #include "GUI/GameControl.h" +#include "Scriptable/Actor.h" //set this to -1 if charname is gabber (iwd2) static int charname=0; @@ -53,7 +55,6 @@ TLKImporter::TLKImporter(void) } str = NULL; override = NULL; - autoFree = false; AutoTable tm("gender"); if (tm) { @@ -73,17 +74,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); @@ -110,16 +108,13 @@ void TLKImporter::OpenAux() } } -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) { @@ -146,7 +141,7 @@ inline char* mystrncpy(char* dest, const char* source, int maxlength, 0 - PROTAGONIST 1-9 - PLAYERx */ -inline Actor *GetActorFromSlot(int slot) +static inline Actor *GetActorFromSlot(int slot) { if (slot==-1) { GameControl *gc = core->GetGameControl(); diff --git a/project/jni/application/gemrb/gemrb/plugins/TLKImporter/TLKImporter.h b/project/jni/application/gemrb/gemrb/plugins/TLKImporter/TLKImporter.h index c2a03e01b..e90b72d05 100644 --- a/project/jni/application/gemrb/gemrb/plugins/TLKImporter/TLKImporter.h +++ b/project/jni/application/gemrb/gemrb/plugins/TLKImporter/TLKImporter.h @@ -28,7 +28,6 @@ class TLKImporter : public StringMgr { private: DataStream* str; - bool autoFree; //Data ieDword StrRefCount, Offset; @@ -41,7 +40,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 */ diff --git a/project/jni/application/gemrb/gemrb/plugins/TLKImporter/TlkOverride.cpp b/project/jni/application/gemrb/gemrb/plugins/TLKImporter/TlkOverride.cpp index 74a149840..4f05ca38c 100644 --- a/project/jni/application/gemrb/gemrb/plugins/TLKImporter/TlkOverride.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/TLKImporter/TlkOverride.cpp @@ -307,7 +307,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 +328,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/project/jni/application/gemrb/gemrb/plugins/WAVReader/WAVReader.cpp b/project/jni/application/gemrb/gemrb/plugins/WAVReader/WAVReader.cpp index 90c701014..4c564c51a 100644 --- a/project/jni/application/gemrb/gemrb/plugins/WAVReader/WAVReader.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/WAVReader/WAVReader.cpp @@ -189,5 +189,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/project/jni/application/gemrb/gemrb/plugins/WEDImporter/WEDImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/WEDImporter/WEDImporter.cpp index 802937dcc..f662ce717 100644 --- a/project/jni/application/gemrb/gemrb/plugins/WEDImporter/WEDImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/WEDImporter/WEDImporter.cpp @@ -32,6 +32,7 @@ #include "GameData.h" #include "Interface.h" +#include "PluginMgr.h" #include "TileSetMgr.h" struct wed_polygon { @@ -47,30 +48,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" ); + print( "[WEDImporter]: This file is not a valid WED File\n" ); return false; } str->ReadDword( &OverlaysCount ); @@ -214,7 +209,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"); + print("[WEDImporter]: Found broken door polygon header!\n"); } ieDword polycount = basecount/WED_POLYGON_SIZE+count-WallPolygonsCount; if (polycount>DoorPolygonsCount) { @@ -249,7 +244,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" ); + print( "[WEDImporter]: Found door without WED entry!\n" ); return NULL; } diff --git a/project/jni/application/gemrb/gemrb/plugins/WEDImporter/WEDImporter.h b/project/jni/application/gemrb/gemrb/plugins/WEDImporter/WEDImporter.h index f725b7841..3ddf3d1b0 100644 --- a/project/jni/application/gemrb/gemrb/plugins/WEDImporter/WEDImporter.h +++ b/project/jni/application/gemrb/gemrb/plugins/WEDImporter/WEDImporter.h @@ -36,7 +36,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 +51,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); diff --git a/project/jni/application/gemrb/gemrb/plugins/WMPImporter/WMPImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/WMPImporter/WMPImporter.cpp index 929c76b5a..012701243 100644 --- a/project/jni/application/gemrb/gemrb/plugins/WMPImporter/WMPImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/WMPImporter/WMPImporter.cpp @@ -30,41 +30,31 @@ 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); + printMessage("WMPImporter", "This file is not a valid WMP File\n-->%s<--\n", LIGHT_RED, + stream1->filename); return false; } str1->ReadDword( &WorldMapsCount1 ); @@ -77,8 +67,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); + printMessage("WMPImporter", "This file is not a valid WMP File\n-->%s<--\n", LIGHT_RED, + stream2->filename); return false; } str2->ReadDword( &WorldMapsCount2 ); @@ -177,6 +167,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 +192,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++) { diff --git a/project/jni/application/gemrb/gemrb/plugins/WMPImporter/WMPImporter.h b/project/jni/application/gemrb/gemrb/plugins/WMPImporter/WMPImporter.h index 9c8d51597..b346528c1 100644 --- a/project/jni/application/gemrb/gemrb/plugins/WMPImporter/WMPImporter.h +++ b/project/jni/application/gemrb/gemrb/plugins/WMPImporter/WMPImporter.h @@ -32,7 +32,6 @@ class WMPImporter : public WorldMapMgr { private: DataStream* str1; DataStream* str2; - bool autoFree; ieDword WorldMapsCount; ieDword WorldMapsCount1, WorldMapsCount2; @@ -41,7 +40,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); diff --git a/project/jni/application/gemrb/gemrb/plugins/ZLibManager/ZLibManager.cpp b/project/jni/application/gemrb/gemrb/plugins/ZLibManager/ZLibManager.cpp index 858ae716c..6d2286c81 100644 --- a/project/jni/application/gemrb/gemrb/plugins/ZLibManager/ZLibManager.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/ZLibManager/ZLibManager.cpp @@ -39,7 +39,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 +84,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/project/jni/application/gemrb/gemrb/plugins/ZLibManager/ZLibManager.h b/project/jni/application/gemrb/gemrb/plugins/ZLibManager/ZLibManager.h index 784494cae..0beced8a9 100644 --- a/project/jni/application/gemrb/gemrb/plugins/ZLibManager/ZLibManager.h +++ b/project/jni/application/gemrb/gemrb/plugins/ZLibManager/ZLibManager.h @@ -28,7 +28,7 @@ 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; };