diff --git a/project/jni/application/gemrb/AndroidAppSettings.cfg b/project/jni/application/gemrb/AndroidAppSettings.cfg index efda239cb..3889d0934 100644 --- a/project/jni/application/gemrb/AndroidAppSettings.cfg +++ b/project/jni/application/gemrb/AndroidAppSettings.cfg @@ -1,19 +1,20 @@ # The application settings for Android libSDL port -AppSettingVersion=16 +AppSettingVersion=17 LibSdlVersion=1.2 AppName="GemRB" AppFullName=net.sourceforge.gemrb ScreenOrientation=h InhibitSuspend=n -AppDataDownloadUrl="GemRB data(local)|data1.zip" +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" SdlVideoResize=y SdlVideoResizeKeepAspect=y NeedDepthBuffer=n +SwVideoMode=n AppUsesMouse=y AppNeedsTwoButtonMouse=y AppNeedsArrowKeys=n AppNeedsTextInput=y -AppUsesJoystick=y +AppUsesJoystick=n AppHandlesJoystickSensitivity=n AppUsesMultitouch=n NonBlockingSwapBuffers=n @@ -22,13 +23,12 @@ AppTouchscreenKeyboardKeysAmount=0 AppTouchscreenKeyboardKeysAmountAutoFire=0 RedefinedKeysScreenKb="LCTRL c p o e" MultiABI=y -AppVersionCode=0631 -AppVersionName="0.6.3.1" +AppVersionCode=0641 +AppVersionName="0.6.4.1" CompiledLibraries="sdl_mixer ogg vorbis openal png python" CustomBuildScript=n AppCflags='-fexceptions -finline-functions -O3 -DSTATIC_LINK=Yes -DHAVE_SNPRINTF -DTOUCHSCREEN' AppLdflags='' AppSubdirsBuild='' -AppUseCrystaXToolchain=y AppCmdline='GemRB' ReadmeText='^You may press "Home" now - the data will be downloaded in background' diff --git a/project/jni/application/gemrb/AndroidData/override2.zip b/project/jni/application/gemrb/AndroidData/override2.zip new file mode 100644 index 000000000..30e998be8 Binary files /dev/null and b/project/jni/application/gemrb/AndroidData/override2.zip differ diff --git a/project/jni/application/gemrb/AndroidData/scripts2.zip b/project/jni/application/gemrb/AndroidData/scripts2.zip new file mode 100644 index 000000000..eb6799f2b Binary files /dev/null and b/project/jni/application/gemrb/AndroidData/scripts2.zip differ diff --git a/project/jni/application/gemrb/gemrb/CMakeLists.txt b/project/jni/application/gemrb/gemrb/CMakeLists.txt index 199dd2108..0abc5d926 100644 --- a/project/jni/application/gemrb/gemrb/CMakeLists.txt +++ b/project/jni/application/gemrb/gemrb/CMakeLists.txt @@ -12,8 +12,14 @@ IF(WIN32) TARGET_LINK_LIBRARIES(gemrb gemrb_core) ELSE(WIN32) IF(APPLE) - TARGET_LINK_LIBRARIES(gemrb gemrb_core ${SDL_LIBRARY} - ${SDL_MAIN_LIBRARY_PATH} ${COCOA_LIBRARY_PATH} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) + if (STATIC_LINK) + TARGET_LINK_LIBRARIES(gemrb ${SDL_LIBRARY} + ${SDL_MAIN_LIBRARY_PATH} ${COCOA_LIBRARY_PATH} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT} + gemrb_core ${plugins} -Wl,-all_load) + else (STATIC_LINK) + TARGET_LINK_LIBRARIES(gemrb gemrb_core ${SDL_LIBRARY} + ${SDL_MAIN_LIBRARY_PATH} ${COCOA_LIBRARY_PATH} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) + endif (STATIC_LINK) ELSE(APPLE) if (STATIC_LINK) TARGET_LINK_LIBRARIES(gemrb ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT} diff --git a/project/jni/application/gemrb/gemrb/GemRB.cfg.noinstall.sample b/project/jni/application/gemrb/gemrb/GemRB.cfg.noinstall.sample index 1f2261507..fb76d5566 100644 --- a/project/jni/application/gemrb/gemrb/GemRB.cfg.noinstall.sample +++ b/project/jni/application/gemrb/gemrb/GemRB.cfg.noinstall.sample @@ -25,10 +25,12 @@ # Game Type [String] Use one of the following # # values: # # # +# auto Attempt to autodetect game type # +# # # bg1 Baldur's Gate # # bg2 Baldur's Gate 2 : SoA or ToB # # tob Baldur's Gate 2 : ToB (obsolete) # -# iwd IceWind Dale # +# iwd IceWind Dale (no How or ToTL installed)# # how IceWind Dale : HoW or ToTL # # iwd2 IceWind Dale 2 # # pst Planescape Torment # diff --git a/project/jni/application/gemrb/gemrb/GemRB.cfg.sample.in b/project/jni/application/gemrb/gemrb/GemRB.cfg.sample.in index 4b4dfbdac..7ebccd139 100644 --- a/project/jni/application/gemrb/gemrb/GemRB.cfg.sample.in +++ b/project/jni/application/gemrb/gemrb/GemRB.cfg.sample.in @@ -25,10 +25,12 @@ # Game Type [String] Use one of the following # # values: # # # +# auto Attempt to autodetect game type # +# # # bg1 Baldur's Gate # # bg2 Baldur's Gate 2 : SoA or ToB # # tob Baldur's Gate 2 : ToB (obsolete) # -# iwd IceWind Dale # +# iwd IceWind Dale (no How or ToTL installed)# # how IceWind Dale : HoW or ToTL # # iwd2 IceWind Dale 2 # # pst Planescape Torment # diff --git a/project/jni/application/gemrb/gemrb/GemRB.cpp b/project/jni/application/gemrb/gemrb/GemRB.cpp index 9f8b08b75..dc688302e 100644 --- a/project/jni/application/gemrb/gemrb/GemRB.cpp +++ b/project/jni/application/gemrb/gemrb/GemRB.cpp @@ -35,17 +35,17 @@ #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 diff --git a/project/jni/application/gemrb/gemrb/core/Audio.h b/project/jni/application/gemrb/gemrb/core/Audio.h index af7e57766..4606f38f7 100644 --- a/project/jni/application/gemrb/gemrb/core/Audio.h +++ b/project/jni/application/gemrb/gemrb/core/Audio.h @@ -49,33 +49,33 @@ class GEM_EXPORT Audio : public Plugin { public: static const TypeID ID; public: - Audio(void); - virtual ~Audio(); - virtual bool Init(void) = 0; - virtual Holder Play(const char* ResRef, int XPos, int YPos, unsigned int flags = 0, unsigned int *length = 0) = 0; - virtual Holder Play(const char* ResRef, unsigned int *length = 0) { return Play(ResRef, 0, 0, GEM_SND_RELATIVE, length); } - virtual bool IsSpeaking() = 0; - virtual AmbientMgr* GetAmbientMgr() { return ambim; } - virtual void UpdateVolume(unsigned int flags = GEM_SND_VOL_MUSIC | GEM_SND_VOL_AMBIENTS) = 0; - virtual bool CanPlay() = 0; - virtual void ResetMusics() = 0; - virtual bool Play() = 0; - virtual bool Stop() = 0; - virtual bool Pause() = 0; - virtual bool Resume() = 0; - virtual int CreateStream(Holder) = 0; - virtual void UpdateListenerPos(int XPos, int YPos ) = 0; - virtual void GetListenerPos(int &XPos, int &YPos ) = 0; - virtual bool ReleaseStream(int stream, bool HardStop=false ) = 0; - virtual int SetupNewStream( ieWord x, ieWord y, ieWord z, - ieWord gain, bool point, bool Ambient) = 0; - virtual int QueueAmbient(int stream, const char* sound) = 0; - virtual void SetAmbientStreamVolume(int stream, int volume) = 0; - virtual void QueueBuffer(int stream, unsigned short bits, - int channels, short* memory, int size, int samplerate) = 0; + Audio(void); + virtual ~Audio(); + virtual bool Init(void) = 0; + virtual Holder Play(const char* ResRef, int XPos, int YPos, unsigned int flags = 0, unsigned int *length = 0) = 0; + virtual Holder Play(const char* ResRef, unsigned int *length = 0) { return Play(ResRef, 0, 0, GEM_SND_RELATIVE, length); } + virtual bool IsSpeaking() = 0; + virtual AmbientMgr* GetAmbientMgr() { return ambim; } + virtual void UpdateVolume(unsigned int flags = GEM_SND_VOL_MUSIC | GEM_SND_VOL_AMBIENTS) = 0; + virtual bool CanPlay() = 0; + virtual void ResetMusics() = 0; + virtual bool Play() = 0; + virtual bool Stop() = 0; + virtual bool Pause() = 0; + virtual bool Resume() = 0; + virtual int CreateStream(Holder) = 0; + virtual void UpdateListenerPos(int XPos, int YPos ) = 0; + virtual void GetListenerPos(int &XPos, int &YPos ) = 0; + virtual bool ReleaseStream(int stream, bool HardStop=false ) = 0; + virtual int SetupNewStream( ieWord x, ieWord y, ieWord z, + ieWord gain, bool point, bool Ambient) = 0; + virtual int QueueAmbient(int stream, const char* sound) = 0; + virtual void SetAmbientStreamVolume(int stream, int volume) = 0; + virtual void QueueBuffer(int stream, unsigned short bits, + int channels, short* memory, int size, int samplerate) = 0; protected: - AmbientMgr* ambim; + AmbientMgr* ambim; }; diff --git a/project/jni/application/gemrb/gemrb/core/CMakeLists.txt b/project/jni/application/gemrb/gemrb/core/CMakeLists.txt index aafa67645..767e0332f 100644 --- a/project/jni/application/gemrb/gemrb/core/CMakeLists.txt +++ b/project/jni/application/gemrb/gemrb/core/CMakeLists.txt @@ -22,7 +22,10 @@ FILE(GLOB gemrb_core_LIB_SRCS "*.cpp" GUI/Window.cpp GUI/WorldMapControl.cpp Scriptable/Actor.cpp - Scriptable/ActorBlock.cpp + Scriptable/Container.cpp + Scriptable/Door.cpp + Scriptable/InfoPoint.cpp + Scriptable/Scriptable.cpp Scriptable/PCStatStruct.cpp System/CachedFileStream.cpp System/DataStream.cpp diff --git a/project/jni/application/gemrb/gemrb/core/CharAnimations.cpp b/project/jni/application/gemrb/gemrb/core/CharAnimations.cpp index 7104db16f..66dc4b1eb 100644 --- a/project/jni/application/gemrb/gemrb/core/CharAnimations.cpp +++ b/project/jni/application/gemrb/gemrb/core/CharAnimations.cpp @@ -273,6 +273,28 @@ void CharAnimations::SetColors(const ieDword *arg) SetupColors(PAL_HELMET); } +void CharAnimations::CheckColorMod() +{ + if (!GlobalColorMod.locked) { + if (GlobalColorMod.type != RGBModifier::NONE) { + GlobalColorMod.type = RGBModifier::NONE; + GlobalColorMod.speed = 0; + change[0]=change[1]=change[2]=change[3]=true; + } + } + unsigned int location; + + for (location = 0; location < 32; ++location) { + if (!ColorMods[location].phase) { + if (ColorMods[location].type != RGBModifier::NONE) { + ColorMods[location].type = RGBModifier::NONE; + ColorMods[location].speed = 0; + change[location>>3]=true; + } + } + } +} + void CharAnimations::SetupColors(PaletteType type) { Palette* pal = palette[(int)type]; @@ -307,11 +329,16 @@ void CharAnimations::SetupColors(PaletteType type) if (GlobalColorMod.type != RGBModifier::NONE) { needmod = true; } + //don't drop the palette, it disables rgb pulse effects + //also don't bail out, we need to free the modified palette later + //so this entire block is needless + /* if ((colorcount == 0) && (needmod==false) ) { - gamedata->FreePalette(palette[PAL_MAIN], PaletteResRef); + gamedata->FreePalette(palette[PAL_MAIN], PaletteResRef); PaletteResRef[0]=0; return; } + */ for (int i = 0; i < colorcount; i++) { core->GetPalette( Colors[i]&255, size, &palette[PAL_MAIN]->col[dest] ); @@ -529,6 +556,7 @@ CharAnimations::CharAnimations(unsigned int AnimID, ieDword ArmourLevel) Colors = NULL; int i,j; for (i = 0; i < 4; ++i) { + change[i] = true; modifiedPalette[i] = NULL; palette[i] = NULL; } @@ -2328,7 +2356,7 @@ void CharAnimations::PulseRGBModifiers() if (time - lastModUpdate > 400) lastModUpdate = time - 40; int inc = (time - lastModUpdate)/40; - bool change[4] = { false, false, false, false }; + if (GlobalColorMod.type != RGBModifier::NONE && GlobalColorMod.speed > 0) { @@ -2359,10 +2387,22 @@ void CharAnimations::PulseRGBModifiers() } } - if (change[0]) SetupColors(PAL_MAIN); - if (change[1]) SetupColors(PAL_WEAPON); - if (change[2]) SetupColors(PAL_OFFHAND); - if (change[3]) SetupColors(PAL_HELMET); + if (change[0]) { + change[0]=0; + SetupColors(PAL_MAIN); + } + if (change[1]) { + change[1]=0; + SetupColors(PAL_WEAPON); + } + if (change[2]) { + change[2]=0; + SetupColors(PAL_OFFHAND); + } + if (change[3]) { + change[3]=0; + SetupColors(PAL_HELMET); + } lastModUpdate += inc*40; } diff --git a/project/jni/application/gemrb/gemrb/core/CharAnimations.h b/project/jni/application/gemrb/gemrb/core/CharAnimations.h index c963663a9..ea3331073 100644 --- a/project/jni/application/gemrb/gemrb/core/CharAnimations.h +++ b/project/jni/application/gemrb/gemrb/core/CharAnimations.h @@ -138,6 +138,7 @@ public: unsigned long lastModUpdate; RGBModifier GlobalColorMod; // global color modification effect + bool change[4]; Palette* palette[4]; Palette* modifiedPalette[4]; unsigned int AvatarsRowNum; @@ -157,8 +158,9 @@ public: void SetHelmetRef(const char* ref); void SetWeaponRef(const char* ref); void SetOffhandRef(const char* ref); - void SetupColors(PaletteType type); void SetColors(const ieDword *Colors); + void CheckColorMod(); + void SetupColors(PaletteType type); void LockPalette(const ieDword *Colors); // returns an array of animations of size GetTotalPartCount() diff --git a/project/jni/application/gemrb/gemrb/core/Core.cpp b/project/jni/application/gemrb/gemrb/core/Core.cpp index f0c075366..5fd0b66e6 100644 --- a/project/jni/application/gemrb/gemrb/core/Core.cpp +++ b/project/jni/application/gemrb/gemrb/core/Core.cpp @@ -76,12 +76,12 @@ void strnuprcpy(char* dest, const char *source, int count) *dest=0; } -// this one also filters spaces +// 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_lowercase[(ieByte) *source]; + char c = pl_uppercase[(ieByte) *source]; if (c!=' ') { *dest++=c; } diff --git a/project/jni/application/gemrb/gemrb/core/Dialog.h b/project/jni/application/gemrb/gemrb/core/Dialog.h index 4dc473b6a..2b7e921c3 100644 --- a/project/jni/application/gemrb/gemrb/core/Dialog.h +++ b/project/jni/application/gemrb/gemrb/core/Dialog.h @@ -24,8 +24,6 @@ #include "exports.h" #include "globals.h" -#include "GameScript/GameScript.h" - #include #define IE_DLG_TR_TEXT 0x01 @@ -37,6 +35,9 @@ #define IE_DLG_SOLVED 0x100 #define IE_DLG_QUEST_GROUP 0x4000 // this is a GemRB extension +class Condition; +class Action; + struct DialogTransition { ieDword Flags; ieStrRef textStrRef; diff --git a/project/jni/application/gemrb/gemrb/core/DialogHandler.cpp b/project/jni/application/gemrb/gemrb/core/DialogHandler.cpp index 5653a8096..0be1070b5 100644 --- a/project/jni/application/gemrb/gemrb/core/DialogHandler.cpp +++ b/project/jni/application/gemrb/gemrb/core/DialogHandler.cpp @@ -25,7 +25,9 @@ #include "DisplayMessage.h" #include "Game.h" #include "GameData.h" +#include "ScriptEngine.h" #include "Video.h" +#include "GameScript/GameScript.h" #include "GUI/GameControl.h" //translate section values (journal, solved, unsolved, user) @@ -89,8 +91,13 @@ int DialogHandler::InitDialog(Scriptable* spk, Scriptable* tgt, const char* dlgr } if (oldTarget) oldTarget->SetCircleSize(); + GameControl *gc = core->GetGameControl(); + + if (!gc) + return -1; + //check if we are already in dialog - if (core->GetGameControl()->GetDialogueFlags()&DF_IN_DIALOG) { + if (gc->GetDialogueFlags()&DF_IN_DIALOG) { return 0; } @@ -100,11 +107,12 @@ int DialogHandler::InitDialog(Scriptable* spk, Scriptable* tgt, const char* dlgr } //we need GUI for dialogs - core->GetGameControl()->UnhideGUI(); + //but the guiscript must be in control here + //gc->UnhideGUI(); //no exploring while in dialogue - core->GetGameControl()->SetScreenFlags(SF_GUIENABLED|SF_DISABLEMOUSE|SF_LOCKSCROLL, BM_OR); - core->GetGameControl()->SetDialogueFlags(DF_IN_DIALOG, BM_OR); + gc->SetScreenFlags(/*SF_GUIENABLED|*/SF_DISABLEMOUSE|SF_LOCKSCROLL, BM_OR); + gc->SetDialogueFlags(DF_IN_DIALOG, BM_OR); if (tgt->Type==ST_ACTOR) { Actor *tar = (Actor *) tgt; @@ -119,12 +127,13 @@ int DialogHandler::InitDialog(Scriptable* spk, Scriptable* tgt, const char* dlgr video->MoveViewportTo( tgt->Pos.x-vp.w/2, tgt->Pos.y-vp.h/2 ); //there are 3 bits, if they are all unset, the dialog freezes scripts if (!(dlg->Flags&7) ) { - core->GetGameControl()->SetDialogueFlags(DF_FREEZE_SCRIPTS, BM_OR); + gc->SetDialogueFlags(DF_FREEZE_SCRIPTS, BM_OR); } //opening control size to maximum, enabling dialog window - core->GetGame()->SetControlStatus(CS_HIDEGUI, BM_NAND); - core->GetGame()->SetControlStatus(CS_DIALOG, BM_OR); - core->SetEventFlag(EF_PORTRAIT); + //but the guiscript must be in control here + //core->GetGame()->SetControlStatus(CS_HIDEGUI, BM_NAND); + //core->GetGame()->SetControlStatus(CS_DIALOG, BM_OR); + //core->SetEventFlag(EF_PORTRAIT); return 0; } @@ -157,6 +166,8 @@ void DialogHandler::EndDialog(bool try_to_break) delete dlg; dlg = NULL; } + // FIXME: it's not so nice having this here, but things call EndDialog directly :( + core->GetGUIScriptEngine()->RunFunction( "GUIWORLD", "DialogEnded" ); //restoring original size core->GetGame()->SetControlStatus(CS_DIALOG, BM_NAND); core->GetGameControl()->SetScreenFlags(SF_DISABLEMOUSE|SF_LOCKSCROLL, BM_NAND); @@ -264,10 +275,15 @@ void DialogHandler::DialogChoose(unsigned int choose) if (target->Type == ST_ACTOR) ((Movable *)target)->ClearPath(); // fuzzie added this target->ClearActions(); + // do not interrupt during dialog actions (needed for aerie.d polymorph block) + char buf[20]; + strcpy(buf, "SetInterrupt(FALSE)"); + target->AddAction( GenerateAction( buf ) ); for (unsigned int i = 0; i < tr->actions.size(); i++) { target->AddAction(tr->actions[i]); - //GameScript::ExecuteAction( target, action ); } + strcpy(buf, "SetInterrupt(TRUE)"); + target->AddAction( GenerateAction( buf ) ); } int final_dialog = tr->Flags & IE_DLG_TR_FINAL; @@ -277,11 +293,6 @@ void DialogHandler::DialogChoose(unsigned int choose) EndDialog(); } - // *** the commented-out line here should no longer be required, with instant handling *** - // all dialog actions must be executed immediately - //target->ProcessActions(true); - // (do not clear actions - final actions can involve waiting/moving) - if (final_dialog) { return; } @@ -457,11 +468,11 @@ Scriptable *DialogHandler::GetTarget() if (actor) return actor; Door *door = area->GetDoorByGlobalID(targetID); - if (door) return door; + if (door) return (Scriptable *)door; Container *container = area->GetContainerByGlobalID(targetID); - if (container) return container; + if (container) return (Scriptable *)container; InfoPoint *ip = area->GetInfoPointByGlobalID(targetID); - if (ip) return ip; + if (ip) return (Scriptable *)ip; return NULL; } diff --git a/project/jni/application/gemrb/gemrb/core/DisplayMessage.cpp b/project/jni/application/gemrb/gemrb/core/DisplayMessage.cpp index 941391d52..ceecd6bb9 100644 --- a/project/jni/application/gemrb/gemrb/core/DisplayMessage.cpp +++ b/project/jni/application/gemrb/gemrb/core/DisplayMessage.cpp @@ -97,7 +97,7 @@ unsigned int DisplayMessage::GetSpeakerColor(const char *&name, const Scriptable speaker_color = (ActorColor[4].r<<16) | (ActorColor[4].g<<8) | ActorColor[4].b; break; case ST_TRIGGER: case ST_PROXIMITY: case ST_TRAVEL: - name = core->GetString( ((InfoPoint *) speaker)->DialogName ); + name = core->GetString( speaker->DialogName ); speaker_color = 0xc0c0c0; break; default: diff --git a/project/jni/application/gemrb/gemrb/core/EffectQueue.cpp b/project/jni/application/gemrb/gemrb/core/EffectQueue.cpp index b34f6dd52..ca980d686 100644 --- a/project/jni/application/gemrb/gemrb/core/EffectQueue.cpp +++ b/project/jni/application/gemrb/gemrb/core/EffectQueue.cpp @@ -35,10 +35,11 @@ static struct { const char* Name; EffectFunction Function; int Strref; + int Flags; } Opcodes[MAX_EFFECTS]; static int initialized = 0; -static EffectRef *effectnames = NULL; +static EffectDesc *effectnames = NULL; static int effectnames_count = 0; static int pstflags = false; @@ -54,6 +55,13 @@ bool EffectQueue::match_ids(Actor *target, int table, ieDword value) case 2: //EA stat = IE_EA; break; case 3: //GENERAL + //this is a hack to support dead only projectiles in PST + //if it interferes with something feel free to remove + if (value==GEN_DEAD) { + if (target->GetStat(IE_STATE_ID)&STATE_DEAD) { + return true; + } + } stat = IE_GENERAL; break; case 4: //RACE stat = IE_RACE; break; @@ -165,49 +173,25 @@ int find_effect(const void *a, const void *b) return stricmp((const char *) a,((const EffectRef *) b)->Name); } -static EffectRef* FindEffect(const char* effectname) +static EffectDesc* FindEffect(const char* effectname) { if( !effectname || !effectnames) { return NULL; } - void *tmp = bsearch(effectname, effectnames, effectnames_count, sizeof(EffectRef), find_effect); + void *tmp = bsearch(effectname, effectnames, effectnames_count, sizeof(EffectDesc), find_effect); if( !tmp) { printMessage( "EffectQueue", "", YELLOW); printf("Couldn't assign effect: %s\n", effectname ); } - return (EffectRef *) tmp; + return (EffectDesc *) tmp; } -static EffectRef fx_protection_from_display_string_ref={"Protection:String",NULL,-1}; - -//special effects without level check (but with damage dices precalculated) -static EffectRef diced_effects[] = { - //core effects - {"Damage",NULL,-1}, - {"CurrentHPModifier",NULL,-1}, - {"MaximumHPModifier",NULL,-1}, - //iwd effects - {"BurningBlood",NULL,-1}, //iwd - {"ColdDamage",NULL,-1}, - {"CrushingDamage",NULL,-1}, - {"VampiricTouch",NULL,-1}, - {"VitriolicSphere",NULL,-1}, - //pst effects - {"TransferHP",NULL,-1}, -{NULL,NULL,0} }; - -//special effects without level check (but with damage dices not precalculated) -static EffectRef diced_effects2[] = { - {"BurningBlood2",NULL,-1}, //how/iwd2 - {"StaticCharge",NULL,-1}, //how/iwd2 - {"SoulEater",NULL,-1}, //how/iwd2 - {"LichTouch",NULL,-1}, //how -{NULL,NULL,0} }; +static EffectRef fx_protection_from_display_string_ref = { "Protection:String", -1 }; inline static void ResolveEffectRef(EffectRef &effect_reference) { if( effect_reference.opcode==-1) { - EffectRef* ref = FindEffect(effect_reference.Name); + EffectDesc* ref = FindEffect(effect_reference.Name); if( ref && ref->opcode>=0) { effect_reference.opcode = ref->opcode; return; @@ -258,10 +242,11 @@ bool Init_EffectQueue() } } - EffectRef* poi = FindEffect( effectname ); + EffectDesc* poi = FindEffect( effectname ); if( poi != NULL) { Opcodes[i].Function = poi->Function; Opcodes[i].Name = poi->Name; + Opcodes[i].Flags = poi->Flags; //reverse linking opcode number //using this unused field if( (poi->opcode!=-1) && effectname[0]!='*') { @@ -274,14 +259,6 @@ bool Init_EffectQueue() } core->DelSymbol( eT ); - //additional initialisations - for (i=0;diced_effects[i].Name;i++) { - ResolveEffectRef(diced_effects[i]); - } - for (i=0;diced_effects2[i].Name;i++) { - ResolveEffectRef(diced_effects2[i]); - } - return true; } @@ -294,21 +271,21 @@ void EffectQueue_ReleaseMemory() effectnames = NULL; } -void EffectQueue_RegisterOpcodes(int count, const EffectRef* opcodes) +void EffectQueue_RegisterOpcodes(int count, const EffectDesc* opcodes) { if( ! effectnames) { - effectnames = (EffectRef*) malloc( (count+1) * sizeof( EffectRef ) ); + effectnames = (EffectDesc*) malloc( (count+1) * sizeof( EffectDesc ) ); } else { - effectnames = (EffectRef*) realloc( effectnames, (effectnames_count + count + 1) * sizeof( EffectRef ) ); + effectnames = (EffectDesc*) realloc( effectnames, (effectnames_count + count + 1) * sizeof( EffectDesc ) ); } - memcpy( effectnames + effectnames_count, opcodes, count * sizeof( EffectRef )); + memcpy( effectnames + effectnames_count, opcodes, count * sizeof( EffectDesc )); effectnames_count += count; effectnames[effectnames_count].Name = NULL; //if we merge two effect lists, then we need to sort their effect tables //actually, we might always want to sort this list, so there is no //need to do it manually (sorted table is needed if we use bsearch) - qsort(effectnames, effectnames_count, sizeof(EffectRef), compare_effects); + qsort(effectnames, effectnames_count, sizeof(EffectDesc), compare_effects); } EffectQueue::EffectQueue() @@ -424,7 +401,7 @@ Effect *EffectQueue::CreateEffectCopy(Effect *oldfx, EffectRef &effect_reference return CreateEffectCopy(oldfx, effect_reference.opcode, param1, param2); } -static EffectRef fx_unsummon_creature_ref={"UnsummonCreature",NULL,-1}; +static EffectRef fx_unsummon_creature_ref = { "UnsummonCreature", -1 }; Effect *EffectQueue::CreateUnsummonEffect(Effect *fx) { @@ -512,7 +489,7 @@ int EffectQueue::AddEffect(Effect* fx, Scriptable* self, Actor* pretarget, const switch (fx->Target) { case FX_TARGET_ORIGINAL: fx->SetPosition(self->Pos); - + flg = ApplyEffect( st, fx, 1 ); if( fx->TimingMode != FX_DURATION_JUST_EXPIRED) { if( st) { @@ -611,9 +588,9 @@ int EffectQueue::AddEffect(Effect* fx, Scriptable* self, Actor* pretarget, const case FX_TARGET_PARTY: all_party: game = core->GetGame(); - i = game->GetPartySize(true); + i = game->GetPartySize(false); while(i--) { - Actor* actor = game->GetPC( i, true ); + Actor* actor = game->GetPC( i, false ); fx->SetPosition(actor->Pos); flg = ApplyEffect( actor, fx, 1 ); @@ -703,39 +680,17 @@ int EffectQueue::AddAllEffects(Actor* target, const Point &destination) const return res; } -//check if an effect has no level based resistance, but instead the dice sizes/count -//adjusts Parameter1 (like a damage causing effect) -inline static bool IsDicedEffect(int opcode) -{ - int i; - - for(i=0;diced_effects[i].Name;i++) { - if( diced_effects[i].opcode==opcode) { - return true; - } - } - return false; -} - -//there is no level based resistance, but Parameter1 cannot be precalculated -//these effects use the Dice fields in a special way -inline static bool IsDicedEffect2(int opcode) -{ - int i; - - for(i=0;diced_effects2[i].Name;i++) { - if( diced_effects2[i].opcode==opcode) { - return true; - } - } - return false; -} - //resisted effect based on level inline bool check_level(Actor *target, Effect *fx) { //skip non level based effects - if( IsDicedEffect((int) fx->Opcode)) { + //check if an effect has no level based resistance, but instead the dice sizes/count + //adjusts Parameter1 (like a damage causing effect) + if( Opcodes[fx->Opcode].Flags & EFFECT_DICED ) { + //add the caster level to the dice count + if (fx->IsVariable) { + fx->DiceThrown+=fx->CasterLevel; + } fx->Parameter1 = DICE_ROLL((signed)fx->Parameter1); //this is a hack for PST style diced effects if( core->HasFeature(GF_SAVE_FOR_HALF) ) { @@ -749,7 +704,9 @@ inline bool check_level(Actor *target, Effect *fx) } return false; } - if( IsDicedEffect2((int) fx->Opcode)) { + //there is no level based resistance, but Parameter1 cannot be precalculated + //these effects use the Dice fields in a special way + if( Opcodes[fx->Opcode].Flags & EFFECT_NO_LEVEL_CHECK ) { return false; } @@ -770,7 +727,7 @@ inline bool check_level(Actor *target, Effect *fx) return false; } -//roll for the effect probability, there is a high and a low treshold, the d100 +//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) { @@ -784,36 +741,36 @@ inline bool check_probability(Effect* fx) } //immunity effects -static EffectRef fx_level_immunity_ref={"Protection:Spelllevel",NULL,-1}; -static EffectRef fx_opcode_immunity_ref={"Protection:Opcode",NULL,-1}; //bg2 -static EffectRef fx_opcode_immunity2_ref={"Protection:Opcode2",NULL,-1};//iwd -static EffectRef fx_spell_immunity_ref={"Protection:Spell",NULL,-1}; //bg2 -static EffectRef fx_spell_immunity2_ref={"Protection:Spell2",NULL,-1};//iwd -static EffectRef fx_store_spell_sequencer_ref={"Sequencer:Store",NULL,-1}; //bg2, works against sequencers -static EffectRef fx_school_immunity_ref={"Protection:School",NULL,-1}; -static EffectRef fx_secondary_type_immunity_ref={"Protection:SecondaryType",NULL,-1}; +static EffectRef fx_level_immunity_ref = { "Protection:Spelllevel", -1 }; +static EffectRef fx_opcode_immunity_ref = { "Protection:Opcode", -1 }; //bg2 +static EffectRef fx_opcode_immunity2_ref = { "Protection:Opcode2", -1 };//iwd +static EffectRef fx_spell_immunity_ref = { "Protection:Spell", -1 }; //bg2 +static EffectRef fx_spell_immunity2_ref = { "Protection:Spell2", -1 };//iwd +static EffectRef fx_store_spell_sequencer_ref = { "Sequencer:Store", -1 }; //bg2, works against sequencers +static EffectRef fx_school_immunity_ref = { "Protection:School", -1 }; +static EffectRef fx_secondary_type_immunity_ref = { "Protection:SecondaryType", -1 }; //decrementing immunity effects -static EffectRef fx_level_immunity_dec_ref={"Protection:SpellLevelDec",NULL,-1}; -static EffectRef fx_spell_immunity_dec_ref={"Protection:SpellDec",NULL,-1}; -static EffectRef fx_school_immunity_dec_ref={"Protection:SchoolDec",NULL,-1}; -static EffectRef fx_secondary_type_immunity_dec_ref={"Protection:SecondaryTypeDec",NULL,-1}; +static EffectRef fx_level_immunity_dec_ref = { "Protection:SpellLevelDec", -1 }; +static EffectRef fx_spell_immunity_dec_ref = { "Protection:SpellDec", -1 }; +static EffectRef fx_school_immunity_dec_ref = { "Protection:SchoolDec", -1 }; +static EffectRef fx_secondary_type_immunity_dec_ref = { "Protection:SecondaryTypeDec", -1 }; //bounce effects -static EffectRef fx_level_bounce_ref={"Bounce:SpellLevel",NULL,-1}; -//static EffectRef fx_opcode_bounce_ref={"Bounce:Opcode",NULL,-1}; -static EffectRef fx_spell_bounce_ref={"Bounce:Spell",NULL,-1}; -static EffectRef fx_school_bounce_ref={"Bounce:School",NULL,-1}; -static EffectRef fx_secondary_type_bounce_ref={"Bounce:SecondaryType",NULL,-1}; +static EffectRef fx_level_bounce_ref = { "Bounce:SpellLevel", -1 }; +//static EffectRef fx_opcode_bounce_ref = { "Bounce:Opcode", -1 }; +static EffectRef fx_spell_bounce_ref = { "Bounce:Spell", -1 }; +static EffectRef fx_school_bounce_ref = { "Bounce:School", -1 }; +static EffectRef fx_secondary_type_bounce_ref = { "Bounce:SecondaryType", -1 }; //decrementing bounce effects -static EffectRef fx_level_bounce_dec_ref={"Bounce:SpellLevelDec",NULL,-1}; -static EffectRef fx_spell_bounce_dec_ref={"Bounce:SpellDec",NULL,-1}; -static EffectRef fx_school_bounce_dec_ref={"Bounce:SchoolDec",NULL,-1}; -static EffectRef fx_secondary_type_bounce_dec_ref={"Bounce:SecondaryTypeDec",NULL,-1}; +static EffectRef fx_level_bounce_dec_ref = { "Bounce:SpellLevelDec", -1 }; +static EffectRef fx_spell_bounce_dec_ref = { "Bounce:SpellDec", -1 }; +static EffectRef fx_school_bounce_dec_ref = { "Bounce:SchoolDec", -1 }; +static EffectRef fx_secondary_type_bounce_dec_ref = { "Bounce:SecondaryTypeDec", -1 }; //spelltrap (multiple decrementing immunity) -static EffectRef fx_spelltrap={"SpellTrap", NULL,-1}; +static EffectRef fx_spelltrap = { "SpellTrap", -1 }; //this is for whole spell immunity/bounce inline static void DecreaseEffect(Effect *efx) @@ -1078,6 +1035,8 @@ int EffectQueue::ApplyEffect(Actor* target, Effect* fx, ieDword first_apply, ieD fx->FirstApply=first_apply; if( first_apply) { + if (Owner) + fx->CasterID = Owner->GetGlobalID(); if( (fx->PosX==0xffffffff) && (fx->PosY==0xffffffff)) { fx->PosX = target->Pos.x; fx->PosY = target->Pos.y; @@ -1158,6 +1117,10 @@ int EffectQueue::ApplyEffect(Actor* target, Effect* fx, ieDword first_apply, ieD 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); + return FX_NOT_APPLIED; + } } int res = FX_ABORT; if( fn) { @@ -1533,7 +1496,7 @@ int EffectQueue::SpecificDamageBonus(ieDword opcode, ieDword param2) const return bonus; } -static EffectRef fx_damage_bonus_modifier_ref={"DamageBonusModifier",NULL,-1}; +static EffectRef fx_damage_bonus_modifier_ref = { "DamageBonusModifier", -1 }; int EffectQueue::SpecificDamageBonus(ieDword damage_type) const { ResolveEffectRef(fx_damage_bonus_modifier_ref); @@ -1625,7 +1588,7 @@ bool EffectQueue::WeaponImmunity(ieDword opcode, int enchantment, ieDword weapon return false; } -static EffectRef fx_weapon_immunity_ref={"Protection:Weapons",NULL,-1}; +static EffectRef fx_weapon_immunity_ref = { "Protection:Weapons", -1 }; bool EffectQueue::WeaponImmunity(int enchantment, ieDword weapontype) const { @@ -1659,7 +1622,7 @@ void EffectQueue::AddWeaponEffects(EffectQueue *fxqueue, EffectRef &fx_ref) cons } /* no longer needed, use IE_CASTING stat -static EffectRef fx_disable_spellcasting_ref={ "DisableCasting", NULL, -1 }; +static EffectRef fx_disable_spellcasting_ref = { "DisableCasting", -1 }; int EffectQueue::DisabledSpellcasting(int types) const { ResolveEffectRef(fx_disable_spellcasting_ref); @@ -1800,7 +1763,7 @@ bool EffectQueue::HasDuration(Effect *fx) return false; } -static EffectRef fx_variable_ref={"Variable:StoreLocalVariable",NULL,-1}; +static EffectRef fx_variable_ref = { "Variable:StoreLocalVariable", -1 }; //returns true if the effect must be saved //variables are saved differently diff --git a/project/jni/application/gemrb/gemrb/core/EffectQueue.h b/project/jni/application/gemrb/gemrb/core/EffectQueue.h index 52c9b6e6c..1380c394a 100644 --- a/project/jni/application/gemrb/gemrb/core/EffectQueue.h +++ b/project/jni/application/gemrb/gemrb/core/EffectQueue.h @@ -100,6 +100,9 @@ class Scriptable; // You will need to get GameTime somehow to use this macro #define PrepareDuration(fx) fx->Duration = (fx->Duration*AI_UPDATE_TIME + GameTime) +//return the caster object +#define GetCasterObject() (core->GetGame()->GetActorByGlobalID(fx->CasterID)) + // often used stat modifications, usually Parameter2 types 0, 1 and 2 //these macros should work differently in permanent mode (modify base too) #define STAT_GET(stat) (target->Modified[ stat ]) @@ -135,19 +138,33 @@ class Scriptable; typedef int (* EffectFunction)(Scriptable*, Actor*, Effect*); -/** Links Effect name to a function implementing the effect */ +/** Cached Effect -> opcode mapping */ struct EffectRef { const char* Name; - EffectFunction Function; int opcode; }; +/** Links Effect name to a function implementing the effect */ +struct EffectDesc { + const char* Name; + EffectFunction Function; + int Flags; + int opcode; +}; + +enum EffectFlags { + EFFECT_NORMAL = 0, + EFFECT_DICED = 1, + EFFECT_NO_LEVEL_CHECK = 2, + EFFECT_NO_ACTOR = 4 +}; + /** Initializes table of available spell Effects used by all the queues. */ /** The available effects should already be registered by the effect plugins */ bool Init_EffectQueue(); /** Registers opcodes implemented by an effect plugin */ -void EffectQueue_RegisterOpcodes(int count, const EffectRef *opcodes); +void EffectQueue_RegisterOpcodes(int count, const EffectDesc *opcodes); /** release effect list when Interface is destroyed */ void EffectQueue_ReleaseMemory(); @@ -198,7 +215,7 @@ public: void RemoveAllEffectsWithResource(ieDword opcode, const ieResRef resource) const; /* removes any effects (delayed or not) which were using projectile */ - void RemoveAllEffectsWithProjectile(ieDword projectile) const; + void RemoveAllEffectsWithProjectile(ieDword projectile) const; /* removes equipping effects with specified inventory slot code */ void RemoveEquippingEffects(ieDwordSigned slotcode) const; diff --git a/project/jni/application/gemrb/gemrb/core/Font.cpp b/project/jni/application/gemrb/gemrb/core/Font.cpp index d62afecc4..72c7b888f 100644 --- a/project/jni/application/gemrb/gemrb/core/Font.cpp +++ b/project/jni/application/gemrb/gemrb/core/Font.cpp @@ -215,7 +215,7 @@ void Font::PrintFromLine(int startrow, Region rgn, const unsigned char* string, if (sscanf( tag, "color=%02X%02X%02X", &r, &g, &b ) != 3) continue; const Color c = {(unsigned char) r,(unsigned char)g, (unsigned char)b, 0}; - Palette* newPal = core->CreatePalette( c, black ); + Palette* newPal = core->CreatePalette( c, palette->back ); sprBuffer->SetPalette( newPal ); gamedata->FreePalette( newPal ); continue; @@ -390,7 +390,7 @@ void Font::Print(Region cliprgn, Region rgn, const unsigned char* string, if (sscanf( tag, "color=%02X%02X%02X", &r, &g, &b ) != 3) continue; const Color c = {(unsigned char) r,(unsigned char) g,(unsigned char) b, 0}; - Palette* newPal = core->CreatePalette( c, black ); + Palette* newPal = core->CreatePalette( c, palette->back ); sprBuffer->SetPalette( newPal ); gamedata->FreePalette( newPal ); continue; diff --git a/project/jni/application/gemrb/gemrb/core/GUI/Button.cpp b/project/jni/application/gemrb/gemrb/core/GUI/Button.cpp index 83930d2be..941cdd474 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/Button.cpp +++ b/project/jni/application/gemrb/gemrb/core/GUI/Button.cpp @@ -394,7 +394,7 @@ void Button::OnMouseDown(unsigned short x, unsigned short y, drag_start.x = Owner->XPos + XPos + x; drag_start.y = Owner->YPos + YPos + y; - if (State == IE_GUI_BUTTON_LOCKED) { + if (State == IE_GUI_BUTTON_LOCKED) { SetState( IE_GUI_BUTTON_LOCKED_PRESSED ); return; } diff --git a/project/jni/application/gemrb/gemrb/core/GUI/Console.cpp b/project/jni/application/gemrb/gemrb/core/GUI/Console.cpp index f9e60fa93..9cf4b950b 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/Console.cpp +++ b/project/jni/application/gemrb/gemrb/core/GUI/Console.cpp @@ -172,7 +172,7 @@ void Console::OnSpecialKeyPress(unsigned char Key) //ctrl-up void Console::HistoryBack() { - HistoryAdd(false); + HistoryAdd(false); if (HistPos < HistMax-1 && Buffer[0]) { HistPos++; } @@ -183,7 +183,7 @@ void Console::HistoryBack() //ctrl-down void Console::HistoryForward() { - HistoryAdd(false); + HistoryAdd(false); if (HistPos == 0) { Buffer[0]=0; CurPos=0; diff --git a/project/jni/application/gemrb/gemrb/core/GUI/GameControl.cpp b/project/jni/application/gemrb/gemrb/core/GUI/GameControl.cpp index 4382281ed..0794c0837 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/GameControl.cpp +++ b/project/jni/application/gemrb/gemrb/core/GUI/GameControl.cpp @@ -36,6 +36,9 @@ #include "Video.h" #include "damages.h" #include "GameScript/GSUtils.h" +#include "Scriptable/Container.h" +#include "Scriptable/Door.h" +#include "Scriptable/InfoPoint.h" #include @@ -44,10 +47,10 @@ #define DEBUG_SHOW_DOORS DEBUG_SHOW_CONTAINERS #define DEBUG_SHOW_LIGHTMAP 0x08 -#ifndef TOUCHSCREEN - #define SCROLL_BORDER 5 +#ifdef TOUCHSCREEN +# define SCROLL_BORDER 32 #else - #define SCROLL_BORDER 32 +# define SCROLL_BORDER 5 #endif static const Color cyan = { @@ -73,12 +76,9 @@ static const Color black = { static const Color blue = { 0x00, 0x00, 0xff, 0x80 }; - -#ifdef TOUCHSCREEN static const Color gray = { 0x80, 0x80, 0x80, 0xff }; -#endif //Animation* effect; @@ -134,11 +134,11 @@ GameControl::GameControl(void) scrolling = false; #ifdef TOUCHSCREEN touched=false; -#endif +#endif numScrollCursor = 0; DebugFlags = 0; AIUpdateCounter = 1; - EnableRunning = true; //make this a game flag if you wish + EnableRunning = true; //make this a game flag if you wish ieDword tmp=0; ResetTargetMode(); @@ -259,14 +259,14 @@ void GameControl::CreateMovement(Actor *actor, const Point &p) Action *action = NULL; if (DoubleClick && EnableRunning) { sprintf( Tmp, "RunToPoint([%d.%d])", p.x, p.y ); - action = GenerateAction( Tmp ); + action = GenerateAction( Tmp ); //if it didn't work don't insist if (!action) EnableRunning = false; } if (!action) { sprintf( Tmp, "MoveToPoint([%d.%d])", p.x, p.y ); - action = GenerateAction( Tmp ); + action = GenerateAction( Tmp ); } actor->AddAction( action ); @@ -499,7 +499,7 @@ void GameControl::Draw(unsigned short x, unsigned short y) Actor *actor = area->GetActorByGlobalID(trackerID); if (actor) { - Actor **monsters = area->GetAllActorsInRadius(actor->Pos, GA_NO_DEAD, distance); + Actor **monsters = area->GetAllActorsInRadius(actor->Pos, GA_NO_DEAD|GA_NO_LOS, distance); int i = 0; while(monsters[i]) { @@ -586,21 +586,21 @@ void GameControl::Draw(unsigned short x, unsigned short y) } } } - + #ifdef TOUCHSCREEN - if(moveY < 0 && scrolling) + 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) + 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) + 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) + 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); @@ -708,8 +708,8 @@ void GameControl::SelectActor(int whom, int type) } //Effect for the ctrl-r cheatkey (resurrect) -static EffectRef heal_ref={"CurrentHPModifier", NULL, -1}; -static EffectRef damage_ref={"Damage", NULL, -1}; +static EffectRef heal_ref = { "CurrentHPModifier", -1 }; +static EffectRef damage_ref = { "Damage", -1 }; /** Key Release Event */ void GameControl::OnKeyRelease(unsigned char Key, unsigned short Mod) @@ -793,9 +793,9 @@ void GameControl::OnKeyRelease(unsigned char Key, unsigned short Mod) if (target) { src->CastSpell( TestSpell, target, false ); if (src->LastTarget) { - src->CastSpellEnd(); + src->CastSpellEnd(0); } else { - src->CastSpellPointEnd(); + src->CastSpellPointEnd(0); } } } @@ -1111,7 +1111,7 @@ void GameControl::DisplayTooltip() { strindex = STR_INJURED2; } else if (hp > maxhp/3) { strindex = STR_INJURED3; - } else { + } else { strindex = STR_INJURED4; } strindex = displaymsg->GetStringReference(strindex); @@ -1229,7 +1229,7 @@ void GameControl::OnMouseOver(unsigned short x, unsigned short y) if (ScreenFlags & SF_DISABLEMOUSE) { return; } - + #ifdef TOUCHSCREEN int mousescrollspd = core->GetMouseScrollSpeed(); Region region; @@ -1240,20 +1240,17 @@ void GameControl::OnMouseOver(unsigned short x, unsigned short y) moveY = 0; // Top scroll area region=Region(XPos, YPos, Width, YPos+SCROLL_BORDER); - if(region.PointInside(x, y)) - { + if (region.PointInside(x, y)) { // Check for end of map area - if(viewport.y > 0) + if (viewport.y > 0) moveY = -mousescrollspd; } // Bottom scroll area region=Region(XPos, Height-SCROLL_BORDER, Width, Height); - if(region.PointInside(x, y)) - { + if (region.PointInside(x, y)) { // Check for end of map area map = core->GetGame()->GetCurrentArea(); - if(map != NULL) - { + if (map != NULL) { mapsize = map->TMap->GetMapSize(); if((viewport.y + viewport.h) < mapsize.y) moveY = mousescrollspd; @@ -1261,40 +1258,34 @@ void GameControl::OnMouseOver(unsigned short x, unsigned short y) } // Left scroll area region=Region(XPos, YPos, XPos+SCROLL_BORDER, Height); - if(region.PointInside(x, y)) - { + 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)) - { + if (region.PointInside(x, y)) { // Check for end of map area map = core->GetGame()->GetCurrentArea(); - if(map != NULL) - { + if (map != NULL) { mapsize = map->TMap->GetMapSize(); if((viewport.x + viewport.w) < mapsize.x) moveX = mousescrollspd; } } - if ((moveX != 0 || moveY != 0) && touched) - { + if ((moveX != 0 || moveY != 0) && touched) { scrolling = true; return; - } - else - { + } else { moveX = 0; moveY = 0; scrolling = false; Video* video = core->GetVideoDriver(); video->SetDragCursor(NULL); } - #endif + lastMouseX = x; lastMouseY = y; Point p( x,y ); @@ -1459,8 +1450,6 @@ end_function: } } -//#define SCROLL_BORDER 5 - /** Global Mouse Move Event */ void GameControl::OnGlobalMouseMove(unsigned short x, unsigned short y) { @@ -1471,6 +1460,7 @@ void GameControl::OnGlobalMouseMove(unsigned short x, unsigned short y) if (Owner->Visible!=WINDOW_VISIBLE) { return; } + #ifndef TOUCHSCREEN int mousescrollspd = core->GetMouseScrollSpeed(); @@ -1499,7 +1489,10 @@ void GameControl::OnGlobalMouseMove(unsigned short x, unsigned short y) Video* video = core->GetVideoDriver(); video->SetDragCursor(NULL); } -#endif +#else +(void)x; +(void)y; +#endif } void GameControl::UpdateScrolling() { @@ -1735,18 +1728,18 @@ void GameControl::HandleContainer(Container *container, Actor *actor) return; } + core->SetEventFlag(EF_RESETTARGET); + if (target_mode == TARGET_MODE_ATTACK) { actor->ClearPath(); actor->ClearActions(); snprintf(Tmp, sizeof(Tmp), "BashDoor(\"%s\")", container->GetScriptName()); actor->AddAction(GenerateAction(Tmp)); - ResetTargetMode(); return; } if ((target_mode == TARGET_MODE_PICK)) { TryToPick(actor, container); - ResetTargetMode(); return; } @@ -1773,18 +1766,18 @@ void GameControl::HandleDoor(Door *door, Actor *actor) return; } + core->SetEventFlag(EF_RESETTARGET); + if (target_mode == TARGET_MODE_ATTACK) { actor->ClearPath(); actor->ClearActions(); snprintf(Tmp, sizeof(Tmp), "BashDoor(\"%s\")", door->GetScriptName()); actor->AddAction(GenerateAction(Tmp)); - ResetTargetMode(); return; } if (target_mode == TARGET_MODE_PICK) { TryToPick(actor, door); - ResetTargetMode(); return; } @@ -1807,7 +1800,6 @@ bool GameControl::HandleActiveRegion(InfoPoint *trap, Actor * actor, Point &p) } if ((target_mode == TARGET_MODE_PICK)) { TryToDisarm(actor, trap); - ResetTargetMode(); return true; } @@ -1885,7 +1877,7 @@ void GameControl::OnMouseDown(unsigned short x, unsigned short y, unsigned short SelectionRect.h = 0; #ifdef TOUCHSCREEN touched=true; -#endif +#endif } } @@ -1912,25 +1904,21 @@ void GameControl::OnMouseUp(unsigned short x, unsigned short y, unsigned short B #ifdef TOUCHSCREEN touched=false; - if(scrolling) - { + if (scrolling) { moveX = 0; moveY = 0; scrolling=false; Video* video = core->GetVideoDriver(); video->SetDragCursor(NULL); - if (DrawSelectionRect) - { + if (DrawSelectionRect) { Actor** ab; unsigned int count = area->GetActorInRect( ab, SelectionRect,true ); - if (count != 0) - { + 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++) - { + for (i = 0; i < count; i++) { // FIXME: should call handler only once game->SelectActor( ab[i], true, SELECT_NORMAL ); } @@ -1960,7 +1948,7 @@ void GameControl::OnMouseUp(unsigned short x, unsigned short y, unsigned short B } //hidden actors are not selectable by clicking on them - Actor* actor = area->GetActor( p, GA_DEFAULT | GA_NO_DEAD | GA_NO_HIDDEN); + Actor* actor = area->GetActor( p, GA_DEFAULT /*| GA_NO_DEAD */| GA_NO_HIDDEN | target_types); if (Button == GEM_MB_MENU) { if (actor) { //from GSUtils @@ -2013,6 +2001,7 @@ void GameControl::OnMouseUp(unsigned short x, unsigned short y, unsigned short B } } else { if (HandleActiveRegion(overInfoPoint, pc, p)) { + core->SetEventFlag(EF_RESETTARGET); return; } } @@ -2205,8 +2194,12 @@ void GameControl::SetTargetMode(int mode) { } void GameControl::ResetTargetMode() { - SetTargetMode(TARGET_MODE_NONE); target_types = GA_NO_DEAD|GA_NO_HIDDEN; + SetTargetMode(TARGET_MODE_NONE); +} + +void GameControl::UpdateTargetMode() { + SetTargetMode(target_mode); } /** Special Key Press */ @@ -2635,7 +2628,7 @@ void GameControl::ChangeMap(Actor *pc, bool forced) { //swap in the area of the actor Game* game = core->GetGame(); - if (forced || (stricmp( pc->Area, game->CurrentArea) != 0) ) { + if (forced || (pc && stricmp( pc->Area, game->CurrentArea) != 0) ) { dialoghandler->EndDialog(); overInfoPoint = NULL; overContainer = NULL; diff --git a/project/jni/application/gemrb/gemrb/core/GUI/GameControl.h b/project/jni/application/gemrb/gemrb/core/GUI/GameControl.h index 8a4f845f2..0ff21d3e1 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/GameControl.h +++ b/project/jni/application/gemrb/gemrb/core/GUI/GameControl.h @@ -114,7 +114,7 @@ private: //int action; #ifdef TOUCHSCREEN bool touched; // true, if player touched screen (left button down and hold) -#endif +#endif public: Door* overDoor; Container* overContainer; @@ -216,6 +216,7 @@ public: void TryToDisarm(Actor *source, InfoPoint *tgt); void PerformActionOn(Actor *actor); void ResetTargetMode(); + void UpdateTargetMode(); // returns the default cursor fitting the targeting mode int GetDefaultCursor() const; diff --git a/project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.cpp b/project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.cpp index a0591b043..cca132fc9 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.cpp +++ b/project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.cpp @@ -67,6 +67,8 @@ WorldMapControl::WorldMapControl(const char *font, int direction) } // initialize label colors + // NOTE: it would be better to initialize these colors from + // some 2da file Color normal = { 0xf0, 0xf0, 0xf0, 0xff }; Color selected = { 0xf0, 0x80, 0x80, 0xff }; Color notvisited = { 0x80, 0x80, 0xf0, 0xff }; @@ -315,10 +317,10 @@ void WorldMapControl::OnMouseUp(unsigned short /*x*/, unsigned short /*y*/, if (Button != GEM_MB_ACTION) { return; } + MouseIsDown = false; if (lastCursor==IE_CURSOR_NORMAL) { RunEventHandler( WorldMapControlOnPress ); } - MouseIsDown = false; } /** Special Key Press */ @@ -377,19 +379,35 @@ bool WorldMapControl::SetEvent(int eventType, EventHandler handler) void WorldMapControl::SetColor(int which, Color color) { - Color black = { 0x00, 0x00, 0x00, 0x00 }; + Palette* pal; + // FIXME: clearly it can cause palettes to be re-created several times, + // because setting background color creates all palettes anew. switch (which) { - case IE_GUI_WMAP_COLOR_NORMAL: + case IE_GUI_WMAP_COLOR_BACKGROUND: + pal = core->CreatePalette( pal_normal->front, color ); gamedata->FreePalette( pal_normal ); - pal_normal = core->CreatePalette( color, black ); + pal_normal = pal; + pal = core->CreatePalette( pal_selected->front, color ); + gamedata->FreePalette( pal_selected ); + pal_selected = pal; + pal = core->CreatePalette( pal_notvisited->front, color ); + gamedata->FreePalette( pal_notvisited ); + pal_notvisited = pal; + break; + case IE_GUI_WMAP_COLOR_NORMAL: + pal = core->CreatePalette( color, pal_normal->back ); + gamedata->FreePalette( pal_normal ); + pal_normal = pal; break; case IE_GUI_WMAP_COLOR_SELECTED: + pal = core->CreatePalette( color, pal_selected->back ); gamedata->FreePalette( pal_selected ); - pal_selected = core->CreatePalette( color, black ); + pal_selected = pal; break; case IE_GUI_WMAP_COLOR_NOTVISITED: + pal = core->CreatePalette( color, pal_notvisited->back ); gamedata->FreePalette( pal_notvisited ); - pal_notvisited = core->CreatePalette( color, black ); + pal_notvisited = pal; break; default: break; diff --git a/project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.h b/project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.h index 36ee06007..c02cef7f5 100644 --- a/project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.h +++ b/project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.h @@ -40,9 +40,10 @@ class WorldMapControl; // !!! Keep these synchronized with GUIDefines.py !!! /** Which label color is set with SetColor() */ -#define IE_GUI_WMAP_COLOR_NORMAL 0 -#define IE_GUI_WMAP_COLOR_SELECTED 1 -#define IE_GUI_WMAP_COLOR_NOTVISITED 2 +#define IE_GUI_WMAP_COLOR_BACKGROUND 0 +#define IE_GUI_WMAP_COLOR_NORMAL 1 +#define IE_GUI_WMAP_COLOR_SELECTED 2 +#define IE_GUI_WMAP_COLOR_NOTVISITED 3 /** diff --git a/project/jni/application/gemrb/gemrb/core/Game.cpp b/project/jni/application/gemrb/gemrb/core/Game.cpp index a5f706c10..00009c481 100644 --- a/project/jni/application/gemrb/gemrb/core/Game.cpp +++ b/project/jni/application/gemrb/gemrb/core/Game.cpp @@ -635,6 +635,15 @@ Map *Game::GetMap(const char *areaname, bool change) area->ChangeMap(IsDay()); ChangeSong(false, true); Infravision(); + + //call area customization script for PST + //moved here because the current area is set here + ScriptEngine *sE = core->GetGUIScriptEngine(); + if (core->HasFeature(GF_AREA_OVERRIDE) && sE) { + //area ResRef is accessible by GemRB.GetGameString (STR_AREANAME) + sE->RunFunction("Maze", "CustomizeArea"); + } + return area; } return GetMap(index); @@ -738,6 +747,7 @@ int Game::LoadMap(const char* ResRef, bool loadscreen) unsigned int i; Map *newMap; PluginHolder mM(IE_ARE_CLASS_ID); + ScriptEngine *sE = core->GetGUIScriptEngine(); //this shouldn't happen if (!mM) { @@ -750,10 +760,10 @@ int Game::LoadMap(const char* ResRef, bool loadscreen) } bool hide = false; - if (loadscreen) { + if (loadscreen && sE) { hide = core->HideGCWindow(); - core->GetGUIScriptEngine()->RunFunction("LoadScreen", "StartLoadScreen"); - core->GetGUIScriptEngine()->RunFunction("LoadScreen", "SetLoadScreen"); + sE->RunFunction("LoadScreen", "StartLoadScreen"); + sE->RunFunction("LoadScreen", "SetLoadScreen"); } DataStream* ds = gamedata->GetResource( ResRef, IE_ARE_CLASS_ID ); if (!ds) { @@ -766,6 +776,7 @@ int Game::LoadMap(const char* ResRef, bool loadscreen) if (!newMap) { goto failedload; } + core->LoadProgress(100); for (i = 0; i < PCs.size(); i++) { @@ -1129,7 +1140,8 @@ void Game::IncrementChapter() //chapter first set to 0 (prologue) ieDword chapter = (ieDword) -1; locals->Lookup("CHAPTER",chapter); - locals->SetAt("CHAPTER",chapter+1); + //increment chapter only if it exists + locals->SetAt("CHAPTER", chapter+1, core->HasFeature(GF_NO_NEW_VARIABLES) ); //clear statistics for (unsigned int i=0; ipartysize); } -bool Game::PCInCombat(Actor* actor) const -{ - if (!CombatCounter) { - return false; - } - - if (actor->LastTarget) { - return true; - } - if (AttackersOf(actor->GetGlobalID(), actor->GetCurrentArea())) { - return true; - } - return false; -} - bool Game::AnyPCInCombat() const { if (!CombatCounter) { return false; } - for (unsigned int i=0; iUpdateScripts(); - size_t acnt=Attackers.size(); - while(acnt--) { - Actor *actor = Maps[idx]->GetActorByGlobalID(Attackers[acnt]); - if (actor) { - if ( !Maps[idx]->GetActorByGlobalID(actor->LastTarget) ) { - //Actor's target left area - OutAttack(Attackers[acnt]); - continue; - } else { - //each attacker handles their own round initiation - actor->InitRound(GameTime); - if (actor->InParty) { - PartyAttack = true; - } - } - } else { - //Attacker is gone from area - OutAttack(Attackers[acnt]); - } - } } if (PartyAttack) { @@ -1626,28 +1598,6 @@ bool Game::IsDay() return true; } -void Game::InAttack(ieDword globalID) -{ - std::vector< ieDword>::const_iterator idx; - - for(idx=Attackers.begin(); idx!=Attackers.end();idx++) { - if (*idx==globalID) return; - } - Attackers.push_back(globalID); -} - -void Game::OutAttack(ieDword globalID) -{ - std::vector< ieDword>::iterator idx; - - for(idx=Attackers.begin(); idx!=Attackers.end();idx++) { - if (*idx==globalID) { - Attackers.erase(idx); - break; - } - } -} - void Game::ChangeSong(bool always, bool force) { int Song; @@ -1666,25 +1616,6 @@ void Game::ChangeSong(bool always, bool force) area->PlayAreaSong( Song, always, force ); } -int Game::AttackersOf(ieDword globalID, Map *area) const -{ - if (!area) { - return 0; - } - std::vector< ieDword>::const_iterator idx; - - int cnt = 0; - for(idx=Attackers.begin(); idx!=Attackers.end();idx++) { - Actor * actor = area->GetActorByGlobalID(*idx); - if (actor) { - if (actor->LastTarget==globalID) { - cnt++; - } - } - } - return cnt; -} - /* this method redraws weather. If update is false, then the weather particles won't change (game paused) */ @@ -1795,16 +1726,6 @@ void Game::DebugDump() printf("Current area: %s Previous area: %s\n", CurrentArea, PreviousArea); printf("Global script: %s\n", Scripts[0]->GetName()); printf("CombatCounter: %d\n", (int) CombatCounter); - printf("Attackers count: %d\n", (int) Attackers.size()); - for(idx=0;idxLastTarget); - printf("Name: %s Attacking : %s\n", actor->ShortName, whom?whom->ShortName:"???"); - } printf("Party size: %d\n", (int) PCs.size()); for(idx=0;idx savedpositions; std::vector< GAMLocationEntry*> planepositions; std::vector< char*> mastarea; - std::vector< ieDword> Attackers; CRRow *crtable; ieResRef restmovies[8]; ieResRef daymovies[8]; @@ -286,6 +285,7 @@ public: EventHandler event_handler; //like in Control bool hasInfra; bool familiarBlock; + bool PartyAttack; private: /** reads the challenge rating table */ void LoadCRTable(); @@ -354,9 +354,6 @@ public: Actor* GetNPC(unsigned int Index); void SwapPCs(unsigned int Index1, unsigned int Index2); bool IsDay(); - void InAttack(ieDword globalID); - void OutAttack(ieDword globalID); - int AttackersOf(ieDword globalID, Map *area) const; //journal entries /** Deletes one or all journal entries if strref is -1 */ @@ -409,9 +406,6 @@ public: } return Formations[WhichFormation]; } - size_t GetAttackerCount() const { - return Attackers.size(); - } /** converts challenge rating to xp */ int GetXPFromCR(int cr); @@ -419,8 +413,6 @@ public: void ShareXP(int XP, int flags); /** returns true if we should start the party overflow window */ bool PartyOverflow() const; - /** returns true if actor is an attacker or being attacked */ - bool PCInCombat(Actor *actor) const; /** returns true if any pc is attacker or being attacked */ bool AnyPCInCombat() const; /** returns true if the party death condition is true */ diff --git a/project/jni/application/gemrb/gemrb/core/GameData.cpp b/project/jni/application/gemrb/gemrb/core/GameData.cpp index f8fb2d6e6..038711cbd 100644 --- a/project/jni/application/gemrb/gemrb/core/GameData.cpp +++ b/project/jni/application/gemrb/gemrb/core/GameData.cpp @@ -411,7 +411,7 @@ ScriptedAnimation* GameData::GetScriptedAnimation( const char *effect, bool doub { ScriptedAnimation *ret = NULL; - if (Exists( effect, IE_VVC_CLASS_ID ) ) { + if (Exists( effect, IE_VVC_CLASS_ID, true ) ) { DataStream *ds = GetResource( effect, IE_VVC_CLASS_ID ); ret = new ScriptedAnimation(ds, true); } else { diff --git a/project/jni/application/gemrb/gemrb/core/GameScript/Actions.cpp b/project/jni/application/gemrb/gemrb/core/GameScript/Actions.cpp index f6cb55b7e..fb34e6c63 100644 --- a/project/jni/application/gemrb/gemrb/core/GameScript/Actions.cpp +++ b/project/jni/application/gemrb/gemrb/core/GameScript/Actions.cpp @@ -41,6 +41,9 @@ #include "Video.h" #include "WorldMap.h" #include "GUI/GameControl.h" +#include "Scriptable/Container.h" +#include "Scriptable/Door.h" +#include "Scriptable/InfoPoint.h" //------------------------------------------------------------ // Action Functions @@ -549,7 +552,7 @@ void GameScript::TeleportParty(Scriptable* /*Sender*/, Action* parameters) int i = game->GetPartySize(false); while (i--) { Actor *tar = game->GetPC(i, false); - MoveBetweenAreasCore( tar, parameters->string1Parameter, + MoveBetweenAreasCore( tar, parameters->string0Parameter, parameters->pointParameter, -1, true); } } @@ -785,24 +788,24 @@ void GameScript::Ally(Scriptable* Sender, Action* /*parameters*/) /** GemRB extension: you can replace baldur.bcs */ void GameScript::ChangeAIScript(Scriptable* Sender, Action* parameters) { - if (parameters->int0Parameter>7) { - return; - } - if (Sender->Type!=ST_ACTOR && parameters->int0Parameter) { + if (parameters->int0Parameter>=MAX_SCRIPTS) { return; } + //clearing the queue, and checking script level was intentionally removed Sender->SetScript( parameters->string0Parameter, parameters->int0Parameter, false ); } void GameScript::ForceAIScript(Scriptable* Sender, Action* parameters) { + if (parameters->int0Parameter>=MAX_SCRIPTS) { + return; + } Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); if (!tar || tar->Type != ST_ACTOR) { return; } Actor* actor = ( Actor* ) tar; - //changeaiscript clears the queue, i believe - // actor->ClearActions(); + //clearing the queue, and checking script level was intentionally removed actor->SetScript( parameters->string0Parameter, parameters->int0Parameter, false ); } @@ -1123,14 +1126,12 @@ void GameScript::MoveToPoint(Scriptable* Sender, Action* parameters) return; } Actor* actor = ( Actor* ) Sender; - //WalkTo could release the current action, so we need this - ieDword tmp = (ieDword) parameters->int0Parameter; //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, tmp ); + actor->WalkTo( parameters->pointParameter, 0 ); dest = actor->Destination; } @@ -1139,19 +1140,6 @@ void GameScript::MoveToPoint(Scriptable* Sender, Action* parameters) // we should probably instead keep retrying until we reach dest Sender->ReleaseCurrentAction(); } - - if (tmp) { - if (!actor->InMove()) { - //can't reach target, movement failed - //we have to use tmp-1 because the distance required might be 0, - //so in GoNearAndRetry we add 1 to distance - if (Distance(dest,actor)>tmp-1) { - //to prevent deadlocks, we free the action - //which caused MoveToPoint in the first place - Sender->PopNextAction(); - } - } - } } //bg2, jumps to saved location in variable @@ -1753,6 +1741,7 @@ void GameScript::StartMusic(Scriptable* Sender, Action* parameters) case 3: //force switch, but wait for previous music to end gracefully force = false; restart = true; + break; default: force = false; restart = false; @@ -2578,14 +2567,14 @@ void GameScript::Spell(Scriptable* Sender, Action* parameters) //if target was set, fire spell if (Sender->LastTarget) { - Sender->CastSpellEnd(); + Sender->CastSpellEnd(0); Sender->ReleaseCurrentAction(); return; } //the target was converted to a point if(!Sender->LastTargetPos.isempty()) { - Sender->CastSpellPointEnd(); + Sender->CastSpellPointEnd(0); Sender->ReleaseCurrentAction(); return; } @@ -2609,8 +2598,8 @@ void GameScript::Spell(Scriptable* Sender, Action* parameters) Actor *act = (Actor *) Sender; //move near to target - if (dist != 0xfffffff) { - if (PersonalDistance(tar, Sender) > dist) { + if (dist != 0xffffffff) { + if (PersonalDistance(tar, Sender) > dist || !Sender->GetCurrentArea()->IsVisible(Sender->Pos, tar->Pos)) { MoveNearerTo(Sender,tar,dist); return; } @@ -2647,7 +2636,7 @@ void GameScript::SpellPoint(Scriptable* Sender, Action* parameters) //if target was set, fire spell if (!Sender->LastTargetPos.isempty()) { - Sender->CastSpellPointEnd(); + Sender->CastSpellPointEnd(0); Sender->ReleaseCurrentAction(); return; } @@ -2657,7 +2646,7 @@ void GameScript::SpellPoint(Scriptable* Sender, Action* parameters) Actor *act = (Actor *) Sender; //move near to target - if (PersonalDistance(parameters->pointParameter, Sender) > dist) { + if (PersonalDistance(parameters->pointParameter, Sender) > dist || !Sender->GetCurrentArea()->IsVisible(Sender->Pos, parameters->pointParameter)) { MoveNearerTo(Sender,parameters->pointParameter,dist, 0); return; } @@ -2696,14 +2685,14 @@ void GameScript::SpellNoDec(Scriptable* Sender, Action* parameters) //if target was set, fire spell if (Sender->LastTarget) { - Sender->CastSpellEnd(); + Sender->CastSpellEnd(0); Sender->ReleaseCurrentAction(); return; } //the target was converted to a point if(!Sender->LastTargetPos.isempty()) { - Sender->CastSpellPointEnd(); + Sender->CastSpellPointEnd(0); Sender->ReleaseCurrentAction(); return; } @@ -2753,7 +2742,7 @@ void GameScript::SpellPointNoDec(Scriptable* Sender, Action* parameters) //if target was set, fire spell if (!Sender->LastTargetPos.isempty()) { - Sender->CastSpellPointEnd(); + Sender->CastSpellPointEnd(0); Sender->ReleaseCurrentAction(); return; } @@ -2795,14 +2784,14 @@ void GameScript::ForceSpell(Scriptable* Sender, Action* parameters) //if target was set, fire spell if (Sender->LastTarget) { - Sender->CastSpellEnd(); + Sender->CastSpellEnd(0); Sender->ReleaseCurrentAction(); return; } //the target was converted to a point if(!Sender->LastTargetPos.isempty()) { - Sender->CastSpellPointEnd(); + Sender->CastSpellPointEnd(0); Sender->ReleaseCurrentAction(); return; } @@ -2851,7 +2840,7 @@ void GameScript::ForceSpellPoint(Scriptable* Sender, Action* parameters) //if target was set, fire spell if (!Sender->LastTargetPos.isempty()) { - Sender->CastSpellPointEnd(); + Sender->CastSpellPointEnd(0); Sender->ReleaseCurrentAction(); return; } @@ -2877,10 +2866,11 @@ void GameScript::ForceSpellPoint(Scriptable* Sender, Action* parameters) //ForceSpell with zero casting time //zero casting time, no depletion, not interruptable //FIXME The caster must meet the level requirements as set in the spell file -//FIXME The spell level is taken as parameter2 in some cases +//FIXME The spell level is taken as parameter2 in some cases (FIXED) void GameScript::ReallyForceSpell(Scriptable* Sender, Action* parameters) { ieResRef spellres; + int level; if (!ResolveSpellName( spellres, parameters) ) { Sender->ReleaseCurrentAction(); @@ -2904,10 +2894,15 @@ void GameScript::ReallyForceSpell(Scriptable* Sender, Action* parameters) actor->SetStance (IE_ANI_CONJURE); } Sender->CastSpell (spellres, tar, false, true); - if (tar->Type==ST_ACTOR) { - Sender->CastSpellEnd(); + if (parameters->string0Parameter[0]) { + level = parameters->int0Parameter; } else { - Sender->CastSpellPointEnd(); + level = parameters->int1Parameter; + } + if (tar->Type==ST_ACTOR) { + Sender->CastSpellEnd(level); + } else { + Sender->CastSpellPointEnd(level); } Sender->ReleaseCurrentAction(); } @@ -2919,6 +2914,7 @@ void GameScript::ReallyForceSpell(Scriptable* Sender, Action* parameters) void GameScript::ReallyForceSpellPoint(Scriptable* Sender, Action* parameters) { ieResRef spellres; + int level; if (!ResolveSpellName( spellres, parameters) ) { Sender->ReleaseCurrentAction(); @@ -2940,7 +2936,12 @@ void GameScript::ReallyForceSpellPoint(Scriptable* Sender, Action* parameters) actor->SetStance (IE_ANI_CONJURE); } Sender->CastSpellPoint (spellres, parameters->pointParameter, false, true); - Sender->CastSpellPointEnd(); + if (parameters->string0Parameter[0]) { + level = parameters->int0Parameter; + } else { + level = parameters->int1Parameter; + } + Sender->CastSpellPointEnd(level); Sender->ReleaseCurrentAction(); } @@ -2949,6 +2950,7 @@ void GameScript::ReallyForceSpellPoint(Scriptable* Sender, Action* parameters) void GameScript::ReallyForceSpellDead(Scriptable* Sender, Action* parameters) { ieResRef spellres; + int level; if (!ResolveSpellName( spellres, parameters) ) { Sender->ReleaseCurrentAction(); @@ -2965,18 +2967,17 @@ void GameScript::ReallyForceSpellDead(Scriptable* Sender, Action* parameters) return; } Sender->LastTargetPos=parameters->pointParameter; - /* - if (Sender->Type == ST_ACTOR) { - Actor *actor = (Actor *) Sender; - //the dead don't wiggle their fingers - //actor->SetStance (IE_ANI_CONJURE); - } - */ + Sender->CastSpell (spellres, tar, false, true); - if (tar->Type==ST_ACTOR) { - Sender->CastSpellEnd(); + if (parameters->string0Parameter[0]) { + level = parameters->int0Parameter; } else { - Sender->CastSpellPointEnd(); + level = parameters->int1Parameter; + } + if (tar->Type==ST_ACTOR) { + Sender->CastSpellEnd(parameters->int1Parameter); + } else { + Sender->CastSpellPointEnd(parameters->int1Parameter); } Sender->ReleaseCurrentAction(); } @@ -3200,10 +3201,17 @@ void GameScript::JoinParty(Scriptable* Sender, Action* parameters) if (Sender->Type != ST_ACTOR) { return; } + // make sure we're in the same area, otherwise Dynaheir joins when Minsc does + // but she's in another area and needs to be rescued first! + Actor* act = ( Actor* ) Sender; + Game *game = core->GetGame(); + if (act->GetCurrentArea() != game->GetCurrentArea()) { + return; + } + /* calling this, so it is simpler to change */ /* i'm not sure this is required here at all */ SetBeenInPartyFlags(Sender, parameters); - Actor* act = ( Actor* ) Sender; act->SetBase( IE_EA, EA_PC ); if (core->HasFeature( GF_HAS_DPLAYER )) { /* we must reset various existing scripts */ @@ -3222,7 +3230,7 @@ void GameScript::JoinParty(Scriptable* Sender, Action* parameters) act->SetDialog( resref ); } } - core->GetGame()->JoinParty( act, JP_JOIN ); + game->JoinParty( act, JP_JOIN ); } void GameScript::LeaveParty(Scriptable* Sender, Action* /*parameters*/) @@ -4076,7 +4084,7 @@ void GameScript::UnloadArea(Scriptable* /*Sender*/, Action* parameters) } } -static EffectRef fx_death_ref={"Death", NULL, -1}; +static EffectRef fx_death_ref = { "Death", -1 }; void GameScript::Kill(Scriptable* Sender, Action* parameters) { Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); @@ -4185,7 +4193,7 @@ void GameScript::TakePartyItem(Scriptable* Sender, Action* parameters) Game *game=core->GetGame(); int i=game->GetPartySize(false); while (i--) { - int res=MoveItemCore(game->GetPC(i,false), Sender, parameters->string0Parameter,0,IE_INV_ITEM_UNSTEALABLE); + int res=MoveItemCore(game->GetPC(i,false), Sender, parameters->string0Parameter,IE_INV_ITEM_UNDROPPABLE,IE_INV_ITEM_UNSTEALABLE); if (res!=MIC_NOITEM) return; } } @@ -4197,7 +4205,7 @@ void GameScript::TakePartyItemNum(Scriptable* Sender, Action* parameters) Game *game=core->GetGame(); int i=game->GetPartySize(false); while (i--) { - int res=MoveItemCore(game->GetPC(i,false), Sender, parameters->string0Parameter,0, IE_INV_ITEM_UNSTEALABLE); + int res=MoveItemCore(game->GetPC(i,false), Sender, parameters->string0Parameter,IE_INV_ITEM_UNDROPPABLE, IE_INV_ITEM_UNSTEALABLE); if (res == MIC_GOTITEM) { i++; count--; @@ -4213,7 +4221,7 @@ void GameScript::TakePartyItemRange(Scriptable* Sender, Action* parameters) while (i--) { Actor *ac = game->GetPC(i,false); if (Distance(Sender, ac)string0Parameter,0,IE_INV_ITEM_UNSTEALABLE)==MIC_GOTITEM) { } + while (MoveItemCore(ac, Sender, parameters->string0Parameter,IE_INV_ITEM_UNDROPPABLE,IE_INV_ITEM_UNSTEALABLE)==MIC_GOTITEM) { } } } } @@ -4223,7 +4231,7 @@ void GameScript::TakePartyItemAll(Scriptable* Sender, Action* parameters) Game *game=core->GetGame(); int i=game->GetPartySize(false); while (i--) { - while (MoveItemCore(game->GetPC(i,false), Sender, parameters->string0Parameter,0, IE_INV_ITEM_UNSTEALABLE)==MIC_GOTITEM) { } + while (MoveItemCore(game->GetPC(i,false), Sender, parameters->string0Parameter,IE_INV_ITEM_UNDROPPABLE, IE_INV_ITEM_UNSTEALABLE)==MIC_GOTITEM) { } } } @@ -5232,9 +5240,11 @@ void GameScript::RemoveSpell( Scriptable* Sender, Action* parameters) } Actor *actor = (Actor *) Sender; if (parameters->string0Parameter[0]) { - type = parameters->int1Parameter; - } else { + //the spell resref is in the string parameter type = parameters->int0Parameter; + } else { + //the spell number is in the int0 parameter + type = parameters->int1Parameter; } if (type==2) { //remove spell from both book and memorization @@ -5548,6 +5558,13 @@ void GameScript::UseContainer(Scriptable* Sender, Action* /*parameters*/) Sender->ReleaseCurrentAction(); return; } + + if (core->InCutSceneMode()) { + //cannot use container in dialog or cutscene + Sender->ReleaseCurrentAction(); + return; + } + Actor *actor = (Actor *)Sender; Container *container = core->GetCurrentContainer(); if (!container) { @@ -5623,7 +5640,9 @@ void GameScript::FixEngineRoom(Scriptable* Sender, Action* /*parameters*/) int value = CheckVariable( Sender, "EnginInMaze","GLOBAL"); if (value) { SetVariable(Sender, "EnginInMaze", "GLOBAL", 0); - core->SetEventFlag(EF_CREATEMAZE); + //this works only because the engine room exit depends only on the EnginInMaze variable + ScriptEngine *sE = core->GetGUIScriptEngine(); + sE->RunFunction("Maze", "CustomizeArea"); } } @@ -6983,7 +7002,7 @@ void GameScript::SpellCastEffect(Scriptable* Sender, Action* parameters) //this action plays a vvc animation over target //we simply apply the appropriate opcode on the target (see iwdopcodes) //the list of vvcs is in iwdshtab.2da -EffectRef fx_iwd_visual_spell_hit_ref={"IWDVisualSpellHit",NULL,-1}; +static EffectRef fx_iwd_visual_spell_hit_ref = { "IWDVisualSpellHit", -1 }; void GameScript::SpellHitEffectSprite(Scriptable* Sender, Action* parameters) { diff --git a/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.cpp b/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.cpp index a6d653cd9..9fe3c6c31 100644 --- a/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.cpp +++ b/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.cpp @@ -37,6 +37,9 @@ #include "TileMap.h" #include "Video.h" #include "GUI/GameControl.h" +#include "Scriptable/Container.h" +#include "Scriptable/Door.h" +#include "Scriptable/InfoPoint.h" #include @@ -57,6 +60,9 @@ int ObjectIDSCount = 7; int MaxObjectNesting = 5; bool HasAdditionalRect = false; bool HasTriggerPoint = false; +//don't create new variables +bool NoCreate = false; +bool HasKaputz = false; //released by ReleaseMemory ieResRef *ObjectIDSTableNames; int ObjectFieldsCount = 7; @@ -700,6 +706,8 @@ void ChangeAnimationCore(Actor *src, const char *resref, bool effect) map->AddActor( tar ); Point pos = src->Pos; tar->SetOrientation(src->GetOrientation(), false ); + // make sure to copy the HP, to avoid things like magically-healing trolls + tar->BaseStats[IE_HITPOINTS]=src->BaseStats[IE_HITPOINTS]; src->DestroySelf(); // can't SetPosition while the old actor is taking the spot tar->SetPosition(pos, 1); @@ -1133,15 +1141,19 @@ void MoveToObjectCore(Scriptable *Sender, Action *parameters, ieDword flags, boo void CreateItemCore(CREItem *item, const char *resref, int a, int b, int c) { - strncpy(item->ItemResRef, resref, 8); + //copy the whole resref, including the terminating zero + strnuprcpy(item->ItemResRef, resref, 8); core->ResolveRandomItem(item); if (a==-1) { - Item *origitem = gamedata->GetItem(resref); - for(int i=0;i<3;i++) { - ITMExtHeader *e = origitem->GetExtHeader(i); - item->Usages[i]=e?e->Charges:0; + //use the default charge counts of the item + Item *origitem = gamedata->GetItem(item->ItemResRef); + if (origitem) { + for(int i=0;i<3;i++) { + ITMExtHeader *e = origitem->GetExtHeader(i); + item->Usages[i]=e?e->Charges:0; + } + gamedata->FreeItem(origitem, item->ItemResRef, false); } - gamedata->FreeItem(origitem, resref, false); } else { item->Usages[0]=(ieWord) a; item->Usages[1]=(ieWord) b; @@ -1207,7 +1219,8 @@ void AttackCore(Scriptable *Sender, Scriptable *target, int flags) actor->SetTarget( target ); } if ( Sender->GetCurrentArea()!=target->GetCurrentArea() || - (PersonalDistance(Sender, target) > wi.range) ) { + (PersonalDistance(Sender, target) > wi.range) || + (!Sender->GetCurrentArea()->IsVisible(Sender->Pos, target->Pos))) { MoveNearerTo(Sender, target, wi.range); return; } else if (target->Type == ST_DOOR) { @@ -1567,7 +1580,7 @@ void MoveNearerTo(Scriptable *Sender, Scriptable *target, int distance) myarea = Sender->GetCurrentArea(); hisarea = target->GetCurrentArea(); - if (hisarea!=myarea) { + if (hisarea && hisarea!=myarea) { target = myarea->GetTileMap()->GetTravelTo(hisarea->GetScriptName()); if (!target) { @@ -1575,9 +1588,9 @@ void MoveNearerTo(Scriptable *Sender, Scriptable *target, int distance) Sender->ReleaseCurrentAction(); return; } - ((Actor *) Sender)->UseExit(true); + ((Actor *) Sender)->UseExit(target->GetGlobalID()); } else { - ((Actor *) Sender)->UseExit(false); + ((Actor *) Sender)->UseExit(0); } // we deliberately don't try GetLikelyPosition here for now, // maybe a future idea if we have a better implementation @@ -1606,6 +1619,10 @@ int MoveNearerTo(Scriptable *Sender, const Point &p, int distance, int dont_rele return 0; } + //chasing is unbreakable + //TODO: is this true? + Sender->CurrentActionInterruptable = false; + Actor *actor = (Actor *)Sender; if (!actor->InMove() || actor->Destination != p) { @@ -1622,33 +1639,7 @@ int MoveNearerTo(Scriptable *Sender, const Point &p, int distance, int dont_rele } return 0; } -/* -void GoNearAndRetry(Scriptable *Sender, Scriptable *target, bool flag, int distance) -{ - Point p; - GetPositionFromScriptable(target,p,flag); - GoNearAndRetry(Sender, p, distance); -} -void GoNearAndRetry(Scriptable *Sender, const Point &p, int distance) -{ - if (!Sender->GetCurrentAction() ) { - printMessage("GameScript","NULL action retried???\n",LIGHT_RED); - return; - } - Sender->AddActionInFront( Sender->GetCurrentAction() ); - char Tmp[256]; - sprintf( Tmp, "MoveToPoint([%hd.%hd])", p.x, p.y ); - Action * action = GenerateAction( Tmp); - //experimental hack, this value means, - //MoveToPoint shall pop the next action too if movement fails - //and the actor is farther than distance - //this will prevent deadlocks - //(we have to add 1 because otherwise distance==0 fails, we subtract it in MoveToPoint) - action->int0Parameter = distance+1; - Sender->AddActionInFront( action ); -} -*/ void FreeSrc(SrcVector *poi, const ieResRef key) { int res = SrcCache.DecRef((void *) poi, key, true); @@ -1892,18 +1883,19 @@ void SetVariable(Scriptable* Sender, const char* VarName, const char* Context, i printf( "Setting variable(\"%s%s\", %d)\n", Context, VarName, value ); } + strncpy( newVarName, Context, 6 ); newVarName[6]=0; if (strnicmp( newVarName, "MYAREA", 6 ) == 0) { - Sender->GetCurrentArea()->locals->SetAt( VarName, value ); + Sender->GetCurrentArea()->locals->SetAt( VarName, value, NoCreate ); return; } if (strnicmp( newVarName, "LOCALS", 6 ) == 0) { - Sender->locals->SetAt( VarName, value ); + Sender->locals->SetAt( VarName, value, NoCreate ); return; } Game *game = core->GetGame(); - if (!strnicmp(newVarName,"KAPUTZ",6) && core->HasFeature(GF_HAS_KAPUTZ) ) { + if (HasKaputz && !strnicmp(newVarName,"KAPUTZ",6) ) { game->kaputz->SetAt( VarName, value ); return; } @@ -1911,7 +1903,7 @@ void SetVariable(Scriptable* Sender, const char* VarName, const char* Context, i if (strnicmp(newVarName,"GLOBAL",6) ) { Map *map=game->GetMap(game->FindMap(newVarName)); if (map) { - map->locals->SetAt( VarName, value); + map->locals->SetAt( VarName, value, NoCreate); } else if (InDebug&ID_VARIABLES) { printMessage("GameScript"," ",YELLOW); @@ -1919,7 +1911,7 @@ void SetVariable(Scriptable* Sender, const char* VarName, const char* Context, i } } else { - game->locals->SetAt( VarName, ( ieDword ) value ); + game->locals->SetAt( VarName, ( ieDword ) value, NoCreate ); } } @@ -1940,22 +1932,22 @@ void SetVariable(Scriptable* Sender, const char* VarName, ieDword value) strncpy( newVarName, VarName, 6 ); newVarName[6]=0; if (strnicmp( newVarName, "MYAREA", 6 ) == 0) { - Sender->GetCurrentArea()->locals->SetAt( poi, value ); + Sender->GetCurrentArea()->locals->SetAt( poi, value, NoCreate ); return; } if (strnicmp( newVarName, "LOCALS", 6 ) == 0) { - Sender->locals->SetAt( poi, value ); + Sender->locals->SetAt( poi, value, NoCreate ); return; } Game *game = core->GetGame(); - if (!strnicmp(newVarName,"KAPUTZ",6) && core->HasFeature(GF_HAS_KAPUTZ) ) { - game->kaputz->SetAt( poi, value ); + if (HasKaputz && !strnicmp(newVarName,"KAPUTZ",6) ) { + game->kaputz->SetAt( poi, value, NoCreate ); return; } if (strnicmp(newVarName,"GLOBAL",6) ) { Map *map=game->GetMap(game->FindMap(newVarName)); if (map) { - map->locals->SetAt( poi, value); + map->locals->SetAt( poi, value, NoCreate); } else if (InDebug&ID_VARIABLES) { printMessage("GameScript"," ",YELLOW); @@ -1963,7 +1955,7 @@ void SetVariable(Scriptable* Sender, const char* VarName, ieDword value) } } else { - game->locals->SetAt( poi, ( ieDword ) value ); + game->locals->SetAt( poi, ( ieDword ) value, NoCreate ); } } @@ -1996,7 +1988,7 @@ ieDword CheckVariable(Scriptable* Sender, const char* VarName, bool *valid) return value; } Game *game = core->GetGame(); - if (!strnicmp(newVarName,"KAPUTZ",6) && core->HasFeature(GF_HAS_KAPUTZ) ) { + if (HasKaputz && !strnicmp(newVarName,"KAPUTZ",6) ) { game->kaputz->Lookup( poi, value ); if (InDebug&ID_VARIABLES) { printf("CheckVariable %s: %d\n",VarName, value); @@ -2047,7 +2039,7 @@ ieDword CheckVariable(Scriptable* Sender, const char* VarName, const char* Conte return value; } Game *game = core->GetGame(); - if (!strnicmp(newVarName,"KAPUTZ",6) && core->HasFeature(GF_HAS_KAPUTZ) ) { + if (HasKaputz && !strnicmp(newVarName,"KAPUTZ",6) ) { game->kaputz->Lookup( VarName, value ); if (InDebug&ID_VARIABLES) { printf("CheckVariable %s%s: %d\n",Context, VarName, value); @@ -2173,7 +2165,7 @@ Point GetEntryPoint(const char *areaname, const char *entryname) } /* returns a spell's casting distance, it depends on the caster (level), and targeting mode too - the used header is calculated from the caster level */ + the used header is calculated from the caster level */ unsigned int GetSpellDistance(const ieResRef spellres, Scriptable *Sender) { unsigned int dist; @@ -2192,11 +2184,11 @@ unsigned int GetSpellDistance(const ieResRef spellres, Scriptable *Sender) } gamedata->FreeSpell(spl, spellres, false); - return dist*15; + return dist*5; //FIXME: this empirical constant shouldn't be needed! } /* returns an item's casting distance, it depends on the used header, and targeting mode too - the used header is explictly given */ + the used header is explictly given */ unsigned int GetItemDistance(const ieResRef itemres, int header) { unsigned int dist; diff --git a/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.h b/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.h index 9297ba792..fe3a9bfd0 100644 --- a/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.h +++ b/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.h @@ -51,6 +51,8 @@ extern int ObjectIDSCount; extern int MaxObjectNesting; extern bool HasAdditionalRect; extern bool HasTriggerPoint; +extern bool NoCreate; +extern bool HasKaputz; extern ieResRef *ObjectIDSTableNames; extern int ObjectFieldsCount; extern int ExtraParametersCount; @@ -90,8 +92,6 @@ void EscapeAreaCore(Scriptable *Sender, const Point &p, const char *area, const void GoNear(Scriptable *Sender, const Point &p); void MoveNearerTo(Scriptable *Sender, Scriptable *target, int distance); int MoveNearerTo(Scriptable *Sender, const Point &p, int distance, int no_release); -void GoNearAndRetry(Scriptable *Sender, Scriptable *target, bool destination, int distance); -void GoNearAndRetry(Scriptable *Sender, const Point &p, int distance); #define NO_OPERATION -1 #define LESS_OR_EQUALS 0 @@ -110,8 +110,8 @@ void GoNearAndRetry(Scriptable *Sender, const Point &p, int distance); GEM_EXPORT int GetGroup(Actor *actor); -void FreeSrc(SrcVector *poi, const ieResRef key); -SrcVector *LoadSrc(const ieResRef resname); +GEM_EXPORT void FreeSrc(SrcVector *poi, const ieResRef key); +GEM_EXPORT SrcVector *LoadSrc(const ieResRef resname); Action *ParamCopy(Action *parameters); Action *ParamCopyNoOverride(Action *parameters); void SetVariable(Scriptable* Sender, const char* VarName, ieDword value); diff --git a/project/jni/application/gemrb/gemrb/core/GameScript/GameScript.cpp b/project/jni/application/gemrb/gemrb/core/GameScript/GameScript.cpp index 37fc21835..9c15f1b68 100644 --- a/project/jni/application/gemrb/gemrb/core/GameScript/GameScript.cpp +++ b/project/jni/application/gemrb/gemrb/core/GameScript/GameScript.cpp @@ -204,6 +204,7 @@ static const TriggerLink triggernames[] = { {"isactive", GameScript::IsActive, 0}, {"isanimationid", GameScript::AnimationID, 0}, {"iscreatureareaflag", GameScript::IsCreatureAreaFlag, 0}, + {"iscreaturehiddeninshadows", GameScript::IsCreatureHiddenInShadows, 0}, {"isfacingobject", GameScript::IsFacingObject, 0}, {"isfacingsavedrotation", GameScript::IsFacingSavedRotation, 0}, {"isgabber", GameScript::IsGabber, 0}, @@ -1254,6 +1255,10 @@ void Targets::Clear() /** releasing global memory */ static void CleanupIEScript() { + triggersTable.release(); + actionsTable.release(); + objectsTable.release(); + overrideActionsTable.release(); if (ObjectIDSTableNames) free(ObjectIDSTableNames); ObjectIDSTableNames = NULL; @@ -1281,6 +1286,9 @@ void InitializeIEScript() PluginMgr::Get()->RegisterCleanup(CleanupIEScript); + NoCreate = core->HasFeature(GF_NO_NEW_VARIABLES); + HasKaputz = core->HasFeature(GF_HAS_KAPUTZ); + InitScriptTables(); int tT = core->LoadSymbol( "trigger" ); int aT = core->LoadSymbol( "action" ); @@ -1721,8 +1729,9 @@ static Object* DecodeObject(const char* line) printf("%s\n", origline); } //let the object realize it has no future (in case of null objects) - if (oB->ReadyToDie()) { - oB = NULL; + if (oB->isNull()) { + oB->Release(); + return NULL; } return oB; } @@ -1841,13 +1850,10 @@ bool GameScript::Update(bool *continuing, bool *done) } continueExecution = ( rB->responseSet->Execute(MySelf) != 0); if (continuing) *continuing = continueExecution; - //clear triggers after response executed - //MySelf->ClearTriggers(); if (!continueExecution) { if (done) *done = true; break; } - //continueExecution = false; } } return true; @@ -2315,8 +2321,8 @@ Action* GenerateActionDirect(char *String, Scriptable *object) return action; } -/** Self-destructing object if it is empty */ -bool Object::ReadyToDie() +/** Return true if object is null */ +bool Object::isNull() { if (objectName[0]!=0) { return false; @@ -2329,8 +2335,6 @@ bool Object::ReadyToDie() return false; } } - //commit suicide - Release(); return true; } diff --git a/project/jni/application/gemrb/gemrb/core/GameScript/GameScript.h b/project/jni/application/gemrb/gemrb/core/GameScript/GameScript.h index e6dc3c1e5..874aa00e5 100644 --- a/project/jni/application/gemrb/gemrb/core/GameScript/GameScript.h +++ b/project/jni/application/gemrb/gemrb/core/GameScript/GameScript.h @@ -104,11 +104,11 @@ class GameScript; #define MAX_NESTING 5 #define GSASSERT(f,c) \ - if(!(f)) \ - { \ - printf("Assertion failed: %s [0x%08lX] Line %d",#f, c, __LINE__); \ - abort(); \ - } + if(!(f)) \ + { \ + printf("Assertion failed: %s [0x%08lX] Line %d",#f, c, __LINE__); \ + abort(); \ + } typedef std::vector SrcVector; @@ -192,7 +192,7 @@ public: canary = 0xdddddddd; delete this; } - bool ReadyToDie(); + bool isNull(); }; class GEM_EXPORT Trigger { diff --git a/project/jni/application/gemrb/gemrb/core/GameScript/Matching.cpp b/project/jni/application/gemrb/gemrb/core/GameScript/Matching.cpp index f0ad5d186..be43aff7d 100644 --- a/project/jni/application/gemrb/gemrb/core/GameScript/Matching.cpp +++ b/project/jni/application/gemrb/gemrb/core/GameScript/Matching.cpp @@ -25,6 +25,9 @@ #include "Interface.h" #include "Game.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) @@ -77,7 +80,7 @@ inline static Targets *DoObjectFiltering(Scriptable *Sender, Targets *tgts, Obje return tgts; } -static EffectRef fx_protection_creature_ref = { "Protection:Creature", NULL, -1 }; +static EffectRef fx_protection_creature_ref = { "Protection:Creature", -1 }; inline static bool DoObjectChecks(Map *map, Scriptable *Sender, Actor *target, int &dist, bool ignoreinvis=false) { diff --git a/project/jni/application/gemrb/gemrb/core/GameScript/Triggers.cpp b/project/jni/application/gemrb/gemrb/core/GameScript/Triggers.cpp index 874845a94..da8f35ee6 100644 --- a/project/jni/application/gemrb/gemrb/core/GameScript/Triggers.cpp +++ b/project/jni/application/gemrb/gemrb/core/GameScript/Triggers.cpp @@ -32,6 +32,9 @@ #include "Video.h" #include "GUI/GameControl.h" #include "math.h" //needs for acos +#include "Scriptable/Container.h" +#include "Scriptable/Door.h" +#include "Scriptable/InfoPoint.h" //------------------------------------------------------------- // Trigger Functions @@ -1129,8 +1132,8 @@ int GameScript::Acquired(Scriptable * Sender, Trigger* parameters) return 0; } -/** this trigger accepts a numeric parameter, this number could be: */ -/** 0 - normal, 1 - equipped, 2 - identified, 3 - equipped&identified */ +/** this trigger accepts a numeric parameter, this number is the same as inventory flags + like: 1 - identified, 2 - unstealable, 4 - stolen, 8 - undroppable, etc. */ /** this is a GemRB extension */ int GameScript::PartyHasItem(Scriptable * /*Sender*/, Trigger* parameters) { @@ -1512,8 +1515,8 @@ int GameScript::NearLocation(Scriptable* Sender, Trigger* parameters) } return 0; } - // should this be PersonalDistance? - int distance = Distance(parameters->pointParameter, scr); + //personaldistance is needed for modron constructs in PST maze + int distance = PersonalDistance(parameters->pointParameter, scr); if (distance <= ( parameters->int0Parameter * 10 )) { return 1; } diff --git a/project/jni/application/gemrb/gemrb/core/GlobalTimer.cpp b/project/jni/application/gemrb/gemrb/core/GlobalTimer.cpp index 1f71723d2..64d2c74b7 100644 --- a/project/jni/application/gemrb/gemrb/core/GlobalTimer.cpp +++ b/project/jni/application/gemrb/gemrb/core/GlobalTimer.cpp @@ -69,7 +69,7 @@ void GlobalTimer::Freeze() if (!game) { return; } - game->RealTime+=advance; + game->RealTime++; ieDword count = advance/interval; // pst/bg2 do this, if you fix it for another game, wrap it in a check @@ -141,7 +141,7 @@ void GlobalTimer::DoStep(int count) video->MoveViewportTo(x,y); } -void GlobalTimer::Update() +bool GlobalTimer::Update() { Map *map; Game *game; @@ -159,12 +159,12 @@ void GlobalTimer::Update() if (!startTime) { startTime = thisTime; - return; + return false; } advance = thisTime - startTime; if ( advance < interval) { - return; + return false; } ieDword count = advance/interval; DoStep(count); @@ -187,15 +187,16 @@ void GlobalTimer::Update() map->UpdateEffects(); if (thisTime) { //this measures in-world time (affected by effects, actions, etc) - game->AdvanceTime(count); + game->AdvanceTime(1); } } //this measures time spent in the game (including pauses) if (thisTime) { - game->RealTime+=advance; + game->RealTime++; } end: startTime = thisTime; + return true; } diff --git a/project/jni/application/gemrb/gemrb/core/GlobalTimer.h b/project/jni/application/gemrb/gemrb/core/GlobalTimer.h index ebf955c82..bcb933102 100644 --- a/project/jni/application/gemrb/gemrb/core/GlobalTimer.h +++ b/project/jni/application/gemrb/gemrb/core/GlobalTimer.h @@ -60,7 +60,7 @@ public: public: void Init(); void Freeze(); - void Update(); + bool Update(); bool ViewportIsMoving(); void DoStep(int count); void SetMoveViewPort(ieDword x, ieDword y, int spd, bool center); diff --git a/project/jni/application/gemrb/gemrb/core/Interface.cpp b/project/jni/application/gemrb/gemrb/core/Interface.cpp index ee7b52cec..2f85d9cc2 100644 --- a/project/jni/application/gemrb/gemrb/core/Interface.cpp +++ b/project/jni/application/gemrb/gemrb/core/Interface.cpp @@ -61,15 +61,18 @@ #include "SpellMgr.h" #include "StoreMgr.h" #include "StringMgr.h" +#include "SymbolMgr.h" #include "TileMap.h" #include "Video.h" #include "WorldMapMgr.h" +#include "GameScript/GameScript.h" #include "GUI/Button.h" #include "GUI/Console.h" #include "GUI/GameControl.h" #include "GUI/Label.h" #include "GUI/MapControl.h" #include "GUI/WorldMapControl.h" +#include "Scriptable/Container.h" #include "System/FileStream.h" #include "System/VFS.h" @@ -166,6 +169,7 @@ Interface::Interface(int iargc, char* iargv[]) mousescrollspd = 10; + strncpy( GameType, "auto", sizeof( GameType )-1); ConsolePopped = false; CheatFlag = false; FogOfWar = 1; @@ -181,6 +185,7 @@ Interface::Interface(int iargc, char* iargv[]) DrawFPS = false; KeepCache = false; TooltipDelay = 100; + IgnoreOriginalINI = 0; FullScreen = 0; GUIScriptsPath[0] = 0; GamePath[0] = 0; @@ -590,6 +595,19 @@ void Interface::HandleEvents() guiscript->RunFunction( "Maze", "CreateMaze", false ); return; } + + if ((EventFlag&EF_RESETTARGET) && gc) { + EventFlag&=~EF_RESETTARGET; + EventFlag|=EF_TARGETMODE; + gc->ResetTargetMode(); + return; + } + + if ((EventFlag&EF_TARGETMODE) && gc) { + EventFlag&=~EF_TARGETMODE; + gc->UpdateTargetMode(); + return; + } } /* handle main loop events that might destroy or create windows @@ -1409,6 +1427,8 @@ int Interface::Init() printStatus( "OK", LIGHT_GREEN ); if (!LoadConfig()) { + printMessage( "Core", "Could not load config file ", YELLOW); + printStatus( "ERROR", LIGHT_RED ); return GEM_ERROR; } printMessage( "Core", "Starting Plugin Manager...\n", WHITE ); @@ -1488,13 +1508,15 @@ int Interface::Init() gamedata->AddSource(path, "Data", PLUGIN_RESOURCE_DIRECTORY); //IWD2 movies are on the CD but not in the BIF + char *description = strdup("CD1/data"); for (i = 0; i < MAX_CD; i++) { for (size_t j=0;jAddSource(path, description, PLUGIN_RESOURCE_DIRECTORY); } } + free(description); printStatus( "OK", LIGHT_GREEN ); } @@ -1510,27 +1532,47 @@ int Interface::Init() printStatus( "OK", LIGHT_GREEN ); } - printMessage( "Core", "Reading Game Options...\n", WHITE ); - if (!LoadGemRBINI()) + printMessage( "Core", "Initializing GUI Script Engine...", WHITE ); + guiscript = PluginHolder(IE_GUI_SCRIPT_CLASS_ID); + if (guiscript == NULL) { + printStatus( "ERROR", LIGHT_RED ); + return GEM_ERROR; + } + if (!guiscript->Init()) { + printStatus( "ERROR", LIGHT_RED ); + return GEM_ERROR; + } + printStatus( "OK", LIGHT_GREEN ); + strcpy( NextScript, "Start" ); + { + // re-set the gemrb override path, since we now have the correct GameType if 'auto' was used + char path[_MAX_PATH]; + PathJoin( path, GemRBOverridePath, "override", GameType, NULL); + gamedata->AddSource(path, "GemRB Override", PLUGIN_RESOURCE_DIRECTORY, RM_REPLACE_SAME_SOURCE); + } + + printMessage( "Core", "Reading Game Options...\n", WHITE ); + if (!LoadGemRBINI()) { printf( "Cannot Load INI\nTermination in Progress...\n" ); return GEM_ERROR; } //loading baldur.ini - { + if (!IgnoreOriginalINI) { char ini_path[_MAX_PATH]; PathJoin( ini_path, GamePath, INIConfig, NULL ); LoadINI( ini_path ); - int i; - for (i = 0; i < 8; i++) { - if (INIConfig[i] == '.') - break; - GameNameResRef[i] = INIConfig[i]; - } - GameNameResRef[i] = 0; } + int i; + for (i = 0; i < 8; i++) { + if (INIConfig[i] == '.') + break; + GameNameResRef[i] = INIConfig[i]; + } + GameNameResRef[i] = 0; + printMessage( "Core", "Creating Projectile Server...\n", WHITE ); projserv = new ProjectileServer(); if (!projserv->GetHighestProjectileNumber()) { @@ -1602,18 +1644,6 @@ int Interface::Init() return GEM_ERROR; } printStatus( "OK", LIGHT_GREEN ); - printMessage( "Core", "Initializing GUI Script Engine...", WHITE ); - guiscript = PluginHolder(IE_GUI_SCRIPT_CLASS_ID); - if (guiscript == NULL) { - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - if (!guiscript->Init()) { - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - printStatus( "OK", LIGHT_GREEN ); - strcpy( NextScript, "Start" ); int ret = LoadSprites(); if (ret) return ret; @@ -2054,36 +2084,11 @@ void Interface::SetFeature(int flag, int position) } else { GameFeatures[position>>5] &= ~(1<<(position&31) ); } -/* - if (position>=32) { - position-=32; - if (flag) { - GameFeatures2 |= 1 << position; - } else { - GameFeatures2 &= ~( 1 << position ); - } - return; - } - if (flag) { - GameFeatures |= 1 << position; - } else { - GameFeatures &= ~( 1 << position ); - } -*/ } ieDword Interface::HasFeature(int position) const { return GameFeatures[position>>5] & (1<<(position&31)); -/* - if (position>=64) { - return GameFeatures3 & ( 1 << (position-64) ); - } - if (position>=32) { - return GameFeatures2 & ( 1 << (position-32) ); - } - return GameFeatures & ( 1 << position ); -*/ } /** Search directories and load a config file */ @@ -2192,38 +2197,51 @@ bool Interface::LoadConfig(const char* filename) printf("%s ", filename); config = fopen( filename, "rb" ); if (config == NULL) { - printStatus("NOT FOUND", LIGHT_RED); + printStatus("NOT FOUND", YELLOW); return false; } - char name[65], value[_MAX_PATH + 3]; + 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 )) { - char rem; - - if (fread( &rem, 1, 1, config ) != 1) + if (! fgets( line, sizeof(line), config )) { // also if len == size(line) break; + } + lineno++; - if (rem == '#') { - //it should always return 0 - if (fscanf( config, "%*[^\r\n]%*[\r\n]" )!=0) - break; + // skip leading blanks from name + name = line; + name += strspn( line, " \t\r\n" ); + + // ignore empty or comment lines + if (*name == '\0' || *name == '#') { continue; } - fseek( config, -1, SEEK_CUR ); - memset(value,'\0',_MAX_PATH + 3); - //the * element is not counted - if (fscanf( config, "%64[^= ] = %[^\r\n]%*[\r\n]", name, value )!=2) + + value = strchr( name, '=' ); + if (!value || value == name) { + printf( "Invalid line %d\n", lineno ); continue; - for (i=_MAX_PATH + 2; i > 0; i--) { - if (value[i] == '\0') continue; - if (value[i] == ' ') { - value[i] = '\0'; - } else { - break; - } + } + + // trim trailing blanks from name + nameend = value; + while (nameend > name && strchr( "= \t", *nameend )) { + *nameend-- = '\0'; + } + + value++; + // skip leading blanks + value += strspn( value, " \t"); + + // trim trailing blanks from value + valueend = value + strlen( value ) - 1; + while (valueend >= value && strchr( " \t\r\n", *valueend )) { + *valueend-- = '\0'; } if (false) { @@ -2249,6 +2267,7 @@ bool Interface::LoadConfig(const char* filename) CONFIG_INT("SkipIntroVideos", SkipIntroVideos = ); CONFIG_INT("TooltipDelay", TooltipDelay = ); CONFIG_INT("Width", Width = ); + CONFIG_INT("IgnoreOriginalINI", IgnoreOriginalINI = ); #undef CONFIG_INT #define CONFIG_STRING(str, var) \ } else if (stricmp(name, str) == 0) { \ @@ -2483,6 +2502,8 @@ static const char *game_flags[GF_COUNT+1]={ "CastingSounds", //57GF_CASTING_SOUNDS "EnhancedCastingSounds", //58GF_CASTING_SOUNDS2 "ForceAreaScript", //59GF_FORCE_AREA_SCRIPT + "AreaOverride", //60GF_AREA_OVERRIDE + "NoNewVariables", //61GF_NO_NEW_VARIABLES NULL //for our own safety, this marks the end of the pole }; @@ -2626,6 +2647,8 @@ bool Interface::LoadGemRBINI() Palette* Interface::CreatePalette(const Color &color, const Color &back) { Palette* pal = new Palette(); + pal->front = color; + pal->back = back; pal->col[0].r = 0; pal->col[0].g = 0xff; pal->col[0].b = 0; @@ -2706,7 +2729,7 @@ ScriptEngine* Interface::GetGUIScriptEngine() const return guiscript.get(); } -static EffectRef fx_summon_disable_ref={"AvatarRemovalModifier",NULL,-1}; +static EffectRef fx_summon_disable_ref = { "AvatarRemovalModifier", -1 }; //NOTE: if there were more summoned creatures, it will return only the last Actor *Interface::SummonCreature(const ieResRef resource, const ieResRef vvcres, Scriptable *Owner, Actor *target, const Point &position, int eamod, int level, Effect *fx, bool sexmod) @@ -3219,7 +3242,7 @@ void Interface::GameLoop(void) update_scripts = !(gc->GetDialogueFlags() & DF_FREEZE_SCRIPTS); } - GSUpdate(update_scripts); + update_scripts = GSUpdate(update_scripts); //i'm not sure if this should be here @@ -3252,8 +3275,12 @@ void Interface::HandleGUIBehaviour(void) ieDword var = (ieDword) -3; vars->Lookup("DialogChoose", var); if ((int) var == -2) { + // TODO: this seems to never be called? (EndDialog is called from elsewhere instead) gc->dialoghandler->EndDialog(); } else if ( (int)var !=-3) { + if ( (int) var == -1) { + guiscript->RunFunction( "GUIWORLD", "DialogStarted" ); + } gc->dialoghandler->DialogChoose(var); if (!(gc->GetDialogueFlags() & (DF_OPENCONTINUEWINDOW | DF_OPENENDWINDOW))) guiscript->RunFunction( "GUIWORLD", "NextDialogState" ); @@ -3818,7 +3845,12 @@ bool Interface::LoadINI(const char* filename) void Interface::SetCutSceneMode(bool active) { GameControl *gc = GetGameControl(); + if (gc) { + // don't mess with controls/etc if we're already in a cutscene + if (active == (gc->GetScreenFlags()&SF_CUTSCENE)) + return; + gc->SetCutSceneMode( active ); } if (game) { @@ -3832,9 +3864,26 @@ void Interface::SetCutSceneMode(bool active) video->SetMouseEnabled(!active); } +/** returns true if in dialogue or cutscene */ bool Interface::InCutSceneMode() const { - return (GetGameControl()->GetScreenFlags()&SF_DISABLEMOUSE)!=0; + GameControl *gc = GetGameControl(); + if (!gc || (gc->GetDialogueFlags()&DF_IN_DIALOG) || (gc->GetScreenFlags()&SF_DISABLEMOUSE) ) { + return true; + } + return false; +} + +/** Updates the Game Script Engine State */ +bool Interface::GSUpdate(bool update_scripts) +{ + if(update_scripts) { + return timer->Update(); + } + else { + timer->Freeze(); + return false; + } } void Interface::QuitGame(int BackToMain) @@ -4580,7 +4629,13 @@ bool Interface::ReadRandomItems() CREItem *Interface::ReadItem(DataStream *str) { CREItem *itm = new CREItem(); + if (ReadItem(str, itm)) return itm; + delete itm; + return NULL; +} +CREItem *Interface::ReadItem(DataStream *str, CREItem *itm) +{ str->ReadResRef( itm->ItemResRef ); str->ReadWord( &itm->Expired ); str->ReadWord( &itm->Usages[0] ); @@ -4590,7 +4645,6 @@ CREItem *Interface::ReadItem(DataStream *str) if (ResolveRandomItem(itm) ) { return itm; } - delete itm; return NULL; } @@ -4858,19 +4912,24 @@ void Interface::PlaySound(int index) Actor *Interface::GetFirstSelectedPC(bool forced) { + Actor *ret = NULL; + int slot = 0; int partySize = game->GetPartySize( false ); if (!partySize) return NULL; for (int i = 0; i < partySize; i++) { Actor* actor = game->GetPC( i,false ); if (actor->IsSelected()) { - return actor; + if (actor->InPartyInParty; + } } } - if (forced) { - return game->GetPC(0,false); + if (forced && !ret) { + return game->FindPC((unsigned int) 0); } - return NULL; + return ret; } Actor *Interface::GetFirstSelectedActor() @@ -4925,8 +4984,8 @@ void Interface::ApplySpell(const ieResRef resname, Actor *actor, Scriptable *cas return; } - level = spell->GetHeaderIndexFromLevel(level); - EffectQueue *fxqueue = spell->GetEffectBlock(caster, actor->Pos, level); + int header = spell->GetHeaderIndexFromLevel(level); + EffectQueue *fxqueue = spell->GetEffectBlock(caster, actor->Pos, header, level); ApplyEffectQueue(fxqueue, actor, caster, actor->Pos); delete fxqueue; @@ -4938,9 +4997,9 @@ void Interface::ApplySpellPoint(const ieResRef resname, Map* area, const Point & if (!spell) { return; } - level = spell->GetHeaderIndexFromLevel(level); - Projectile *pro = spell->GetProjectile(caster, level, pos); - pro->SetCaster(caster->GetGlobalID()); + int header = spell->GetHeaderIndexFromLevel(level); + Projectile *pro = spell->GetProjectile(caster, header, pos); + pro->SetCaster(caster->GetGlobalID(), level); area->AddProjectile(pro, caster->Pos, pos); } @@ -4982,7 +5041,7 @@ int Interface::ApplyEffectQueue(EffectQueue *fxqueue, Actor *actor, Scriptable * } fxqueue->SetOwner( caster ); - if (fxqueue->AddAllEffects( actor, p )==FX_NOT_APPLIED) { + if (fxqueue->AddAllEffects( actor, p)==FX_NOT_APPLIED) { res=0; } } @@ -5322,7 +5381,7 @@ int Interface::Autopause(ieDword flag) return 0; } -void Interface::RegisterOpcodes(int count, const EffectRef *opcodes) +void Interface::RegisterOpcodes(int count, const EffectDesc *opcodes) { EffectQueue_RegisterOpcodes(count, opcodes); } diff --git a/project/jni/application/gemrb/gemrb/core/Interface.h b/project/jni/application/gemrb/gemrb/core/Interface.h index 06eb11b9b..2e6180174 100644 --- a/project/jni/application/gemrb/gemrb/core/Interface.h +++ b/project/jni/application/gemrb/gemrb/core/Interface.h @@ -61,7 +61,7 @@ class Control; class DataFileMgr; struct Effect; class EffectQueue; -struct EffectRef; +struct EffectDesc; class EventMgr; class Factory; class Font; @@ -201,6 +201,8 @@ public: #define EF_OPENSTORE 256 //open store window #define EF_EXPANSION 512 //upgrade game request #define EF_CREATEMAZE 1024 //call the maze generator +#define EF_RESETTARGET 2048 //reset the mouse cursor +#define EF_TARGETMODE 4096 //update the mouse cursor //autopause #define AP_UNUSABLE 0 @@ -493,15 +495,7 @@ public: /** returns true if in cutscene mode */ bool InCutSceneMode() const; /** Updates the Game Script Engine State */ - void GSUpdate(bool update_scripts) - { - if(update_scripts) { - timer->Update(); - } - else { - timer->Freeze(); - } - } + bool GSUpdate(bool update_scripts); /** Get the Party INI Interpreter */ DataFileMgr * GetPartyINI() const { @@ -586,6 +580,7 @@ public: int GetDraggedPortrait() const { return DraggedPortrait; } void SetDraggedPortrait(int dp, int cursor=-1); CREItem *ReadItem(DataStream *str); + CREItem *ReadItem(DataStream *str, CREItem *itm); bool ResolveRandomItem(CREItem *itm); ieStrRef GetRumour(const ieResRef resname); Container *GetCurrentContainer(); @@ -653,7 +648,7 @@ public: /** receives an autopause reason, returns 1 if pause was triggered by this call, -1 if it was already triggered */ int Autopause(ieDword reason); /** registers engine opcodes */ - void RegisterOpcodes(int count, const EffectRef *opcodes); + void RegisterOpcodes(int count, const EffectDesc *opcodes); /** reads a list of resrefs into an array, returns array size */ int ReadResRefTable(const ieResRef tablename, ieResRef *&data); /** frees the data */ @@ -686,8 +681,8 @@ public: static const char *GetDeathVarFormat(); int CheckSpecialSpell(ieResRef resref, Actor *actor); int GetSpecialSpell(ieResRef resref); - int GetSpecialSpellsCount() { return SpecialSpellsCount; }; - SpellDescType *GetSpecialSpells() { return SpecialSpells; }; + int GetSpecialSpellsCount() { return SpecialSpellsCount; } + SpellDescType *GetSpecialSpells() { return SpecialSpells; } private: int LoadSprites(); bool LoadConfig(void); @@ -748,6 +743,7 @@ public: std::vector ModPath; int Width, Height, Bpp, ForceStereo; unsigned int TooltipDelay; + int IgnoreOriginalINI; unsigned int FogOfWar; bool CaseSensitive, GameOnCD, SkipIntroVideos, DrawFPS; bool GUIEnhancements; diff --git a/project/jni/application/gemrb/gemrb/core/Inventory.cpp b/project/jni/application/gemrb/gemrb/core/Inventory.cpp index 1dcc638c6..087943737 100644 --- a/project/jni/application/gemrb/gemrb/core/Inventory.cpp +++ b/project/jni/application/gemrb/gemrb/core/Inventory.cpp @@ -892,6 +892,26 @@ bool Inventory::DropItemAtLocation(const char *resref, unsigned int flags, Map * if (resref[0]) break; } + + //dropping gold too + if (!resref[0]) { + if (Owner->Type==ST_ACTOR) { + Actor *act = (Actor *) Owner; + if (! act->BaseStats[IE_GOLD]) { + return dropped; + } + CREItem *gold = new CREItem(); + + gold->Expired=0; + gold->Flags=0; + gold->Usages[1]=0; + gold->Usages[2]=0; + memcpy(gold->ItemResRef, core->GoldResRef, sizeof(ieResRef) ); + gold->Usages[0] = act->BaseStats[IE_GOLD]; + act->BaseStats[IE_GOLD] = 0; + map->AddItemToLocation(loc, gold); + } + } return dropped; } diff --git a/project/jni/application/gemrb/gemrb/core/Item.cpp b/project/jni/application/gemrb/gemrb/core/Item.cpp index 86e32f7e4..0c9eed485 100644 --- a/project/jni/application/gemrb/gemrb/core/Item.cpp +++ b/project/jni/application/gemrb/gemrb/core/Item.cpp @@ -74,6 +74,7 @@ EffectQueue *Item::GetEffectBlock(Scriptable *self, const Point &pos, int usage, for (int i=0;iInventorySlot = invslot; + fx->CasterLevel = ITEM_CASTERLEVEL; //items all have casterlevel 10 if (usage >= 0) { //this is not coming from the item header, but from the recharge flags fx->SourceFlags = ext_headers[usage].RechargeFlags; @@ -219,7 +220,7 @@ Projectile *Item::GetProjectile(Scriptable *self, int header, const Point &targe } //this is the implementation of the weapon glow effect in PST -static EffectRef glow_ref ={"Color:PulseRGB",NULL,-1}; +static EffectRef glow_ref = { "Color:PulseRGB", -1 }; //this type of colour uses PAL32, a PST specific palette #define PALSIZE 32 static Color ActorColor[PALSIZE]; diff --git a/project/jni/application/gemrb/gemrb/core/Item.h b/project/jni/application/gemrb/gemrb/core/Item.h index f26754503..d3952689d 100644 --- a/project/jni/application/gemrb/gemrb/core/Item.h +++ b/project/jni/application/gemrb/gemrb/core/Item.h @@ -99,6 +99,8 @@ class Projectile; #define CHG_NOSOUND 2 #define CHG_DAY 3 +//items caster level is hardcoded to 10 +#define ITEM_CASTERLEVEL 10 /** * @class ITMExtHeader * Header for special effects and uses of an Item. diff --git a/project/jni/application/gemrb/gemrb/core/Makefile.am b/project/jni/application/gemrb/gemrb/core/Makefile.am index 0b91d67df..26bea7942 100644 --- a/project/jni/application/gemrb/gemrb/core/Makefile.am +++ b/project/jni/application/gemrb/gemrb/core/Makefile.am @@ -83,7 +83,10 @@ libgemrb_core_la_SOURCES = \ SaveGameMgr.cpp \ ScriptEngine.cpp \ Scriptable/Actor.cpp \ - Scriptable/ActorBlock.cpp \ + Scriptable/Container.cpp \ + Scriptable/Door.cpp \ + Scriptable/InfoPoint.cpp \ + Scriptable/Scriptable.cpp \ Scriptable/PCStatStruct.cpp \ ScriptedAnimation.cpp \ SoundMgr.cpp \ diff --git a/project/jni/application/gemrb/gemrb/core/Map.cpp b/project/jni/application/gemrb/gemrb/core/Map.cpp index 45e1dc9e8..f89036c80 100644 --- a/project/jni/application/gemrb/gemrb/core/Map.cpp +++ b/project/jni/application/gemrb/gemrb/core/Map.cpp @@ -33,6 +33,7 @@ #include "Interface.h" #include "MapMgr.h" #include "MusicMgr.h" +#include "ImageMgr.h" #include "Palette.h" #include "Particles.h" #include "PathFinder.h" @@ -44,6 +45,9 @@ #include "strrefs.h" #include "GameScript/GSUtils.h" #include "GUI/GameControl.h" +#include "Scriptable/Container.h" +#include "Scriptable/Door.h" +#include "Scriptable/InfoPoint.h" #include #include @@ -103,7 +107,8 @@ inline static AnimationObjectType SelectObject(Actor *actor, int q, AreaAnimatio int aah; if (a) { - aah = a->Pos.y;//+a->height; + //aah = a->Pos.y;//+a->height; + aah = a->GetHeight(); } else { aah = 0x7fffffff; } @@ -227,8 +232,8 @@ void InitPathFinder() void AddLOS(int destx, int desty, int slot) { for (int i=0;iGetGame()->MasterArea(scriptName); + Background = NULL; + BgDuration = 0; } Map::~Map(void) @@ -432,6 +439,9 @@ void Map::AddTileMap(TileMap* tm, Image* lm, Bitmap* sr, Sprite2D* sm, Bitmap* h SrchMap[y*Width+x] = Passable[sr->GetAt(x,y)&PATH_MAP_AREAMASK]; } } + + //delete the original searchmap + delete sr; } void Map::MoveToNewArea(const char *area, const char *entrance, unsigned int direction, int EveryOne, Actor *actor) @@ -621,8 +631,9 @@ void Map::UpdateScripts() // possibly wrong (so if you have problems, revert this and find // another way) if (has_pcs) { - //Run the Map Script - ExecuteScript( 1 ); + //Run all the Map Scripts (as in the original) + //The default area script is in the last slot anyway + ExecuteScript( MAX_SCRIPTS ); } //Execute Pending Actions @@ -660,8 +671,9 @@ void Map::UpdateScripts() actor->fxqueue.Cleanup(); //if the actor is immobile, don't run the scripts + //FIXME: this is not universaly true, only some states have this effect if (!game->StateOverrideFlag && !game->StateOverrideTime) { - if (actor->Immobile() || actor->GetStat(IE_STATE_ID) & STATE_SLEEP) { + if (/*actor->Immobile() ||*/ actor->GetStat(IE_STATE_ID) & STATE_SLEEP) { actor->no_more_steps = true; continue; } @@ -781,17 +793,15 @@ void Map::UpdateScripts() if (!ip) break; //If this InfoPoint has no script and it is not a Travel Trigger, skip it - bool wasActive = (ip->Scripts[0] || ( ip->Type == ST_TRAVEL )); // InfoPoints of all types don't run scripts if TRAP_DEACTIVATED is set // (eg, TriggerActivation changes this, see lightning room from SoA) - if (wasActive) - wasActive = !(ip->Flags&TRAP_DEACTIVATED); + int wasActive = (!(ip->Flags&TRAP_DEACTIVATED) ) || (ip->Type==ST_TRAVEL); //If this InfoPoint is a Switch Trigger if (ip->Type == ST_TRIGGER) { //Check if this InfoPoint was activated if (ip->LastTrigger) { - if (wasActive) { + if (wasActive && ip->Scripts[0]) { //Run the InfoPoint script ip->ExecuteScript( 1 ); } @@ -814,6 +824,7 @@ void Map::UpdateScripts() if(ip->Entered(actor)) { //if trap triggered, then mark actor actor->SetInTrap(ipCount); + wasActive|=TRAP_USEPOINT; } } else { //ST_TRAVEL @@ -834,6 +845,10 @@ 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); + } } //Execute Pending Actions ip->ProcessActions(false); @@ -877,7 +892,7 @@ bool Map::DoStepForActor(Actor *actor, int speed, ieDword time) { } void Map::ClearSearchMapFor( Movable *actor ) { - Actor** nearActors = GetAllActorsInRadius(actor->Pos, GA_NO_DEAD, MAX_CIRCLE_SIZE*2*16); + Actor** nearActors = GetAllActorsInRadius(actor->Pos, GA_NO_DEAD|GA_NO_LOS, MAX_CIRCLE_SIZE*2*16); BlockSearchMap( actor->Pos, actor->size, PATH_MAP_FREE); // Restore the searchmap areas of any nearby actors that could @@ -1040,20 +1055,33 @@ void Map::DrawMap(Region screen) INISpawn->CheckSpawn(); } - int rain; - if (HasWeather()) { - //zero when the weather particles are all gone - rain = game->weather->GetPhase()-P_EMPTY; - } else { - rain = 0; - } - TMap->DrawOverlays( screen, rain ); - //Blit the Background Map Animations (before actors) Video* video = core->GetVideoDriver(); + int bgoverride = false; - //Draw Outlines - DrawHighlightables( screen ); + if (Background) { + if (BgDurationFreeSprite(Background); + } else { + video->BlitSprite(Background,0,0,true); + bgoverride = true; + } + } + + if (!bgoverride) { + int rain; + if (HasWeather()) { + //zero when the weather particles are all gone + rain = game->weather->GetPhase()-P_EMPTY; + } else { + rain = 0; + } + + TMap->DrawOverlays( screen, rain ); + + //Draw Outlines + DrawHighlightables( screen ); + } Region vp = video->GetViewport(); //if it is only here, then the scripting will fail? @@ -1224,23 +1252,20 @@ void Map::DrawSearchMap(const Region &screen) } //adding animation in order, based on its height parameter -void Map::AddAnimation(AreaAnimation* anim) +void Map::AddAnimation(AreaAnimation* panim) { - //this hack is to make sure animations flagged with background - //are always drawn first (-9999 seems sufficiently small) - if (anim->Flags&A_ANI_BACKGROUND) { - anim->height=-9999; - } + //copy external memory to core memory for msvc's sake + AreaAnimation *anim = new AreaAnimation(); + memcpy(anim, panim, sizeof(AreaAnimation) ); + + anim->InitAnimation(); aniIterator iter; - for(iter=animations.begin(); (iter!=animations.end()) && ((*iter)->heightheight); iter++) ; - animations.insert(iter, anim); - /* - Animation *a = anim->animation[0]; - anim->SetSpriteCover(BuildSpriteCover(anim->Pos.x, anim->Pos.y,-a->animArea.x, - -a->animArea.y, a->animArea.w, a->animArea.h,0 - )); - */ + + 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()Schedule(gametime, true) ) { continue; } + if (!(flags&GA_NO_LOS)) { + if (!IsVisible(actor->Pos, p)) { + continue; + } + } count++; } @@ -1517,6 +1548,12 @@ Actor **Map::GetAllActorsInRadius(const Point &p, int flags, unsigned int radius if (!actor->Schedule(gametime, true) ) { continue; } + if (!(flags&GA_NO_LOS)) { + if (!IsVisible(actor->Pos, p)) { + continue; + } + } + ret[j++]=actor; } @@ -1729,7 +1766,7 @@ unsigned int Map::GetBlocked(unsigned int x, unsigned int y) return 0; } unsigned int ret = SrchMap[y*Width+x]; - if (ret&(PATH_MAP_DOOR_TRANSPARENT|PATH_MAP_ACTOR)) { + if (ret&(PATH_MAP_DOOR_IMPASSABLE|PATH_MAP_ACTOR)) { ret&=~PATH_MAP_PASSABLE; } if (ret&PATH_MAP_DOOR_OPAQUE) { @@ -2083,7 +2120,18 @@ bool Map::CanFree() void Map::DebugDump(bool show_actors) const { + size_t i; + printf( "DebugDump of Area %s:\n", scriptName ); + printf ("Scripts:"); + + for (i = 0; i < MAX_SCRIPTS; i++) { + const char* poi = ""; + if (Scripts[i]) { + poi = Scripts[i]->GetName(); + } + printf( " %.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 ) ); @@ -2094,7 +2142,7 @@ void Map::DebugDump(bool show_actors) const if (show_actors) { printf("\n"); - size_t i = actors.size(); + 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); @@ -2981,7 +3029,7 @@ void Map::SetMapVisibility(int setreset) memset( VisibleBitmap, setreset, GetExploredMapSize() ); } -// x, y are in tile coordinates +// x, y are not in tile coordinates void Map::ExploreTile(const Point &pos) { int h = TMap->YCellCount * 2 + LargeFog; @@ -3302,10 +3350,14 @@ void Map::FadeSparkle(const Point &pos, bool forced) } } -void Map::Sparkle(ieDword duration, ieDword color, ieDword type, const Point &pos, unsigned int FragAnimID) +void Map::Sparkle(ieDword duration, ieDword color, ieDword type, const Point &pos, unsigned int FragAnimID, int Zpos) { int style, path, grow, size, width, ttl; + if (!Zpos) { + Zpos = 30; + } + //the high word is ignored in the original engine (compatibility hack) switch(type&0xffff) { case SPARKLE_SHOWER: //simple falling sparks @@ -3320,14 +3372,14 @@ void Map::Sparkle(ieDword duration, ieDword color, ieDword type, const Point &po grow = SP_SPAWN_SOME; size = 40; width = 40; - ttl = core->GetGame()->GameTime+25; + ttl = core->GetGame()->GameTime+Zpos; break; case SPARKLE_EXPLOSION: //this isn't in the original engine, but it is a nice effect to have path = SP_PATH_EXPL; grow = SP_SPAWN_SOME; - size = 40; + size = 10; width = 40; - ttl = core->GetGame()->GameTime+25; + ttl = core->GetGame()->GameTime+Zpos; break; default: path = SP_PATH_FLIT; @@ -3339,7 +3391,7 @@ void Map::Sparkle(ieDword duration, ieDword color, ieDword type, const Point &po } Particles *sparkles = new Particles(size); sparkles->SetOwner(this); - sparkles->SetRegion(pos.x-width/2, pos.y-30, width, 30); + sparkles->SetRegion(pos.x-width/2, pos.y-Zpos, width, Zpos); sparkles->SetTimeToLive(ttl); if (FragAnimID) { @@ -3528,7 +3580,7 @@ void AreaAnimation::BlendAnimation() palette->CreateShadedAlphaChannel(); } -bool AreaAnimation::Schedule(ieDword gametime) +bool AreaAnimation::Schedule(ieDword gametime) const { if (!(Flags&A_ANI_ACTIVE) ) { return false; @@ -3542,9 +3594,17 @@ bool AreaAnimation::Schedule(ieDword gametime) return false; } +int AreaAnimation::GetHeight() const +{ + if (Flags&A_ANI_BACKGROUND) return -9999; + return Pos.y+height; + //FIXME: this is obviously a hack that is destined to crash, also useless, so + //See ar9101 in HoW and ar0602 in bg2 before committing anything + //return Pos.y+height-animation[0][0].GetFrame(0)->Height; +} + void AreaAnimation::Draw(const Region &screen, Map *area) { - int ac=animcount; Video* video = core->GetVideoDriver(); //always draw the animation tinted because tint is also used for @@ -3559,7 +3619,8 @@ void AreaAnimation::Draw(const Region &screen, Map *area) covers=(SpriteCover **) calloc( animcount, sizeof(SpriteCover *) ); } } - ac=animcount; + + int ac = animcount; while (ac--) { Animation *anim = animation[ac]; Sprite2D *frame = anim->NextFrame(); @@ -3629,3 +3690,15 @@ void Map::SetInternalSearchMap(int x, int y, int value) { } SrchMap[x+y*Width] = value; } + +void Map::SetBackground(const ieResRef &bgResRef, ieDword duration) { + Video* video = core->GetVideoDriver(); + + ResourceHolder bmp(bgResRef); + + if (Background) { + video->FreeSprite(Background); + } + Background = bmp->GetSprite2D(); + BgDuration = duration; +} diff --git a/project/jni/application/gemrb/gemrb/core/Map.h b/project/jni/application/gemrb/gemrb/core/Map.h index bf9cce508..7e830c6f0 100644 --- a/project/jni/application/gemrb/gemrb/core/Map.h +++ b/project/jni/application/gemrb/gemrb/core/Map.h @@ -30,7 +30,7 @@ class Map; #include "Image.h" #include "IniSpawn.h" #include "SpriteCover.h" -#include "Scriptable/ActorBlock.h" +#include "Scriptable/Scriptable.h" #include @@ -153,8 +153,8 @@ public: class TerrainSounds { public: - ieResRef Group; - ieResRef Sounds[16]; + ieResRef Group; + ieResRef Sounds[16]; }; class SpawnGroup { @@ -204,8 +204,9 @@ public: void InitAnimation(); void SetPalette(ieResRef PaletteRef); void BlendAnimation(); - bool Schedule(ieDword gametime); + bool Schedule(ieDword gametime) const; void Draw(const Region &screen, Map *area); + int GetHeight() const; private: Animation *GetAnimationPiece(AnimationFactory *af, int animCycle); }; @@ -244,12 +245,15 @@ public: bool DayNight; //movies for day/night (only in ToB) ieResRef Dream[2]; + Sprite2D *Background; + ieDword BgDuration; + private: ieStrRef trackString; int trackFlag; ieWord trackDiff; unsigned short* MapSet; - unsigned short* SrchMap; //internal searchmap + unsigned short* SrchMap; //internal searchmap std::queue< unsigned int> InternalStack; unsigned int Width, Height; std::list< AreaAnimation*> animations; @@ -373,7 +377,7 @@ public: //adds a sparkle puff of colour to a point in the area //FragAnimID is an optional avatar animation ID (see avatars.2da) for //fragment animation - void Sparkle(ieDword duration, ieDword color, ieDword type, const Point &pos, unsigned int FragAnimID = 0); + void Sparkle(ieDword duration, ieDword color, ieDword type, const Point &pos, unsigned int FragAnimID = 0, int Zpos = 0); //removes or fades the sparkle puff at a point void FadeSparkle(const Point &pos, bool forced); @@ -470,6 +474,7 @@ public: unsigned int GetLightLevel(const Point &Pos); unsigned short GetInternalSearchMap(int x, int y); void SetInternalSearchMap(int x, int y, int value); + void SetBackground(const ieResRef &bgResref, ieDword duration); private: AreaAnimation *GetNextAreaAnimation(aniIterator &iter, ieDword gametime); Particles *GetNextSpark(spaIterator &iter); diff --git a/project/jni/application/gemrb/gemrb/core/MapMgr.h b/project/jni/application/gemrb/gemrb/core/MapMgr.h index b6142405e..c709e707f 100644 --- a/project/jni/application/gemrb/gemrb/core/MapMgr.h +++ b/project/jni/application/gemrb/gemrb/core/MapMgr.h @@ -29,7 +29,7 @@ #include "Map.h" #include "Plugin.h" -#include "Scriptable/ActorBlock.h" +#include "Scriptable/Scriptable.h" #include "System/DataStream.h" /** diff --git a/project/jni/application/gemrb/gemrb/core/Palette.h b/project/jni/application/gemrb/gemrb/core/Palette.h index 14d53bb2c..ba857d173 100644 --- a/project/jni/application/gemrb/gemrb/core/Palette.h +++ b/project/jni/application/gemrb/gemrb/core/Palette.h @@ -67,6 +67,8 @@ public: Color col[256]; //< RGB or RGBA 8 bit palette bool alpha; //< true if this is a RGBA palette bool named; //< true if the palette comes from a bmp and cached + Color front; // Original colors used by core->CreatePalette() + Color back; void IncRef() { refcount++; diff --git a/project/jni/application/gemrb/gemrb/core/Particles.cpp b/project/jni/application/gemrb/gemrb/core/Particles.cpp index 0fcbbeb31..ce3195fbe 100644 --- a/project/jni/application/gemrb/gemrb/core/Particles.cpp +++ b/project/jni/application/gemrb/gemrb/core/Particles.cpp @@ -331,7 +331,7 @@ int Particles::Update() continue; } drawn=true; - if (!points[i].state) { + if (!points[i].state) { grow++; } points[i].state--; diff --git a/project/jni/application/gemrb/gemrb/core/PathFinder.h b/project/jni/application/gemrb/gemrb/core/PathFinder.h index 3b1d22483..b8b6ca7af 100644 --- a/project/jni/application/gemrb/gemrb/core/PathFinder.h +++ b/project/jni/application/gemrb/gemrb/core/PathFinder.h @@ -31,11 +31,11 @@ enum { PATH_MAP_AREAMASK = 15, PATH_MAP_FREE = 0, PATH_MAP_DOOR_OPAQUE = 16, - PATH_MAP_DOOR_TRANSPARENT = 32, + PATH_MAP_DOOR_IMPASSABLE = 32, PATH_MAP_PC = 64, PATH_MAP_NPC = 128, PATH_MAP_ACTOR = (PATH_MAP_PC|PATH_MAP_NPC), - PATH_MAP_DOOR = (PATH_MAP_DOOR_OPAQUE|PATH_MAP_DOOR_TRANSPARENT), + PATH_MAP_DOOR = (PATH_MAP_DOOR_OPAQUE|PATH_MAP_DOOR_IMPASSABLE), PATH_MAP_NOTAREA = (PATH_MAP_ACTOR|PATH_MAP_DOOR), PATH_MAP_NOTDOOR = (PATH_MAP_ACTOR|PATH_MAP_AREAMASK), PATH_MAP_NOTACTOR = (PATH_MAP_DOOR|PATH_MAP_AREAMASK) diff --git a/project/jni/application/gemrb/gemrb/core/Projectile.cpp b/project/jni/application/gemrb/gemrb/core/Projectile.cpp index 576ec5f3d..b63f075d8 100644 --- a/project/jni/application/gemrb/gemrb/core/Projectile.cpp +++ b/project/jni/application/gemrb/gemrb/core/Projectile.cpp @@ -34,11 +34,14 @@ #include //to get gradient color -#define PALSIZE 12 +//apparently pst doesn't have the small palette correctly +#define PALSIZE 32 static const ieByte SixteenToNine[MAX_ORIENT]={0,1,2,3,4,5,6,7,8,7,6,5,4,3,2,1}; static const ieByte SixteenToFive[MAX_ORIENT]={0,1,2,3,4,3,2,1,0,1,2,3,4,3,2,1}; +static ProjectileServer *server = NULL; + Projectile::Projectile() { autofree = false; @@ -62,6 +65,13 @@ Projectile::Projectile() memset(smokebam, 0, sizeof(smokebam)); light = NULL; pathcounter = 0x7fff; + FakeTarget = 0; + bend = 0; + drawSpark = 0; + ZPos = 0; + extension_delay = 0; + if (!server) + server = core->GetProjectileServer(); } Projectile::~Projectile() @@ -77,8 +87,8 @@ Projectile::~Projectile() ClearPath(); if (travel_handle) { - travel_handle->Stop(); - travel_handle.release(); + //allow an explosion sound to finish completely + travel_handle->StopLooping(); } if (phase != P_UNINITED) { @@ -253,10 +263,13 @@ void Projectile::SetBlend() //create another projectile with type-1 (iterate magic missiles and call lightning) void Projectile::CreateIteration() { - ProjectileServer *server = core->GetProjectileServer(); Projectile *pro = server->GetProjectileByIndex(type-1); pro->SetEffectsCopy(effects); - pro->SetCaster(Caster); + pro->SetCaster(Caster, Level); + if (ExtFlags&PEF_CURVE) { + pro->bend=bend+1; + } + if (FakeTarget) { area->AddProjectile(pro, Pos, FakeTarget, true); } else { @@ -302,15 +315,19 @@ void Projectile::Setup() } } - if(Shake) { - core->timer->SetScreenShake( Shake, Shake, Shake); - } - + //falling = vertical + //incoming = right side + //both = left side if(ExtFlags&(PEF_FALLING|PEF_INCOMING) ) { - if (ExtFlags&PEF_FALLING) { + if (ExtFlags&PEF_INCOMING) { + if (ExtFlags&PEF_FALLING) { + Pos.x=Destination.x-200; + } else { + Pos.x=Destination.x+200; + } + } + else { Pos.x=Destination.x; - } else { - Pos.x=Destination.x+200; } Pos.y=Destination.y-200; NextTarget(Destination); @@ -324,6 +341,7 @@ void Projectile::Setup() //but also makes the caster immune to the effect if (Extension) { if (Extension->AFlags&PAF_CONE) { + NewOrientation = Orientation = GetOrient(Destination, Pos); Destination=Pos; ExtFlags|=PEF_NO_TRAVEL; } @@ -366,13 +384,16 @@ void Projectile::Setup() if(ExtFlags&PEF_POP) { //the explosion consists of a pop in/hold/pop out of the travel projectile (dimension door) if(travel[0] && shadow[0]) { - SetDelay(travel[0]->GetFrameCount()*2+shadow[0]->GetFrameCount() ); + extension_delay = travel[0]->GetFrameCount()*2+shadow[0]->GetFrameCount(); + //SetDelay( travel[0]->GetFrameCount()*2+shadow[0]->GetFrameCount()); travel[0]->Flags|=A_ANI_PLAYONCE; shadow[0]->Flags|=A_ANI_PLAYONCE; } } else { if(travel[0]) { - SetDelay(travel[0]->GetFrameCount() ); + extension_delay = travel[0]->GetFrameCount(); + travel[0]->Flags|=A_ANI_PLAYONCE; + //SetDelay(travel[0]->GetFrameCount() ); } } } @@ -390,6 +411,9 @@ void Projectile::Setup() if (TFlags&PTF_BLEND) { SetBlend(); } + if (SFlags&PSF_FLYING) { + ZPos = FLY_HEIGHT; + } phase = P_TRAVEL; travel_handle = core->GetAudioDrv()->Play(SoundRes1, Pos.x, Pos.y, (SFlags & PSF_LOOPING ? GEM_SND_LOOPING : 0)); @@ -436,11 +460,79 @@ void Projectile::SetDelay(int delay) ExtFlags|=PEF_FREEZE; } +//copied from Actor.cpp +#define ATTACKROLL 20 +#define WEAPON_FIST 0 + +bool Projectile::FailedIDS(Actor *target) const +{ + bool fail = !EffectQueue::match_ids( target, IDSType, IDSValue); + if (ExtFlags&PEF_NOTIDS) { + fail = !fail; + } + if (ExtFlags&PEF_BOTH) { + if (!fail) { + fail = !EffectQueue::match_ids( target, IDSType2, IDSValue2); + if (ExtFlags&PEF_NOTIDS2) { + fail = !fail; + } + } + } + else + { + if (fail && IDSType2) { + fail = !EffectQueue::match_ids( target, IDSType2, IDSValue2); + if (ExtFlags&PEF_NOTIDS2) { + fail = !fail; + } + } + } + + if (!fail) { + if(ExtFlags&PEF_TOUCH) { + Actor *caster = core->GetGame()->GetActorByGlobalID(Caster); + if (caster) { + //TODO move this to Actor + //TODO some projectiles use melee attack (fist), others use projectile attack + //this apparently depends on the spell's spell form (normal vs. projectile) + int roll = caster->LuckyRoll(1, ATTACKROLL, 0); + if (roll==1) { + return true; //critical failure + } + + if (!(target->GetStat(IE_STATE_ID)&STATE_CRIT_PROT)) { + if (roll >= (ATTACKROLL - (int) caster->GetStat(IE_CRITICALHITBONUS))) { + return false; //critical success + } + } + + //handle attack type here, weapon depends on it too? + int tohit = caster->GetToHit(0, WEAPON_FIST, target); + //damage type, should be generic? + int defense = target->GetDefense(0, caster); + if(target->IsReverseToHit()) { + fail = roll + defense < tohit; + } else { + fail = tohit + roll < defense; + } + } + } + } + + return fail; +} + void Projectile::Payload() { Actor *target; - if(!effects) { + if(Shake) { + core->timer->SetScreenShake( Shake, Shake, Shake); + Shake = 0; + } + + //allow area affecting projectile with a spell + if(!(effects || (!Target && FailSpell[0]))) { return; } @@ -459,28 +551,77 @@ void Projectile::Payload() target = core->GetGame()->GetActorByGlobalID(FakeTarget); } } else { - target = area->GetActorByGlobalID(Caster); - + target = area->GetActorByGlobalID(Caster); } Actor *source = area->GetActorByGlobalID(Caster); - if (source) { - effects->SetOwner(source); - } else { - effects->SetOwner(target); + if (effects) { + if (source) { + effects->SetOwner(source); + } else { + effects->SetOwner(target); + } } } - if (target) { - if(ExtFlags&PEF_RGB) { - target->SetColorMod(0xff, RGBModifier::ADD, ColorSpeed, - RGB >> 8, RGB >> 16, RGB >> 24); - } - effects->AddAllEffects(target, Destination); + if (target) { + //apply this spell on target when the projectile fails + if (FailedIDS(target)) { + if (FailSpell[0]) { + if (Target) { + core->ApplySpell(FailSpell, target, effects->GetOwner(), Level); + } else { + //no Target, using the fake target as owner + core->ApplySpellPoint(FailSpell, area, Destination, target, Level); + } + } + } else { + //apply this spell on the target when the projectile succeeds + if (SuccSpell[0]) { + core->ApplySpell(SuccSpell, target, effects->GetOwner(), Level); + } + + if(ExtFlags&PEF_RGB) { + target->SetColorMod(0xff, RGBModifier::ADD, ColorSpeed, + RGB >> 8, RGB >> 16, RGB >> 24); + } + + effects->AddAllEffects(target, Destination); + } } + delete effects; effects = NULL; } +void Projectile::ApplyDefault() +{ + Actor *actor = area->GetActorByGlobalID(Caster); + if (actor) { + //name is the projectile's name + //for simplicity, we apply a spell of the same name + core->ApplySpell(name, actor, actor, Level); + } +} + +void Projectile::StopSound() +{ + if (travel_handle) { + travel_handle->Stop(); + travel_handle.release(); + } +} + +void Projectile::UpdateSound() +{ + if (!(SFlags&PSF_SOUND2)) { + StopSound(); + } + if (!travel_handle || !travel_handle->Playing()) { + travel_handle = core->GetAudioDrv()->Play(SoundRes2, Pos.x, Pos.y, (SFlags & PSF_LOOPING2 ? GEM_SND_LOOPING : 0)); + SFlags|=PSF_SOUND2; + } +} + //control the phase change when the projectile reached its target //possible actions: vanish, hover over point, explode //depends on the area extension @@ -494,25 +635,46 @@ void Projectile::ChangePhase() return; } } + + if (phase == P_TRAVEL) { + if ((ExtFlags&PEF_DELAY) && extension_delay) { + extension_delay--; + UpdateSound(); + return; + } + } + //reached target, and explodes now if (!Extension) { - if (travel_handle) { - travel_handle->Stop(); - travel_handle.release(); - } //there are no-effect projectiles, like missed arrows //Payload can redirect the projectile in case of projectile reflection - Payload(); + if (phase ==P_TRAVEL) { + if(ExtFlags&PEF_DEFSPELL) { + ApplyDefault(); + } + StopSound(); + Payload(); + phase = P_TRAVEL2; + } //freeze on target, this is recommended only for child projectiles //as the projectile won't go away on its own if(ExtFlags&PEF_FREEZE) { if(extension_delay) { if (extension_delay>0) { extension_delay--; + UpdateSound(); } return; } } + + if (phase == P_TRAVEL2) { + if (extension_delay) { + extension_delay--; + return; + } + } + if(ExtFlags&PEF_FADE) { TFlags &= ~PTF_TINT; //turn off area tint tint.a--; @@ -520,9 +682,6 @@ void Projectile::ChangePhase() return; } } - - phase = P_EXPIRED; - return; } EndTravel(); @@ -553,6 +712,8 @@ int Projectile::CalculateExplosionCount() void Projectile::EndTravel() { + StopSound(); + UpdateSound(); if(!Extension) { phase = P_EXPIRED; return; @@ -565,24 +726,23 @@ void Projectile::EndTravel() } else { phase = P_EXPLODING1; } - - if (travel_handle) { - travel_handle->Stop(); - travel_handle.release(); - } - - //this sound is not played for projectiles waiting for trigger - //it is probably also played when a travel projectile ends its mission - core->GetAudioDrv()->Play(SoundRes2, Pos.x, Pos.y); } -void Projectile::AddTrail(ieResRef BAM, const ieByte *pal) +int Projectile::AddTrail(ieResRef BAM, const ieByte *pal) { ScriptedAnimation *sca=gamedata->GetScriptedAnimation(BAM,0); - if (!sca) return; + if (!sca) return 0; if(pal) { - for(int i=0;i<7;i++) { - sca->SetPalette(pal[i], 4+i*PALSIZE); + if (ExtFlags & PEF_TINT) { + Color tmpColor[PALSIZE]; + + core->GetPalette( pal[0], PALSIZE, tmpColor ); + sca->Tint = tmpColor[PALSIZE/2]; + sca->Transparency |= BLIT_TINTED; + } else { + for(int i=0;i<7;i++) { + sca->SetPalette(pal[i], 4+i*PALSIZE); + } } } sca->SetOrientation(Orientation); @@ -591,6 +751,7 @@ void Projectile::AddTrail(ieResRef BAM, const ieByte *pal) sca->XPos += Pos.x; sca->YPos += Pos.y; area->AddVVCell(sca); + return sca->GetSequenceDuration(AI_UPDATE_TIME); } void Projectile::DoStep(unsigned int walk_speed) @@ -601,6 +762,15 @@ void Projectile::DoStep(unsigned int walk_speed) ClearPath(); } + //intro trailing, drawn only once at the beginning + if (pathcounter==0x7ffe) { + for(int i=0;i<3;i++) { + if(!TrailSpeed[i] && TrailBAM[i][0]) { + extension_delay = AddTrail(TrailBAM[i], (ExtFlags&PEF_TINT)?Gradients:NULL); + } + } + } + if (!path) { ChangePhase(); return; @@ -621,7 +791,7 @@ void Projectile::DoStep(unsigned int walk_speed) for(int i=0;i<3;i++) { if(TrailSpeed[i] && !(pathcounter%TrailSpeed[i])) { - AddTrail(TrailBAM[i], 0); + AddTrail(TrailBAM[i], (ExtFlags&PEF_TINT)?Gradients:NULL); } } @@ -672,6 +842,11 @@ void Projectile::DoStep(unsigned int walk_speed) if (!walk_speed) { return; } + + if (SFlags&PSF_SPARKS) { + drawSpark = 1; + } + if (step->Next->x > step->x) Pos.x += ( unsigned short ) ( ( step->Next->x - Pos.x ) * ( time - timeStartStep ) / walk_speed ); @@ -684,11 +859,13 @@ void Projectile::DoStep(unsigned int walk_speed) else Pos.y -= ( unsigned short ) ( ( Pos.y - step->Next->y ) * ( time - timeStartStep ) / walk_speed ); + } -void Projectile::SetCaster(ieDword caster) +void Projectile::SetCaster(ieDword caster, int level) { Caster=caster; + Level=level; } ieDword Projectile::GetCaster() const @@ -785,6 +962,10 @@ int Projectile::CalculateTargetFlag() //if there are any, then change phase to exploding int flags = GA_NO_DEAD; + if (Extension->AFlags&PAF_NO_WALL) { + flags|=GA_NO_LOS; + } + //projectiles don't affect dead/inanimate normally if (Extension->AFlags&PAF_INANIMATE) { flags&=~GA_NO_DEAD; @@ -805,6 +986,11 @@ int Projectile::CalculateTargetFlag() return flags; } + //this is the only way to affect neutrals and enemies + if (Extension->APFlags&APF_INVERT_TARGET) { + flags^=(GA_NO_ALLY|GA_NO_ENEMY); + } + Actor *caster = area->GetActorByGlobalID(Caster); if (caster && ((Actor *) caster)->GetStat(IE_EA)APFlags&APF_SPELLFAIL); + //if the spell was already applied on explosion, ignore this + bool fail= !!(Extension->APFlags&APF_SPELLFAIL) && !(ExtFlags&PEF_DEFSPELL); int mindeg = 0; int maxdeg = 0; @@ -894,11 +1081,18 @@ void Projectile::SecondaryTarget() maxdeg=mindeg+Extension->ConeWidth; } - ProjectileServer *server = core->GetProjectileServer(); int radius = Extension->ExplosionRadius; Actor **actors = area->GetAllActorsInRadius(Pos, CalculateTargetFlag(), radius); Actor **poi=actors; + if (Extension->DiceCount) { + //precalculate the maximum affected target count in case of PAF_AFFECT_ONE + extension_targetcount = core->Roll(Extension->DiceCount, Extension->DiceSize, 0); + } else { + //this is the default case (for original engine) + extension_targetcount = 1; + } + while(*poi) { ieDword Target = (*poi)->GetGlobalID(); @@ -908,6 +1102,12 @@ void Projectile::SecondaryTarget() continue; } + //IDS targeting for area projectiles + if (FailedIDS(*poi)) { + poi++; + continue; + } + if (Extension->AFlags&PAF_CONE) { //cone never affects the caster if(Caster==Target) { @@ -938,19 +1138,37 @@ void Projectile::SecondaryTarget() continue; } } + Projectile *pro = server->GetProjectileByIndex(Extension->ExplProjIdx); pro->SetEffectsCopy(effects); - pro->SetCaster(Caster); + //copy the additional effects reference to the child projectile + //but only when there is a spell to copy + if (SuccSpell[0]) + memcpy(pro->SuccSpell, SuccSpell, sizeof(ieResRef) ); + pro->SetCaster(Caster, Level); + //this is needed to apply the success spell on the center point + pro->SetTarget(Pos); //TODO:actually some of the splash projectiles are a good example of faketarget //projectiles (that don't follow the target, but still hit) area->AddProjectile(pro, Pos, Target, false); + poi++; fail=false; //we already got one target affected in the AOE, this flag says - //that was enough + //that was enough (the GemRB extension can repeat this a random time (x d y) if(Extension->AFlags&PAF_AFFECT_ONE) { - break; + if (extension_targetcount<=0) { + break; + } + //if target counting is per HD and this target is an actor, use the xp level field + //otherwise count it as one + if ((Extension->APFlags&APF_COUNT_HD) && ((*poi)->Type==ST_ACTOR) ) { + Actor *actor = (Actor *) *poi; + extension_targetcount-= actor->GetXPLevel(true); + } else { + extension_targetcount--; + } } } free(actors); @@ -958,12 +1176,7 @@ void Projectile::SecondaryTarget() //In case of utter failure, apply a spell of the same name on the caster //this feature is used by SCHARGE, PRTL_OP and PRTL_CL in the HoW pack if(fail) { - Actor *actor = area->GetActorByGlobalID(Caster); - if (actor) { - //name is the projectile's name - //for simplicity, we apply a spell of the same name - core->ApplySpell(name, actor, actor, 0); - } + ApplyDefault(); } } @@ -987,7 +1200,7 @@ int Projectile::Update() SetTarget(Target, false); } - if (phase == P_TRAVEL) { + if (phase == P_TRAVEL || phase == P_TRAVEL2) { DoStep(Speed); } return 1; @@ -1002,14 +1215,19 @@ void Projectile::Draw(const Region &screen) //This extension flag is to enable the travel projectile at //trigger/explosion time if (Extension->AFlags&PAF_VISIBLE) { + //if (!Extension || (Extension->AFlags&PAF_VISIBLE)) { DrawTravel(screen); } + /* + if (!Extension) { + return; + }*/ CheckTrigger(Extension->TriggerRadius); if (phase == P_EXPLODING1 || phase == P_EXPLODING2) { DrawExplosion(screen); } break; - case P_TRAVEL: + case P_TRAVEL: case P_TRAVEL2: //There is no Extension for simple traveling projectiles! DrawTravel(screen); return; @@ -1049,6 +1267,22 @@ void Projectile::DrawExploded(const Region &screen) phase = P_EXPIRED; } +void Projectile::SpawnFragment(Point &dest) +{ + Projectile *pro = server->GetProjectileByIndex(Extension->FragProjIdx); + if (pro) { + if (Extension->AFlags&PAF_SECONDARY) { + pro->SetEffectsCopy(effects); + } + pro->SetCaster(Caster, Level); + if (pro->ExtFlags&PEF_RANDOM) { + dest.x+=core->Roll(1,Extension->TileX, -Extension->TileX/2); + dest.y+=core->Roll(1,Extension->TileY, -Extension->TileY/2); + } + area->AddProjectile(pro, dest, dest); + } +} + void Projectile::DrawExplosion(const Region &screen) { //This seems to be a needless safeguard @@ -1057,11 +1291,7 @@ void Projectile::DrawExplosion(const Region &screen) return; } - if (travel_handle) { - travel_handle->Stop(); - travel_handle.release(); - } - + StopSound(); DrawChildren(screen); int pause = core->IsFreezed(); @@ -1088,6 +1318,9 @@ void Projectile::DrawExplosion(const Region &screen) LineTarget(); } + int apflags = Extension->APFlags; + int aoeflags = Extension->AFlags; + //no idea what is PAF_SECONDARY //probably it is to alter some behaviour in the secondary //projectile generation @@ -1098,37 +1331,66 @@ void Projectile::DrawExplosion(const Region &screen) SecondaryTarget(); //draw fragment graphics animation at the explosion center - if (Extension->AFlags&PAF_FRAGMENT) { + if (aoeflags&PAF_FRAGMENT) { //there is a character animation in the center of the explosion //which will go towards the edges (flames, etc) //Extension->ExplColor fake color for single shades (blue,green,red flames) //Extension->FragAnimID the animation id for the character animation //This color is not used in the original game - area->Sparkle(0, Extension->ExplColor, SPARKLE_EXPLOSION, Pos, Extension->FragAnimID); + Point pos = Pos; + pos.x+=screen.x; + pos.y+=screen.y; + area->Sparkle(0, Extension->ExplColor, SPARKLE_EXPLOSION, pos, Extension->FragAnimID, GetZPos()); + } + + if(Shake) { + core->timer->SetScreenShake( Shake, Shake, Shake); + Shake = 0; } - ProjectileServer *server = core->GetProjectileServer(); //the center of the explosion could be another projectile played over the target + //warning: this projectile doesn't inherit any effects, so its payload function + //won't be doing anything (any effect of PAF_SECONDARY?) + if (Extension->FragProjIdx) { - Projectile *pro = server->GetProjectileByIndex(Extension->FragProjIdx); - if (pro) { - area->AddProjectile(pro, Pos, Pos); + if (apflags&APF_TILED) { + int i,j; + int radius = Extension->ExplosionRadius; + + for (i=-radius;iTileX) { + for(j=-radius;jTileY) { + if (i*i+j*jAPFlags; //draw it only once, at the time of explosion if (phase==P_EXPLODING1) { core->GetAudioDrv()->Play(Extension->SoundRes, Pos.x, Pos.y); //play VVC in center - if (Extension->AFlags&PAF_VVC) { + if (aoeflags&PAF_VVC) { ScriptedAnimation* vvc = gamedata->GetScriptedAnimation(Extension->VVCRes, false); if (vvc) { if (apflags & APF_VVCPAL) { - vvc->SetPalette(Extension->ExplColor); + //if the palette is used as tint (as opposed to clown colorset) tint the vvc + if (apflags & APF_TINT) { + Color tmpColor[PALSIZE]; + + core->GetPalette( Extension->ExplColor, PALSIZE, tmpColor ); + vvc->Tint = tmpColor[PALSIZE/2]; + vvc->Transparency |= BLIT_TINTED; + } else { + vvc->SetPalette(Extension->ExplColor); + } } //if the trail oriented, then the center is oriented too if (ExtFlags&PEF_TRAIL) { @@ -1163,7 +1425,7 @@ void Projectile::DrawExplosion(const Region &screen) } //zero cone width means single line area of effect - if((Extension->AFlags&PAF_CONE) && !Extension->ConeWidth) { + if((aoeflags&PAF_CONE) && !Extension->ConeWidth) { child_size = 1; } @@ -1197,7 +1459,7 @@ void Projectile::DrawExplosion(const Region &screen) } int max = 360; int add = 0; - if (Extension->AFlags&PAF_CONE) { + if (aoeflags&PAF_CONE) { max=Extension->ConeWidth; add=(Orientation*45-max)/2; } @@ -1266,7 +1528,7 @@ void Projectile::DrawExplosion(const Region &screen) } } -int Projectile::GetTravelPos(int face) +int Projectile::GetTravelPos(int face) const { if (travel[face]) { return travel[face]->GetCurrentFrame(); @@ -1274,7 +1536,7 @@ int Projectile::GetTravelPos(int face) return 0; } -int Projectile::GetShadowPos(int face) +int Projectile::GetShadowPos(int face) const { if (shadow[face]) { return shadow[face]->GetCurrentFrame(); @@ -1308,7 +1570,7 @@ void Projectile::SetupWall() void Projectile::DrawLine(const Region &screen, int face, ieDword flag) { - Video *video = core->GetVideoDriver(); + Video *video = core->GetVideoDriver(); PathNode *iter = path; Sprite2D *frame = travel[face]->NextFrame(); while(iter) { @@ -1355,12 +1617,7 @@ void Projectile::DrawTravel(const Region &screen) pos.x+=screen.x; pos.y+=screen.y; - if(ExtFlags&PEF_CURVE && phase == P_TRAVEL && Origin != Destination && type >= 68 && type <= 77) { - // TODO: we want projectile# (starting at 0) because the lower-level - // casts should be near the centre, so this is hard-coding the - // magic missile id.. - int id = type - 68; - + if(bend && phase == P_TRAVEL && Origin != Destination) { double total_distance = Distance(Origin, Destination); double travelled_distance = Distance(Origin, Pos); @@ -1371,14 +1628,12 @@ void Projectile::DrawTravel(const Region &screen) // input to sin(): 0 to pi gives us an arc double arc_angle = travelled * M_PI; - //printf("id %d, travelled %f, angle %f\n", id, travelled, arc_angle); - // calculate the distance between the arc and the current pos // (this could use travelled and a larger constant multiplier, // to make the arc size fixed rather than relative to the total // distance to travel) - double length_of_normal = travelled_distance * sin(arc_angle) * 0.3 * ((id / 2) + 1); - if (id % 2) length_of_normal = -length_of_normal; + double length_of_normal = travelled_distance * sin(arc_angle) * 0.3 * ((bend / 2) + 1); + if (bend % 2) length_of_normal = -length_of_normal; // adjust the to-be-rendered point by that distance double x_vector = (Destination.x - Origin.x) / total_distance, @@ -1426,9 +1681,7 @@ void Projectile::DrawTravel(const Region &screen) video->BlitGameSprite( frame, pos.x, pos.y, flag, tint, NULL, palette, &screen); } - if (SFlags&PSF_FLYING) { - pos.y-=FLY_HEIGHT; - } + pos.y-=GetZPos(); if (ExtFlags&PEF_PILLAR) { //draw all frames simultaneously on top of each other @@ -1446,9 +1699,16 @@ void Projectile::DrawTravel(const Region &screen) } } - if (SFlags&PSF_SPARKS) { - area->Sparkle(0,SparkColor,SPARKLE_EXPLOSION,pos); + if (drawSpark) { + area->Sparkle(0,SparkColor, SPARKLE_EXPLOSION, pos, 0, GetZPos() ); + drawSpark = 0; } + +} + +int Projectile::GetZPos() const +{ + return ZPos; } void Projectile::SetIdentifiers(const char *resref, ieWord id) diff --git a/project/jni/application/gemrb/gemrb/core/Projectile.h b/project/jni/application/gemrb/gemrb/core/Projectile.h index 5463dbbaf..16e899d13 100644 --- a/project/jni/application/gemrb/gemrb/core/Projectile.h +++ b/project/jni/application/gemrb/gemrb/core/Projectile.h @@ -45,17 +45,21 @@ //projectile phases #define P_UNINITED -1 #define P_TRAVEL 0 //projectile moves to target -#define P_TRIGGER 1 //projectile hovers over target, waits for trigger -#define P_EXPLODING1 2 //projectile explosion spreads -#define P_EXPLODING2 3 //projectile explosion repeats -#define P_EXPLODED 4 //projectile spread over area +#define P_TRAVEL2 1 //projectile hit target +#define P_TRIGGER 2 //projectile hovers over target, waits for trigger +#define P_EXPLODING1 3 //projectile explosion spreads +#define P_EXPLODING2 4 //projectile explosion repeats +#define P_EXPLODED 5 //projectile spread over area #define P_EXPIRED 99 //projectile scheduled for removal (existing parts are still drawn) //projectile spark flags #define PSF_SPARKS 1 #define PSF_FLYING 2 -#define PSF_LOOPING 4 //looping sound +#define PSF_LOOPING 4 //looping sound +#define PSF_LOOPING2 8 //looping second sound #define PSF_IGNORE_CENTER 16 +//gemrb specific internal flag +#define PSF_SOUND2 0x80000000//already started sound2 //projectile travel flags #define PTF_COLOUR 1 //fake colours @@ -68,6 +72,7 @@ //projectile extended travel flags (gemrb specific) #define PEF_BOUNCE 1 //bounce from walls (lightning bolt) #define PEF_CONTINUE 2 //continue as a travel projectile after trigger (lightning bolt) +//TODO: This can probably be replaced by an area projectile trigger (like skull trap, glyph) #define PEF_FREEZE 4 //stay around (ice dagger) #define PEF_NO_TRAVEL 8 //all instant projectiles (draw upon holy might, finger of death) #define PEF_TRAIL 16 //trail bams facing value uses the same field as the travel projectile (otherwise it defaults to 9) (shout in iwd) @@ -77,7 +82,7 @@ #define PEF_HALFTRANS 256 //half-transparency (holy might) #define PEF_TINT 512 //use palette gradient as tint #define PEF_ITERATION 1024 //create another projectile of type-1 (magic missiles) -#define PEF_TILED 2048 //tiled AOE (bg1 cone of cold/fire) +#define PEF_DEFSPELL 2048 //always apply the default spell on the caster #define PEF_FALLING 4096 //projectile falls down vertically (cow) #define PEF_INCOMING 8192 //projectile falls in on trajectory (comet) #define PEF_LINE 16384 //solid line between source and target (agannazar's scorcher) @@ -85,11 +90,17 @@ #define PEF_BACKGROUND 0x10000 //draw under target,overrides flying (dimension door) #define PEF_POP 0x20000 //draw travel bam, then shadow, then travel bam backwards #define PEF_UNPOP 0x40000 //draw shadow, then travel bam (this is an internal flag) -#define PEF_FADE 0x80000 //gradually fade on spot if used with PEF_FREEZE (ice dagger) +//TODO: The next flag is probably not needed, it is done by a separate area hit animation +#define PEF_FADE 0x80000 //gradually fade on spot if used with PEF_FREEZE (ice dagger) #define PEF_TEXT 0x100000//display text during setup #define PEF_WANDERING 0x200000//random movement (no real path) #define PEF_CYCLE 0x400000//random cycle #define PEF_RGB 0x800000//rgb pulse on hit +#define PEF_TOUCH 0x1000000//successful to hit roll needed +#define PEF_NOTIDS 0x2000000//negate IDS check +#define PEF_NOTIDS2 0x4000000//negate secondary IDS check +#define PEF_BOTH 0x8000000//both IDS check must succeed +#define PEF_DELAY 0x10000000//delay payload until travel projectile cycle ends //projectile area flags #define PAF_VISIBLE 1 //the travel projectile is visible until explosion @@ -110,7 +121,6 @@ #define PAF_DELAY 0x4000 // #define PAF_AFFECT_ONE 0x8000 // - //area projectile flags (in areapro.2da) //this functionality was hardcoded in the original engine, so the bit flags are //completely arbitrary (i assign them as need arises) @@ -132,6 +142,14 @@ #define APF_MORE 128 //apply spell on caster if failed to find target #define APF_SPELLFAIL 256 +//multiple directions +#define APF_MULTIDIR 512 +//target HD counting +#define APF_COUNT_HD 1024 +//target flag enemy ally switched +#define APF_INVERT_TARGET 2048 +//tiled AoE animation +#define APF_TILED 4096 struct ProjectileExtension { @@ -153,6 +171,11 @@ struct ProjectileExtension ieResRef Spread; //areapro.2da first resref ieResRef Secondary; //areapro.2da third resref ieResRef AreaSound; //areapro.2da second sound resource + //used for target or HD counting + ieWord DiceCount; + ieWord DiceSize; + ieWord TileX; + ieWord TileY; }; class GEM_EXPORT Projectile @@ -166,13 +189,19 @@ public: ieDword SFlags; ieResRef SoundRes1; ieResRef SoundRes2; - ieResRef SoundRes3; + ieResRef TravelVVC; ieDword SparkColor; ieDword ExtFlags; ieDword StrRef; ieDword RGB; ieWord ColorSpeed; ieWord Shake; + ieWord IDSType; + ieWord IDSValue; + ieWord IDSType2; + ieWord IDSValue2; + ieResRef FailSpell; + ieResRef SuccSpell; ////// gap ieDword TFlags; ieResRef BAMRes1; @@ -204,9 +233,11 @@ protected: //similar to normal actors Map *area; Point Pos; + int ZPos; Point Destination; Point Origin; ieDword Caster; //the globalID of the caster actor + int Level; //the caster's level ieDword Target; //the globalID of target actor ieDword FakeTarget; //a globalID for target that isn't followed int phase; @@ -216,6 +247,7 @@ protected: //these come from the extension area int extension_delay; int extension_explosioncount; + int extension_targetcount; Color tint; //special (not using char animations) @@ -226,10 +258,13 @@ protected: Projectile **children; int child_size; int pathcounter; + int bend; + int drawSpark; Holder travel_handle; public: - void SetCaster(ieDword t); + void SetCaster(ieDword t, int level); ieDword GetCaster() const; + bool FailedIDS(Actor *target) const; void SetTarget(ieDword t, bool fake); void SetTarget(const Point &p); bool PointInRadius(const Point &p) const; @@ -325,23 +360,37 @@ private: void GetPaletteCopy(Animation *anim[], Palette *&pal); void GetSmokeAnim(); void SetBlend(); + //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(); + //if there is an extension, convert to exploding or wait for trigger void EndTravel(); + //apply default spell + void ApplyDefault(); + //stops the current sound + void StopSound(); + //kickstarts the secondary sound + void UpdateSound(); + //reached end of single travel missile, explode or expire now void ChangePhase(); - void AddTrail(ieResRef BAM, const ieByte *pal); + //drop a BAM or VVC on the trail path, return the length of the animation + int AddTrail(ieResRef BAM, const ieByte *pal); void DoStep(unsigned int walk_speed); void LineTarget(); //line projectiles (walls, scorchers) void SecondaryTarget(); //area projectiles (circles, cones) void CheckTrigger(unsigned int radius); + //calculate target and destination points for a firewall void SetupWall(); void DrawLine(const Region &screen, int face, ieDword flag); void DrawTravel(const Region &screen); bool DrawChildren(const Region &screen); void DrawExplosion(const Region &screen); + void SpawnFragment(Point &pos); void DrawExploded(const Region &screen); - int GetTravelPos(int face); - int GetShadowPos(int face); + int GetTravelPos(int face) const; + int GetShadowPos(int face) const; void SetPos(int face, int frame1, int frame2); + inline int GetZPos() const; //logic to resolve target when single projectile hit destination int CalculateTargetFlag(); diff --git a/project/jni/application/gemrb/gemrb/core/ResourceManager.cpp b/project/jni/application/gemrb/gemrb/core/ResourceManager.cpp index ede2c7295..95c131e58 100644 --- a/project/jni/application/gemrb/gemrb/core/ResourceManager.cpp +++ b/project/jni/application/gemrb/gemrb/core/ResourceManager.cpp @@ -35,13 +35,23 @@ ResourceManager::~ResourceManager() { } -bool ResourceManager::AddSource(const char *path, const char *description, PluginID type) +bool ResourceManager::AddSource(const char *path, const char *description, PluginID type, int flags) { PluginHolder source(type); if (!source->Open(path, description)) { return false; } - searchPath.push_back(source); + + if (flags & RM_REPLACE_SAME_SOURCE) { + for (size_t i = 0; i < searchPath.size(); i++) { + if (!stricmp(description, searchPath[i]->GetDescription())) { + searchPath[i] = source; + break; + } + } + } else { + searchPath.push_back(source); + } return true; } diff --git a/project/jni/application/gemrb/gemrb/core/ResourceManager.h b/project/jni/application/gemrb/gemrb/core/ResourceManager.h index 7a5792664..7fcbe2d55 100644 --- a/project/jni/application/gemrb/gemrb/core/ResourceManager.h +++ b/project/jni/application/gemrb/gemrb/core/ResourceManager.h @@ -32,6 +32,8 @@ #include "ResourceSource.h" #endif +#define RM_REPLACE_SAME_SOURCE 1 + class DataStream; class Resource; class ResourceSource; @@ -49,7 +51,7 @@ public: * @param[in] description Description of the source. * @param[in] type Plugin type used for source. **/ - bool AddSource(const char *path, const char *description, PluginID type); + bool AddSource(const char *path, const char *description, PluginID type, int flags=0); /** returns true if resource exists */ bool Exists(const char *ResRef, SClass_ID type, bool silent=false) const; diff --git a/project/jni/application/gemrb/gemrb/core/ResourceSource.h b/project/jni/application/gemrb/gemrb/core/ResourceSource.h index 1b9418013..11608b985 100644 --- a/project/jni/application/gemrb/gemrb/core/ResourceSource.h +++ b/project/jni/application/gemrb/gemrb/core/ResourceSource.h @@ -41,7 +41,7 @@ public: virtual DataStream* GetResource(const char* resname, const ResourceDesc &type) = 0; const char *GetDescription() const { return description; } protected: - const char *description; + char *description; }; #endif diff --git a/project/jni/application/gemrb/gemrb/core/Scriptable/Actor.cpp b/project/jni/application/gemrb/gemrb/core/Scriptable/Actor.cpp index bf07faf3e..61f8a9a19 100644 --- a/project/jni/application/gemrb/gemrb/core/Scriptable/Actor.cpp +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/Actor.cpp @@ -20,7 +20,7 @@ //This class represents the .cre (creature) files. //Any player or non-player character is a creature. -//Actor is a scriptable object (Scriptable). See ActorBlock.cpp +//Actor is a scriptable object (Scriptable). See Scriptable.cpp #include "Scriptable/Actor.h" @@ -115,6 +115,7 @@ struct ItemUseType { static ItemUseType *itemuse = NULL; static int usecount = -1; static bool pstflags = false; +static bool nocreate = false; //used in many places, but different in engines static ieDword state_invisible = STATE_INVISIBLE; @@ -1371,6 +1372,7 @@ static void InitActorTables() int i, j; pstflags = core->HasFeature(GF_PST_STATE_FLAGS); + nocreate = core->HasFeature(GF_NO_NEW_VARIABLES); if (pstflags) { state_invisible=STATE_PST_INVIS; } else { @@ -1919,20 +1921,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) @@ -2185,17 +2187,7 @@ void Actor::RefreshEffects(EffectQueue *fx) //put all special cleanup calls here CharAnimations* anims = GetAnims(); if (anims) { - if (!anims->GlobalColorMod.locked) { - anims->GlobalColorMod.type = RGBModifier::NONE; - anims->GlobalColorMod.speed = 0; - } - unsigned int location; - for (location = 0; location < 32; ++location) { - if (!anims->ColorMods[location].phase) { - anims->ColorMods[location].type = RGBModifier::NONE; - anims->ColorMods[location].speed = 0; - } - } + anims->CheckColorMod(); } spellbook.ClearBonus(); /* these apply resrefs should be on a list as a trigger+resref */ @@ -2660,7 +2652,7 @@ void Actor::DialogInterrupt() } } -static EffectRef fx_cure_sleep_ref={"Cure:Sleep",NULL,-1}; +static EffectRef fx_cure_sleep_ref = { "Cure:Sleep", -1 }; void Actor::GetHit() { @@ -2687,7 +2679,7 @@ bool Actor::HandleCastingStance(const ieResRef SpellResRef, bool deplete) return false; } -static EffectRef fx_sleep_ref={"State:Helpless", NULL, -1}; +static EffectRef fx_sleep_ref = { "State:Helpless", -1 }; //returns actual damage int Actor::Damage(int damage, int damagetype, Scriptable *hitter, int modtype) @@ -2983,7 +2975,7 @@ void Actor::DebugDump() printf( "\nArea: %.8s ", Area ); printf( "Dialog: %.8s\n", Dialog ); printf( "Global ID: %d PartySlot: %d\n", GetGlobalID(), InParty); - printf( "Script name:%.32s\n", scriptName ); + 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] ); @@ -3210,9 +3202,9 @@ int Actor::GetEncumbrance() } //bg2 and iwd1 -EffectRef control_creature_ref = { "ControlCreature", NULL, -1}; +static EffectRef control_creature_ref = { "ControlCreature", -1 }; //iwd2 -EffectRef control_undead_ref = { "ControlUndead2", NULL, -1}; +static EffectRef control_undead_ref = { "ControlUndead2", -1 }; //receive turning void Actor::Turn(Scriptable *cleric, ieDword turnlevel) @@ -3242,7 +3234,7 @@ void Actor::Turn(Scriptable *cleric, ieDword turnlevel) LastTurner = cleric->GetGlobalID(); if (turnlevel >= level+TURN_DEATH_LVL_MOD) { if (gamedata->Exists("panic", IE_SPL_CLASS_ID)) { - core->ApplySpell("panic", this, cleric, 0); + core->ApplySpell("panic", this, cleric, level); } else { printf("Panic from turning!\n"); Panic(cleric, PANIC_RUNAWAY); @@ -3305,18 +3297,18 @@ void Actor::Resurrect() ieDword value=0; game->kaputz->Lookup(DeathVar, value); - if (value) { + if (value>0) { game->kaputz->SetAt(DeathVar, value-1); } } //clear effects? } -static EffectRef fx_cure_poisoned_state_ref={"Cure:Poison",NULL,-1}; -static EffectRef fx_cure_hold_state_ref={"Cure:Hold",NULL,-1}; -static EffectRef fx_cure_stun_state_ref={"Cure:Stun",NULL,-1}; -static EffectRef fx_remove_portrait_icon_ref={"Icon:Remove",NULL,-1}; -static EffectRef fx_unpause_caster_ref={"Cure:CasterHold",NULL,-1}; +static EffectRef fx_cure_poisoned_state_ref = { "Cure:Poison", -1 }; +static EffectRef fx_cure_hold_state_ref = { "Cure:Hold", -1 }; +static EffectRef fx_cure_stun_state_ref = { "Cure:Stun", -1 }; +static EffectRef fx_remove_portrait_icon_ref = { "Icon:Remove", -1 }; +static EffectRef fx_unpause_caster_ref = { "Cure:CasterHold", -1 }; void Actor::Die(Scriptable *killer) { @@ -3329,7 +3321,6 @@ void Actor::Die(Scriptable *killer) //Can't simply set Selected to false, game has its own little list Game *game = core->GetGame(); game->SelectActor(this, false, SELECT_NORMAL); - game->OutAttack(GetGlobalID()); displaymsg->DisplayConstantStringName(STR_DEATH, 0xffffff, this); DisplayStringCore(this, VB_DIE, DS_CONSOLE|DS_CONST ); @@ -3432,18 +3423,22 @@ void Actor::Die(Scriptable *killer) // death variables are updated at the moment of death if (KillVar[0]) { + //don't use the raw killVar here if (core->HasFeature(GF_HAS_KAPUTZ) ) { - game->kaputz->Lookup(KillVar, value); - game->kaputz->SetAt(KillVar, value+1); + if (AppearanceFlags&APP_DEATHTYPE) { + snprintf(varname, 32, "KILL_%s", KillVar); + game->kaputz->Lookup(varname, value); + game->kaputz->SetAt(varname, value+1, nocreate); + } } else { // iwd/iwd2 path *sets* this var, so i changed it, not sure about pst above - game->locals->SetAt(KillVar, 1); + game->locals->SetAt(KillVar, 1, nocreate); } } if (IncKillVar[0]) { value = 0; game->locals->Lookup(IncKillVar, value); - game->locals->SetAt(IncKillVar, value + 1); + game->locals->SetAt(IncKillVar, value + 1, nocreate); } if (scriptName[0]) { @@ -3452,29 +3447,24 @@ void Actor::Die(Scriptable *killer) if (AppearanceFlags&APP_DEATHVAR) { snprintf(varname, 32, "%s_DEAD", scriptName); game->kaputz->Lookup(varname, value); - game->kaputz->SetAt(varname, value+1); - } - if (AppearanceFlags&APP_DEATHTYPE) { - snprintf(varname, 32, "KILL_%s", KillVar); - game->kaputz->Lookup(varname, value); - game->kaputz->SetAt(varname, value+1); + game->kaputz->SetAt(varname, value+1, nocreate); } } else { snprintf(varname, 32, core->GetDeathVarFormat(), scriptName); game->locals->Lookup(varname, value); - game->locals->SetAt(varname, value+1); + game->locals->SetAt(varname, value+1, nocreate); } if (SetDeathVar) { value = 0; snprintf(varname, 32, "%s_DEAD", scriptName); game->locals->Lookup(varname, value); - game->locals->SetAt(varname, 1); + game->locals->SetAt(varname, 1, nocreate); if (value) { snprintf(varname, 32, "%s_KILL_CNT", scriptName); value = 1; game->locals->Lookup(varname, value); - game->locals->SetAt(varname, value + 1); + game->locals->SetAt(varname, value + 1, nocreate); } } } @@ -3490,7 +3480,7 @@ void Actor::Die(Scriptable *killer) // todo: should probably not set this for humans in iwd? snprintf(varname, 32, "KILL_%s_CNT", raceName); game->locals->Lookup(varname, value); - game->locals->SetAt(varname, value+1); + game->locals->SetAt(varname, value+1, nocreate); } } } @@ -3501,7 +3491,7 @@ void Actor::Die(Scriptable *killer) if (AppearanceFlags&j) { ieDword value = 0; game->locals->Lookup(CounterNames[i], value); - game->locals->SetAt(CounterNames[i], value+DeathCounters[i]); + game->locals->SetAt(CounterNames[i], value+DeathCounters[i], nocreate); } j+=j; } @@ -4026,8 +4016,8 @@ int Actor::LearnSpell(const ieResRef spellname, ieDword flags) // chance to learn roll int roll = LuckyRoll(1, 100, 0); // adjust the roll for specialist mages - // doesn't work in bg1, since its spells don't have PrimaryType set - if (GetKitIndex(BaseStats[IE_KIT])) { + // doesn't work in bg1, since its spells don't have PrimaryType set (0 is NONE) + if (GetKitIndex(BaseStats[IE_KIT]) && spell->PrimaryType) { if ((signed)BaseStats[IE_KIT] == 1<<(spell->PrimaryType+5)) { // +5 since the kit values start at 0x40 roll += 15; } else { @@ -4063,7 +4053,7 @@ int Actor::LearnSpell(const ieResRef spellname, ieDword flags) if (tmp) { displaymsg->DisplayConstantStringName(tmp, 0xbcefbc, this); } - if (flags&LS_ADDXP) { + if (flags&LS_ADDXP && !(flags&LS_NOXP)) { int xp = CalculateExperience(XP_LEARNSPELL, explev); Game *game = core->GetGame(); game->ShareXP(xp, SX_DIVIDE); @@ -4176,9 +4166,6 @@ int Actor::GetAttackStyle() const void Actor::AttackedBy( Actor *attacker) { LastAttacker = attacker->GetGlobalID(); - Game * game = core->GetGame(); - game->InAttack(GetGlobalID() ); - game->InAttack(LastAttacker); } void Actor::SetTarget( Scriptable *target) @@ -4196,7 +4183,6 @@ void Actor::StopAttack() { SetStance(IE_ANI_READY); secondround = 0; - core->GetGame()->OutAttack(GetGlobalID()); InternalFlags|=IF_TARGETGONE; //this is for the trigger! if (InParty) { core->Autopause(AP_NOTARGET); @@ -4227,47 +4213,12 @@ void Actor::InitRound(ieDword gameTime) lastInit = gameTime; secondround = !secondround; - //roundTime will equal 0 if we aren't attacking something - if (roundTime) { - //only perform calculations at the beginning of the round! - if (((gameTime-roundTime)%core->Time.round_size != 0) || \ - (roundTime == lastInit)) { - return; - } - } - //reset variables used in PerformAttack attackcount = 0; attacksperround = 0; nextattack = 0; lastattack = 0; - //we set roundTime to zero on any of the following returns, because this - //is guaranteed to be the start of a round, and we only want roundTime - //if we are attacking this round - if (InternalFlags&IF_STOPATTACK) { - core->GetGame()->OutAttack(GetGlobalID()); - roundTime = 0; - return; - } - - if (!LastTarget) { - StopAttack(); - roundTime = 0; - return; - } - - //if held or disabled, etc, then cannot continue attacking - ieDword state = GetStat(IE_STATE_ID); - if (state&STATE_CANTMOVE) { - roundTime = 0; - return; - } - if (Immobile()) { - roundTime = 0; - return; - } - //add one for second round to get an extra attack only if we //are x/2 attacks per round attackcount = GetStat(IE_NUMBEROFATTACKS); @@ -4488,8 +4439,9 @@ int Actor::GetToHit(int bonus, ieDword Flags, Actor *target) const static const int weapon_damagetype[] = {DAMAGE_CRUSHING, DAMAGE_PIERCING, DAMAGE_CRUSHING, DAMAGE_SLASHING, DAMAGE_MISSILE, DAMAGE_STUNNING}; +static EffectRef fx_ac_vs_creature_type_ref = { "ACVsCreatureType", -1 }; -int Actor::GetDefense(int DamageType) const +int Actor::GetDefense(int DamageType, Actor *attacker) const { //specific damage type bonus. int defense = 0; @@ -4542,23 +4494,42 @@ int Actor::GetDefense(int DamageType) const defense += GetStat(IE_ARMORCLASS); } //Dexterity bonus is stored negative in 2da files. - return defense + core->GetDexterityBonus(STAT_DEX_AC, GetStat(IE_DEX) ); + defense += core->GetDexterityBonus(STAT_DEX_AC, GetStat(IE_DEX) ); + if (attacker) { + defense -= fxqueue.BonusAgainstCreature(fx_ac_vs_creature_type_ref,attacker); + } + return defense; } -static EffectRef fx_ac_vs_creature_type_ref={"ACVsCreatureType",NULL,-1}; - void Actor::PerformAttack(ieDword gameTime) { - // start a new round if we really don't have one yet - if (!roundTime) { - printMessage("Actor", "Unregistered attack. We shouldn't be here?\n", RED); - secondround = 0; + if (InParty) { + // TODO: this is temporary hack + Game *game = core->GetGame(); + game->PartyAttack = true; + } + + // if held or disabled, etc, then cannot continue attacking + // TODO: should be in action + ieDword state = GetStat(IE_STATE_ID); + if (state&STATE_CANTMOVE || Immobile()) { + // this is also part of the UpdateActorState hack below. sorry! + lastattack = gameTime; + return; + } + + if (!roundTime || (gameTime-roundTime > core->Time.round_size)) { + // TODO: do we need cleverness for secondround here? InitRound(gameTime); } //only return if we don't have any attacks left this round - if (attackcount==0) return; + if (attackcount==0) { + // this is also part of the UpdateActorState hack below. sorry! + lastattack = gameTime; + return; + } // this check shouldn't be necessary, but it causes a divide-by-zero below, // so i would like it to be clear if it ever happens @@ -4712,8 +4683,7 @@ void Actor::PerformAttack(ieDword gameTime) //get target's defense against attack - int defense = target->GetDefense(damagetype); - defense -= target->fxqueue.BonusAgainstCreature(fx_ac_vs_creature_type_ref,this); + int defense = target->GetDefense(damagetype, this); bool success; if(ReverseToHit) { @@ -4739,10 +4709,10 @@ void Actor::PerformAttack(ieDword gameTime) ResetState(); } -static EffectRef fx_stoneskin_ref={"StoneSkinModifier",NULL,-1}; -static EffectRef fx_stoneskin2_ref={"StoneSkin2Modifier",NULL,-1}; -static EffectRef fx_mirrorimage_ref={"MirrorImageModifier",NULL,-1}; -static EffectRef fx_aegis_ref={"Aegis",NULL,-1}; +static EffectRef fx_stoneskin_ref = { "StoneSkinModifier", -1 }; +static EffectRef fx_stoneskin2_ref = { "StoneSkin2Modifier", -1 }; +static EffectRef fx_mirrorimage_ref = { "MirrorImageModifier", -1 }; +static EffectRef fx_aegis_ref = { "Aegis", -1 }; void Actor::ModifyDamage(Actor *target, Scriptable *hitter, int &damage, int &resisted, int damagetype, WeaponInfo *wi, bool critical) { @@ -4886,10 +4856,8 @@ void Actor::UpdateActorState(ieDword gameTime) { StopAttack(); } else { printMessage("Attack","(Leaving attack)", GREEN); - core->GetGame()->OutAttack(GetGlobalID()); } - roundTime = 0; lastattack = 0; } @@ -5775,8 +5743,12 @@ void Actor::SetPortrait(const char* ResRef, int Which) } if(!Which) { for (i = 0; i < 8 && ResRef[i]; i++) {}; - SmallPortrait[i] = 'S'; - LargePortrait[i] = 'M'; + if (SmallPortrait[i-1] != 'S' && SmallPortrait[i-1] != 's') { + SmallPortrait[i] = 'S'; + } + if (LargePortrait[i-1] != 'M' && LargePortrait[i-1] != 'm') { + LargePortrait[i] = 'M'; + } } } @@ -6047,16 +6019,16 @@ bool Actor::UseItemPoint(ieDword slot, ieDword header, const Point &target, ieDw ChargeItem(slot, header, item, itm, flags&UI_SILENT); gamedata->FreeItem(itm,tmpresref, false); if (pro) { - pro->SetCaster(GetGlobalID()); + pro->SetCaster(GetGlobalID(), ITEM_CASTERLEVEL); GetCurrentArea()->AddProjectile(pro, Pos, target); return true; } return false; } -static EffectRef fx_damage_ref={"Damage",NULL,-1}; -static EffectRef fx_melee_ref={"SetMeleeEffect",NULL,-1}; -static EffectRef fx_ranged_ref={"SetRangedEffect",NULL,-1}; +static EffectRef fx_damage_ref = { "Damage", -1 }; +static EffectRef fx_melee_ref = { "SetMeleeEffect", -1 }; +static EffectRef fx_ranged_ref = { "SetRangedEffect", -1 }; bool Actor::UseItem(ieDword slot, ieDword header, Scriptable* target, ieDword flags, int damage) { @@ -6084,7 +6056,7 @@ bool Actor::UseItem(ieDword slot, ieDword header, Scriptable* target, ieDword fl gamedata->FreeItem(itm,tmpresref, false); if (pro) { //ieDword is unsigned!! - pro->SetCaster(GetGlobalID()); + pro->SetCaster(GetGlobalID(), ITEM_CASTERLEVEL); if(((int)header < 0) && !(flags&UI_MISS)) { //using a weapon bool ranged = header == (ieDword)-2; ITMExtHeader *which = itm->GetWeaponHeader(ranged); @@ -6356,8 +6328,8 @@ int Actor::CheckUsability(Item *item) const return 0; } -static EffectRef fx_cant_use_item_ref={"CantUseItem",NULL,-1}; -static EffectRef fx_cant_use_item_type_ref={"CantUseItemType",NULL,-1}; +static EffectRef fx_cant_use_item_ref = { "CantUseItem", -1 }; +static EffectRef fx_cant_use_item_type_ref = { "CantUseItemType", -1 }; //this one is the same, but returns strrefs based on effects ieStrRef Actor::Disabled(ieResRef name, ieDword type) const @@ -6891,7 +6863,7 @@ int Actor::LuckyRoll(int dice, int size, int add, ieDword flags, Actor* opponent return result + add; } -static EffectRef fx_remove_invisible_state_ref={"ForceVisible",NULL,-1}; +static EffectRef fx_remove_invisible_state_ref = { "ForceVisible", -1 }; // removes the (normal) invisibility state void Actor::CureInvisibility() @@ -6911,7 +6883,7 @@ void Actor::CureInvisibility() } } -static EffectRef fx_remove_sanctuary_ref={"Cure:Sanctuary",NULL,-1}; +static EffectRef fx_remove_sanctuary_ref = { "Cure:Sanctuary", -1 }; // removes the sanctuary effect void Actor::CureSanctuary() @@ -6979,7 +6951,7 @@ bool Actor::ModalSpellSkillCheck() { } } -static EffectRef fx_disable_button_ref={ "DisableButton", NULL, -1 }; +static EffectRef fx_disable_button_ref = { "DisableButton", -1 }; inline void HideFailed(Actor* actor) { @@ -7004,9 +6976,20 @@ bool Actor::TryToHide() { return false; } - // check if the pc is in combat (seen / heard) - Game *game = core->GetGame(); - if (game->PCInCombat(this)) { + // check if the actor is seen by enemy + Actor** visActors = GetCurrentArea()->GetAllActorsInRadius(Pos, GA_NO_DEAD, Modified[IE_VISUALRANGE]); + Actor** poi = visActors; + bool seen = false; + while (*poi && !seen) { + Actor *toCheck = *poi++; + if (Modified[IE_EA] >= EA_EVILCUTOFF) + seen = toCheck->Modified[IE_EA] < EA_EVILCUTOFF; + else + seen = toCheck->Modified[IE_EA] > EA_GOODCUTOFF; + } + free(visActors); + + if (seen) { HideFailed(this); return false; } @@ -7018,6 +7001,7 @@ bool Actor::TryToHide() { skill = GetStat(IE_STEALTH); } + Game *game = core->GetGame(); // check how bright our spot is ieDword lightness = game->GetCurrentArea()->GetLightLevel(Pos); // seems to be the color overlay at midnight; lightness of a point with rgb (200, 100, 100) diff --git a/project/jni/application/gemrb/gemrb/core/Scriptable/Actor.h b/project/jni/application/gemrb/gemrb/core/Scriptable/Actor.h index 358fdd357..5b54b5bf1 100644 --- a/project/jni/application/gemrb/gemrb/core/Scriptable/Actor.h +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/Actor.h @@ -21,7 +21,7 @@ #ifndef ACTOR_H #define ACTOR_H -#include "Scriptable/ActorBlock.h" +#include "Scriptable/Scriptable.h" #include "Scriptable/PCStatStruct.h" @@ -125,6 +125,9 @@ struct PolymorphCache; //added this comment for some clues if you really need it) //#define GA_GLOBAL 4096 +//line of sight is ignored (for GetAllActorsInRadius) +#define GA_NO_LOS 4096 + // Detect() mode: IDS matching ignores invisibility #define GA_DETECT 8192 @@ -571,7 +574,7 @@ public: /* gets the to hit value */ int GetToHit(int bonus, ieDword Flags, Actor *target) const; /* gets the defense against an attack */ - int GetDefense(int DamageType) const; + int GetDefense(int DamageType, Actor *attacker) const; /* get the current hit bonus */ bool GetCombatDetails(int &tohit, bool leftorright, WeaponInfo &wi, ITMExtHeader *&header, ITMExtHeader *&hittingheader,\ ieDword &Flags, int &DamageBonus, int &speed, int &CriticalBonus, int &style, Actor *target) const; diff --git a/project/jni/application/gemrb/gemrb/core/Scriptable/Container.cpp b/project/jni/application/gemrb/gemrb/core/Scriptable/Container.cpp new file mode 100644 index 000000000..e2f675774 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/Container.cpp @@ -0,0 +1,292 @@ +/* GemRB - Infinity Engine Emulator + * Copyright (C) 2003-2005 The GemRB Project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public 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 "Scriptable/Container.h" + +#include "strrefs.h" +#include "win32def.h" + +#include "Audio.h" +#include "DisplayMessage.h" +#include "Game.h" +#include "GameData.h" +#include "Interface.h" +#include "Item.h" +#include "Map.h" +#include "Projectile.h" +#include "Spell.h" +#include "SpriteCover.h" +#include "TileMap.h" +#include "Video.h" +#include "GameScript/GSUtils.h" +#include "GUI/GameControl.h" + +#include +#include + +#define YESNO(x) ( (x)?"Yes":"No") + +Container::Container(void) + : Highlightable( ST_CONTAINER ) +{ + Type = 0; + LockDifficulty = 0; + Flags = 0; + TrapDetectionDiff = 0; + TrapRemovalDiff = 0; + Trapped = 0; + TrapDetected = 0; + inventory.SetInventoryType(INVENTORY_HEAP); + // NULL should be 0 for this + memset (groundicons, 0, sizeof(groundicons) ); + groundiconcover = 0; +} + +void Container::FreeGroundIcons() +{ + Video* video = core->GetVideoDriver(); + + for (int i = 0;iFreeSprite( groundicons[i] ); + groundicons[i]=NULL; + } + } + delete groundiconcover; + groundiconcover = 0; +} + +Container::~Container() +{ + FreeGroundIcons(); +} + +void Container::DrawPile(bool highlight, Region screen, Color tint) +{ + Video* video = core->GetVideoDriver(); + CreateGroundIconCover(); + for (int i = 0;iBlitGameSprite(groundicons[i], + screen.x + Pos.x, screen.y + Pos.y, + BLIT_TINTED | (highlight ? 0:BLIT_NOSHADOW), + tint, groundiconcover); + } + } +} + +// create the SpriteCover for the groundicons +void Container::CreateGroundIconCover() +{ + int xpos = 0; + int ypos = 0; + int width = 0; + int height = 0; + + int i; //msvc6.0 + for (i = 0;iCovers(Pos.x, Pos.y, xpos, ypos, width, height)) + { + delete groundiconcover; + groundiconcover = 0; + if (width*height > 0) { + groundiconcover = GetCurrentArea()->BuildSpriteCover + (Pos.x, Pos.y, xpos, ypos, width, height, WantDither()); + } + } + +#ifndef NDEBUG + // TODO: remove this checking code eventually + for (i = 0;iCovers(Pos.x, Pos.y, spr.XPos, spr.YPos, spr.Width, spr.Height)); + } + } +#endif +} + +void Container::SetContainerLocked(bool lock) +{ + if (lock) { + Flags|=CONT_LOCKED; + } else { + Flags&=~CONT_LOCKED; + } +} + +//This function doesn't exist in the original IE, destroys a container +//turning it to a ground pile +void Container::DestroyContainer() +{ + //it is already a groundpile? + if (Type == IE_CONTAINER_PILE) + return; + Type = IE_CONTAINER_PILE; + RefreshGroundIcons(); + //probably we should stop the script or trigger it, whatever +} + +//Takes an item from the container's inventory and returns its pointer +CREItem *Container::RemoveItem(unsigned int idx, unsigned int count) +{ + CREItem *ret = inventory.RemoveItem(idx, count); + //we just took the 3. or less item, groundpile changed + if ((Type == IE_CONTAINER_PILE) && (inventory.GetSlotCount()<3)) { + RefreshGroundIcons(); + } + return ret; +} + +//Adds an item to the container's inventory +//containers always have enough capacity (so far), thus we always return 2 +int Container::AddItem(CREItem *item) +{ + inventory.AddItem(item); + //we just added a 3. or less item, groundpile changed + if ((Type == IE_CONTAINER_PILE) && (inventory.GetSlotCount()<4)) { + RefreshGroundIcons(); + } + return 2; +} + +void Container::RefreshGroundIcons() +{ + int i = inventory.GetSlotCount(); + if (i>MAX_GROUND_ICON_DRAWN) + i = MAX_GROUND_ICON_DRAWN; + FreeGroundIcons(); + while (i--) { + CREItem *slot = inventory.GetSlotItem(i); //borrowed reference + Item *itm = gamedata->GetItem( slot->ItemResRef ); //cached reference + //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 ); + gamedata->FreeItem( itm, slot->ItemResRef ); //decref + } +} + +//used for ground piles +int Container::WantDither() +{ + //if pile is highlighted, always dither it + if (Highlight) { + return 2; //dither me if you want + } + //if pile isn't highlighted, dither it if the polygon wants + return 1; +} + +int Container::IsOpen() const +{ + if (Flags&CONT_LOCKED) { + return false; + } + return true; +} + +void Container::TryPickLock(Actor *actor) +{ + if (LockDifficulty == 100) { + if (OpenFail != (ieDword)-1) { + displaymsg->DisplayStringName(OpenFail, 0xbcefbc, actor, IE_STR_SOUND|IE_STR_SPEECH); + } else { + displaymsg->DisplayConstantStringName(STR_CONT_NOPICK, 0xbcefbc, actor); + } + return; + } + if (actor->GetStat(IE_LOCKPICKING)DisplayConstantStringName(STR_LOCKPICK_FAILED, 0xbcefbc, actor); + LastPickLockFailed = actor->GetGlobalID(); + return; + } + SetContainerLocked(false); + displaymsg->DisplayConstantStringName(STR_LOCKPICK_DONE, 0xd7d7be, actor); + LastUnlocked = actor->GetGlobalID(); + ImmediateEvent(); + int xp = actor->CalculateExperience(XP_LOCKPICK, actor->GetXPLevel(1)); + Game *game = core->GetGame(); + game->ShareXP(xp, SX_DIVIDE); +} + +void Container::TryBashLock(Actor *actor) +{ + //Get the strength bonus agains lock difficulty + int str = actor->GetStat(IE_STR); + int strEx = actor->GetStat(IE_STREXTRA); + unsigned int bonus = core->GetStrengthBonus(2, str, strEx); //BEND_BARS_LIFT_GATES + unsigned int roll = actor->LuckyRoll(1, 10, bonus, 0); + + if(roll < LockDifficulty || LockDifficulty == 100) { + displaymsg->DisplayConstantStringName(STR_CONTBASH_FAIL, 0xbcefbc, actor); + return; + } + + displaymsg->DisplayConstantStringName(STR_CONTBASH_DONE, 0xd7d7be, actor); + SetContainerLocked(false); + //Is this really useful ? + LastUnlocked = 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, + TrapRemovalDiff ); + const char *name = "NONE"; + if (Scripts[0]) { + name = Scripts[0]->GetName(); + } + printf( "Script: %s, Key: %s\n", name, KeyResRef ); + // FIXME: const_cast + const_cast(inventory).dump(); +} + +bool Container::TryUnlock(Actor *actor) { + if (!(Flags&CONT_LOCKED)) return true; + + return Highlightable::TryUnlock(actor, false); +} + diff --git a/project/jni/application/gemrb/gemrb/core/Scriptable/Container.h b/project/jni/application/gemrb/gemrb/core/Scriptable/Container.h new file mode 100644 index 000000000..39fd7bb01 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/Container.h @@ -0,0 +1,70 @@ +/* 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 CONTAINER_H +#define CONTAINER_H + +#include "Scriptable.h" + +//container flags +#define CONT_LOCKED 1 +#define CONT_RESET 8 +#define CONT_DISABLED 32 + +class GEM_EXPORT Container : public Highlightable { +public: + Container(void); + ~Container(void); + void SetContainerLocked(bool lock); + //turns the container to a pile + void DestroyContainer(); + //removes an item from the container's inventory + CREItem *RemoveItem(unsigned int idx, unsigned int count); + //adds an item to the container's inventory + int AddItem(CREItem *item); + //draws the ground icons + void DrawPile(bool highlight, Region screen, Color tint); + //returns dithering option + int WantDither(); + int IsOpen() const; + void TryPickLock(Actor *actor); + void TryBashLock(Actor* actor) ; + bool TryUnlock(Actor *actor); + void DebugDump() const; + int TrapResets() const { return Flags & CONT_RESET; } +private: + //updates the ground icons for a pile + void RefreshGroundIcons(); + void FreeGroundIcons(); + void CreateGroundIconCover(); +public: + Point toOpen; + ieWord Type; + ieDword Flags; + ieWord LockDifficulty; + Inventory inventory; + ieStrRef OpenFail; + //these are not saved + Sprite2D *groundicons[3]; + SpriteCover *groundiconcover; + //keyresref is stored in Highlightable +}; + +#endif diff --git a/project/jni/application/gemrb/gemrb/core/Scriptable/Door.cpp b/project/jni/application/gemrb/gemrb/core/Scriptable/Door.cpp new file mode 100644 index 000000000..33df7bdaf --- /dev/null +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/Door.cpp @@ -0,0 +1,409 @@ +/* GemRB - Infinity Engine Emulator + * Copyright (C) 2003-2005 The GemRB Project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public 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 "Scriptable/Door.h" + +#include "strrefs.h" +#include "win32def.h" + +#include "Audio.h" +#include "DisplayMessage.h" +#include "Game.h" +#include "GameData.h" +#include "Interface.h" +#include "Item.h" +#include "Map.h" +#include "Projectile.h" +#include "Spell.h" +#include "SpriteCover.h" +#include "TileMap.h" +#include "Video.h" +#include "GameScript/GSUtils.h" +#include "GUI/GameControl.h" +#include "Scriptable/InfoPoint.h" + +#include +#include + +#define YESNO(x) ( (x)?"Yes":"No") + +Door::Door(TileOverlay* Overlay) + : Highlightable( ST_DOOR ) +{ + tiles = NULL; + tilecount = 0; + Flags = 0; + open = NULL; + closed = NULL; + open_ib = NULL; + oibcount = 0; + closed_ib = NULL; + cibcount = 0; + OpenSound[0] = 0; + CloseSound[0] = 0; + LockSound[0] = 0; + UnLockSound[0] = 0; + overlay = Overlay; + LinkedInfo[0] = 0; + OpenStrRef = (ieDword) -1; +} + +Door::~Door(void) +{ + if (Flags&DOOR_OPEN) { + if (closed) { + delete( closed ); + } + } else { + if (open) { + delete( open ); + } + } + if (tiles) { + free( tiles ); + } + if (open_ib) { + free( open_ib ); + } + if (closed_ib) { + free( closed_ib ); + } +} + +void Door::ImpedeBlocks(int count, Point *points, unsigned char value) +{ + for(int i = 0;iGetInternalSearchMap(points[i].x, points[i].y) & PATH_MAP_NOTDOOR; + area->SetInternalSearchMap(points[i].x, points[i].y, tmp|value); + } +} + +void Door::UpdateDoor() +{ + if (Flags&DOOR_OPEN) { + outline = open; + } else { + outline = closed; + } + // update the Scriptable position + 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; + if (Flags & DOOR_TRANSPARENT) { + cval = 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; + } + if (Flags &DOOR_OPEN) { + ImpedeBlocks(cibcount, closed_ib, 0); + ImpedeBlocks(oibcount, open_ib, cval); + } + else { + ImpedeBlocks(oibcount, open_ib, 0); + ImpedeBlocks(cibcount, closed_ib, cval); + } + + InfoPoint *ip = area->TMap->GetInfoPoint(LinkedInfo); + if (ip) { + if (Flags&DOOR_OPEN) ip->Flags&=~INFO_DOOR; + else ip->Flags|=INFO_DOOR; + } +} + +void Door::ToggleTiles(int State, int playsound) +{ + int i; + int state; + + if (State) { + state = !closedIndex; + if (playsound && ( OpenSound[0] != '\0' )) + core->GetAudioDrv()->Play( OpenSound ); + } else { + state = closedIndex; + if (playsound && ( CloseSound[0] != '\0' )) + core->GetAudioDrv()->Play( CloseSound ); + } + for (i = 0; i < tilecount; i++) { + overlay->tiles[tiles[i]]->tileIndex = (ieByte) state; + } + + //set door_open as state + Flags = (Flags & ~DOOR_OPEN) | (State == !core->HasFeature(GF_REVERSE_DOOR) ); +} + +//this is the short name (not the scripting name) +void Door::SetName(const char* name) +{ + strnlwrcpy( ID, name, 8 ); +} + +void Door::SetTiles(unsigned short* Tiles, int cnt) +{ + if (tiles) { + free( tiles ); + } + tiles = Tiles; + tilecount = cnt; +} + +void Door::SetDoorLocked(int Locked, int playsound) +{ + if (Locked) { + if (Flags & DOOR_LOCKED) return; + Flags|=DOOR_LOCKED; + if (playsound && ( LockSound[0] != '\0' )) + core->GetAudioDrv()->Play( LockSound ); + } + else { + if (!(Flags & DOOR_LOCKED)) return; + Flags&=~DOOR_LOCKED; + if (playsound && ( UnLockSound[0] != '\0' )) + core->GetAudioDrv()->Play( UnLockSound ); + } +} + +int Door::IsOpen() const +{ + int ret = core->HasFeature(GF_REVERSE_DOOR); + if (Flags&DOOR_OPEN) { + ret = !ret; + } + return ret; +} + +//also mark actors to fix position +bool Door::BlockedOpen(int Open, int ForceOpen) +{ + bool blocked; + int count; + Point *points; + + blocked = false; + if (Open) { + count = oibcount; + points = open_ib; + } else { + count = cibcount; + points = closed_ib; + } + //getting all impeded actors flagged for jump + Region rgn; + rgn.w = 16; + rgn.h = 12; + for(int i = 0;iGetInternalSearchMap(points[i].x, points[i].y) & PATH_MAP_ACTOR; + if (tmp) { + int ac = area->GetActorInRect(ab, rgn, false); + while(ac--) { + if (ab[ac]->GetBase(IE_DONOTJUMP)) { + continue; + } + ab[ac]->SetBase(IE_DONOTJUMP, DNJ_JUMP); + blocked = true; + } + if (ab) { + free(ab); + } + } + } + + if ((Flags&DOOR_SLIDE) || ForceOpen) { + return false; + } + return blocked; +} + +void Door::SetDoorOpen(int Open, int playsound, ieDword ID) +{ + if (playsound) { + //the door cannot be blocked when opening, + //but the actors will be pushed + //BlockedOpen will mark actors to be pushed + if (BlockedOpen(Open,0) && !Open) { + //clear up the blocking actors + area->JumpActors(false); + return; + } + area->JumpActors(true); + } + if (Open) { + LastEntered = ID; //used as lastOpener + + // 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 + } + ToggleTiles(Open, playsound); + //synchronising other data with the door state + UpdateDoor(); + area->ActivateWallgroups(open_wg_index, open_wg_count, Flags&DOOR_OPEN); + area->ActivateWallgroups(closed_wg_index, closed_wg_count, !(Flags&DOOR_OPEN)); + core->SetEventFlag(EF_TARGETMODE); +} + +bool Door::TryUnlock(Actor *actor) { + if (!(Flags&DOOR_LOCKED)) return true; + + // don't remove key in PS:T! + bool removekey = !core->HasFeature(GF_REVERSE_DOOR) && Flags&DOOR_KEY; + return Highlightable::TryUnlock(actor, removekey); +} + +void Door::TryDetectSecret(int skill) +{ + if (Type != ST_DOOR) return; + if (Visible()) return; + if (skill > (signed)DiscoveryDiff) { + Flags |= DOOR_FOUND; + core->PlaySound(DS_FOUNDSECRET); + } +} + +// return true if the door isn't secret or if it is, but was already discovered +bool Door::Visible() +{ + return (!(Flags & DOOR_SECRET) || (Flags & DOOR_FOUND)); +} + +void Door::SetPolygon(bool Open, Gem_Polygon* poly) +{ + if (Open) { + if (open) + delete( open ); + open = poly; + } else { + if (closed) + delete( closed ); + closed = poly; + } +} + +void Door::SetNewOverlay(TileOverlay *Overlay) { + overlay = Overlay; + ToggleTiles(IsOpen(), false); +} + +void Highlightable::SetTrapDetected(int x) +{ + if(x == TrapDetected) + return; + TrapDetected = x; + if(TrapDetected) { + core->Autopause(AP_TRAP); + } +} + +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(); + //trap removed + Trapped = 0; + displaymsg->DisplayConstantStringName(STR_DISARM_DONE, 0xd7d7be, actor); + int xp = actor->CalculateExperience(XP_DISARM, actor->GetXPLevel(1)); + Game *game = core->GetGame(); + game->ShareXP(xp, SX_DIVIDE); + } else { + displaymsg->DisplayConstantStringName(STR_DISARM_FAIL, 0xd7d7be, actor); + TriggerTrap(skill, LastTrigger); + } + ImmediateEvent(); +} + +void Door::TryPickLock(Actor *actor) +{ + if (LockDifficulty == 100) { + if (OpenStrRef != (ieDword)-1) { + displaymsg->DisplayStringName(OpenStrRef, 0xbcefbc, actor, IE_STR_SOUND|IE_STR_SPEECH); + } else { + displaymsg->DisplayConstantStringName(STR_DOOR_NOPICK, 0xbcefbc, actor); + } + return; + } + if (actor->GetStat(IE_LOCKPICKING)DisplayConstantStringName(STR_LOCKPICK_FAILED, 0xbcefbc, actor); + LastPickLockFailed = actor->GetGlobalID(); + return; + } + SetDoorLocked( false, true); + displaymsg->DisplayConstantStringName(STR_LOCKPICK_DONE, 0xd7d7be, actor); + LastUnlocked = actor->GetGlobalID(); + ImmediateEvent(); + int xp = actor->CalculateExperience(XP_LOCKPICK, actor->GetXPLevel(1)); + Game *game = core->GetGame(); + game->ShareXP(xp, SX_DIVIDE); +} + +void Door::TryBashLock(Actor *actor) +{ + //Get the strength bonus agains lock difficulty + int str = actor->GetStat(IE_STR); + int strEx = actor->GetStat(IE_STREXTRA); + unsigned int bonus = core->GetStrengthBonus(2, str, strEx); //BEND_BARS_LIFT_GATES + unsigned int roll = actor->LuckyRoll(1, 10, bonus, 0); + + if(roll < LockDifficulty || LockDifficulty == 100) { + displaymsg->DisplayConstantStringName(STR_DOORBASH_FAIL, 0xbcefbc, actor); + return; + } + + displaymsg->DisplayConstantStringName(STR_DOORBASH_DONE, 0xd7d7be, actor); + SetDoorLocked(false, true); + //Is this really useful ? + LastUnlocked = 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)); + if (Trapped) { + printf( "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)); + 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 ); +} + diff --git a/project/jni/application/gemrb/gemrb/core/Scriptable/Door.h b/project/jni/application/gemrb/gemrb/core/Scriptable/Door.h new file mode 100644 index 000000000..5d6e4db82 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/Door.h @@ -0,0 +1,98 @@ +/* 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 DOOR_H +#define DOOR_H + +#include "Scriptable.h" + +//door flags +#define DOOR_OPEN 1 +#define DOOR_LOCKED 2 +#define DOOR_RESET 4 //reset trap +#define DOOR_DETECTABLE 8 //trap detectable +#define DOOR_16 16 //unknown +#define DOOR_32 32 //unknown +#define DOOR_LINKED 64 //info trigger linked to this door +#define DOOR_SECRET 128 //door is secret +#define DOOR_FOUND 256 //secret door found +#define DOOR_TRANSPARENT 512 //obscures vision +#define DOOR_KEY 1024 //key removed when used +#define DOOR_SLIDE 2048 //impeded blocks ignored + +class GEM_EXPORT Door : public Highlightable { +public: + Door(TileOverlay* Overlay); + ~Door(void); +public: + ieVariable LinkedInfo; + ieResRef ID; //WED ID + TileOverlay* overlay; + unsigned short* tiles; + int tilecount; + ieDword Flags; + int closedIndex; + //trigger areas + Gem_Polygon* open; + Gem_Polygon* closed; + //impeded blocks + Point* open_ib; //impeded blocks stored in a Point array + int oibcount; + Point* closed_ib; + int cibcount; + //wallgroup covers + unsigned int open_wg_index; + unsigned int open_wg_count; + unsigned int closed_wg_index; + unsigned int closed_wg_count; + Point toOpen[2]; + ieResRef OpenSound; + ieResRef CloseSound; + ieResRef LockSound; + ieResRef UnLockSound; + ieDword DiscoveryDiff; + ieDword LockDifficulty; //this is a dword? + ieStrRef OpenStrRef; + ieStrRef NameStrRef; + ieDword Unknown54; //unused in tob +private: + void SetWallgroups(int count, int value); + void ImpedeBlocks(int count, Point *points, unsigned char value); + void UpdateDoor(); + bool BlockedOpen(int Open, int ForceOpen); +public: + void ToggleTiles(int State, int playsound = false); + void SetName(const char* Name); // sets door ID + void SetTiles(unsigned short* Tiles, int count); + void SetDoorLocked(int Locked, int playsound); + void SetDoorOpen(int Open, int playsound, ieDword ID); + void SetPolygon(bool Open, Gem_Polygon* poly); + int IsOpen() const; + void TryPickLock(Actor *actor); + void TryBashLock(Actor* actor) ; + bool TryUnlock(Actor *actor); + void TryDetectSecret(int skill); + bool Visible(); + void DebugDump() const; + int TrapResets() const { return Flags & DOOR_RESET; } + void SetNewOverlay(TileOverlay *Overlay); +}; + +#endif diff --git a/project/jni/application/gemrb/gemrb/core/Scriptable/InfoPoint.cpp b/project/jni/application/gemrb/gemrb/core/Scriptable/InfoPoint.cpp new file mode 100644 index 000000000..0199bc7d0 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/InfoPoint.cpp @@ -0,0 +1,272 @@ +/* GemRB - Infinity Engine Emulator + * Copyright (C) 2003-2005 The GemRB Project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public 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 "Scriptable/InfoPoint.h" + +#include "strrefs.h" +#include "win32def.h" + +#include "Audio.h" +#include "DisplayMessage.h" +#include "Game.h" +#include "GameData.h" +#include "Interface.h" +#include "Item.h" +#include "Map.h" +#include "Projectile.h" +#include "Spell.h" +#include "SpriteCover.h" +#include "TileMap.h" +#include "Video.h" +#include "GameScript/GSUtils.h" +#include "GUI/GameControl.h" + +#include +#include + +#define YESNO(x) ( (x)?"Yes":"No") + +InfoPoint::InfoPoint(void) + : Highlightable( ST_TRIGGER ) +{ + Destination[0] = 0; + EntranceName[0] = 0; + Flags = 0; + TrapDetectionDiff = 0; + TrapRemovalDiff = 0; + TrapDetected = 0; + TrapLaunch.empty(); + EnterWav[0] = 0; +} + +InfoPoint::~InfoPoint(void) +{ +} + +void InfoPoint::SetEnter(const char *resref) +{ + if (gamedata->Exists(resref, IE_WAV_CLASS_ID) ) { + strnuprcpy(EnterWav, resref, 8); + } +} + +//checks if the actor may use this travel trigger +//bit 1 : can use +//bit 2 : whole team +int InfoPoint::CheckTravel(Actor *actor) +{ + if (Flags&TRAP_DEACTIVATED) return CT_CANTMOVE; + if (!actor->InParty && (Flags&TRAVEL_NONPC) ) return CT_CANTMOVE; + if (actor->InParty && (Flags&TRAVEL_PARTY) ) { + if (core->HasFeature(GF_TEAM_MOVEMENT) || core->GetGame()->EveryoneNearPoint(actor->GetCurrentArea(), actor->Pos, ENP_CANMOVE) ) { + return CT_WHOLE; + } + return CT_GO_CLOSER; + } + if(actor->IsSelected() ) { + if(core->GetGame()->EveryoneNearPoint(actor->GetCurrentArea(), actor->Pos, ENP_CANMOVE|ENP_ONLYSELECT) ) { + return CT_MOVE_SELECTED; + } + return CT_SELECTED; + } + 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 +{ + // Only detectable trap-type infopoints. + return (CanDetectTrap() && (Type == ST_PROXIMITY) ); +} + +bool InfoPoint::CanDetectTrap() const +{ + // Traps can be detected on all types of infopoint, as long + // as the trap is detectable and isn't deactivated. + return ((Flags&TRAP_DETECTABLE) && !(Flags&TRAP_DEACTIVATED)); +} + +// returns true if the infopoint is a PS:T portal +// GF_REVERSE_DOOR is the closest game feature (exists only in PST, and about area objects) +bool InfoPoint::IsPortal() const +{ + if (Type!=ST_TRAVEL) return false; + if (Cursor != IE_CURSOR_PORTAL) return false; + return core->HasFeature(GF_REVERSE_DOOR); +} + +//trap that is visible on screen (marked by red) +//if TrapDetected is a bitflag, we could show traps selectively for +//players, really nice for multiplayer +bool Highlightable::VisibleTrap(int see_all) const +{ + if (!Trapped) return false; + if (!PossibleToSeeTrap()) return false; + if (!Scripts[0]) return false; + if (see_all) return true; + if (TrapDetected ) return true; + 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) +{ + if (Type!=ST_PROXIMITY) { + return true; + } + if (Flags&TRAP_DEACTIVATED) { + return false; + } + if (!Trapped) { + // we have to set Entered somewhere, here seems best.. + LastEntered = ID; + return true; + } else if (Highlightable::TriggerTrap(skill, ID)) { + if (!Trapped) { + Flags|=TRAP_DEACTIVATED; + } + // ok, so this is a pain. Entered() trigger checks Trapped, + // so it needs to be kept set. how to do this right? + Trapped = true; + return true; + } + return false; +} + +bool InfoPoint::Entered(Actor *actor) +{ + if (outline->PointIn( actor->Pos ) ) { + goto check; + } + // why is this here? actors which aren't *in* a trap get IF_INTRAP + // repeatedly unset, so this triggers again and again and again. + // i disabled it for ST_PROXIMITY for now.. + /*if (Type != ST_PROXIMITY && (PersonalDistance(Pos, actor)GetInternalFlag()&IF_INTRAP) { + return false; + } + + if (actor->InParty || (Flags&TRAP_NPC) ) { + //no need to avoid a travel trigger + + //skill? + if (TriggerTrap(0, actor->GetGlobalID()) ) { + return true; + } + } + return false; +} + +void InfoPoint::DebugDump() const +{ + switch (Type) { + case ST_TRIGGER: + printf( "Debugdump of InfoPoint Region %s:\n", GetScriptName() ); + break; + case ST_PROXIMITY: + printf( "Debugdump of Trap Region %s:\n", GetScriptName() ); + break; + case ST_TRAVEL: + printf( "Debugdump of Travel Region %s:\n", GetScriptName() ); + break; + default: + printf( "Debugdump of Unsupported Region %s:\n", GetScriptName() ); + break; + } + printf( "Region Global ID: %d\n", GetGlobalID()); + printf( "Position: %d.%d\n", Pos.x, Pos.y); + switch(Type) { + case ST_TRAVEL: + printf( "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, + TrapRemovalDiff ); + break; + case ST_TRIGGER: + printf ( "InfoString: %s\n", overHeadText ); + break; + default:; + } + const char *name = "NONE"; + 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)); +} + diff --git a/project/jni/application/gemrb/gemrb/core/Scriptable/InfoPoint.h b/project/jni/application/gemrb/gemrb/core/Scriptable/InfoPoint.h new file mode 100644 index 000000000..0eb628278 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/InfoPoint.h @@ -0,0 +1,68 @@ +/* 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 INFOPOINT_H +#define INFOPOINT_H + +#include "Scriptable.h" + +//trigger flags +#define TRAP_INVISIBLE 1 +#define TRAP_RESET 2 +#define TRAVEL_PARTY 4 +#define TRAP_DETECTABLE 8 +//#define TRAP_16 16 +#define TRAP_LOWMEM 32 //special treatment when low on memory ? +#define TRAP_NPC 64 +//#define TRAP_128 128 +#define TRAP_DEACTIVATED 256 +#define TRAVEL_NONPC 512 +#define TRAP_USEPOINT 1024 //override usage point of travel regions (used for sound in PST traps) +#define INFO_DOOR 2048 //info trigger blocked by door + +class GEM_EXPORT InfoPoint : public Highlightable { +public: + InfoPoint(void); + ~InfoPoint(void); + //returns true if trap has been triggered, tumble skill??? + void SetEnter(const char *resref); + bool TriggerTrap(int skill, ieDword ID); + //call this to check if an actor entered the trigger zone + bool Entered(Actor *actor); + //checks if the actor may use this travel trigger + int CheckTravel(Actor *actor); + void DebugDump() const; + int TrapResets() const { return Flags & TRAP_RESET; } + bool CanDetectTrap() const; + bool PossibleToSeeTrap() const; + bool IsPortal() const; + +public: + ieResRef Destination; + ieVariable EntranceName; + ieDword Flags; + //overheadtext contains the string, but we have to save this + 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 new file mode 100644 index 000000000..e1bd727eb --- /dev/null +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/Scriptable.cpp @@ -0,0 +1,1973 @@ +/* GemRB - Infinity Engine Emulator + * Copyright (C) 2003-2005 The GemRB Project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public 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 "Scriptable/Scriptable.h" + +#include "strrefs.h" +#include "win32def.h" + +#include "Audio.h" +#include "DisplayMessage.h" +#include "Game.h" +#include "GameData.h" +#include "Interface.h" +#include "Item.h" +#include "Map.h" +#include "Projectile.h" +#include "Spell.h" +#include "SpriteCover.h" +#include "TileMap.h" +#include "Video.h" +#include "GameScript/GSUtils.h" +#include "GUI/GameControl.h" +#include "Scriptable/InfoPoint.h" + +#include +#include + +#define YESNO(x) ( (x)?"Yes":"No") + +// we start this at a non-zero value to make debugging easier +static ieDword globalActorCounter = 10000; + +/*********************** + * Scriptable Class * + ***********************/ +Scriptable::Scriptable(ScriptableType type) +{ + Type = type; + for (int i = 0; i < MAX_SCRIPTS; i++) { + Scripts[i] = NULL; + } + overHeadText = NULL; + overHeadTextPos.empty(); + 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; + DialogName = 0; + CurrentAction = NULL; + CurrentActionState = 0; + CurrentActionTarget = 0; + CurrentActionInterruptable = true; + UnselectableTimer = 0; + startTime = 0; //executing scripts + lastRunTime = 0; //evaluating scripts + lastDelay = 0; + Dialog[0] = 0; + + globalID = ++globalActorCounter; + + interval = ( 1000 / AI_UPDATE_TIME ); + WaitCounter = 0; + if (Type == ST_ACTOR) { + InternalFlags = IF_VISIBLE | IF_ONCREATION | IF_USEDSAVE; + } else { + InternalFlags = IF_ACTIVE | IF_VISIBLE | IF_ONCREATION | IF_NOINT; + } + area = 0; + Pos.x = 0; + Pos.y = 0; + + LastCasterOnMe = 0; + LastSpellOnMe = 0xffffffff; + LastCasterSeen = 0; + LastSpellSeen = 0xffffffff; + SpellHeader = -1; + SpellResRef[0] = 0; + LastTargetPos.empty(); + locals = new Variables(); + locals->SetType( GEM_VARIABLES_INT ); + locals->ParseKey( 1 ); + InitTriggers(); + + memset( script_timers,0, sizeof(script_timers)); +} + +Scriptable::~Scriptable(void) +{ + if (CurrentAction) { + ReleaseCurrentAction(); + } + ClearActions(); + for (int i = 0; i < MAX_SCRIPTS; i++) { + if (Scripts[i]) { + delete( Scripts[i] ); + } + } + if (overHeadText) { + core->FreeString( overHeadText ); + } + if (locals) { + delete( locals ); + } +} + +void Scriptable::SetScriptName(const char* text) +{ + //if (text && text[0]) { //this leaves some uninitialized bytes + //lets hope this won't break anything + if (text) { + strnspccpy( scriptName, text, 32 ); + } +} + +/** Gets the DeathVariable */ +const char* Scriptable::GetScriptName(void) const +{ + return scriptName; +} + +void Scriptable::SetDialog(const char *resref) { + if (gamedata->Exists(resref, IE_DLG_CLASS_ID) ) { + strnuprcpy(Dialog, resref, 8); + } + } + +Map* Scriptable::GetCurrentArea() const +{ + //this could be NULL, always check it + return area; +} + +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(); + } + area = map; +} + +//ai is nonzero if this is an actor currently in the party +//if the script level is AI_SCRIPT_LEVEL, then we need to +//load an AI script (.bs) instead of (.bcs) +void Scriptable::SetScript(const ieResRef aScript, int idx, bool ai) +{ + if (idx >= MAX_SCRIPTS) { + printMessage("Scriptable","Invalid script index!\n",LIGHT_RED); + abort(); + } + if (Scripts[idx]) { + delete Scripts[idx]; + } + Scripts[idx] = NULL; + // NONE is an 'invalid' script name, never used seriously + // This hack is to prevent flooding of the console + if (aScript[0] && stricmp(aScript, "NONE") ) { + if (idx!=AI_SCRIPT_LEVEL) ai = false; + Scripts[idx] = new GameScript( aScript, this, idx, ai ); + } +} + +void Scriptable::SetScript(int index, GameScript* script) +{ + if (index >= MAX_SCRIPTS) { + printMessage("Scriptable","Invalid script index!\n",LIGHT_RED); + return; + } + if (Scripts[index] ) { + delete Scripts[index]; + } + Scripts[index] = script; +} + +void Scriptable::SetSpellResRef(ieResRef resref) { + strnuprcpy(SpellResRef, resref, 8); +} + +void Scriptable::DisplayHeadText(const char* text) +{ + if (overHeadText) { + core->FreeString( overHeadText ); + } + overHeadText = (char *) text; + overHeadTextPos.empty(); + if (text) { + timeStartDisplaying = core->GetGame()->Ticks; + textDisplaying = 1; + } + else { + timeStartDisplaying = 0; + textDisplaying = 0; + } +} + +/* 'fix' the current overhead text in the current position */ +void Scriptable::FixHeadTextPos() +{ + overHeadTextPos = Pos; +} + +#define MAX_DELAY 6000 +static const Color black={0,0,0,0}; + +void Scriptable::DrawOverheadText(const Region &screen) +{ + unsigned long time = core->GetGame()->Ticks; + Palette *palette = NULL; + + if (!textDisplaying) + return; + + time -= timeStartDisplaying; + + Font* font = core->GetFont( 1 ); + if (time >= MAX_DELAY) { + textDisplaying = 0; + return; + } else { + time = (MAX_DELAY-time)/10; + if (time<256) { + const Color overHeadColor = {time,time,time,time}; + palette = core->CreatePalette(overHeadColor, black); + } + } + + int cs = 100; + if (Type == ST_ACTOR) { + cs = ((Selectable *) this)->size*50; + } + + short x, y; + if (overHeadTextPos.isempty()) { + x = Pos.x; + y = Pos.y; + } else { + x = overHeadTextPos.x; + y = overHeadTextPos.y; + } + + Region rgn( x-100+screen.x, y - cs + screen.y, 200, 400 ); + font->Print( rgn, ( unsigned char * ) overHeadText, + palette?palette:core->InfoTextPalette, IE_FONT_ALIGN_CENTER | IE_FONT_ALIGN_TOP, false ); + gamedata->FreePalette(palette); +} + +void Scriptable::DelayedEvent() +{ + lastRunTime = core->GetGame()->Ticks; +} + +void Scriptable::ImmediateEvent() +{ + lastRunTime = 0; +} + +bool Scriptable::IsPC() const +{ + if(Type == ST_ACTOR) { + if (((Actor *) this)->GetStat(IE_EA) <= EA_CHARMED) { + return true; + } + } + return false; +} + +void Scriptable::ExecuteScript(int scriptCount) +{ + // area scripts still run for at least the current area, in bg1 (see ar2631, confirmed by testing) + // but not in bg2 (kill Abazigal in ar6005) + if (core->GetGameControl()->GetScreenFlags()&SF_CUTSCENE) { + if (! (core->HasFeature(GF_CUTSCENE_AREASCRIPTS) && Type == ST_AREA)) { + return; + } + } + + // Don't abort if there is a running non-interruptable action. + if ((InternalFlags & IF_NOINT) && (CurrentAction || GetNextAction())) { + return; + } + if (!CurrentActionInterruptable) { + // sanity check + if (!CurrentAction && !GetNextAction()) + abort(); + 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; + // TODO: hardcoded action hacks + + bool continuing = false, done = false; + for (int i = 0;iUpdate(&continuing, &done); + } + + /* scripts are not concurrent, see WAITPC override script for example */ + if (done) break; + } + if (changed && UnselectableTimer) { + UnselectableTimer--; + if (!UnselectableTimer) { + if (Type == ST_ACTOR) { + ((Actor *) this)->SetCircleSize(); + } + } + } + + if (changed) + ClearTriggers(); +} + +void Scriptable::AddAction(Action* aC) +{ + if (!aC) { + printf( "[GameScript]: NULL action encountered for %s!\n",scriptName ); + return; + } + + InternalFlags|=IF_ACTIVE; + aC->IncRef(); + + // attempt to handle 'instant' actions, from instant.ids, which run immediately + // when added if the action queue is empty, even on actors which are Held/etc + if (!CurrentAction && !GetNextAction()) { + if (actionflags[aC->actionID] & AF_INSTANT) { + CurrentAction = aC; + GameScript::ExecuteAction( this, CurrentAction ); + return; + } + } + + actionQueue.push_back( aC ); +} + +void Scriptable::AddActionInFront(Action* aC) +{ + if (!aC) { + printf( "[GameScript]: NULL action encountered for %s!\n",scriptName ); + return; + } + InternalFlags|=IF_ACTIVE; + actionQueue.push_front( aC ); + aC->IncRef(); +} + +Action* Scriptable::GetNextAction() const +{ + if (actionQueue.size() == 0) { + return NULL; + } + return actionQueue.front(); +} + +Action* Scriptable::PopNextAction() +{ + if (actionQueue.size() == 0) { + return NULL; + } + Action* aC = actionQueue.front(); + actionQueue.pop_front(); + return aC; +} + +void Scriptable::ClearActions() +{ + ReleaseCurrentAction(); + for (unsigned int i = 0; i < actionQueue.size(); i++) { + Action* aC = actionQueue.front(); + actionQueue.pop_front(); + aC->Release(); + } + actionQueue.clear(); + WaitCounter = 0; + LastTarget = 0; + + if (Type == ST_ACTOR) { + Interrupt(); + } else { + NoInterrupt(); + } +} + +void Scriptable::ReleaseCurrentAction() +{ + if (CurrentAction) { + CurrentAction->Release(); + CurrentAction = NULL; + } + + CurrentActionState = 0; + CurrentActionTarget = 0; + CurrentActionInterruptable = true; +} + +void Scriptable::ProcessActions(bool force) +{ + unsigned long thisTime = core->GetGame()->Ticks; + + if (!force && (( thisTime - startTime ) < interval)) { + return; + } + startTime = thisTime; + if (WaitCounter) { + WaitCounter--; + if (WaitCounter) return; + } + + while (true) { + CurrentActionInterruptable = true; + if (!CurrentAction) { + CurrentAction = PopNextAction(); + } + if (!CurrentAction) { + ClearActions(); + break; + } + GameScript::ExecuteAction( this, CurrentAction ); + //break execution in case of a Wait flag + if (WaitCounter) { + break; + } + //break execution in case of blocking action + if (CurrentAction) { + break; + } + //break execution in case of movement + //we should not actually break here, or else fix waypoints + if (InMove()) { + break; + } + } + if (InternalFlags&IF_IDLE) { + Deactivate(); + } +} + +bool Scriptable::InMove() const +{ + if (Type!=ST_ACTOR) { + return false; + } + Movable *me = (Movable *) this; + return me->GetNextStep()!=NULL; +} + +void Scriptable::SetWait(unsigned long time) +{ + WaitCounter = time; +} + +unsigned long Scriptable::GetWait() const +{ + return WaitCounter; +} + +void Scriptable::LeaveDialog() +{ + InternalFlags |=IF_WASINDIALOG; +} + +void Scriptable::Hide() +{ + InternalFlags &=~(IF_VISIBLE); +} + +void Scriptable::Unhide() +{ + InternalFlags |= IF_VISIBLE; +} + +void Scriptable::Interrupt() +{ + InternalFlags &= ~IF_NOINT; +} + +void Scriptable::NoInterrupt() +{ + InternalFlags |= IF_NOINT; +} + +//also turning off the idle flag so it won't run continuously +void Scriptable::Deactivate() +{ + InternalFlags &=~(IF_ACTIVE|IF_IDLE); +} + +//turning off the not interruptable flag, actions should reenable it themselves +//also turning off the idle flag +//heh, no, i wonder why did i touch the interruptable flag here +void Scriptable::Activate() +{ + InternalFlags |= IF_ACTIVE; + InternalFlags &= ~IF_IDLE; +} + +void Scriptable::PartyRested() +{ + InternalFlags |=IF_PARTYRESTED; +} + +ieDword Scriptable::GetInternalFlag() +{ + return InternalFlags; +} + +void Scriptable::InitTriggers() +{ + tolist.clear(); + bittriggers = 0; +} + +void Scriptable::ClearTriggers() +{ + for (TriggerObjects::iterator m = tolist.begin(); m != tolist.end (); m++) { + *(*m) = 0; + } + if (!bittriggers) { + return; + } + if (bittriggers & BT_DIE) { + InternalFlags &= ~IF_JUSTDIED; + } + if (bittriggers & BT_ONCREATION) { + InternalFlags &= ~IF_ONCREATION; + } + if (bittriggers & BT_BECAMEVISIBLE) { + InternalFlags &= ~IF_BECAMEVISIBLE; + } + if (bittriggers & BT_PARTYRESTED) { + InternalFlags &= ~IF_PARTYRESTED; + } + if (bittriggers & BT_WASINDIALOG) { + InternalFlags &= ~IF_WASINDIALOG; + } + if (bittriggers & BT_PARTYRESTED) { + InternalFlags &= ~IF_PARTYRESTED; + } + InitTriggers(); +} + +void Scriptable::SetBitTrigger(ieDword bittrigger) +{ + bittriggers |= bittrigger; +} + +void Scriptable::AddTrigger(ieDword *actorref) +{ + tolist.push_back(actorref); +} + +static EffectRef fx_set_invisible_state_ref = { "State:Invisible", -1 }; + +void Scriptable::CreateProjectile(const ieResRef SpellResRef, ieDword tgt, int level, bool fake) +{ + Spell* spl = gamedata->GetSpell( SpellResRef ); + Actor *caster = NULL; + + //PST has a weird effect, called Enoll Eva's duplication + //it creates every projectile of the affected actor twice + int duplicate = 1; + if (Type == ST_ACTOR) { + caster = (Actor *) this; + //FIXME: 1 duplicate is no duplicate, right? + duplicate = caster->wildSurgeMods.num_castings; + if (!duplicate) { + duplicate = 1; + } + } + if (core->HasFeature(GF_PST_STATE_FLAGS) && (Type == ST_ACTOR)) { + if (caster->GetStat(IE_STATE_ID)&STATE_EE_DUPL) { + //seriously, wild surges and EE in the same game? + //anyway, it would be too many duplications + duplicate = 2; + } + } + + while(duplicate --) { + Projectile *pro = NULL; + // jump through hoops to skip applying selftargetting spells to the caster + // if we'll be changing the target + int tct = 0; + if (caster) { + tct = caster->wildSurgeMods.target_change_type; + } + if (!caster || !tct || tct == WSTC_ADDTYPE || !caster->wildSurgeMods.projectile_id) { + pro = spl->GetProjectile(this, SpellHeader, LastTargetPos); + if (!pro) { + return; + } + pro->SetCaster(GetGlobalID(), level); + } + + Point origin = Pos; + if (Type == ST_TRIGGER || Type == ST_PROXIMITY) { + // try and make projectiles start from the right trap position + // see the traps in the duergar/assassin battle in bg2 dungeon + // see also function below - maybe we should fix Pos instead + origin = ((InfoPoint *)this)->TrapLaunch; + } + + if (caster) { + // check for target (type) change + int count, i; + Actor *newact = NULL; + SPLExtHeader *seh = NULL; + Effect *fx = NULL; + switch (caster->wildSurgeMods.target_change_type) { + case WSTC_SETTYPE: + seh = &spl->ext_headers[SpellHeader]; + for (i=0; i < seh->FeatureCount; i++) { + seh->features[i].Target = caster->wildSurgeMods.target_type; + } + // we need to fetch the projectile, so the effect queue is created + // (skipped above) + pro = spl->GetProjectile(this, SpellHeader, LastTargetPos); + pro->SetCaster(GetGlobalID(), level); + break; + case WSTC_ADDTYPE: + // TODO: unhardcode to allow for mixing all the target types + // caster gets selftargetting fx when the projectile is fetched above + seh = &spl->ext_headers[SpellHeader]; + for (i=0; i < seh->FeatureCount; i++) { + if (seh->features[i].Target == FX_TARGET_SELF) { + seh->features[i].Target = caster->wildSurgeMods.target_type; + } else { + // also apply to the caster + fx = seh->features+i; + core->ApplyEffect(fx, caster, caster); + } + } + // we need to refetch the projectile, so the effect queue is created + pro = spl->GetProjectile(this, SpellHeader, LastTargetPos); + pro->SetCaster(GetGlobalID(), level); + break; + case WSTC_RANDOMIZE: + count = area->GetActorCount(false); + newact = area->GetActor(core->Roll(1,count,-1), false); + if (count > 1 && newact == caster) { + while (newact == caster) { + newact = area->GetActor(core->Roll(1,count,-1), false); + } + } + if (tgt) { + LastTarget = newact->GetGlobalID(); + LastTargetPos = newact->Pos; + } else { + // no better idea; I wonder if the original randomized point targets at all + LastTargetPos = newact->Pos; + } + + // make it also work for self-targetting spells: + // change the payload or this was all in vain + seh = &spl->ext_headers[SpellHeader]; + for (i=0; i < seh->FeatureCount; i++) { + if (seh->features[i].Target == FX_TARGET_SELF) { + seh->features[i].Target = FX_TARGET_PRESET; + } + } + // we need to fetch the projectile, so the effect queue is created + // (skipped above) + pro = spl->GetProjectile(this, SpellHeader, LastTargetPos); + pro->SetCaster(GetGlobalID(), level); + break; + default: //0 - do nothing + break; + } + + // apply the saving throw mod + if (caster->wildSurgeMods.saving_throw_mod) { + seh = &spl->ext_headers[SpellHeader]; + for (i=0; i < seh->FeatureCount; i++) { + seh->features[i].SavingThrowBonus += caster->wildSurgeMods.saving_throw_mod; + } + } + + // change the projectile + if (caster->wildSurgeMods.projectile_id) { + spl->ext_headers[SpellHeader].ProjectileAnimation = caster->wildSurgeMods.projectile_id; + // make it also work for self-targetting spells: + // change the payload or this was all in vain + seh = &spl->ext_headers[SpellHeader]; + for (i=0; i < seh->FeatureCount; i++) { + if (seh->features[i].Target == FX_TARGET_SELF) { + seh->features[i].Target = FX_TARGET_PRESET; + } + } + // we need to refetch the projectile, so the new one is used + pro = spl->GetProjectile(this, SpellHeader, LastTargetPos); + pro->SetCaster(GetGlobalID(), level); + } + + // check for the speed mod + if (caster->wildSurgeMods.projectile_speed_mod) { + pro->Speed = (pro->Speed * caster->wildSurgeMods.projectile_speed_mod) / 100; + if (!pro->Speed) { + pro->Speed = 1; + } + } + } + + if (tgt) { + area->AddProjectile(pro, origin, LastTarget, fake); + } else { + area->AddProjectile(pro, origin, LastTargetPos); + } + } + + ieDword spellnum=ResolveSpellNumber( SpellResRef ); + if (spellnum!=0xffffffff) { + area->SeeSpellCast(this, spellnum); + + // caster - Casts spellname : target OR + // caster - spellname : target (repeating spells) + Scriptable *target = NULL; + char tmp[100]; + const char* msg = core->GetString(displaymsg->GetStringReference(STR_ACTION_CAST), 0); + const char* spell = core->GetString(spl->SpellName); + if (LastTarget) { + target = area->GetActorByGlobalID(LastTarget); + if (!target) { + target=core->GetGame()->GetActorByGlobalID(LastTarget); + } + } + if (stricmp(spell, "")) { + if (target) { + snprintf(tmp, sizeof(tmp), "%s %s : %s", msg, spell, target->GetName(-1)); + } else { + snprintf(tmp, sizeof(tmp), "%s : %s", spell, GetName(-1)); + } + displaymsg->DisplayStringName(tmp, 0xffffff, this); + } + + if(LastTarget) { + if (target && (Type==ST_ACTOR) ) { + target->LastSpellOnMe = spellnum; + target->LastCasterOnMe = caster->GetGlobalID(); + // don't cure invisibility if this is a self targetting invisibility spell + // like shadow door + //can't check GetEffectBlock, since it doesn't construct the queue for selftargetting spells + bool invis = false; + unsigned int opcode = EffectQueue::ResolveEffect(fx_set_invisible_state_ref); + for (unsigned int i=0; i < spl->ext_headers[SpellHeader].FeatureCount; i++) { + if (spl->GetExtHeader(SpellHeader)->features[i].Opcode == opcode) { + invis = true; + break; + } + } + if (invis && spl->GetExtHeader(SpellHeader)->Target == TARGET_SELF) { + //pass + } else { + caster->CureInvisibility(); + } + // sanctuary ends with all hostile actions or when the caster targets someone else + if (target != this || spl->Flags & SF_HOSTILE) { + caster->CureSanctuary(); + } + } + } + } + + core->Autopause(AP_SPELLCAST); + + gamedata->FreeSpell(spl, SpellResRef, false); + +} + +void Scriptable::CastSpellPointEnd(int level) +{ + Actor *caster = NULL; + if (Type == ST_ACTOR) { + caster = ((Actor *) this); + caster->SetStance(IE_ANI_CONJURE); + if (level == 0) { + Spell* spl = gamedata->GetSpell(SpellResRef); // this was checked before we got here + Actor *actor = NULL; + if (Type == ST_ACTOR) { + actor = (Actor *) this; + level = actor->GetCasterLevel(spl->SpellType); + } + gamedata->FreeSpell(spl, SpellResRef, false); + } + } + + if (SpellHeader == -1) { + LastTargetPos.empty(); + return; + } + + if (LastTargetPos.isempty()) { + SpellHeader = -1; + return; + } + + if (!SpellResRef[0]) { + return; + } + + CreateProjectile(SpellResRef, 0, level, false); + + SpellHeader = -1; + SpellResRef[0] = 0; + LastTarget = 0; + LastTargetPos.empty(); + if (caster) { + memset(&(caster->wildSurgeMods), 0, sizeof(caster->wildSurgeMods)); + } +} + +void Scriptable::CastSpellEnd(int level) +{ + Actor *caster = NULL; + if (Type == ST_ACTOR) { + caster = ((Actor *) this); + caster->SetStance(IE_ANI_CONJURE); + if (level == 0) { + Spell* spl = gamedata->GetSpell(SpellResRef); // this was checked before we got here + Actor *actor = NULL; + if (Type == ST_ACTOR) { + actor = (Actor *) this; + level = actor->GetCasterLevel(spl->SpellType); + } + gamedata->FreeSpell(spl, SpellResRef, false); + } + } + + if (SpellHeader == -1) { + LastTarget = 0; + return; + } + if (!LastTarget) { + SpellHeader = -1; + return; + } + if (!SpellResRef[0]) { + return; + } + + //if the projectile doesn't need to follow the target, then use the target position + CreateProjectile(SpellResRef, LastTarget, level, GetSpellDistance(SpellResRef, this)==0xffffffff); + SpellHeader = -1; + SpellResRef[0] = 0; + LastTarget = 0; + LastTargetPos.empty(); + if (caster) { + memset(&(caster->wildSurgeMods), 0, sizeof(caster->wildSurgeMods)); + } +} + +// check for input sanity and good casting conditions +int Scriptable::CanCast(const ieResRef SpellResRef) { + Spell* spl = gamedata->GetSpell(SpellResRef); + if (!spl) { + SpellHeader = -1; + printMessage("Scriptable", "Spell not found, aborting cast!\n", LIGHT_RED); + return 0; + } + + // check for area dead magic + // tob AR3004 is a dead magic area, but using a script with personal dead magic + if (area->GetInternalFlag()&AF_DEADMAGIC) { + // TODO: display fizzling animation + displaymsg->DisplayConstantStringName(STR_DEADMAGIC_FAIL, 0xffffff, this); + return 0; + } + + // various individual checks + if (Type == ST_ACTOR) { + Actor *actor = (Actor *) this; + + // check for silence + // only a handful of spells don't have a verbal component - + // the original hardcoded vocalize and a few more + // we (also) ignore nonmagic spells + if (actor->Modified[IE_STATE_ID] & STATE_SILENCED) { + if (!(core->GetSpecialSpell(spl->Name)&SP_SILENCE) && !(spl->Flags&SF_HLA)) { + printMessage("Scriptable", "Tried to cast while silenced!\n", YELLOW); + return 0; + } + } + + // check for personal dead magic + if (actor->Modified[IE_DEADMAGIC]) { + // TODO: display fizzling animation + displaymsg->DisplayConstantStringName(STR_DEADMAGIC_FAIL, 0xffffff, this); + return 0; + } + + // check for miscast magic and similar + ieDword roll = actor->LuckyRoll(1, 100, 0, 0); + bool failed = false; + switch(spl->SpellType) + { + case IE_SPL_PRIEST: + if (actor->Modified[IE_SPELLFAILUREPRIEST] >= roll) { + failed = true; + } + break; + case IE_SPL_WIZARD: + if (actor->Modified[IE_SPELLFAILUREMAGE] >= roll) { + failed = true; + } + break; + case IE_SPL_INNATE: + if (actor->Modified[IE_SPELLFAILUREINNATE] >= roll) { + failed = true; + } + break; + } + if (failed) { + // TODO: display fizzling animation + displaymsg->DisplayConstantStringName(STR_MISCASTMAGIC, 0xffffff, this); + return 0; + } + } + + return 1; +} + +//set target as point +//if spell needs to be depleted, do it +//if spell is illegal stop casting +int Scriptable::CastSpellPoint( ieResRef &SpellRef, const Point &target, bool deplete, bool instant ) +{ + LastTarget = 0; + LastTargetPos.empty(); + if (Type == ST_ACTOR) { + Actor *actor = (Actor *) this; + if (actor->HandleCastingStance(SpellRef,deplete) ) { + printMessage("Scriptable", "Spell not known or memorized, aborting cast!\n", LIGHT_RED); + return -1; + } + } + if(deplete && !CanCast(SpellRef)) { + SpellResRef[0] = 0; + if (Type == ST_ACTOR) { + Actor *actor = (Actor *) this; + actor->SetStance(IE_ANI_READY); + } + return -1; + } + + if (!SpellResRef[0]) { + SetSpellResRef(SpellRef); + } + + LastTargetPos = target; + + if(!CheckWildSurge()) { + return -1; + } + return SpellCast(instant); +} + +//set target as actor (if target isn't actor, use its position) +//if spell needs to be depleted, do it +//if spell is illegal stop casting +int Scriptable::CastSpell( ieResRef &SpellRef, Scriptable* target, bool deplete, bool instant ) +{ + LastTarget = 0; + LastTargetPos.empty(); + if (Type == ST_ACTOR) { + Actor *actor = (Actor *) this; + if (actor->HandleCastingStance(SpellRef,deplete) ) { + printMessage("Scriptable", "Spell not known or memorized, aborting cast!\n", LIGHT_RED); + return -1; + } + } + + // FIXME: fishy + if (!target) target = this; + + if(deplete && !CanCast(SpellRef)) { + SpellResRef[0] = 0; + if (Type == ST_ACTOR) { + Actor *actor = (Actor *) this; + actor->SetStance(IE_ANI_READY); + } + return -1; + } + + if (!SpellResRef[0]) { + SetSpellResRef(SpellRef); + } + + LastTargetPos = target->Pos; + if (target->Type==ST_ACTOR) { + LastTarget = target->GetGlobalID(); + } + + if(!CheckWildSurge()) { + return -1; + } + + return SpellCast(instant); +} + +static EffectRef fx_force_surge_modifier_ref = { "ForceSurgeModifier", -1 }; + +//start spellcasting (common part) +int Scriptable::SpellCast(bool instant) +{ + Spell* spl = gamedata->GetSpell(SpellResRef); // this was checked before we got here + Actor *actor = NULL; + int level = 0; + if (Type == ST_ACTOR) { + actor = (Actor *) this; + + //The ext. index is here to calculate the casting time + level = actor->GetCasterLevel(spl->SpellType); + SpellHeader = spl->GetHeaderIndexFromLevel(level); + } else { + SpellHeader = 0; + } + + SPLExtHeader *header = spl->GetExtHeader(SpellHeader); + int casting_time = (int)header->CastingTime; + // how does this work for non-actors exactly? + if (actor) { + // The mental speed effect can shorten or lengthen the casting time. + casting_time -= (int)actor->Modified[IE_MENTALSPEED]; + if (casting_time < 0) casting_time = 0; + } + // this is a guess which seems approximately right so far + int duration = (casting_time*core->Time.round_size) / 10; + if (instant) { + duration = 0; + } + if (actor) { + //cfb + EffectQueue *fxqueue = spl->GetEffectBlock(this, this->Pos, -1, level); + fxqueue->SetOwner(actor); + if (!actor->Modified[IE_AVATARREMOVAL]) { + spl->AddCastingGlow(fxqueue, duration, actor->Modified[IE_SEX]); + } + fxqueue->AddAllEffects(actor, actor->Pos); + delete fxqueue; + actor->WMLevelMod = 0; + if (actor->Modified[IE_FORCESURGE] == 1) { + // affects only the next spell cast, but since the timing is permanent, + // we have to remove it manually + actor->fxqueue.RemoveAllEffectsWithParam(fx_force_surge_modifier_ref, 1); + } + } + + gamedata->FreeSpell(spl, SpellResRef, false); + return duration; +} + +// Anyone with some wildness has 5% chance of getting a wild surge when casting, +// but most innates are excluded, due to being nonmagic. +// A d100 roll is made, some stat boni are added, then either: +// 1. the spell is cast normally (score of 100 or more) +// 2. one or more wild surges happen and something else is cast +// 2.1. this can loop, since some surges cause rerolls +int Scriptable::CheckWildSurge() +{ + if (Type != ST_ACTOR || core->HasFeature(GF_3ED_RULES)) { + return 1; + } + Actor *caster = (Actor *) this; + + int roll = core->Roll(1, 100, 0); + if ((roll <= 5 && caster->Modified[IE_SURGEMOD]) || caster->Modified[IE_FORCESURGE]) { + ieResRef OldSpellResRef; + memcpy(OldSpellResRef, SpellResRef, sizeof(OldSpellResRef)); + Spell *spl = gamedata->GetSpell( OldSpellResRef ); // this was checked before we got here + // ignore non-magic "spells" + if (!(spl->Flags&SF_HLA)) { + int check = roll + caster->GetCasterLevel(spl->SpellType) + caster->Modified[IE_SURGEMOD]; + // hundred or more means a normal cast + if (check < 100) { + // display feedback: Wild Surge: bla bla + char text[200]; + snprintf(text, 200, "%s %s", core->GetString(displaymsg->GetStringReference(STR_WILDSURGE), 0), core->GetString(core->SurgeSpells[check-1].message, 0)); + displaymsg->DisplayStringName(text, 0xffffff, this); + + // lookup the spell in the "check" row of wildmag.2da + ieResRef surgeSpellRef; + memset(surgeSpellRef, 0, sizeof(surgeSpellRef)); + strncpy(surgeSpellRef, core->SurgeSpells[check-1].spell, 8); + + if (!gamedata->Exists(surgeSpellRef, IE_SPL_CLASS_ID)) { + // handle the hardcoded cases - they'll also fail here + if (!HandleHardcodedSurge(surgeSpellRef, spl, caster)) { + //free the spell handle because we need to return + gamedata->FreeSpell(spl, OldSpellResRef, false); + return 0; + } + } else { + // finally change the spell + // the hardcoded bunch does it on its own when needed + strncpy(SpellResRef, surgeSpellRef, 8); + } + } + } + + //free the spell handle + gamedata->FreeSpell(spl, OldSpellResRef, false); + } + + return 1; +} + +bool Scriptable::HandleHardcodedSurge(ieResRef surgeSpellRef, Spell *spl, Actor *caster) +{ + // format: ID or ID.param1 or +SPELLREF + int types = caster->spellbook.GetTypes(); + int lvl = spl->SpellLevel-1; + int count, i, tmp, tmp2, tmp3; + Scriptable *target = NULL; + Point targetpos(-1, -1); + ieResRef newspl; + + int level = caster->GetCasterLevel(spl->SpellType); + switch (surgeSpellRef[0]) { + case '+': // cast normally, but also cast SPELLREF first + core->ApplySpell(surgeSpellRef+1, caster, caster, level); + break; + case '0': // cast spell param1 times + strtok(surgeSpellRef,"."); + count = strtol(strtok(NULL,"."), NULL, 0); + caster->wildSurgeMods.num_castings = count; + break; + case '1': // change projectile (id) to param1 + strtok(surgeSpellRef,"."); + count = strtol(strtok(NULL,"."), NULL, 0); + caster->wildSurgeMods.projectile_id = count; + break; + case '2': // also target target type param1 + strtok(surgeSpellRef,"."); + count = strtol(strtok(NULL,"."), NULL, 0); + caster->wildSurgeMods.target_type = count; + caster->wildSurgeMods.target_change_type = WSTC_ADDTYPE; + break; + case '3': // (wild surge) roll param1 more times + strtok(surgeSpellRef,"."); + count = strtol(strtok(NULL,"."), NULL, 0); + // force surge and then cast + // force the surge roll to be < 100, so we cast a spell from the surge table + tmp = caster->Modified[IE_FORCESURGE]; + tmp2 = caster->Modified[IE_SURGEMOD]; + tmp3 = caster->WMLevelMod; // also save caster level; the original didn't reroll the bonus + caster->Modified[IE_FORCESURGE] = 7; + caster->Modified[IE_SURGEMOD] = - caster->GetCasterLevel(spl->SpellType); // nulify the bonus + if (LastTarget) { + target = area->GetActorByGlobalID(LastTarget); + if (!target) { + target = core->GetGame()->GetActorByGlobalID(LastTarget); + } + } + if (!LastTargetPos.isempty()) { + targetpos = LastTargetPos; + } else if (target) { + targetpos = target->Pos; + } + for (i=0; iCastSpell(SpellResRef, target, false, true); + strncpy(newspl, SpellResRef, 8); + caster->WMLevelMod = tmp3; + caster->CastSpellEnd(level); + } else { + caster->CastSpellPoint(SpellResRef, targetpos, false, true); + strncpy(newspl, SpellResRef, 8); + caster->WMLevelMod = tmp3; + caster->CastSpellPointEnd(level); + } + // reset the ref, since CastSpell*End destroyed it + strncpy(SpellResRef, newspl, 8); + } + caster->Modified[IE_FORCESURGE] = tmp; + caster->Modified[IE_SURGEMOD] = tmp2; + break; + case '4': // change the target type to param1 + strtok(surgeSpellRef,"."); + count = strtol(strtok(NULL,"."), NULL, 0); + caster->wildSurgeMods.target_type = count; + caster->wildSurgeMods.target_change_type = WSTC_SETTYPE; + break; + case '5': // change the target to a random actor + caster->wildSurgeMods.target_change_type = WSTC_RANDOMIZE; + break; + case '6': // change saving throw (+param1) + strtok(surgeSpellRef,"."); + count = strtol(strtok(NULL,"."), NULL, 0); + caster->wildSurgeMods.saving_throw_mod = count; + break; + case '7': // random spell of the same level (FIXME: make an effect out of this?) + // change this if we ever want the surges to respect the original type + for (i=0; ispellbook.GetKnownSpellsCount(i, lvl); + if (!spellCount) continue; + int id = core->Roll(1, spellCount, -1); + CREKnownSpell *ck = caster->spellbook.GetKnownSpell(i, lvl, id); + if (ck) { + strncpy(SpellResRef, ck->SpellResRef, 8); + break; + } + } + break; + case '8': // set projectile speed to param1 % + strtok(surgeSpellRef,"."); + count = strtol(strtok(NULL,"."), NULL, 0); + caster->wildSurgeMods.projectile_speed_mod = count; + break; + default: + SpellHeader = -1; + SpellResRef[0] = 0; + printMessage("Scriptable", "New spell not found, aborting cast mid-surge!\n", LIGHT_RED); + caster->SetStance(IE_ANI_READY); + return false; + } + return true; +} + +bool Scriptable::TimerActive(ieDword ID) +{ + if (ID>=MAX_TIMER) { + return false; + } + if (script_timers[ID]) { + return true; + } + return false; +} + +bool Scriptable::TimerExpired(ieDword ID) +{ + if (ID>=MAX_TIMER) { + return false; + } + if (script_timers[ID] && script_timers[ID] < core->GetGame()->GameTime) { + // expired timers become inactive after being checked + script_timers[ID] = 0; + return true; + } + return false; +} + +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); + return; + } + script_timers[ID]= core->GetGame()->GameTime + expiration*AI_UPDATE_TIME; +} + +/******************** + * Selectable Class * + ********************/ + +Selectable::Selectable(ScriptableType type) + : Scriptable( type ) +{ + Selected = false; + Over = false; + size = 0; + cover = NULL; + circleBitmap[0] = NULL; + circleBitmap[1] = NULL; +} + +void Selectable::SetSpriteCover(SpriteCover* c) +{ + delete cover; + cover = c; +} + +Selectable::~Selectable(void) +{ + delete cover; +} + +void Selectable::SetBBox(const Region &newBBox) +{ + BBox = newBBox; +} + +static const unsigned long tp_steps[8]={3,2,1,0,1,2,3,4}; + +void Selectable::DrawCircle(const Region &vp) +{ + /* BG2 colours ground circles as follows: + dark green for unselected party members + bright green for selected party members + flashing green/white for a party member the mouse is over + bright red for enemies + yellow for panicked actors + flashing red/white for enemies the mouse is over + flashing cyan/white for neutrals the mouse is over + */ + + if (size<=0) { + return; + } + Color mix; + Color* col = &selectedColor; + Sprite2D* sprite = circleBitmap[0]; + + if (Selected) { + sprite = circleBitmap[1]; + } else if (Over) { + //doing a time dependent flashing of colors + //if it is too fast, increase the 6 to 7 + unsigned long step; + GetTime( step ); + step = tp_steps [(step >> 6) & 7]; + mix.a = overColor.a; + mix.r = (overColor.r*step+selectedColor.r*(8-step))/8; + mix.g = (overColor.g*step+selectedColor.g*(8-step))/8; + mix.b = (overColor.b*step+selectedColor.b*(8-step))/8; + col = &mix; + } else if (IsPC()) { + col = &overColor; + } + + if (sprite) { + core->GetVideoDriver()->BlitSprite( sprite, Pos.x - vp.x, Pos.y - vp.y, true ); + } else { + // for size >= 2, radii are (size-1)*16, (size-1)*12 + // for size == 1, radii are 12, 9 + int csize = (size - 1) * 4; + if (csize < 4) csize = 3; + core->GetVideoDriver()->DrawEllipse( (ieWord) (Pos.x - vp.x), (ieWord) (Pos.y - vp.y), + (ieWord) (csize * 4), (ieWord) (csize * 3), *col ); + } +} + +// Check if P is over our ground circle +bool Selectable::IsOver(const Point &P) const +{ + int csize = size; + if (csize < 2) csize = 2; + + int dx = P.x - Pos.x; + int dy = P.y - Pos.y; + + // check rectangle first + if (dx < -(csize-1)*16 || dx > (csize-1)*16) return false; + if (dy < -(csize-1)*12 || dy > (csize-1)*12) return false; + + // then check ellipse + int r = 9*dx*dx + 16*dy*dy; // 48^2 * ( (dx/16)^2 + (dy/12)^2 ) + + return (r <= 48*48*(csize-1)*(csize-1)); +} + +bool Selectable::IsSelected() const +{ + return Selected == 1; +} + +void Selectable::SetOver(bool over) +{ + Over = over; +} + +//don't call this function after rendering the cover and before the +//blitting of the sprite or bad things will happen :) +void Selectable::Select(int Value) +{ + if (Selected!=0x80 || Value!=1) { + Selected = (ieWord) Value; + } + //forcing regeneration of the cover + SetSpriteCover(NULL); +} + +void Selectable::SetCircle(int circlesize, const Color &color, Sprite2D* normal_circle, Sprite2D* selected_circle) +{ + size = circlesize; + selectedColor = color; + overColor.r = color.r >> 1; + overColor.g = color.g >> 1; + overColor.b = color.b >> 1; + overColor.a = color.a; + circleBitmap[0] = normal_circle; + circleBitmap[1] = selected_circle; +} + +//used for creatures +int Selectable::WantDither() +{ + //if dithering is disabled globally, don't do it + if (core->FogOfWar&FOG_DITHERSPRITES) { + return 0; + } + //if actor is dead, dither it if polygon wants + if (Selected&0x80) { + return 1; + } + //if actor is selected dither it + if (Selected) { + return 2; + } + return 1; +} + +/*********************** + * Highlightable Class * + ***********************/ + +Highlightable::Highlightable(ScriptableType type) + : Scriptable( type ) +{ + outline = NULL; + Highlight = false; + Cursor = IE_CURSOR_NORMAL; + KeyResRef[0] = 0; +} + +Highlightable::~Highlightable(void) +{ + if (outline) { + delete( outline ); + } +} + +bool Highlightable::IsOver(const Point &Pos) const +{ + if (!outline) { + return false; + } + return outline->PointIn( Pos ); +} + +void Highlightable::DrawOutline() const +{ + if (!outline) { + return; + } + core->GetVideoDriver()->DrawPolyline( outline, outlineColor, true ); +} + +void Highlightable::SetCursor(unsigned char CursorIndex) +{ + Cursor = CursorIndex; +} + +bool Highlightable::TryUnlock(Actor *actor, bool removekey) { + const char *Key = GetKey(); + Actor *haskey = NULL; + + if (Key && actor->InParty) { + Game *game = core->GetGame(); + //allow unlock when the key is on any partymember + for (int idx = 0; idx < game->GetPartySize(false); idx++) { + Actor *pc = game->FindPC(idx + 1); + if (!pc) continue; + + if (pc->inventory.HasItem(Key,0) ) { + haskey = pc; + break; + } + } + } else if (Key) { + //actor is not in party, check only actor + if (actor->inventory.HasItem(Key,0) ) { + haskey = actor; + } + } + + if (!haskey) { + return false; + } + + if (removekey) { + CREItem *item = NULL; + haskey->inventory.RemoveItem(Key,0,&item); + //the item should always be existing!!! + if (item) { + delete item; + } + } + + return true; +} + + +/***************** + * Movable Class * + *****************/ + +Movable::Movable(ScriptableType type) + : Selectable( type ) +{ + Destination = Pos; + Orientation = 0; + NewOrientation = 0; + StanceID = 0; + path = NULL; + step = NULL; + timeStartStep = 0; + lastFrame = NULL; + Area[0] = 0; + AttackMovements[0] = 100; + AttackMovements[1] = 0; + AttackMovements[2] = 0; +} + +Movable::~Movable(void) +{ + if (path) { + ClearPath(); + } +} + +int Movable::GetPathLength() +{ + PathNode *node = GetNextStep(0); + int i = 0; + while (node->Next) { + i++; + node = node->Next; + } + return i; +} + +PathNode *Movable::GetNextStep(int x) +{ + if (!step) { + DoStep((unsigned int) ~0); + } + PathNode *node = step; + while(node && x--) { + node = node->Next; + } + return node; +} + +Point Movable::GetMostLikelyPosition() +{ + if (!path) { + return Pos; + } + +//actually, sometimes middle path would be better, if +//we stand in Destination already + int halfway = GetPathLength()/2; + PathNode *node = GetNextStep(halfway); + if (node) { + return Point((ieWord) ((node->x*16)+8), (ieWord) ((node->y*12)+6) ); + } + return Destination; +} + +void Movable::SetStance(unsigned int arg) +{ + //don't modify stance from dead back to anything if the actor is dead + if ((StanceID==IE_ANI_TWITCH || StanceID==IE_ANI_DIE) && (arg!=IE_ANI_TWITCH) ) { + if (GetInternalFlag()&IF_REALLYDIED) { + printMessage("Movable","Stance overridden by death\n", YELLOW); + return; + } + } + + if (StanceID == IE_ANI_CONJURE && StanceID != arg && Type ==ST_ACTOR) { + Actor *caster = (Actor *) this; + if (caster->casting_sound) { + caster->casting_sound->Stop(); + caster->casting_sound.release(); + } + } + + if (argGetLine( p, steps, orient, Pass ); +} + +void AdjustPositionTowards(Point &Pos, ieDword time_diff, unsigned int walk_speed, short srcx, short srcy, short destx, short desty) { + if (destx > srcx) + Pos.x += ( unsigned short ) + ( ( ( ( ( destx * 16 ) + 8 ) - Pos.x ) * ( time_diff ) ) / walk_speed ); + else + Pos.x -= ( unsigned short ) + ( ( ( Pos.x - ( ( destx * 16 ) + 8 ) ) * ( time_diff ) ) / walk_speed ); + if (desty > srcy) + Pos.y += ( unsigned short ) + ( ( ( ( ( desty * 12 ) + 6 ) - Pos.y ) * ( time_diff ) ) / walk_speed ); + else + Pos.y -= ( unsigned short ) + ( ( ( Pos.y - ( ( desty * 12 ) + 6 ) ) * ( time_diff ) ) / walk_speed ); +} + +// returns whether we made all pending steps (so, false if we must be called again this tick) +// we can't just do them all here because the caller might have to update searchmap etc +bool Movable::DoStep(unsigned int walk_speed, ieDword time) +{ + if (!path) { + return true; + } + if (!time) time = core->GetGame()->Ticks; + if (!walk_speed) { + // zero speed: no movement + timeStartStep = time; + StanceID = IE_ANI_READY; + return true; + } + if (!step) { + step = path; + timeStartStep = time; + } else if (step->Next && (( time - timeStartStep ) >= walk_speed)) { + //printf("[New Step] : Orientation = %d\n", step->orient); + step = step->Next; + timeStartStep = timeStartStep + walk_speed; + } + SetOrientation (step->orient, false); + StanceID = IE_ANI_WALK; + if ((Type == ST_ACTOR) && (InternalFlags & IF_RUNNING)) { + StanceID = IE_ANI_RUN; + } + Pos.x = ( step->x * 16 ) + 8; + Pos.y = ( step->y * 12 ) + 6; + if (!step->Next) { + // we reached our destination, we are done + ClearPath(); + NewOrientation = Orientation; + //since clearpath no longer sets currentaction to NULL + //we set it here + //no we don't, action is responsible for releasing itself + //ReleaseCurrentAction(); + return true; + } + if (( time - timeStartStep ) >= walk_speed) { + // we didn't finish all pending steps, yet + return false; + } + AdjustPositionTowards(Pos, time - timeStartStep, walk_speed, step->x, step->y, step->Next->x, step->Next->y); + return true; +} + +void Movable::AddWayPoint(const Point &Des) +{ + if (!path) { + WalkTo(Des); + return; + } + Destination = Des; + //it is tempting to use 'step' here, as it could + //be about half of the current path already + PathNode *endNode = path; + while(endNode->Next) { + endNode = endNode->Next; + } + Point p(endNode->x, endNode->y); + area->ClearSearchMapFor(this); + PathNode *path2 = area->FindPath( p, Des, size ); + endNode->Next = path2; + //probably it is wise to connect it both ways? + path2->Parent = endNode; +} + +void Movable::FixPosition() +{ + if (Type!=ST_ACTOR) { + return; + } + Actor *actor = (Actor *) this; + if (actor->GetStat(IE_DONOTJUMP)&DNJ_BIRD ) { + return; + } + //before fixposition, you should remove own shadow + area->ClearSearchMapFor(this); + Pos.x/=16; + Pos.y/=12; + GetCurrentArea()->AdjustPosition(Pos); + Pos.x=Pos.x*16+8; + Pos.y=Pos.y*12+6; +} + +void Movable::WalkTo(const Point &Des, int distance) +{ + Point from; + + // maybe caller should be responsible for this + if ((Des.x/16 == Pos.x/16) && (Des.y/12 == Pos.y/12)) { + ClearPath(); + return; + } + + // the prev_step stuff is a naive attempt to allow re-pathing while moving + PathNode *prev_step = NULL; + unsigned char old_stance = StanceID; + if (step && step->Next) { + // don't interrupt in the middle of a step; path from the next one + prev_step = new PathNode(*step); + from.x = ( step->Next->x * 16 ) + 8; + from.y = ( step->Next->y * 12 ) + 6; + } + + ClearPath(); + if (!prev_step) { + FixPosition(); + from = Pos; + } + area->ClearSearchMapFor(this); + if (distance) { + path = area->FindPathNear( from, Des, size, distance ); + } else { + path = area->FindPath( from, Des, size, distance ); + } + //ClearPath sets destination, so Destination must be set after it + //also we should set Destination only if there is a walkable path + if (path) { + Destination = Des; + + if (prev_step) { + // we want to smoothly continue, please + // this all needs more thought! but it seems to work okay + StanceID = old_stance; + + if (path->Next) { + // this is a terrible hack to make up for the + // pathfinder orienting the first node wrong + // should be fixed in pathfinder and not here! + Point next, follow; + next.x = path->x; next.y = path->y; + follow.x = path->Next->x; + follow.y = path->Next->y; + path->orient = GetOrient(follow, next); + } + + // then put the prev_step at the beginning of the path + prev_step->Next = path; + path->Parent = prev_step; + path = prev_step; + + step = path; + } + } else { + // pathing failed + if (prev_step) { + delete( prev_step ); + FixPosition(); + } + } +} + +void Movable::RunAwayFrom(const Point &Des, int PathLength, int flags) +{ + ClearPath(); + area->ClearSearchMapFor(this); + path = area->RunAway( Pos, Des, size, PathLength, flags ); +} + +void Movable::RandomWalk(bool can_stop, bool run) +{ + if (path) { + return; + } + //if not continous random walk, then stops for a while + if (can_stop && (rand()&3) ) { + SetWait((rand()&7)+7); + return; + } + if (run) { + InternalFlags|=IF_RUNNING; + } + //the commenting-out of the clear search map call was removed in 0.4.0 + //if you want to put it back for some reason, check + //if the searchmap is not eaten up + area->ClearSearchMapFor(this); + Point p = Pos; + + //selecting points around a circle's edge around actor (didn't work better) + //int x = core->Roll(1,100,-50); + //p.x+=x; + //p.y+=(int) sqrt(100-x*x); + + //selecting points in a square around actor + p.x+=core->Roll(1,50,-25); + p.y+=core->Roll(1,50,-25); + //the 5th parameter is controlling the orientation of the actor + //0 - back away, 1 - face direction + path = area->RunAway( Pos, p, size, 50, 1 ); +} + +void Movable::MoveTo(const Point &Des) +{ + area->ClearSearchMapFor(this); + Pos = Des; + Destination = Des; + if (BlocksSearchMap()) { + area->BlockSearchMap( Pos, size, IsPC()?PATH_MAP_PC:PATH_MAP_NPC); + } +} + +void Movable::ClearPath() +{ + //this is to make sure attackers come to us + //make sure ClearPath doesn't screw Destination (in the rare cases Destination + //is set before ClearPath + Destination = Pos; + if (StanceID==IE_ANI_WALK || StanceID==IE_ANI_RUN) { + StanceID = IE_ANI_AWAKE; + } + InternalFlags&=~IF_NORECTICLE; + PathNode* thisNode = path; + while (thisNode) { + PathNode* nextNode = thisNode->Next; + delete( thisNode ); + thisNode = nextNode; + } + path = NULL; + step = NULL; + //don't call ReleaseCurrentAction +} + +void Movable::DrawTargetPoint(const Region &vp) +{ + if (!path || !Selected || (InternalFlags&IF_NORECTICLE) ) + return; + + // recticles are never drawn in cutscenes + if ((core->GetGameControl()->GetScreenFlags()&SF_CUTSCENE)) + return; + + // generates "step" from sequence 3 2 1 0 1 2 3 4 + // updated each 1/15 sec + unsigned long step; + GetTime( step ); + step = tp_steps [(step >> 6) & 7]; + + step = step + 1; + int csize = (size - 1) * 4; + if (csize < 4) csize = 3; + + /* segments should not go outside selection radius */ + unsigned short xradius = (csize * 4) - 5; + unsigned short yradius = (csize * 3) - 5; + ieWord xcentre = (ieWord) (Destination.x - vp.x); + ieWord ycentre = (ieWord) (Destination.y - vp.y); + + // TODO: 0.5 and 0.7 are pretty much random values + // right segment + core->GetVideoDriver()->DrawEllipseSegment( xcentre + step, ycentre, xradius, + yradius, selectedColor, -0.5, 0.5 ); + // top segment + core->GetVideoDriver()->DrawEllipseSegment( xcentre, ycentre - step, xradius, + yradius, selectedColor, -0.7 - M_PI_2, 0.7 - M_PI_2 ); + // left segment + core->GetVideoDriver()->DrawEllipseSegment( xcentre - step, ycentre, xradius, + yradius, selectedColor, -0.5 - M_PI, 0.5 - M_PI ); + // bottom segment + core->GetVideoDriver()->DrawEllipseSegment( xcentre, ycentre + step, xradius, + yradius, selectedColor, -0.7 - M_PI - M_PI_2, 0.7 - M_PI - M_PI_2 ); +} + +/********************** + * Tiled Object Class * + **********************/ + +TileObject::TileObject() +{ + opentiles = NULL; + opencount = 0; + closedtiles = NULL; + closedcount = 0; + Flags = 0; +} + +TileObject::~TileObject() +{ + if (opentiles) { + free( opentiles ); + } + if (closedtiles) { + free( closedtiles ); + } +} + +void TileObject::SetOpenTiles(unsigned short* Tiles, int cnt) +{ + if (opentiles) { + free( opentiles ); + } + opentiles = Tiles; + opencount = cnt; +} + +void TileObject::SetClosedTiles(unsigned short* Tiles, int cnt) +{ + if (closedtiles) { + free( closedtiles ); + } + closedtiles = Tiles; + closedcount = cnt; +} + diff --git a/project/jni/application/gemrb/gemrb/core/Scriptable/Scriptable.h b/project/jni/application/gemrb/gemrb/core/Scriptable/Scriptable.h new file mode 100644 index 000000000..0e5a0c991 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/core/Scriptable/Scriptable.h @@ -0,0 +1,451 @@ +/* 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 SCRIPTABLE_H +#define SCRIPTABLE_H + +#include "exports.h" + +#include "CharAnimations.h" +#include "Inventory.h" +#include "PathFinder.h" +#include "Sprite2D.h" +#include "TileOverlay.h" +#include "Variables.h" + +#include + +class Action; +class Actor; +class Container; +class Door; +class GameScript; +class Gem_Polygon; +class Highlightable; +class InfoPoint; +class Movable; +class Scriptable; +class Selectable; +class Spell; +class SpriteCover; + +#define MAX_SCRIPTS 8 +#define MAX_GROUND_ICON_DRAWN 3 +#define MAX_TIMER 256 + +/** The distance of operating a trigger, container, etc. */ +#define MAX_OPERATING_DISTANCE 40 //a search square is 16x12 +/** The distance between PC's who are about to enter a new area */ +#define MAX_TRAVELING_DISTANCE 400 + +#define SCR_OVERRIDE 0 +#define SCR_AREA 1 +#define SCR_SPECIFICS 2 +#define SCR_RESERVED 3 +#define SCR_CLASS 4 +#define SCR_RACE 5 +#define SCR_GENERAL 6 +#define SCR_DEFAULT 7 + +//pst trap flags (portal) +#define PORTAL_CURSOR 1 +#define PORTAL_TRAVEL 2 + +//trigger flags +#define TRAP_INVISIBLE 1 +#define TRAP_RESET 2 +#define TRAVEL_PARTY 4 +#define TRAP_DETECTABLE 8 +//#define TRAP_16 16 +#define TRAP_LOWMEM 32 //special treatment when low on memory ? +#define TRAP_NPC 64 +//#define TRAP_128 128 +#define TRAP_DEACTIVATED 256 +#define TRAVEL_NONPC 512 +#define TRAP_USEPOINT 1024 //override usage point of travel regions (used for sound in PST traps) +#define INFO_DOOR 2048 //info trigger blocked by door + +//internal actor flags +#define IF_GIVEXP 1 //give xp for this death +#define IF_JUSTDIED 2 //Died() will return true +#define IF_FROMGAME 4 //this is an NPC or PC +#define IF_REALLYDIED 8 //real death happened, actor will be set to dead +#define IF_NORECTICLE 16 //draw recticle (target mark) +#define IF_NOINT 32 //cannot interrupt the actions of this actor (save is not possible!) +#define IF_CLEANUP 64 //actor died chunky death, or other total destruction +#define IF_RUNNING 128 //actor is running +//these bits could be set by a WalkTo +#define IF_RUNFLAGS (IF_RUNNING|IF_NORECTICLE|IF_NOINT) +#define IF_BECAMEVISIBLE 0x100//actor just became visible (trigger event) +#define IF_INITIALIZED 0x200 +#define IF_USEDSAVE 0x400 //actor needed saving throws +#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 + +//scriptable flags +#define IF_ACTIVE 0x10000 +#define IF_VISIBLE 0x40000 +#define IF_ONCREATION 0x80000 +#define IF_IDLE 0x100000 +#define IF_PARTYRESTED 0x200000 //party rested trigger event + +//the actor should stop attacking +#define IF_STOPATTACK (IF_JUSTDIED|IF_REALLYDIED|IF_CLEANUP|IF_IDLE) + +//CheckTravel return value +#define CT_CANTMOVE 0 //inactive +#define CT_ACTIVE 1 //actor can move +#define CT_GO_CLOSER 2 //entire team would move, but not close enough +#define CT_WHOLE 3 //team can move +#define CT_SELECTED 4 //not all selected actors are there +#define CT_MOVE_SELECTED 5 //all selected can move + +//bits for binary trigger bitfield +#define BT_DIE 1 +#define BT_ONCREATION 2 +#define BT_BECAMEVISIBLE 4 +#define BT_WASINDIALOG 8 +#define BT_PARTYRESTED 16 +#define BT_VACANT 32 + +//xp bonus types (for xpbonus.2da) +#define XP_LOCKPICK 0 +#define XP_DISARM 1 +#define XP_LEARNSPELL 2 + +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; + +//#define SEA_RESET 0x00000002 +//#define SEA_PARTY_REQUIRED 0x00000004 + +class GEM_EXPORT Scriptable { +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 + Map *area; + ieVariable scriptName; + ieDword InternalFlags; //for triggers + ieResRef Dialog; + std::list< Action*> actionQueue; + Action* CurrentAction; +public: + // State relating to the currently-running action. + int CurrentActionState; + ieDword CurrentActionTarget; + bool CurrentActionInterruptable; + + // Timing state for ExecuteScript. + ieDword lastDelay; + ieDword lastRunTime; + + Variables* locals; + ScriptableType Type; + Point Pos; + + ieStrRef DialogName; + //play this wav file when stepping on the trap + ieResRef EnterWav; + + GameScript* Scripts[MAX_SCRIPTS]; + + // Variables for overhead text. + char* overHeadText; + Point overHeadTextPos; + unsigned char textDisplaying; + unsigned long timeStartDisplaying; + + 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 + + Point LastTargetPos; + int SpellHeader; + ieResRef SpellResRef; +public: + /** Gets the Dialog ResRef */ + const char* GetDialog(void) const + { + return Dialog; + } + void SetDialog(const char *resref); + void SetScript(const ieResRef aScript, int idx, bool ai=false); + void SetSpellResRef(ieResRef resref); + void SetWait(unsigned long time); + unsigned long GetWait() const; + void LeaveDialog(); + void Interrupt(); + void NoInterrupt(); + void Hide(); + void Unhide(); + void Activate(); + void Deactivate(); + void PartyRested(); + ieDword GetInternalFlag(); + const char* GetScriptName() const; + Map* GetCurrentArea() const; + void SetMap(Map *map); + void SetScript(int index, GameScript* script); + void DisplayHeadText(const char* text); + void FixHeadTextPos(); + void SetScriptName(const char* text); + //call this to deny script running in the next AI cycle + void DelayedEvent(); + //call this to enable script running as soon as possible + void ImmediateEvent(); + bool IsPC() const; + void ExecuteScript(int scriptCount); + void AddAction(Action* aC); + void AddActionInFront(Action* aC); + Action* GetCurrentAction() const { return CurrentAction; } + Action* GetNextAction() const; + Action* PopNextAction(); + void ClearActions(); + void ReleaseCurrentAction(); + bool InMove() const; + void ProcessActions(bool force); + //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); + /* re/draws overhead text on the map screen */ + void DrawOverheadText(const Region &screen); + /* check if casting is allowed at all */ + int CanCast(const ieResRef SpellResRef); + /* check for and trigger a wild surge */ + int CheckWildSurge(); + /* actor/scriptable casts spell */ + int CastSpellPoint( ieResRef &SpellRef, const Point &Target, bool deplete, bool instant = false ); + int CastSpell( ieResRef &SpellRef, Scriptable* Target, bool deplete, bool instant = false ); + /* spellcasting finished */ + void CastSpellPointEnd(int level); + void CastSpellEnd(int level); + ieDword GetGlobalID() const { return globalID; } + /** timer functions (numeric ID, not saved) */ + bool TimerActive(ieDword ID); + bool TimerExpired(ieDword ID); + void StartTimer(ieDword ID, ieDword expiration); + virtual char* GetName(int /*which*/) const { return NULL; } +private: + /* used internally to handle start of spellcasting */ + int SpellCast(bool instant); + /* also part of the spellcasting process, creating the projectile */ + void CreateProjectile(const ieResRef SpellResRef, ieDword tgt, int level, bool fake); + /* do some magic for the wierd/awesome wild surges */ + bool HandleHardcodedSurge(ieResRef surgeSpellRef, Spell *spl, Actor *caster); +}; + +class GEM_EXPORT Selectable : public Scriptable { +public: + Selectable(ScriptableType type); + virtual ~Selectable(void); +public: + Region BBox; + ieWord Selected; //could be 0x80 for unselectable + bool Over; + Color selectedColor; + Color overColor; + Sprite2D *circleBitmap[2]; + int size; +private: + // current SpriteCover for wallgroups + SpriteCover* cover; +public: + void SetBBox(const Region &newBBox); + void DrawCircle(const Region &vp); + bool IsOver(const Point &Pos) const; + void SetOver(bool over); + bool IsSelected() const; + void Select(int Value); + void SetCircle(int size, const Color &color, Sprite2D* normal_circle, Sprite2D* selected_circle); + + /* store SpriteCover */ + void SetSpriteCover(SpriteCover* c); + /* get stored SpriteCover */ + SpriteCover* GetSpriteCover() const { return cover; } + /* want dithered SpriteCover */ + int WantDither(); +}; + +class GEM_EXPORT Highlightable : public Scriptable { +public: + Highlightable(ScriptableType type); + virtual ~Highlightable(void); + virtual int TrapResets() const = 0; + virtual bool CanDetectTrap() const { return true; } + virtual bool PossibleToSeeTrap() const; +public: + Gem_Polygon* outline; + Color outlineColor; + ieDword Cursor; + bool Highlight; + Point TrapLaunch; + ieWord TrapDetectionDiff; + ieWord TrapRemovalDiff; + ieWord Trapped; + ieWord TrapDetected; + ieResRef KeyResRef; +public: + bool IsOver(const Point &Pos) const; + void DrawOutline() const; + void SetCursor(unsigned char CursorIndex); + const char* GetKey(void) const + { + if (KeyResRef[0]) return KeyResRef; + return NULL; + } + void SetTrapDetected(int x); + void TryDisarm(Actor *actor); + //detect trap, set skill to 256 if you want sure fire + void DetectTrap(int skill); + //returns true if trap is visible, only_detected must be true + //if you want to see discovered traps, false is for cheats + bool VisibleTrap(int only_detected) const; + //returns true if trap has been triggered, tumble skill??? + virtual bool TriggerTrap(int skill, ieDword ID); + bool TryUnlock(Actor *actor, bool removekey); +}; + +class GEM_EXPORT Movable : public Selectable { +private: //these seem to be sensitive, so get protection + unsigned char StanceID; + unsigned char Orientation, NewOrientation; + ieWord AttackMovements[3]; + + PathNode* path; //whole path + PathNode* step; //actual step +public: + Movable(ScriptableType type); + virtual ~Movable(void); + Point Destination; + ieDword timeStartStep; + Sprite2D* lastFrame; + ieResRef Area; +public: + PathNode *GetNextStep(int x); + int GetPathLength(); +//inliners to protect data consistency + inline PathNode * GetNextStep() { + if (!step) { + DoStep((unsigned int) ~0); + } + return step; + } + + inline unsigned char GetOrientation() const { + return Orientation; + } + + inline unsigned char GetNextFace() { + //slow turning + if (Orientation != NewOrientation) { + if ( ( (NewOrientation-Orientation) & (MAX_ORIENT-1) ) <= MAX_ORIENT/2) { + Orientation++; + } else { + Orientation--; + } + Orientation = Orientation&(MAX_ORIENT-1); + } + + return Orientation; + } + inline unsigned char GetStance() const { + return StanceID; + } + + inline void SetOrientation(int value, bool slow) { + //MAX_ORIENT == 16, so we can do this + NewOrientation = (unsigned char) (value&(MAX_ORIENT-1)); + if (!slow) { + Orientation = NewOrientation; + } + } + + void SetStance(unsigned int arg); + void SetAttackMoveChances(ieWord *amc); + bool DoStep(unsigned int walk_speed, ieDword time = 0); + void AddWayPoint(const Point &Des); + void RunAwayFrom(const Point &Des, int PathLength, int flags); + void RandomWalk(bool can_stop, bool run); + void MoveLine(int steps, int Pass, ieDword Orient); + void FixPosition(); + void WalkTo(const Point &Des, int MinDistance = 0); + void MoveTo(const Point &Des); + void ClearPath(); + void DrawTargetPoint(const Region &vp); + /* returns the most likely position of this actor */ + Point GetMostLikelyPosition(); + virtual bool BlocksSearchMap() const = 0; + +}; + +//Tiled objects are not used (and maybe not even implemented correctly in IE) +//they seem to be most closer to a door and probably obsoleted by it +//are they scriptable? +class GEM_EXPORT TileObject { +public: + TileObject(void); + ~TileObject(void); + void SetOpenTiles(unsigned short *indices, int count); + void SetClosedTiles(unsigned short *indices, int count); + +public: + ieVariable Name; + ieResRef Tileset; //or wed door ID? + ieDword Flags; + unsigned short* opentiles; + ieDword opencount; + unsigned short* closedtiles; + ieDword closedcount; +}; + +#endif diff --git a/project/jni/application/gemrb/gemrb/core/ScriptedAnimation.cpp b/project/jni/application/gemrb/gemrb/core/ScriptedAnimation.cpp index 82e3b8eb0..f1c9d9e16 100644 --- a/project/jni/application/gemrb/gemrb/core/ScriptedAnimation.cpp +++ b/project/jni/application/gemrb/gemrb/core/ScriptedAnimation.cpp @@ -40,6 +40,7 @@ #define NINE 16 //nine faces (orientation) #define SEVENEYES 32 //special hack for seven eyes +#define DEFAULT_FRAMERATE 15 #define MAX_CYCLE_TYPE 16 static const ieByte ctypes[MAX_CYCLE_TYPE]={ ILLEGAL, ONE, TWO, THREE, TWO|DOUBLE, ONE|FIVE, THREE|DOUBLE, ILLEGAL, @@ -75,7 +76,7 @@ void ScriptedAnimation::Init() Fade = 0; SequenceFlags = 0; XPos = YPos = ZPos = 0; - FrameRate = 15; + FrameRate = DEFAULT_FRAMERATE; FaceTarget = 0; Orientation = 0; Dither = 0; @@ -86,6 +87,12 @@ void ScriptedAnimation::Init() Phase = P_NOTINITED; effect_owned = false; active = true; + Delay = 0; + light = NULL; + LightX = 0; + LightY = 0; + LightZ = 0; + starttime = 0; } void ScriptedAnimation::Override(ScriptedAnimation *templ) @@ -252,11 +259,16 @@ ScriptedAnimation::ScriptedAnimation(DataStream* stream, bool autoFree) ZPos = (signed) tmp; stream->Seek( 4, GEM_CURRENT_POS ); stream->ReadDword( &FrameRate ); + + if (!FrameRate) FrameRate = DEFAULT_FRAMERATE; + stream->ReadDword( &FaceTarget ); stream->Seek( 16, GEM_CURRENT_POS ); stream->ReadDword( &tmp ); //this doesn't affect visibility YPos = (signed) tmp; - stream->Seek( 12, GEM_CURRENT_POS ); + stream->ReadDword( &LightX ); + stream->ReadDword( &LightY ); + stream->ReadDword( &LightZ ); stream->ReadDword( &Duration ); stream->Seek( 8, GEM_CURRENT_POS ); stream->ReadDword( &seq1 ); @@ -395,6 +407,9 @@ ScriptedAnimation::~ScriptedAnimation(void) sound_handle->Stop(); sound_handle.release(); } + if(light) { + core->GetVideoDriver()->FreeSprite(light); + } } void ScriptedAnimation::SetPhase(int arg) @@ -490,8 +505,17 @@ ieDword ScriptedAnimation::GetSequenceDuration(ieDword multiplier) return 0; } +void ScriptedAnimation::SetDelay(ieDword delay) +{ + Delay = delay; + if (twin) { + twin->Delay=delay; + } +} + void ScriptedAnimation::SetDefaultDuration(ieDword duration) { + if (!(SequenceFlags&(IE_VVC_LOOP|IE_VVC_FREEZE) )) return; if (Duration==0xffffffff) { Duration = duration; } @@ -517,11 +541,32 @@ void ScriptedAnimation::SetOrientation(int orientation) bool ScriptedAnimation::HandlePhase(Sprite2D *&frame) { + unsigned int inc = 0; + if (justCreated) { if (Phase == P_NOTINITED) { printMessage("ScriptedAnimation", "Not fully initialised VVC!\n", LIGHT_RED); return true; } + unsigned long time; + time = core->GetGame()->Ticks; + if (starttime == 0) { + starttime = time; + } + if (( time - starttime ) >= ( unsigned long ) ( 1000 / FrameRate )) { + inc = (time-starttime)*FrameRate/1000; + starttime += inc*1000/FrameRate; + } + + if (Delay>inc) { + Delay-=inc; + return false; + } + + if (SequenceFlags&IE_VVC_LIGHTSPOT) { + light = core->GetVideoDriver()->CreateLight(LightX, LightZ); + } + if (Duration!=0xffffffff) { Duration += core->GetGame()->GameTime; } @@ -558,6 +603,10 @@ retry: goto retry; } } + if (SequenceFlags&IE_VVC_FREEZE) { + return false; + } + //automatically slip from onset to hold to release if (!frame || anims[Phase*MAX_ORIENT+Orientation]->endReached) { if (Phase>=P_RELEASE) { @@ -594,9 +643,15 @@ bool ScriptedAnimation::Draw(const Region &screen, const Point &Pos, const Color Sprite2D* frame; if (HandlePhase(frame)) { + //expired return true; } + //delayed + if (justCreated) { + return false; + } + ieDword flag = BLIT_TRANSSHADOW; //transferring flags to SDLdriver, this will have to be consolidated later @@ -614,7 +669,7 @@ bool ScriptedAnimation::Draw(const Region &screen, const Point &Pos, const Color flag |= BLIT_GREY; } - if (Transparency & IE_VVC_RED_TINT) { + if (Transparency & IE_VVC_SEPIA) { flag |= BLIT_RED; } @@ -642,6 +697,9 @@ bool ScriptedAnimation::Draw(const Region &screen, const Point &Pos, const Color } video->BlitGameSprite( frame, cx + screen.x, cy + screen.y, flag, tint, cover, palette, &screen); + if (light) { + video->BlitGameSprite( light, cx + screen.x, cy + screen.y, 0, tint, NULL, NULL, &screen); + } return false; } diff --git a/project/jni/application/gemrb/gemrb/core/ScriptedAnimation.h b/project/jni/application/gemrb/gemrb/core/ScriptedAnimation.h index 4fb8e8f01..088a8bf8b 100644 --- a/project/jni/application/gemrb/gemrb/core/ScriptedAnimation.h +++ b/project/jni/application/gemrb/gemrb/core/ScriptedAnimation.h @@ -36,17 +36,31 @@ #define IE_VVC_BLENDED 0x00000008 #define IE_VVC_MIRRORX 0x00000010 #define IE_VVC_MIRRORY 0x00000020 +#define IE_VVC_CLIPPED 0x00000040 +#define IE_VVC_3D_BLEND 0x00000200 +#define IE_VVC_NOCOVER_2 0x00000400 +#define IE_VVC_NO_TIMESTOP 0x00000800 //ignore timestop palette +#define IE_VVC_NO_SEPIA 0x00001000 //ignore dream palette +#define IE_VVC_2D_BLEND 0x00002000 #define IE_VVC_TINT 0x00030000 //2 bits need to be set for tint -#define IE_VVC_GREYSCALE 0x00080000 +#define IE_VVC_GREYSCALE 0x00080000 //timestopped palette #define IE_VVC_DARKEN 0x00100000 //this is unsure -#define IE_VVC_GLOWING 0x00200000 -#define IE_VVC_RED_TINT 0x02000000 +#define IE_VVC_GLOWING 0x00200000 //internal gamma +#define IE_VVC_SEPIA 0x02000000 //dream palette #define IE_VVC_LOOP 0x00000001 +#define IE_VVC_LIGHTSPOT 0x00000002 //draw lightspot +#define IE_VVC_HEIGHT 0x00000004 #define IE_VVC_BAM 0x00000008 +#define IE_VVC_OWN_PAL 0x00000010 #define IE_VVC_NOCOVER 0x00000040 +#define IE_VVC_MID_BRIGHTEN 0x00000080 +#define IE_VVC_HIGH_BRIGHTEN 0x00000100 -#define IE_VVC_UNUSED 0xe0000000U + +//#define IE_VVC_UNUSED 0xe0000000U +//gemrb specific sequence flags +#define IE_VVC_FREEZE 0x80000000 //phases #define P_NOTINITED -1 @@ -78,10 +92,13 @@ public: int Dither; //these are signed int XPos, YPos, ZPos; + ieDword LightX, LightY, LightZ; + Sprite2D* light;//this is just a round/halftrans sprite, has no animation ieDword FrameRate; ieDword FaceTarget; ieByte Orientation; ieDword Duration; + ieDword Delay; bool justCreated; ieResRef ResName; int Phase; @@ -90,6 +107,7 @@ public: bool active; bool effect_owned; Holder sound_handle; + unsigned long starttime; public: //draws the next frame of the videocell bool Draw(const Region &screen, const Point &Pos, const Color &tint, Map *area, int dither, int orientation); @@ -111,6 +129,8 @@ public: SpriteCover* GetSpriteCover() const { return cover; } int GetCurrentFrame(); ieDword GetSequenceDuration(ieDword multiplier); + /* sets up a delay in the beginning of the vvc */ + void SetDelay(ieDword delay); /* sets default duration if it wasn't set yet */ void SetDefaultDuration(unsigned int duration); /* sets up the direction of the vvc */ diff --git a/project/jni/application/gemrb/gemrb/core/Spell.cpp b/project/jni/application/gemrb/gemrb/core/Spell.cpp index c7eec2698..06512ebf1 100644 --- a/project/jni/application/gemrb/gemrb/core/Spell.cpp +++ b/project/jni/application/gemrb/gemrb/core/Spell.cpp @@ -73,7 +73,7 @@ int Spell::GetHeaderIndexFromLevel(int level) const //-1 will return cfb //0 will always return first spell block //otherwise set to caster level -static EffectRef fx_casting_glow_ref={"CastingGlow",NULL,-1}; +static EffectRef fx_casting_glow_ref = { "CastingGlow", -1 }; void Spell::AddCastingGlow(EffectQueue *fxqueue, ieDword duration, int gender) { @@ -118,7 +118,7 @@ void Spell::AddCastingGlow(EffectQueue *fxqueue, ieDword duration, int gender) delete fx; } -EffectQueue *Spell::GetEffectBlock(Scriptable *self, const Point &pos, int block_index, ieDword pro) const +EffectQueue *Spell::GetEffectBlock(Scriptable *self, const Point &pos, int block_index, int level, ieDword pro) const { Effect *features; int count; @@ -140,21 +140,23 @@ EffectQueue *Spell::GetEffectBlock(Scriptable *self, const Point &pos, int block EffectQueue *selfqueue = NULL; for (int i=0;i=0)) { //hack the effect according to Level //fxqueue->AddEffect will copy the effect, //so we don't risk any overwriting if (EffectQueue::HasDuration(features+i)) { - features[i].Duration = (TimePerLevel*block_index+TimeConstant)*core->Time.round_sec; + fx->Duration = (TimePerLevel*block_index+TimeConstant)*core->Time.round_sec; } } //fill these for completeness, inventoryslot is a good way //to discern a spell from an item effect - Effect *fx = features+i; fx->InventorySlot = 0xffff; //the hostile flag is used to determine if this was an attack fx->SourceFlags = Flags; + fx->CasterLevel = level; // apply the stat-based spell duration modifier if (self->Type == ST_ACTOR) { diff --git a/project/jni/application/gemrb/gemrb/core/Spell.h b/project/jni/application/gemrb/gemrb/core/Spell.h index 785f1ac0c..810cb4103 100644 --- a/project/jni/application/gemrb/gemrb/core/Spell.h +++ b/project/jni/application/gemrb/gemrb/core/Spell.h @@ -57,6 +57,9 @@ class Projectile; //this is not the same as the book types which is 3 or 11) #define NUM_SPELL_TYPES 6 +#define SPEC_IDENTIFY 1 //spells that don't appear in the casting bar +#define SPEC_SILENCE 2 //spells that can be cast when silenced +#define SPEC_DEAD 4 //spells that can target dead actors despite their target type is 1 (pst hack) /** * @class SPLExtHeader * Header for Spell special effects @@ -160,7 +163,7 @@ public: //converts a wanted level to block index count int GetHeaderIndexFromLevel(int level) const; //-1 will return the cfb - EffectQueue *GetEffectBlock(Scriptable *self, const Point &pos, int block_index, ieDword pro=0) const; + EffectQueue *GetEffectBlock(Scriptable *self, const Point &pos, int block_index, int level, ieDword pro=0) const; // add appropriate casting glow effect void AddCastingGlow(EffectQueue *fxqueue, ieDword duration, int gender); //returns a projectile created from an extended header diff --git a/project/jni/application/gemrb/gemrb/core/Spellbook.h b/project/jni/application/gemrb/gemrb/core/Spellbook.h index fb24516d7..97c962e1c 100644 --- a/project/jni/application/gemrb/gemrb/core/Spellbook.h +++ b/project/jni/application/gemrb/gemrb/core/Spellbook.h @@ -47,6 +47,7 @@ class Spell; #define LS_LEARN 2 //give message when learned it #define LS_STATS 4 //check stats (alignment, etc) #define LS_MEMO 8 //memorize it instantly (add innate) +#define LS_NOXP 16 //disable giving of xp (LS_ADDXP) //LearnSpell return values #define LSR_OK 0 diff --git a/project/jni/application/gemrb/gemrb/core/Store.h b/project/jni/application/gemrb/gemrb/core/Store.h index 905c9f4c3..aaabd35a8 100644 --- a/project/jni/application/gemrb/gemrb/core/Store.h +++ b/project/jni/application/gemrb/gemrb/core/Store.h @@ -130,7 +130,7 @@ public: ieDword PurchasedCategoriesOffset; ieDword PurchasedCategoriesCount; ieDword ItemsOffset; - //don't use this value directly, use GetRealStockSize + //don't use this value directly, use GetRealStockSize ieDword ItemsCount; ieDword Lore; ieDword IDPrice; diff --git a/project/jni/application/gemrb/gemrb/core/System/VFS.h b/project/jni/application/gemrb/gemrb/core/System/VFS.h index 71ea1c789..d78cb2828 100644 --- a/project/jni/application/gemrb/gemrb/core/System/VFS.h +++ b/project/jni/application/gemrb/gemrb/core/System/VFS.h @@ -131,10 +131,10 @@ GEM_EXPORT void FixPath (char *path, bool needslash); GEM_EXPORT void ExtractFileFromPath(char *file, const char *full_path); -class DirectoryIterator { +class GEM_EXPORT DirectoryIterator { public: /** - * @param[in] path Path to direcrtory to search. + * @param[in] path Path to directory to search. * * WARNING: the lifetime of path must be longer than the lifetime * of DirectoryIterator. diff --git a/project/jni/application/gemrb/gemrb/core/System/android_log_printf.cpp b/project/jni/application/gemrb/gemrb/core/System/android_log_printf.cpp new file mode 100644 index 000000000..73bf15cfd --- /dev/null +++ b/project/jni/application/gemrb/gemrb/core/System/android_log_printf.cpp @@ -0,0 +1,35 @@ +/* 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 +#include +#include + +int android_log_printf(const char * fmt, ...) { + int return_value; + va_list ap; + va_start(ap, fmt); + int characters = vfprintf(stdout, fmt, ap); // determine buffer size + if(characters<0) return characters; + char* buff = new char[characters+1]; + return_value = vsprintf(buff, fmt, ap); + va_end(ap); + __android_log_print(ANDROID_LOG_INFO, "printf:", buff); + delete buff; + return return_value; +} diff --git a/project/jni/application/gemrb/gemrb/core/System/android_log_printf.h b/project/jni/application/gemrb/gemrb/core/System/android_log_printf.h new file mode 100644 index 000000000..1cc17befc --- /dev/null +++ b/project/jni/application/gemrb/gemrb/core/System/android_log_printf.h @@ -0,0 +1,24 @@ +/* GemRB - Infinity Engine Emulator + * Copyright (C) 2011 The GemRB Project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef IE_ANDROID_LOG_PRINTF_H +#define IE_ANDROID_LOG_PRINTF_H + +int android_log_printf(const char * fmt, ...); + +#endif diff --git a/project/jni/application/gemrb/gemrb/core/TileMap.cpp b/project/jni/application/gemrb/gemrb/core/TileMap.cpp index e00920d63..ae2fc7a22 100644 --- a/project/jni/application/gemrb/gemrb/core/TileMap.cpp +++ b/project/jni/application/gemrb/gemrb/core/TileMap.cpp @@ -23,6 +23,10 @@ #include "Interface.h" #include "Video.h" +#include "Scriptable/Container.h" +#include "Scriptable/Door.h" +#include "Scriptable/InfoPoint.h" + TileMap::TileMap(void) { XCellCount = 0; diff --git a/project/jni/application/gemrb/gemrb/core/TileMap.h b/project/jni/application/gemrb/gemrb/core/TileMap.h index c1556eca4..ad97d10c7 100644 --- a/project/jni/application/gemrb/gemrb/core/TileMap.h +++ b/project/jni/application/gemrb/gemrb/core/TileMap.h @@ -25,11 +25,15 @@ #include "Polygon.h" #include "TileOverlay.h" -#include "GameScript/GameScript.h" //special container types #define IE_CONTAINER_PILE 4 +class Container; +class Door; +class InfoPoint; +class TileObject; + class GEM_EXPORT TileMap { private: std::vector< TileOverlay*> overlays; diff --git a/project/jni/application/gemrb/gemrb/core/Variables.cpp b/project/jni/application/gemrb/gemrb/core/Variables.cpp index 2393d3b15..9be058f16 100644 --- a/project/jni/application/gemrb/gemrb/core/Variables.cpp +++ b/project/jni/application/gemrb/gemrb/core/Variables.cpp @@ -418,13 +418,19 @@ void Variables::SetAt(const char* key, void* value) } -void Variables::SetAt(const char* key, ieDword value) +void Variables::SetAt(const char* key, ieDword value, bool nocreate) { unsigned int nHash; Variables::MyAssoc* pAssoc; 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); + return; + } + if (m_pHashTable == NULL) InitHashTable( m_nHashTableSize ); diff --git a/project/jni/application/gemrb/gemrb/core/Variables.h b/project/jni/application/gemrb/gemrb/core/Variables.h index dc955c158..db392a8f3 100644 --- a/project/jni/application/gemrb/gemrb/core/Variables.h +++ b/project/jni/application/gemrb/gemrb/core/Variables.h @@ -95,7 +95,7 @@ public: void SetAtCopy(const char* key, int newValue); void SetAt(const char* key, char* newValue); void SetAt(const char* key, void* newValue); - void SetAt(const char* key, ieDword newValue); + void SetAt(const char* key, ieDword newValue, bool nocreate=false); void Remove(const char* key); void RemoveAll(ReleaseFun fun); void InitHashTable(unsigned int hashSize, bool bAllocNow = true); diff --git a/project/jni/application/gemrb/gemrb/core/Video.cpp b/project/jni/application/gemrb/gemrb/core/Video.cpp index 50d2e657b..22eeb17c0 100644 --- a/project/jni/application/gemrb/gemrb/core/Video.cpp +++ b/project/jni/application/gemrb/gemrb/core/Video.cpp @@ -143,6 +143,8 @@ Sprite2D* Video::SpriteScaleDown( const Sprite2D* sprite, unsigned int ratio ) return small; } +//TODO light could be elliptical in the original engine +//is it difficult? Sprite2D* Video::CreateLight(int radius, int intensity) { if(!radius) return NULL; diff --git a/project/jni/application/gemrb/gemrb/core/Video.h b/project/jni/application/gemrb/gemrb/core/Video.h index 7b76e3c2a..1560e5e89 100644 --- a/project/jni/application/gemrb/gemrb/core/Video.h +++ b/project/jni/application/gemrb/gemrb/core/Video.h @@ -49,8 +49,8 @@ enum SpriteBlitFlags { BLIT_NOSHADOW = 0x1000, BLIT_TRANSSHADOW = 0x2000, BLIT_TINTED = 0x00010000, // IE_VVC_TINT = 0x00030000 - BLIT_GREY = IE_VVC_GREYSCALE, // 0x80000 - BLIT_RED = IE_VVC_RED_TINT, // 0x02000000 + BLIT_GREY = IE_VVC_GREYSCALE, // 0x80000; timestop palette + BLIT_RED = IE_VVC_SEPIA, // 0x02000000; dream scene palette BLIT_DARK = IE_VVC_DARKEN, // 0x00100000; not implemented in SDLVideo yet BLIT_GLOW = IE_VVC_GLOWING // 0x00200000; not implemented in SDLVideo yet // Note: bits 29,30,31 are used by SDLVideo internally diff --git a/project/jni/application/gemrb/gemrb/core/WorldMap.cpp b/project/jni/application/gemrb/gemrb/core/WorldMap.cpp index 3b1e1053e..c2face07e 100644 --- a/project/jni/application/gemrb/gemrb/core/WorldMap.cpp +++ b/project/jni/application/gemrb/gemrb/core/WorldMap.cpp @@ -171,21 +171,21 @@ void WorldMap::SetAreaEntry(unsigned int x, WMPAreaEntry *ae) area_entries.push_back(ae); } -void WorldMap::InsertAreaLink(unsigned int idx, unsigned int dir, WMPAreaLink *arealink) +void WorldMap::InsertAreaLink(unsigned int areaidx, unsigned int dir, WMPAreaLink *arealink) { unsigned int pos; WMPAreaEntry *ae; WMPAreaLink *al = new WMPAreaLink(); memcpy(al, arealink, sizeof(WMPAreaLink) ); - unsigned int max = area_links.size(); + unsigned int idx = area_entries[areaidx]->AreaLinksIndex[dir]; area_links.insert(area_links.begin()+idx,al); - max = area_entries.size(); + unsigned int max = area_entries.size(); for(pos = 0; posAreaLinksCount[k]++; continue; } diff --git a/project/jni/application/gemrb/gemrb/docs/CMakeLists.txt b/project/jni/application/gemrb/gemrb/docs/CMakeLists.txt new file mode 100644 index 000000000..37f622c03 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/CMakeLists.txt @@ -0,0 +1 @@ +ADD_SUBDIRECTORY( en ) diff --git a/project/jni/application/gemrb/gemrb/docs/Makefile.am b/project/jni/application/gemrb/gemrb/docs/Makefile.am new file mode 100644 index 000000000..81fee2104 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = en diff --git a/project/jni/application/gemrb/gemrb/docs/en/CMakeLists.txt b/project/jni/application/gemrb/gemrb/docs/en/CMakeLists.txt new file mode 100644 index 000000000..f0874181d --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/CMakeLists.txt @@ -0,0 +1,7 @@ +INSTALL( + DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + DESTINATION ${DOC_DIR} + PATTERN CMakeLists.txt EXCLUDE + PATTERN Makefile.am EXCLUDE + PATTERN doxygen/* EXCLUDE +) diff --git a/project/jni/application/gemrb/gemrb/docs/en/CheatKeys.txt b/project/jni/application/gemrb/gemrb/docs/en/CheatKeys.txt new file mode 100644 index 000000000..0706a55a8 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/CheatKeys.txt @@ -0,0 +1,88 @@ +CHEAT AND DEBUG KEYS +-------------------- + + +Following is a list of cheats you can use during development of GemRB. +If you implement a new cheatkey, try to assign the same key as in the +original engine (if you implement a similar function). +This list can be incomplete and obsolete - for current status, look into +gemrb/plugins/Core/GameControl.cpp, functions GameControl::OnKeyRelease() +and GameControl::Draw(). + +Cheat keys are disabled by default. To activate them, either type command +GemRB.EnableCheatKeys(1) on console (pops-up with CTRL+SPACE key combination) +or put it into some GUIScript - e.g. for PS:T in Start.py. + +GameControl control must be focused for the keys to be recognized, so it +might be needed to 'click' the GameControl (i.e. map) first. + + +Ctrl-A - Alters the animation ID of the actor. You have to hover your + mouse over it. + +Ctrl-B - Draws path from start point marked by Ctrl-O to current mouse + position. + +Ctrl-C - Force casts a hardcoded spell. The last selected actor is the + caster and the target is the door/actor currently under the + pointer. This currently casts knock (SPWI207). + +Ctrl-D - Trap or trapped container pointed w/ mouse is disarmed. + +Ctrl-F - Toggles fullscreen mode + +Ctrl-G - Dumps the global (game) object. Currently shows only loaded areas. + +Ctrl-I - Triggers an interaction between the last pointed npc and a random + party member. + +Ctrl-J - Teleports (jumps) selected actors to current mouse position. + +Ctrl-K - Kicks the actor out of the party. + +Ctrl-L - Plays the S056ICBL animation over the actor. (This exists in PST only) + TODO: iterate through animations, like the IE does. + +Ctrl-M - Prints (on terminal or DOS window) useful info on pointed actor, door + container or infopoint and current map + +Ctrl-O - Marks current mouse position as start point (origin) for path drawn + with Ctrl-B + +Ctrl-P - Centers the viewport on the selected actor. + +Ctrl-Q - The pointed actor will join the party. + +Ctrl-R - Resurrects pointed actor. If she's already alive, just heals. + +Ctrl-S - Alters the stance (animation state) of the actor. You have to + hover your mouse over it. + +Ctrl-T - Advances time by one hour. + +Ctrl-V - Explores a small, random part of the pointed area. + +Ctrl-X - Prints (on terminal or DOS window) name of current area script + and current mouse position converted to game coordinates. + +Ctrl-Y - Kills pointed actor or unlocks the pointed door/container, even + if it requires a key. + +Ctrl-Z - Same as Ctrl-A but backward + +Ctrl-1 - Changes the armour level + +Ctrl-4 - Toggles debug flag DEBUG_SHOW_INFOPOINTS (show all + traps, infopoints and wallgroups) + +Ctrl-6 - Toggles debug flag DEBUG_SHOW_LIGHTMAP (show the lightmap) + +Ctrl-7 - Toggle drawing of Fog-Of-War (actually explored bitmap atm.) + in GameControl. + +Ctrl-8 - Toggle drawing of searchmap over the area in GameControl. + +ALT - Toggles debug flag DEBUG_SHOW_CONTAINERS (show all containers + and doors) + +TAB - Sets debug flag DEBUG_XXX while pressed (unused) diff --git a/project/jni/application/gemrb/gemrb/docs/en/CodingStyle.txt b/project/jni/application/gemrb/gemrb/docs/en/CodingStyle.txt new file mode 100644 index 000000000..a0aeaa8d0 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/CodingStyle.txt @@ -0,0 +1,9 @@ +Header file include order. + +- Header file associated to cpp file, or plugin base class header. +- Additional plugin headers. +- Headers in includes. +- Headers in core followed by subdirectories. +- System and library headers. + +Each item should be sorted in ascii order, and separated by blank lines. diff --git a/project/jni/application/gemrb/gemrb/docs/en/Engine/Charcolors.txt b/project/jni/application/gemrb/gemrb/docs/en/Engine/Charcolors.txt new file mode 100644 index 000000000..1d8de000e --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Engine/Charcolors.txt @@ -0,0 +1,36 @@ +There are 4 distinct palettes. + +Known values of palette (p) are: +0 Body +1 Weapon +2 Shield (or Off-hand weapon) +3 Helmet + +Each has 7 colour slots at most. +Known values of slots (s) are: +Body: + 0 - Metal + 1 - Minor + 2 - Major + 3 - Skin + 4 - Leather + 5 - Armor + 6 - Hair + +Weapon: + 0 - Crossguard + .. + 5 - Grip + 6 - Blade + +etc. + +The combined palette location is given in

format, where both numbers are 4 bits. + + + +In GemRB we store these values in the 7 stats starting at IE_COLORS. +Each stat stores four colour gradients (each as a byte). +The n-th stat contains the n-th colour for body, weapon, shield, helmet, from +least significant to most significant byte. + diff --git a/project/jni/application/gemrb/gemrb/docs/en/Engine/Containers.txt b/project/jni/application/gemrb/gemrb/docs/en/Engine/Containers.txt new file mode 100644 index 000000000..86f8e0c91 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Engine/Containers.txt @@ -0,0 +1,57 @@ + +Container specification (based on IESDP) + +Relevant structures: +-------------------- + +typedef struct { + char containername[32]; + short posx, posy; + short type; + short lockdiff; + long flags; + short trapdetect; + short trapremove; + short trapped; + short trapvisible; + short launchx, launchy; + short p1x, p1y, p2x, p2y; //minimum bounding box + long firstitem; + long itemcount; + char trapscript[8]; + long firstvertex; + short vertexcount; + short unknown56; + char scriptname[32]; + char keyitem[8]; + short unknown80; + short unknown82; + long strref; //STRREF!!! + char unused[56]; +} area_container; + + +Description: +------------ +The container's name is not really relevant, it is used only in editors. Scripts reference a container by +the scriptname field. The container's position determines the opening location. +All container types are similar, except that only a few got a special graphics (BAM), see containr.2da in GemRB. +The ground piles are special containers of type 4. Ground pile containers show the item's ground icon instead of +the container's trigger polygon. Containers could be locked, the lockdiff field determines the difficulty to open +them by force. The trapdetect and trapremove fields determine the trap detection and removal difficulties. +The trapped field shows if the trap is still trapped, and the trapvisible field (GemRB implements it as a countdown) +shows if the trap is still visible. The launch point determines the origin of spells cast by the trap script. +The bounding box has effect on the polygon only. The trapscript is not necessarily a trap, this script is always running +not like the door's script. There are several triggers that might affect this script. (OpenFail, Open, Lockpick fail). +The firstitem/itemcount fields point to the inventory of the container (or ground pile). +The keyitem determines if there is a key. (There should be a keyremoval field like with doors, but it isn't yet found). +The strref is the openfail message (when it is 100% impossible to open). + +Container flags: +---------------- +0x00000001 - The container is locked, opening by brute force, key or lockpick is needed. +0x00000002 - ? +0x00000004 - ? +0x00000008 - The script isn't removed when it is triggered. +0x00000010 - ? +0x00000020 - The container is disabled, the polygon is still active, but the container is not accessible to PC's diff --git a/project/jni/application/gemrb/gemrb/docs/en/Engine/Doors.txt b/project/jni/application/gemrb/gemrb/docs/en/Engine/Doors.txt new file mode 100644 index 000000000..dbed88f61 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Engine/Doors.txt @@ -0,0 +1,101 @@ + +Door specification (based on IESDP) + +Relevant structures: +-------------------- + +typedef struct { + char doorid[8]; //matched with area_door.doorid + short closed; //this is largely unknown, probably it shows which tile represents the closed state + short firstdoortileidx; //door tile cell indices are 16 bit values + short countdoortileidx; + short countpolygonopen; //wallpolygon count for the open door state + short countpolygonclose; //wallpolygon count for the closed door state + long offsetpolygonopen; //wallpolygon offset for the open door state + long offsetpolygonclose; //wallpolygon offset for the closed door state +} wed_door; + +typedef struct { + char doorname[32]; //scripting name + char doorid[8]; //wed reference + long flags; //door flags, see below + long firstvertexopen; //first open vertex index + short countvertexopen; //count of open vertices + short countvertexclose; //count of closed vertices + long firstvertexclose; //first closed vertex index + short op1x,op1y,op2x,op2y; //minimum bounding box for open + short cp1x,cp1y,cp2x,cp2y; //minimum bounding box for close + long firstblockopen; //first open impeded blocks (for searchmap) + short countblockopen; //count of open impeded blocks + short countblockclose; //count of closed impeded blocks + long firstblockclose; //first closed impeded blocks (for searchmap) + long unknown54; //unused in tob + char openres[8]; //opening sound resource reference + char closeres[8]; //closing sound resource reference + long cursortype; //mouse cursor type (when mouse is over the door polygon) + short trapdetect; //difficulty of detecting a trap + short trapremoval; //difficulty of removing a trap + short trapflags; // + short trapdetflags; // + short launchx, launchy; //traps are launched from this point + char key[8]; //key item resource reference + char openscript[8]; //(trap) script, activated at first triggering (opening door) + long locked; // + long lockremoval; //difficulty of opening the door + short locp1x, locp1y; //open location 1 + short locp2x, locp2y; //open location 2 + long strref; //check this for missing strings STRREF!!! + char regionlink[24]; + long nameref; //check this for missing strings STRREF!!! + char dlgref[8]; //? + char unknownc0[8]; //? +} area_door; + +Description: +------------ + +Scripts reference the door using the doorname field (Scripting Name). +The relation between the two structures (wed/area) is established by the doorid field. +Each door is a 'wall', the wall polygons are stored in the wed part of the door. +The doors also reference two sets of tiles (also in the wed). +Each door is a special info point with a separate trigger area (polygon) for the open/closed state. +The bounding boxes are used when rendering the trigger area polygons (actually, could be auto-generated). +The impeded blocks are superpositioned on the searchmap, they block passage, vision (unless door is transparent) or +changing the door's state (unless door is sliding). +The opening/closing sounds of a door are modifiable, though there is a default one (PST has no default sounds). +If a door is hidden, then the default sound is different. +The cursor type applies when the mouse is over the trigger area of the door (both states have the same cursor). +If a door has a script assigned and the trap is detectable the trap detection difficulty determines the chance of +success. If the difficulty is exactly 100, then it is impossible to detect (a flaw in the original engine lets >100 +values to be detectable). In the impossible case, a message (strref) will be displayed. +The trap removal difficulty is similarly handled. If trapflags is nonzero, then the trap is still active. +If Trapdetflags is nonzero, then the trap is still visible. (GemRB will implement the latter as a counter which +counts down until 0). The trap (if the script starts a spell) is fired from the launch point. +The key resource has meaning only if the door is locked. If it is empty, then the door cannot be unlocked by key. +The door is also openable by brute force, the difficulty for this is stored in lockremoval. +The actor who operates the door will walk up to the closest of the open locations. +Regionlink is a reference to a travel region which is blocked by the door, if the door is closed. +//not tested +Nameref is the name of the door in case of a dialog. DlgRef is the door's dialog. + +The door flags are these: + +Value Meaning if set +----- -------------- +0x00000001 - The door is closed (PST), the door is open (other games). When a door's state is changed, + (OpenDoor/CloseDoor actions), its (trap) script is triggered. +0x00000002 - The door is locked, the lock difficulty must be set to nonzero to have this any effect. +0x00000004 - The script isn't removed when it is triggered. +0x00000008 - The trap (script) is detectable (fair to set it for real traps). +0x00000010 - Broken? +0x00000020 - Can't close? +0x00000040 - An info trigger is linked to this door. +0x00000080 - Secret door +0x00000100 - Secret door already found (purple outline) +0x00000200 - The impeded doors are ignored concerning vision (door is transparent) +0x00000400 - The key object is removed when unlocking the door +0x00000800 - The impeded blocks are ignored when opening the door (sliding door) +0x00001000 - ? +0x00002000 - ? +0x00004000 - ? +0x00008000 - ? diff --git a/project/jni/application/gemrb/gemrb/docs/en/Engine/Effects.txt b/project/jni/application/gemrb/gemrb/docs/en/Engine/Effects.txt new file mode 100644 index 000000000..c6e139e3d --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Engine/Effects.txt @@ -0,0 +1,116 @@ +A kind of 'specification' for the IE game effects. +This description uses the IESDP effect structure definition with updates. + +V1.0 effect struct (you need to convert it to V2 on the fly) +typedef struct { + short feature; //opcode + unsigned char target; //target type + unsigned char power; //level + parameter par1; + parameter par2; + unsigned char timing; //timing method + unsigned char resist; //resistance type + long duration; + unsigned char prob2; //usually 100 + unsigned char prob1; //usually 0 + char resource[8]; //1. resource + long count; + long sides; + long stype; + long sbonus; + long unknown2c; //unused in V1.0, but copied over to 2.0 +} feat_block; + +//effect body (V2.0 effects) +//please note that in an .eff file there is an additional header +//before these (the first 8 bytes are doubled) +Offset Size (data type) Description +0x0000 4 (char array) For on disk effects, this is a copy of the Signature field from the header. For embedded EFF V2.0 structures, this is zeroed out. +0x0004 4 (char array) For on disk effects, this is a copy of the Version field from the header. For embedded EFF V2.0 structures, this is zeroed out. +0x0008 4 (dword) Effect type +0x000c 4 (dword) Target type +0x0010 4 (dword) Power (level) +0x0014 4 (dword) NP1 +0x0018 4 (dword) NP2 +0x001c 4 (dword) Flags (timing method) + 0 - duration + 1 - permanent + 2 - while equipped (source of effect) + 3 - delayed duration (after delay duration) + 4 - delayed (after delay it is permanent) + 5 - special, delayed, unsaved + 6 - special, duration + 7 - special, ? + 8 - permanent, unsaved + 9 - permanent after death + 10 - trigger (just expired) + +0x0020 4 (dword) Time (duration) +0x0024 2 (word) Probability 1 +0x0026 2 (word) Probability 2 +0x0028 8 (resref) resource +0x0030 4 (dword) die sides/max level +0x0034 4 (dword) dice count/min level +0x0038 4 (dword) save type (stype) +0x003c 4 (dword) save bonus (sbonus) +0x0040 4 (dword) Is Variable? (same as 0x2c in EFF V1.0) +0x0044 4 (dword) Spell School (used for dispelling) +0x0048 4*3 (dword) Unknown +0x0054 4 (dword) Resistance Type (resist) +0x0058 4 (dword) NP3 +0x005c 4 (dword) NP4 +0x0060 4*2 (dword) unknown +0x0068 8 (resref) VVC +0x0070 8 (resref) 3. resource +0x0078 4*2 (point) Source point +0x0080 4*2 (point) Target point +0x0088 4 (dword) Source type of effect (0 - none, 1 - item, 2 - spell) +0x008c 8 (resref) Source of Effect (used for equipping and dispelling) +0x0094 4 (dword) resource flags +0x0098 4 (dword) projectile +0x009c 4 (dword) item slot +0x00a0 32 (bytes) variable +0x00c0 4*2 (dword) unknown +0x00c8 4 (dword) Secondary Type (used for dispelling) +0x00cc 4*15 (dword) unknown + + +An effect's lifecycle: +(apply time) +1. Check if it affects the target +- if percentages don't match, drop it +- if level limits don't match, drop it (some effects don't have this) +- if resistable, check for resistance (once for an applied block) +- if saving throw applies, check for it (once for an applied block) +2. If it is a delayed effect +- precalculate the time of onset (in game time) (store it in the duration field). +- put it on the fx list +3. If it is an instant effect (some opcodes ignore delays, so they are always instant) + +(in each update cycle in creatures) +1. copy the original stats to the modified stats +2. apply all effects in their original order +- if the effect isn't in time (delayed or delayed duration, 3 or 4), skip it +- if a delayed effect reached time: change it to permanent (i think this is a different permanent) +- if a delayed duration effect reached time: change it to duration +- if the effect is permanent (1 or 9), apply it (some effects couldn't be permanent, these effects just apply, then go away) +- if the effect reached end (duration), set a special timing method (10) +- if an effect reached expiration (10) remove it from the queue + +(dispelling/removal) +There should be a way of: +1. Dispelling all by power level ( remove all effects <= power level) +2. Dispelling all by source of effect ( remove all effects == soe) +3. Dispelling all or first that matches a spell school or secondary type +- there is a 'dispellable' flag in the effects which normally disables dispelling. But there should be a 'forced dispel' flag. +4 On death: remove all effects except (9) + +(saving) +Effects that are not saved: 2 -'while equipped' + + +(probability, gemrb specific) +If the low probability field was set to 100, then the high probability field contains the +stat which determines the chance of the effect. For example: +100/136 would determine the chance of the effect based on the caster's detect illusions skill. + diff --git a/project/jni/application/gemrb/gemrb/docs/en/Engine/Makefile.am b/project/jni/application/gemrb/gemrb/docs/en/Engine/Makefile.am new file mode 100644 index 000000000..340c98d2c --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Engine/Makefile.am @@ -0,0 +1,3 @@ +enginedocs_DATA = *.txt +enginedocsdir = $(docdir)/Engine/ +EXTRA_DIST = *.txt diff --git a/project/jni/application/gemrb/gemrb/docs/en/Engine/Projectile.txt b/project/jni/application/gemrb/gemrb/docs/en/Engine/Projectile.txt new file mode 100644 index 000000000..f69c898e5 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Engine/Projectile.txt @@ -0,0 +1,38 @@ +Projectile extension flags for GemRB + +These flags reside in the .pro format on offset 0x2c + +1 Bounce from walls +2 Continue on original path as travel projectile after explosion +4 Freeze as travel projectile after explosion +8 No travel path (move to destination immediately, thus skipping the travel phase) +16 Trail bams got the same orientation behaviour as the travel bam +32 Curved path +64 Random starting frame for travel projectile +128 Pillar type projectiles (instead of orientations, the cycles are drawn vertically on top of each other) +256 Half transparent travel projectile (not blend, but could be combined with it) +512 Static tinted travel projectile +1024 Create another projectile with an ID one less than the current one (missile iteration) +2048 Tile the whole area of effect with the travel bam +4096 Freefalling trajectory (appears horizontally over the target) +8192 Incoming trajectory (appears diagonally over the target) +16384 The area of effect is a line from source to target +32768 The area of effect is a line (wall) crossing target, ahead of source +65536 Draw behind (under) the target +0x20000 Draw pop in/hold/pop out animation sequence +0x40000 Internal flag for 0x20000 (after pop in phase was done) - could be used to play 2 phases, first shadow, then travel bam +0x80000 Slowly fade out a freezed projectile (used with flag 0x4) +0x100000 Display string in setup (string reference is stored on offset 0x30) +0x200000 Random movement instead of path + +These fields are in the .pro format in the Extension structure: +0x228 - ResRef - spread animation (RESOURCE2 in areapro.2da) +0x230 - ResRef - secondary animation (RESOURCE3 in areapro.2da) +0x238 - ResRef - area sound (SOUND2 in areapro.2da) +0x240 - Dword - flags in areapro.2da + +Other areapro.2da fields +0x21c - ResRef - RESOURCE1 +0x208 - ResRef - SOUND1 + +See areapro.2da for more information. diff --git a/project/jni/application/gemrb/gemrb/docs/en/Engine/Triggers.txt b/project/jni/application/gemrb/gemrb/docs/en/Engine/Triggers.txt new file mode 100644 index 000000000..4722e74d7 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Engine/Triggers.txt @@ -0,0 +1,8 @@ + Door Container Travel Trap Info Actor +LastEntered Opened - - Entered/IsOverMe - LastHitter +LastTrigger Closed - - - Clicked LastSummoner +LastUnlocked Unlocked - - - - LastTalkedTo +LastDisarmFailed DisarmFailed DisarmFailed - DisarmFailed - LastTarget +LastDisarmed Disarmed Disarmed - Disarmed - LastAttacker +LastOpenFailed OpenFailed OpenFailed - + PickPocketFailed diff --git a/project/jni/application/gemrb/gemrb/docs/en/Engine/Usability.txt b/project/jni/application/gemrb/gemrb/docs/en/Engine/Usability.txt new file mode 100644 index 000000000..41028c38e --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Engine/Usability.txt @@ -0,0 +1,5 @@ +Usability hacks in the original IE engine + +(0x00040000) Assasin - 15 skill points (skills.2da) +(0x00080000) Bountyhunter - 20 skill points (skills.2da) +(0x00100000) Swashbuckler - no backstab multiplier (TODO) diff --git a/project/jni/application/gemrb/gemrb/docs/en/EngineChanges.txt b/project/jni/application/gemrb/gemrb/docs/en/EngineChanges.txt new file mode 100644 index 000000000..2a45d9451 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/EngineChanges.txt @@ -0,0 +1,29 @@ +Changes to the original engines +******************************* + + +Generally the changes were designed to be compatible with the original game files. No additional fields added (so far), only previously unused parts are used. + +1. Items entries: +Item entries in stores, containers, creatures will have additional flags. These flags will extend the usage of HasItem, DestroyItem, TakeItem scripting functions. The first four flags should be familiar. + +IE_ITEM_IDENTIFIED = 1 +IE_ITEM_UNSTEALABLE = 2 +IE_ITEM_STOLEN = 4 +IE_ITEM_UNDROPPABLE = 8 +//these are GemRB extensions +IE_ITEM_ACQUIRED = 0x10 +IE_ITEM_DESTRUCTIBLE = 0x20 +IE_ITEM_EQUIPPED = 0x40 +IE_ITEM_STACKED = 0x80 + +This will make possible scripts like these: +HasAnyItem(STOLEN) +TakeAllStolenItem() +DropAllEquippedItem() +HasItem("SWORD",EQUIPPED|IDENTIFIED) + +2. Journal entries: +Journal entries will have an additional Group ID. This group ID will make it possible to remove a group of journal entries along with adding a new one of the same group using solely the dialog structure. This eliminates the problem of residue entries. Also, you don't have to remember the journal entry strref, just assign a unique group (quest ID). +The quest ID byte will be stored on offset 0x0002 in the transition table entry. +The former flags field (it was a dword) will be a word. Its highest bit will be the group flag. Unless this flag is set, the behaviour will be the same as before. If you set this flag, then all journal entries set with the same id will be removed before adding the new one. The scripting actions will also accept an additional quest ID parameter. diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ActOnPC.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ActOnPC.txt new file mode 100644 index 000000000..5cdefa66b --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ActOnPC.txt @@ -0,0 +1,13 @@ + +Prototype: ActOnPC(player) + +Metaclass Prototype: / + +Description: Targets the selected PC for an action (cast spell, attack, ...) + +Parameters: player - the pc's party position (1-10) + +Return value: / + +See also: ClearActions, SetModalState, SpellCast + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/AddGameTypeHint.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/AddGameTypeHint.txt new file mode 100644 index 000000000..5c48c7200 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/AddGameTypeHint.txt @@ -0,0 +1,17 @@ +Prototype: GemRB.AddGameTypeHint(type, weight, flags=0) + +Description: Asserts that GameType should be TYPE, with confidence WEIGHT. + This is used by Autodetect.py scripts when GameType was + set to 'auto' in config file. + +Parameters: type - GameType (e.g. bg1, bg2, iwd, how, iwd2, pst and possibly others) + weight - numeric, confidence that TYPE is correct. Standard games should use + values <= 100, (eventual) new games based on the standard ones + should use values above 100. + flags - numeric, not used now + + +Return value: N/A + +MD5: 1c130785e329448b743a7f160b07a312 + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/AdjustScrolling.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/AdjustScrolling.txt new file mode 100644 index 000000000..76bd4ce8b --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/AdjustScrolling.txt @@ -0,0 +1,26 @@ + +Prototype: AdjustScrolling(WindowIndex, ControlIndex, x, y) + +Metaclass Prototype: AdjustScrolling(x, y) + +Description: Sets the scrolling offset of a WorldMapControl. + +Parameters: WindowIndex, ControlIndex - the control's reference +x,y - scrolling offset values + +Return value: N/A + +Example: + #northeast + Button = GemRB.GetControl (Window, 9) + GemRB.SetEvent (Window, Button, IE_GUI_BUTTON_ON_PRESS, "MapNE") +... +def MapNE(): + GemRB.AdjustScrolling (Window, WorldMapControl, 10, -10) + return +The above lines set up a button event. When the button is pressed the worldmap will be shifted in the northeastern direction. + +See also: CreateWorldMapControl + + +MD5: 500775c70886362ce1ebc9353505027f diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ApplyEffect.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ApplyEffect.txt new file mode 100644 index 000000000..6d9dc6661 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ApplyEffect.txt @@ -0,0 +1,31 @@ + +Prototype: GemRB.ApplyEffect(PartyID, opcode, param1, param2[, resref, resref2, resref3, source]) + +Description: Creates a basic effect and applies it on the player character +marked by PartyID. +This function could be used to add stats that are stored in effect blocks. + +Parameters: +PartyID - the player character's index in the party +opcode - the effect opcode (for values see effects.ids) +param1 - parameter 1 for the opcode +param2 - parameter 2 for the opcode +resref - optional resource reference to set in effect +resref2 - (optional) resource reference to set in the effect +resref3 - (optional) resource reference to set in the effect +resref4 - (optional) resource reference to set in the effect +source - (optional) source to set in the effect + +Return value: N/A + +Example: + for i in range(ProfCount-8): + StatID = GemRB.GetTableValue(TmpTable, i+8, 0) + Value = GemRB.GetVar ("Prof "+str(i) ) + if Value: + GemRB.ApplyEffect (MyChar, "Proficiency", Value, StatID ) + +The above example sets the weapon proficiencies in a bg2's CharGen9.py script. + +See also: SpellCast, SetPlayerStat, GetPlayerStat, CountEffects + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ApplySpell.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ApplySpell.txt new file mode 100644 index 000000000..7bfc00818 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ApplySpell.txt @@ -0,0 +1,14 @@ + +Prototype: GemRB.ApplySpell(PartyID, resref) + +Description: Applies a spell on the actor marked by PartyID. +This function can be used to add abilities that are stored as spells (eg. innates) + +Parameters: +PartyID - the player character's index in the party +resref - spell resource reference + +Return value: N/A + +See also: SpellCast, ApplyEffect, CountEffects + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/AttachScrollBar.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/AttachScrollBar.txt new file mode 100644 index 000000000..ed93c5014 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/AttachScrollBar.txt @@ -0,0 +1,12 @@ + +Prototype: AttachScrollBar(WindowIndex, ControlIndex, ScrollBarControlIndex) + +Description: Attaches a scrollbar to a control. If the control receives mousewheel events, it will be relayed to the ScrollBar. TextArea controls will also be synchronised with the scrollbar. If there is a single ScrollBar on the window, or the ScrollBar was set with SetDefaultScrollBar, this command is not needed. + +Parameters: WindowIndex, ControlIndex - the control's reference +ScrollBarControlIndex - the scrollbar's index on the same window + +Return value: N/A + +See also: ConvertEdit, SetDefaultScrollBar + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CanUseItemType.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CanUseItemType.txt new file mode 100644 index 000000000..4576a8258 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CanUseItemType.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.CanUseItemType(slottype, itemname[, actor, equipped]) + +Description: Checks the itemtype vs. slottype, and also checks the usability flags vs. Actor's stats (alignment, class, race, kit etc.) + +Parameters: +slottype - the slot to check (See ie_slots.py) +itemname - the resource reference of the item +actor - the actor's number in the team (if 0, then actor is not unimportant) +equipped - whether the item is equipped (if so, don't consider disabled items to be unusable) + +Return value: boolean + +See also: DropDraggedItem, UseItem + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ChangeContainerItem.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ChangeContainerItem.txt new file mode 100644 index 000000000..545a50574 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ChangeContainerItem.txt @@ -0,0 +1,18 @@ + +Prototype: ChangeContainerItem( PartyID, slot, action ) + +Description: Moves an item from PC's inventory into a container or vice versa. If PartyID is 0 then PC is the first selected PC and container is the current container. If PartyID is not 0 then the container is the pile at the feet of that PC. + +Parameters: +PartyID - the PC's position in the party +slot - the item's inventory or container slot +action = + 0 - put item of PC into container + 1 - get item from container and put it in actor's inventory (backpack) + +Return value: None + +See also: GetContainer, GetSlotItem + + +MD5: b5226a9f5a886c5552438cf1598c72e1 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ChangeItemFlag.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ChangeItemFlag.txt new file mode 100644 index 000000000..39c0c5d93 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ChangeItemFlag.txt @@ -0,0 +1,28 @@ + +Prototype: GemRB.ChangeItemFlag(PartyID, slot, flags, mode) + +Description: Changes the flags of an inventory slot. For example, identifies an item. + +Parameters: +PartyID - the PC's position in the party (1 based) +slot - inventory slot +flags - a bitfield, same as the GetSlotItem flags +IE_INV_ITEM_IDENTIFIED = 0x01 - the item is identified +IE_INV_ITEM_UNSTEALABLE = 0x02 - the item is unstealable +IE_INV_ITEM_STOLEN = 0x04 - the item is marked as stolen +IE_INV_ITEM_UNDROPPABLE = 0x08 - the item is undroppable (dragitem fails) +IE_INV_ITEM_ACQUIRED = 0x10 - the item was recently acquired +IE_INV_ITEM_DESTRUCTIBLE = 0x20 - the item is removable +IE_INV_ITEM_EQUIPPED = 0x40 - the item is equipped +IE_INV_ITEM_STACKED = 0x80 - the item is a stacked item + +mode - binary operation type +OP_SET = 0 - sets all bits as flag +OP_AND = 1 - turns all other bits off +OP_OR = 2 - turns bit on +OP_XOR = 3 - toggles bit +OP_NAND = 4 - turns bit off + +Return value: Returns false if the item was not found. + +See also: GetSlotItem diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ChangeStoreItem.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ChangeStoreItem.txt new file mode 100644 index 000000000..67eff2774 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ChangeStoreItem.txt @@ -0,0 +1,23 @@ + +Prototype: ChangeStoreItem( PartyID, slot, action ) + +Description: Performs a buy, sell, identify or steal action. Action has the same bit values as IsValidStoreItem. + +Parameters: +PartyID - the PC's position in the party +slot - the item's inventory or store slot +action - bitfield +1 - buy +2 - sell +4 - identify +8 - steal +Add 0x40 for selection (in case of buy/sell only) + +Return value: + 0 - failure + 2 - success + +See also: EnterStore, GetSlotItem, GetStoreItem, IsValidStoreItem + + +MD5: 07c89de8dbd0236f8c206b06abe4b3dc diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CheckFeatCondition.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CheckFeatCondition.txt new file mode 100644 index 000000000..835350dea --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CheckFeatCondition.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.CheckFeatCondition(partyslot, a_stat, a_value, b_stat, b_value, c_stat, c_value, d_stat, d_value) + +Description: Checks if a party character is eligible for a feat, the formula is: (stat[a]>=a or stat[b]>=b) and (stat[c]>=c or stat[d]>=d) + +Parameters: partyslot - the characters position in the party + a_stat,b_stat, c_stat, d_stat - stat IDs + a_value, b_value, c_value, d_value - stat value limits + +Return value: bool + +See also: GetPlayerStat, SetPlayerStat + + +MD5: b237a66b3abbb49ede75897d3d1ee0da diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CheckVar.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CheckVar.txt new file mode 100644 index 000000000..d737eb191 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CheckVar.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.CheckVar(VariableName, Context) + +Description: Return (and output on terminal) the value of a Game Variable. It executes the CheckVariable gamescript function in the last actor's context, or, short of that, in the current area's context. If there is no running game, it terminates the script. +GetGameVar("variable") is effectively the same as CheckVar("variable","GLOBAL"). + +Parameters: VariableName - must be shorter than 32 bytes + Context - must be exactly 6 bytes long +Special cases for Context: LOCALS, GLOBAL, MYAREA + +Return value: numeric + +See also: GetGameVar + + +MD5: 872634ab7317e9f381a71f00771f29cd diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ClearActions.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ClearActions.txt new file mode 100644 index 000000000..95aea7612 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ClearActions.txt @@ -0,0 +1,9 @@ + +Prototype: GemRB.ClearActions(Slot) + +Description: Stops a player character's movement and any pending action. + +Parameters: Slot - actor index in game structure + +Return value: N/A + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ConvertEdit.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ConvertEdit.txt new file mode 100644 index 000000000..cf6b138d4 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ConvertEdit.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.ConvertEdit(WindowIndex, ControlID[, ScrollBarID]) + +Description: Converts a TextEdit control into an editable TextArea control. TextAreas have unlimited editbuffer, scrollbar and wordwrap abilities. The optional ScrollBar must already been created. + +Parameters: +WindowIndex - the value returned from LoadWindow +ControlID - the old control's controlID, usually it will be preserved, but don't rely on it +ScrollBarID - the optional ScrollBar controlID. + +Return value: The new ControlID + +See also: CreateTextEdit diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CountEffects.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CountEffects.txt new file mode 100644 index 000000000..34a823c45 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CountEffects.txt @@ -0,0 +1,22 @@ + +Prototype: GemRB.CountEffects(PartyID, opcode, param1, param2[, resref]) + +Description: Counts the number of effects currently affecting the target. +If a parameter was set to -1, it will be ignored. + +Parameters: +PartyID - the player character's index in the party +opcode - the effect opcode (for values see effects.ids) +param1 - parameter 1 for the opcode +param2 - parameter 2 for the opcode +resref - optional resource reference to match the effect + +Return value: N/A + +Example: + res = GemRB.CountEffect (MyChar, "HLA", -1, -1, AbilityName ) + +The above example returns how many HLA effects were applied on the character. + +See also: ApplyEffect + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateButton.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateButton.txt new file mode 100644 index 000000000..7ce76ac3a --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateButton.txt @@ -0,0 +1,17 @@ + +Prototype: GemRB.CreateButton(WindowIndex, ControlID, x, y, w, h) + +Metaclass Prototype: CreateButton(ControlID, x, y, w, h) + +Description: Creates and adds a new Button to a Window. + +Parameters: +WindowIndex - the value returned from LoadWindow +ControlID - the new control will be available via this controlID +x,y,w,h - X position, Y position, Width and Height of the control + +Return value: N/A + +See also: CreateLabel, CreateMapControl, CreateWorldMapControl, CreateTextEdit + +MD5: cca3f572a4ebf8b1e9974f83f6e756aa diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateCreature.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateCreature.txt new file mode 100644 index 000000000..1c72b31cb --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateCreature.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.CreateCreature(PartyID, CreResRef) + +Description: Creates Creature in the vicinity of the player character. + +Parameters: +PartyID - the PC's position in the party +CreResRef - the creature's name (.cre resref) + +Return value: N/A + +See also: CreateItem + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateItem.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateItem.txt new file mode 100644 index 000000000..1e121f912 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateItem.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.CreateItem(PartyID, ItemResRef, [SlotID, Charge0, Charge1, Charge2]) + +Description: Creates Item in the inventory of the player character. + +Parameters: +PartyID - the PC's position in the party +ItemResRef - the item's name (.itm resref) +SlotID - Inventory Slot (-1 means any backpack slot) +Charge0-2 - The item's stack amount/charges + +Return value: N/A + +See also: + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateLabel.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateLabel.txt new file mode 100644 index 000000000..118c19ced --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateLabel.txt @@ -0,0 +1,27 @@ + +Prototype: GemRB.CreateLabel(WindowIndex, ControlID, x, y, w, h, font, text, align) + +Metaclass Prototype: CreateLabel(ControlID, x, y, w, h, font, text, align) + +Description: Creates and adds a new Label to a Window. + +Parameters: +WindowIndex - the value returned from LoadWindow +ControlID - the new control will be available via this controlID +x,y,w,h - X position, Y position, Width and Height of the control +font - a .bam resref which must be listed in fonts.2da too +text - initial text of the label (must be string) +align - label text alignment + +Return value: N/A + +Example: + GemRB.CreateLabel(StartWindow, 0x0fff0000, 0,415,640,30, "EXOFONT", "", 1) + Label=GemRB.GetControl(StartWindow, 0x0fff0000) + GemRB.SetText(StartWindow, Label,GEMRB_VERSION) +The above lines add the GemRB version string to the PST main screen. + +See also: CreateButton, SetText + + +MD5: aaeaa42947bb1bc3cde0719ad5e08b51 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateLabelOnButton.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateLabelOnButton.txt new file mode 100644 index 000000000..3bad18370 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateLabelOnButton.txt @@ -0,0 +1,18 @@ + +Prototype: GemRB.CreateLabelOnButton(WindowIndex, ButtonControlID, NewID, font, align) + +Metaclass Prototype: CreateLabelOnButton(NewID, font, align) + +Description: Creates and adds a new Label to a Window, based on the dimensions of an existing button. If the NewID is the same as the old button ID, the old button will be converted to this Label (the old button will be removed). + +Parameters: +WindowIndex - the value returned from LoadWindow +ButtonControlID - the button control to be copied/converted +NewID - the new control will be available via this controlID +font - a .bam resref which must be listed in fonts.2da too +align - label text alignment + +Return value: N/A + +See also: CreateButton, CreateLabel + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateMapControl.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateMapControl.txt new file mode 100644 index 000000000..d07339de6 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateMapControl.txt @@ -0,0 +1,20 @@ + +Prototype: GemRB.CreateMapControl(WindowIndex, ControlID, x, y, w, h, [LabelID, FlagResRef [, Flag2ResRef]] + +Metaclass Prototype: CreateMapControl(ControlID, x, y, w, h, [LabelID, FlagResRef [, Flag2ResRef]] + +Description: Creates and adds a new Area Map Control to a Window. If WindowIndex and ControlID (not ControlIndex!) point to a valid control, it will replace that control with the MapControl using the original control's dimensions (x,y,w,h are ignored). It is possible to associate a variable with the MapControl, in this case, the associated variable will enable or disable mapnotes (you must supply a LabelID and the resources for the pins). + +Parameters: +WindowIndex - the value returned from LoadWindow +ControlID - the new control will be available via this controlID +x,y,w,h - X position, Y position, Width and Height of the control +LabelID - associated control ID to display mapnotes, it must be a label +FlagResRef - Resource Reference for the pins, if no Flag2ResRef is given, this should be a .bam resref. If there is a second resref, then both must be .bmp. +Flag2ResRef - the readonly mapnotes are marked by this .bam (red pin) + + +Return value: N/A + +See also: SetVarAssoc, SetMapnote + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateMovement.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateMovement.txt new file mode 100644 index 000000000..acd09b821 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateMovement.txt @@ -0,0 +1,14 @@ + +Prototype: GemRB.CreateMovement(Area, Entrance[, Direction]) + +Description: Moves some or all actors of the current area to the destination area. + +Parameters: Area - The area resource reference where the player(s) should arrive. + Entrance - The area entrance in the Destination area. + Direction - The direction flag (from WMP) to use if the entrance doesn't exist. + +Return value: N/A + +See also: GetDestinationArea + +MD5: b19700ed972c915b0910b40a746a87ee diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreatePlayer.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreatePlayer.txt new file mode 100644 index 000000000..dd8bc3063 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreatePlayer.txt @@ -0,0 +1,25 @@ + +Prototype: CreatePlayer(CREResRef, Slot [,Import, VersionOverride] ) + +Description: Adds an actor (PC) to the current game. It works only after a LoadGame() was executed, and should be used before an EnterGame(). It is also used to import a .chr file as a PC. A new character will need additional SetPlayerStat() and FillPlayerInfo() calls to be a working character. + +Parameters: CREResRef - The name of the creature to be used as the actor, usually 'charbase' + Slot - The player character's position in the party + Import - Set it to 1 if you want to import a .chr instead of creating a new character + VersionOverride - Force version of new actor. + +Return value: the new player's index in the game structure + +Examples: + MyChar = GemRB.GetVar("Slot") + GemRB.CreatePlayer("charbase", MyChar ) + +The above example will create a new player character in the slot selected by the Slot variable. + + MyChar = GemRB.GetVar("Slot") + ImportName = "avenger" + GemRB.CreatePlayer(ImportName, MyChar, 1 ) +The above example would import avenger.chr into the slot selected by the Slot Variable. (If it exists in the Characters directory of the game). + +See also: LoadGame, EnterGame, QuitGame, FillPlayerInfo, SetPlayerStat + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateScrollBar.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateScrollBar.txt new file mode 100644 index 000000000..3e00475f6 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateScrollBar.txt @@ -0,0 +1,19 @@ +v +Prototype: GemRB.CreateScrollBar(WindowIndex, ControlID, x, y, w, h) + +Metaclass Prototype: CreateScrollBar(ControlID, x, y, w, h) + +Description: Creates and adds a new ScrollBar to a Window. + +Parameters: +WindowIndex - the window control +ControlID - the id of the new control +x - position +y - position +w - width +h - height + +Return value: ControlIndex + +See also: SetScrollBarSprites, SetDefaultScrollBar, AttachScrollBar + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateTextEdit.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateTextEdit.txt new file mode 100644 index 000000000..1ba63da5b --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateTextEdit.txt @@ -0,0 +1,19 @@ + +Prototype: GemRB.CreateTextEdit(WindowIndex, ControlID, x, y, w, h, font, text) + +Metaclass Prototype: CreateTextEdit(ControlID, x, y, w, h, font, text) + +Description: Creates and adds a new TextEdit field to a Window. Used in PST MapNote editor. The maximum length of the edit field is 500 characters. + +Parameters: +WindowIndex - the value returned from LoadWindow +ControlID - the new control will be available via this controlID +x,y,w,h - X position, Y position, Width and Height of the control +font - font BAM ResRef +text - initial text + +Return value: N/A + +See also: CreateLabel, CreateMapControl, CreateWorldMapControl, CreateButton + +MD5: dd93ef5d51dda6ab1a2b5050bb0c4e3f diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateWindow.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateWindow.txt new file mode 100644 index 000000000..4714d67c6 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateWindow.txt @@ -0,0 +1,17 @@ + +Prototype: GemRB.CreateWindow(WindowID, X, Y, Width, Height, MosResRef) + +Description: Creates a new empty window and returns its index. + +Parameters: +WindowID - the window's ID +X,Y - the window's position +Width, Height - the window's dimensions +MosResRef - the background image (.mos resref) + +Return value: a window index + +See also: + + +MD5: f28c0c3fb8a9e7d0a279d735c5b94d6f diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateWorldMapControl.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateWorldMapControl.txt new file mode 100644 index 000000000..6984b482c --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/CreateWorldMapControl.txt @@ -0,0 +1,25 @@ + +Prototype: GemRB.CreateWorldMapControl(WindowIndex, ControlID, x, y, w, h, direction[, font]) + +Metaclass Prototype: CreateWorldMapControl(ControlID, x, y, w, h, direction[, font]) + +Description: This command will create a special WorldMapControl, which is currently unavailable via .chu files. If WindowIndex and ControlID (not ControlIndex!) point to a valid control, it will replace that control with the WorldMapControl using the original control's dimensions (x,y,w,h are ignored). + +Parameters: +WindowIndex - the value returned from LoadWindow +ControlID - the new control will be available via this controlID +x,y,w,h - X position, Y position, Width and Height of the control +direction +font - font uused to display names of map locations + +Return value: N/A + +Example: + Window = GemRB.LoadWindow (0) + GemRB.CreateWorldMapControl (Window, 4, 0, 62, 640, 418, Travel, "floattxt") + WorldMapControl = GemRB.GetControl (Window, 4) + +See also: GetDestinationArea, CreateMovement + + +MD5: ec421a1b6a60206700cad9c9776f78e6 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/DeleteControl.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/DeleteControl.txt new file mode 100644 index 000000000..3a5607793 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/DeleteControl.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.DeleteControl(WindowIndex, ControlID) + +Metaclass Prototype: DeleteControl(ControlID) + +Description: Deletes a control from a Window. + +Parameters: WindowIndex - the return value of a previous LoadWindow call. + ControlID - a control ID, see the .chu file specification + +Return value: N/A + +See also: GetControl + + +MD5: dfbf18fa1830fccf5eb61cf2b39b5147 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/DeleteSaveGame.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/DeleteSaveGame.txt new file mode 100644 index 000000000..854a70097 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/DeleteSaveGame.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.DeleteSaveGame(SlotCount) + +Description: Deletes a saved game folder completely. + +Parameters: SlotCount - the index of a saved game + +Return value: N/A + +See also: GetSaveGameCount + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/DisplayString.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/DisplayString.txt new file mode 100644 index 000000000..2fe05d0e7 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/DisplayString.txt @@ -0,0 +1,14 @@ + +Prototype: GemRB.DisplayString(strref, color[, PartyID]) + +Description: Displays a string in the messagewindow using methods supplied by the core engine. + +Parameters: strref - the tlk reference + color - a hex packed RGB value + PartyID - if supplied, then the PC's name will be displayed too + +Return value: N/A + +See also: SetText + +MD5: diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/DragItem.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/DragItem.txt new file mode 100644 index 000000000..1d7a84a70 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/DragItem.txt @@ -0,0 +1,14 @@ + +Prototype: GemRB.DragItem(PartyID, Slot, ResRef, [Count=0]) + +Description: Start dragging specified item. If Count is given, it will try to split the item. If an item is already dragged, it won't do anything. + +Parameters: PartyID - the PC's position in the party + Slot - actor index in game structure + ResRef - item name (.itm resref) + Count - stack size (0 means all) + +Return value: N/A + +See also: DropDraggedItem, IsDraggingItem + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/DrawWindows.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/DrawWindows.txt new file mode 100644 index 000000000..f0c3f962e --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/DrawWindows.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.DrawWindows() + +Description: Refreshes the User Interface by redrawing invalidated controls. + +Parameters: N/A + +Return value: N/A + +See also: InvalidateWindow, UnhideGUI + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/DropDraggedItem.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/DropDraggedItem.txt new file mode 100644 index 000000000..c20e80367 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/DropDraggedItem.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.DropDraggedItem(PartyID, Slot) + +Description: Stop dragging specified item. Dropping the item in an invalid slot will result in 0. Partial success may happen if the item was dropped into a stack, but not all items were moved. The dragging status will be removed only after a complete success. Not all inventory slots may carry any type of item. The item could be dropped in an unspecified inventory slot, the ground, or an equippable slot fitting for the item. + +Parameters: PartyID - the actor's inparty index + Slot - the Inventory Slot +Special values for Slot: + -1 any equippable slot fitting for the item + -2 ground + -3 any inventory slot +Return value: integer, the action was: 0 (unsuccessful), 1 (partial success) or 2 (complete success) + +See also: DragItem, IsDraggingItem, CanUseItemType + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/EnableButtonBorder.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/EnableButtonBorder.txt new file mode 100644 index 000000000..8ef57ecd6 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/EnableButtonBorder.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.EnableButtonBorder(WindowIndex, ControlIndex, BorderIndex, enabled) + +Metaclass Prototype: EnableBorder(BorderIndex, enabled) + +Description: Enable or disable specified border/frame/overlay of a button control. + +Parameters: +WindowIndex, ControlIndex - the control's reference +BorderIndex - 0,1 or 2 +enabled - boolean, true enables the border + +Return value: N/A + +See also: SetButtonBAM, SetButtonFlags, SetButtonBorder + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/EnableCheatKeys.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/EnableCheatKeys.txt new file mode 100644 index 000000000..e0713c4b0 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/EnableCheatKeys.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.EnableCheatKeys(flag) + +Description: Turns the debug keys on or off. + +Parameters: flag - boolean + +Return value: N/A + +See also: + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/EndCutSceneMode.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/EndCutSceneMode.txt new file mode 100644 index 000000000..976e2fbe0 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/EndCutSceneMode.txt @@ -0,0 +1,11 @@ + +Prototype: EndCutSceneMode() + +Description: Exits the CutScene Mode. It is similar to the gamescript command of the same name. It gives back the cursor, and shows the game GUI windows hidden by the CutSceneMode() gamescript action. (This is mainly a debug command.) + +Parameters: N/A + +Return value: N/A + +See also: HideGUI, UnhideGUI + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/EnterGame.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/EnterGame.txt new file mode 100644 index 000000000..7706a41d3 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/EnterGame.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.EnterGame() + +Description: Starts new game and enters it. It destructs all existing windows, and creates a GameControl window as the 0. window (the GameControl object will be its 0. control). You should already load a game using LoadGame(), otherwise the engine may terminate. The Game won't be entered until the execution of the current script ended, but a LoadGame() may precede EnterGame() in the same function. (SetNextScript too). + +Parameters: N/A + +Return value: N/A + +See also: QuitGame, LoadGame, SetNextScript + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/EnterStore.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/EnterStore.txt new file mode 100644 index 000000000..789a2858e --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/EnterStore.txt @@ -0,0 +1,11 @@ + +Prototype: EnterStore( StoreResRef ) + +Description: Loads a store and sets it as current (used) store. + +Parameters: StoreResRef - the store's resource name + +Return value: None + +See also: GetStore, GetStoreCure, GetStoreDrink, LeaveStore, SetPurchasedAmount + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/EvaluateString.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/EvaluateString.txt new file mode 100644 index 000000000..615905230 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/EvaluateString.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.EvaluateString(String) + +Description: Evaluates an In-Game Script Trigger in the current Area Script Context. It prints the result. (The command is more useful from the Console than using from scripts) + +Parameters: String - a gamescript trigger + +Return value: N/A (the trigger's return value is printed) + +See also: ExecuteString + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ExecuteString.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ExecuteString.txt new file mode 100644 index 000000000..8b904e027 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ExecuteString.txt @@ -0,0 +1,20 @@ + +Prototype: GemRB.ExecuteString(String[,Slot]) + +Description: Executes an In-Game Script Action in the current Area Script Context. This means that LOCALS will be treated as the current area's variable. + +Parameters: String - a gamescript action + Slot - a player slot +Return value: N/A + +Example: + GemRB.ExecuteString("ActionOverride([PC], Attack(NearestEnemyOf(Myself)) )") + +The above example will force a player (most likely Player1) to attack an enemy, issuing the command as it would come from the current area's script. The current gametype must support the scripting action. + + GemRB.ExecuteString("Attack(NearestEnemyOf(Myself))", 2) + +The above example will force Player2 to attack an enemy, as the example will run in that actor's script context. + +See also: EvaluateString, gamescripts + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ExploreArea.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ExploreArea.txt new file mode 100644 index 000000000..625b9d6be --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ExploreArea.txt @@ -0,0 +1,13 @@ + +Prototype: ExploreArea( [value] ) + +Description: Fills the explored bitmap with the value given. If there was no value given, it will fill with -1 (all bit set). + +Parameters: 0 - undo explore + -1 - explore + all other values give meaningless results + +Return value: None + +See also: MoveToArea + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/FillPlayerInfo.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/FillPlayerInfo.txt new file mode 100644 index 000000000..25b08f8fb --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/FillPlayerInfo.txt @@ -0,0 +1,38 @@ + +Prototype: GemRB.FillPlayerInfo(Slot[, Portrait1, Portrait2]) + +Description: Fills basic character info, that is not stored in stats. This command will generate an AnimationID for the character based on the avprefix.2da table, the character must have the stats referenced in the avprefix structure already set. It will also set the player's portraits if given. It will set the actor's area/position according to the "PlayMode" variable and the Slot value (using the startpos.2da table). This command must be called once after a character was created and before EnterGame(). + +Parameters: Slot - the new character's slot + Portrait1 - medium (or large) portrait + Portrait2 - small portrait +The avprefix structure: +avprefix.2da is a gemrb specific table. Its first row contains the base animationID used for the actor. Its optional additional rows contain other table resrefs which refine the animationID by different player stats. The first row of these tables contain the stat which affects the animationID. The other rows assign cummulative values to the animationID. +For example: + +avprefix.2da + RESOURCE +0 0x6000 +1 avprefr +2 avprefg +3 avprefc +avprefr.2da + RACE +TYPE 201 +HUMAN 0 +ELF 1 +HALF_ELF 1 +GNOME 4 +HALFLING 3 +DWARF 2 +HALFORC 5 + +Based on the avatar's stat (201 == race) the animationID (0x6000) will be increased by the given values. For example an elf's animationID will be 0x6001. The animationID will be further modified by gender and class. + +Return value: N/A + +Examples: + GemRB.FillPlayerInfo(MyChar, PortraitName+"M", PortraitName+"S") + +See also: LoadGame, CreatePlayer, SetPlayerStat, EnterGame + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/FindTableValue.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/FindTableValue.txt new file mode 100644 index 000000000..dcac5d316 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/FindTableValue.txt @@ -0,0 +1,19 @@ + +Prototype: GemRB.FindTableValue(TableIndex, ColumnIndex, Value[, Start]) + +Metaclass Prototype: FindValue(ColumnIndex, Value[, Start]) + +Description: Returns the first rowcount of a field value in a 2DA Table. If Start +is omitted, the search starts from the beginning. This command doesn't work with +a string value. + +Parameters: +TableIndex - integer, returned by a previous LoadTable command. +ColumnIndex - integer, the index of the column in which you look for the value. +Value - integer, The value to find in the table +Start - integer, The starting row + +Return value: numeric, -1 if the value isn't to be found + +See also: LoadTable, GetTableValue + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameControlGetTargetMode.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameControlGetTargetMode.txt new file mode 100644 index 000000000..efd82ae48 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameControlGetTargetMode.txt @@ -0,0 +1,9 @@ + +Prototype: GemRB.GameControlGetTargetMode() + +Description: Returns the current target mode. It could be: talk, attack, spellcast and such. + +Return value: numeric (see GameControlSetTargetMode) + +See also: GameControlSetScreenFlags + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameControlSetLastActor.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameControlSetLastActor.txt new file mode 100644 index 000000000..e9fd4bb1f --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameControlSetLastActor.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.GameControlSetLastActor(partyID) + +Description: Sets LastActor in the GameControl object. The LastActor object is the player character which is currently about to be selected by the player. Its feet circle is flickering. + +Parameters: partyID - 0 to delete any previous settings, or the partyID. + +Return value: None + +See also: GameSelectPCSingle + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameControlSetScreenFlags.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameControlSetScreenFlags.txt new file mode 100644 index 000000000..a93a603bb --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameControlSetScreenFlags.txt @@ -0,0 +1,18 @@ + +Prototype: GemRB.GameControlSetScreenFlags(Mode, Operation) + +Description: Sets screen flags, like cutscene mode, disable mouse, etc. Don't confuse it with the saved screen flags set by GameSetScreenFlags. + +Parameters: +Mode - bitfield + 1 - disable mouse + 2 - center on actor (one time) + 4 - center on actor (always) + 8 - enable gui + 16 - lock scroll +Operation - see bit_operation.txt + +Return value: N/A + +See also: GameSetScreenFlags, bit_operation + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameControlSetTargetMode.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameControlSetTargetMode.txt new file mode 100644 index 000000000..2f7db92cb --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameControlSetTargetMode.txt @@ -0,0 +1,22 @@ + +Prototype: GemRB.GameControlSetTargetMode(Mode) + +Description: Sets action to be made by the player (the cursor will change). It could be: talk, attack, spellcast. + +Parameters: + Mode - 0 none + 1 talk + 2 attack (bash) + 4 spellcast + 8 defend + 16 pick lock + + Also the target type could be added: +TARGET_MODE_ALLY = 0x100 +TARGET_MODE_ENEMY = 0x200 +TARGET_MODE_NEUTRAL = 0x400 + +Return value: N/A + +See also: GameControlSetScreenFlags, GameControlGetTargetMode + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameGetFirstSelectedPC.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameGetFirstSelectedPC.txt new file mode 100644 index 000000000..5c309f279 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameGetFirstSelectedPC.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.GameGetFirstSelectedPC() + +Description: Returns index of the first selected PC or 0 if none. + +Parameters: N/A + +Return value: the first selected PC's position in the party (it will look in the original party order, thus the protagonist will be always first!) + +See also: GameSelectPC, GameIsPCSelected + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameGetFormation.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameGetFormation.txt new file mode 100644 index 000000000..a51f6a09d --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameGetFormation.txt @@ -0,0 +1,11 @@ + +Prototype: GameGetFormation() + +Description: Returns current party formation. The formations are stored in the GemRB specific formatio.2da table. + +Parameters: N/A + +Return value: integer + +See also: GameSetFormation + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameGetPartyGold.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameGetPartyGold.txt new file mode 100644 index 000000000..f7dc2d9e3 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameGetPartyGold.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.GameGetPartyGold() + +Description: Returns current party gold. + +Parameters: N/A + +Return value: numeric + +See also: GetPlayerStat + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameGetReputation.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameGetReputation.txt new file mode 100644 index 000000000..9deb646ea --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameGetReputation.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.GameGetReputation() + +Description: Returns current party's reputation. + +Parameters: N/A + +Return value: numeric + +See also: GetPlayerStat, GameSetReputation + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameGetSelectedPCSingle.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameGetSelectedPCSingle.txt new file mode 100644 index 000000000..cb1e0a45f --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameGetSelectedPCSingle.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.GameGetSelectedPCSingle(flag) + +Description: If flag is 0 or omitted, then returns currently active pc in non-walk environment (i.e. in shops, inventory,...). If flag is set to non-zero, then returns the currently speaking PC. +If there is no such PC, then returns 0. + +Parameters: flag - 0/1 + +Return value: PartyID (1-10) + +See also: GameSelectPC, GameSelectPCSingle + +MD5: b19700ed972c915b0910b40a746a87ee diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameIsBeastKnown.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameIsBeastKnown.txt new file mode 100644 index 000000000..a575d627f --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameIsBeastKnown.txt @@ -0,0 +1,11 @@ + +Prototype: GameIsBeastKnown(index) + +Description: Returns whether beast with given index is known to PCs (works only on PST). + +Parameters: index - the beast's index as of beast.ini + +Return value: boolean, 1 means beast is known. + +See also: GetINIBeastsKey + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameIsPCSelected.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameIsPCSelected.txt new file mode 100644 index 000000000..726e7875a --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameIsPCSelected.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.GameIsPCSelected(Slot) + +Description: Returns true if the PC is selected. + +Parameters: Slot - the PC's position in the party (1 based) + +Return value: boolean, 1 if the PC is selected + +See also: GameSelectPC, GameGetFirstSelectedPC + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GamePause.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GamePause.txt new file mode 100644 index 000000000..abb50175d --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GamePause.txt @@ -0,0 +1,12 @@ + +Prototype: GemRB.GamePause(pause, quiet) + +Description: Pauses or unpauses the current game. This affects all ingame events, including: scripts, animations, movement. It doesn't affect the GUI. + +Parameters: pause - int, 1 = pause, 0 = continue, 2 = toggle pause + quiet - bool, true = no message, false = game paused/unpaused message + +Return value: N/A + +See also: + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSelectPC.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSelectPC.txt new file mode 100644 index 000000000..023eb4485 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSelectPC.txt @@ -0,0 +1,21 @@ + +Prototype: GemRB.GameSelectPC(PartyID, Selected, [Flags = SELECT_NORMAL]) + +Description: Selects or deselects a PC. Note: some things use a different PC selection mechanism (dialogs and stores are not unified yet). + +Parameters: PartyID - the PC's position in the party, 0 means ALL + Selected - boolean + Flags - bitflags +bit 1 - if set deselect all other actors +bit 2 - do not run SelectionHandler (no GUI feedback) + +Return value: N/A + +Example: +def SelectAllOnPress (): + GemRB.GameSelectPC (0, 1) + return +The above function is associated to the 'select all' button of the GUI screen. + +See also: GameIsPCSelected, GameSelectPCSingle, GameGetSelectedPCSingle, GameGetFirstSelectedPC + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSelectPCSingle.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSelectPCSingle.txt new file mode 100644 index 000000000..a1d9226a4 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSelectPCSingle.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.GameSelectPCSingle(PartyID) + +Description: Selects one PC in non-walk environment (i.e. in shops, inventory,...). + +Parameters: +PartyID - the PC's position in the party + +Return value: N/A + +See also: GameSelectPC, GameGetSelectedPCSingle + +MD5: 6ff47eca2a1cc470e3b909a8c1f9fa0b diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSetExpansion.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSetExpansion.txt new file mode 100644 index 000000000..3139b4e3a --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSetExpansion.txt @@ -0,0 +1,14 @@ + +Prototype: GemRB.GameSetExpansion(mode) + +Description: Sets the expansion mode. Most games were created in a two in one and could start the game as expansion only (or transfer to the expansion). +This command selects between these two modes. + +-- this command is not working -- + +Parameters: Mode - 0 or 1 + +Return value: N/A + +See also: LoadGame, GameType(variable) + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSetFormation.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSetFormation.txt new file mode 100644 index 000000000..db882adc9 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSetFormation.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.GameSetFormation(Formation) + +Description: Sets party formation. + +Parameters: the row index of formatio.2da + +Return value: N/A + +See also: GameGetFormation + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSetPartyGold.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSetPartyGold.txt new file mode 100644 index 000000000..f4f5f21df --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSetPartyGold.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.GameSetPartyGold(Gold) + +Description: Sets current party gold. + +Parameters: the gold amount to be set + +Return value: N/A + +See also: GameGetPartyGold + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSetPartySize.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSetPartySize.txt new file mode 100644 index 000000000..56f078762 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSetPartySize.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.GameSetPartySize(Size) + +Description: Sets the maximum number of PCs. This command works only after a LoadGame(). If the party size was set to 0, then it means unlimited size. + +Parameters: Size - must be 0-8 + +Return value: N/A + +See also: GetPartySize + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSetProtagonistMode.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSetProtagonistMode.txt new file mode 100644 index 000000000..31eb71f6d --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSetProtagonistMode.txt @@ -0,0 +1,14 @@ + +Prototype: GemRB.GameSetProtagonistMode(Mode) + +Description: Sets the mode the game handles the game over event. This action works only after a LoadGame. + +Parameters: + Mode - 0 no check + 1 game over when protagonist dies + 2 game over when whole party is dead + +Return value: N/A + +See also: LoadGame, GameSetPartySize + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSetReputation.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSetReputation.txt new file mode 100644 index 000000000..9b3d46af6 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSetReputation.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.GameSetReputation(Reputation) + +Description: Sets current party's reputation. + +Parameters: the reputation amount to be set. (It is divided by ten when displayed). + +Return value: N/A + +See also: GameGetReputation, IncreaseReputation + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSetScreenFlags.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSetScreenFlags.txt new file mode 100644 index 000000000..d7c1b79fd --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GameSetScreenFlags.txt @@ -0,0 +1,14 @@ + +Prototype: GemRB.GameSetScreenFlags(Bits, Operation) + +Description: Stores the portrait/options/message window size value in the game object. + +Parameters: + Bits - This depends on the game. + The lowest 2 bits are the message window size + Operation - The usual bit operations (see bit_operation.txt) + +Return value: N/A + +See also: SetVisible, bit_operation + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetAbilityBonus.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetAbilityBonus.txt new file mode 100644 index 000000000..e3af6dbf8 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetAbilityBonus.txt @@ -0,0 +1,23 @@ + +Prototype: GemRB.GetAbilityBonus(stat, column, value[, ex]) + +Description: Returns ability based values from different .2da files. Like strmod, dexmod, etc. + +Parameters: stat - a stat value, like IE_STR + column - integer, the column index of the value in the .2da file + +Column indices: + +IE_STR: 0 - To hit, 1 - Damage, 2 - Open doors, 3 - Weight allowance +IE_INT: 0 - learn spell, 1 - max spell level, 2 - max spell number on level +IE_DEX: 0 - reaction adjustment, 1 - missile, 2 - AC +IE_CON: 0 - normal hp, 1 - warrior hp, 2 - minimum hp roll, 3 - hp regen rate, 4 - fatigue +IE_CHR: 0 - reaction +IE_LORE: 0 - lore bonus (int+wis based) +IE_REPUTATION: 0 - reaction (chr+reputation based) +IE_WIS: 0 - percentile xp bonus + +Return value: -9999 if the parameters are illegal, otherwise the required bonus + +See also: SetPlayerStat, GetPlayerStat, GetTableValue + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetCharSounds.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetCharSounds.txt new file mode 100644 index 000000000..6b605b32c --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetCharSounds.txt @@ -0,0 +1,20 @@ + +Prototype: GemRB.GetCharSounds(WindowIndex, ControlIndex) + +Metaclass Prototype: GetCharSounds(ControlIndex) + +Description: Reads the contents of the sounds subfolder into a TextArea control. + +Parameters: +WindowIndex, ControlIndex - the control's reference + + +Return value: numeric, the number of rows read into the TextArea control. +Example: + TextAreaControl = GemRB.GetControl(SoundWindow, 45) + GemRB.SetTextAreaSelectable(SoundWindow, TextAreaControl,1) + GemRB.SetVarAssoc(SoundWindow, TextAreaControl, "Sound", 0) + RowCount=GemRB.GetCharSounds(SoundWindow, TextAreaControl) + +See also: QueryText, GetCharacters + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetCharacters.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetCharacters.txt new file mode 100644 index 000000000..396f3f023 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetCharacters.txt @@ -0,0 +1,20 @@ + +Prototype: GemRB.GetCharacters(WindowIndex, ControlIndex) + +Metaclass Prototype: GetCharacters(ControlIndex) + +Description: Reads the contents of the characters subfolder into a TextArea control. + +Parameters: +WindowIndex, ControlIndex - the control's reference + + +Return value: numeric, the number of rows read into the TextArea control. +Example: + TextAreaControl = GemRB.GetControl(SoundWindow, 45) + GemRB.SetTextAreaSelectable(SoundWindow, TextAreaControl,1) + GemRB.SetVarAssoc(SoundWindow, TextAreaControl, "Characters", 0) + RowCount=GemRB.GetCharSounds(SoundWindow, TextAreaControl) + +See also: QueryText, GetCharSounds + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetCombatDetails.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetCombatDetails.txt new file mode 100644 index 000000000..fa148dab1 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetCombatDetails.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.GetCombatDetails(pc, leftorright) + +Description: Returns the current THAC0 and other data in relation to the equipped weapon. + +Parameters: +pc - position in the party +leftorright - left or right hand weapon (main or offhand) + +Return value: dict: "ToHit", "Flags", "DamageBonus", "Speed", "CriticalBonus", "Style" + +See also: IsDualWielding + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetContainer.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetContainer.txt new file mode 100644 index 000000000..a8a1d33ad --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetContainer.txt @@ -0,0 +1,15 @@ + +Prototype: GetContainer( PartyID, autoselect ) + +Description: Gets the current container's type and other basic header information. The player is always the first selected player. If PartyID is 0 then the default PC is the first multiselected PC. Autoselect will always select a groundpile. If there is no container at the feet of the PC autoselect will create the container. + +Parameters: + PartyID - the PC's position in the party + autoselect - is 1 if you call this function from a player inventory (so you select the pile at their feet) + +Return value: dictionary +"Type" - the container's type, numeric (see IESDP) +"ItemCount" - the number of items in the container + +See also: GetStore, GameGetFirstSelectedPC, GetContainerItem + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetContainerItem.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetContainerItem.txt new file mode 100644 index 000000000..ee6d64656 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetContainerItem.txt @@ -0,0 +1,19 @@ + +Prototype: GetContainerItem( PartyID, index ) + +Description: Returns the container item referenced by the index. If PartyID is 0 then the container was opened manually and should be the current container. If PartyID is not 0 then the container is autoselected and should be at the feet of the player. + +Parameters: + PartyID - the PC's position in the party + index - the item's index in the container + +Return value: dictionary +"ItemResRef" - the ResRef of the item +"ItemName" - the StrRef of the item's name (identified or not) +"Usages0" - The primary charges of the item (or the item's stack amount if the item is stackable). +"Usages1" - The secondary charges of the item. +"Usages2" - The tertiary charges of the item. +"Flags" - Item flags. + +See also: GetContainer, GameGetFirstSelectedPC, GetStoreItem + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetControl.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetControl.txt new file mode 100644 index 000000000..3852268e6 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetControl.txt @@ -0,0 +1,14 @@ + +Prototype: GemRB.GetControl(WindowIndex, ControlID) + +Description: Returns a control in a Window. + +Parameters: WindowIndex - the return value of a previous LoadWindow call. + ControlID - a control ID, see the .chu file specification + +Return value: a control index + +See also: LoadWindowPack, LoadWindow + + +MD5: eccbc1af698fd8d4e5eec5004433e515 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetControlObject.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetControlObject.txt new file mode 100644 index 000000000..610e4e051 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetControlObject.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.GetControlObject(WindowID, ControlID) + +Description: Returns a control as an object. + +Parameters: +WindowIndex - the window control id +ControlID - the id of the target control + +Return value: GControl + +See also: + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetCurrentArea.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetCurrentArea.txt new file mode 100644 index 000000000..dc778686d --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetCurrentArea.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.GetCurrentArea() + +Description: Returns the name of the current area. It is the same as GetGameString(1). It works only after a LoadGame() was issued. + +Parameters: N/A + +Return value: string, (ARE resref) + +See also: GetGameString + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetDestinationArea.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetDestinationArea.txt new file mode 100644 index 000000000..2dc9e84b8 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetDestinationArea.txt @@ -0,0 +1,21 @@ + +Prototype: GemRB.GetDestinationArea(WindowIndex, ControlIndex[, RndEncounter]) + +Metaclass Prototype: GetDestinationArea([RndEncounter]) + +Description: Returns a dictionary of the selected area by the worldmap control. +If the route is blocked, then Distance will return a negative value and Destination/Entrance won't be set. Random encounters could be optionally evaluated. + +Parameters: + WindowIndex, ControlIndex - designate a worldmap control + RndEncounter - 0/1 + +Return value: Dictionary +Target - The target area selected by the player +Distance - The traveling distance, if it is negative, the way is blocked +Destination - The area resource reference where the player arrives (if there was a random encounter, it differs from Target) +Entrance - The area entrance in the Destination area, it could be empty, in this casethe player should appear in middle of the area + +See also: CreateWorldMapControl, CreateMovement, accessing_gui_controls + +MD5: b19700ed972c915b0910b40a746a87ee diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetEquippedAmmunition.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetEquippedAmmunition.txt new file mode 100644 index 000000000..79687ffe6 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetEquippedAmmunition.txt @@ -0,0 +1,11 @@ +Prototype: GemRB.GetEquippedAmmunition(PartyID) + +Description: Returns the equipped ammunition, if any + +Parameters: PartyID - the PC's position in the party (1 based) + +Return value: If ammunition is equipped, the inventory slot, otherwise -1. + +See also: GetEquippedQuickSlot + +MD5: f8136021ae5f439ccbd5fa3de99574a1 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetEquippedQuickSlot.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetEquippedQuickSlot.txt new file mode 100644 index 000000000..5562f13d2 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetEquippedQuickSlot.txt @@ -0,0 +1,14 @@ +Prototype: GemRB.GetEquippedQuickSlot(PartyID[, NoTrans]) + +Description: Returns the quickweapon slot index or the inventory slot. + +Parameters: + PartyID - the PC's position in the party (1 based) + NoTrans - 0 - return the inventory slot + 1 - return the quickweapon slot index + +Return value: numeric + +See also: SetEquippedQuickSlot, GetEquippedAmmunition + +MD5: 587dea2203900410b41c8775a9cc4d18 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetGameString.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetGameString.txt new file mode 100644 index 000000000..dd1eb40ce --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetGameString.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.GetGameString(Index) + +Description: Returns a system variable of string type referenced by Index. + +Parameters: Index +0 - returns the loading picture's name (MOS resref) +1 - returns the current area's name (ARE resref) + +Return value: string - the referenced system variable + +See also: GetSystemVariable, GetToken + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetGameTime.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetGameTime.txt new file mode 100644 index 000000000..4ca892fd0 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetGameTime.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.GetGameTime() + +Description: Returns current game time (rounds passed since start). + +Parameters: N/A + +Return value: numeric + +See also: GameGetPartyGold, GetPartySize + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetGameVar.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetGameVar.txt new file mode 100644 index 000000000..b7066045b --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetGameVar.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.GetGameVar(VariableName) + +Description: Get a Variable value from the Game Global Dictionary. This is what gamescripts know as GLOBAL variable. + +Parameters: + +Return value: + +Example: Chapter = GemRB.GetGameVar("chapter") + +See also: GetVar, GetToken, CheckVar + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetINIBeastsKey.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetINIBeastsKey.txt new file mode 100644 index 000000000..24785fc75 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetINIBeastsKey.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.GetINIBeastsKey(Tag, Key, Default) + +Description: Returns a Value from the beast.ini File (works only on PST). + +Parameters: +Tag - a section in the beast.ini file +Key - a field in the section +Default - default value in case the entry doesn't exist + +Return value: string, the entry from the ini file + +See also: GetINIQuestsKey diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetINIPartyCount.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetINIPartyCount.txt new file mode 100644 index 000000000..92ee07f23 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetINIPartyCount.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.GetINIPartyCount() + +Description: Returns the Number of Parties defined in Party.ini (works only on IWD2). + +Parameters: N/A + +Return value: the number of predefined parties as of party.ini + +See also: GetINIPartyKey + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetINIPartyKey.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetINIPartyKey.txt new file mode 100644 index 000000000..eb822ec5c --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetINIPartyKey.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.GetINIPartyKey(Tag, Key, Default) + +Description: Returns a Value from the party.ini File (works only on IWD2). + +Parameters: +Tag - a section in the party.ini file +Key - a field in the section +Default - default value in case the entry doesn't exist + +Return value: string, the entry from the ini file + +See also: GetINIPartyCount diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetINIQuestsKey.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetINIQuestsKey.txt new file mode 100644 index 000000000..121eda78c --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetINIQuestsKey.txt @@ -0,0 +1,14 @@ + +Prototype: GemRB.GetINIQuestsKey(Tag, Key, Default) + +Description: Returns a Value from the quests.ini File (works only on PST). + +Parameters: +Tag - a section in the quests.ini file +Key - a field in the section +Default - default value in case the entry doesn't exist + +Return value: string, the entry from the ini file + +See also: GetINIBeastsKey + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetItem.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetItem.txt new file mode 100644 index 000000000..3b157d1ab --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetItem.txt @@ -0,0 +1,33 @@ + +Prototype: GemRB.GetItem(ResRef) + +Description: Returns dictionary with the specified item's data. + +Parameters: ResRef - the resource reference of the item + +Return value: dictionary +The fields of the dictionary are the following: +"ItemName" - strref of unidentified name. +"ItemNameIdentified" - strref of identified name. +"ItemDesc" - strref of unidentified description. +"ItemDescIdentified" - strref of identified description. +"ItemIcon" - the item's icon (.bam resref) +"StackAmount" - maximum stackable amount +"Dialog" - item dialog (.dlg resref) +"DialogName" - the item dialog name +"Function" - returns special function + 0 - no special function + 1 - item is a copyable scroll (2. header's 1. feature is 'Learn spell') + 2 - item is a drinkable potion +"Spell" - the spell's strref if the item is a copyable scroll +"DescIcon" - the description icon +"BrokenItem" - the replacement item (used for items with broken sounds) +"Price" - the base item price +"Type" - the item type (see itemtype.2da) +"AnimationType" - the item animation ID +"Exclusion" - the exclusion bit (used by eg. magic armor and rings of protection). +"LoreToID" - the required lore to identify the item +"Tooltips" - the item tooltips + +See also: GetSlotItem, GetSpell, SetItemIcon + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetJournalEntry.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetJournalEntry.txt new file mode 100644 index 000000000..67232936d --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetJournalEntry.txt @@ -0,0 +1,17 @@ + +Prototype: GemRB.GetJournalEntry(chapter, index[, section]) + +Description: Returns dictionary representing journal entry w/ given chapter, section and index. Section will default to zero. + +Parameters: chapter - the chapter of the journal entry + index - the index of the entry in the given section/chapter + section - the section of the journal + +Return value: dictionary with the following fields: +"Text" - strref of the journal entry +"GameTime" - time of entry +"Section" - same as the input parameter +"Chapter" - same as the input parameter + +See also: GetJournalSize, SetJournalEntry + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetJournalSize.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetJournalSize.txt new file mode 100644 index 000000000..2b1dc201e --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetJournalSize.txt @@ -0,0 +1,12 @@ + +Prototype: GemRB.GetJournalSize(chapter[, section]) + +Description: Returns the number of entries in the given section of journal. Please note that various engines implemented the chapter/sections at various degree. For example PST has none of these. Section will default to zero. + +Parameters: chapter - the chapter of the journal page + section - 0,1,2 or 4 - general, quest, solved quest or user notes. + +Return value: numeric + +See also: GetJournalEntry, SetJournalEntry + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetKnownSpell.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetKnownSpell.txt new file mode 100644 index 000000000..82307aca5 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetKnownSpell.txt @@ -0,0 +1,17 @@ + +Prototype: GemRB.GetKnownSpell(PartyID, SpellType, Level, Index) + +Description: Returns dictionary with specified known spell from PC's spellbook. + +Parameters: +PartyID - the PC's position in the party +SpellType - 0 - priest, 1 - wizard, 2 - innate +Level - the memorized spell's level +Index - the memorized spell's index + +Return value: dictionary +The field(s) of the dictionary are the following: +"SpellResRef" - The name of the spell (.spl resref) + +See also: GetMemorizedSpell + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetKnownSpellsCount.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetKnownSpellsCount.txt new file mode 100644 index 000000000..28e293d8e --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetKnownSpellsCount.txt @@ -0,0 +1,14 @@ + +Prototype: GemRB.GetKnownSpellsCount(PartyID, SpellType, Level) + +Description: Returns number of known spells of given type and level in a player character's spellbook. + +Parameters: +PartyID - the PC's position in the party +SpellType - 0 - priest, 1 - wizard, 2 - innate +Level - the memorized spell's level + +Return value: numeric + +See also: GetMemorizedSpellsCount, GetKnownSpell + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetMemorizableSpellsCount.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetMemorizableSpellsCount.txt new file mode 100644 index 000000000..d8de78aba --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetMemorizableSpellsCount.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.GetMemorizableSpellsCount(PartyID, SpellType, Level [,Bonus]) + +Description: Returns number of memorizable spells of given type and level in a player character's spellbook. + +Parameters: +PartyID - the PC's position in the party +SpellType - 0 - priest, 1 - wizard, 2 - innate +Level - the memorized spell's level +Bonus - whether querying the modified or the base value + +Return value: numeric, it returns -1 if the query is invalid (no spellcaster, bad spelltype, too high level). + +See also: SetMemorizableSpellsCount + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetMemorizedSpell.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetMemorizedSpell.txt new file mode 100644 index 000000000..fb0965225 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetMemorizedSpell.txt @@ -0,0 +1,18 @@ + +Prototype: GemRB.GetMemorizedSpell(PartyID, SpellType, Level, Index) + +Description: Returns dict with specified memorized spell from PC's spellbook. + +Parameters: +PartyID - the PC's position in the party +SpellType - 0 - priest, 1 - wizard, 2 - innate +Level - the memorized spell's level +Index - the memorized spell's index + +Return value: dictionary +The fields of the dictionary are the following: +"SpellResRef" - The name of the spell (.spl resref) +"Flags" - Is the spell castable, or already spent + +See also: GetMemorizedSpellsCount + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetMemorizedSpellsCount.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetMemorizedSpellsCount.txt new file mode 100644 index 000000000..53beb6d66 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetMemorizedSpellsCount.txt @@ -0,0 +1,14 @@ + +Prototype: GemRB.GetMemorizedSpellsCount(PartyID, SpellType, Level) + +Description: Returns number of spells of given type and level in selected character's memory. + +Parameters: +PartyID - the PC's position in the party +SpellType - 0 - priest, 1 - wizard, 2 - innate +Level - the memorized spell's level + +Return value: numeric + +See also: GetMemorizedSpell, GetKnownSpellsCount + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetMessageWindowSize.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetMessageWindowSize.txt new file mode 100644 index 000000000..74e2f5e2e --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetMessageWindowSize.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.GetMessageWindowSize() + +Description: Returns current MessageWindowSize, it works only when a game is loaded. + +Parameters: N/A + +Return value: int + +See also: + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPCStats.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPCStats.txt new file mode 100644 index 000000000..d560c4842 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPCStats.txt @@ -0,0 +1,20 @@ + +Prototype: GemRB.GetPCStats(PartyID) + +Description: Returns dictionary of PC's performance stats. + +Parameters: PartyID - the PC's position in the party (1 based) + +Return value: A Python dictionary containing the following items +"BestKilledName" - strref of killed creature with biggest XP +"BestKilledXP" - XP value of this creature +"JoinDate" - date joined the team +"KillsChapterXP" - total XP from kills gathered in this chapter +"KillsChapterCount"- total number of kills in this chapter +"KillsTotalXP" - total XP from kills +"KillsTotalCount" - total number of kills +"FavouriteSpell" - spell used the most of the time +"FavouriteWeapon" - weapon bringing the most kill XP + +See also: + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPartySize.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPartySize.txt new file mode 100644 index 000000000..61b1239d7 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPartySize.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.GetPartySize() + +Description: Returns the actual number of PCs (dead included). This command works only after a LoadGame(). + +Parameters: N/A + +Return value: numeric (should be 0-8) + +See also: LoadGame, QuitGame, GameSetPartySize + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPlayerName.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPlayerName.txt new file mode 100644 index 000000000..705c352af --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPlayerName.txt @@ -0,0 +1,17 @@ + +Prototype: GemRB.GetPlayerName(PartyID[, LongOrShort]) + +Description: Queries the player character's name. + +Parameters: +PartyID - the PC's position in the party (1 based) +LongOrShort - which name to query +-1 : default name + 0 : shortname + 1 : longname + 2 : scripting name + +Return value: string, it returns ??? if the PC doesn't exist. + +See also: SetPlayerName, GetPlayerStat + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPlayerPortrait.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPlayerPortrait.txt new file mode 100644 index 000000000..9d932337a --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPlayerPortrait.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.GetPlayerPortrait(Slot[, SmallOrLarge]) + +Description: Queries the player's portrait. To set the portrait of a new character you must use FillPlayerInfo(). + +Parameters: +Slot - the PC's position in the party +SmallOrLarge - boolean, specify 1 if you want to get the large portrait + +Return value: the player's portrait name (.bmp resref) + +See also: FillPlayerInfo + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPlayerScript.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPlayerScript.txt new file mode 100644 index 000000000..1418d753a --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPlayerScript.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.GetPlayerScript(Slot[, Index]) + +Description: Queries the player's script. You can also set the scripts. + +Parameters: +Slot - the PC's position in the party +Index - script index (see scrlevel.2da) + +Return value: the player's script (.bcs or .baf resref) + +See also: SetPlayerScript + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPlayerStat.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPlayerStat.txt new file mode 100644 index 000000000..b08d17241 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPlayerStat.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.GetPlayerStat(Slot, ID[, Base]) + +Description: Queries a stat of the player character. The stats are listed in ie_stats.py. + +Parameters: Slot - actor index in game structure + ID - Stat index + Base - if set to 1, the function will return the base instead of the modified (current) value + +Return value: numeric + +See also: SetPlayerStat, GetPlayerName, GetPlayerStates + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPlayerStates.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPlayerStates.txt new file mode 100644 index 000000000..9d543d1f7 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPlayerStates.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.GetPlayerStates(PartyID) + +Description: Returns the active spell states on the player. The state descriptions are in the statdesc.2da file which comes with the original games. The values in the character array equal to the corresponding cycle number in states.bam. To reference statdesc.2da, subtract 65 from the values. + +Parameters: + PartyID - the character's position in the party + +Return value: a string whose letters are greater or equal ascii 65. + +See also: GetPlayerName, GetPlayerStat diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPlayerString.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPlayerString.txt new file mode 100644 index 000000000..3be37b9a1 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPlayerString.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.GetPlayerString(PartyID, StringIndex) + +Description: Returns the string reference of a Verbal Constant set in the player. +The biography string is an example of such a string. + +Parameters: + PartyID - the character's position in the party + StringIndex - the verbal constant's index + +Return value: a string reference. + +See also: GetPlayerName, GetPlayerStat, GetPlayerScript + +See also: sndslot.ids, soundoff.ids (it is a bit unclear which one is it) diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPortraits.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPortraits.txt new file mode 100644 index 000000000..a8edee387 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetPortraits.txt @@ -0,0 +1,21 @@ + +Prototype: GemRB.GetPortraits(WindowIndex, ControlIndex, SmallOrLarge) + +Metaclass Prototype: GetPortraits(SmallOrLarge) + +Description: Reads the contents of the portraits subfolder into a TextArea control. + +Parameters: +WindowIndex, ControlIndex - the control's reference +SmallOrLarge - 0 means the portraits with 'M' as the suffix, anything else 'S' + + +Return value: numeric, the number of rows read into the TextArea control. +Example: + TextAreaControl = GemRB.GetControl(SoundWindow, 45) + GemRB.SetTextAreaSelectable(SoundWindow, TextAreaControl,1) + GemRB.SetVarAssoc(SoundWindow, TextAreaControl, "Sound", 0) + RowCount=GemRB.GetPortraits(SoundWindow, TextAreaControl, 0) + +See also: QueryText, GetCharacters, GetCharSounds + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetRumour.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetRumour.txt new file mode 100644 index 000000000..3144f3441 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetRumour.txt @@ -0,0 +1,12 @@ + +Prototype: GetRumour( percent, DialogResRef ) + +Description: Gets a rumour string reference from a rumour dialog. + +Parameters: percent - chance of not returning -1 +DialogResRef - a rumour dialog resource + +Return value: a string reference + +See also: EnterStore, GetStoreDrink, GetStore + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSaveGameAttrib.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSaveGameAttrib.txt new file mode 100644 index 000000000..b9a78c9d8 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSaveGameAttrib.txt @@ -0,0 +1,20 @@ + +Prototype: GemRB.GetSaveGameAttrib(Type, SlotCount) + +Description: Returns the name, path, prefix and elapsed game time of the +passed saved game. + +Parameters: +Type - the queried attribute's name + 0 - name + 1 - prefix + 2 - path + 3 - date + 4 - elapsed game time + 5 - id +SlotCount - the index of a saved game + +Return value: string + +See also: + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSaveGameCount.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSaveGameCount.txt new file mode 100644 index 000000000..5c6dc96d0 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSaveGameCount.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.GetSaveGameCount() + +Description: Returns the number of saved games. + +Parameters: N/A + +Return value: numeric + +See also: DeleteSaveGame, GetSaveGameAttrib, SetSaveGamePortrait, SetSaveGamePreview, SaveGame + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSelectedSize.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSelectedSize.txt new file mode 100644 index 000000000..36f36de55 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSelectedSize.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.GetSelectedSize() + +Description: Returns the number of actors selected in the party. + +Parameters: + +Return value: int + +See also: + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSlotItem.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSlotItem.txt new file mode 100644 index 000000000..033214f58 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSlotItem.txt @@ -0,0 +1,29 @@ + +Prototype: GemRB.GetSlotItem(PartyID, slot) + +Description: Returns dictionary with the specified actor's inventory slot data. + +Parameters: +PartyID - the PC's position in the party +slot - the item's inventory slot + +Return value: dictionary +The fields of the dictionary are the following: +"ItemResRef" - The name of the item (.itm resref) +"Usages0" - The primary charges of the item (or the item's stack amount if the item is stackable). +"Usages1" - The secondary charges of the item. +"Usages2" - The tertiary charges of the item. +"Flags" - Item flags: +IE_INV_ITEM_IDENTIFIED = 1, The item is identified. +IE_INV_ITEM_UNSTEALABLE = 2, The item is unstealable. +IE_INV_ITEM_STOLEN = 4, The item is stolen. +IE_INV_ITEM_UNDROPPABLE =8, The item is undroppable. +IE_INV_ITEM_ACQUIRED = 0x10, The item was recently moved. +IE_INV_ITEM_DESTRUCTIBLE = 0x20, The item is removable (sellable or destructible). +IE_INV_ITEM_EQUIPPED = 0x40, The item is currently equipped. +IE_INV_ITEM_STACKED = 0x80, The item is a stacked item. +"Header" - Item's extended header assigned to the inventory slot (the + ability to use). Only applicable to quickslots. + +See also: GetItem, SetItemIcon, ChangeItemFlag + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSlotType.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSlotType.txt new file mode 100644 index 000000000..3062d3361 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSlotType.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.GetSlotType(idx) + +Description: Returns dictionary of an itemslot type (slottype.2da). + +Parameters: idx - a row number of slottype.2da + +Return value: dictionary +"Type" - bitfield, The inventory slot's type. +"ID" - the gui button's controlID which belongs to this slot. +"Tip" - the tooltip resref for this slot. +"ResRef" - the background .bam of the slot. + +See also: SetItemIcon + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSlots.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSlots.txt new file mode 100644 index 000000000..f5a9f0825 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSlots.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.GetSlots(PartyID, SlotType[, Flag]) + +Description: Returns the tuple of slots of a PC which match the SlotType criteria. FIXME: This function cannot yet handle PST's diverse slottypes. + +Parameters: PartyID - a PC +SlotType - bitfield, the inventory slot's type (32768 means inventory) +Flag - >0 - returns filled slots + - <0 - returns empty slots + - 0 - returns all slots. +The default is 1. + +Return value: tuple + +See also: GetSlotType diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSpell.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSpell.txt new file mode 100644 index 000000000..383464059 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSpell.txt @@ -0,0 +1,21 @@ + +Prototype: GemRB.GetSpell(ResRef[, silent]) + +Description: Returns dictionary with the specified spell's data. If silent +is set, nothing will be printed to the console. + +Parameters: ResRef - the resource reference of the spell. + +Return value: dictionary +The fields of the dictionary are the following: +"SpellName" - strref of unidentified name. +"SpellDesc" - strref of unidentified description. +"SpellbookIcon" - the spell's icon (.bam resref) +"SpellExclusion" - the excluded schools and alignments +"SpellDivine" - this field tells divine magics apart +"SpellSchool" - the spell's school (primary type) +"SpellType" - the type of text that appears on spell dispelling +"SpellLevel" - the spell's level + +See also: GetItem, SetSpellIcon, spell_structure(IESDP) + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetStore.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetStore.txt new file mode 100644 index 000000000..e8435cbc0 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetStore.txt @@ -0,0 +1,24 @@ + +Prototype: GetStore( ) + +Description: Gets the basic header information of the current store and returns it in a dictionary. The information is precompiled based on room availability, store type + +Parameters: N/A + +Return value: dictionary +"StoreType" - numeric (see IESDP) +"StoreName" - the StrRef of the store name +"StoreDrinkCount" - the count of drinks served (tavern) +"StoreCureCount" - the count of cures served (temple) +"StoreItemCount" - the count of items sold, in case of PST the availability trigger is also checked +"StoreCapacity" - the capacity of the store +"StoreRoomPrices" - a four elements tuple, negative if the room type is unavailable +"StoreButtons" - a four elements tuple, possible actions +"StoreFlags" - the store flags if you ever need them, StoreButtons is a digested information, but you might have something else in mind based on these +"TavernRumour" - ResRef of tavern rumour dialog +"TempleRumour" - ResRef of temple rumour dialog + +See also: EnterStore, GetStoreCure, GetStoreDrink, GetRumour + + +MD5: 1899d9bf9e161d3b1a6ec8b3d9fdff19 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetStoreCure.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetStoreCure.txt new file mode 100644 index 000000000..42a271384 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetStoreCure.txt @@ -0,0 +1,14 @@ + +Prototype: GetStoreCure( index ) + +Description: Gets the spell resref, price and description of a store cure referenced by the index. + +Parameters: index - the number of the cure in the store list + +Return value: dictionary +"CureResRef" - the ResRef of the cure spell +"Description" - the StrRef of the spell's description +"Price" - the price of the spell (subtract this from the party gold) + +See also: EnterStore, GetStoreDrink, GetStore + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetStoreDrink.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetStoreDrink.txt new file mode 100644 index 000000000..339988bda --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetStoreDrink.txt @@ -0,0 +1,14 @@ + +Prototype: GetStoreDrink( index ) + +Description: Gets the name, strength and price of a store drink referenced by the index. + +Parameters: index - the number of the drink in the store list + +Return value: dictionary +"DrinkName" - the StrRef of the drink name +"Strength" - the strength if the drink (affects rumour and intoxication) +"Price" - the price of the drink (subtract this from the party gold) + +See also: EnterStore, GetStoreCure, GetStore + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetStoreItem.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetStoreItem.txt new file mode 100644 index 000000000..9dfb07687 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetStoreItem.txt @@ -0,0 +1,20 @@ + +Prototype: GetStoreItem( index ) + +Description: Gets the item resref, price and description of a store item referenced by the index. In case of PST stores the item's availability is also checked against the availability trigger. + +Parameters: index - the number of the cure in the store list + +Return value: dictionary +"ItemResRef" - the ResRef of the item +"ItemName" - the StrRef of the item's name (identified or not) +"ItemDesc" - the StrRef of the item's description (identified or not) +"Price" - the price of the item (subtract this from the party gold) +"Amount" - the amount of item in store (-1 means infinite) +"Usages0" - The primary charges of the item (or the item's stack amount if the item is stackable). +"Usages1" - The secondary charges of the item. +"Usages2" - The tertiary charges of the item. +"Flags" - Item flags. + +See also: EnterStore, GetStoreDrink, GetStoreCure, GetStore, GetSlotItem + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetString.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetString.txt new file mode 100644 index 000000000..133ff4c67 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetString.txt @@ -0,0 +1,23 @@ + +Prototype: GemRB.GetString(Strref, Flags) + +Description: Returns string for given strref. Usually, you don't need to resolve a string before use, you can use SetText with an strref parameter. This command lets you alter the string. For example, if you want to add a level value, you'll need this. + +Parameters: Strref - a string index from the dialog.tlk table. + Flags - a bitfield + +Values for the flags: +1 - strref on +2 - play attached sound +4 - speech (stop previous sound) +256 - strref off (overrides cfg) + +Return value: A string with resolved tokens. To resolve %d's, you must either use StatComment, or do it manually. + +Example: GemRB.SetText (Window, Label, GemRB.GetString(12137)+str(level+1) ) +The above example will display "Level: " in the addressed label. + +See also: StatComment, SetText + + +MD5: 27500d4f0d9773b4cdfdc6f615d0b668 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSymbolValue.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSymbolValue.txt new file mode 100644 index 000000000..c005956e7 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSymbolValue.txt @@ -0,0 +1,26 @@ + +Prototype: GemRB.GetSymbolValue(SymbolIndex, StringVal|IntVal) + +Metaclass Prototype: GetValue(StringVal|IntVal) + +Description: Returns a field of a IDS Symbol Table. + +Parameters: + SymbolIndex - returned by a previous LoadSymbol command + StringVal - the name of the symbol to resolve (first column of .ids file) + IntVal - the value of the symbol to find. (second column of .ids file) + +Return value: + numeric, if the symbol's name was given (the value of the symbol) + string, if the value of the symbol was given (the symbol's name) + +Example: + align = GemRB.GetPlayerStat (pc, IE_ALIGNMENT) + ss = GemRB.LoadSymbol ("ALIGN") + sym = GemRB.GetSymbolValue (ss, align) +The above example will find the symbolic name of the player's alignment. + +See also: LoadSymbol, GetTableValue + + +MD5: afa5d5072904c5d0b345e2e08f8e2cbe diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSystemVariable.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSystemVariable.txt new file mode 100644 index 000000000..389100ad0 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetSystemVariable.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.GetSystemVariable(Index) + +Description: Returns the named Interface attribute. + +Parameters: Index could have the following values: +SV_BPP = 0 - bpp (color resolution) +SV_WIDTH = 1 - screen width +SV_HEIGHT = 2 - screen height + +Return value: This function returns -1 if the index is invalid. + +See also: GetGameString + + +MD5: b60fafad2a078631a0f53b50b323c8b4 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetTableColumnCount.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetTableColumnCount.txt new file mode 100644 index 000000000..9862e3940 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetTableColumnCount.txt @@ -0,0 +1,17 @@ + +Prototype: GemRB.GetTableColumnCount(TableIndex[, Row]) + +Metaclass Prototype: GetColumnCount([Row]) + +Description: Returns the number of columns in the specified row in a 2DA Table. + +Parameters: + TableIndex - returned by a previous LoadTable command. + Row - the row of the table, if omitted, defaults to 0 + +Return value: numeric + +See also: LoadTable, GetTableRowCount + + +MD5: diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetTableColumnIndex.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetTableColumnIndex.txt new file mode 100644 index 000000000..31737a309 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetTableColumnIndex.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.GetTableColumnIndex(TableIndex, ColumnName) + +Metaclass Prototype: GetColumnIndex(ColumnName) + +Description: Returns the Index of a Column referenced by ColumnName in a 2DA Table. + +Parameters: TableIndex - returned by a previous LoadTable command. +ColumnName - a column label + +Return value: numeric, -1 if column doesn't exist + +See also: LoadTable, GetTableRowIndex diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetTableColumnName.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetTableColumnName.txt new file mode 100644 index 000000000..a26d8cae8 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetTableColumnName.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.GetTableColumnName(TableIndex, ColumnIndex) + +Metaclass Prototype: GetColumnName(ColumnIndex) + +Description: Returns the Name of a Column in a 2DA Table. + +Parameters: TableIndex - returned by a previous LoadTable command. +ColumnIndex - the numeric index of the column. + +Return value: string + +See also: LoadTable, GetTableRowName + + +MD5: 1fec0670e5cbec6f1b45ba5214986bbf diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetTableRowCount.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetTableRowCount.txt new file mode 100644 index 000000000..82bf6b0e2 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetTableRowCount.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.GetTableRowCount(TableIndex) + +Metaclass Prototype: GetRowCount(TableIndex) + +Description: Returns the number of rows in a 2DA Table. + +Parameters: TableIndex - returned by a previous LoadTable command. + +Return value: numeric + +See also: LoadTable, GetTableColumnCount + + +MD5: 3b149161b60a872bde007850fa0f2196 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetTableRowIndex.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetTableRowIndex.txt new file mode 100644 index 000000000..0e62fc6c4 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetTableRowIndex.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.GetTableRowIndex(TableIndex, RowName) + +Metaclass Prototype: GetRowIndex(RowName) + +Description: Returns the Index of a Row referenced by RowName in a 2DA Table. + +Parameters: TableIndex - returned by a previous LoadTable command. +RowName - a row label + +Return value: numeric, -1 if row doesn't exist + +See also: LoadTable + + +MD5: eb41ba2363ba1262a8edfff8265514da diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetTableRowName.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetTableRowName.txt new file mode 100644 index 000000000..418776c38 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetTableRowName.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.GetTableRowName(TableIndex, RowIndex) + +Metaclass Prototype: GetRowName(RowIndex) + +Description: Returns the Name of a Row in a 2DA Table. + +Parameters: TableIndex - returned by a previous LoadTable command. +RowIndex - the numeric index of the row. + +Return value: string + +See also: LoadTable, GetTableColumnName + + +MD5: 0f970b7c96685f7e78874353dc885f37 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetTableValue.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetTableValue.txt new file mode 100644 index 000000000..3bab16777 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetTableValue.txt @@ -0,0 +1,23 @@ + +Prototype: GemRB.GetTableValue(TableIndex, RowIndex/RowString, ColIndex/ColString[, Type]) + +Metaclass Prototype: GetValue(RowIndex/RowString, ColIndex/ColString[, Type]) + +Description: Returns a field of a 2DA Table. The row and column indices must be of same type (either string or numeric), the return value will be of the same type. +Type can also be specified. + +Parameters: TableIndex - returned by a previous LoadTable command. +RowIndex, ColIndex - numeric row/column indices +RowString,ColString - the row/column names as written in the 2da file +Type - forces a specific return type +-1 - default + 0 - string + 1 - int + 2 - stat symbol (translated to numeric) + +Return value: numeric or string, based on the indices or type + +See also: GetSymbolValue, FindTableValue, LoadTable + + +MD5: 27a07ff76472c9880891f7548e1ca4f4 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetToken.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetToken.txt new file mode 100644 index 000000000..f79d8fc80 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetToken.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.GetToken(VariableName) + +Description: Get a Variable value from the Token Dictionary. Tokens are string values, both used by the gamescript and the GUI scripts. + +Parameters: VariableName - the name of the variable must be shorter than 32 bytes + +Return value: string, the value of the token + +Example: GemRB.TextAreaAppend(CharGenWindow, TextArea, GemRB.GetToken("CHARNAME")) +The above example will add the protagonist's name to the TextArea (if the token was set correctly). + +See also: SetToken, QueryText + + +MD5: fea89d3ea3aa58100ad165ea6b9cb605 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetVar.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetVar.txt new file mode 100644 index 000000000..c2ffd997c --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/GetVar.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.GetVar(VariableName) + +Description: Get a Variable value from the Global Dictionary. Controls could be set up to be associated with such a variable. Even multiple controls could affect the same variable. + +Parameters: VariableName - the name of the variable must be shorter than 32 bytes + +Return value: numeric, 0 if the variable doesn't exist + +Examples: + selected = GemRB.GetVar ("SelectedMovie") + +See also: SetVar, SetVarAssoc, data_exchange + + +MD5: e1d12a5de0cce9841d6f44622223e79e diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/HardEndPL.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/HardEndPL.txt new file mode 100644 index 000000000..f75bcbe1d --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/HardEndPL.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.HardEndPL() + +Description: Ends a Music Playlist immediately. + +Parameters: N/A + +Return value: N/A + +See also: SoftEndPL + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/HasControl.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/HasControl.txt new file mode 100644 index 000000000..e6508b790 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/HasControl.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.HasControl(WindowIndex, ControlID[, ControlType]) + +Metaclass Prototype: HasControl(ControlID[, ControlType]) + +Description: Returns true if the control exists. + +Parameters: +WindowIndex - the window control id +ControlID - the id of the target control +ControlType - (optional) limit to controls of this type (export them from control.h when needed) + +Return value: bool + +See also: + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/HasResource.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/HasResource.txt new file mode 100644 index 000000000..7ba2dff0d --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/HasResource.txt @@ -0,0 +1,9 @@ + +Prototype: GemRB.HasResource(ResRef, ResType) + +Description: Returns true if the resource exists. + +Parameters: ResRef - the resource reference (8 characters filename) + ResType - the class ID of the resource + +Return value: boolean diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/HasSpecialItem.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/HasSpecialItem.txt new file mode 100644 index 000000000..fcaf7dee9 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/HasSpecialItem.txt @@ -0,0 +1,14 @@ + +Prototype: GemRB.HasSpecialItem(pc, itemtype, useup) + +Description: Checks if a team member has an item, optionally uses it. + +Parameters: +pc - position in the party +itemtype - see itemspec.2da (usually 1) +useup - destroy/remove a charge after use + +Return value: bool + +See also: + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/HasSpecialSpell.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/HasSpecialSpell.txt new file mode 100644 index 000000000..905c8585f --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/HasSpecialSpell.txt @@ -0,0 +1,14 @@ + +Prototype: GemRB.HasSpecialSpell(pc, itemtype, useup) + +Description: Checks if a team member has a spell, optionally uses it. + +Parameters: +pc - position in the party +itemtype - see splspec.2da +useup - destroy/remove a charge after use + +Return value: bool + +See also: + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/HideGUI.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/HideGUI.txt new file mode 100644 index 000000000..bfb6b0884 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/HideGUI.txt @@ -0,0 +1,28 @@ + +Prototype: GemRB.HideGUI() + +Description: Hides the game GUI (all windows except the GameControl window). It is also used before a major change is made on a GUI window. After the changes, an UnhideGUI() command should be issued too. The game GUI window references are stored in the following system variables: +MessageWindow - contains a TextArea for ingame messages/dialogue +OptionsWindow - a series of buttons for Inventory/Spellbook/Journal,etc +PortraitWindow - a series of portrait buttons +ActionsWindow - a series of buttons to Attack/Talk,etc +TopWindow - unused (might be removed later) +OtherWindow - this window usually covers the GameControl, it is used to display maps, inventory, journal, etc. +FloatWindow - special window which floats on top of the GameControl +All these windows are associated with a position variable too, these are MessagePosition, OptionsPosition, etc. +The position value tells the engine the window's relative position to the GameControl GUI. The engine doesn't make any distinction between these windows based on their reference name. The differences come from the position value. +-1 - no position (floats over GameControl) +0 - left +1 - bottom +2 - right +3 - top +4 - bottom (cummulative) + +Parameters: N/A + +Return value: 1 on success? + +See also: UnhideGUI, InvalidateWindow, SetVisible + + +MD5: b95f905bba48f95a878868c7c453d52f diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/IncreaseReputation.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/IncreaseReputation.txt new file mode 100644 index 000000000..ca3d8ccc1 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/IncreaseReputation.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.IncreaseReputation(Donation) + +Description: Increases party's reputation based on Donation. (see reputatio.2da) + +Parameters: the gold spent as donation to increase reputation. You have to change the party's gold separately. + +Return value: Nonzero if the reputation has been increased. (The amount of increase is multiplied by ten.) + +See also: GameGetReputation, GameGetPartyGold, GameSetPartyGold + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/InvalidateWindow.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/InvalidateWindow.txt new file mode 100644 index 000000000..6a301d0da --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/InvalidateWindow.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.InvalidateWindow(WindowIndex) + +Metaclass Prototype: Invalidate() + +Description: Invalidates the given Window so it will be redrawn entirely. + +Parameters: WindowIndex is the index returned by LoadWindow() + +Return value: N/A + +See also: LoadWindow + + +MD5: 98ab4933674a41c8ce3d21ab00ac45af diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/IsDraggingItem.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/IsDraggingItem.txt new file mode 100644 index 000000000..2a5be5571 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/IsDraggingItem.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.IsDraggingItem() + +Description: Returns 1 if the player is dragging an item with the mouse (usually in the inventory screen). Returns 2 if the player is dragging a portrait (rearranging the party). + +Parameters: N/A + +Return value: boolean + +See also: DropDraggedItem, DragItem + + +MD5: 3444790d47084300ab522deaca065d43 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/IsDualWielding.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/IsDualWielding.txt new file mode 100644 index 000000000..7999b07a1 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/IsDualWielding.txt @@ -0,0 +1,12 @@ + +Prototype: GemRB.IsDualWielding(pc) + +Description: 1 if the pc is dual wielding; 0 otherwise. + +Parameters: +pc - position in the party + +Return value: bool + +See also: + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/IsValidStoreItem.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/IsValidStoreItem.txt new file mode 100644 index 000000000..05e5a896e --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/IsValidStoreItem.txt @@ -0,0 +1,18 @@ + +Prototype: IsValidStoreItem( PartyID, slot[, type] ) + +Description: Returns if a pc's inventory item or a store item is valid for buying, selling, identifying or stealing. If Type is 1, then this is a store item. + +Parameters: +PartyID - the PC's position in the party +slot - the item's inventory or store slot + +Return value: bitfield +1 - valid for buy +2 - valid for sell +4 - valid for identify +8 - valid for steal +0x40 - selected for buy or sell + +See also: EnterStore, GetSlotItem, GetStoreItem, ChangeStoreItem + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LearnSpell.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LearnSpell.txt new file mode 100644 index 000000000..9681a8082 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LearnSpell.txt @@ -0,0 +1,19 @@ + +Prototype: GemRB.LearnSpell(PartyID, SpellResRef[, Flags]) + +Description: Tries to learn the specified spell. + +Parameters: +PartyID - the PC's position in the party +SpellResRef - the spell's Resource Reference +Flags - bitmap with the following bits (default is 0): + 1 - Give XP for learning (Level * 100) + 2 - Display message + 4 - Check for insufficient stats + 8 - Also memorize it + +Return value: integer, 0 on success, different values on failure. + +See also: MemorizeSpell, RemoveSpell + +MD5: 768a8203f408816c5294f8601a7a4b4e diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LeaveContainer.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LeaveContainer.txt new file mode 100644 index 000000000..362475205 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LeaveContainer.txt @@ -0,0 +1,11 @@ + +Prototype: LeaveContainer( ) + +Description: Closes the current container by calling 'CloseContainerWindow' in the next update cycle. You cannot call 'CloseContainerWindow' directly, because the core system needs to know if the container subwindow is still open. This function will also remove empty ground piles. + +Parameters: - + +Return value: None + +See also: GetContainer, GetContainerItem, LeaveStore + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LeaveParty.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LeaveParty.txt new file mode 100644 index 000000000..4a5be5e54 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LeaveParty.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.LeaveParty(Slot [, Dialog]) + +Description: Removes the player character from the party. + +Parameters: Slot - actor index in game structure + Dialog - if set to 1, initiate the dialog. + if set to 2, execute "SetLeavePartyDialogFile" and initiate dialog. + +Return value: N/A + +See also: GetPartySize + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LeaveStore.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LeaveStore.txt new file mode 100644 index 000000000..3ca40173b --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LeaveStore.txt @@ -0,0 +1,11 @@ + +Prototype: LeaveStore( ) + +Description: Saves the current store to the Cache folder and removes it from memory. If there was no active store, this function causes a runtime error. + +Parameters: - + +Return value: None + +See also: EnterStore, GetStore + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LoadGame.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LoadGame.txt new file mode 100644 index 000000000..4e64f1aba --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LoadGame.txt @@ -0,0 +1,20 @@ + +Prototype: GemRB.LoadGame(index[,version]) + +Description: Loads a saved game. This must be done before party creation. +You must set the variable called PlayMode before loading a game (see SetVar). +The game won't be loaded before the current GUIScript function returns! + +Parameters: index - the saved game's index, -1 means new game. + version - optional version to override some buggy default savegame versions +PlayMode (variable) - 0 (single player) ,1 (tutorial) ,2 (multi player) + +Return value: N/A + +Example: GemRB.SetVar("PlayMode", 0) + GemRB.LoadGame(-1, 22) + +See also: EnterGame, CreatePlayer, SetVar, SaveGame + + +MD5: a1bc07430d99c420a4e662a67eeda8fb diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LoadMusicPL.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LoadMusicPL.txt new file mode 100644 index 000000000..bbee6f877 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LoadMusicPL.txt @@ -0,0 +1,12 @@ + +Prototype: LoadMusicPL(MusicPlayListResource, HardEnd) + +Description: Loads and starts a Music PlayList. + +Parameters: MusicPlayListResource is a .mus resref +HardEnd - off by default, set to 1 to disable the fading at the end + +Return value: N/A + +See also: SoftEndPL, HardEndPL + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LoadSymbol.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LoadSymbol.txt new file mode 100644 index 000000000..542e4ae2b --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LoadSymbol.txt @@ -0,0 +1,14 @@ + +Prototype: GemRB.LoadSymbol(IDSResRef) + +Description: Loads a IDS Symbol List. In case it was already loaded, it will return the list's existing reference (won't load it again). + +Parameters: IDSResRef - the symbol list's name (.ids resref) + +Return value: + Symbol table reference index + +See also: UnloadSymbol + + +MD5: 40c9dacdfad30df5302c753880a84aa0 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LoadTable.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LoadTable.txt new file mode 100644 index 000000000..09a3b8fd0 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LoadTable.txt @@ -0,0 +1,14 @@ + +Prototype: GemRB.LoadTable(2DAResRef, [ignore_error=0]) + +Description: Loads a 2DA Table. In case it was already loaded, it will return the table's existing reference (won't load it again). + +Parameters: 2DAResRef - the table's name (.2da resref) + ignore_error - boolean, if set, then the script won't be blocked by missing files. + +Return value: GTable + +See also: UnloadTable, LoadSymbol + + +MD5: fc03d66804e2be05bed6bfaa56900d66 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LoadWindow.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LoadWindow.txt new file mode 100644 index 000000000..cc38a1931 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LoadWindow.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.LoadWindow(WindowID) + +Description: Returns a Window. You must call LoadWindowPack before using this command. The window won't be displayed. + If LoadWindowPack() set nonzero natural screen size with Width and Height + parameters, the loaded window is then moved by + (screen size - winpack size) / 2 + +Parameters: a window ID, see the .chu file specification + +Return value: GWindow + +See also: LoadWindowPack, GetControl, SetVisible, ShowModal, accessing_gui_controls + +MD5: c307b6a51ed3bcc0e551bad770b37853 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LoadWindowFrame.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LoadWindowFrame.txt new file mode 100644 index 000000000..84e9dfc0a --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LoadWindowFrame.txt @@ -0,0 +1,32 @@ +Prototype: GemRB.LoadWindowFrame(MOSResRef_Left, MOSResRef_Right, MOSResRef_Top, MOSResRef_Bottom)) + +Description: Load the parts of window frame used to decorate windows + on higher resolutions. + +Parameters: + MOSResRef_Left, + MOSResRef_Right, + MOSResRef_Top, + MOSResRef_Bottom: names of MOS files with frame parts + +Return value: N/A + +Example: (from bg2's Start.py) + # Find proper window border for higher resolutions + screen_width = GemRB.GetSystemVariable (SV_WIDTH) + screen_height = GemRB.GetSystemVariable (SV_HEIGHT) + if screen_width == 800: + GemRB.LoadWindowFrame ("STON08L", "STON08R", "STON08T", "STON08B") + elif screen_width == 1024: + GemRB.LoadWindowFrame ("STON10L", "STON10R", "STON10T", "STON10B") + + # Windows in this winpack were originally made and placed + # for 640x480 screen size + GemRB.LoadWindowPack ("START", 640, 480) + StartWindow = GemRB.LoadWindow (0) + GemRB.SetWindowFrame (StartWindow) + + +See also: SetWindowFrame, LoadWindowPack + +MD5: 22d075f66da06a3c45c66a547719f960 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LoadWindowPack.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LoadWindowPack.txt new file mode 100644 index 000000000..f1d482014 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/LoadWindowPack.txt @@ -0,0 +1,19 @@ + +Prototype: GemRB.LoadWindowPack(CHUIResRef, [Width=0, Height=0]) + +Description: Loads a WindowPack into the Window Manager Module. Only one windowpack may be open at a time, but once a window was selected by LoadWindow, you can get a new windowpack. + +Parameters: + CHUIResRef: the name of the GUI set (.CHU resref) + Width, Height: if nonzero, they set the natural screen size for which + the windows in the winpack are positioned. LoadWindow() uses this + information to automatically reposition loaded windows. + +Return value: N/A + +Example: + LoadWindowPack ("START", 640, 480) + +See also: LoadWindow, LoadWindowFrame + +MD5: 591f80db15302b2a620238219b61f02a diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/Makefile.am b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/Makefile.am new file mode 100644 index 000000000..3a2484302 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/Makefile.am @@ -0,0 +1,3 @@ +guiscriptdocs_DATA = *.txt +guiscriptdocsdir = $(docdir)/GUIScript/ +EXTRA_DIST = *.txt diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/MemorizeSpell.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/MemorizeSpell.txt new file mode 100644 index 000000000..c257d560f --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/MemorizeSpell.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.MemorizeSpell(PartyID, SpellType, Level, Index) + +Description: Sets spell to be memorized on rest. + +Parameters: +PartyID - the PC's position in the party +SpellType - 0 - priest, 1 - wizard, 2 - innate +Level - the known spell's level +Index - the known spell's index + +Return value: boolean, 1 on success. + +See also: GetKnownSpell, UnmemorizeSpell + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ModifyEffect.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ModifyEffect.txt new file mode 100644 index 000000000..704d796be --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ModifyEffect.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.ModifyEffects(PartyID, opcode, x, y) + +Description: Changes/sets the target coordinates of the specified effect. +This command is used for the farsight spell. + +Parameters: +PartyID - the player character's index in the party +opcode - the effect opcode (for values see effects.ids) +x - target x coordinate +y - target y coordinate + +Return value: N/A + +See also: ApplyEffect, CountEffects + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/MoveTAText.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/MoveTAText.txt new file mode 100644 index 000000000..47abc9c8b --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/MoveTAText.txt @@ -0,0 +1,14 @@ + +Prototype: MoveTAText(srcWin, srcCtrl, dstWin, dstCtrl) + +Metaclass Prototype: MoveText(dstCtrl) + +Description: Copies a TextArea content to another TextArea. Both parameter pairs must point to a valid TextArea. + +Parameters: srcWin, srcCtrl - a window index/control index pair of the source control + dstWin, dstCtrl - a window index/control index pair of the destination control + +Return value: N/A + +See also: SetText + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/MoveToArea.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/MoveToArea.txt new file mode 100644 index 000000000..581168087 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/MoveToArea.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.MoveToArea(resref) + +Description: Moves the selected actors to the named area. + +Parameters: resref - The name of the area. + +Return value: N/A + +See also: GetCurrentArea + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/PlayMovie.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/PlayMovie.txt new file mode 100644 index 000000000..d1542fd2e --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/PlayMovie.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.PlayMovie(MOVResRef[,flag]) + +Description: Plays the named movie. Sets the configuration variable MOVResRef to 1. If flag was set to 1 it won't play the movie if the configuration variable was already set. + +Parameters: MOVResRef - a .mve resource reference. + flag - don't play movie twice + +Return value: 0 - movie played + -1 - error occurred + 1 - movie skipped + +See also: SetVar, GetVar + + +MD5: 5aa65188f90931b955b6c91969b3393c diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/PlaySound.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/PlaySound.txt new file mode 100644 index 000000000..1ffcccb12 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/PlaySound.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.PlaySound(SoundResource, xpos, ypos, type) + +Description: Plays a Sound. If there is a single PC selected, then it will play the sound as if it was said by that PC (EAX). + +Parameters: a .wav resref (the format could be raw pcm, wavc or ogg; 8/16 bit; mono/stereo). Use the None python object to simply stop the previous sound. + x coordinate of the position where the sound should be played (optional) + y coordinate of the position where the sound should be played (optional) + type - defaults to 1, use 4 for speeches or other sounds that should stop the previous sounds (optional) + +Return value: N/A + +See also: LoadMusicPL + + +MD5: 7370df8f931c57fc8317ca7472ea612e diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/QueryText.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/QueryText.txt new file mode 100644 index 000000000..2cfbbf301 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/QueryText.txt @@ -0,0 +1,23 @@ + +Prototype: QueryText(WindowIndex, ControlIndex) + +Metaclass Prototype: QueryText() + +Description: Returns the Text of a TextEdit/TextArea/Label control. In case of a TextArea, it will return the selected row, not the entire textarea. + +Parameters: WindowIndex, ControlIndex - the control's reference + +Return value: string, may be empty + +Example: + Name = GemRB.QueryText(NameWindow, NameField) + GemRB.SetToken("CHARNAME",Name) +The above example retrieves the character's name typed into the TextEdit control and stores it in a Token (a string variable accessible to gamescripts, the engine core and to the guiscripts too). + + GemRB.SetToken("VoiceSet", GemRB.QueryText(SoundWindow, TextAreaControl)) +The above example sets the VoiceSet token to the value of the selected string in a TextArea control. Later this voiceset could be stored in the character sheet. + +See also: SetText, SetToken, accessing_gui_controls + + +MD5: 7bcc3ff81f595b8d73c784ca32b06d5e diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/Quit.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/Quit.txt new file mode 100644 index 000000000..b7253ff37 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/Quit.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.Quit() + +Description: Quits the GemRB program immediately. + +Parameters: N/A + +Return value: N/A + +See also: QuitGame + + +MD5: 821540a9b347bc2490ac7935df46f481 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/QuitGame.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/QuitGame.txt new file mode 100644 index 000000000..9ddb07442 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/QuitGame.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.QuitGame() + +Description: Ends the current game session (saved game). To go back to the main screen, you must call SetNextScript. Automatically unloads all existing windows and resets the window variables used by HideGUI(). + +Parameters: N/A + +Return value: N/A + +See also: EnterGame, Quit, SetNextScript, HideGUI + + +MD5: ddab42f8f83286b5499855a5bec36bd1 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/RemoveEffects.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/RemoveEffects.txt new file mode 100644 index 000000000..a290d9305 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/RemoveEffects.txt @@ -0,0 +1,12 @@ + +Prototype: GemRB.RemoveEffects(PartyID, SpellResRef) + +Description: Removes all effects created by the spell named SpellResRef. +This is mostly useful for removing class abilities (CLAB/HLA AP_* entries). + +Parameters: +PartyID - the PC's position in the party +SpellResRef - a spell resource reference + +See also: RemoveSpell, RemoveItem + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/RemoveItem.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/RemoveItem.txt new file mode 100644 index 000000000..2560e5d9a --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/RemoveItem.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.RemoveItem(PartyID, Slot[, Count]) + +Description: Removes and destructs an item in an actor's inventory. This works even if the item is cursed or indestructible. + +Parameters: +PartyID - the PC's position in the party +Slot - The inventory slot index of the item +Count - the number of items + +Return value: boolean, 1 on success + +See also: CreateItem + +MD5: diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/RemoveSpell.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/RemoveSpell.txt new file mode 100644 index 000000000..9d6058999 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/RemoveSpell.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.RemoveSpell(PartyID, SpellType, Level, Index) + +Description: Unlearns a specified known spell. The original game (bg2) let only mage spells unlearned. + +Parameters: +PartyID - the PC's position in the party +SpellType - 0 - priest, 1 - wizard, 2 - innate +Level - the known spell's level +Index - the known spell's index + +Return value: boolean, 1 on success + +See also: UnmemorizeSpell, GetKnownSpellsCount, GetKnownSpell, LearnSpell, RemoveEffects + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/RestParty.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/RestParty.txt new file mode 100644 index 000000000..b13234674 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/RestParty.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.RestParty(flags, hp, movie) + +Description: Makes the party rest. It is possible to check various things that may forbid resting (hostile creatures, area flags, party scattered). It is possible to play a movie animation too. + +Parameters: +flags - +hp - hit points healed, 0 means full healing +movie - a number 0-7, see restmov.2da + +Return value: N/A + +See also: StartStore(gamescript) diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/RevealArea.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/RevealArea.txt new file mode 100644 index 000000000..748587a80 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/RevealArea.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.RevealArea(x, y, radius, type) + +Description: Reveals part of the area. + +Parameters: +x - x coordinate of the center point +y - y coordinate of the center point +radius - radius of the circle to explore +type - if positive will make the effect ignore blocked portions of the map + +Return value: N/A + +See also: + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/RewindTA.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/RewindTA.txt new file mode 100644 index 000000000..46a2893ae --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/RewindTA.txt @@ -0,0 +1,13 @@ + +Prototype: RewindTA(Win, Ctrl, Ticks) + +Metaclass Prototype: Rewind(Ticks) + +Description: Sets up a textarea control for scrolling text. It clears the textarea and sets TEXTAREA_SMOOTHSCROLL attribute in the textarea. + +Parameters: Win, Ctrl - a window index/control index pair of the textarea + Ticks - alters the scrolling speed (delay between steps) + +Return value: N/A + +See also: SetTAHistory, SetTextAreaFlags, SetEvent diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/Roll.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/Roll.txt new file mode 100644 index 000000000..e70e22a0e --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/Roll.txt @@ -0,0 +1,21 @@ + +Prototype: GemRB.Roll(Dice, Size, Add) + +Description: Calls traditional dice roll calculation. + +Parameters: Dice - the number of the dice. + Size - the size of the die. + Add - add this value directly to the sum + +Return value: numeric + +Example: + dice = 3 + size = 5 + v = GemRB.Roll(dice, size, 3) +The above example generates a 3d5+3 number. + +See also: + + +MD5: ad757524b8fb4284f423cd3f5fbb5eb1 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SaveCharacter.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SaveCharacter.txt new file mode 100644 index 000000000..1a647fff8 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SaveCharacter.txt @@ -0,0 +1,19 @@ + +Prototype: GemRB.SaveCharacter(PartyID, filename) + +Description: Saves (exports) the designated partymember into the Characters directory of the game. This character is importable later by a special CreatePlayer call. + +Parameters: + PartyID - the saved character's position in the party + filename - the filename of the character + +Return value: N/A + +Example: + pc = GemRB.GameGetSelectedPCSingle () + GemRB.SaveCharacter(pc, ExportFileName) + +The above example exports the currently selected character. + +See also: CreatePlayer + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SaveGame.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SaveGame.txt new file mode 100644 index 000000000..9732947da --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SaveGame.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.SaveGame(position, description) + +Description: Saves the current game. This won't be started before the current script returns. + +Parameters: + pos - the saved game's index, 0 and 1 are reserved + description - the string that will also appear in the filename + +Return value: N/A + +Example: + GemRB.SaveGame(0, "QuickSave") #this will make a quicksave + +See also: LoadGame, SaveCharacter + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetActionIcon.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetActionIcon.txt new file mode 100644 index 000000000..f3976ba59 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetActionIcon.txt @@ -0,0 +1,14 @@ + +Prototype: GemRB.SetActionIcon(WindowIndex, ControlIndex, ActionIndex) + +Metaclass Prototype: SetActionIcon(ActionIndex) + +Description: Sets up an action button based on the guibtact table. The ActionIndex should be less than 32. This action will set the button's image, the tooltip and the push button event handler. + +Parameters: +WindowIndex, ControlIndex - the button's reference +ActionIndex - the row number in the guibtact.2da file + +Return value: N/A + +See also: SetSpellIcon, SetItemIcon, SetupControls diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetAnimation.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetAnimation.txt new file mode 100644 index 000000000..e742814d4 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetAnimation.txt @@ -0,0 +1,17 @@ + +Prototype: GemRB.SetAnimation(WindowIndex, ControlIndex, BAMResRef[, Cycle]) + +Metaclass Prototype: SetAnimation(BAMResRef[, Cycle]) + +Description: Sets the animation of a Control (usually a Button) from a BAM file. Optionally an animation cycle could be set too. + +Parameters: +WindowIndex - the window control id +ControlID - the id of the target control +BAMResRef - resref of the animation +Cycle - (optional) number of the cycle to use + +Return value: N/A + +See also: SetAnimationPalette + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetAnimationPalette.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetAnimationPalette.txt new file mode 100644 index 000000000..004c4bba8 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetAnimationPalette.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.SetAnimationPalette(WindowIndex, ControlIndex, col1, col2, col3, col4, col5, col6, col7, col8) + +Metaclass Prototype: SetAnimationPalette(col1, col2, col3, col4, col5, col6, col7, col8) + +Description: Sets the palette of an animation already assigned to the button. + +Parameters: +WindowIndex - the window control id +ControlID - the id of the target control +col1 - col8 - colors for the palette + +Return value: N/A + +See also: SetAnimation + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetBufferLength.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetBufferLength.txt new file mode 100644 index 000000000..1052f908c --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetBufferLength.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.SetBufferLength(WindowIndex, ControlIndex, Length) + +Metaclass Prototype: SetBufferLength(Length) + +Description: Sets the maximum text length of a TextEdit Control. It cannot be more than 65535. + +Parameters: +WindowIndex - the window control id +ControlID - the id of the target control +Length - the maximum text length + +Return value: N/A + +See also: + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonBAM.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonBAM.txt new file mode 100644 index 000000000..1fa24bbac --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonBAM.txt @@ -0,0 +1,17 @@ + +Prototype: GemRB.SetButtonBAM(WindowIndex, ControlIndex, BAMResRef, CycleIndex, FrameIndex, col1) + +Metaclass Prototype: SetBAM(BAMResRef, CycleIndex, FrameIndex, col1) + +Description: Sets the Picture of a Button Control from a BAM file. If the supplied color gradient value is -1, then no palette change, if it is >=0, then it changes the 4-16 palette entries of the bam. + +Parameters: +WindowIndex, ControlIndex - the control's reference +BAMResRef - the name of the BAM animation (a .bam resref) +CycleIndex, FrameIndex - the cycle and frame index of the picture in the bam +col1 - the gradient number, (-1 no gradient) + +Return value: N/A + +See also: SetButtonPLT, SetButtonPicture, SetButtonSprites + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonBorder.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonBorder.txt new file mode 100644 index 000000000..509b2e20d --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonBorder.txt @@ -0,0 +1,27 @@ + +Prototype: GemRB.SetButtonBorder(WindowIndex, ControlIndex, BorderIndex, dx1, dy1, dx2, dy2, R, G, B, A, [enabled, filled]) + +Metaclass Prototype: SetBorder(BorderIndex, dx1, dy1, dx2, dy2, R, G, B, A, [enabled, filled]) + +Description: Sets border/frame/overlay parameters for a button. This command can be used for drawing a border around a button, or to overlay it with a tint (like with unusable or unidentified item's icons). + +Parameters: +WindowIndex, ControlIndex - the control's reference +BorderIndex - 0,1 or 2 +dx1,dy1 - Upper left corner +dx2,dy2 - Offset from the lower right corner +RGBA - red,green,blue,opacity components of the border colour +enabled - 1 means enable it immediately +filled - 1 means draw it filled (overlays) + +Return value: N/A + +Examples: +GemRB.SetButtonBorder (Window, Icon, 0, 0, 0, 0, 0, 0, 0, 0, 160, 0, 1) +Not known spells are drawn darkened (the whole button will be overlaid). + +GemRB.SetButtonBorder (Window, Button, FRAME_PC_SELECTED, 1, 1, 2, 2, 0, 255, 0, 255) +This will draw a green frame around the portrait. + +See also: EnableButtonBorder + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonFlags.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonFlags.txt new file mode 100644 index 000000000..480d57453 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonFlags.txt @@ -0,0 +1,35 @@ + +Prototype: GemRB.SetButtonFlags(WindowIndex, ControlIndex, Flags, Operation) + +Metaclass Prototype: SetFlags(Flags, Operation) + +Description: Sets the Display Flags of a Button. + +Parameters: +WindowIndex, ControlIndex - the control's reference +Flags - various bits altering the behaviour of the control +IE_GUI_BUTTON_NO_IMAGE = 0x00000001, no button image set by SetButtonSprites +IE_GUI_BUTTON_PICTURE = 0x00000002, has picture set by other SetButton* commands +IE_GUI_BUTTON_SOUND = 0x00000004, clicking the button has a sound +IE_GUI_BUTTON_ALT_SOUND = 0x00000008, clicking the button has a different sound +IE_GUI_BUTTON_CHECKBOX = 0x00000010, it is a checkbox +IE_GUI_BUTTON_RADIOBUTTON= 0x00000020, it is a radio button +IE_GUI_BUTTON_DEFAULT = 0x00000040, it is the default button +IE_GUI_BUTTON_DRAGGABLE = 0x00000080, the image of the button is draggable? +Operation - the binary operation to be performed on the + current button flags +OP_SET = 0, sets the value completely +OP_OR = 1, sets (turns on) the 1 bits of the value +OP_NAND = 2, resets (turns off) the 1 bits of the value + +Return value: N/A + +Examples: +GemRB.SetButtonFlags (window, button, IE_GUI_BUTTON_CHECKBOX, OP_OR) +This command will make the button behave like a checkbox. + +GemRB.SetButtonFlags (Window, Button, IE_GUI_BUTTON_NO_IMAGE, OP_NAND) +This command will re-enable the images of the button (making it visible). + +See also: SetButtonSprites, SetButtonPicture, SetButtonBAM + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonFont.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonFont.txt new file mode 100644 index 000000000..3af39c0b0 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonFont.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.SetButtonFont(WindowIndex, ControlIndex, FontResRef) + +Metaclass Prototype: SetFont(FontResRef) + +Description: Sets font used for drawing button text. + +Parameters: +WindowIndex, ControlIndex - the control's reference +FontResref - a .bam resref which must be listed in fonts.2da + +Return value: N/A + +See also: CreateLabel + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonMOS.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonMOS.txt new file mode 100644 index 000000000..1da76dfdf --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonMOS.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.SetButtonMOS(WindowIndex, ControlIndex, MOSResRef) + +Metaclass Prototype: SetMOS(MOSResRef) + +Description: Sets the Picture of a Button Control from a MOS file. + +Parameters: +WindowIndex, ControlIndex - the control's reference +MOSResRef - the name of the picture (a .mos resref) + +Return value: N/A + +See also: SetButtonBAM, SetButtonPLT, SetButtonPicture + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonOverlay.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonOverlay.txt new file mode 100644 index 000000000..58c991401 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonOverlay.txt @@ -0,0 +1,17 @@ + +Prototype: GemRB.SetButtonOverlay(Window, Button, ratio, r1,g1,b1,a1, r2,g2,b2,a2) + +Metaclass Prototype: SetOverlay(ratio, r1,g1,b1,a1, r2,g2,b2,a2) + +Description: Sets ratio (0-1.0) of height to which button picture will be overlaid in a different colour. The colour will fade from the first rgba values to the second. + +Parameters: +Window, Button - the control's reference +ClippingRatio - a floating point value from the 0-1 interval +rgba1 - source colour +rgba2 - target colour + +Return value: N/A + +See also: SetButtonPictureClipping + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonPLT.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonPLT.txt new file mode 100644 index 000000000..b1e06c3d3 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonPLT.txt @@ -0,0 +1,21 @@ + +Prototype: GemRB.SetButtonPLT(WindowIndex, ControlIndex, PLTResRef, col1, col2, col3, col4, col5, col6, col7, col8, type) + +Metaclass Prototype: SetPLT(PLTResRef, col1, col2, col3, col4, col5, col6, col7, col8, type) + +Description: Sets the Picture of a Button Control from a PLT file. Sets up the palette based on the eight given gradient colors. + +Parameters: +WindowIndex, ControlIndex - the control's reference +PLTResRef - the name of the picture (a .plt resref) +col1-8 - color gradients +type - the byte to use from the gradients + 0 Body (robe or armour) + 1 Weapon + 2 Shield + 3 Helmet + +Return value: N/A + +See also: SetButtonBAM + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonPicture.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonPicture.txt new file mode 100644 index 000000000..fd4d3fa85 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonPicture.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.SetButtonPicture(WindowIndex, ControlIndex, PictureResRef, DefaultResRef) + +Metaclass Prototype: SetPicture(PictureResRef, DefaultResRef) + +Description: Sets the Picture of a Button Control from a BMP file. + +Parameters: +WindowIndex, ControlIndex - the control's reference +PictureResRef - the name of the picture (a .bmp resref) +DefaultResRef - an alternate bmp should the picture be nonexistent +Return value: N/A + +See also: SetButtonBAM, SetButtonPLT, SetButtonSprites, SetButtonPictureClipping, SetWindowPicture + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonPictureClipping.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonPictureClipping.txt new file mode 100644 index 000000000..5cb7e1463 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonPictureClipping.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.SetButtonPictureClipping(Window, Button, ClippingRatio) + +Metaclass Prototype: SetPictureClipping(ClippingRatio) + +Description: Sets percent (0-1.0) of width to which button picture will be clipped. This clipping cannot be used simultaneously with SetButtonOverlay. + +Parameters: +Window, Button - the control's reference +ClippingRatio - a floating point value from the 0-1 interval + +Return value: N/A + +See also: SetButtonPicture, SetButtonOverlay + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonSprites.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonSprites.txt new file mode 100644 index 000000000..3b6c20438 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonSprites.txt @@ -0,0 +1,20 @@ + +Prototype: GemRB.SetButtonSprites(WindowIndex, ControlIndex, ResRef, Cycle, UnpressedFrame, PressedFrame, SelectedFrame, DisabledFrame) + +Metaclass Prototype: SetSprites(ResRef, Cycle, UnpressedFrame, PressedFrame, SelectedFrame, DisabledFrame) + +Description: Sets the Button's Images. You can disable the images by setting the IE_GUI_BUTTON_NO_IMAGE flag on the control. + +Parameters: +WindowIndex, ControlIndex - the control's reference +ResRef - a .bam animation resource (.bam resref) +Cycle - the cycle of the .bam from which all frames of this button will come +UnpressedFrame - the frame which will be displayed by default +PressedFrame - the frame which will be displayed when the button is pressed +SelectedFrame - this is for selected checkboxes +DisabledFrame - this is for inactivated buttons + +Return value: N/A + +See also: SetButtonFlags, SetButtonBAM, SetButtonPicture + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonState.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonState.txt new file mode 100644 index 000000000..b439d823c --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonState.txt @@ -0,0 +1,23 @@ + +Prototype: GemRB.SetButtonState(WindowIndex, ControlIndex, State) + +Metaclass Prototype: SetState(State) + +Description: Sets the state of a Button Control. Doesn't work if the button +is a checkbox or a radio button though, their states are handled internally. + +Parameters: WindowIndex, ControlIndex - the control's reference +State - the new state of the button: +IE_GUI_BUTTON_ENABLED = 0x00000000, default state +IE_GUI_BUTTON_UNPRESSED = 0x00000000, same as above +IE_GUI_BUTTON_PRESSED = 0x00000001, the button is pressed +IE_GUI_BUTTON_SELECTED = 0x00000002, the button stuck in pressed state +IE_GUI_BUTTON_DISABLED = 0x00000003, the button is disabled +IE_GUI_BUTTON_LOCKED = 0x00000004, the button is inactive (like DISABLED, but processes MouseOver events and draws UNPRESSED bitmap) +IE_GUI_BUTTON_THIRD = 0x00000005, draws DISABLED bitmap, but it isn't disabled +IE_GUI_BUTTON_SECOND = 0x00000006, draws PRESSED bitmap, but it isn't shifted + +Return value: N/A + +See also: SetButtonFlags + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonTextColor.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonTextColor.txt new file mode 100644 index 000000000..2b4c56410 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetButtonTextColor.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.SetButtonTextColor(WindowIndex, ControlIndex, red, green, blue) + +Metaclass Prototype: SetTextColor(red, green, blue) + +Description: Sets the Text Color of a Button Control. + +Parameters: +WindowIndex, ControlIndex - the control's reference +red,green,blue - the rgb color values + +Return value: N/A + +See also: SetLabelUseRGB, SetLabelTextColor + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetControlPos.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetControlPos.txt new file mode 100644 index 000000000..4d755c264 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetControlPos.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.SetControlPos(WindowIndex, ControlIndex, X, Y) + +Metaclass Prototype: SetPos(X, Y) + +Description: Moves a Control. + +Parameters: WindowIndex, ControlIndex - the control's reference +X,Y - the new position of the control relative to the window + +Return value: N/A + +See also: SetControlSize, accessing_gui_controls + + +MD5: fdec6fc5feaa586ba735e4b36c086989 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetControlSize.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetControlSize.txt new file mode 100644 index 000000000..d4667ae41 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetControlSize.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.SetControlSize(WindowIndex, ControlIndex, Width, Height) + +Metaclass Prototype: SetSize(Width, Height) + +Description: Resizes a Control. + +Parameters: WindowIndex, ControlIndex - the control's reference +Width, Height - the new dimensions of the control + +Return value: N/A + +See also: SetControlPos, accessing_gui_controls + + +MD5: e7467f0f874bffc30c31ef6030422c16 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetControlStatus.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetControlStatus.txt new file mode 100644 index 000000000..4eb417832 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetControlStatus.txt @@ -0,0 +1,31 @@ + +Prototype: GemRB.SetControlStatus(WindowIndex, ControlIndex, State) + +Metaclass Prototype: SetStatus(State) + +Description: Sets the state of a Control. For buttons, this is the same as SetButtonState. You can additionally use 0x80 for a focused control. +For other controls, this command will set the common Value of the control, which has various uses. + +Parameters: WindowIndex, ControlIndex - the control's reference + +Button States: +IE_GUI_BUTTON_ENABLED = 0x00000000, default state +IE_GUI_BUTTON_UNPRESSED = 0x00000000, same as above +IE_GUI_BUTTON_PRESSED = 0x00000001, the button is pressed +IE_GUI_BUTTON_SELECTED = 0x00000002, the button stuck in pressed state +IE_GUI_BUTTON_DISABLED = 0x00000003, the button is disabled +IE_GUI_BUTTON_LOCKED = 0x00000004, the button is inactive + +#Text Edit states +IE_GUI_EDIT_NUMBER = 0x030000001, the textedit will accept only digits + +Map Control States (add 0x09000000 to these): +IE_GUI_MAP_NO_NOTES = 0, no mapnotes visible +IE_GUI_MAP_VIEW_NOTES = 1, view notes (no setting) +IE_GUI_MAP_SET_NOTE = 2, allow setting notes + + +Return value: N/A + +See also: SetButtonState + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetDefaultActions.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetDefaultActions.txt new file mode 100644 index 000000000..4805d82c3 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetDefaultActions.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.SetDefaultActions(qslot, action1, action2, action3) + +Description: Sets whether quick slots need an additional translation like in iwd2. +Also sets up the first three default action types. + + +Parameters: qslot - bool + action1-3 - button codes + +Return value: N/A + +See also: SetupControls diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetDefaultScrollBar.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetDefaultScrollBar.txt new file mode 100644 index 000000000..664d447b1 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetDefaultScrollBar.txt @@ -0,0 +1,13 @@ + +Prototype: SetDefaultScrollBar(WindowIndex, ControlIndex) + +Metaclass Prototype: SetDefaultScrollBar() + +Description: Sets a ScrollBar as default on a window. If any control receives mousewheel events, it will be relayed to this ScrollBar, unless there is another attached to the control. + +Parameters: WindowIndex, ControlIndex - the ScrollBar control's reference + +Return value: N/A + +See also: AttachScrollBar + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetEquippedQuickSlot.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetEquippedQuickSlot.txt new file mode 100644 index 000000000..42cadd911 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetEquippedQuickSlot.txt @@ -0,0 +1,14 @@ +Prototype: GemRB.SetEquippedQuickSlot(PartyID, QWeaponSlot[, ability]) + +Description: Sets the specified weapon slot as equipped weapon slot. + +Parameters: +PartyID - the PC's position in the party (1 based) +QWeaponSlot - the quickslot to equip +ability - optional integer, sets the used ability + +Return value: 0 success, -1 silent failure + +See also: GetEquippedQuickSlot, SetupQuickSlot + +MD5: dde8a3aad7a34d817501e1d8877f5173 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetEvent.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetEvent.txt new file mode 100644 index 000000000..98ff994df --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetEvent.txt @@ -0,0 +1,43 @@ + +Prototype: Control.SetEvent(EventMask, PythonFunction) + +Description: Sets an event of a control on a window to a python function + +Parameters: +EventMask - a dword describing the event. Its high byte is actually the control's type. +PythonFunction - the function object + +Implemented events: +IE_GUI_BUTTON_ON_PRESS = 0x00000000, the user pressed the button. +IE_GUI_MOUSE_OVER_BUTTON = 0x00000001, the user hovered the mouse over the button. +IE_GUI_MOUSE_ENTER_BUTTON = 0x00000002, the user just moved the mouse onto the button. +IE_GUI_MOUSE_LEAVE_BUTTON = 0x00000003, the mouse just left the button +IE_GUI_BUTTON_ON_SHIFT_PRESS = 0x00000004, the button was pressed along with the shift key. +IE_GUI_BUTTON_ON_RIGHT_PRESS = 0x00000005, the button was right clicked +IE_GUI_BUTTON_ON_DRAG_DROP = 0x00000006, the button was clicked during a drag&drop action. +IE_GUI_PROGRESS_END_REACHED = 0x01000000, the progressbar received a 100 percent value. +IE_GUI_SLIDER_ON_CHANGE = 0x02000000, the slider's knob position has changed. +IE_GUI_EDIT_ON_CHANGE = 0x03000000, the text in the editbox has changed. +IE_GUI_TEXTAREA_ON_CHANGE = 0x05000000, the text in the textarea has changed. +IE_GUI_TEXTAREA_OUT_OF_TEXT = 0x05000001, the smooth scrolling textarea is out of text. +IE_GUI_LABEL_ON_PRESS = 0x06000000, the label was pressed. +IE_GUI_SCROLLBAR_ON_CHANGE= 0x07000000, the scrollbar's knob position has changed. +.... (See GUIDefines.py for more event types) + +Return value: N/A + +Examples: + Bar.SetEvent (IE_GUI_PROGRESS_END_REACHED, EndLoadScreen) + ... + def EndLoadScreen (): + Skull = GemRB.GetControl (LoadScreen, 1) + GemRB.SetButtonMOS (LoadScreen, Skull, "GSKULON") +The above example changes the image on the loadscreen when the progressbar reaches the end. + + Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, Buttons.YesButton) +The above example sets up the 'YesButton' function from the Buttons module to be called when the button is pressed. + + Button.SetEvent (IE_GUI_MOUSE_OVER_BUTTON, ChaPress) +The above example shows how to implement 'context sensitive help'. The 'ChaPress' function displays a help text on the screen when you hover the mouse over a button. + +See also: GetControl, SetVarAssoc, SetTimedEvent, accessing_gui_controls diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetFullScreen.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetFullScreen.txt new file mode 100644 index 000000000..0a0bdffac --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetFullScreen.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.SetFullScreen(flag) + +Description: Adjusts fullscreen mode. + +Parameters: +flag: + -1 : toggle fullscreen mode + 0 : set windowed mode + 1 : set fullscreen mode + +Return value: N/A + +See also: SetGamma + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetGamePortraitPreview.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetGamePortraitPreview.txt new file mode 100644 index 000000000..9bc782235 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetGamePortraitPreview.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.SetGamePortraitPreview(WindowIndex, ControlIndex, PCSlotCount) + +Metaclass Prototype: SetGamePortraitPreview(PCSlotCount) + +Description: Sets a current game PC portrait preview bmp onto a button as picture. + +Parameters: +WindowIndex - the window control id +ControlID - the id of the target control +PCSlotCount - number of pcs + +Return value: N/A + +See also: SetGamePreview + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetGamePreview.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetGamePreview.txt new file mode 100644 index 000000000..c7cc236ec --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetGamePreview.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.SetGamePreview(WindowIndex, ControlIndex) + +Metaclass Prototype: SetGamePreview() + +Description: Sets current game area preview bmp onto a button as picture. + +Parameters: +WindowIndex - the window control id +ControlID - the id of the target control + +Return value: N/A + +See also: SetGamePortraitPreview + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetGamma.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetGamma.txt new file mode 100644 index 000000000..613c9a40c --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetGamma.txt @@ -0,0 +1,12 @@ + +Prototype: GemRB.SetGamma(brightness, contrast) + +Description: Adjusts brightness and contrast. + +Parameters: +brightness - value must be 0 .. 40 +contrast - value must be 0 .. 5 + +Return value: N/A + +See also: SetFullScreen diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetGlobal.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetGlobal.txt new file mode 100644 index 000000000..7c93329fc --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetGlobal.txt @@ -0,0 +1,14 @@ + +Prototype: GemRB.SetGlobal(VariableName, Context, Value) + +Description: Sets a gamescript variable to the specificed numeric value. + +Parameters: +VariableName - name of the variable +Context - LOCALS, GLOBALS or area specific +Value - value to set + +Return value: N/A + +See also: SetVar, SetVarAssoc, SetToken, data_exchange + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetInfoTextColor.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetInfoTextColor.txt new file mode 100644 index 000000000..60c8385e9 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetInfoTextColor.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.SetInfoTextColor(red, green, blue, [alpha]) + +Description: Sets the color of floating messages in GameControl. Floating messages are in-game messages issued by actors, or information text coming from game objects. + +Parameters: red,green,blue,alpha - color code, alpha defaults to 255 (completely opaque) + +Return value: N/A + +See also: SetLabelTextColor, SetButtonTextColor + + +MD5: e48af04dbba2632c62459f3aba05d0a9 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetItemIcon.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetItemIcon.txt new file mode 100644 index 000000000..1108df099 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetItemIcon.txt @@ -0,0 +1,26 @@ + +Prototype: GemRB.SetItemIcon(WindowIndex, ControlIndex, ITMResRef[, Type, Tooltip, ITM2ResRef]) + +Metaclass Prototype: SetItemIcon(ITMResRef[, Type, Tooltip, ITM2ResRef]) + +Description: Sets Item icon image on a Button control. + +Parameters: +WindowIndex, ControlIndex - the control's reference +ITMResRef - the name of the item (.itm resref) +Type - 0-5 (the icon's type) + 0 - Inventory Icon1 + 1 - Inventory Icon2 + 2 - Description Icon (for BG) + 3 - No Icon (empty slot) + 4 - Activation Icon1 + 5 - Activation Icon2 + 6 - Item ability icon for first extended header + 7 - Item ability icon for second extended header + 8 - etc. + +Tooltip - if set to 1, the tooltip for the item will also be set +ITM2ResRef - if set, a second item to display in the icon. ITM2 is drawn first. The tooltip of ITM is used. Only valid for Type 4 and 5 +Return value: N/A + +See also: SetSpellIcon, SetActionIcon diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetJournalEntry.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetJournalEntry.txt new file mode 100644 index 000000000..d735d00fc --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetJournalEntry.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.SetJournalEntry(strref[, section, chapter]) + +Description: Sets a journal journal entry w/ given chapter and section, if section was not given, then it will delete the entry. Chapter is optional, if it is omitted, then the current chapter will be used. If strref is -1, then it will delete the whole journal. + +Parameters: strref - strref of the journal entry + section - the section of the journal (only if the journal has sections) + chapter - the chapter of the journal entry + +Return value: NONE + +See also: GetJournalEntry + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetLabelTextColor.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetLabelTextColor.txt new file mode 100644 index 000000000..2b074de76 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetLabelTextColor.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.SetLabelTextColor(WindowIndex, ControlIndex, red, green, blue) + +Metaclass Prototype: SetTextColor(red, green, blue) + +Description: Sets the Text Color of a Label Control. If the the Font has no own palette, you can set a default palette by this command. + +Parameters: WindowIndex, ControlIndex - the control's reference + red,green,blue - the control's desired text color + +Return value: N/A + +See also: SetLabelUseRGB + + +MD5: aa639bfaf8d66d2eefba1f96c9a5b6a2 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetLabelUseRGB.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetLabelUseRGB.txt new file mode 100644 index 000000000..ac28e92e4 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetLabelUseRGB.txt @@ -0,0 +1,17 @@ + +Prototype: GemRB.SetLabelUseRGB(WindowIndex, ControlIndex, status) + +Metaclass Prototype: SetUseRGB(status) + +Description: Sets a Label control to use the colors coming from the Font. If the font has its own color, you must set this. If a label was set to not use the Font's colors you can alter its color by SetLabelTextColor(). + +Parameters: +WindowIndex, ControlIndex - the control's reference +status - boolean + +Return value: N/A + +See also: SetLabelTextColor + + +MD5: 1e4a2ea507466dd58981d8a898254e61 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetMapnote.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetMapnote.txt new file mode 100644 index 000000000..31e81b162 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetMapnote.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.SetMapnote(X, Y, color, text) + +Description: Adds or removes a mapnote to the current map (area). + +Parameters: +X,Y: the position of the mapnote +color: the color index (0-7) of the note (in case of PST it is only 0 or 1) +text: string, the text of the note. If it's empty, the mapnote is removed. + +Return value: N/A + +See also: CreateMapControl + + +MD5: eb32f54196b822f64fc53b72c071d64d diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetMasterScript.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetMasterScript.txt new file mode 100644 index 000000000..ba7de9dea --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetMasterScript.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.SetMasterScript(ScriptResRef, WMPResRef) + +Description: Sets the worldmap and master script names. This function is required if you want to alter the worldmap or the master script (simulating the ToB or HoW expansions). + +Parameters: +ScriptResRef - the name of the master script (.bcs resref). +WMPResRef - the name of the worldmap (.wmp resref). + +Return value: N/A + +See also: LoadGame + + +MD5: 35143c4d12005fd3162c08cf6851ccfb diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetMemorizableSpellsCount.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetMemorizableSpellsCount.txt new file mode 100644 index 000000000..174c72a76 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetMemorizableSpellsCount.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.SetMemorizableSpellsCount(PartyID, Value, SpellType, Level) + +Description: Sets number of memorizable spells of given type and level in a player character's spellbook. + +Parameters: +PartyID - the PC's position in the party +Value - number of memorizable spells +SpellType - 0 - priest, 1 - wizard, 2 - innate +Level - the memorized spell's level + +Return value: N/A + +See also: GetMemorizableSpellsCount + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetModalState.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetModalState.txt new file mode 100644 index 000000000..ff42de72b --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetModalState.txt @@ -0,0 +1,18 @@ + +Prototype: GemRB.SetModalState(Slot, Value[, spell]) + +Description: Sets a player character's modal state. The modal states are listed in ie_modal.py. + +Parameters: Slot - actor index in game structure + Value - New modal state + Spell - the spell resource associated with the state + +If spell is not given, a default value from modal.2da will be used. + +Return value: N/A + +Examples: + GemRB.SetModalState (pc, MS_TURNUNDEAD) +The above example makes the player start the turn undead action. + +See also: SetPlayerStat, SetPlayerName diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetMouseScrollSpeed.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetMouseScrollSpeed.txt new file mode 100644 index 000000000..b342d2bcd --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetMouseScrollSpeed.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.SetMouseScrollSpeed(speed) + +Description: Adjusts the mouse scroll speed. + +Parameters: +speed - + +Return value: N/A + +See also: SetTooltipDelay diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetNextScript.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetNextScript.txt new file mode 100644 index 000000000..c8c2fac5e --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetNextScript.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.SetNextScript(scriptname) + +Description: Instructs the GUIScript engine to load the script when this script has terminated. (Usually it is the last command before return). + +Parameters: scriptname - It is the name of the python script to be executed. The name of the script may not exceed 60 characters. + +Return value: N/A + +Example: GemRB.SetNextScript("CharGen") + return + +See also: QuitGame + + +MD5: 5c3c21b6a1f1bc4f00041cc075e35b45 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetPlayerName.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetPlayerName.txt new file mode 100644 index 000000000..bead6db1c --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetPlayerName.txt @@ -0,0 +1,17 @@ + +Prototype: GemRB.SetPlayerName(Slot, Name[, LongOrShort]) + +Description: Sets the player name. Each actor has 2 names, this command can set either or both. + +Parameters: Slot - numeric, the character's slot + Name - string, the name + LongOrShort- 0 (both), 1 - (short), 2 - (long) + +Return value: N/A + +Example: + GemRB.SetPlayerName(MyChar, GemRB.GetToken("CHARNAME"), 0) +In the above example we set the player's name to a previously set Token (Global String). + +See also: QueryText, GetToken + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetPlayerScript.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetPlayerScript.txt new file mode 100644 index 000000000..a166f17a6 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetPlayerScript.txt @@ -0,0 +1,12 @@ + +Prototype: GemRB.SetPlayerScript(Slot, Index, ScriptName) + +Description: Sets the player character's script. Normally only one of the scripts are customisable via the GUI. + +Parameters: Slot - numeric, the character's slot + Index - the script index (see scrlevel.2da) + ScriptName - the script resource + +Return value: N/A + +See also: GetPlayerScript diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetPlayerSound.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetPlayerSound.txt new file mode 100644 index 000000000..53c54ce80 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetPlayerSound.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.SetPlayerSound(Slot, SoundFolder) + +Description: Sets the player character's soundset. + +Parameters: Slot - numeric, the character's slot + SoundFolder - string, a folder in Sounds (iwd2 style), or a filename (bg2 style) + +Return value: N/A + +See also: FillPlayerInfo, SetPlayerString diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetPlayerStat.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetPlayerStat.txt new file mode 100644 index 000000000..d6eb59e8c --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetPlayerStat.txt @@ -0,0 +1,19 @@ + +Prototype: GemRB.SetPlayerStat(Slot, ID, Value[, PCF]) + +Description: Sets a player character's base stat. The stats are listed in ie_stats.py. + +Parameters: Slot - actor index in game structure + ID - Stat index + Value - New stat value + PCF - Set to 0 if you don't want the stat's post-change function to be ran + +Return value: N/A + +Example: + PickedColor=GemRB.GetTableValue(ColorTable, ColorIndex, GemRB.GetVar("Selected")) + GemRB.SetPlayerStat (pc, IE_MAJOR_COLOR, PickedColor) +The above example sets the player's color just picked via the color customisation dialog. ColorTable holds the available colors. + +See also: GetPlayerStat, SetPlayerName, ApplyEffect + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetPlayerString.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetPlayerString.txt new file mode 100644 index 000000000..9562262dc --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetPlayerString.txt @@ -0,0 +1,12 @@ +Missing function already used in bg2 biography (cg uses a token) + +Prototype: + +Description: + +Parameters: + +Return value: + +See also: + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetPurchasedAmount.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetPurchasedAmount.txt new file mode 100644 index 000000000..546765bf0 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetPurchasedAmount.txt @@ -0,0 +1,12 @@ + +Prototype: SetPurchasedAmount( Index, Amount ) + +Description: Sets the amount of purchased items of a type. If it was 0, then the item will be deselected from the purchase list. This function works only with an active store. + +Parameters: Index - the store item's index + Amount - a numeric value not less than 0 + +Return value: None + +See also: EnterStore, LeaveStore, SetPurchasedAmount + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetRepeatClickFlags.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetRepeatClickFlags.txt new file mode 100644 index 000000000..852343d7b --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetRepeatClickFlags.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.SetRepeatClickFlags(value, op) + +Description: Sets the mode repeat clicks are handled. + +Parameters: +value - speed, see the GEM_RK* flags in GUIDefines.py +op - operation + +Return value: N/A + +See also: + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetSaveGamePortrait.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetSaveGamePortrait.txt new file mode 100644 index 000000000..8283acbe2 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetSaveGamePortrait.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.SetSaveGamePortrait(WindowIndex, ControlIndex, SaveSlotCount, PCSlotCount) + +Metaclass Prototype: SetSaveGamePortrait(SaveSlotCount, PCSlotCount) + +Description: Sets a savegame PC portrait bmp onto a button as picture. + +Parameters: WindowIndex, ControlIndex - the control's reference +SlotCount - the index of a saved game +PCSlotCount - the index of the portrait in the saved game + +Return value: N/A + +See also: SetSaveGamePreview + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetSaveGamePreview.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetSaveGamePreview.txt new file mode 100644 index 000000000..47c9e405a --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetSaveGamePreview.txt @@ -0,0 +1,14 @@ + +Prototype: GemRB.SetSaveGamePreview(WindowIndex, ControlIndex, SlotCount) + +Metaclass Prototype: SetSaveGamePreview(SlotCount) + +Description: Sets a savegame area preview bmp onto a button as picture. + +Parameters: WindowIndex, ControlIndex - the control's reference + SlotCount - the index of a saved game + +Return value: N/A + +See also: SetSaveGamePortrait + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetScrollBarSprites.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetScrollBarSprites.txt new file mode 100644 index 000000000..4b93c34b8 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetScrollBarSprites.txt @@ -0,0 +1,23 @@ + +Prototype: GemRB.SetScrollBarSprites(WindowIndex, ControlIndex, ResRef, Cycle, UpUnpressedFrame, UpPressedFrame, DownUnpressedFrame, DownPressedFrame, TroughFrame, SliderFrame) + +Metaclass Prototype: SetSprites(ResRef, Cycle, UpUnpressedFrame, UpPressedFrame, DownUnpressedFrame, DownPressedFrame, TroughFrame, SliderFrame) + +Description: Sets a ScrollBar Sprites Images. + +Parameters: +WindowIndex - the window control id +ControlID - the id of the target control +ResRef - bam resref +Cycle - cycle number +UpUnpressedFrame - frame number +UpPressedFrame - frame number +DownUnpressedFrame - frame number +DownPressedFrame - frame number +TroughFrame - frame number +SliderFrame - frame number + +Return value: + +See also: + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetSpellIcon.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetSpellIcon.txt new file mode 100644 index 000000000..aef782a1d --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetSpellIcon.txt @@ -0,0 +1,20 @@ + +Prototype: GemRB.SetSpellIcon(WindowIndex, ControlIndex, SPLResRef[, Type, Tooltip, Function]) + +Metaclass Prototype: SetSpellIcon(SPLResRef[, Type, Tooltip, Function]) + +Description: Sets Spell icon image on a Button control. Type determines the icon type, if set to 1 it will use the Memorised Icon instead of the Spellbook Icon + +Parameters: +WindowIndex, ControlIndex - the control's reference +SPLResRef - the name of the spell (.spl resref) +Type - 0 (default, use parchment background) or 1 (use stone background) +Tooltip - 0 (default); if 1, set the tooltip "F " +Function - number to be used in the tooltip above + +Return value: N/A + +See also: SetItemIcon + + +MD5: b7895d38a8e3f389bb1f702ce99bcf57 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetTAHistory.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetTAHistory.txt new file mode 100644 index 000000000..216f525f0 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetTAHistory.txt @@ -0,0 +1,13 @@ + +Prototype: SetTAHistory(Win, Ctrl, KeepLines) + +Metaclass Prototype: SetHistory(KeepLines) + +Description: Sets up a textarea control for holding large amounts of text. If more than 'KeepLines' text scrolls up above, it will be discarded. This works best if TEXTAREA_AUTOSCROLL was set. The text is cut when new text is appended to the buffer, without TEXTAREA_AUTOSCROLL there is no automatic scrolling out of text. This function sets the TEXTAREA_HISTORY flag. + +Parameters: Win, Ctrl - a window index/control index pair of the textarea + KeepLines - the number of lines to be kept + +Return value: N/A + +See also: RewindTA, SetTextAreaFlags diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetText.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetText.txt new file mode 100644 index 000000000..ca43b5636 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetText.txt @@ -0,0 +1,18 @@ + +Prototype: GemRB.SetText(WindowIndex, ControlIndex, String|Strref) + +Metaclass Prototype: SetText(String|Strref) + +Description: Sets the Text of a control in a Window. In case of strrefs, any tokens contained by the string will be resolved. (For example the substring "" will be replaced by the "CHARNAME" token.) -1 is a special Strref, it will be resolved to the name/version of the running engine. + +Parameters: +WindowIndex, ControlIndex - the control's reference +String - an arbitrary string +Strref - a string index from the dialog.tlk table. + +Return value: +0 on success, -1 otherwise + +See also: QueryText, DisplayString, GetControl, accessing_gui_controls + +MD5: 583a8146b015a25b137c43a036043991 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetTextAreaFlags.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetTextAreaFlags.txt new file mode 100644 index 000000000..19e57107a --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetTextAreaFlags.txt @@ -0,0 +1,34 @@ + +Prototype: GemRB.SetTextAreaFlags(WindowIndex, ControlIndex, Flags, Operation) + +Metaclass Prototype: SetFlags(Flags, Operation) + +Description: Sets the Flags of a TextArea. + +Parameters: WindowIndex, ControlIndex - the control's reference +Flags - various bits altering the behaviour of the control +To make sure the flags are not misplaced, the high byte must be 5 (the textarea control's type). + +IE_GUI_TEXTAREA_SELECTABLE - 0x05000001 +The TextArea will be able to return a selected row. +IE_GUI_TEXTAREA_AUTOSCROLL - 0x05000002 +Some TextAreas are autoscrolling while text was written into them, thus always showing the last content. +IE_GUI_TEXTAREA_SMOOTHSCROLL - 0x05000004 +The TextArea will slowly scroll its content. If it is out of text, it will call the TEXTAREA_OUT_OF_TEXT callback. +IE_GUI_TEXTAREA_HISTORY - 0x05000008 +The TextArea will drop some of the scrolled out text. + +Operation - could be OP_SET, OP_OR or OP_NAND, default is OP_SET. + +Return value: N/A + +Example: + TextAreaControl = GemRB.GetControl(SoundWindow, 45) + GemRB.SetTextAreaFlags(SoundWindow, TextAreaControl,IE_GUI_TEXTAREA_SELECTABLE) + GemRB.SetVarAssoc(SoundWindow, TextAreaControl, "Sound", 0) + RowCount=GemRB.GetCharSounds(SoundWindow, TextAreaControl) +The above code will set up the TextArea as a ListBox control, by reading the names of available character soundsets into the TextArea and setting it up as selectable. When the user clicks on row, the "Sound" variable will be assigned a row number. + +See also: RewindTA, SetTAHistory, GetCharSounds, GetCharacters, QueryText, accessing_gui_controls + +MD5: 30fd7c88972e5fc7e4f41158a28ceaff diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetTimedEvent.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetTimedEvent.txt new file mode 100644 index 000000000..79a692f88 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetTimedEvent.txt @@ -0,0 +1,12 @@ + +Prototype: GemRB.SetTimedEvent(FunctionName, rounds) + +Description: Sets a timed event to be called by the Game object. If there is no game loaded, this command is ignored. If the game is unloaded, the event won't be called. + +Parameters: +FunctionName - a python function object +rounds - the time when the function should be called + +Return value: N/A + +See also: SetEvent diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetToken.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetToken.txt new file mode 100644 index 000000000..72bcb2905 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetToken.txt @@ -0,0 +1,27 @@ + +Prototype: GemRB.SetToken(VariableName, Value) + +Description: Set/Create a token to be replaced in StrRefs. QueryText() will use the actual value of the token when it encounters "" substrings in a retrieved dialog.tlk entry. Some tokens are hardcoded and you can't affect QueryText() by setting them. Usage of those tokens should be avoided. The hardcoded token list: +FIGHTERTYPE - always resolves to strref #10174 +RACE - always resolves to the race of the last speaker +GABBER - always resolves to the longname of the last speaker +SIRMAAM - strref #27473/#27475 depending on last speaker's gender +GIRLBOY - strref #27477/#27476 depending on last speaker's gender +BROTHERSISTER- strref #27478/#27479 ... +LADYLORD - strref #27481/#27480 ... +MALEFEMALE - strref #27483/#27482 ... +HESHE - strref #27485/#27484 ... +HISHER - strref #27487/#27486 ... +HIMHER - strref #27487/#27488 ... +MANWOMAN - strref #27490/#27489 ... +PRO_* - same as above with protagonist + +Parameters: + VariableName - the name of the variable must be shorter than 32 bytes + Value - string, the value of the token + +Return value: N/A + +See also: GetToken, QueryText + +MD5: fd99519e2b63105ddb7d772476886701 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetTooltip.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetTooltip.txt new file mode 100644 index 000000000..dff924ea1 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetTooltip.txt @@ -0,0 +1,26 @@ + +Prototype: GemRB.SetTooltip(WindowIndex, ControlIndex, String|Strref) + +Metaclass Prototype: SetTooltip(String|Strref) + +Description: Sets control's tooltip. Any control may have a tooltip. + +Parameters: WindowIndex, ControlIndex - the control's reference +String - an arbitrary string +Strref - a string index from the dialog.tlk table. + +Return value: +0 on success, -1 on error + +The tooltip's visual properties must be set in the gemrb.ini file: + TooltipFont - Font used to display tooltips + TooltipBack - Sprite displayed behind the tooltip text, if any + TooltipColor - Tooltip text color (RGBA) + TooltipMargin - Space between tooltip text and sides of TooltipBack (x2) + + + +See also: SetText + + +MD5: 055166c150ec66ca9649006b42114967 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetTooltipDelay.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetTooltipDelay.txt new file mode 100644 index 000000000..a3812041e --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetTooltipDelay.txt @@ -0,0 +1,9 @@ + +Prototype: GemRB.SetTooltipDelay(time) + +Description: Sets the tooltip delay. + +Parameters: +time - 0-10 + +See also: SetTooltip, SetMouseScrollSpeed diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetVar.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetVar.txt new file mode 100644 index 000000000..003db0bdf --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetVar.txt @@ -0,0 +1,28 @@ + +Prototype: GemRB.SetVar(VariableName, Value) + +Description: Set a Variable of the Global Dictionary. This is an independent dictionary from the gamescript. It contains configuration variables, and provides a flexible interface between guiscript and the engine core. There are some preserved names that are referenced from the core, these are described in different places. +variable described in +PlayMode - LoadGame +*Window - HideGUI +*Position - HideGUI +Progress - data_exchange + +Parameters: VariableName - the name of the variable must be shorter than 32 bytes + Value - numeric, the new value + +Return value: N/A + +Examples: + GemRB.SetVar("ActionsWindow", ActionsWindow) + GemRB.SetVar("OptionsWindow", OptionsWindow) + GemRB.SetVar("MessageWindow", MessageWindow) + GemRB.SetVar("ActionsPosition", 4) #BottomAdded + GemRB.SetVar("OptionsPosition", 0) #Left + GemRB.SetVar("MessagePosition", 4) #BottomAdded +The above lines set up some windows of the main game screen. + +See also: SetVarAssoc, SetToken, LoadGame, HideGUI, data_exchange + + +MD5: f85bcb143ff3359936e78780da210367 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetVarAssoc.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetVarAssoc.txt new file mode 100644 index 000000000..e59aa6489 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetVarAssoc.txt @@ -0,0 +1,20 @@ + +Prototype: GemRB.SetVarAssoc(WindowIndex, ControlIndex, VariableName, LongValue) + +Metaclass Prototype: SetVarAssoc(VariableName, LongValue) + +Description: It associates a variable name and value with a control. The control uses this associated value differently, depending on the control. See more about this in "data_exchange". + +Parameters: +WindowIndex, ControlIndex - the control's reference +Variablename - string, a Global Dictionary Name associated with the control +LongValue - numeric, a value associated with the control + +Return value: N/A + +Special: If the 'DialogChoose' variable was set to -1 or 0 during a dialog session, it will terminate (-1) or pick the first available option (0) from the dialog automatically. (0 is used for 'continue', -1 is used for 'end dialogue'). + +See also: SetButtonFlags, SetVar, GetVar, data_exchange, accessing_gui_controls + + +MD5: df5c51a71e7368c22b2d3e5a0bac311a diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetVisible.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetVisible.txt new file mode 100644 index 000000000..995521d5b --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetVisible.txt @@ -0,0 +1,21 @@ + +Prototype: GemRB.SetVisible(WindowIndex, Visible) + +Metaclass Prototype: SetVisible(Visible) + +Description: Sets the Visibility Flag of a Window. +Window index 0 can be used to manipulate the game control window + +Parameters: WindowIndex - the index returned by LoadWindow() + Visible: +WINDOW_INVISIBLE - Window is invisible +WINDOW_VISIBLE - Window is visible +WINDOW_GRAYED - Window is shaded +WINDOW_FRONT - Window is drawn in the foreground + +Return value: N/A + +See also: ShowModal, SetWindowFrame + + +MD5: cc9b69351e5e62f28a5c65247cae7880 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetWindowFrame.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetWindowFrame.txt new file mode 100644 index 000000000..00632b62b --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetWindowFrame.txt @@ -0,0 +1,24 @@ +Prototype: GemRB.SetWindowFrame(WindowIndex) + +Metaclass Prototype: SetFrame() + +Description: Sets Window to have a frame used to fill screen on higher + resolutions. At present all windows having frames have the same one. + + To automatically move the windows from the edges and to let GemRB know + how much space is there, the LoadWindowPack() function should be called + with size parameters. + + Make sure to set the frame only for the window on the bottom, because the + frames will erase the whole screen before drawing. + +Parameters: + WindowIndex - the index returned by LoadWindow() + +Return value: N/A + +See also: LoadWindowFrame, LoadWindowPack, LoadWindow, SetWindowPos + +MD5: 1b3199cc5121101643080fbac127f93d + + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetWindowPicture.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetWindowPicture.txt new file mode 100644 index 000000000..c4f890e41 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetWindowPicture.txt @@ -0,0 +1,23 @@ + +Prototype: GemRB.SetWindowPicture(WindowIndex, MosResRef) + +Metaclass Prototype: SetPicture(MosResRef) + +Description: Changes the background of a Window. + +Parameters: +WindowIndex - the index returned by LoadWindow() +MosResRef - the name of the background image (.mos resref) + +Return value: N/A + +Example: + LoadPic = GemRB.GetGameString (STR_LOADMOS) + if LoadPic=="": + LoadPic = "GUILS0"+str(GemRB.Roll(1,9,0)) + GemRB.SetWindowPicture(LoadScreen, LoadPic) +The above snippet is responsible to generate a random loading screen. + +See also: SetButtonPicture + +MD5: 62884cae84603d33be1551873d6b93cc diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetWindowPos.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetWindowPos.txt new file mode 100644 index 000000000..2b68fc65b --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetWindowPos.txt @@ -0,0 +1,36 @@ + +Prototype: GemRB.SetWindowPos(WindowIndex, X, Y, [Flags=WINDOW_TOPLEFT]) + +Metaclass Prototype: SetPos(X, Y, [Flags=WINDOW_TOPLEFT]) + +Description: Moves a Window. + +Parameters: +WindowIndex - the index returned by LoadWindow() +X,Y - placement of the window, see Flags below for meaning + for each flag +Flags - bitmask of WINDOW_(TOPLEFT|CENTER|ABSCENTER|BOUNDED), + used to modify the meaning of X and Y. + TOPLEFT : X, Y are coordinates of upper-left corner. + CENTER : X, Y are coordinates of window's center. + ABSCENTER: window is placed at screen center, moved by X, Y. + RELATIVE : window is moved by X, Y. + SCALE : window is moved by diff of screen size and X, Y, divided by 2. + BOUNDED : the window is kept within screen boundaries. + + +Return value: N/A + +Note: + All flags except WINDOW_BOUNDED are mutually exclusive + +Example: + x, y = GemRB.GetVar ("MenuX"), GemRB.GetVar ("MenuY") + GemRB.SetWindowPos (Window, x, y, WINDOW_CENTER | WINDOW_BOUNDED) + +The above example is from the PST FloatMenuWindow script. It centers +pie-menu window around the mouse cursor, but keeps it within screen. + +See also: SetWindowSize, SetControlPos + +MD5: e560702a81119365804f7944792d9b01 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetWindowSize.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetWindowSize.txt new file mode 100644 index 000000000..025f8f323 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetWindowSize.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.SetWindowSize(WindowIndex, Width, Height) + +Metaclass Prototype: SetSize(Width, Height) + +Description: Resizes a Window. + +Parameters: +WindowIndex - the index returned by LoadWindow() +Width, Height - the new dimensions of the window + +Return value: N/A + +See also: LoadWindow, SetWindowPos, SetControlSize + +MD5: 2188d78694c9c447bf881fb37a9bfa4e diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetWorldMapTextColor.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetWorldMapTextColor.txt new file mode 100644 index 000000000..09e60a6fa --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetWorldMapTextColor.txt @@ -0,0 +1,19 @@ + +Prototype: GemRB.SetWorldMapTextColor(WindowIndex, ControlIndex, which, red, green, blue) + +Metaclass Prototype: SetTextColor(which, red, green, blue) + +Description: Sets the label colors of a WorldMap Control. "which" selects the color affected and is one of IE_GUI_WMAP_COLOR_(BACKGROUND|NORMAL|SELECTED|NOTVISITED). + +Parameters: +WindowIndex - the window control id +ControlID - the id of the target control +which - selects the color affected (one of IE_GUI_WMAP_COLOR_(BACKGROUND|NORMAL|SELECTED|NOTVISITED) +red - red value +green - green value +blue - blue value + +Return value: N/A + +See also: + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetupControls.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetupControls.txt new file mode 100644 index 000000000..61bfd09c8 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetupControls.txt @@ -0,0 +1,14 @@ + +Prototype: GemRB.SetupControls(WindowIndex, Slot) + +Metaclass Prototype: SetupControls(Slot) + +Description: Sets up all 12 action buttons for a player character, based on preset preferences and the character's class. + +Parameters: +WindowIndex - the buttons' window index +Slot - the player character's index in the party + +Return value: N/A + +See also: SetActionIcon, SetDefaultActions, SetupEquipmentIcons, SetupSpellIcons diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetupEquipmentIcons.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetupEquipmentIcons.txt new file mode 100644 index 000000000..81c58a9bd --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetupEquipmentIcons.txt @@ -0,0 +1,17 @@ + +Prototype: GemRB.SetupEquipmentIcons(WindowIndex, Slot[, Start]) + +Metaclass Prototype: SetupEquipmentIcons(Slot[, Start]) + +Description: Sets up all 12 action buttons for a player character with the usable equipment functions. +It also sets up the scroll buttons left and right if needed. +If Start is supplied, it will skip the first few items. + +Parameters: +WindowIndex - the buttons' window index +Slot - the player character's index in the party +Start - start the equipment list from this value + +Return value: N/A + +See also: SetupSpellIcons, SetupControls, UseItem diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetupQuickSlot.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetupQuickSlot.txt new file mode 100644 index 000000000..a22087a80 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetupQuickSlot.txt @@ -0,0 +1,22 @@ +Prototype: GemRB.SetupQuickSlot(PartyID, QuickSlotID, InventorySlot[, AbilityIndex]) + +Description: Sets up a quickslot to point to a particular inventory slot. +Also sets the used ability for that given quickslot. +If the abilityindex is omitted, it will be assumed as 0. +If the InventorySlot is -1, then it won't be assigned to the quickslot +(this way you can alter the used Ability index only). +If the QuickSlotID is 0, then it will try to find the quickslot/weaponslot +by the InventorySlot, and assign the AbilityIndex to it. +(Use this if you don't know the exact quick slot, or don't care to find it). + +Parameters: +PartyID - the PC's position in the party (1 based) +QuickSlotID - the quickslot to set up +InventorySlot - the inventory slot assigned to this quickslot, this is usually constant +and taken care by the core +AbilityIndex - the number of the item extended header to use with this quickslot + +Return value: N/A + +See also: GetEquippedQuickSlot, SetEquippedQuickSlot + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetupSpellIcons.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetupSpellIcons.txt new file mode 100644 index 000000000..343a4dd7f --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SetupSpellIcons.txt @@ -0,0 +1,18 @@ + +Prototype: GemRB.SetupSpellIcons(WindowIndex, Slot, Type[, Start]) + +Metaclass Prototype: SetupSpellIcons(Slot, Type[, Start]) + +Description: Sets up all 12 action buttons for a player character with spell or innate icons. +It also sets up the scroll buttons left and right if needed. +If Start is supplied, it will skip the first few items. + +Parameters: +WindowIndex - the buttons' window index +Slot - the player character's index in the party +Type - the spell type bitfield (1-mage, 2-priest, 4-innate) +Start - start the spell list from this value + +Return value: N/A + +See also: SetupEquipmentIcons, SetupControls, SpellCast diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ShowModal.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ShowModal.txt new file mode 100644 index 000000000..e4d873a83 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/ShowModal.txt @@ -0,0 +1,18 @@ + +Prototype: GemRB.ShowModal(WindowIndex, [Shadow=MODAL_SHADOW_NONE]) + +Metaclass Prototype: ShowModal([Shadow=MODAL_SHADOW_NONE]) + +Description: Show a Window on Screen setting the Modal Status. If Shadow is MODAL_SHADOW_GRAY, other windows are grayed. If Shadow is MODAL_SHADOW_BLACK, they are blacked out. + +Parameters: WindowIndex - the index returned by LoadWindow() +Shadow - 0,1 or 2 +MODAL_SHADOW_NONE = 0 +MODAL_SHADOW_GRAY = 1 +MODAL_SHADOW_BLACK = 2 + +Return value: N/A + +See also: SetVisible + +MD5: fdde4cda097b7ab5cd23aae7fb1313ec diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SoftEndPL.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SoftEndPL.txt new file mode 100644 index 000000000..3fed5308d --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SoftEndPL.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.SoftEndPL() + +Description: Ends the currently playing Music Playlist softly. + +Parameters: N/A + +Return value: N/A + +See also: HardEndPL + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SpellCast.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SpellCast.txt new file mode 100644 index 000000000..cdf39a6a1 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SpellCast.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.SpellCast(PartyID, Type, Spell) + +Description: Makes PartyID to cast a spell of Type. This handles targeting and executes the appropriate scripting command. + +Parameters: +PartyID - the player character's index in the party +Type - the spell type bitfield (1-mage, 2-priest, 4-innate) +Spell - the spell's index in the list + +Return value: N/A + +See also: SetupSpellIcons diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/StatComment.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/StatComment.txt new file mode 100644 index 000000000..b081a8e67 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/StatComment.txt @@ -0,0 +1,20 @@ + +Prototype: GemRB.StatComment(Strref, X, Y) + +Description: Replaces %d's with the values of X and Y in a string referenced by strref. PST uses %d values in place of tokens, thus it requires a special command. (Note that you can safely replace this command with a few Python scripting commands). In other engines use GetString after setting the needed tokens by SetToken (if you need to set them at all). + +Parameters: Sttref - a string index from the dialog.tlk table. + X,Y - two numerical values to be replaced in place of %d's. + +Return value: A string with resolved %d's. + +Example: +def IntPress(): + GemRB.SetText(NewLifeWindow, TextArea, 18488) + GemRB.TextAreaAppend(NewLifeWindow, TextArea, "\n\n"+GemRB.StatComment(GemRB.GetTableValue(StatTable,Int,1),0,0) ) + return + +The above example comes directly from our PST script, it will display the description of the intelligence stat (strref==18488), adding a comment based on the current Int variable. StatTable (a table index) contains the comment strref values associated with an intelligence value. + +See also: GetString, SetToken, GetTableValue, SetText, LoadTable, TextAreaAppend + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/StealFailed.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/StealFailed.txt new file mode 100644 index 000000000..9a9f46037 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/StealFailed.txt @@ -0,0 +1,12 @@ + +Prototype: StealFailed() + +Description: Triggers the steal failed event for the currently selected actor. +The event will be triggered in the actor 'owning' the store currently open. + +Parameters: None + +Return value: N/A + +See also: GetStore, EnterStore, LeaveStore, GameGetSelectedPCSingle + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SwapPCs.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SwapPCs.txt new file mode 100644 index 000000000..fe5e2123a --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/SwapPCs.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.SwapPCs(idx1, idx2) + +Description: Swaps the party order for two player characters. + +Parameters: +idx1 - position in the party +idx2 - position in the party + +Return value: N/A + +See also: + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/TextAreaAppend.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/TextAreaAppend.txt new file mode 100644 index 000000000..56639b79c --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/TextAreaAppend.txt @@ -0,0 +1,23 @@ + +Prototype: GemRB.TextAreaAppend(WindowIndex, ControlIndex, String|Strref [, Row[, Flag]]) + +Metaclass Prototype: TextAreaAppend(String|Strref [, Row[, Flag]]) + +Description: Appends the Text to the TextArea Control in the Window. If row is specificed, it can also append text to existing rows. + +Parameters: +WindowIndex, ControlIndex - the control's reference +String - literal text, it could have embedded colour codes +Strref - a string index from the dialog.tlk table. +Row - the row of text to add the text to, if omitted, the text will be added (in a new row) after the last row. +Flag - the flags for QueryText (if strref resolution is used) + 1 - strrefs displayed (even if not enabled by default) + 2 - sound (plays the associated sound) + 4 - speech (works only with if sound was set) + 256 - strrefs not displayed (even if allowed by default) + +Return value: + Index of the row appended or changed + +See also: TextAreaClear, SetText, QueryText + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/TextAreaClear.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/TextAreaClear.txt new file mode 100644 index 000000000..f924199f0 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/TextAreaClear.txt @@ -0,0 +1,14 @@ + +Prototype: GemRB.TextAreaClear(WindowIndex, ControlIndex) + +Metaclass Prototype: Clear() + +Description: Clears the Text from the TextArea Control in the Window. + +Parameters: WindowIndex, ControlIndex - the control's reference + +Return value: N/A + +See also: TextAreaAppend + +MD5: 4c563da47e77f8962c62c67a6de8c906 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/TextAreaScroll.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/TextAreaScroll.txt new file mode 100644 index 000000000..0e9d3063d --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/TextAreaScroll.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.TextAreaScroll(WindowIndex, ControlIndex, offset) + +Metaclass Prototype: Scroll(offset) + +Description: Scrolls the textarea up or down by offset. + +Parameters: +WindowIndex - the window control id +ControlID - the id of the target control +offset - amount to scroll + +Return value: N/A + +See also: + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/UnhideGUI.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/UnhideGUI.txt new file mode 100644 index 000000000..c184ab838 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/UnhideGUI.txt @@ -0,0 +1,13 @@ + +Prototype: GemRB.UnhideGUI() + +Description: Shows the Game GUI and redraws windows. + +Parameters: N/A + +Return value: N/A + +See also: HideGUI, InvalidateWindow, SetVisible + + +MD5: da75d42bc5444aff63580ee249c5b858 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/UnloadSymbol.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/UnloadSymbol.txt new file mode 100644 index 000000000..c1f88f2e2 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/UnloadSymbol.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.UnloadSymbol(SymbolIndex) + +Metaclass Prototype: Unload() + +Description: Unloads an IDS symbol list. + +Parameters: SymbolIndex - returned by a previous LoadSymbol command. + +Return value: N/A + +See also: LoadSymbol, UnloadTable + + +MD5: 87793ebcb18bf5c2fb1fa011245e470d diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/UnloadTable.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/UnloadTable.txt new file mode 100644 index 000000000..74f86787f --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/UnloadTable.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.UnloadTable(TableIndex) + +Metaclass Prototype: Unload() + +Description: Unloads a 2DA Table. + +Parameters: TableIndex - returned by a previous LoadTable command. + +Return value: N/A + +See also: LoadTable + + +MD5: f281a449838425a6265967006640abbc diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/UnloadWindow.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/UnloadWindow.txt new file mode 100644 index 000000000..46b1fd1e2 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/UnloadWindow.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.UnloadWindow(WindowIndex) + +Metaclass Prototype: Unload() + +Description: Unloads a previously loaded Window. EnterGame() and QuitGame() automatically unload all loaded windows. + +Parameters: WindowIndex - the index returned by LoadWindow() + +Return value: N/A + +See also: LoadWindow, EnterGame, QuitGame + + +MD5: 0a64fd889b01eecf2351c4ebb77b3ca0 diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/UnmemorizeSpell.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/UnmemorizeSpell.txt new file mode 100644 index 000000000..8cb391c57 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/UnmemorizeSpell.txt @@ -0,0 +1,15 @@ + +Prototype: GemRB.UnmemorizeSpell(PartyID, SpellType, Level, Index) + +Description: Unmemorizes specified memorized spell. + +Parameters: +PartyID - the PC's position in the party +SpellType - 0 - priest, 1 - wizard, 2 - innate +Level - the memorized spell's level +Index - the memorized spell's index + +Return value: boolean, 1 on success + +See also: MemorizeSpell, GetMemorizedSpellsCount, GetMemorizedSpell + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/UpdateAmbientsVolume.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/UpdateAmbientsVolume.txt new file mode 100644 index 000000000..b52e27cc6 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/UpdateAmbientsVolume.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.UpdateAmbientsVolume() + +Description: Updates ambients volume on-the-fly. + +Parameters: N/A + +Return value: N/A + +See also: UpdateMusicVolume + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/UpdateMusicVolume.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/UpdateMusicVolume.txt new file mode 100644 index 000000000..e6ab838ca --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/UpdateMusicVolume.txt @@ -0,0 +1,11 @@ + +Prototype: GemRB.UpdateMusicVolume() + +Description: Updates music volume on-the-fly. + +Parameters: N/A + +Return value: N/A + +See also: UpdateAmbientsVolume + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/UseItem.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/UseItem.txt new file mode 100644 index 000000000..747609f64 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/UseItem.txt @@ -0,0 +1,16 @@ + +Prototype: GemRB.UseItem(PartyID, Slot, ItemIndex) + +Description: Makes PartyID to use an item. +If slot is negative, then item is the index of the item functionality in the use +item list. If slot is non-negative, then item is the quick item or weapon in slot. +This handles targeting and executes the appropriate scripting command. + +Parameters: +PartyID - the player character's index in the party +Slot - the item's inventory slot, if it is -1 then ItemIndex is used +ItemIndex - the item index from the SetupEquipmentIcons list, an item may have multiple entries, because of multiple features + +Return value: N/A + +See also: CanUseItemType, SpellCast, SetupEquipmentIcons diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/accessing_gui_controls.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/accessing_gui_controls.txt new file mode 100644 index 000000000..42638c4ca --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/accessing_gui_controls.txt @@ -0,0 +1,11 @@ +Accessing GUI controls. + +Description: To access a GUI control, you must know its window index and control index. You must use LoadWindow and GetControl to obtain these indices. +Usually a GUI command works only on one type of controls. A wrong control type will cause a Runtime Error and terminates the GUI script (not the game or the engine). + +Example: + StartWindow = GemRB.LoadWindow(7) + Label = GemRB.GetControl(StartWindow, 0x0fff0000) + GemRB.SetText(StartWindow, Label, GEMRB_VERSION) + +In the above example we just load a window whose window ID is 7, and store its window index in StartWindow. We also try to find a control whose control ID is 0xfff0000 and resides on the window pointed by StartWindow. diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/bit_operation.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/bit_operation.txt new file mode 100644 index 000000000..77e36f274 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/bit_operation.txt @@ -0,0 +1,7 @@ +The following bitwise operators exist in many guiscript commands. + + BM_SET 0 - sets exact value + BM_AND 1 - performs the AND operation (turns off unlisted bits) + BM_OR 2 - performs the OR operation (turns on listed bits) + BM_XOR 3 - performs the XOR operation (toggles the listed bits) + BM_NAND 4 - performs the NAND operation (turns off listed bits) diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/console.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/console.txt new file mode 100644 index 000000000..410991c4a --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/console.txt @@ -0,0 +1,9 @@ +The 'cheat console'. + +Description: You can pop the Console window anytime by pressing the ESC key. Any command you type in will be executed as a GUIScript command. You can use Python variables, issue Python commands as well as the GemRB scripting commands. If a command didn't execute, GemRB will retry its execution by adding "GemRB." to it, thus you can omit it in case you are extremely lazy. + +Examples (typed in the console): +GemRB.Quit() - quit the program +Quit() - same as above, but shorter +EnableCheatKeys(1) - enables the debug keys + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/controls.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/controls.txt new file mode 100644 index 000000000..8c1ee3082 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/controls.txt @@ -0,0 +1,52 @@ +Button: + +Buttons are the most versatile controls in the GUI engine. The following button types exist: checkbox, radiobutton and normal button. +Checkboxes of the same type are cummulative, and usually hold a bit value. +Radiobuttons of the same type are mutually exclusive. +Normal buttons are similar to radiobuttons, but they are not affecting each other. + +Progressbar: + +This control has no equivalent in the original Infinity Engine. It provides a graphical output of a numeric value, currently used only in LoadScreen. + + +Slider: + +A slider is used for limited numeric input. + + +TextEdit: + +This is a text input field. It has a configurable maximum input length. + + +TextArea: + +Textareas are used in two ways: massive text output, it could be colour coded. Textareas are also used to simulate list controls where you could select a line and receive the row number of the selected item. It is also possible to assign a specific value to each row. + + +Label: + +A label is simply a static text control, but it defines a few mouse events. Not so complex as a button. + + +Scrollbar: + +A scrollbar is mostly used in connection with a Textarea, but it could be used differently. (See GUILOAD as an example). + + +Worldmap: + +This control has a button type placeholder in the original user interface files. + The current GemRB chui loader can't handle this type, so you must create it via a CreateWorldMapControl command. + + +Map: + +This control has a button type placeholder in the original user interface files. The current GemRB chui loader can't handle this type, so you must create it via a CreateMapControl command. + + +Game: + +This control has no equivalent in the original user interface files. It covers the main game area where the actors are placed. The engine enforces that the game control is always the first control of the first window. To achieve this, it will close all windows when entering the game. + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/data_exchange.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/data_exchange.txt new file mode 100644 index 000000000..c7e221e97 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/data_exchange.txt @@ -0,0 +1,48 @@ +Data exchange between GUI controls and Global Dictionary Names. + +Each control has an associated 'Value' which could be assigned to it by the SetVarAssoc command. The controls handle this value according to their type and subtype. To set a button's subtype, use the SetButtonFlags command. + +Normal button: the associated variable will be set to the 'Value', other controls are unaffected. +CheckBox : the associated variable will be or-ed with the value, other controls may change accordingly to the new value. +RadioButton : the associated variable will be set to the 'Value', other controls are changed accordingly to the new value. + +Progressbar: the progressbar will handle Value as a percentage (it can't alter the value). + +Slider: the slider will handle Value as a scaling factor (not the actual position!), it will set the associated Variable to Position*Value. + +TextEdit: cannot be associated with a variable. You have to use QueryText() + +TextArea: cannot be associated with a variable, use the various TextArea commands. + +Label: labels work like a normal button, the Value will be assigned to the associated variable when the label was 'pushed'. + +ScrollBar: Value will be set based on the scrollbar's knob position. The scrollbar will be redrawn based on Value. If a textarea was associated to the ScrollBar (via the .chu) then the textarea will also be scrolled. + +WorldMapControl: whether travel allowed or not (change the cursor) + +MapControl: the mapcontrol will use the first bit of the associated value to display mapnotes. + +Examples: + Progress = 0 + GemRB.SetVar ("Progress", Progress) + Bar = GemRB.GetControl (LoadScreen, 0) + GemRB.SetVarAssoc (LoadScreen, Bar, "Progress", Progress) +Bar is a ProgressBar control, the engine will refresh the "Progress" Global Dictionary Variable as it progresses with the EnterGame command. + + GemRB.SetButtonFlags(FeedbackWindow,THac0RollsB, IE_GUI_BUTTON_CHECKBOX, OP_OR) + GemRB.SetVarAssoc(FeedbackWindow,THac0RollsB, "Rolls",1) +The above commands (from the options screen) will change the "Rolls" variable according to the CheckBox' state. + + BppButtonB1 = GemRB.GetControl(GraphicsWindow, 5) + BppButtonB2 = GemRB.GetControl(GraphicsWindow, 6) + BppButtonB3 = GemRB.GetControl(GraphicsWindow, 7) + GemRB.SetButtonFlags(GraphicsWindow, BppButtonB1, IE_GUI_BUTTON_RADIOBUTTON,OP_OR) + GemRB.SetButtonFlags(GraphicsWindow, BppButtonB2, IE_GUI_BUTTON_RADIOBUTTON,OP_OR) + GemRB.SetButtonFlags(GraphicsWindow, BppButtonB3, IE_GUI_BUTTON_RADIOBUTTON,OP_OR) + GemRB.SetVarAssoc(GraphicsWindow, BppButtonB1, "BitsPerPixel",16) + GemRB.SetVarAssoc(GraphicsWindow, BppButtonB2, "BitsPerPixel",24) + GemRB.SetVarAssoc(GraphicsWindow, BppButtonB3, "BitsPerPixel",32) +The above commands will set up the BPP selection RadioButton group. + +See also: SetVarAssoc, SetVar, GetVar, QueryText, SetButtonFlags, accessing_gui_controls + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/doc_template.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/doc_template.txt new file mode 100644 index 000000000..da13f83ad --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/doc_template.txt @@ -0,0 +1,13 @@ + +Prototype: + +Metaclass Prototype: + +Description: + +Parameters: + +Return value: + +See also: + diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript/reserved_functions.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/reserved_functions.txt new file mode 100644 index 000000000..032ab5e72 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript/reserved_functions.txt @@ -0,0 +1,44 @@ +The following functions have a special meaning: + +OnLoad(): + This function is called when the GUI script was loaded by GemRB. + +StartTextScreen(): + This function is called when the engine encountered a TextScreen or an + IncrementChapter game script action. + +OpenWorldMapWindow(): + This function is called when the worldmap window must be opened. + +UpdatePortraitWindow(): + This function is called when there was a change in the party, this includes + party order and PC hitpoints or state changes that may affect portraits. + +SelectionChanged(): + This function is called when there was a change in selection of a team member. + +OpenStoreWindow(): + This function is called when the StartStore scripting action was called. + Or a container item was accessed. + +UpdateControlStatus(): + This function is called when a pane changed on the game screen. + +OpenContinueMessageWindow(): + This function is called when the player may choose to continue a dialog. + +OpenEndMessageWindow(): + This function is called when the player may choose to end a dialog. + +DeathWindow(): + This function is called when the team/protagonist is killed. See also + GameSetProtagonistMode(). + +OpenReformPartyWindow(): + This function is called when there are too many teammembers. + +OpenContainerWindow(): + This function is called when the player accessed a ground pile or container. + +CloseContainerWindow(): + This function is called when GemRB requests the container window to be closed. diff --git a/project/jni/application/gemrb/gemrb/docs/en/GUIScript_introduction.txt b/project/jni/application/gemrb/gemrb/docs/en/GUIScript_introduction.txt new file mode 100644 index 000000000..17d588e9b --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/GUIScript_introduction.txt @@ -0,0 +1,275 @@ +GUISCRIPT INTRODUCTION +---------------------- + +This file is intended as a brief overview for one of two scripting systems +in GemRB - GUIScript. You should read it if you want to hack on GemRB's GUI. + + +Contents +-------- + + - Introduction - GUIScript and GameScript + - Script execution + - Typical GUIScript + - GUIScripter's Workflow + - Notes + +Introduction - GUIScript and GameScript +--------------------------------------- + +As said above, there are two scripting systems within GemRB - GUIScript +and GameScript. What's the difference between them? + +The first one, GUIScript, concerns mostly with game GUI, i.e. user +interaction, opening and closing windows, pushing of character sheet +buttons, inventory, etc. This functionality was hardwired in the +original games (probably with Lua scripts compiled-in into the main +EXE) and so we need to implement it anew. GUIScript scripts have to be +tailored for each game type, because each game uses more or less +different GUI, string refs, and so on. We program these scripts in +Python. + +The second one, GameScript, governs almost all AI and "AI" in game, +effects of opening a trapped chest, annoying an important NPC or +putting together pieces of a puzzle. These scripts are of course +totally story (and hence game) dependent, fortunately they are stored +in game's data files. They are written in special language and +usually compiled in *.bcs files. Some of them are uncompiled (*.bs +files) or even stored in dialog.tlk. + +This file concerns with the first type of scripts, GUIScripts. + + +Script execution +---------------- + +GUIScripts are stored in gemrb/GUIScripts//. First script to +be run is always named Start.py. Main window with messages, map +display, character portraits, action buttons etc. is named +MessageWindow.py. Other scripts are usually named after *.CHU resource +file they mostly use. + + Example: + Planescape: Torment startup script: + gemrb/GUIScripts/pst/Start.py + + Baldur's Gate 2 inventory: + gemrb/GUIScripts/bg2/GUIINV.py + +GemRB API is provided to the scripts by means of GemRB module. The +module is implemented together with Python interpreter glue in +GUIScript plugin in gemrb/plugins/GUIScript/GUIScript.cpp. + + Example: + import GemRB + GemRB.LoadTable ("RACES") + +Description of all functions in the huge GemRB module is in +gemrb/docs/en/GUIScript directory, GUIScript.cpp file itself or obtained +by typing help(GemRB) in GemRB console (type ESC to open console). In +that case the help is dumped to stdout. + +All scripts to be run have to define OnLoad() function, which is +called by GemRB each time the script is loaded. Those python files +without OnLoad() function are merely modules imported into another +script, usually MessageWindow.py. + +The control between scripts is passed with GemRB.SetNextScript() +function, which causes another script to be loaded. Repeated loading +of a script causes repeated calling of its OnLoad() function. + +All scripts automagically import all symbols from file +gemrb/GUIScripts/GUIDefines.py, which contains definition of constants +commonly used in the scripts. Other files in this directory can be +imported too. + + Example: + import GemRB + from ie_stats import IE_SAVEVSPOLY + def OnLoad(): + print IE_GUI_BUTTON_NORMAL, IE_SAVEVSPOLY + GemRB.SetNextScript("MessageWindow") + + + +Typical GUIScript +----------------- + +A typical script's task is to open a window, setting button labels and +callbacks and then return control back to GemRB. The script also +provides a mean to close the window created. + +Since most scripts are modules of MessageWindow.py instead of +independent scripts, we will use a simplified version of one of them +for an example + + + ## Standard header and boilerplate, put in all the scripts. + + # -*-python-*- + # GemRB - Infinity Engine Emulator + # Copyright (C) 2003 The GemRB Project + ..... + + + ## Since this is only a module, GemRB and GUIDefines have to be explicitly + ## imported + + ################################################### + import GemRB + from GUIDefines import * + from GUICommon import CloseOtherWindow + + ################################################### + JournalWindow = None + LogWindow = None + QuestsWindow = None + ## Function called from a callback in MessageWindow.py + + ################################################### + def OpenJournalWindow (): + global JournalWindow + + ## This is a common way of closing another window before opening + ## our own one (here Journal window). If Journal window already + ## exists, it's closed and the control is returned to the caller + ## (this implements toggling of a window) + + if CloseOtherWindow (OpenJournalWindow): + ## this part is called if we are closing Journal window + + ## Close any opened children windows + + if LogWindow: OpenLogWindow() + if QuestsWindow: OpenQuestsWindow() + + ## Freezes the GUI + GemRB.HideGUI () + + ## Free the window resource and delete Journal window + ## from window manager + GemRB.UnloadWindow(JournalWindow) + JournalWindow = None + GemRB.SetVar("OtherWindow", -1) + + ## Unfreeze the GUI, redraws screen, reshuffles windows in + ## window manager + + GemRB.UnhideGUI () + + ## Return to the caller + return + + ## This part is executed when we did not close Journal window + ## and will open it instead + + ## Freeze the GUI + GemRB.HideGUI () + + ## Loads CHU resource file. This one contains windows for Journal, + ## Log, and PC/NPC encyclopedia. + + GemRB.LoadWindowPack ("GUIJRNL") + + ## Load window with ID 0 (Main Journal window) from GUIJRNL.CHU file. + + JournalWindow = GemRB.LoadWindow (0) + + ## Add the new window to window manager. "OtherWindow" is name reserved + ## for non-floating windows in the center of the screen. + + GemRB.SetVar("OtherWindow", JournalWindow) + + ## Now access some buttons in the new window and assign + ## labels and callbacks to them + + ## Comment the button processing with the label of the button for + ## easy maintenance + + # Quests + + ## Quest button has ID 0 in GUIJRNL.CHU in window ID 0 + Button = GemRB.GetControl (JournalWindow, 0) + + ## Set the label for the button to strref 20430 ("Quests") + GemRB.SetText (JournalWindow, Button, 20430) + + ## When the button is clicked by mouse, call fn OpenQuestsWindow() + GemRB.SetEvent (JournalWindow, Button, IE_GUI_BUTTON_ON_PRESS, "OpenQuestsWindow") + + ## Now some other buttons. Note that "Done" button calls this + ## function, which causes closing of the Journal window + + # Beasts + Button = GemRB.GetControl (JournalWindow, 1) + GemRB.SetText (JournalWindow, Button, 20634) + GemRB.SetEvent (JournalWindow, Button, IE_GUI_BUTTON_ON_PRESS, "OpenBeastsWindow") + + # Done + Button = GemRB.GetControl (JournalWindow, 3) + GemRB.SetText (JournalWindow, Button, 20636) + GemRB.SetEvent (JournalWindow, Button, IE_GUI_BUTTON_ON_PRESS, "OpenJournalWindow") + + + ## Unfreeze the GUI, redraw screen and restart window manager + GemRB.UnhideGUI() + + +GUIScripter's Workflow +---------------------- + +- Run GemRB and an original game in parallel and notice GUI parts + missing or badly done in GemRB. + +- Divine the CHU file containing the window resource. It can either be + guessed by comparing names of all CHU files in the game to required + functionality, from GUIScript already implementing related part of + the GUI or by viewing all CHU files in CHU/BAM/MOS viewer (DLTCEP, + NearInfinity) and finding the right looking one. + +- Find ID of the window to be implemented in the CHU file, usually + with DLTCEP or NearInfinity. + +- Copy & paste common parts of the script from another one opening + similar windows. + +- Using CHU viewer find control IDs for the controls you need to + configure in the script and add their setting into the script, again + copy & pasting from another script. Usually start with magic trinity + of GetControl, SetText, SetEvent for each button. Use dummy numbers + for now. Beware, NearInfinity displays wrong IDs for labels. You will + have to add the label's control ID to "buffer size" << 32 to get the + right control ID. + +- Write down button labels as they are seen in the original game and + find their strrefs using DLTCEP or NI. Alternatively, you can set + "Strref On=1" in *.INI of the original games and write down directly + the strrefs as they are displayed instead of the labels. This + however does not work with Planescape: Torment. + +- Put the strrefs into the SetText() functions in the script. + +- Now when the trivial parts are done, the real fun can begin. + But that's a subject too advanced for this file :-). + + +Notes +----- + +Please try to follow the indentation style of other GUIScript scripts, +in particular: + + - indent each level with 1 TAB character + + - insert space between function name and opening parenthesis in + function calls and around operators and after the hash sign in + text comments + + - insert blank lines between logically separated chunks of code, + e.g. between setting of different controls + + - insert blank lines after functions and a row of hashes + + - keep naming convention for windows, callback etc. + + - comment your code diff --git a/project/jni/application/gemrb/gemrb/docs/en/Makefile.am b/project/jni/application/gemrb/gemrb/docs/en/Makefile.am new file mode 100644 index 000000000..b4b653e55 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Makefile.am @@ -0,0 +1,6 @@ +SUBDIRS = Tables GUIScript Engine +docs_DATA = *.txt +docsdir = $(docdir)/ +EXTRA_DIST = *.txt + +CLEANFILES = doxygen/html/* doxygen/latex/* diff --git a/project/jni/application/gemrb/gemrb/docs/en/Release.txt b/project/jni/application/gemrb/gemrb/docs/en/Release.txt new file mode 100644 index 000000000..ea9ade024 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Release.txt @@ -0,0 +1,78 @@ +How to make a release +********************* + +Preparing and testing GIT +========================= + +* Make sure that version numbers in + configure.in + gemrb/includes/globals.h + are correct for the upcoming version. + +* Update NEWS with highlights since the last release + +* Make sure that GemRB GIT is in compilable and runnable state + - download a clean GIT tree and test it. + - Make distribution .tar.gz (see Source release below) and test it as well - + especially make sure all needed files are included. + +* Tag current GIT to version number e.g. v0.9.0 + i.e. in the gemrb root directory do + git tag -a -m "GemRB 0.9.0" v0.9.0 + git push origin v0.9.0 +* Update from GIT to the tagged version + git checkout v0.9.0 + +* After you're done, update the version with a -git suffix, so it will be + easier to tell if people are running release builds or not + +Source release +============== + +* on Unix/Linux: + make dist + + +Linux binary release +==================== + + ./autogen.sh + ./configure --prefix=/usr/local + make + make install DESTDIR=/tmp/fakeroot + cd /tmp/fakeroot/usr/local + copy ~/GemRB-binary.cfg over etc/GemRB.cfg, rename to etc/gemrb.cfg + strip bin/gemrb lib/* lib/gemrb/* + sudo chown -R 0:0 * + sudo tar cvzf ../gemrb-0.2.5-linux_i386.tar.gz * + + +Windows binary release +====================== + +* FIXME: To be defined.... + + +Release and Announcements +========================= + +* Write the release notes if necessary. They are mainly for packagers, so +create them if there are structural or build related changes. New config +options should also be mentioned here if they're not part of the changelog. + +* Put the tarballs/binaries into Releases on SF + - go to the Files section + - click on the sources subdir + - add a new similarly-named folder + - use "add file" to upload the sources and release notes + - change the file properties to set the default platforms (under "view details") + +* Test the downloads from sourceforge.net + +* Announce on homepage, SF, #GemRB in channel and title, Happypenguin, LGDB and + Gibberlings3: + - our forum + - modding news (Avenger, Theacefes, Grim Squeaker, DavidW and cmorgan have access) + (a template is available in admin/announcement.template) + +* Run admin/restart_news.sh to restart the NEWS cycle diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/HPBARB.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/HPBARB.txt new file mode 100644 index 000000000..943f35d97 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/HPBARB.txt @@ -0,0 +1,8 @@ +Description: Contains the hp to gain on barbarian level up. + +Columns - +SIDES - number of sides to roll +ROLL - number of rolls +MODIFIER - add after the roll + +Rows - the level the roll applies to diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/Makefile.am b/project/jni/application/gemrb/gemrb/docs/en/Tables/Makefile.am new file mode 100644 index 000000000..63decc795 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/Makefile.am @@ -0,0 +1,3 @@ +tabledocs_DATA = *.txt +tabledocsdir = $(docdir)/Tables/ +EXTRA_DIST = *.txt diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/ability.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/ability.txt new file mode 100644 index 000000000..bcc2f846d --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/ability.txt @@ -0,0 +1,10 @@ +Description: This table lists the abilities (strength, intelligence) in the game. + +Columns - +NAME_REF - the name of the ability +CAP_REF - the capitalized name of the ability +DESC_REF - the description of the ability +STAT_ID - the ability stat value + +Rows - abilities + diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/aligns.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/aligns.txt new file mode 100644 index 000000000..8435eb375 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/aligns.txt @@ -0,0 +1,12 @@ +Description: This table lists the alignments pickable in the game. + +Columns - +NAME_REF - the name of the alignment +CAP_REF - the capitalized name of the alignment +DESC_REF - the description of the alignment +VALUE - the alignment stat value +COLNAME - the column name for this alignment in other tables +USABILITY - the item usability flag + +Rows - alignments + diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/areapro.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/areapro.txt new file mode 100644 index 000000000..ebee0f6bc --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/areapro.txt @@ -0,0 +1,25 @@ +Description: This table lists resource data for area projectiles. The original engine had these hardcoded in the .exe + +Columns - + RESOURCE1 - A BAM resref which is drawn in the entire area of effect. + RESOURCE2 - A VVC (or BAM) resref which is drawn in the center of effect once. + RESOURCE3 - An alternate animation (named recoil without better name) + SOUND1 - Explosion sound (played on first explosion) + SOUND2 - Area sound (played on subsequent explosions) + FLAGS - a bitfield which alters the way the resources are drawn + +Values for the FLAGS bitfield - + 1 - RESOURCE1 is recoloured by the gradient set in the projectile + 2 - fills the entire area of effect randomly, otherwise it is a (spreading) circle + 4 - no spreading, the filler graphic is already at its destination, otherwise it starts from the center + 8 - RESOURCE2 is recoloured by the gradient set in the projectile + 0x10 - repopulate children that vanished + 0x20 - the child projectiles need gradient colouring + 0x40 - draw RESOURCE3 projectiles too (halves the number of children as well) + 0x80 - double the number of child projectiles + 0x100 - if none was affected by this projectile, apply a spell of same name on the caster + +areapro.2da data could be completely incorporated into the projectile file, it is supplied +only for some BG2 spells that don't use the extended projectile format. + +See projectile.txt for more information. diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/avatars.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/avatars.txt new file mode 100644 index 000000000..de8e2af44 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/avatars.txt @@ -0,0 +1,66 @@ +Description: This table lists the avatar animations. PST has a slightly different animation scheme, this could be turned on by the OneByteAnimationID option (in gemrb.ini). When it is on, the high byte of the animation ID will control the palette flag thus eliminating the need of the PALETTE column. + +[ Note: apparently, PST is more complicated than that: +Foundry gears: 0x2000 +Iron Golem: 0x3000 +Mortuary ghost: 0xD400 +Pillar of Skulls: 0xF000 +black abishai: 0xE000 + +The only normal one of them is black abishai, the others are all somewhat special. For example, Pillar of Skulls consists of two BAMs, POSMAIN and POSSHAD (the pillar and its shadow, both animated). See ANIMATE.IDS. ] + + +Columns: AT_1 - first armour level animation prefix + AT_2 - second armour level animation prefix + AT_3 - third armour level animation prefix + AT_4 - fourth armour level animation prefix + TYPE - the animation scheme + +0 - Many files, this is the avatar animation of BG2. +1 - The whole animation is in one file. Scheme is: [NAME][G1]. There are 16 orientations. +2 - The whole animation is in four files. Scheme is: [NAME][G1-2][/E]. +3 - The whole animation is in two files. Scheme is: [NAME][G1][/E]. +4 - Many files (simular to 0), but all with G. Scheme is: [NAME][G][1-2][1-6]. +5 - ? +6 - BG2 style animation. Scheme is:[NAME][ACTIONCODE][/E]. The G1 code contains many sequences. (5 orientations). +7 - Bird animations, one file, only movement with orientations. +8 - Six files contain the whole animation. Scheme is:[NAME][G1-3][/E] +9 - IWD style animation. Scheme is:[NAME][ACTIONTYPE][/E]. The main difference from 6 is that instead of G1, it has separate bams for many actions. (9 orientations). +10 - The whole animation is in two files [NAME][G1][/E]. Used for some low res static BG1 animations like the horse and cow. It lacks the walking animations of type 3. +11 - large 2x2 animations (wyvern and balor) +12 - huge 3x3 dragon animations +13 - 15 reserved for non pst anims +16 - full PST style animation. Scheme is:[C/D][ACTIONTYPE][NAME][B] +17 - stand still animation (no orientations) +18 - stand still animation with orientations +19 - full PST animation without different stc/std sequences + +PST ACTIONTYPE: +AT1, AT2 +C2S +CF1, CF2 +DFB +GUP Get Up +HIT Hit +MS1, MS2 +RUN Run +S2C +SF1, SF2 +SP1 .. SP4 +STC Fight Stance? +STD +TK1 .. TK6 Talk +WLK Walk + + SPACE - the personal space of the creature + PALETTE - set it to 1 if the animation has its own palette (0 for fake colored avatars). +Not needed if OneByteAnimation was set. + SIZE - Used for selecting possible weapon animation BAMs. +Not needed if OneByteAnimation was set. + +Rows: each row begins with a hexadecimal Animation ID. One or two bytes. + +Example: the wyvern animation + AT_1 AT_2 AT_3 AT_4 TYPE SPACE PALETTE +0x1000 MWYV MWYV MWYV MWYV 2 5 1 + diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/avprefix.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/avprefix.txt new file mode 100644 index 000000000..50b90c857 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/avprefix.txt @@ -0,0 +1,34 @@ +Description: Contains the scheme of the avatar animation IDs based on character stats. The first row, contains the base Animation ID of the avatars. A second column may store the first stance of the generated character (useful only for PST). Additional rows may contain a table ResRef which modifies the animation ID based on a stat. These tables contain a stat number in their first (0.) row. The other rows contain the modifier value based on the stat. + +Columns: RESREF - One column, with different values. + +Rows: 0 - base Animation ID + - table ResRef + +Example (BG2): + RESOURCE +0 0x6000 +1 avprefr +2 avprefg +3 avprefc + +avprefr.2da: + RACE +TYPE 201 +HUMAN 0 +ELF 1 +... +avprefc.2da: + CLASS +TYPE 202 +FIGHTER 0x100 +MAGE 0x200 +... +The Animation ID depends on race, gender and class in bg2. The race stat is 201, so that is in the first row. + +Example (PST): + RESOURCE STANCE +0 0x6032 18 + +The Animation ID is constant, but there is a special stance (waking up on the slab). + diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/cgtable.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/cgtable.txt new file mode 100644 index 000000000..c7d8e6df3 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/cgtable.txt @@ -0,0 +1,6 @@ +Description: This table is used by the casting glow opcode and also when casting a spell (the spell header contains the casting glow code). + +Columns: the casting glow resref (VVC or BAM) + +Rows: the casting glow code + diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/classes.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/classes.txt new file mode 100644 index 000000000..b51630e69 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/classes.txt @@ -0,0 +1,15 @@ +Description: This table lists the playable classes in the game. + +Columns - +NAME_REF - the name of the class +CAP_REF - the capitalized name of the class +DESC_REF - the description of the class +SAVE - the saving throw table for this class +USABILITY - the item usability flag +MULTI - if multi class, which classes are combined +ID - the class stat value +HP - the hp table for the class + - the rest of the columns enable or disable the class (2 means partially usable) + +Rows - classes + diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/clowncol.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/clowncol.txt new file mode 100644 index 000000000..85e592b09 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/clowncol.txt @@ -0,0 +1,10 @@ +Description: This table lists the pickable colours for the avatar. + +Columns - gradient slots + +Rows - + MAJOR - the gradient values for the major colour + MINOR - the gradient values for the minor colour + HAIR - the gradient values for the hair colour + SKIN - the gradient values for the skin colour + diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/containr.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/containr.txt new file mode 100644 index 000000000..28f9472c2 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/containr.txt @@ -0,0 +1,11 @@ +Description: This table lists the resources used for container types. + +Columns: The BAM and Sound resource references associated with the type. + +Rows: Container types. The row index is based on the container type set in the container data of an area. + +Example: + SOUND BAM +* * * +BAG GAM_12A1 CONTSACK + diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/damage.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/damage.txt new file mode 100644 index 000000000..0d7a8113b --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/damage.txt @@ -0,0 +1,10 @@ +Description: This table lists the damage animations. + +Columns - + MAIN - the damage hit animation + SPARKS - additional splash animations + GRADIENT - fake coloured animations will be recoloured with this gradient + +Rows - damage types + +See also: dmgtypes.txt diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/defsound.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/defsound.txt new file mode 100644 index 000000000..cc4a801a9 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/defsound.txt @@ -0,0 +1 @@ +Description: This table lists default sounds used by the engine. diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/dmgtype.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/dmgtype.txt new file mode 100644 index 000000000..4dbad7299 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/dmgtype.txt @@ -0,0 +1,11 @@ +Description: This table lists the damage type resistances. + +Columns - + LOWER - string reference index (there is a second indirection by strings.2da) + RESIST_STAT - character stat which provides resistance + VALUE - damagetype value + IWDMOD - value of the type parameter to the bonus damage modifier effect in iwd + +Rows - damage types + +See also: damage.txt diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/fistweap.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/fistweap.txt new file mode 100644 index 000000000..32a5d2d39 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/fistweap.txt @@ -0,0 +1,7 @@ +Description: This table contains what resref will be created in the fist slot of a creature. +This is usually the FIST object, but for the monk class it varies with level. +It is possible to add other classes which have level based fist weapon. + +Columns: The levels + +Rows: The classes (use class id as label) diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/fonts.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/fonts.txt new file mode 100644 index 000000000..4e2b730d7 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/fonts.txt @@ -0,0 +1,13 @@ +Description: This table lists fonts. Only fonts listed here could be used as a font resource. + +Columns: RESREF - the .bam ResRef of the font + NEED_PALETTE - if the font has no own palette, set this to 1 + FIRST_CHAR - usually 0, it contains the first printable character of the font. + +Rows: - make sure the 9. font is a 'normal' font. Used for floating texts. (this is a hacked legacy feature, it may go away). + +Example (BG2): + RESREF NEED_PALETTE FIRST_CHAR +0 NORMAL 1 0 +1 NUMBER 0 47 +2 INITIALS 0 0 diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/formatio.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/formatio.txt new file mode 100644 index 000000000..c8e2fd72e --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/formatio.txt @@ -0,0 +1,10 @@ +Description: This table contains preset party formations. + +Columns: X/Y pairs of relative coordinates from the target location. 7-10 pairs can be specified. The coordinates must be given for the north direction. (Other directions will be calculated). + +Rows: Formation types. + +Example: + X1 Y1 X2 Y2 X3 Y3 X4 Y4 X5 Y5 X6 Y6 X7 Y7 +FOLLOW 0 0 0 1 0 2 0 3 0 4 0 5 0 6 + diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/guibtact.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/guibtact.txt new file mode 100644 index 000000000..05f2506dd --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/guibtact.txt @@ -0,0 +1,9 @@ +Description: This file describes the action button icons and associated tooltips. + +The row names are also part of the function name to run when the button is +pressed ("Action%sPressed"). For example, clicking the thieving button +will run "ActionThievingPressed()". + +Columns: 1-4: The button BAM Frame numbers for the four button sprites. + TOOLTIP: The tooltip strref for the action. + RESREF: The resref of the button icon. diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/item_use.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/item_use.txt new file mode 100644 index 000000000..5a96e86b8 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/item_use.txt @@ -0,0 +1,7 @@ +Description: This table lists special items that won't be dropped by certain actors. + +Columns: +USER - the scripting name of the playable character +STRREF - the displayed string + +Rows: Item resrefs diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/itemsnd.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/itemsnd.txt new file mode 100644 index 000000000..d8dea45e2 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/itemsnd.txt @@ -0,0 +1,9 @@ +Description: This table assigns sounds to item types. The itemtypes must be defined by itemtype.2da. The last four itemtypes are reserved for armourlevel based sounds of body armors. + +Columns: Sound resource references for the TAKE and the DROP sound. + +Rows: Item types. They must follow the item types in itemtype.2da. There must be four extra item types at the end: +DEFAULT +LEATHER +CHAIN +PLATE diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/itemspec.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/itemspec.txt new file mode 100644 index 000000000..bb08a97cf --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/itemspec.txt @@ -0,0 +1,6 @@ +Description: This table lists special functionality items. + +Columns: + IDENTIFY - the item could be used as identifying tool. The item's first extended header will be executed. + +Rows: Item resrefs diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/itemtype.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/itemtype.txt new file mode 100644 index 000000000..d13e75a6b --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/itemtype.txt @@ -0,0 +1,17 @@ +Description: This table assigns item types to inventory slot types. It tells which item may go into which inventory slot. The slot types are the bit values of slottypes.2da + 1 - helm (or earring in pst) + 2 - armour + 4 - shield + 8 - gauntlet + 16 - ring + 32 - amulet + 64 - belt + 128 - boot + 256 - weapon + 512 - quiver +1024 - cloak +2048 - quick item + +Columns: Slot types. They must follow in the same order in any engine, you may add additional columns if needed. (Probably only in PST). + +Rows: Item types. They must follow the natural order of item types as of the original engine. diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/itemuse.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/itemuse.txt new file mode 100644 index 000000000..133be8ec7 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/itemuse.txt @@ -0,0 +1,10 @@ +Description: This table lists the item usability flags. + +Columns: +STAT - the stat which affects the bits +FILE - the file which contains the usability values assigned to the stat values +MCOL - the stat values +VCOL - the usability values +WHICH - which bitfield group is affected (could be only 0 or 1) + +Rows: Item resrefs diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/magesch.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/magesch.txt new file mode 100644 index 000000000..7897694b3 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/magesch.txt @@ -0,0 +1,9 @@ +Description: This table lists the mage schools pickable in the game. + +Columns - +NAME_REF - the name of the mage school +CAP_REF - the capitalized name of the mage school +DESC_REF - the description of the mage school +KIT - the mage school kit value (also used as usability flag) + +Rows - mage schools diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/modal.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/modal.txt new file mode 100644 index 000000000..a67632292 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/modal.txt @@ -0,0 +1,15 @@ +Description: This table assigns spell resources to modal actions. +These modal actions were hardcoded in the original engines. + +Columns - + SPELL - the spell resource assigned to the modal action. + ACTION - the name of the equivalent action in GemRB + STR_ON - the string to display when enabling this action/state + STR_OFF - the string to display when disabling this state + STR_FAILED - the string to display when enabling of this state fails + AOESPELL - does the SPELL have an area of effect? + +Rows - the modal actions have a somewhat determined order. +The first row should be left blank. + +See modal.ids of the original engine. diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/overlay.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/overlay.txt new file mode 100644 index 000000000..0e951529a --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/overlay.txt @@ -0,0 +1,5 @@ +Description: This table lists the hardcoded overlay animations. + +Columns - + +Rows - resrefs for each overlay type (the slots are mandatory) diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/pathfind.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/pathfind.txt new file mode 100644 index 000000000..3052106f8 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/pathfind.txt @@ -0,0 +1,16 @@ +Description: This table describes how the pathfinder must handle the searchmap entries. Also it sets the cost of reaching a neighbouring point. + +Columns: + +Rows: The first row contains 16 bitfields, one for each search map value. The bits make it possible to have an opaque, but passable area (but this isn't too meaningful). +1 - passable (can walk through) +2 - travel region +4 - opaque (can't see through) +8 - sidewall (blocks sight specially) +(As you can see 14 marks the travel region). +The second row contains the cost of walking straight, and the additional cost of walking diagonals. + +Example (BG2): + 0 1 2 3 4 5 6 7 8 9 a b c d e f +PASSABLE 4 1 1 1 1 1 1 1 0 1 8 0 0 0 3 1 +COST 10 4 diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/pdolls.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/pdolls.txt new file mode 100644 index 000000000..9e22f7c90 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/pdolls.txt @@ -0,0 +1,8 @@ +Description: This table lists the paperdolls linked to each avatar animation ID. + +Columns - + LEVEL1-4 - the paperdoll for each armour level + SIZE - the size suffix (for equipment layers) + +Rows - animation IDs + diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/pictures.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/pictures.txt new file mode 100644 index 000000000..0da0aa25d --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/pictures.txt @@ -0,0 +1,11 @@ +Description: This table lists the pickable portraits and the default colours for the avatar, based on the portrait icon. + +Columns - + GENDER - male of female portrait (the gender stat) + HAIR - the default hair colour + SKIN - the default skin colour + MAJOR - the default major robe colour + MINOR - the default minor robe colour + +Rows - + portraits diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/polystat.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/polystat.txt new file mode 100644 index 000000000..0068f084a --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/polystat.txt @@ -0,0 +1,4 @@ +Description: This table lists the stats that are copied from a polymorph creature into the target of a polymorph effect. The stats could be given numerically, or literally as they are written in stats.ids + +Columns - + 0 - the only column, containing stat values (or names). diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/qslots.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/qslots.txt new file mode 100644 index 000000000..22531877d --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/qslots.txt @@ -0,0 +1,11 @@ +Description: This file contains the default action buttons based on class. +This file is inherited from IWD2, although IWD2 uses a slightly different version. +The columns of the table contain the nine modifiable actions for each class. +A value of 100 means an unavailable slot. +The values may be 0-31, and represent the first 32 rows of guibtact.2da + +Columns: the quick slots + +Rows: the classes + +See also: guibtact.txt diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/races.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/races.txt new file mode 100644 index 000000000..8d66a8552 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/races.txt @@ -0,0 +1,11 @@ +Description: This table lists the playable races in the game. + +Columns - +NAME_REF - the name of the race +CAP_REF - the capitalized name of the race +DESC_REF - the description of the race +ID - the race stat value +USABILITY - the item usability flag + +Rows - races + diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/randitem.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/randitem.txt new file mode 100644 index 000000000..f41ff18e9 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/randitem.txt @@ -0,0 +1,25 @@ +Description: The randitem.2da file serves as a compatibility switch between different engine versions. It contains the ResRef for the gold item and it is the root table for random item tables. Two major random item distributions are allowed: multiple tables or single table. To have a single table, the second row (RND) must contain two ResRefs. +More rows will follow with the table prefixes. The table prefixes must not exceed 6 characters in length. It may also contain two ResRefs for original game engine single treasure tables (no suffix). + +Columns: RESREF - the table names + FURY_MODE - use these values in the highest difficulty level + +Rows: GOLD - it must be the first row, and contains the gold ResRef. When the system needs the gold item, it will use this ResRef. + RND - if numeric, it contains the number of treasure tables which employ a numerical suffix (like rndequ01). If text, it contains table ResRefs. + - if RND was numeric, there follows x table suffixes + +Example (BG2): + RESREF FURY_MODE +GOLD MISC07 +RND 5 5 +RNDEQU RNDEQUIP RNDEQUIP +RNDMAG RNDMAGIC RNDMAGIC +RNDSCR RNDSCROL RNDSCROL +RNDTRE RNDTREAS RNDTREAS +RNDWEP RNDWEP RNDWEP + +Example (IWD2): + RESREF FURY_MODE +GOLD MISC07 +RND RT_NORM RT_FURY + diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/restmov.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/restmov.txt new file mode 100644 index 000000000..0cb480af3 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/restmov.txt @@ -0,0 +1,12 @@ +Description: This table lists the resting and day/night switching movies. +The resting movie index is determined by 3 bits of the areatype. (CITY/FOREST/DUNGEON). +Day/night switching occurs only for areas marked by the EXTENDED_NIGHT flag (also in areatype). +The original engine showed only a single switching movie (for a city environment), but +GemRB allows for 8 different movies (based on the areatype bit combinations). + +Columns - + resting movies + day switching movies + night movies + +Rows - The movie resource references for each areatype. diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/savegame.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/savegame.txt new file mode 100644 index 000000000..7eb03372a --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/savegame.txt @@ -0,0 +1 @@ +Description: This table lists save game name prefixes used by the SaveGame() action. diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/script.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/script.txt new file mode 100644 index 000000000..41e190efe --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/script.txt @@ -0,0 +1,14 @@ +Description: This table describes how the script file objects and triggers look like. + +Columns: + +Rows: + OBJECT_IDS_COUNT - the count and name of the IDS identifiers (ea, general, race...) + MAX_OBJECT_NESTING - the maximum number of object filters + + ADDITIONAL_RECT - 1 if the object has additional rectangle parameter + + EXTRA_PARAMETERS_COUNT - the number of IDS after the string parameter + + TRIGGER_POINT - 1 if the triggers contain an extra point parameter + diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/shtable.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/shtable.txt new file mode 100644 index 000000000..84a9ec1e8 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/shtable.txt @@ -0,0 +1,6 @@ +Description: This table is used by the spell hit animation opcode. + +Columns: the spell hit animation resref (VVC or BAM) + +Rows: the spell hit code + diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/skills.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/skills.txt new file mode 100644 index 000000000..be45c9e4e --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/skills.txt @@ -0,0 +1,9 @@ +Description: This table is used by the character generator (and when leveling up). +It lists the thieving skills. The first two rows contain the distributable points per level. + +Columns - rogue classes or kits + +Rows - distributable points and skills + +The clskills.2da table's THIEFSKILL column contains the reference to this table. +Theoretically it is possible to have different tables per class. diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/skillsta.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/skillsta.txt new file mode 100644 index 000000000..a70b8e06e --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/skillsta.txt @@ -0,0 +1 @@ +Description: This table is used by the CheckSkill gamescript trigger to translate skills to stats. The guiscript for character generation in IWD2 also uses it. diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/slottype.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/slottype.txt new file mode 100644 index 000000000..f3640b60a --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/slottype.txt @@ -0,0 +1,20 @@ +Description: This table must have rows equal to the number of itemslots in a creature. + +Columns: BITS - connects the itemslots to item types (see itemtype.2da). If a bit is set to 1, the slot may carry a specific item type. -1 means all (inventory slot). The core system uses this column to determine slot types. + SCRIPT - usually the ControlID of the slot on the inventory screen, but your script may use it differently. (For example PST is a bit different). + ICON - usually a bam ResRef of the background image of the slot in the inventory screen. (Your script may use it differently). + STRREF - usually a tooltip StrRef, but your script may use it differently. + EFFECT - whether the slot is an equipping slot (for equipping effects) + FLAGS - fine tuning of slot mechanics: + - 0: normal + - 1: this slot cannot be stolen from (used for eg. the fists slot) + +Rows: each row represents a creature item slot, even unused or invisible slots must be represented. + +Example (BG2): + BITS SCRIPT ICON STRREF EFFECT FLAGS +10 0 0 * 0 2 0 +6 1 13 STONHELM 11999 7 0 +1 2 11 STONARM 11997 1 0 +... + diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/spells.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/spells.txt new file mode 100644 index 000000000..9e1eaa896 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/spells.txt @@ -0,0 +1,6 @@ +Description: This table lists the highest .spl learnable at the given level. + +Columns - +1-9 - the level to limit + +Rows - the types of spells to limit (MAGE, PRIEST, INNATE) diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/splprot.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/splprot.txt new file mode 100644 index 000000000..8440379f0 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/splprot.txt @@ -0,0 +1,41 @@ +Description: This table implements spell resistances based on a simple condition of the target's stats. +One row defines a certain 'semi-hardcoded' condition. For iwd/iwd2 these conditions were hardcoded into the engine. + +Columns - +STAT - the name or number of the stat +VALUE - a value which has to match the stat +RELATION - a symbol for the comparation to be performed +COMMENT - unused by GemRB, it is just a reminder + +Rows - spell immunity conditions used by some iwd effects. + +Stat names are coming from stats.ids +Stats over 255 (0x100 and above) are not real stats, but either virtual stats, or +composite conditions. + + +0x100 - caster is source of the spell (spell effect won't affect self) +0x101 - caster isn't source of the spell (spell effect won't affect others) +0x102 - the personal space of the target, set in avatars.2da (SPACE column) +0x103 - both rows are true (the two fields designate 2 other rows in this file) +0x104 - neither rows are true (similar to 0x103) +0x105 - only the lowest 2 bits of alignment are calculated +0x106 - area flags (outdoor, forest, etc) +0x107 - daytime flag +0x108 - caster and target EA relation (using the EA fields to calculate this) + +The relation could be +0 - less or equal +1 - equal +2 - less +3 - greater +4 - greater or equal +5 - not equal +6 - binary less or equal (all bits of left side are in right side) +7 - binary more or equal (all bits of right side are in left side) +8 - binary intersect (left and right side has at least one common bit) +9 - binary not intersect (left and right side has no common bits) +10 - binary more (left side has bits that are not in right side) +11 - binary less (right side has bits that are not in left side) + +See also: featreq diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/start.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/start.txt new file mode 100644 index 000000000..16b90dc7d --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/start.txt @@ -0,0 +1,12 @@ +Description: This table is a layer of indirection to support various startpos.2da configurations. It simply describes the used row labels for startpos.2da + +Columns - +XPOS - x position labels +YPOS - y position labels +AREA - starting area labels +ROT - optional facing direction labels + +Rows - +NORMAL - data for a normal game starting positions +TUTORIAL - data for the tutorial starting positions +EXPANSION - data for the expansion only game starting positions diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/states.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/states.txt new file mode 100644 index 000000000..f4ea6efd9 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/states.txt @@ -0,0 +1,16 @@ +Description: strrefs for character state names. + +Columns: (keys) - bitmask for particular state + NAME_REF - strref for name of this state + +Rows: each row maps one state bit (as a bitmask) to its strref + +Example (PST): + NAME_REF +0 67220 +1 59824 +2 59825 +4 59826 +8 59830 +16 59831 +... diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/strings.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/strings.txt new file mode 100644 index 000000000..4912e5fc7 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/strings.txt @@ -0,0 +1,5 @@ +Description: This table lists the hardcoded string constants used by the core engine. + +Columns - + +Rows - string references for each slot. (The order is mandatory). diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/table_template.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/table_template.txt new file mode 100644 index 000000000..9a1033744 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/table_template.txt @@ -0,0 +1,7 @@ +Description: + +Columns: + +Rows: + +Example: diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/wildmag.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/wildmag.txt new file mode 100644 index 000000000..041674ae1 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/wildmag.txt @@ -0,0 +1,27 @@ +Description: This table lists spells that are used when wild magic surges occur. The original engine had these hardcoded in the .exe. + +The row name corresponds to the required roll. The 100th row will be ignored, since a roll of 100 or more signifies a normal cast. + +Columns - + SPELL - A spell resref (to be cast instead) or one of the special codes below. + STRREF - The string to be displayed when the surge occurs (eg. "Oops, is that a Pit Fiend?") + COMMENT - unused + +The syntax of the SPELL column is as follows: + - SPELLREF (use this spell instead) + - +SPELLREF (cast this spell first, then the chosen one) + - ID.parameter (use hardcoded feature number ID, passing a parameter) + +Possible values for ID are - + 0 - cast spell //parameter// times + 1 - change projectile to parameter + 2 - also target (caster) + 3 - roll on this wild surge table //parameter// times + 4 - change target to parameter + 5 - use a random target + 6 - change the spell saving throws by //parameter// + 7 - cast a random known spell + 8 - set the projectile speed to //parameter// percent + +2 and 4 can take any effect target type as the parameter. + diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/wsshield.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/wsshield.txt new file mode 100644 index 000000000..427f1132a --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/wsshield.txt @@ -0,0 +1,6 @@ +Description: This table lists the benefits for points in sword/shield proficiency. (BG2-specific) + +Columns - +ACVSMISSILE - bonus to ac vs missile weapons + +Rows - number of stars diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/wssingle.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/wssingle.txt new file mode 100644 index 000000000..4586f5e92 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/wssingle.txt @@ -0,0 +1,7 @@ +Description: This table lists the benefits for points in single-weapon proficiency. (BG2-specific) + +Columns - +AC - bonus to ac +CRITICALHITBONUS - bonus to critical range + +Rows - number of stars diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/wstwohnd.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/wstwohnd.txt new file mode 100644 index 000000000..420000411 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/wstwohnd.txt @@ -0,0 +1,8 @@ +Description: This table lists the benefits for points in two-handed weapon proficiency. (BG2-specific) + +Columns - +DAMAGEBONUS - additional damage +CRITICALBONUS - critical roll modifier +PHYSICALSPEED - speed modifier + +Rows - number of stars diff --git a/project/jni/application/gemrb/gemrb/docs/en/Tables/wstwowpn.txt b/project/jni/application/gemrb/gemrb/docs/en/Tables/wstwowpn.txt new file mode 100644 index 000000000..c656150f3 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/Tables/wstwowpn.txt @@ -0,0 +1,7 @@ +Description: This table lists the benefits for points in two-weapon proficiency. (BG2-specific) + +Columns - +THAC0BONUSRIGHT - penalty to the main hand +THAC0BONUSLEFT - penalty to the off hand + +Rows - number of stars diff --git a/project/jni/application/gemrb/gemrb/docs/en/gemrb_ini.txt b/project/jni/application/gemrb/gemrb/docs/en/gemrb_ini.txt new file mode 100644 index 000000000..a1a1a9d07 --- /dev/null +++ b/project/jni/application/gemrb/gemrb/docs/en/gemrb_ini.txt @@ -0,0 +1,322 @@ +GAME-SPECIFIC CONFIGURATION FILE GEMRB.INI +****************************************** + +Contents +-------- + - Introduction + - INI File Format + - Options Values Types + - List of Options + + +Introduction +------------ + +gemrb.ini is a file containing game-specific configuration for GemRB +engine. It's used for options with simple value types which are +specific to GemRB and which are not intended to be usually changed by +a user. More complicated configuration data (tables, etc.) are kept in +their own files. User specific configuration is in other file (GemRB.cfg). + +[FIXME: eventually, this file could be searched for in user's config directory too] + +This file's path can be + /gemrb/override//gemrb.ini + /gemrb/override//gemrb.ini + /override//gemrb.ini + + +INI File Format +--------------- + +gemrb.ini file is in Windows *.INI format. That means it's line +oriented, consisting of a list of options, each on its own +line. Options are grouped into sections, each section labeled with +section name in [brackets]. Comments have to be on their own line, they +start with a semicolon (;) and last to the end of the line. + +Options are in this file described in the format optionname = . +For the moment all the options have to be in [resources] section. + + +Options Values Types +-------------------- +These are types of values used in description of particular options. + + resref - resource identifier as defined in KEY file, string of at most + 8 characters. The case is not important, but is usually written in + all upper-case to be easily distinguished. + + string + + rgba_color - hexadecimal RGBA quadruplet written as #rrggbbaa, + e.g. #00ff00ff is opaque bright green. + + number - unsigned integer number + + bool - boolean value, for now either 0 (false) or 1 (true) + + +List of Options +--------------- + +CursorBAM = +- - - - - - - - - - - +Name of bitmap resource with cursor images (e.g. PST: CARET) + +ScrollCursorBAM = +- - - - - - - - - - - - - - +Name of bitmap resource with scroll cursor images (e.g. BG2: CURSARW) + +ButtonFont = +- - - - - - - - - - - +Name of bitmap resource used for button font in dialog windows +(e.g. BG1: STONESML) + +MovieFont = +- - - - - - - - - - - +Name of bitmap resource used for the movie subtitles + +TooltipFont = +- - - - - - - - - - - - +Name of bitmap resource with font used to display tooltips +(e.g. PST: TRMTFONT) + + +TooltipBack = +- - - - - - - - - - - - +Sprite displayed behind the tooltip text, if any. Leave undefined when +tooltips don't use background bitmap. +(e.g. BG1: TOOLTIP) + + +TooltipColor = +- - - - - - - - - - - - - - +Tooltip text color. Default is #ffffffff, i.e. opaque white. + + +TooltipMargin = +- - - - - - - - - - - - - +Space between tooltip text and sides of TooltipBack (x2) + + +GroundCircleBAM1 = +GroundCircleBAM2 = +GroundCircleBAM3 = / +- - - - - - - - - - - - - - - - - +Sprites displayed as a ground circle under actors (PST only). +Actually, there should be this directive for each ground circle +size, from 1 to 3 (sizes in PST). + +If the ResRef is immediately followed by a slash and a number, +the bitmap is scaled down by this factor. That's used in PST, +where resources exist for circle sizes 2 and 3 only. +(e.g. GroundCircleBAM1 = wmpickl/3) + + +INIConfig = +- - - - - - - - - - - - +Name of INI file from the original game. This file is searched for in +the game root directory. + + +Palette16 = +Palette32 = +Palette256 = +- - - - - - - - - - - +Palette bitmap resources for various number of colors in a gradient. +Each pixel line in these files is for one base color. Pixels in the +row then define the gradient of that color. + + +IgnoreButtonFrames = +- - - - - - - - - - - - - - +If set to 1, buttons will ignore frame numbers as set in button CHU +resource, and always use frames 0, 1, 2, 3 from their associated +BAM. (PST, ...) + + +AllStringsTagged = +- - - - - - - - - - - - - +If set to 1, .tlk tokens are always resolved regardless of the token +flag in dialog.tlk. Normally only BG2 has token flags (0), all other +games have this option set to 1. + +HasDPLAYER = +- - - - - - - - - - +If set to 1, then NPCs will get a default player script (DPLAYER2) set +when they join the party. PST has no such feature. + +HasPickSound = +- - - - - - - - - - - +If set to 1, items have a pick up sound resource reference instead of a +description icon. PST has this option. (Mutually exclusive with the +HasDescIcon option). + +HasDescIcon = +- - - - - - - - - - - +If set to 1, items have a description icon, instead of a pick up sound. +BG2 has this option. (Mutually exclusive with the HasPickSound option). + +HasEXPTABLE = +- - - - - - - - - - - +If set to 1, then an exptable.2da file is responsible of storing quest +based experience awards. If the option doesn't exist, then the engine +will use xplist.2da table for a similar feature. AddXP2da and AddXPVar +scripting actions use this option to determine which .2da file to use. +XPList is bg2 specific, while exptable is an iwd2 feature. + +SoundFolders = +- - - - - - - - - - - +If set to 1, then there are separate directories for each player +character soundset. IWD2 specific. + +HasSongList = +- - - - - - - - - - - +If set to 1, then the music files are listed in a songlist.2da file. +Otherwise the music files are listed in a music.2da file. Original +BG1 and PST doesn't have either of these files (the list is hardcoded +into the engine), GemRB supplies a music.2da file for them. + +UpperButtonText = +- - - - - - - - - - - - - +Set to 1 if button labels should be converted to upper-case (e.g. BG2) + + +LowerLabelText = +- - - - - - - - - - - - +Set to 1 if label text should be converted to lower-case. + +HasPartyINI = +- - - - - - - - - - - +If set to 1, then there is a party.ini file describing pre-generated +parties. Normally only IWD2 has this option set. + +HasBeastsINI = +- - - - - - - - - - - +Whether original game data contains beasts.ini and quests.ini files +with descriptions of monsters and quests (PST only). + +ForceStereo = +- - - - - - - - - - - +If set to 1, all acm files will be player as if they are stereo. +Some early .ACM files (PST, IWD1) were encoded with a faulty channel +number, this option overrides the channel number. + +TeamMovement = +- - - - - - - - - - - +If set to 1, the team always moves to the protagonist (first player). +This option is 1 for original PST. + +OneByteAnimationID = +- - - - - - - - - - - - - - +If set to 1, then only the lower byte of the animation ID will be used +to index the avatar.2da table. The upper byte is responsible for various +displaying properties (clown colour, transparency). This option is 1 for +original PST. /warning/ Some other unrelated, but PST specific, features +are also controlled by this flag. One such example is the avatar icon +size in the saved games. If set to 1, then the avatar portrait won't be +shrunk further. Otherwise the saved portrait bmp's will be shrunk 2:1. + +AutomapINI = +- - - - - - - - - - +If set to 1, automap entries will be done PST style. + +SmallFog = +- - - - - - - - - - - +Whether fog-of-war maintained in Map::ExploredBitmap is aligned with +map boundary (SmallFog=1, like in PST) or the fog is half a tile +larger in each of four cardinal directions (SmallFog=0, e.g. in BG2) + +ReverseDoor = +- - - - - - - - - - - +If set to 1, doors will have a reversed open/closed state. PST quirk. + +ProtagonistTalks = +- - - - - - - - - - - - - +If set to 1, only protagonist speaks with stranger for the whole party (PST). + +HasKaputz = +- - - - - - - - - - +If set to 1, then death variables will be in a separate context. +This is PST specific. + +IWDMapDimensions = +- - - - - - - - - - - - - +If set to 1, then the minimap dimensions are using the IWD specific ratio. + +IWD2ScriptName = +- - - - - - - - - - - - +If set to 1, then areas always override the scripting name of the creature. +Normally there is an area flag for this. + +DialogueScrolls = +- - - - - - - - - - - - - +If set to 1, dialogue window behaves as in PS:T - i.e. talk between +Nameless One and others is appended into the window as it comes. If set to +0 (default) each new pair of NPC's talk and Nameless One's replies is +written from the start of the page, like in BG2. + +MaximumAbility = 25|40 +- - - - - - - - - - - - +Determines the maximum value of character abilities. Setting it to absurd +values might cause problems. Its value should be 40 for IWD2, 25 for all +other games. + +StrrefSaveGame = 0|1 +- - - - - - - - - - - +Determines whether the GameScript action SaveGame uses the int0 paramater +to lookup a strref, or to look in savegame.2da for the save game name. + +ReverseToHit = 0|1 +- - - - - - - - - - +Determines whether higher armor class is better (iwd2) or worse (the rest). + +RedrawTile = 0|1 +- - - - - - - - - +Force redraw of some overlay tiles?? + +CheckAbilities = 0|1 +- - - - - - - - - - - +Determines if character abilities should matter in item usability checks. + +SpellBookIconHack = 0|1 +- - - - - - - - - - - - +Enables the spell book icon name hack needed for ToB. + +DeathOnZeroStat = 0|1 +- - - - - - - - - - - +Determines whether characters should die if any of their primary stats +reaches zero. + +BreakableWeapons = 0|1 +- - - - - - - - - - - - +Determines if weapons can randomly break when used (1% chance in bg1). + +SelectiveMagicRes = 0|1 +- - - - - - - - - - - - +Determines whether the magic resistance applies to all effects, even the +beneficial ones. + +HasHideInShadows = 0|1 +- - - - - - - - - - - - +Enable this if the characters also have the IE_HIDEINSHADOWS stat besides +IE_STEALTH. + +ProperBackstab = 0|1 +- - - - - - - - - - - +Determines how many checks the backstabbing code does before treating an +attack as a backstab. + +HasSpecificDamageBonus = 0|1 +- - - - - - - - - - - - - - - +Determines if the game supports specific damage bonus like for example +10% +extra cold damage. + +StealIsAttack = 0|1 +- - - - - - - - - - +Determines whether a detected stealing attempt causes the shopkeep to turn hostile. + +CutsceneAreascripts = 0|1 +- - - - - - - - - - +Determines whether area scripts should run during cutscenes or not. diff --git a/project/jni/application/gemrb/gemrb/includes/diff.txt b/project/jni/application/gemrb/gemrb/includes/diff.txt new file mode 100644 index 000000000..855ec846b --- /dev/null +++ b/project/jni/application/gemrb/gemrb/includes/diff.txt @@ -0,0 +1,20 @@ +diff --git a/gemrb/includes/logging.h b/gemrb/includes/logging.h +index 54a4892..b993955 100644 +--- a/gemrb/includes/logging.h ++++ b/gemrb/includes/logging.h +@@ -30,6 +30,7 @@ + + #ifdef ANDROID + # include ++# include "android_log_printf.h" + #endif + + #ifdef WIN32 +@@ -109,6 +110,7 @@ extern GEM_EXPORT HANDLE hConsole; + # define printStatus(status, color) printBracket(status, color); printf("\n") + # define printMessage(owner, message, color) printBracket(owner, LIGHT_WHITE); printf(": "); textcolor(color); printf("%s", message) + #else ++# define printf android_log_printf + # define printBracket(status, color) + # define printStatus(status, color) __android_log_print(ANDROID_LOG_INFO, "GemRB", "[%s]", status) + # define printMessage(owner, message, color) __android_log_print(ANDROID_LOG_INFO, "GemRB", "%s: %s", owner, message) diff --git a/project/jni/application/gemrb/gemrb/includes/globals.h b/project/jni/application/gemrb/gemrb/includes/globals.h index e4ff5cfef..a34c470ff 100644 --- a/project/jni/application/gemrb/gemrb/includes/globals.h +++ b/project/jni/application/gemrb/gemrb/includes/globals.h @@ -34,7 +34,7 @@ #include "ie_types.h" -#define VERSION_GEMRB "0.6.3-git" +#define VERSION_GEMRB "0.6.4-git" #define GEMRB_STRING "GemRB v" VERSION_GEMRB @@ -147,8 +147,10 @@ #define GF_CASTING_SOUNDS 57 //all except pst and bg1 #define GF_CASTING_SOUNDS2 58 //bg2 #define GF_FORCE_AREA_SCRIPT 59 //how and iwd2 (maybe iwd1) +#define GF_AREA_OVERRIDE 60 //pst maze and other hardcode +#define GF_NO_NEW_VARIABLES 61 //pst //update this or bad things can happen -#define GF_COUNT 60 +#define GF_COUNT 62 //the number of item usage fields (used in CREItem and STOItem) #define CHARGE_COUNTERS 3 @@ -210,8 +212,6 @@ GEM_EXPORT char* strlwr(char* string); } #endif -//struct ActorBlock; - inline int MIN(int a, int b) { return (a > b ? b : a); @@ -224,10 +224,10 @@ inline int MAX(int a, int b) inline bool valid_number(const char* string, long& val) { - char* endpr; + char* endpr; - val = (long) strtoul( string, &endpr, 0 ); - return ( const char * ) endpr != string; + val = (long) strtoul( string, &endpr, 0 ); + return ( const char * ) endpr != string; } //we need 32+6 bytes at least, because we store 'context' in the variable diff --git a/project/jni/application/gemrb/gemrb/includes/ie_stats.h b/project/jni/application/gemrb/gemrb/includes/ie_stats.h index 99e784bd7..fa61ca130 100644 --- a/project/jni/application/gemrb/gemrb/includes/ie_stats.h +++ b/project/jni/application/gemrb/gemrb/includes/ie_stats.h @@ -49,6 +49,7 @@ #define EA_EVILCUTOFF 200 #define EA_EVILBUTGREEN 201 #define EA_EVILBUTBLUE 202 +#define EA_CHARMEDPC 254 #define EA_ENEMY 255 //GENERAL values diff --git a/project/jni/application/gemrb/gemrb/includes/logging.h b/project/jni/application/gemrb/gemrb/includes/logging.h index 3378c5178..b9939551c 100644 --- a/project/jni/application/gemrb/gemrb/includes/logging.h +++ b/project/jni/application/gemrb/gemrb/includes/logging.h @@ -29,71 +29,91 @@ #include "exports.h" #ifdef ANDROID -# include +# include +# include "android_log_printf.h" #endif #ifdef WIN32 -# define ADV_TEXT -# include +# define ADV_TEXT +# include extern GEM_EXPORT HANDLE hConsole; -# define textcolor(i) SetConsoleTextAttribute(hConsole, i) - -# ifndef __MINGW32__ -# define printf cprintf //broken in mingw !! -# endif - -#define BLACK 0 -#define RED FOREGROUND_RED -#define GREEN FOREGROUND_GREEN -#define BROWN FOREGROUND_GREEN | FOREGROUND_RED -#define BLUE FOREGROUND_BLUE -#define MAGENTA FOREGROUND_RED | FOREGROUND_BLUE -#define CYAN FOREGROUND_BLUE | FOREGROUND_GREEN -#define WHITE FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED -#define LIGHT_RED (RED | FOREGROUND_INTENSITY) -#define LIGHT_GREEN (GREEN | FOREGROUND_INTENSITY) -#define YELLOW (GREEN | RED | FOREGROUND_INTENSITY) -#define LIGHT_BLUE (BLUE | FOREGROUND_INTENSITY) -#define LIGHT_MAGENTA (MAGENTA | FOREGROUND_INTENSITY) -#define LIGHT_CYAN (CYAN | FOREGROUND_INTENSITY) -#define LIGHT_WHITE (WHITE | FOREGROUND_INTENSITY) -#define DEFAULT WHITE - +# define textcolor(i) SetConsoleTextAttribute(hConsole, i) +# ifndef __MINGW32__ +# define printf cprintf //broken in mingw !! +# endif #else //WIN32 -# ifndef ANDROID -# include -# endif -# include -# include - -# define textcolor(i) i - -#define DEFAULT printf("\033[0m"); -#define BLACK printf("\033[0m\033[30;40m"); -#define RED printf("\033[0m\033[31;40m"); -#define GREEN printf("\033[0m\033[32;40m"); -#define BROWN printf("\033[0m\033[33;40m"); -#define BLUE printf("\033[0m\033[34;40m"); -#define MAGENTA printf("\033[0m\033[35;40m"); -#define CYAN printf("\033[0m\033[36;40m"); -#define WHITE printf("\033[0m\033[37;40m"); -#define LIGHT_RED printf("\033[1m\033[31;40m"); -#define LIGHT_GREEN printf("\033[1m\033[32;40m"); -#define YELLOW printf("\033[1m\033[33;40m"); -#define LIGHT_BLUE printf("\033[1m\033[34;40m"); -#define LIGHT_MAGENTA printf("\033[1m\033[35;40m"); -#define LIGHT_CYAN printf("\033[1m\033[36;40m"); -#define LIGHT_WHITE printf("\033[1m\033[37;40m"); +# ifndef ANDROID +# include +# endif +# include +# include +# define textcolor(i) i #endif //WIN32 -#ifndef ANDROID -#define printBracket(status, color) textcolor(WHITE); printf("["); textcolor(color); printf("%s", status); textcolor(WHITE); printf("]") -#define printStatus(status, color) printBracket(status, color); printf("\n") -#define printMessage(owner, message, color) printBracket(owner, LIGHT_WHITE); printf(": "); textcolor(color); printf("%s", message) +#ifdef NOCOLOR +# define DEFAULT printf("%s",""); +# define BLACK printf("%s",""); +# define RED printf("%s",""); +# define GREEN printf("%s",""); +# define BROWN printf("%s",""); +# define BLUE printf("%s",""); +# define MAGENTA printf("%s",""); +# define CYAN printf("%s",""); +# define WHITE printf("%s",""); +# define LIGHT_RED printf("%s",""); +# define LIGHT_GREEN printf("%s",""); +# define YELLOW printf("%s",""); +# define LIGHT_BLUE printf("%s",""); +# define LIGHT_MAGENTA printf("%s",""); +# define LIGHT_CYAN printf("%s",""); +# define LIGHT_WHITE printf("%s",""); #else -#define printBracket(status, color) -#define printStatus(status, color) __android_log_print(ANDROID_LOG_INFO, "GemRB", "[%s]", status) -#define printMessage(owner, message, color) __android_log_print(ANDROID_LOG_INFO, "GemRB", "%s: %s", owner, message) +# ifdef WIN32 +# define BLACK 0 +# define RED FOREGROUND_RED +# define GREEN FOREGROUND_GREEN +# define BROWN FOREGROUND_GREEN | FOREGROUND_RED +# define BLUE FOREGROUND_BLUE +# define MAGENTA FOREGROUND_RED | FOREGROUND_BLUE +# define CYAN FOREGROUND_BLUE | FOREGROUND_GREEN +# define WHITE FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED +# define LIGHT_RED (RED | FOREGROUND_INTENSITY) +# define LIGHT_GREEN (GREEN | FOREGROUND_INTENSITY) +# define YELLOW (GREEN | RED | FOREGROUND_INTENSITY) +# define LIGHT_BLUE (BLUE | FOREGROUND_INTENSITY) +# define LIGHT_MAGENTA (MAGENTA | FOREGROUND_INTENSITY) +# define LIGHT_CYAN (CYAN | FOREGROUND_INTENSITY) +# define LIGHT_WHITE (WHITE | FOREGROUND_INTENSITY) +# define DEFAULT WHITE +# else //WIN32 +# define DEFAULT printf("\033[0m"); +# define BLACK printf("\033[0m\033[30;40m"); +# define RED printf("\033[0m\033[31;40m"); +# define GREEN printf("\033[0m\033[32;40m"); +# define BROWN printf("\033[0m\033[33;40m"); +# define BLUE printf("\033[0m\033[34;40m"); +# define MAGENTA printf("\033[0m\033[35;40m"); +# define CYAN printf("\033[0m\033[36;40m"); +# define WHITE printf("\033[0m\033[37;40m"); +# define LIGHT_RED printf("\033[1m\033[31;40m"); +# define LIGHT_GREEN printf("\033[1m\033[32;40m"); +# define YELLOW printf("\033[1m\033[33;40m"); +# define LIGHT_BLUE printf("\033[1m\033[34;40m"); +# define LIGHT_MAGENTA printf("\033[1m\033[35;40m"); +# define LIGHT_CYAN printf("\033[1m\033[36;40m"); +# define LIGHT_WHITE printf("\033[1m\033[37;40m"); +# endif //WIN32 +#endif + +#ifndef ANDROID +# define printBracket(status, color) textcolor(WHITE); printf("["); textcolor(color); printf("%s", status); textcolor(WHITE); printf("]") +# define printStatus(status, color) printBracket(status, color); printf("\n") +# define printMessage(owner, message, color) printBracket(owner, LIGHT_WHITE); printf(": "); textcolor(color); printf("%s", message) +#else +# define printf android_log_printf +# define printBracket(status, color) +# define printStatus(status, color) __android_log_print(ANDROID_LOG_INFO, "GemRB", "[%s]", status) +# define printMessage(owner, message, color) __android_log_print(ANDROID_LOG_INFO, "GemRB", "%s: %s", owner, message) #endif #endif diff --git a/project/jni/application/gemrb/gemrb/plugins/AREImporter/AREImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/AREImporter/AREImporter.cpp index 8d79968f0..45e1a81ad 100644 --- a/project/jni/application/gemrb/gemrb/plugins/AREImporter/AREImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/AREImporter/AREImporter.cpp @@ -36,6 +36,10 @@ #include "ProjectileServer.h" #include "TileMapMgr.h" #include "Video.h" +#include "GameScript/GameScript.h" +#include "Scriptable/Container.h" +#include "Scriptable/Door.h" +#include "Scriptable/InfoPoint.h" #include "System/CachedFileStream.h" #include "System/FileStream.h" @@ -343,6 +347,12 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) // small map is *optional*! ResourceHolder sm(TmpResRef); + //if the Script field is empty, the area name will be copied into it on first load + //this works only in the iwd branch of the games + if (!Script[0] && core->HasFeature(GF_FORCE_AREA_SCRIPT) ) { + memcpy(Script, ResRef, sizeof(ieResRef) ); + } + if (Script[0]) { //for some reason the area's script is run from the last slot //at least one area script depends on this, if you need something @@ -417,7 +427,8 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) ieWord PosX, PosY; ieWord TalkX, TalkY; ieVariable Name, Entrance; - ieResRef Script, DialogResRef, KeyResRef, Destination; + ieResRef Script, KeyResRef, Destination; + ieResRef DialogResRef, WavResRef; //adopted pst specific fields ieStrRef DialogName; str->Read( Name, 32 ); Name[32] = 0; @@ -451,15 +462,11 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) str->ReadWord( &LaunchY ); str->ReadResRef( KeyResRef ); str->ReadResRef( Script ); - //if the Script field is empty, the area name will be copied into it on first load - //this works only in the iwd branch of the games - if (!Script[0] && core->HasFeature(GF_FORCE_AREA_SCRIPT) ) { - memcpy(Script, ResRef, sizeof(ieResRef) ); - } str->ReadWord( &PosX); str->ReadWord( &PosY); //maybe we have to store this - str->Seek( 44, GEM_CURRENT_POS ); + str->Seek( 36, GEM_CURRENT_POS ); + str->ReadResRef( WavResRef ); str->ReadWord( &TalkX); str->ReadWord( &TalkY); str->ReadDword( &DialogName ); @@ -507,6 +514,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) ip->TalkPos.y=TalkY; ip->DialogName=DialogName; ip->SetDialog(DialogResRef); + ip->SetEnter(WavResRef); if (Script[0]) { ip->Scripts[0] = new GameScript( Script, ip ); @@ -995,7 +1003,7 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) str->ReadWord( &anim->sequence ); str->ReadWord( &anim->frame ); str->ReadDword( &anim->Flags ); - str->ReadWord( (ieWord *) &anim->height ); + str->ReadWordSigned( &anim->height ); str->ReadWord( &anim->transparency ); str->ReadWord( &anim->unknown3c ); //not completely understood, if not 0, sequence is started str->Read( &anim->startchance,1 ); @@ -1009,9 +1017,9 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) //set up the animation, it cannot be done here //because a StaticSequence action can change //it later - anim->InitAnimation(); - map->AddAnimation( anim ); + //the animation was safely transferred to internal memory + delete anim; } } @@ -1166,9 +1174,9 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) ieDword TrapEffOffset; ieWord TrapSize, ProID; ieWord X,Y; - ieDword Unknown1; - ieWord Unknown2; - ieByte Unknown3; + ieDword Ticks; + ieWord Unknown; + ieByte PartyID; ieByte Owner; str->Seek( TrapOffset + ( i * 0x1c ), GEM_STREAM_START ); @@ -1177,11 +1185,11 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) str->ReadDword( &TrapEffOffset ); str->ReadWord( &TrapSize ); str->ReadWord( &ProID ); - str->ReadDword( &Unknown1 ); + str->ReadDword( &Ticks ); str->ReadWord( &X ); str->ReadWord( &Y ); - str->ReadWord( &Unknown2 ); - str->Read( &Unknown3,1 ); + str->ReadWord( &Unknown ); + str->Read( &PartyID,1 ); str->Read( &Owner,1 ); int TrapEffectCount = TrapSize/0x108; if(TrapEffectCount*0x108!=TrapSize) { @@ -1200,9 +1208,12 @@ Map* AREImporter::GetMap(const char *ResRef, bool day_or_night) CachedFileStream *fs = new CachedFileStream( (CachedFileStream *) str, TrapEffOffset, TrapSize, true); ReadEffects((DataStream *) fs,fxqueue, TrapEffectCount); - Actor * caster = core->GetGame()->FindPC(Owner); + Actor * caster = core->GetGame()->FindPC(PartyID); pro->SetEffects(fxqueue); - if (caster) pro->SetCaster(caster->GetGlobalID()); + if (caster) { + //FIXME: i don't know the level info + pro->SetCaster(caster->GetGlobalID(), 10); + } Point pos(X,Y); map->AddProjectile( pro, pos, pos); } @@ -1439,7 +1450,9 @@ int AREImporter::PutHeader(DataStream *stream, Map *map) stream->WriteDword( &VariablesOffset ); stream->WriteDword( &VariablesCount ); stream->WriteDword( &tmpDword); - GameScript *s = map->Scripts[0]; + + //the saved area script is in the last script slot! + GameScript *s = map->Scripts[MAX_SCRIPTS-1]; if (s) { stream->WriteResRef( s->GetName() ); } else { @@ -1695,7 +1708,7 @@ int AREImporter::PutRegions( DataStream *stream, Map *map, ieDword &VertIndex) { ieDword tmpDword = 0; ieWord tmpWord; - char filling[56]; + char filling[36]; memset(filling,0,sizeof(filling) ); for (unsigned int i=0;iWriteWord( &tmpWord); tmpWord = (ieWord) ip->UsePoint.y; stream->WriteWord( &tmpWord); - stream->Write( filling, 44); //unknown + stream->Write( filling, 36); //unknown //these are probably only in PST + stream->WriteResRef( ip->EnterWav); tmpWord = (ieWord) ip->TalkPos.x; stream->WriteWord( &tmpWord); tmpWord = (ieWord) ip->TalkPos.y; diff --git a/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/BIKPlayer.cpp b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/BIKPlayer.cpp index aa5228e02..5a7da6e9e 100644 --- a/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/BIKPlayer.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/BIKPlayer.cpp @@ -430,8 +430,8 @@ int BIKPlayer::sound_init(bool need_init) sample_rate *= header.channels; s_frame_len *= header.channels; s_channels = 1; - if (header.channels == 2) - frame_len_bits++; + if (header.channels == 2) + frame_len_bits++; } s_overlap_len = s_frame_len / 16; @@ -460,10 +460,10 @@ int BIKPlayer::sound_init(bool need_init) s_first = 1; for (i = 0; i < s_channels; i++) - s_coeffs_ptr[i] = s_coeffs + i * s_frame_len; + s_coeffs_ptr[i] = s_coeffs + i * s_frame_len; if (header.audioflag&BINK_AUD_USEDCT) - ret = ff_dct_init(&s_trans.dct, frame_len_bits, 0); + ret = ff_dct_init(&s_trans.dct, frame_len_bits, 1); else ret = ff_rdft_init(&s_trans.rdft, frame_len_bits, IRIDFT); @@ -596,18 +596,18 @@ const uint8_t ff_log2_tab[256]={ static inline av_const int av_log2(unsigned int v) { - int n = 0; - if (v & 0xffff0000) { - v >>= 16; - n += 16; - } - if (v & 0xff00) { - v >>= 8; - n += 8; - } - n += ff_log2_tab[v]; + int n = 0; + if (v & 0xffff0000) { + v >>= 16; + n += 16; + } + if (v & 0xff00) { + v >>= 8; + n += 8; + } + n += ff_log2_tab[v]; - return n; + return n; } static inline int float_to_int16_one(const float *src){ @@ -652,12 +652,12 @@ void BIKPlayer::DecodeBlock(short *out) for (ch = 0; ch < s_channels; ch++) { FFTSample *coeffs = s_coeffs_ptr[ch]; q = 0.0; - coeffs[0] = s_gb.get_float(); - coeffs[1] = s_gb.get_float(); + coeffs[0] = s_gb.get_float() * s_root; + coeffs[1] = s_gb.get_float() * s_root; for (i = 0; i < s_num_bands; i++) { int value = s_gb.get_bits(8); - quant[i] = (float) pow(10.0, FFMIN(value, 95) * 0.066399999); + quant[i] = (float) pow(10.0, FFMIN(value, 95) * 0.066399999) * s_root; } // find band (k) @@ -701,13 +701,13 @@ void BIKPlayer::DecodeBlock(short *out) } } - if (header.audioflag&BINK_AUD_USEDCT) + if (header.audioflag&BINK_AUD_USEDCT) { + coeffs[0] /= 0.5; ff_dct_calc (&s_trans.dct, coeffs); - else + for (i = 0; i < s_frame_len; i++) + coeffs[i] *= s_frame_len / 2; + } else ff_rdft_calc(&s_trans.rdft, coeffs); - - for (i = 0; i < s_frame_len; i++) - coeffs[i] *= s_root; } ff_float_to_int16_interleave_c(out, (const float **)s_coeffs_ptr, s_frame_len, s_channels); @@ -767,11 +767,15 @@ int BIKPlayer::DecodeAudioFrame(void *data, int data_size) * @param scan scan order table * @return 0 for success, negative value in other cases */ -int BIKPlayer::read_dct_coeffs(DCTELEM block[64], const uint8_t *scan) +int BIKPlayer::read_dct_coeffs(DCTELEM block[64], const uint8_t *scan, bool is_intra) { int mode_list[128]; int i, t, mask, bits, ccoef, mode; int list_start = 64, list_end = 64, list_pos; + int coef_count = 0; + int coef_idx[64]; + int quant_idx; + const uint32_t* quant; mode_list[list_end++] = ( 4 << 2) | 0; mode_list[list_end++] = (24 << 2) | 0; @@ -812,6 +816,7 @@ int BIKPlayer::read_dct_coeffs(DCTELEM block[64], const uint8_t *scan) } } block[scan[ccoef]] = t; + coef_idx[coef_count++] = ccoef; } } break; @@ -831,12 +836,22 @@ int BIKPlayer::read_dct_coeffs(DCTELEM block[64], const uint8_t *scan) t = -t; } block[scan[ccoef]] = t; + coef_idx[coef_count++] = ccoef; mode_list[list_pos++] = 0; break; } } } + quant_idx = v_gb.get_bits(4); + quant = is_intra ? bink_intra_quant[quant_idx] + : bink_inter_quant[quant_idx]; + block[0] = (block[0] * quant[0]) >> 11; + for (i = 0; i < coef_count; i++) { + int idx = coef_idx[i]; + block[scan[idx]] = (block[scan[idx]] * quant[idx]) >> 11; + } + return 0; } @@ -1222,39 +1237,39 @@ static void get_pixels(DCTELEM *block, const uint8_t *pixels, int line_size) static void put_pixels_nonclamped(const DCTELEM *block, uint8_t *pixels, int line_size) { - int i; - /* read the pixels */ - for(i=0;i<8;i++) { - pixels[0] = block[0]; - pixels[1] = block[1]; - pixels[2] = block[2]; - pixels[3] = block[3]; - pixels[4] = block[4]; - pixels[5] = block[5]; - pixels[6] = block[6]; - pixels[7] = block[7]; - pixels += line_size; - block += 8; - } + int i; + /* read the pixels */ + for(i=0;i<8;i++) { + pixels[0] = block[0]; + pixels[1] = block[1]; + pixels[2] = block[2]; + pixels[3] = block[3]; + pixels[4] = block[4]; + pixels[5] = block[5]; + pixels[6] = block[6]; + pixels[7] = block[7]; + pixels += line_size; + block += 8; + } } static void add_pixels_nonclamped(const DCTELEM *block, uint8_t *pixels, int line_size) { - int i; + int i; - /* read the pixels */ - for(i=0;i<8;i++) { - pixels[0] += block[0]; - pixels[1] += block[1]; - pixels[2] += block[2]; - pixels[3] += block[3]; - pixels[4] += block[4]; - pixels[5] += block[5]; - pixels[6] += block[6]; - pixels[7] += block[7]; - pixels += line_size; - block += 8; - } + /* read the pixels */ + for(i=0;i<8;i++) { + pixels[0] += block[0]; + pixels[1] += block[1]; + pixels[2] += block[2]; + pixels[3] += block[3]; + pixels[4] += block[4]; + pixels[5] += block[5]; + pixels[6] += block[6]; + pixels[7] += block[7]; + pixels += line_size; + block += 8; + } } static inline void copy_block(DCTELEM block[64], const uint8_t *src, uint8_t *dst, int stride) @@ -1268,78 +1283,78 @@ static inline void copy_block(DCTELEM block[64], const uint8_t *src, uint8_t *ds //This replaces the j_rev_dct module void bink_idct(DCTELEM *block) { - int i, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, tA, tB, tC; - int tblock[64]; + int i, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, tA, tB, tC; + int tblock[64]; - for (i = 0; i < 8; i++) { - t0 = block[i+ 0] + block[i+32]; - t1 = block[i+ 0] - block[i+32]; - t2 = block[i+16] + block[i+48]; - t3 = block[i+16] - block[i+48]; - t3 = ((t3 * 0xB50) >> 11) - t2; + for (i = 0; i < 8; i++) { + t0 = block[i+ 0] + block[i+32]; + t1 = block[i+ 0] - block[i+32]; + t2 = block[i+16] + block[i+48]; + t3 = block[i+16] - block[i+48]; + t3 = ((t3 * 0xB50) >> 11) - t2; - t4 = t0 - t2; - t5 = t0 + t2; - t6 = t1 + t3; - t7 = t1 - t3; + t4 = t0 - t2; + t5 = t0 + t2; + t6 = t1 + t3; + t7 = t1 - t3; - t0 = block[i+40] + block[i+24]; - t1 = block[i+40] - block[i+24]; - t2 = block[i+ 8] + block[i+56]; - t3 = block[i+ 8] - block[i+56]; + t0 = block[i+40] + block[i+24]; + t1 = block[i+40] - block[i+24]; + t2 = block[i+ 8] + block[i+56]; + t3 = block[i+ 8] - block[i+56]; - t8 = t2 + t0; - t9 = t3 + t1; - t9 = (0xEC8 * t9) >> 11; - tA = ((-0x14E8 * t1) >> 11) + t9 - t8; - tB = t2 - t0; - tB = ((0xB50 * tB) >> 11) - tA; - tC = ((0x8A9 * t3) >> 11) + tB - t9; + t8 = t2 + t0; + t9 = t3 + t1; + t9 = (0xEC8 * t9) >> 11; + tA = ((-0x14E8 * t1) >> 11) + t9 - t8; + tB = t2 - t0; + tB = ((0xB50 * tB) >> 11) - tA; + tC = ((0x8A9 * t3) >> 11) + tB - t9; - tblock[i+ 0] = t5 + t8; - tblock[i+56] = t5 - t8; - tblock[i+ 8] = t6 + tA; - tblock[i+48] = t6 - tA; - tblock[i+16] = t7 + tB; - tblock[i+40] = t7 - tB; - tblock[i+32] = t4 + tC; - tblock[i+24] = t4 - tC; - } + tblock[i+ 0] = t5 + t8; + tblock[i+56] = t5 - t8; + tblock[i+ 8] = t6 + tA; + tblock[i+48] = t6 - tA; + tblock[i+16] = t7 + tB; + tblock[i+40] = t7 - tB; + tblock[i+32] = t4 + tC; + tblock[i+24] = t4 - tC; + } - for (i = 0; i < 64; i += 8) { - t0 = tblock[i+0] + tblock[i+4]; - t1 = tblock[i+0] - tblock[i+4]; - t2 = tblock[i+2] + tblock[i+6]; - t3 = tblock[i+2] - tblock[i+6]; - t3 = ((t3 * 0xB50) >> 11) - t2; + for (i = 0; i < 64; i += 8) { + t0 = tblock[i+0] + tblock[i+4]; + t1 = tblock[i+0] - tblock[i+4]; + t2 = tblock[i+2] + tblock[i+6]; + t3 = tblock[i+2] - tblock[i+6]; + t3 = ((t3 * 0xB50) >> 11) - t2; - t4 = t0 - t2; - t5 = t0 + t2; - t6 = t1 + t3; - t7 = t1 - t3; + t4 = t0 - t2; + t5 = t0 + t2; + t6 = t1 + t3; + t7 = t1 - t3; - t0 = tblock[i+5] + tblock[i+3]; - t1 = tblock[i+5] - tblock[i+3]; - t2 = tblock[i+1] + tblock[i+7]; - t3 = tblock[i+1] - tblock[i+7]; + t0 = tblock[i+5] + tblock[i+3]; + t1 = tblock[i+5] - tblock[i+3]; + t2 = tblock[i+1] + tblock[i+7]; + t3 = tblock[i+1] - tblock[i+7]; - t8 = t2 + t0; - t9 = t3 + t1; - t9 = (0xEC8 * t9) >> 11; - tA = ((-0x14E8 * t1) >> 11) + t9 - t8; - tB = t2 - t0; - tB = ((0xB50 * tB) >> 11) - tA; - tC = ((0x8A9 * t3) >> 11) + tB - t9; + t8 = t2 + t0; + t9 = t3 + t1; + t9 = (0xEC8 * t9) >> 11; + tA = ((-0x14E8 * t1) >> 11) + t9 - t8; + tB = t2 - t0; + tB = ((0xB50 * tB) >> 11) - tA; + tC = ((0x8A9 * t3) >> 11) + tB - t9; - block[i+0] = (t5 + t8 + 0x7F) >> 8; - block[i+7] = (t5 - t8 + 0x7F) >> 8; - block[i+1] = (t6 + tA + 0x7F) >> 8; - block[i+6] = (t6 - tA + 0x7F) >> 8; - block[i+2] = (t7 + tB + 0x7F) >> 8; - block[i+5] = (t7 - tB + 0x7F) >> 8; - block[i+4] = (t4 + tC + 0x7F) >> 8; - block[i+3] = (t4 - tC + 0x7F) >> 8; - } + block[i+0] = (t5 + t8 + 0x7F) >> 8; + block[i+7] = (t5 - t8 + 0x7F) >> 8; + block[i+1] = (t6 + tA + 0x7F) >> 8; + block[i+6] = (t6 - tA + 0x7F) >> 8; + block[i+2] = (t7 + tB + 0x7F) >> 8; + block[i+5] = (t7 - tB + 0x7F) >> 8; + block[i+4] = (t4 + tC + 0x7F) >> 8; + block[i+3] = (t4 - tC + 0x7F) >> 8; + } } static void idct_put(uint8_t *dest, int line_size, DCTELEM *block) @@ -1361,7 +1376,6 @@ int BIKPlayer::DecodeVideoFrame(void *data, int data_size) uint8_t *dst, *prev; int v, c1, c2; const uint8_t *scan; - const uint32_t *quant; int xoff, yoff; #pragma pack(push,16) DCTELEM block[64]; @@ -1457,11 +1471,7 @@ int BIKPlayer::DecodeVideoFrame(void *data, int data_size) case INTRA_BLOCK: clear_block(block); block[0] = get_value(BINK_SRC_INTRA_DC); - read_dct_coeffs(block, c_scantable.permutated); - quant = bink_intra_quant[v_gb.get_bits(4)]; - for (i = 0; i < 64; i++) { - block[i] = (block[i] * quant[i]) >> 11; - } + read_dct_coeffs(block, c_scantable.permutated,true); bink_idct(block); for (j = 0; j < 8; j++) { for (i = 0; i < 8; i++) { @@ -1481,7 +1491,7 @@ int BIKPlayer::DecodeVideoFrame(void *data, int data_size) for (i = 0; i < 8; i++) { v = get_value(BINK_SRC_PATTERN); for (j = 0; j < 8; j++, v >>= 1) { - PUT2x2(dst, stride, i, j, (v & 1) ? c2 : c1); + PUT2x2(dst, stride, j, i, (v & 1) ? c2 : c1); } } break; @@ -1541,11 +1551,7 @@ int BIKPlayer::DecodeVideoFrame(void *data, int data_size) case INTRA_BLOCK: clear_block(block); block[0] = get_value(BINK_SRC_INTRA_DC); - read_dct_coeffs(block, c_scantable.permutated); - quant = bink_intra_quant[v_gb.get_bits(4)]; - for (i = 0; i < 64; i++) { - block[i] = (block[i] * quant[i]) >> 11; - } + read_dct_coeffs(block, c_scantable.permutated,true); idct_put(dst, stride, block); break; case FILL_BLOCK: @@ -1560,11 +1566,7 @@ int BIKPlayer::DecodeVideoFrame(void *data, int data_size) copy_block(block, prev + xoff + yoff*stride, dst, stride); clear_block(block); block[0] = get_value(BINK_SRC_INTER_DC); - read_dct_coeffs(block, c_scantable.permutated); - quant = bink_inter_quant[v_gb.get_bits(4)]; - for (i = 0; i < 64; i++) { - block[i] = (block[i] * quant[i]) >> 11; - } + read_dct_coeffs(block, c_scantable.permutated,false); idct_add(dst, stride, block); break; case PATTERN_BLOCK: @@ -1573,7 +1575,7 @@ int BIKPlayer::DecodeVideoFrame(void *data, int data_size) for (i = 0; i < 8; i++) { v = get_value(BINK_SRC_PATTERN); for (j = 0; j < 8; j++, v >>= 1) { - dst[i + j*stride] = (v & 1) ? c2 : c1; + dst[i*stride+j] = (v & 1) ? c2 : c1; } } break; diff --git a/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/BIKPlayer.h b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/BIKPlayer.h index 628d282e8..baba42501 100644 --- a/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/BIKPlayer.h +++ b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/BIKPlayer.h @@ -194,7 +194,7 @@ private: long timer_last_sec; long timer_last_usec; unsigned int frame_wait; - bool video_rendered_frame; + bool video_rendered_frame; unsigned int video_frameskip; bool done; int outputwidth, outputheight; @@ -234,7 +234,7 @@ private: void DecodeBlock(short *out); int DecodeAudioFrame(void *data, int data_size); inline int get_value(int bundle); - int read_dct_coeffs(DCTELEM block[64], const uint8_t *scan); + int read_dct_coeffs(DCTELEM block[64], const uint8_t *scan, bool is_intra); int read_residue(DCTELEM block[64], int masks_count); int read_runs(Bundle *b); int read_motion_values(Bundle *b); diff --git a/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/binkdata.h b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/binkdata.h index 984400804..f9013c8bd 100644 --- a/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/binkdata.h +++ b/project/jni/application/gemrb/gemrb/plugins/BIKPlayer/binkdata.h @@ -285,328 +285,329 @@ static const uint8_t bink_patterns[16][64] = { static const uint32_t bink_intra_quant[16][64] = { { - 0x00010000, 0x00016315, 0x00014E7B, 0x00016577, 0x00010000, 0x0000EEDA, 0x0000BE80, 0x0000611E, - 0x0001E83D, 0x0002A535, 0x0002F1E6, 0x0002724C, 0x00024102, 0x00017F9B, 0x0001083C, 0x0000A552, - 0x0002346F, 0x00030EE5, 0x0002C628, 0x00027F20, 0x00021F88, 0x0001DC53, 0x00014819, 0x0000A743, - 0x0001FBFA, 0x0002C096, 0x000297B5, 0x00023F32, 0x00027FAD, 0x0001F697, 0x00015A31, 0x00009688, - 0x0001D000, 0x00028396, 0x0002346F, 0x0001FBFA, 0x00025000, 0x0001AB6B, 0x00012669, 0x00008D43, - 0x00019247, 0x0001F9AA, 0x0001DC53, 0x000231B8, 0x0001D122, 0x000159B3, 0x0000EE1F, 0x000075ED, - 0x00012F12, 0x0001E06C, 0x0001C48C, 0x00019748, 0x0001490C, 0x00010288, 0x0000E0F1, 0x000072AD, - 0x0000CB10, 0x000119A8, 0x00014E86, 0x000122AF, 0x0000F735, 0x0000EF51, 0x0000A4D8, 0x00006517, + 0x010000, 0x016315, 0x01E83D, 0x02A535, 0x014E7B, 0x016577, 0x02F1E6, 0x02724C, + 0x010000, 0x00EEDA, 0x024102, 0x017F9B, 0x00BE80, 0x00611E, 0x01083C, 0x00A552, + 0x021F88, 0x01DC53, 0x027FAD, 0x01F697, 0x014819, 0x00A743, 0x015A31, 0x009688, + 0x02346F, 0x030EE5, 0x01FBFA, 0x02C096, 0x01D000, 0x028396, 0x019247, 0x01F9AA, + 0x02346F, 0x01FBFA, 0x01DC53, 0x0231B8, 0x012F12, 0x01E06C, 0x00CB10, 0x0119A8, + 0x01C48C, 0x019748, 0x014E86, 0x0122AF, 0x02C628, 0x027F20, 0x0297B5, 0x023F32, + 0x025000, 0x01AB6B, 0x01D122, 0x0159B3, 0x012669, 0x008D43, 0x00EE1F, 0x0075ED, + 0x01490C, 0x010288, 0x00F735, 0x00EF51, 0x00E0F1, 0x0072AD, 0x00A4D8, 0x006517, }, { - 0x00015555, 0x0001D971, 0x0001BDF9, 0x0001DC9F, 0x00015555, 0x00013E78, 0x0000FE00, 0x0000817D, - 0x00028AFC, 0x000386F1, 0x0003ED33, 0x00034311, 0x00030158, 0x0001FF7A, 0x0001604F, 0x0000DC6D, - 0x0002F095, 0x000413DC, 0x0003B2E0, 0x0003542A, 0x0002D4B5, 0x00027B19, 0x0001B577, 0x0000DF04, - 0x0002A54E, 0x0003AB73, 0x000374F1, 0x0002FEEE, 0x000354E7, 0x00029E1F, 0x0001CD96, 0x0000C8B6, - 0x00026AAB, 0x00035A1E, 0x0002F095, 0x0002A54E, 0x00031555, 0x000239E4, 0x0001888C, 0x0000BC59, - 0x0002185E, 0x0002A238, 0x00027B19, 0x0002ECF5, 0x00026C2D, 0x0001CCEE, 0x00013D7E, 0x00009D3C, - 0x00019418, 0x00028090, 0x00025B66, 0x00021F0B, 0x0001B6BB, 0x000158B5, 0x00012BEC, 0x000098E6, - 0x00010EC0, 0x0001778A, 0x0001BE09, 0x00018394, 0x0001499C, 0x00013F17, 0x0000DBCB, 0x000086C9, + 0x015555, 0x01D971, 0x028AFC, 0x0386F1, 0x01BDF9, 0x01DC9F, 0x03ED33, 0x034311, + 0x015555, 0x013E78, 0x030158, 0x01FF7A, 0x00FE00, 0x00817D, 0x01604F, 0x00DC6D, + 0x02D4B5, 0x027B19, 0x0354E7, 0x029E1F, 0x01B577, 0x00DF04, 0x01CD96, 0x00C8B6, + 0x02F095, 0x0413DC, 0x02A54E, 0x03AB73, 0x026AAB, 0x035A1E, 0x02185E, 0x02A238, + 0x02F095, 0x02A54E, 0x027B19, 0x02ECF5, 0x019418, 0x028090, 0x010EC0, 0x01778A, + 0x025B66, 0x021F0B, 0x01BE09, 0x018394, 0x03B2E0, 0x03542A, 0x0374F1, 0x02FEEE, + 0x031555, 0x0239E4, 0x026C2D, 0x01CCEE, 0x01888C, 0x00BC59, 0x013D7E, 0x009D3C, + 0x01B6BB, 0x0158B5, 0x01499C, 0x013F17, 0x012BEC, 0x0098E6, 0x00DBCB, 0x0086C9, }, { - 0x0001AAAB, 0x00024FCE, 0x00022D78, 0x000253C7, 0x0001AAAB, 0x00018E16, 0x00013D80, 0x0000A1DC, - 0x00032DBB, 0x000468AD, 0x0004E87F, 0x000413D5, 0x0003C1AE, 0x00027F58, 0x0001B863, 0x00011388, - 0x0003ACBA, 0x000518D3, 0x00049F98, 0x00042935, 0x000389E2, 0x000319DF, 0x000222D4, 0x000116C5, - 0x00034EA1, 0x0004964F, 0x0004522D, 0x0003BEA9, 0x00042A21, 0x000345A7, 0x000240FC, 0x0000FAE3, - 0x00030555, 0x000430A5, 0x0003ACBA, 0x00034EA1, 0x0003DAAB, 0x0002C85D, 0x0001EAAF, 0x0000EB6F, - 0x00029E76, 0x00034AC5, 0x000319DF, 0x0003A833, 0x00030738, 0x0002402A, 0x00018CDE, 0x0000C48A, - 0x0001F91E, 0x000320B4, 0x0002F23F, 0x0002A6CE, 0x00022469, 0x0001AEE2, 0x000176E7, 0x0000BF20, - 0x00015270, 0x0001D56D, 0x00022D8B, 0x0001E479, 0x00019C02, 0x00018EDD, 0x000112BE, 0x0000A87B, + 0x01AAAB, 0x024FCE, 0x032DBB, 0x0468AD, 0x022D78, 0x0253C7, 0x04E87F, 0x0413D5, + 0x01AAAB, 0x018E16, 0x03C1AE, 0x027F58, 0x013D80, 0x00A1DC, 0x01B863, 0x011388, + 0x0389E2, 0x0319DF, 0x042A21, 0x0345A7, 0x0222D4, 0x0116C5, 0x0240FC, 0x00FAE3, + 0x03ACBA, 0x0518D3, 0x034EA1, 0x04964F, 0x030555, 0x0430A5, 0x029E76, 0x034AC5, + 0x03ACBA, 0x034EA1, 0x0319DF, 0x03A833, 0x01F91E, 0x0320B4, 0x015270, 0x01D56D, + 0x02F23F, 0x02A6CE, 0x022D8B, 0x01E479, 0x049F98, 0x042935, 0x04522D, 0x03BEA9, + 0x03DAAB, 0x02C85D, 0x030738, 0x02402A, 0x01EAAF, 0x00EB6F, 0x018CDE, 0x00C48A, + 0x022469, 0x01AEE2, 0x019C02, 0x018EDD, 0x0176E7, 0x00BF20, 0x0112BE, 0x00A87B, }, { - 0x00020000, 0x0002C62A, 0x00029CF6, 0x0002CAEF, 0x00020000, 0x0001DDB4, 0x00017D01, 0x0000C23C, - 0x0003D07A, 0x00054A69, 0x0005E3CC, 0x0004E499, 0x00048204, 0x0002FF36, 0x00021077, 0x00014AA3, - 0x000468DF, 0x00061DCA, 0x00058C50, 0x0004FE3F, 0x00043F0F, 0x0003B8A6, 0x00029032, 0x00014E86, - 0x0003F7F5, 0x0005812C, 0x00052F69, 0x00047E65, 0x0004FF5A, 0x0003ED2E, 0x0002B461, 0x00012D11, - 0x0003A000, 0x0005072C, 0x000468DF, 0x0003F7F5, 0x0004A000, 0x000356D6, 0x00024CD2, 0x00011A85, - 0x0003248D, 0x0003F353, 0x0003B8A6, 0x00046370, 0x0003A243, 0x0002B365, 0x0001DC3E, 0x0000EBD9, - 0x00025E24, 0x0003C0D8, 0x00038919, 0x00032E91, 0x00029218, 0x00020510, 0x0001C1E2, 0x0000E559, - 0x00019620, 0x0002334F, 0x00029D0D, 0x0002455E, 0x0001EE69, 0x0001DEA2, 0x000149B0, 0x0000CA2D, + 0x020000, 0x02C62A, 0x03D07A, 0x054A69, 0x029CF6, 0x02CAEF, 0x05E3CC, 0x04E499, + 0x020000, 0x01DDB4, 0x048204, 0x02FF36, 0x017D01, 0x00C23C, 0x021077, 0x014AA3, + 0x043F0F, 0x03B8A6, 0x04FF5A, 0x03ED2E, 0x029032, 0x014E86, 0x02B461, 0x012D11, + 0x0468DF, 0x061DCA, 0x03F7F5, 0x05812C, 0x03A000, 0x05072C, 0x03248D, 0x03F353, + 0x0468DF, 0x03F7F5, 0x03B8A6, 0x046370, 0x025E24, 0x03C0D8, 0x019620, 0x02334F, + 0x038919, 0x032E91, 0x029D0D, 0x02455E, 0x058C50, 0x04FE3F, 0x052F69, 0x047E65, + 0x04A000, 0x0356D6, 0x03A243, 0x02B365, 0x024CD2, 0x011A85, 0x01DC3E, 0x00EBD9, + 0x029218, 0x020510, 0x01EE69, 0x01DEA2, 0x01C1E2, 0x00E559, 0x0149B0, 0x00CA2D, }, { - 0x0002AAAB, 0x0003B2E3, 0x00037BF2, 0x0003B93E, 0x0002AAAB, 0x00027CF0, 0x0001FC01, 0x000102FA, - 0x000515F8, 0x00070DE2, 0x0007DA65, 0x00068621, 0x000602B1, 0x0003FEF3, 0x0002C09F, 0x0001B8DA, - 0x0005E129, 0x000827B8, 0x000765C0, 0x0006A855, 0x0005A96A, 0x0004F632, 0x00036AED, 0x0001BE09, - 0x00054A9C, 0x000756E5, 0x0006E9E2, 0x0005FDDB, 0x0006A9CE, 0x00053C3E, 0x00039B2D, 0x0001916B, - 0x0004D555, 0x0006B43B, 0x0005E129, 0x00054A9C, 0x00062AAB, 0x000473C8, 0x00031118, 0x000178B2, - 0x000430BC, 0x0005446F, 0x0004F632, 0x0005D9EB, 0x0004D85A, 0x000399DC, 0x00027AFD, 0x00013A77, - 0x00032830, 0x00050121, 0x0004B6CC, 0x00043E16, 0x00036D76, 0x0002B16A, 0x000257D8, 0x000131CC, - 0x00021D80, 0x0002EF14, 0x00037C11, 0x00030728, 0x00029337, 0x00027E2E, 0x0001B796, 0x00010D91, + 0x02AAAB, 0x03B2E3, 0x0515F8, 0x070DE2, 0x037BF2, 0x03B93E, 0x07DA65, 0x068621, + 0x02AAAB, 0x027CF0, 0x0602B1, 0x03FEF3, 0x01FC01, 0x0102FA, 0x02C09F, 0x01B8DA, + 0x05A96A, 0x04F632, 0x06A9CE, 0x053C3E, 0x036AED, 0x01BE09, 0x039B2D, 0x01916B, + 0x05E129, 0x0827B8, 0x054A9C, 0x0756E5, 0x04D555, 0x06B43B, 0x0430BC, 0x05446F, + 0x05E129, 0x054A9C, 0x04F632, 0x05D9EB, 0x032830, 0x050121, 0x021D80, 0x02EF14, + 0x04B6CC, 0x043E16, 0x037C11, 0x030728, 0x0765C0, 0x06A855, 0x06E9E2, 0x05FDDB, + 0x062AAB, 0x0473C8, 0x04D85A, 0x0399DC, 0x031118, 0x0178B2, 0x027AFD, 0x013A77, + 0x036D76, 0x02B16A, 0x029337, 0x027E2E, 0x0257D8, 0x0131CC, 0x01B796, 0x010D91, }, { - 0x00038000, 0x0004DACA, 0x000492AE, 0x0004E322, 0x00038000, 0x000343FB, 0x00029AC1, 0x000153E8, - 0x0006ACD5, 0x00094238, 0x000A4EA5, 0x0008900C, 0x0007E388, 0x00053E9F, 0x00039CD0, 0x0002429E, - 0x0007B786, 0x000AB421, 0x0009B58C, 0x0008BCEF, 0x00076E5B, 0x00068322, 0x00047C57, 0x0002496B, - 0x0006F1ED, 0x0009A20D, 0x000912F8, 0x0007DD30, 0x0008BEDE, 0x0006DF11, 0x0004BBAB, 0x00020EDD, - 0x00065800, 0x0008CC8E, 0x0007B786, 0x0006F1ED, 0x00081800, 0x0005D7F7, 0x00040670, 0x0001EE69, - 0x00057FF7, 0x0006E9D2, 0x00068322, 0x0007AE04, 0x00065BF6, 0x0004B9F1, 0x0003416C, 0x00019CBC, - 0x000424BF, 0x0006917B, 0x00062FEB, 0x0005917D, 0x00047FAA, 0x000388DC, 0x0003134C, 0x0001915C, - 0x0002C6B8, 0x0003D9CB, 0x000492D7, 0x0003F964, 0x00036138, 0x0003459C, 0x000240F5, 0x000161CF, + 0x038000, 0x04DACA, 0x06ACD5, 0x094238, 0x0492AE, 0x04E322, 0x0A4EA5, 0x08900C, + 0x038000, 0x0343FB, 0x07E388, 0x053E9F, 0x029AC1, 0x0153E8, 0x039CD0, 0x02429E, + 0x076E5B, 0x068322, 0x08BEDE, 0x06DF11, 0x047C57, 0x02496B, 0x04BBAB, 0x020EDD, + 0x07B786, 0x0AB421, 0x06F1ED, 0x09A20D, 0x065800, 0x08CC8E, 0x057FF7, 0x06E9D2, + 0x07B786, 0x06F1ED, 0x068322, 0x07AE04, 0x0424BF, 0x06917B, 0x02C6B8, 0x03D9CB, + 0x062FEB, 0x05917D, 0x0492D7, 0x03F964, 0x09B58C, 0x08BCEF, 0x0912F8, 0x07DD30, + 0x081800, 0x05D7F7, 0x065BF6, 0x04B9F1, 0x040670, 0x01EE69, 0x03416C, 0x019CBC, + 0x047FAA, 0x0388DC, 0x036138, 0x03459C, 0x03134C, 0x01915C, 0x0240F5, 0x0161CF, }, { - 0x00040000, 0x00058C54, 0x000539EC, 0x000595DD, 0x00040000, 0x0003BB68, 0x0002FA01, 0x00018477, - 0x0007A0F4, 0x000A94D3, 0x000BC798, 0x0009C932, 0x00090409, 0x0005FE6D, 0x000420EE, 0x00029547, - 0x0008D1BE, 0x000C3B94, 0x000B18A0, 0x0009FC7F, 0x00087E1F, 0x0007714C, 0x00052064, 0x00029D0D, - 0x0007EFEA, 0x000B0258, 0x000A5ED3, 0x0008FCC9, 0x0009FEB5, 0x0007DA5D, 0x000568C3, 0x00025A21, - 0x00074000, 0x000A0E59, 0x0008D1BE, 0x0007EFEA, 0x00094000, 0x0006ADAC, 0x000499A5, 0x0002350B, - 0x0006491A, 0x0007E6A7, 0x0007714C, 0x0008C6E0, 0x00074487, 0x000566CA, 0x0003B87B, 0x0001D7B3, - 0x0004BC48, 0x000781B1, 0x00071232, 0x00065D22, 0x00052430, 0x00040A20, 0x000383C5, 0x0001CAB3, - 0x00032C3F, 0x0004669F, 0x00053A1A, 0x00048ABC, 0x0003DCD3, 0x0003BD45, 0x00029361, 0x0001945A, + 0x040000, 0x058C54, 0x07A0F4, 0x0A94D3, 0x0539EC, 0x0595DD, 0x0BC798, 0x09C932, + 0x040000, 0x03BB68, 0x090409, 0x05FE6D, 0x02FA01, 0x018477, 0x0420EE, 0x029547, + 0x087E1F, 0x07714C, 0x09FEB5, 0x07DA5D, 0x052064, 0x029D0D, 0x0568C3, 0x025A21, + 0x08D1BE, 0x0C3B94, 0x07EFEA, 0x0B0258, 0x074000, 0x0A0E59, 0x06491A, 0x07E6A7, + 0x08D1BE, 0x07EFEA, 0x07714C, 0x08C6E0, 0x04BC48, 0x0781B1, 0x032C3F, 0x04669F, + 0x071232, 0x065D22, 0x053A1A, 0x048ABC, 0x0B18A0, 0x09FC7F, 0x0A5ED3, 0x08FCC9, + 0x094000, 0x06ADAC, 0x074487, 0x0566CA, 0x0499A5, 0x02350B, 0x03B87B, 0x01D7B3, + 0x052430, 0x040A20, 0x03DCD3, 0x03BD45, 0x0383C5, 0x01CAB3, 0x029361, 0x01945A, }, { - 0x00050000, 0x0006EF69, 0x00068867, 0x0006FB55, 0x00050000, 0x0004AA42, 0x0003B881, 0x0001E595, - 0x00098931, 0x000D3A07, 0x000EB97E, 0x000C3B7E, 0x000B450B, 0x00077E08, 0x0005292A, 0x00033A99, - 0x000B062D, 0x000F4A78, 0x000DDEC8, 0x000C7B9F, 0x000A9DA7, 0x00094D9F, 0x0006687D, 0x00034450, - 0x0009EBE4, 0x000DC2EE, 0x000CF687, 0x000B3BFB, 0x000C7E62, 0x0009D0F4, 0x0006C2F4, 0x0002F0AA, - 0x00091000, 0x000C91EF, 0x000B062D, 0x0009EBE4, 0x000B9000, 0x00085917, 0x0005C00E, 0x0002C24D, - 0x0007DB61, 0x0009E050, 0x00094D9F, 0x000AF898, 0x000915A8, 0x0006C07D, 0x0004A69A, 0x00024D9F, - 0x0005EB59, 0x0009621D, 0x0008D6BE, 0x0007F46A, 0x00066D3C, 0x00050CA7, 0x000464B6, 0x00023D5F, - 0x0003F74F, 0x00058046, 0x000688A0, 0x0005AD6B, 0x0004D407, 0x0004AC96, 0x00033839, 0x0001F971, + 0x050000, 0x06EF69, 0x098931, 0x0D3A07, 0x068867, 0x06FB55, 0x0EB97E, 0x0C3B7E, + 0x050000, 0x04AA42, 0x0B450B, 0x077E08, 0x03B881, 0x01E595, 0x05292A, 0x033A99, + 0x0A9DA7, 0x094D9F, 0x0C7E62, 0x09D0F4, 0x06687D, 0x034450, 0x06C2F4, 0x02F0AA, + 0x0B062D, 0x0F4A78, 0x09EBE4, 0x0DC2EE, 0x091000, 0x0C91EF, 0x07DB61, 0x09E050, + 0x0B062D, 0x09EBE4, 0x094D9F, 0x0AF898, 0x05EB59, 0x09621D, 0x03F74F, 0x058046, + 0x08D6BE, 0x07F46A, 0x0688A0, 0x05AD6B, 0x0DDEC8, 0x0C7B9F, 0x0CF687, 0x0B3BFB, + 0x0B9000, 0x085917, 0x0915A8, 0x06C07D, 0x05C00E, 0x02C24D, 0x04A69A, 0x024D9F, + 0x066D3C, 0x050CA7, 0x04D407, 0x04AC96, 0x0464B6, 0x023D5F, 0x033839, 0x01F971, }, { - 0x00060000, 0x0008527E, 0x0007D6E1, 0x000860CC, 0x00060000, 0x0005991C, 0x00047702, 0x000246B3, - 0x000B716E, 0x000FDF3C, 0x0011AB63, 0x000EADCB, 0x000D860D, 0x0008FDA3, 0x00063165, 0x0003DFEA, - 0x000D3A9C, 0x0012595D, 0x0010A4F0, 0x000EFABE, 0x000CBD2E, 0x000B29F1, 0x0007B096, 0x0003EB93, - 0x000BE7DF, 0x00108384, 0x000F8E3C, 0x000D7B2E, 0x000EFE0F, 0x000BC78B, 0x00081D24, 0x00038732, - 0x000AE000, 0x000F1585, 0x000D3A9C, 0x000BE7DF, 0x000DE000, 0x000A0482, 0x0006E677, 0x00034F90, - 0x00096DA8, 0x000BD9FA, 0x000B29F1, 0x000D2A50, 0x000AE6CA, 0x00081A2F, 0x000594B9, 0x0002C38C, - 0x00071A6B, 0x000B4289, 0x000A9B4A, 0x00098BB2, 0x0007B649, 0x00060F2F, 0x000545A7, 0x0002B00C, - 0x0004C25F, 0x000699EE, 0x0007D727, 0x0006D01A, 0x0005CB3C, 0x00059BE7, 0x0003DD11, 0x00025E87, + 0x060000, 0x08527E, 0x0B716E, 0x0FDF3C, 0x07D6E1, 0x0860CC, 0x11AB63, 0x0EADCB, + 0x060000, 0x05991C, 0x0D860D, 0x08FDA3, 0x047702, 0x0246B3, 0x063165, 0x03DFEA, + 0x0CBD2E, 0x0B29F1, 0x0EFE0F, 0x0BC78B, 0x07B096, 0x03EB93, 0x081D24, 0x038732, + 0x0D3A9C, 0x12595D, 0x0BE7DF, 0x108384, 0x0AE000, 0x0F1585, 0x096DA8, 0x0BD9FA, + 0x0D3A9C, 0x0BE7DF, 0x0B29F1, 0x0D2A50, 0x071A6B, 0x0B4289, 0x04C25F, 0x0699EE, + 0x0A9B4A, 0x098BB2, 0x07D727, 0x06D01A, 0x10A4F0, 0x0EFABE, 0x0F8E3C, 0x0D7B2E, + 0x0DE000, 0x0A0482, 0x0AE6CA, 0x081A2F, 0x06E677, 0x034F90, 0x0594B9, 0x02C38C, + 0x07B649, 0x060F2F, 0x05CB3C, 0x059BE7, 0x0545A7, 0x02B00C, 0x03DD11, 0x025E87, }, { - 0x00080000, 0x000B18A8, 0x000A73D7, 0x000B2BBB, 0x00080000, 0x000776CF, 0x0005F402, 0x000308EF, - 0x000F41E8, 0x001529A5, 0x00178F2F, 0x00139264, 0x00120812, 0x000BFCD9, 0x000841DC, 0x00052A8E, - 0x0011A37B, 0x00187727, 0x00163140, 0x0013F8FE, 0x0010FC3E, 0x000EE297, 0x000A40C8, 0x00053A1A, - 0x000FDFD4, 0x001604B0, 0x0014BDA5, 0x0011F992, 0x0013FD69, 0x000FB4B9, 0x000AD186, 0x0004B442, - 0x000E8000, 0x00141CB1, 0x0011A37B, 0x000FDFD4, 0x00128000, 0x000D5B58, 0x00093349, 0x00046A15, - 0x000C9235, 0x000FCD4D, 0x000EE297, 0x00118DC0, 0x000E890D, 0x000ACD94, 0x000770F7, 0x0003AF65, - 0x0009788F, 0x000F0362, 0x000E2463, 0x000CBA43, 0x000A4861, 0x0008143F, 0x00070789, 0x00039565, - 0x0006587F, 0x0008CD3D, 0x000A7434, 0x00091577, 0x0007B9A6, 0x00077A89, 0x000526C2, 0x000328B4, + 0x080000, 0x0B18A8, 0x0F41E8, 0x1529A5, 0x0A73D7, 0x0B2BBB, 0x178F2F, 0x139264, + 0x080000, 0x0776CF, 0x120812, 0x0BFCD9, 0x05F402, 0x0308EF, 0x0841DC, 0x052A8E, + 0x10FC3E, 0x0EE297, 0x13FD69, 0x0FB4B9, 0x0A40C8, 0x053A1A, 0x0AD186, 0x04B442, + 0x11A37B, 0x187727, 0x0FDFD4, 0x1604B0, 0x0E8000, 0x141CB1, 0x0C9235, 0x0FCD4D, + 0x11A37B, 0x0FDFD4, 0x0EE297, 0x118DC0, 0x09788F, 0x0F0362, 0x06587F, 0x08CD3D, + 0x0E2463, 0x0CBA43, 0x0A7434, 0x091577, 0x163140, 0x13F8FE, 0x14BDA5, 0x11F992, + 0x128000, 0x0D5B58, 0x0E890D, 0x0ACD94, 0x093349, 0x046A15, 0x0770F7, 0x03AF65, + 0x0A4861, 0x08143F, 0x07B9A6, 0x077A89, 0x070789, 0x039565, 0x0526C2, 0x0328B4, }, { - 0x000C0000, 0x0010A4FD, 0x000FADC3, 0x0010C198, 0x000C0000, 0x000B3237, 0x0008EE03, 0x00048D66, - 0x0016E2DB, 0x001FBE78, 0x002356C7, 0x001D5B96, 0x001B0C1A, 0x0011FB46, 0x000C62CA, 0x0007BFD5, - 0x001A7539, 0x0024B2BB, 0x002149E1, 0x001DF57D, 0x00197A5D, 0x001653E3, 0x000F612C, 0x0007D727, - 0x0017CFBD, 0x00210709, 0x001F1C78, 0x001AF65B, 0x001DFC1E, 0x00178F16, 0x00103A49, 0x00070E64, - 0x0015C000, 0x001E2B0A, 0x001A7539, 0x0017CFBD, 0x001BC000, 0x00140904, 0x000DCCEE, 0x00069F20, - 0x0012DB4F, 0x0017B3F4, 0x001653E3, 0x001A54A0, 0x0015CD94, 0x0010345E, 0x000B2972, 0x00058718, - 0x000E34D7, 0x00168513, 0x00153695, 0x00131765, 0x000F6C91, 0x000C1E5E, 0x000A8B4E, 0x00056018, - 0x000984BE, 0x000D33DC, 0x000FAE4E, 0x000DA033, 0x000B9678, 0x000B37CE, 0x0007BA22, 0x0004BD0E, + 0x0C0000, 0x10A4FD, 0x16E2DB, 0x1FBE78, 0x0FADC3, 0x10C198, 0x2356C7, 0x1D5B96, + 0x0C0000, 0x0B3237, 0x1B0C1A, 0x11FB46, 0x08EE03, 0x048D66, 0x0C62CA, 0x07BFD5, + 0x197A5D, 0x1653E3, 0x1DFC1E, 0x178F16, 0x0F612C, 0x07D727, 0x103A49, 0x070E64, + 0x1A7539, 0x24B2BB, 0x17CFBD, 0x210709, 0x15C000, 0x1E2B0A, 0x12DB4F, 0x17B3F4, + 0x1A7539, 0x17CFBD, 0x1653E3, 0x1A54A0, 0x0E34D7, 0x168513, 0x0984BE, 0x0D33DC, + 0x153695, 0x131765, 0x0FAE4E, 0x0DA033, 0x2149E1, 0x1DF57D, 0x1F1C78, 0x1AF65B, + 0x1BC000, 0x140904, 0x15CD94, 0x10345E, 0x0DCCEE, 0x069F20, 0x0B2972, 0x058718, + 0x0F6C91, 0x0C1E5E, 0x0B9678, 0x0B37CE, 0x0A8B4E, 0x056018, 0x07BA22, 0x04BD0E, }, { - 0x00110000, 0x00179466, 0x0016362A, 0x0017BCED, 0x00110000, 0x000FDC79, 0x000CA685, 0x000672FB, - 0x00206C0C, 0x002CF87F, 0x00321044, 0x00299714, 0x00265125, 0x0019794E, 0x00118BF4, 0x000AFA6D, - 0x00257B66, 0x0033FD33, 0x002F28A9, 0x002A711B, 0x00241804, 0x001FA181, 0x0015C9A9, 0x000B1B77, - 0x0021BBA2, 0x002EC9F7, 0x002C12FF, 0x00263256, 0x002A7A80, 0x0021600A, 0x0016FD3C, 0x0009FF0D, - 0x001ED000, 0x002ABCF9, 0x00257B66, 0x0021BBA2, 0x00275000, 0x001C621B, 0x00138CFB, 0x0009616E, - 0x001AB6B0, 0x00219444, 0x001FA181, 0x00254D38, 0x001EE33C, 0x0016F4DB, 0x000FD00C, 0x0007D4B7, - 0x00142030, 0x001FE730, 0x001E0D52, 0x001B0BCF, 0x0015D9CE, 0x00112B06, 0x000EF004, 0x00079D77, - 0x000D7C0E, 0x0012B423, 0x001636EE, 0x00134D9E, 0x00106A80, 0x000FE464, 0x000AF25B, 0x0006B67F, + 0x110000, 0x179466, 0x206C0C, 0x2CF87F, 0x16362A, 0x17BCED, 0x321044, 0x299714, + 0x110000, 0x0FDC79, 0x265125, 0x19794E, 0x0CA685, 0x0672FB, 0x118BF4, 0x0AFA6D, + 0x241804, 0x1FA181, 0x2A7A80, 0x21600A, 0x15C9A9, 0x0B1B77, 0x16FD3C, 0x09FF0D, + 0x257B66, 0x33FD33, 0x21BBA2, 0x2EC9F7, 0x1ED000, 0x2ABCF9, 0x1AB6B0, 0x219444, + 0x257B66, 0x21BBA2, 0x1FA181, 0x254D38, 0x142030, 0x1FE730, 0x0D7C0E, 0x12B423, + 0x1E0D52, 0x1B0BCF, 0x1636EE, 0x134D9E, 0x2F28A9, 0x2A711B, 0x2C12FF, 0x263256, + 0x275000, 0x1C621B, 0x1EE33C, 0x16F4DB, 0x138CFB, 0x09616E, 0x0FD00C, 0x07D4B7, + 0x15D9CE, 0x112B06, 0x106A80, 0x0FE464, 0x0EF004, 0x079D77, 0x0AF25B, 0x06B67F, }, { - 0x00160000, 0x001E83CF, 0x001CBE90, 0x001EB842, 0x00160000, 0x001486BA, 0x00105F06, 0x00085891, - 0x0029F53D, 0x003A3286, 0x0040C9C2, 0x0035D293, 0x00319630, 0x0020F756, 0x0016B51E, 0x000E3506, - 0x00308193, 0x004347AC, 0x003D0771, 0x0036ECBA, 0x002EB5AA, 0x0028EF20, 0x001C3225, 0x000E5FC7, - 0x002BA786, 0x003C8CE5, 0x00390986, 0x00316E52, 0x0036F8E1, 0x002B30FE, 0x001DC030, 0x000CEFB7, - 0x0027E000, 0x00374EE7, 0x00308193, 0x002BA786, 0x0032E000, 0x0024BB33, 0x00194D09, 0x000C23BB, - 0x00229212, 0x002B7494, 0x0028EF20, 0x003045D0, 0x0027F8E4, 0x001DB557, 0x001476A6, 0x000A2256, - 0x001A0B89, 0x0029494D, 0x0026E410, 0x00230039, 0x001C470A, 0x001637AD, 0x001354B9, 0x0009DAD6, - 0x0011735D, 0x00183469, 0x001CBF8F, 0x0018FB09, 0x00153E87, 0x001490FA, 0x000E2A94, 0x0008AFF0, + 0x160000, 0x1E83CF, 0x29F53D, 0x3A3286, 0x1CBE90, 0x1EB842, 0x40C9C2, 0x35D293, + 0x160000, 0x1486BA, 0x319630, 0x20F756, 0x105F06, 0x085891, 0x16B51E, 0x0E3506, + 0x2EB5AA, 0x28EF20, 0x36F8E1, 0x2B30FE, 0x1C3225, 0x0E5FC7, 0x1DC030, 0x0CEFB7, + 0x308193, 0x4347AC, 0x2BA786, 0x3C8CE5, 0x27E000, 0x374EE7, 0x229212, 0x2B7494, + 0x308193, 0x2BA786, 0x28EF20, 0x3045D0, 0x1A0B89, 0x29494D, 0x11735D, 0x183469, + 0x26E410, 0x230039, 0x1CBF8F, 0x18FB09, 0x3D0771, 0x36ECBA, 0x390986, 0x316E52, + 0x32E000, 0x24BB33, 0x27F8E4, 0x1DB557, 0x194D09, 0x0C23BB, 0x1476A6, 0x0A2256, + 0x1C470A, 0x1637AD, 0x153E87, 0x1490FA, 0x1354B9, 0x09DAD6, 0x0E2A94, 0x08AFF0, }, { - 0x001C0000, 0x0026D64D, 0x00249572, 0x0027190E, 0x001C0000, 0x001A1FD6, 0x0014D607, 0x000A9F44, - 0x003566AA, 0x004A11C2, 0x00527525, 0x0044805E, 0x003F1C3E, 0x0029F4F9, 0x001CE683, 0x001214F0, - 0x003DBC30, 0x0055A109, 0x004DAC61, 0x0045E778, 0x003B72D9, 0x00341911, 0x0023E2BB, 0x00124B5B, - 0x00378F64, 0x004D1069, 0x004897C2, 0x003EE97F, 0x0045F6F0, 0x0036F889, 0x0025DD54, 0x001076E9, - 0x0032C000, 0x0046646C, 0x003DBC30, 0x00378F64, 0x0040C000, 0x002EBFB5, 0x00203380, 0x000F734B, - 0x002BFFB9, 0x00374E8E, 0x00341911, 0x003D7020, 0x0032DFAE, 0x0025CF86, 0x001A0B5F, 0x000CE5E2, - 0x002125F5, 0x00348BD6, 0x00317F5B, 0x002C8BEB, 0x0023FD53, 0x001C46DC, 0x00189A60, 0x000C8AE2, - 0x001635BC, 0x001ECE57, 0x002496B6, 0x001FCB22, 0x001B09C4, 0x001A2CE1, 0x001207A5, 0x000B0E77, + 0x1C0000, 0x26D64D, 0x3566AA, 0x4A11C2, 0x249572, 0x27190E, 0x527525, 0x44805E, + 0x1C0000, 0x1A1FD6, 0x3F1C3E, 0x29F4F9, 0x14D607, 0x0A9F44, 0x1CE683, 0x1214F0, + 0x3B72D9, 0x341911, 0x45F6F0, 0x36F889, 0x23E2BB, 0x124B5B, 0x25DD54, 0x1076E9, + 0x3DBC30, 0x55A109, 0x378F64, 0x4D1069, 0x32C000, 0x46646C, 0x2BFFB9, 0x374E8E, + 0x3DBC30, 0x378F64, 0x341911, 0x3D7020, 0x2125F5, 0x348BD6, 0x1635BC, 0x1ECE57, + 0x317F5B, 0x2C8BEB, 0x2496B6, 0x1FCB22, 0x4DAC61, 0x45E778, 0x4897C2, 0x3EE97F, + 0x40C000, 0x2EBFB5, 0x32DFAE, 0x25CF86, 0x203380, 0x0F734B, 0x1A0B5F, 0x0CE5E2, + 0x23FD53, 0x1C46DC, 0x1B09C4, 0x1A2CE1, 0x189A60, 0x0C8AE2, 0x1207A5, 0x0B0E77, }, { - 0x00220000, 0x002F28CC, 0x002C6C53, 0x002F79DA, 0x00220000, 0x001FB8F1, 0x00194D09, 0x000CE5F7, - 0x0040D818, 0x0059F0FE, 0x00642089, 0x00532E29, 0x004CA24B, 0x0032F29C, 0x002317E8, 0x0015F4DB, - 0x004AF6CC, 0x0067FA67, 0x005E5152, 0x0054E237, 0x00483007, 0x003F4303, 0x002B9351, 0x001636EE, - 0x00437743, 0x005D93EE, 0x005825FE, 0x004C64AD, 0x0054F4FF, 0x0042C014, 0x002DFA79, 0x0013FE1A, - 0x003DA000, 0x005579F1, 0x004AF6CC, 0x00437743, 0x004EA000, 0x0038C437, 0x002719F7, 0x0012C2DB, - 0x00356D61, 0x00432888, 0x003F4303, 0x004A9A70, 0x003DC678, 0x002DE9B5, 0x001FA018, 0x000FA96E, - 0x00284060, 0x003FCE60, 0x003C1AA5, 0x0036179D, 0x002BB39B, 0x0022560C, 0x001DE007, 0x000F3AEE, - 0x001AF81B, 0x00256845, 0x002C6DDD, 0x00269B3C, 0x0020D500, 0x001FC8C8, 0x0015E4B7, 0x000D6CFE, + 0x220000, 0x2F28CC, 0x40D818, 0x59F0FE, 0x2C6C53, 0x2F79DA, 0x642089, 0x532E29, + 0x220000, 0x1FB8F1, 0x4CA24B, 0x32F29C, 0x194D09, 0x0CE5F7, 0x2317E8, 0x15F4DB, + 0x483007, 0x3F4303, 0x54F4FF, 0x42C014, 0x2B9351, 0x1636EE, 0x2DFA79, 0x13FE1A, + 0x4AF6CC, 0x67FA67, 0x437743, 0x5D93EE, 0x3DA000, 0x5579F1, 0x356D61, 0x432888, + 0x4AF6CC, 0x437743, 0x3F4303, 0x4A9A70, 0x284060, 0x3FCE60, 0x1AF81B, 0x256845, + 0x3C1AA5, 0x36179D, 0x2C6DDD, 0x269B3C, 0x5E5152, 0x54E237, 0x5825FE, 0x4C64AD, + 0x4EA000, 0x38C437, 0x3DC678, 0x2DE9B5, 0x2719F7, 0x12C2DB, 0x1FA018, 0x0FA96E, + 0x2BB39B, 0x22560C, 0x20D500, 0x1FC8C8, 0x1DE007, 0x0F3AEE, 0x15E4B7, 0x0D6CFE, }, { - 0x002C0000, 0x003D079E, 0x00397D20, 0x003D7083, 0x002C0000, 0x00290D75, 0x0020BE0C, 0x0010B121, - 0x0053EA79, 0x0074650C, 0x00819383, 0x006BA525, 0x00632C61, 0x0041EEAC, 0x002D6A3B, 0x001C6A0C, - 0x00610326, 0x00868F57, 0x007A0EE2, 0x006DD974, 0x005D6B54, 0x0051DE40, 0x0038644B, 0x001CBF8F, - 0x00574F0B, 0x007919CA, 0x0072130C, 0x0062DCA3, 0x006DF1C2, 0x005661FB, 0x003B8060, 0x0019DF6D, - 0x004FC000, 0x006E9DCE, 0x00610326, 0x00574F0B, 0x0065C000, 0x00497665, 0x00329A12, 0x00184776, - 0x00452423, 0x0056E928, 0x0051DE40, 0x00608BA0, 0x004FF1C9, 0x003B6AAE, 0x0028ED4D, 0x001444AC, - 0x00341713, 0x0052929A, 0x004DC821, 0x00460071, 0x00388E14, 0x002C6F5A, 0x0026A973, 0x0013B5AD, - 0x0022E6BA, 0x003068D2, 0x00397F1E, 0x0031F611, 0x002A7D0F, 0x002921F4, 0x001C5528, 0x00115FDF, -} + 0x2C0000, 0x3D079E, 0x53EA79, 0x74650C, 0x397D20, 0x3D7083, 0x819383, 0x6BA525, + 0x2C0000, 0x290D75, 0x632C61, 0x41EEAC, 0x20BE0C, 0x10B121, 0x2D6A3B, 0x1C6A0C, + 0x5D6B54, 0x51DE40, 0x6DF1C2, 0x5661FB, 0x38644B, 0x1CBF8F, 0x3B8060, 0x19DF6D, + 0x610326, 0x868F57, 0x574F0B, 0x7919CA, 0x4FC000, 0x6E9DCE, 0x452423, 0x56E928, + 0x610326, 0x574F0B, 0x51DE40, 0x608BA0, 0x341713, 0x52929A, 0x22E6BA, 0x3068D2, + 0x4DC821, 0x460071, 0x397F1E, 0x31F611, 0x7A0EE2, 0x6DD974, 0x72130C, 0x62DCA3, + 0x65C000, 0x497665, 0x4FF1C9, 0x3B6AAE, 0x329A12, 0x184776, 0x28ED4D, 0x1444AC, + 0x388E14, 0x2C6F5A, 0x2A7D0F, 0x2921F4, 0x26A973, 0x13B5AD, 0x1C5528, 0x115FDF, +}, }; static const uint32_t bink_inter_quant[16][64] = { { - 0x00010000, 0x00017946, 0x00016363, 0x000152A7, 0x00012000, 0x0000E248, 0x0000A486, 0x000053E0, - 0x0001A5A9, 0x000248DC, 0x000243EC, 0x000209EA, 0x0001BBDA, 0x00015CBC, 0x0000F036, 0x00008095, - 0x0001B701, 0x000260EB, 0x00023D97, 0x00020437, 0x0001B701, 0x00016959, 0x0000F8E7, 0x00007EE4, - 0x00019DE9, 0x00023E1B, 0x00021CCC, 0x0001E6B4, 0x0001B0B9, 0x000153FD, 0x0000EA30, 0x00007763, - 0x00017000, 0x0001FE6E, 0x0001E0D1, 0x0001B0B9, 0x00018000, 0x00012DB5, 0x0000CFD2, 0x00006E5C, - 0x00012DB5, 0x0001A27B, 0x00018A33, 0x0001718D, 0x000146D9, 0x000100CE, 0x0000B0E4, 0x00005A2D, - 0x0000D87A, 0x00014449, 0x00013178, 0x000112EA, 0x0000E9CC, 0x0000B7B1, 0x00008337, 0x000042E5, - 0x00007B9A, 0x0000AB71, 0x0000AD08, 0x00009BB9, 0x0000846F, 0x00006B85, 0x00004A10, 0x00002831, + 0x010000, 0x017946, 0x01A5A9, 0x0248DC, 0x016363, 0x0152A7, 0x0243EC, 0x0209EA, + 0x012000, 0x00E248, 0x01BBDA, 0x015CBC, 0x00A486, 0x0053E0, 0x00F036, 0x008095, + 0x01B701, 0x016959, 0x01B0B9, 0x0153FD, 0x00F8E7, 0x007EE4, 0x00EA30, 0x007763, + 0x01B701, 0x0260EB, 0x019DE9, 0x023E1B, 0x017000, 0x01FE6E, 0x012DB5, 0x01A27B, + 0x01E0D1, 0x01B0B9, 0x018A33, 0x01718D, 0x00D87A, 0x014449, 0x007B9A, 0x00AB71, + 0x013178, 0x0112EA, 0x00AD08, 0x009BB9, 0x023D97, 0x020437, 0x021CCC, 0x01E6B4, + 0x018000, 0x012DB5, 0x0146D9, 0x0100CE, 0x00CFD2, 0x006E5C, 0x00B0E4, 0x005A2D, + 0x00E9CC, 0x00B7B1, 0x00846F, 0x006B85, 0x008337, 0x0042E5, 0x004A10, 0x002831, }, { - 0x00015555, 0x0001F708, 0x0001D9D9, 0x0001C389, 0x00018000, 0x00012DB5, 0x0000DB5D, 0x00006FD5, - 0x00023237, 0x00030BD0, 0x0003053B, 0x0002B7E3, 0x00024FCE, 0x0001D0FA, 0x00014048, 0x0000AB71, - 0x00024957, 0x00032BE4, 0x0002FCC9, 0x0002B04A, 0x00024957, 0x0001E1CC, 0x00014BDE, 0x0000A92F, - 0x000227E1, 0x0002FD7A, 0x0002D110, 0x000288F1, 0x000240F7, 0x0001C551, 0x00013840, 0x00009F2F, - 0x0001EAAB, 0x0002A893, 0x00028116, 0x000240F7, 0x00020000, 0x00019247, 0x00011518, 0x00009325, - 0x00019247, 0x00022DF9, 0x00020D99, 0x0001ECBC, 0x0001B3CC, 0x00015668, 0x0000EBDA, 0x0000783D, - 0x000120A3, 0x0001B061, 0x0001974B, 0x00016E8E, 0x000137BB, 0x0000F4ED, 0x0000AEF4, 0x00005931, - 0x0000A4CE, 0x0000E497, 0x0000E6B5, 0x0000CFA2, 0x0000B093, 0x00008F5C, 0x000062BF, 0x00003597, + 0x015555, 0x01F708, 0x023237, 0x030BD0, 0x01D9D9, 0x01C389, 0x03053B, 0x02B7E3, + 0x018000, 0x012DB5, 0x024FCE, 0x01D0FA, 0x00DB5D, 0x006FD5, 0x014048, 0x00AB71, + 0x024957, 0x01E1CC, 0x0240F7, 0x01C551, 0x014BDE, 0x00A92F, 0x013840, 0x009F2F, + 0x024957, 0x032BE4, 0x0227E1, 0x02FD7A, 0x01EAAB, 0x02A893, 0x019247, 0x022DF9, + 0x028116, 0x0240F7, 0x020D99, 0x01ECBC, 0x0120A3, 0x01B061, 0x00A4CE, 0x00E497, + 0x01974B, 0x016E8E, 0x00E6B5, 0x00CFA2, 0x02FCC9, 0x02B04A, 0x02D110, 0x0288F1, + 0x020000, 0x019247, 0x01B3CC, 0x015668, 0x011518, 0x009325, 0x00EBDA, 0x00783D, + 0x0137BB, 0x00F4ED, 0x00B093, 0x008F5C, 0x00AEF4, 0x005931, 0x0062BF, 0x003597, }, { - 0x0001AAAB, 0x000274CB, 0x0002504F, 0x0002346C, 0x0001E000, 0x00017922, 0x00011235, 0x00008BCA, - 0x0002BEC4, 0x0003CEC4, 0x0003C689, 0x000365DC, 0x0002E3C1, 0x00024539, 0x0001905A, 0x0000D64D, - 0x0002DBAD, 0x0003F6DD, 0x0003BBFB, 0x00035C5C, 0x0002DBAD, 0x00025A40, 0x00019ED6, 0x0000D37B, - 0x0002B1D9, 0x0003BCD8, 0x00038554, 0x00032B2D, 0x0002D134, 0x000236A5, 0x00018650, 0x0000C6FB, - 0x00026555, 0x000352B8, 0x0003215C, 0x0002D134, 0x00028000, 0x0001F6D8, 0x00015A5E, 0x0000B7EF, - 0x0001F6D8, 0x0002B977, 0x00029100, 0x000267EB, 0x000220C0, 0x0001AC02, 0x000126D1, 0x0000964C, - 0x000168CC, 0x00021C7A, 0x0001FD1E, 0x0001CA31, 0x000185A9, 0x00013228, 0x0000DAB2, 0x00006F7D, - 0x0000CE01, 0x00011DBD, 0x00012062, 0x0001038A, 0x0000DCB8, 0x0000B333, 0x00007B6F, 0x000042FC, + 0x01AAAB, 0x0274CB, 0x02BEC4, 0x03CEC4, 0x02504F, 0x02346C, 0x03C689, 0x0365DC, + 0x01E000, 0x017922, 0x02E3C1, 0x024539, 0x011235, 0x008BCA, 0x01905A, 0x00D64D, + 0x02DBAD, 0x025A40, 0x02D134, 0x0236A5, 0x019ED6, 0x00D37B, 0x018650, 0x00C6FB, + 0x02DBAD, 0x03F6DD, 0x02B1D9, 0x03BCD8, 0x026555, 0x0352B8, 0x01F6D8, 0x02B977, + 0x03215C, 0x02D134, 0x029100, 0x0267EB, 0x0168CC, 0x021C7A, 0x00CE01, 0x011DBD, + 0x01FD1E, 0x01CA31, 0x012062, 0x01038A, 0x03BBFB, 0x035C5C, 0x038554, 0x032B2D, + 0x028000, 0x01F6D8, 0x0220C0, 0x01AC02, 0x015A5E, 0x00B7EF, 0x0126D1, 0x00964C, + 0x0185A9, 0x013228, 0x00DCB8, 0x00B333, 0x00DAB2, 0x006F7D, 0x007B6F, 0x0042FC, }, { - 0x00020000, 0x0002F28D, 0x0002C6C5, 0x0002A54E, 0x00024000, 0x0001C48F, 0x0001490C, 0x0000A7BF, - 0x00034B52, 0x000491B8, 0x000487D8, 0x000413D5, 0x000377B5, 0x0002B977, 0x0001E06C, 0x0001012A, - 0x00036E03, 0x0004C1D6, 0x00047B2D, 0x0004086E, 0x00036E03, 0x0002D2B3, 0x0001F1CE, 0x0000FDC7, - 0x00033BD1, 0x00047C37, 0x00043998, 0x0003CD69, 0x00036172, 0x0002A7FA, 0x0001D460, 0x0000EEC7, - 0x0002E000, 0x0003FCDD, 0x0003C1A1, 0x00036172, 0x00030000, 0x00025B6A, 0x00019FA3, 0x0000DCB8, - 0x00025B6A, 0x000344F5, 0x00031466, 0x0002E31B, 0x00028DB3, 0x0002019B, 0x000161C7, 0x0000B45B, - 0x0001B0F5, 0x00028892, 0x000262F1, 0x000225D5, 0x0001D398, 0x00016F63, 0x0001066F, 0x000085C9, - 0x0000F735, 0x000156E2, 0x00015A10, 0x00013772, 0x000108DD, 0x0000D70A, 0x0000941F, 0x00005062, + 0x020000, 0x02F28D, 0x034B52, 0x0491B8, 0x02C6C5, 0x02A54E, 0x0487D8, 0x0413D5, + 0x024000, 0x01C48F, 0x0377B5, 0x02B977, 0x01490C, 0x00A7BF, 0x01E06C, 0x01012A, + 0x036E03, 0x02D2B3, 0x036172, 0x02A7FA, 0x01F1CE, 0x00FDC7, 0x01D460, 0x00EEC7, + 0x036E03, 0x04C1D6, 0x033BD1, 0x047C37, 0x02E000, 0x03FCDD, 0x025B6A, 0x0344F5, + 0x03C1A1, 0x036172, 0x031466, 0x02E31B, 0x01B0F5, 0x028892, 0x00F735, 0x0156E2, + 0x0262F1, 0x0225D5, 0x015A10, 0x013772, 0x047B2D, 0x04086E, 0x043998, 0x03CD69, + 0x030000, 0x025B6A, 0x028DB3, 0x02019B, 0x019FA3, 0x00DCB8, 0x0161C7, 0x00B45B, + 0x01D398, 0x016F63, 0x0108DD, 0x00D70A, 0x01066F, 0x0085C9, 0x00941F, 0x005062, }, { - 0x0002AAAB, 0x0003EE11, 0x0003B3B2, 0x00038713, 0x00030000, 0x00025B6A, 0x0001B6BB, 0x0000DFAA, - 0x0004646D, 0x000617A0, 0x00060A75, 0x00056FC6, 0x00049F9B, 0x0003A1F4, 0x00028090, 0x000156E2, - 0x000492AE, 0x000657C8, 0x0005F991, 0x00056093, 0x000492AE, 0x0003C399, 0x000297BD, 0x0001525F, - 0x00044FC1, 0x0005FAF4, 0x0005A220, 0x000511E1, 0x000481ED, 0x00038AA2, 0x00027080, 0x00013E5E, - 0x0003D555, 0x00055126, 0x0005022D, 0x000481ED, 0x00040000, 0x0003248D, 0x00022A2F, 0x0001264B, - 0x0003248D, 0x00045BF2, 0x00041B33, 0x0003D979, 0x00036799, 0x0002ACCF, 0x0001D7B5, 0x0000F079, - 0x00024147, 0x000360C3, 0x00032E96, 0x0002DD1C, 0x00026F75, 0x0001E9D9, 0x00015DE9, 0x0000B262, - 0x0001499C, 0x0001C92E, 0x0001CD6A, 0x00019F43, 0x00016127, 0x00011EB8, 0x0000C57F, 0x00006B2D, + 0x02AAAB, 0x03EE11, 0x04646D, 0x0617A0, 0x03B3B2, 0x038713, 0x060A75, 0x056FC6, + 0x030000, 0x025B6A, 0x049F9B, 0x03A1F4, 0x01B6BB, 0x00DFAA, 0x028090, 0x0156E2, + 0x0492AE, 0x03C399, 0x0481ED, 0x038AA2, 0x0297BD, 0x01525F, 0x027080, 0x013E5E, + 0x0492AE, 0x0657C8, 0x044FC1, 0x05FAF4, 0x03D555, 0x055126, 0x03248D, 0x045BF2, + 0x05022D, 0x0481ED, 0x041B33, 0x03D979, 0x024147, 0x0360C3, 0x01499C, 0x01C92E, + 0x032E96, 0x02DD1C, 0x01CD6A, 0x019F43, 0x05F991, 0x056093, 0x05A220, 0x0511E1, + 0x040000, 0x03248D, 0x036799, 0x02ACCF, 0x022A2F, 0x01264B, 0x01D7B5, 0x00F079, + 0x026F75, 0x01E9D9, 0x016127, 0x011EB8, 0x015DE9, 0x00B262, 0x00C57F, 0x006B2D, }, { - 0x00038000, 0x00052876, 0x0004DBD9, 0x0004A148, 0x0003F000, 0x000317FB, 0x00023FD5, 0x0001258F, - 0x0005C3CF, 0x0007FF02, 0x0007EDBA, 0x000722B4, 0x0006117C, 0x0004C491, 0x000348BD, 0x0001C209, - 0x00060085, 0x00085336, 0x0007D78F, 0x00070EC1, 0x00060085, 0x0004F0B9, 0x00036728, 0x0001BC1C, - 0x0005A8AE, 0x0007D960, 0x000764CA, 0x0006A777, 0x0005EA87, 0x0004A5F5, 0x000333A8, 0x0001A1DB, - 0x00050800, 0x0006FA82, 0x000692DA, 0x0005EA87, 0x00054000, 0x00041FF9, 0x0002D75E, 0x00018242, - 0x00041FF9, 0x0005B8AE, 0x000563B2, 0x00050D6E, 0x000477F9, 0x000382D0, 0x00026B1D, 0x00013B9F, - 0x0002F5AD, 0x00046F00, 0x00042D25, 0x0003C235, 0x0003324A, 0x000282ED, 0x0001CB42, 0x0000EA21, - 0x0001B09C, 0x0002580C, 0x00025D9B, 0x00022108, 0x0001CF83, 0x00017851, 0x00010336, 0x00008CAC, + 0x038000, 0x052876, 0x05C3CF, 0x07FF02, 0x04DBD9, 0x04A148, 0x07EDBA, 0x0722B4, + 0x03F000, 0x0317FB, 0x06117C, 0x04C491, 0x023FD5, 0x01258F, 0x0348BD, 0x01C209, + 0x060085, 0x04F0B9, 0x05EA87, 0x04A5F5, 0x036728, 0x01BC1C, 0x0333A8, 0x01A1DB, + 0x060085, 0x085336, 0x05A8AE, 0x07D960, 0x050800, 0x06FA82, 0x041FF9, 0x05B8AE, + 0x0692DA, 0x05EA87, 0x0563B2, 0x050D6E, 0x02F5AD, 0x046F00, 0x01B09C, 0x02580C, + 0x042D25, 0x03C235, 0x025D9B, 0x022108, 0x07D78F, 0x070EC1, 0x0764CA, 0x06A777, + 0x054000, 0x041FF9, 0x0477F9, 0x0382D0, 0x02D75E, 0x018242, 0x026B1D, 0x013B9F, + 0x03324A, 0x0282ED, 0x01CF83, 0x017851, 0x01CB42, 0x00EA21, 0x010336, 0x008CAC, }, { - 0x00040000, 0x0005E519, 0x00058D8A, 0x00054A9C, 0x00048000, 0x0003891F, 0x00029218, 0x00014F7E, - 0x000696A4, 0x00092370, 0x00090FB0, 0x000827AA, 0x0006EF69, 0x000572EE, 0x0003C0D8, 0x00020254, - 0x0006DC05, 0x000983AC, 0x0008F65A, 0x000810DD, 0x0006DC05, 0x0005A565, 0x0003E39B, 0x0001FB8E, - 0x000677A2, 0x0008F86E, 0x00087330, 0x00079AD1, 0x0006C2E4, 0x00054FF3, 0x0003A8C0, 0x0001DD8D, - 0x0005C000, 0x0007F9B9, 0x00078343, 0x0006C2E4, 0x00060000, 0x0004B6D4, 0x00033F47, 0x0001B970, - 0x0004B6D4, 0x000689EB, 0x000628CC, 0x0005C635, 0x00051B65, 0x00040337, 0x0002C38F, 0x000168B6, - 0x000361EA, 0x00051124, 0x0004C5E1, 0x00044BAA, 0x0003A730, 0x0002DEC6, 0x00020CDD, 0x00010B93, - 0x0001EE69, 0x0002ADC5, 0x0002B41F, 0x00026EE5, 0x000211BA, 0x0001AE14, 0x0001283E, 0x0000A0C4, + 0x040000, 0x05E519, 0x0696A4, 0x092370, 0x058D8A, 0x054A9C, 0x090FB0, 0x0827AA, + 0x048000, 0x03891F, 0x06EF69, 0x0572EE, 0x029218, 0x014F7E, 0x03C0D8, 0x020254, + 0x06DC05, 0x05A565, 0x06C2E4, 0x054FF3, 0x03E39B, 0x01FB8E, 0x03A8C0, 0x01DD8D, + 0x06DC05, 0x0983AC, 0x0677A2, 0x08F86E, 0x05C000, 0x07F9B9, 0x04B6D4, 0x0689EB, + 0x078343, 0x06C2E4, 0x0628CC, 0x05C635, 0x0361EA, 0x051124, 0x01EE69, 0x02ADC5, + 0x04C5E1, 0x044BAA, 0x02B41F, 0x026EE5, 0x08F65A, 0x0810DD, 0x087330, 0x079AD1, + 0x060000, 0x04B6D4, 0x051B65, 0x040337, 0x033F47, 0x01B970, 0x02C38F, 0x0168B6, + 0x03A730, 0x02DEC6, 0x0211BA, 0x01AE14, 0x020CDD, 0x010B93, 0x01283E, 0x00A0C4, }, { - 0x00050000, 0x00075E60, 0x0006F0ED, 0x00069D43, 0x0005A000, 0x00046B67, 0x0003369E, 0x0001A35E, - 0x00083C4D, 0x000B6C4C, 0x000B539C, 0x000A3194, 0x0008AB44, 0x0006CFAA, 0x0004B10F, 0x000282E8, - 0x00089307, 0x000BE497, 0x000B33F1, 0x000A1514, 0x00089307, 0x00070EBF, 0x0004DC82, 0x00027A72, - 0x0008158B, 0x000B3689, 0x000A8FFC, 0x00098186, 0x0008739C, 0x0006A3F0, 0x000492F0, 0x000254F0, - 0x00073000, 0x0009F827, 0x00096413, 0x0008739C, 0x00078000, 0x0005E489, 0x00040F19, 0x000227CC, - 0x0005E489, 0x00082C66, 0x0007B2FF, 0x000737C2, 0x0006623F, 0x00050405, 0x00037473, 0x0001C2E3, - 0x00043A64, 0x0006556D, 0x0005F75A, 0x00055E94, 0x000490FC, 0x00039677, 0x00029015, 0x00014E78, - 0x00026A04, 0x00035936, 0x00036127, 0x00030A9E, 0x00029629, 0x00021999, 0x0001724E, 0x0000C8F5, + 0x050000, 0x075E60, 0x083C4D, 0x0B6C4C, 0x06F0ED, 0x069D43, 0x0B539C, 0x0A3194, + 0x05A000, 0x046B67, 0x08AB44, 0x06CFAA, 0x03369E, 0x01A35E, 0x04B10F, 0x0282E8, + 0x089307, 0x070EBF, 0x08739C, 0x06A3F0, 0x04DC82, 0x027A72, 0x0492F0, 0x0254F0, + 0x089307, 0x0BE497, 0x08158B, 0x0B3689, 0x073000, 0x09F827, 0x05E489, 0x082C66, + 0x096413, 0x08739C, 0x07B2FF, 0x0737C2, 0x043A64, 0x06556D, 0x026A04, 0x035936, + 0x05F75A, 0x055E94, 0x036127, 0x030A9E, 0x0B33F1, 0x0A1514, 0x0A8FFC, 0x098186, + 0x078000, 0x05E489, 0x06623F, 0x050405, 0x040F19, 0x0227CC, 0x037473, 0x01C2E3, + 0x0490FC, 0x039677, 0x029629, 0x021999, 0x029015, 0x014E78, 0x01724E, 0x00C8F5, }, { - 0x00060000, 0x0008D7A6, 0x00085450, 0x0007EFEA, 0x0006C000, 0x00054DAE, 0x0003DB24, 0x0001F73E, - 0x0009E1F6, 0x000DB528, 0x000D9788, 0x000C3B7E, 0x000A671E, 0x00082C66, 0x0005A145, 0x0003037D, - 0x000A4A08, 0x000E4582, 0x000D7187, 0x000C194B, 0x000A4A08, 0x00087818, 0x0005D569, 0x0002F955, - 0x0009B373, 0x000D74A5, 0x000CACC8, 0x000B683A, 0x000A2455, 0x0007F7ED, 0x00057D20, 0x0002CC54, - 0x0008A000, 0x000BF696, 0x000B44E4, 0x000A2455, 0x00090000, 0x0007123E, 0x0004DEEA, 0x00029629, - 0x0007123E, 0x0009CEE0, 0x00093D32, 0x0008A950, 0x0007A918, 0x000604D2, 0x00042556, 0x00021D11, - 0x000512DF, 0x000799B6, 0x000728D2, 0x0006717F, 0x00057AC8, 0x00044E28, 0x0003134C, 0x0001915C, - 0x0002E59E, 0x000404A7, 0x00040E2F, 0x0003A657, 0x00031A97, 0x0002851E, 0x0001BC5D, 0x0000F126, + 0x060000, 0x08D7A6, 0x09E1F6, 0x0DB528, 0x085450, 0x07EFEA, 0x0D9788, 0x0C3B7E, + 0x06C000, 0x054DAE, 0x0A671E, 0x082C66, 0x03DB24, 0x01F73E, 0x05A145, 0x03037D, + 0x0A4A08, 0x087818, 0x0A2455, 0x07F7ED, 0x05D569, 0x02F955, 0x057D20, 0x02CC54, + 0x0A4A08, 0x0E4582, 0x09B373, 0x0D74A5, 0x08A000, 0x0BF696, 0x07123E, 0x09CEE0, + 0x0B44E4, 0x0A2455, 0x093D32, 0x08A950, 0x0512DF, 0x0799B6, 0x02E59E, 0x0404A7, + 0x0728D2, 0x06717F, 0x040E2F, 0x03A657, 0x0D7187, 0x0C194B, 0x0CACC8, 0x0B683A, + 0x090000, 0x07123E, 0x07A918, 0x0604D2, 0x04DEEA, 0x029629, 0x042556, 0x021D11, + 0x057AC8, 0x044E28, 0x031A97, 0x02851E, 0x03134C, 0x01915C, 0x01BC5D, 0x00F126, }, { - 0x00080000, 0x000BCA33, 0x000B1B15, 0x000A9538, 0x00090000, 0x0007123E, 0x00052430, 0x00029EFD, - 0x000D2D48, 0x001246E0, 0x00121F5F, 0x00104F53, 0x000DDED2, 0x000AE5DD, 0x000781B1, 0x000404A7, - 0x000DB80B, 0x00130757, 0x0011ECB4, 0x001021B9, 0x000DB80B, 0x000B4ACB, 0x0007C736, 0x0003F71D, - 0x000CEF44, 0x0011F0DC, 0x0010E661, 0x000F35A3, 0x000D85C7, 0x000A9FE7, 0x00075180, 0x0003BB1A, - 0x000B8000, 0x000FF372, 0x000F0686, 0x000D85C7, 0x000C0000, 0x00096DA8, 0x00067E8E, 0x000372E1, - 0x00096DA8, 0x000D13D6, 0x000C5198, 0x000B8C6A, 0x000A36CB, 0x0008066E, 0x0005871E, 0x0002D16B, - 0x0006C3D4, 0x000A2248, 0x00098BC3, 0x00089754, 0x00074E60, 0x0005BD8B, 0x000419BB, 0x00021726, - 0x0003DCD3, 0x00055B8A, 0x0005683E, 0x0004DDC9, 0x00042374, 0x00035C28, 0x0002507C, 0x00014188, + 0x080000, 0x0BCA33, 0x0D2D48, 0x1246E0, 0x0B1B15, 0x0A9538, 0x121F5F, 0x104F53, + 0x090000, 0x07123E, 0x0DDED2, 0x0AE5DD, 0x052430, 0x029EFD, 0x0781B1, 0x0404A7, + 0x0DB80B, 0x0B4ACB, 0x0D85C7, 0x0A9FE7, 0x07C736, 0x03F71D, 0x075180, 0x03BB1A, + 0x0DB80B, 0x130757, 0x0CEF44, 0x11F0DC, 0x0B8000, 0x0FF372, 0x096DA8, 0x0D13D6, + 0x0F0686, 0x0D85C7, 0x0C5198, 0x0B8C6A, 0x06C3D4, 0x0A2248, 0x03DCD3, 0x055B8A, + 0x098BC3, 0x089754, 0x05683E, 0x04DDC9, 0x11ECB4, 0x1021B9, 0x10E661, 0x0F35A3, + 0x0C0000, 0x096DA8, 0x0A36CB, 0x08066E, 0x067E8E, 0x0372E1, 0x05871E, 0x02D16B, + 0x074E60, 0x05BD8B, 0x042374, 0x035C28, 0x0419BB, 0x021726, 0x02507C, 0x014188, }, { - 0x000C0000, 0x0011AF4C, 0x0010A89F, 0x000FDFD4, 0x000D8000, 0x000A9B5D, 0x0007B649, 0x0003EE7B, - 0x0013C3EC, 0x001B6A50, 0x001B2F0F, 0x001876FD, 0x0014CE3C, 0x001058CB, 0x000B4289, 0x000606FB, - 0x00149410, 0x001C8B03, 0x001AE30E, 0x00183296, 0x00149410, 0x0010F030, 0x000BAAD2, 0x0005F2AB, - 0x001366E6, 0x001AE949, 0x00195991, 0x0016D074, 0x001448AB, 0x000FEFDA, 0x000AFA40, 0x000598A7, - 0x00114000, 0x0017ED2B, 0x001689C8, 0x001448AB, 0x00120000, 0x000E247C, 0x0009BDD5, 0x00052C51, - 0x000E247C, 0x00139DC1, 0x00127A63, 0x0011529F, 0x000F5230, 0x000C09A5, 0x00084AAC, 0x00043A21, - 0x000A25BE, 0x000F336D, 0x000E51A4, 0x000CE2FE, 0x000AF590, 0x00089C51, 0x00062698, 0x000322B9, - 0x0005CB3C, 0x0008094E, 0x00081C5D, 0x00074CAE, 0x0006352E, 0x00050A3B, 0x000378BA, 0x0001E24D, + 0x0C0000, 0x11AF4C, 0x13C3EC, 0x1B6A50, 0x10A89F, 0x0FDFD4, 0x1B2F0F, 0x1876FD, + 0x0D8000, 0x0A9B5D, 0x14CE3C, 0x1058CB, 0x07B649, 0x03EE7B, 0x0B4289, 0x0606FB, + 0x149410, 0x10F030, 0x1448AB, 0x0FEFDA, 0x0BAAD2, 0x05F2AB, 0x0AFA40, 0x0598A7, + 0x149410, 0x1C8B03, 0x1366E6, 0x1AE949, 0x114000, 0x17ED2B, 0x0E247C, 0x139DC1, + 0x1689C8, 0x1448AB, 0x127A63, 0x11529F, 0x0A25BE, 0x0F336D, 0x05CB3C, 0x08094E, + 0x0E51A4, 0x0CE2FE, 0x081C5D, 0x074CAE, 0x1AE30E, 0x183296, 0x195991, 0x16D074, + 0x120000, 0x0E247C, 0x0F5230, 0x0C09A5, 0x09BDD5, 0x052C51, 0x084AAC, 0x043A21, + 0x0AF590, 0x089C51, 0x06352E, 0x050A3B, 0x062698, 0x0322B9, 0x0378BA, 0x01E24D, }, { - 0x00110000, 0x00190DAC, 0x0017998C, 0x00167D16, 0x00132000, 0x000F06C3, 0x000AECE7, 0x000591D9, - 0x001C0039, 0x0026D69C, 0x002682AB, 0x0022A891, 0x001D797F, 0x00172876, 0x000FF398, 0x000889E3, - 0x001D2717, 0x00286F9A, 0x002616FF, 0x002247AA, 0x001D2717, 0x0017FEEF, 0x00108754, 0x00086D1D, - 0x001B7C71, 0x00261FD3, 0x0023E98D, 0x002051FA, 0x001CBC47, 0x001693CA, 0x000F8D30, 0x0007ED98, - 0x00187000, 0x0021E552, 0x001FEDDC, 0x001CBC47, 0x00198000, 0x00140904, 0x000DCCEE, 0x0007541E, - 0x00140904, 0x001BCA27, 0x001A2D62, 0x00188A62, 0x0015B46F, 0x00110DAA, 0x000BBF1F, 0x0005FD04, - 0x000E6022, 0x001588DA, 0x001448FE, 0x00124192, 0x000F868B, 0x000C32C8, 0x0008B6AD, 0x00047130, - 0x00083540, 0x000B6284, 0x000B7D84, 0x000A574B, 0x0008CB57, 0x000723D4, 0x0004EB08, 0x0002AB42, + 0x110000, 0x190DAC, 0x1C0039, 0x26D69C, 0x17998C, 0x167D16, 0x2682AB, 0x22A891, + 0x132000, 0x0F06C3, 0x1D797F, 0x172876, 0x0AECE7, 0x0591D9, 0x0FF398, 0x0889E3, + 0x1D2717, 0x17FEEF, 0x1CBC47, 0x1693CA, 0x108754, 0x086D1D, 0x0F8D30, 0x07ED98, + 0x1D2717, 0x286F9A, 0x1B7C71, 0x261FD3, 0x187000, 0x21E552, 0x140904, 0x1BCA27, + 0x1FEDDC, 0x1CBC47, 0x1A2D62, 0x188A62, 0x0E6022, 0x1588DA, 0x083540, 0x0B6284, + 0x1448FE, 0x124192, 0x0B7D84, 0x0A574B, 0x2616FF, 0x2247AA, 0x23E98D, 0x2051FA, + 0x198000, 0x140904, 0x15B46F, 0x110DAA, 0x0DCCEE, 0x07541E, 0x0BBF1F, 0x05FD04, + 0x0F868B, 0x0C32C8, 0x08CB57, 0x0723D4, 0x08B6AD, 0x047130, 0x04EB08, 0x02AB42, }, { - 0x00160000, 0x00206C0C, 0x001E8A79, 0x001D1A59, 0x0018C000, 0x0013722A, 0x000E2385, 0x00073537, - 0x00243C86, 0x003242E8, 0x0031D646, 0x002CDA25, 0x002624C3, 0x001DF820, 0x0014A4A7, 0x000B0CCC, - 0x0025BA1D, 0x00345430, 0x00314AEF, 0x002C5CBE, 0x0025BA1D, 0x001F0DAE, 0x001563D6, 0x000AE78E, - 0x002391FB, 0x0031565C, 0x002E798A, 0x0029D380, 0x00252FE4, 0x001D37BB, 0x00142021, 0x000A4288, - 0x001FA000, 0x002BDD7A, 0x002951EF, 0x00252FE4, 0x00210000, 0x0019ED8D, 0x0011DC06, 0x00097BEA, - 0x0019ED8D, 0x0023F68C, 0x0021E061, 0x001FC224, 0x001C16AE, 0x001611AE, 0x000F3391, 0x0007BFE7, - 0x00129A87, 0x001BDE47, 0x001A4058, 0x0017A026, 0x00141787, 0x000FC93E, 0x000B46C1, 0x0005BFA8, - 0x000A9F44, 0x000EBBBA, 0x000EDEAB, 0x000D61E9, 0x000B617F, 0x00093D6D, 0x00065D55, 0x00037437, + 0x160000, 0x206C0C, 0x243C86, 0x3242E8, 0x1E8A79, 0x1D1A59, 0x31D646, 0x2CDA25, + 0x18C000, 0x13722A, 0x2624C3, 0x1DF820, 0x0E2385, 0x073537, 0x14A4A7, 0x0B0CCC, + 0x25BA1D, 0x1F0DAE, 0x252FE4, 0x1D37BB, 0x1563D6, 0x0AE78E, 0x142021, 0x0A4288, + 0x25BA1D, 0x345430, 0x2391FB, 0x31565C, 0x1FA000, 0x2BDD7A, 0x19ED8D, 0x23F68C, + 0x2951EF, 0x252FE4, 0x21E061, 0x1FC224, 0x129A87, 0x1BDE47, 0x0A9F44, 0x0EBBBA, + 0x1A4058, 0x17A026, 0x0EDEAB, 0x0D61E9, 0x314AEF, 0x2C5CBE, 0x2E798A, 0x29D380, + 0x210000, 0x19ED8D, 0x1C16AE, 0x1611AE, 0x11DC06, 0x097BEA, 0x0F3391, 0x07BFE7, + 0x141787, 0x0FC93E, 0x0B617F, 0x093D6D, 0x0B46C1, 0x05BFA8, 0x065D55, 0x037437, }, { - 0x001C0000, 0x002943B2, 0x0026DEC9, 0x00250A43, 0x001F8000, 0x0018BFD8, 0x0011FEA9, 0x00092C75, - 0x002E1E7C, 0x003FF810, 0x003F6DCE, 0x003915A3, 0x00308BE1, 0x00262485, 0x001A45EB, 0x000E1049, - 0x00300425, 0x004299B2, 0x003EBC76, 0x00387608, 0x00300425, 0x002785C6, 0x001B393F, 0x000DE0E4, - 0x002D456E, 0x003ECB00, 0x003B2652, 0x00353BBA, 0x002F5439, 0x00252FA8, 0x00199D41, 0x000D0EDC, - 0x00284000, 0x0037D40F, 0x003496D3, 0x002F5439, 0x002A0000, 0x0020FFCB, 0x0016BAF1, 0x000C1213, - 0x0020FFCB, 0x002DC56D, 0x002B1D93, 0x00286B74, 0x0023BFC6, 0x001C1681, 0x001358E8, 0x0009DCF8, - 0x0017AD66, 0x002377FE, 0x0021692A, 0x001E11A5, 0x0019924F, 0x00141767, 0x000E5A0D, 0x00075104, - 0x000D84E2, 0x0012C062, 0x0012ECDA, 0x00110840, 0x000E7C16, 0x000BC28A, 0x000819B2, 0x0004655D, + 0x1C0000, 0x2943B2, 0x2E1E7C, 0x3FF810, 0x26DEC9, 0x250A43, 0x3F6DCE, 0x3915A3, + 0x1F8000, 0x18BFD8, 0x308BE1, 0x262485, 0x11FEA9, 0x092C75, 0x1A45EB, 0x0E1049, + 0x300425, 0x2785C6, 0x2F5439, 0x252FA8, 0x1B393F, 0x0DE0E4, 0x199D41, 0x0D0EDC, + 0x300425, 0x4299B2, 0x2D456E, 0x3ECB00, 0x284000, 0x37D40F, 0x20FFCB, 0x2DC56D, + 0x3496D3, 0x2F5439, 0x2B1D93, 0x286B74, 0x17AD66, 0x2377FE, 0x0D84E2, 0x12C062, + 0x21692A, 0x1E11A5, 0x12ECDA, 0x110840, 0x3EBC76, 0x387608, 0x3B2652, 0x353BBA, + 0x2A0000, 0x20FFCB, 0x23BFC6, 0x1C1681, 0x16BAF1, 0x0C1213, 0x1358E8, 0x09DCF8, + 0x19924F, 0x141767, 0x0E7C16, 0x0BC28A, 0x0E5A0D, 0x075104, 0x0819B2, 0x04655D, }, { - 0x00220000, 0x00321B58, 0x002F3318, 0x002CFA2D, 0x00264000, 0x001E0D86, 0x0015D9CE, 0x000B23B2, - 0x00380072, 0x004DAD38, 0x004D0556, 0x00455122, 0x003AF2FE, 0x002E50EB, 0x001FE730, 0x001113C7, - 0x003A4E2D, 0x0050DF33, 0x004C2DFD, 0x00448F54, 0x003A4E2D, 0x002FFDDF, 0x00210EA8, 0x0010DA39, - 0x0036F8E1, 0x004C3FA5, 0x0047D31B, 0x0040A3F5, 0x0039788E, 0x002D2795, 0x001F1A61, 0x000FDB2F, - 0x0030E000, 0x0043CAA5, 0x003FDBB7, 0x0039788E, 0x00330000, 0x00281209, 0x001B99DB, 0x000EA83B, - 0x00281209, 0x0037944D, 0x00345AC4, 0x003114C3, 0x002B68DF, 0x00221B53, 0x00177E3E, 0x000BFA09, - 0x001CC044, 0x002B11B4, 0x002891FC, 0x00248324, 0x001F0D17, 0x0018658F, 0x00116D5A, 0x0008E260, - 0x00106A80, 0x0016C509, 0x0016FB08, 0x0014AE97, 0x001196AE, 0x000E47A8, 0x0009D60F, 0x00055684, + 0x220000, 0x321B58, 0x380072, 0x4DAD38, 0x2F3318, 0x2CFA2D, 0x4D0556, 0x455122, + 0x264000, 0x1E0D86, 0x3AF2FE, 0x2E50EB, 0x15D9CE, 0x0B23B2, 0x1FE730, 0x1113C7, + 0x3A4E2D, 0x2FFDDF, 0x39788E, 0x2D2795, 0x210EA8, 0x10DA39, 0x1F1A61, 0x0FDB2F, + 0x3A4E2D, 0x50DF33, 0x36F8E1, 0x4C3FA5, 0x30E000, 0x43CAA5, 0x281209, 0x37944D, + 0x3FDBB7, 0x39788E, 0x345AC4, 0x3114C3, 0x1CC044, 0x2B11B4, 0x106A80, 0x16C509, + 0x2891FC, 0x248324, 0x16FB08, 0x14AE97, 0x4C2DFD, 0x448F54, 0x47D31B, 0x40A3F5, + 0x330000, 0x281209, 0x2B68DF, 0x221B53, 0x1B99DB, 0x0EA83B, 0x177E3E, 0x0BFA09, + 0x1F0D17, 0x18658F, 0x1196AE, 0x0E47A8, 0x116D5A, 0x08E260, 0x09D60F, 0x055684, }, { - 0x002C0000, 0x0040D818, 0x003D14F2, 0x003A34B2, 0x00318000, 0x0026E454, 0x001C470A, 0x000E6A6E, - 0x0048790C, 0x006485D0, 0x0063AC8D, 0x0059B44A, 0x004C4986, 0x003BF03F, 0x0029494D, 0x00161998, - 0x004B743A, 0x0068A861, 0x006295DE, 0x0058B97B, 0x004B743A, 0x003E1B5C, 0x002AC7AC, 0x0015CF1D, - 0x004723F6, 0x0062ACB8, 0x005CF313, 0x0053A701, 0x004A5FC7, 0x003A6F75, 0x00284041, 0x00148510, - 0x003F4000, 0x0057BAF3, 0x0052A3DE, 0x004A5FC7, 0x00420000, 0x0033DB1A, 0x0023B80D, 0x0012F7D4, - 0x0033DB1A, 0x0047ED19, 0x0043C0C2, 0x003F8448, 0x00382D5C, 0x002C235D, 0x001E6723, 0x000F7FCF, - 0x0025350D, 0x0037BC8E, 0x003480B0, 0x002F404C, 0x00282F0E, 0x001F927D, 0x00168D83, 0x000B7F50, - 0x00153E87, 0x001D7775, 0x001DBD56, 0x001AC3D2, 0x0016C2FF, 0x00127AD9, 0x000CBAAA, 0x0006E86E, -} + 0x2C0000, 0x40D818, 0x48790C, 0x6485D0, 0x3D14F2, 0x3A34B2, 0x63AC8D, 0x59B44A, + 0x318000, 0x26E454, 0x4C4986, 0x3BF03F, 0x1C470A, 0x0E6A6E, 0x29494D, 0x161998, + 0x4B743A, 0x3E1B5C, 0x4A5FC7, 0x3A6F75, 0x2AC7AC, 0x15CF1D, 0x284041, 0x148510, + 0x4B743A, 0x68A861, 0x4723F6, 0x62ACB8, 0x3F4000, 0x57BAF3, 0x33DB1A, 0x47ED19, + 0x52A3DE, 0x4A5FC7, 0x43C0C2, 0x3F8448, 0x25350D, 0x37BC8E, 0x153E87, 0x1D7775, + 0x3480B0, 0x2F404C, 0x1DBD56, 0x1AC3D2, 0x6295DE, 0x58B97B, 0x5CF313, 0x53A701, + 0x420000, 0x33DB1A, 0x382D5C, 0x2C235D, 0x23B80D, 0x12F7D4, 0x1E6723, 0x0F7FCF, + 0x282F0E, 0x1F927D, 0x16C2FF, 0x127AD9, 0x168D83, 0x0B7F50, 0x0CBAAA, 0x06E86E, +}, }; + #endif /* AVCODEC_BINKDATA_H */ diff --git a/project/jni/application/gemrb/gemrb/plugins/CREImporter/CREImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/CREImporter/CREImporter.cpp index afc03f791..a28e3010b 100644 --- a/project/jni/application/gemrb/gemrb/plugins/CREImporter/CREImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/CREImporter/CREImporter.cpp @@ -1029,58 +1029,52 @@ void CREImporter::GetActorPST(Actor *act) void CREImporter::ReadInventory(Actor *act, unsigned int Inventory_Size) { - CREItem** items; + ieWord *indices = (ieWord *) calloc(Inventory_Size, sizeof(ieWord)); + //CREItem** items; unsigned int i,j,k; - str->Seek( ItemsOffset+CREOffset, GEM_STREAM_START ); - items = (CREItem **) calloc (ItemsCount, sizeof(CREItem *) ); - - for (i = 0; i < ItemsCount; i++) { - items[i] = core->ReadItem(str); //could be NULL item - } act->inventory.SetSlotCount(Inventory_Size+1); - str->Seek( ItemSlotsOffset+CREOffset, GEM_STREAM_START ); - for (i = 1; i <= Inventory_Size; i++) { - int Slot = core->QuerySlot( i ); - ieWord index; - str->ReadWord( &index ); - - if (index != 0xFFFF) { - if (index>=ItemsCount) { - printMessage("CREImporter"," ",LIGHT_RED); - printf("Invalid item index (%d) in creature!\n", index); - continue; - } - CREItem *item = items[index]; - if (item && gamedata->Exists(item->ItemResRef, IE_ITM_CLASS_ID)) { - act->inventory.SetSlotItem( item, Slot ); - items[index] = NULL; - continue; - } - printMessage("CREImporter"," ",LIGHT_RED); - printf("Duplicate or (no-drop) item (%d) in creature!\n", index); - } + //first read the indices + for (i = 0;iReadWord(indices+i); } - - i = ItemsCount; - while(i--) { - if ( items[i]) { - printMessage("CREImporter"," ",LIGHT_RED); - printf("Dangling item in creature: %s!\n", items[i]->ItemResRef); - delete items[i]; - } - } - free (items); - - //this dword contains the equipping info (which slot is selected) + //this word contains the equipping info (which slot is selected) // 0,1,2,3 - weapon slots // 1000 - fist // -24,-23,-22,-21 - quiver //the equipping effects are delayed until the actor gets an area str->ReadWordSigned( &act->Equipped ); + //the equipped slot's selected ability is stored here str->ReadWord( &act->EquippedHeader ); + + //read the item entries based on the previously read indices + //an item entry may be read multiple times if the indices are repeating + for (i = 0;i=ItemsCount) { + printMessage("CREImporter"," ",LIGHT_RED); + printf("Invalid item index (%d) in creature!\n", index); + continue; + } + //20 is the size of CREItem on disc (8+2+3x2+4) + str->Seek( ItemsOffset+index*20 + CREOffset, GEM_STREAM_START ); + //the core allocates this item data + CREItem *item = core->ReadItem(str); + int Slot = core->QuerySlot(i); + if (item) { + act->inventory.SetSlotItem(item, Slot); + } else { + printMessage("CREImporter"," ",LIGHT_RED); + printf("Invalid item index (%d) in creature!\n", index); + } + } + } + + free (indices); // Reading spellbook CREKnownSpell **known_spells=(CREKnownSpell **) calloc(KnownSpellsCount, sizeof(CREKnownSpell *) ); diff --git a/project/jni/application/gemrb/gemrb/plugins/DLGImporter/DLGImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/DLGImporter/DLGImporter.cpp index 8f8be1a07..576831bfb 100644 --- a/project/jni/application/gemrb/gemrb/plugins/DLGImporter/DLGImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/DLGImporter/DLGImporter.cpp @@ -23,6 +23,7 @@ #include "win32def.h" #include "Interface.h" +#include "GameScript/GameScript.h" #include "System/FileStream.h" DLGImporter::DLGImporter(void) diff --git a/project/jni/application/gemrb/gemrb/plugins/DirectoryImporter/DirectoryImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/DirectoryImporter/DirectoryImporter.cpp index 90c770682..9a4ba399c 100644 --- a/project/jni/application/gemrb/gemrb/plugins/DirectoryImporter/DirectoryImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/DirectoryImporter/DirectoryImporter.cpp @@ -27,15 +27,18 @@ DirectoryImporter::DirectoryImporter(void) { + description = NULL; } DirectoryImporter::~DirectoryImporter(void) { + free(description); } bool DirectoryImporter::Open(const char *dir, const char *desc) { - description = desc; + free(description); + description = strdup(desc); strcpy(path, dir); return true; } diff --git a/project/jni/application/gemrb/gemrb/plugins/FXOpcodes/FXOpcodes.cpp b/project/jni/application/gemrb/gemrb/plugins/FXOpcodes/FXOpcodes.cpp index 867cde181..ee921da60 100644 --- a/project/jni/application/gemrb/gemrb/plugins/FXOpcodes/FXOpcodes.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/FXOpcodes/FXOpcodes.cpp @@ -30,6 +30,7 @@ #include "Game.h" #include "GameData.h" #include "Interface.h" +#include "PolymorphCache.h" // fx_polymorph #include "Projectile.h" //needs for clearair #include "Spell.h" //needed for fx_cast_spell feedback #include "TileMap.h" //needs for knock! @@ -38,7 +39,9 @@ #include "GameScript/Matching.h" //needs for GetAllObjects #include "GUI/GameControl.h" #include "Scriptable/Actor.h" -#include "PolymorphCache.h" // fx_polymorph +#include "Scriptable/Container.h" +#include "Scriptable/Door.h" +#include "Scriptable/InfoPoint.h" #include "Scriptable/PCStatStruct.h" //fx_polymorph (action definitions) //FIXME: find a way to handle portrait icons better @@ -366,7 +369,7 @@ int fx_protection_from_string (Scriptable* Owner, Actor* target, Effect* fx);//1 int fx_explore_modifier (Scriptable* Owner, Actor* target, Effect* fx);//10c int fx_screenshake (Scriptable* Owner, Actor* target, Effect* fx);//10d int fx_unpause_caster (Scriptable* Owner, Actor* target, Effect* fx);//10e -int fx_avatar_removal (Scriptable* Owner, Actor* target, Effect* fx);//10f +int fx_summon_disable (Scriptable* Owner, Actor* target, Effect* fx);//10f int fx_apply_effect_repeat (Scriptable* Owner, Actor* target, Effect* fx);//110 int fx_remove_projectile (Scriptable* Owner, Actor* target, Effect* fx);//111 int fx_teleport_to_target (Scriptable* Owner, Actor* target, Effect* fx);//112 @@ -418,345 +421,345 @@ int fx_change_weather (Scriptable* Owner, Actor* target, Effect* fx);//13e Cha int fx_unknown (Scriptable* Owner, Actor* target, Effect* fx);//??? // FIXME: Make this an ordered list, so we could use bsearch! -static EffectRef effectnames[] = { - { "*Crash*", fx_crash, -1 }, - { "AcidResistanceModifier", fx_acid_resistance_modifier, -1 }, - { "ACVsCreatureType", fx_generic_effect, -1 }, //0xdb - { "ACVsDamageTypeModifier", fx_ac_vs_damage_type_modifier, -1 }, - { "ACVsDamageTypeModifier2", fx_ac_vs_damage_type_modifier, -1 }, // used in IWD - { "AidNonCumulative", fx_set_aid_state, -1 }, - { "AIIdentifierModifier", fx_ids_modifier, -1 }, - { "AlchemyModifier", fx_alchemy_modifier, -1 }, - { "Alignment:Change", fx_alignment_change, -1 }, - { "Alignment:Invert", fx_alignment_invert, -1 }, - { "AlwaysBackstab", fx_always_backstab_modifier, -1 }, - { "AnimationIDModifier", fx_animation_id_modifier, -1 }, - { "AnimationStateChange", fx_animation_stance, -1 }, - { "ApplyEffect", fx_apply_effect, -1 }, - { "ApplyEffectCurse", fx_apply_effect_curse, -1 }, - { "ApplyEffectItem", fx_apply_effect_item, -1 }, - { "ApplyEffectItemType", fx_apply_effect_item_type, -1 }, - { "ApplyEffectRepeat", fx_apply_effect_repeat, -1 }, - { "CutScene2", fx_cutscene2, -1 }, - { "AttackSpeedModifier", fx_attackspeed_modifier, -1 }, - { "AttacksPerRoundModifier", fx_attacks_per_round_modifier, -1 }, - { "AuraCleansingModifier", fx_auracleansing_modifier, -1 }, - { "AvatarRemoval", fx_avatar_removal, -1 }, //unknown - { "AvatarRemovalModifier", fx_avatar_removal_modifier, -1 }, - { "BackstabModifier", fx_backstab_modifier, -1 }, - { "BerserkStage1Modifier", fx_berserkstage1_modifier, -1}, - { "BerserkStage2Modifier", fx_berserkstage2_modifier, -1}, - { "BlessNonCumulative", fx_set_bless_state, -1 }, - { "Bounce:School", fx_bounce_school, -1 }, - { "Bounce:SchoolDec", fx_bounce_school_dec, -1 }, - { "Bounce:SecondaryType", fx_bounce_secondary_type, -1 }, - { "Bounce:SecondaryTypeDec", fx_bounce_secondary_type_dec, -1 }, - { "Bounce:Spell", fx_bounce_spell, -1 }, - { "Bounce:SpellDec", fx_bounce_spell_dec, -1 }, - { "Bounce:SpellLevel", fx_bounce_spelllevel, -1}, - { "Bounce:SpellLevelDec", fx_bounce_spelllevel_dec, -1}, - { "Bounce:Opcode", fx_bounce_opcode, -1 }, - { "Bounce:Projectile", fx_bounce_projectile, -1 }, - { "CantUseItem", fx_generic_effect, -1 }, - { "CantUseItemType", fx_generic_effect, -1 }, - { "CanUseAnyItem", fx_can_use_any_item_modifier, -1 }, - { "CastFromList", fx_select_spell, -1 }, - { "CastingGlow", fx_casting_glow, -1 }, - { "CastingGlow2", fx_casting_glow, -1 }, //used in iwd - { "CastingLevelModifier", fx_castinglevel_modifier, -1 }, - { "CastingSpeedModifier", fx_castingspeed_modifier, -1 }, - { "CastSpellOnCondition", fx_cast_spell_on_condition, -1 }, - { "ChangeBardSong", fx_change_bardsong, -1 }, - { "ChangeName", fx_change_name, -1 }, - { "ChangeWeather", fx_change_weather, -1 }, - { "ChantBadNonCumulative", fx_set_chantbad_state, -1 }, - { "ChantNonCumulative", fx_set_chant_state, -1 }, - { "ChaosShieldModifier", fx_chaos_shield_modifier, -1 }, - { "CharismaModifier", fx_charisma_modifier, -1 }, - { "CheckForBerserkModifier", fx_checkforberserk_modifier, -1}, - { "ColdResistanceModifier", fx_cold_resistance_modifier, -1 }, - { "Color:BriefRGB", fx_brief_rgb, -1}, - { "Color:GlowRGB", fx_glow_rgb, -1}, - { "Color:DarkenRGB", fx_darken_rgb, -1}, - { "Color:SetPalette", fx_set_color_gradient, -1 }, - { "Color:SetRGB", fx_set_color_rgb, -1 }, - { "Color:SetRGBGlobal", fx_set_color_rgb_global, -1 }, //08 - { "Color:PulseRGB", fx_set_color_pulse_rgb, -1 }, //9 - { "Color:PulseRGBGlobal", fx_set_color_pulse_rgb_global, -1 }, //9 - { "ConstitutionModifier", fx_constitution_modifier, -1 }, - { "ControlCreature", fx_set_charmed_state, -1 }, //0xf1 same as charm - { "CreateContingency", fx_create_contingency, -1 }, - { "CriticalHitModifier", fx_critical_hit_modifier, -1 }, - { "CrushingResistanceModifier", fx_crushing_resistance_modifier, -1 }, - { "Cure:Berserk", fx_cure_berserk_state, -1 }, - { "Cure:Blind", fx_cure_blind_state, -1 }, - { "Cure:CasterHold", fx_unpause_caster, -1 }, - { "Cure:Confusion", fx_cure_confused_state, -1 }, - { "Cure:Deafness", fx_cure_deaf_state, -1 }, - { "Cure:Death", fx_cure_dead_state, -1 }, - { "Cure:Defrost", fx_cure_frozen_state, -1 }, - { "Cure:Disease", fx_cure_diseased_state, -1 }, - { "Cure:Feeblemind", fx_cure_feebleminded_state, -1 }, - { "Cure:Hold", fx_cure_hold_state, -1 }, - { "Cure:Imprisonment", fx_freedom, -1 }, - { "Cure:Infravision", fx_cure_infravision_state, -1 }, - { "Cure:Intoxication", fx_cure_intoxication, -1 }, //0xa4 (iwd2 has this working) - { "Cure:Invisible", fx_cure_invisible_state, -1 }, //0x2f - { "Cure:Invisible2", fx_cure_invisible_state, -1 }, //0x74 - //{ "Cure:ImprovedInvisible", fx_cure_improved_invisible_state, -1 }, - { "Cure:LevelDrain", fx_cure_leveldrain, -1}, //restoration - { "Cure:Nondetection", fx_cure_nondetection_state, -1 }, - { "Cure:Panic", fx_cure_panic_state, -1 }, - { "Cure:Petrification", fx_cure_petrified_state, -1 }, - { "Cure:Poison", fx_cure_poisoned_state, -1 }, - { "Cure:Sanctuary", fx_cure_sanctuary_state, -1 }, - { "Cure:Silence", fx_cure_silenced_state, -1 }, - { "Cure:Sleep", fx_cure_sleep_state, -1 }, - { "Cure:Stun", fx_cure_stun_state, -1 }, - { "CurrentHPModifier", fx_current_hp_modifier, -1 }, - { "Damage", fx_damage, -1 }, - { "DamageAnimation", fx_damage_animation, -1 }, - { "DamageBonusModifier", fx_damage_bonus_modifier, -1 }, - { "DamageLuckModifier", fx_damageluck_modifier, -1 }, - { "DamageVsCreature", fx_generic_effect, -1 }, - { "Death", fx_death, -1 }, - { "Death2", fx_death, -1 }, //(iwd2 effect) - { "Death3", fx_death, -1 }, //(iwd2 effect too, Banish) - { "DetectAlignment", fx_detect_alignment, -1 }, - { "DetectIllusionsModifier", fx_detect_illusion_modifier, -1 }, - { "DexterityModifier", fx_dexterity_modifier, -1 }, - { "DimensionDoor", fx_dimension_door, -1 }, - { "DisableButton", fx_disable_button, -1 }, //sets disable button flag - { "DisableChunk", fx_disable_chunk_modifier, -1 }, - { "DisableOverlay", fx_disable_overlay_modifier, -1 }, - { "DisableCasting", fx_disable_spellcasting, -1 }, - { "Disintegrate", fx_disintegrate, -1 }, - { "DispelEffects", fx_dispel_effects, -1 }, - { "DispelSchool", fx_dispel_school, -1 }, - { "DispelSchoolOne", fx_dispel_school_one, -1 }, - { "DispelSecondaryType", fx_dispel_secondary_type, -1 }, - { "DispelSecondaryTypeOne", fx_dispel_secondary_type_one, -1 }, - { "DisplayString", fx_display_string, -1 }, - { "Dither", fx_dither, -1 }, - { "DontJumpModifier", fx_dontjump_modifier, -1 }, - { "DrainItems", fx_drain_items, -1 }, - { "DrainSpells", fx_drain_spells, -1 }, - { "DropWeapon", fx_drop_weapon, -1 }, - { "ElectricityResistanceModifier", fx_electricity_resistance_modifier, -1 }, - { "ExistanceDelayModifier", fx_existance_delay_modifier , -1 }, //unknown - { "ExperienceModifier", fx_experience_modifier, -1 }, - { "ExploreModifier", fx_explore_modifier, -1 }, - { "FamiliarBond", fx_familiar_constitution_loss, -1 }, - { "FamiliarMarker", fx_familiar_marker, -1}, - { "Farsee", fx_farsee, -1}, - { "FatigueModifier", fx_fatigue_modifier, -1 }, - { "FindFamiliar", fx_find_familiar, -1 }, - { "FindTraps", fx_find_traps, -1 }, - { "FindTrapsModifier", fx_find_traps_modifier, -1 }, - { "FireResistanceModifier", fx_fire_resistance_modifier, -1 }, - { "FistDamageModifier", fx_fist_damage_modifier, -1 }, - { "FistHitModifier", fx_fist_to_hit_modifier, -1 }, - { "ForceSurgeModifier", fx_force_surge_modifier, -1 }, - { "ForceVisible", fx_force_visible, -1 }, //not invisible but improved invisible - { "FreeAction", fx_cure_slow_state, -1}, - { "GenerateWish", fx_generate_wish, -1}, - { "GoldModifier", fx_gold_modifier, -1 }, - { "HideInShadowsModifier", fx_hide_in_shadows_modifier, -1}, - { "HLA", fx_generic_effect, -1}, - { "HolyNonCumulative", fx_set_holy_state, -1 }, - { "Icon:Disable", fx_disable_portrait_icon, -1 }, - { "Icon:Display", fx_display_portrait_icon, -1 }, - { "Icon:Remove", fx_remove_portrait_icon, -1 }, - { "Identify", fx_identify, -1 }, - { "IgnoreDialogPause", fx_ignore_dialogpause_modifier, -1 }, - { "IntelligenceModifier", fx_intelligence_modifier, -1 }, - { "IntoxicationModifier", fx_intoxication_modifier, -1 }, - { "InvisibleDetection", fx_see_invisible_modifier, -1 }, - { "Item:CreateDays", fx_create_item_days, -1 }, - { "Item:CreateInSlot", fx_create_item_in_slot, -1 }, - { "Item:CreateInventory", fx_create_inventory_item, -1 }, - { "Item:CreateMagic", fx_create_magic_item, -1 }, - { "Item:Equip", fx_equip_item, -1 }, //71 - { "Item:Remove", fx_remove_item, -1 }, //70 - { "Item:RemoveInventory", fx_remove_inventory_item, -1 }, - { "KillCreatureType", fx_kill_creature_type, -1 }, - { "LevelModifier", fx_level_modifier, -1 }, - { "LevelDrainModifier", fx_leveldrain_modifier, -1 }, - { "LoreModifier", fx_lore_modifier, -1 }, - { "LuckModifier", fx_luck_modifier, -1 }, - { "LuckCumulative", fx_luck_cumulative, -1 }, - { "LuckNonCumulative", fx_luck_non_cumulative, -1 }, - { "MagicalColdResistanceModifier", fx_magical_cold_resistance_modifier, -1 }, - { "MagicalFireResistanceModifier", fx_magical_fire_resistance_modifier, -1 }, - { "MagicalRest", fx_magical_rest, -1 }, - { "MagicDamageResistanceModifier", fx_magic_damage_resistance_modifier, -1 }, - { "MagicResistanceModifier", fx_magic_resistance_modifier, -1 }, - { "MassRaiseDead", fx_mass_raise_dead, -1 }, - { "MaximumHPModifier", fx_maximum_hp_modifier, -1 }, - { "Maze", fx_maze, -1}, - { "MeleeDamageModifier", fx_melee_damage_modifier, -1 }, - { "MeleeHitModifier", fx_melee_to_hit_modifier, -1 }, - { "MinimumHPModifier", fx_minimum_hp_modifier, -1 }, - { "MiscastMagicModifier", fx_miscast_magic_modifier, -1 }, - { "MissileDamageModifier", fx_missile_damage_modifier, -1 }, - { "MissileHitModifier", fx_missile_to_hit_modifier, -1 }, - { "MissilesResistanceModifier", fx_missiles_resistance_modifier, -1 }, - { "MirrorImage", fx_mirror_image, -1 }, - { "MirrorImageModifier", fx_mirror_image_modifier, -1 }, - { "ModifyGlobalVariable", fx_modify_global_variable, -1 }, - { "ModifyLocalVariable", fx_modify_local_variable, -1 }, - { "MonsterSummoning", fx_monster_summoning, -1 }, - { "MoraleBreakModifier", fx_morale_break_modifier, -1 }, - { "MoraleModifier", fx_morale_modifier, -1 }, - { "MovementRateModifier", fx_movement_modifier, -1 }, //fast (7e) - { "MovementRateModifier2", fx_movement_modifier, -1 },//slow (b0) - { "MovementRateModifier3", fx_movement_modifier, -1 },//forced (IWD - 10a) - { "MovementRateModifier4", fx_movement_modifier, -1 },//slow (IWD2 - 1b9) - { "MoveToArea", fx_move_to_area, -1 }, //0xba - { "NoCircleState", fx_no_circle_state, -1 }, - { "NPCBump", fx_npc_bump, -1 }, - { "OffscreenAIModifier", fx_offscreenai_modifier, -1 }, - { "OffhandHitModifier", fx_left_to_hit_modifier, -1 }, - { "OpenLocksModifier", fx_open_locks_modifier, -1 }, - { "Overlay:Entangle", fx_set_entangle_state, -1 }, - { "Overlay:Grease", fx_set_grease_state, -1 }, - { "Overlay:MinorGlobe", fx_set_minorglobe_state, -1 }, - { "Overlay:Sanctuary", fx_set_sanctuary_state, -1 }, - { "Overlay:ShieldGlobe", fx_set_shieldglobe_state, -1 }, - { "Overlay:Web", fx_set_web_state, -1 }, - { "PauseTarget", fx_pause_target, -1 }, //also known as casterhold - { "PickPocketsModifier", fx_pick_pockets_modifier, -1 }, - { "PiercingResistanceModifier", fx_piercing_resistance_modifier, -1 }, - { "PlayMovie", fx_play_movie, -1 }, - { "PlaySound", fx_playsound, -1 }, - { "PlayVisualEffect", fx_play_visual_effect, -1 }, - { "PoisonResistanceModifier", fx_poison_resistance_modifier, -1 }, - { "Polymorph", fx_polymorph, -1}, - { "PortraitChange", fx_portrait_change, -1 }, - { "PowerWordKill", fx_power_word_kill, -1 }, - { "PowerWordSleep", fx_power_word_sleep, -1 }, - { "PowerWordStun", fx_power_word_stun, -1 }, - { "PriestSpellSlotsModifier", fx_bonus_priest_spells, -1 }, - { "Proficiency", fx_proficiency, -1 }, -// { "Protection:Animation", fx_protection_from_animation, -1 }, - { "Protection:Animation", fx_generic_effect, -1 }, - { "Protection:Backstab", fx_no_backstab_modifier, -1 }, - { "Protection:Creature", fx_generic_effect, -1 }, - { "Protection:Opcode", fx_protection_opcode, -1 }, - { "Protection:Opcode2", fx_protection_opcode, -1 }, - { "Protection:Projectile",fx_protection_from_projectile, -1}, - { "Protection:School",fx_generic_effect,-1},//overlay? - { "Protection:SchoolDec",fx_protection_school_dec,-1},//overlay? - { "Protection:SecondaryType",fx_protection_secondary_type,-1},//overlay? - { "Protection:SecondaryTypeDec",fx_protection_secondary_type_dec,-1},//overlay? - { "Protection:Spell",fx_resist_spell,-1},//overlay? - { "Protection:SpellDec",fx_resist_spell_dec,-1},//overlay? - { "Protection:SpellLevel",fx_protection_spelllevel,-1},//overlay? - { "Protection:SpellLevelDec",fx_protection_spelllevel_dec,-1},//overlay? - { "Protection:String", fx_generic_effect, -1 }, - { "Protection:Tracking", fx_protection_from_tracking, -1 }, - { "Protection:Turn", fx_protection_from_turn, -1}, - { "Protection:Weapons", fx_immune_to_weapon, -1}, - { "PuppetMarker", fx_puppet_marker, -1}, - { "ProjectImage", fx_puppet_master, -1}, - { "Reveal:Area", fx_reveal_area, -1 }, - { "Reveal:Creatures", fx_reveal_creatures, -1 }, - { "Reveal:Magic", fx_reveal_magic, -1 }, - { "Reveal:Tracks", fx_reveal_tracks, -1 }, - { "RemoveCurse", fx_remove_curse, -1 }, - { "RemoveImmunity", fx_remove_immunity, -1 }, - { "RemoveMapNote", fx_remove_map_note, -1 }, - { "RemoveProjectile", fx_remove_projectile, -1 }, //removes effects from actor and area - { "RenableButton", fx_renable_button, -1 }, //removes disable button flag - { "RemoveCreature", fx_remove_creature, -1 }, - { "ReplaceCreature", fx_replace_creature, -1 }, - { "ReputationModifier", fx_reputation_modifier, -1 }, - { "RestoreSpells", fx_restore_spell_level, -1 }, - { "RightHitModifier", fx_right_to_hit_modifier, -1 }, - { "SaveVsBreathModifier", fx_save_vs_breath_modifier, -1 }, - { "SaveVsDeathModifier", fx_save_vs_death_modifier, -1 }, - { "SaveVsPolyModifier", fx_save_vs_poly_modifier, -1 }, - { "SaveVsSpellsModifier", fx_save_vs_spell_modifier, -1 }, - { "SaveVsWandsModifier", fx_save_vs_wands_modifier, -1 }, - { "ScreenShake", fx_screenshake, -1 }, - { "ScriptingState", fx_scripting_state, -1 }, - { "Sequencer:Activate", fx_activate_spell_sequencer, -1 }, - { "Sequencer:Create", fx_create_spell_sequencer, -1 }, - { "Sequencer:Store", fx_store_spell_sequencer, -1 }, - { "SetAIScript", fx_set_ai_script, -1 }, - { "SetMapNote", fx_set_map_note, -1 }, - { "SetMeleeEffect", fx_generic_effect, -1 }, - { "SetRangedEffect", fx_generic_effect, -1 }, - { "SetTrap", fx_set_area_effect, -1 }, - { "SetTrapsModifier", fx_set_traps_modifier, -1 }, - { "SexModifier", fx_sex_modifier, -1 }, - { "SlashingResistanceModifier", fx_slashing_resistance_modifier, -1 }, - { "Sparkle", fx_sparkle, -1 }, - { "SpellDurationModifier", fx_spell_duration_modifier, -1 }, - { "Spell:Add", fx_add_innate, -1 }, - { "Spell:Cast", fx_cast_spell, -1 }, - { "Spell:CastPoint", fx_cast_spell_point, -1 }, - { "Spell:Learn", fx_learn_spell, -1 }, - { "Spell:Remove", fx_remove_spell, -1 }, - { "Spelltrap",fx_spelltrap , -1 }, //overlay: spmagglo - { "State:Berserk", fx_set_berserk_state, -1 }, - { "State:Blind", fx_set_blind_state, -1 }, - { "State:Blur", fx_set_blur_state, -1 }, - { "State:Charmed", fx_set_charmed_state, -1 }, //0x05 - { "State:Confused", fx_set_confused_state, -1 }, - { "State:Deafness", fx_set_deaf_state, -1 }, - { "State:DeafnessIWD2", fx_set_deaf_state_iwd2, -1 }, //this is a modified version - { "State:Diseased", fx_set_diseased_state, -1 }, - { "State:Feeblemind", fx_set_feebleminded_state, -1 }, - { "State:Hasted", fx_set_hasted_state, -1 }, - { "State:Haste2", fx_set_hasted_state, -1 }, - { "State:Hold", fx_hold_creature, -1 }, //175 (doesn't work in original iwd2) - { "State:Hold2", fx_hold_creature, -1 },//185 (doesn't work in original iwd2) - { "State:Hold3", fx_hold_creature, -1 },//109 iwd2 - { "State:HoldNoIcon", fx_hold_creature_no_icon, -1 }, //109 - { "State:HoldNoIcon2", fx_hold_creature_no_icon, -1 }, //0xfb (iwd/iwd2) - { "State:HoldNoIcon3", fx_hold_creature_no_icon, -1 }, //0x1a8 (iwd2) - { "State:Imprisonment", fx_imprisonment, -1 }, - { "State:Infravision", fx_set_infravision_state, -1 }, - { "State:Invisible", fx_set_invisible_state, -1 }, //both invis or improved invis - { "State:Nondetection", fx_set_nondetection_state, -1 }, - { "State:Panic", fx_set_panic_state, -1 }, - { "State:Petrification", fx_set_petrified_state, -1 }, - { "State:Poisoned", fx_set_poisoned_state, -1 }, - { "State:Regenerating", fx_set_regenerating_state, -1 }, - { "State:Silenced", fx_set_silenced_state, -1 }, - { "State:Helpless", fx_set_unconscious_state, -1 }, - { "State:Sleep", fx_set_unconscious_state, -1}, - { "State:Slowed", fx_set_slowed_state, -1 }, - { "State:Stun", fx_set_stun_state, -1 }, - { "StealthModifier", fx_stealth_modifier, -1 }, - { "StoneSkinModifier", fx_stoneskin_modifier, -1 }, - { "StoneSkin2Modifier", fx_golem_stoneskin_modifier, -1 }, - { "StrengthModifier", fx_strength_modifier, -1 }, - { "StrengthBonusModifier", fx_strength_bonus_modifier, -1 }, - { "SummonCreature", fx_summon_creature, -1 }, - { "RandomTeleport", fx_teleport_field, -1 }, - { "TeleportToTarget", fx_teleport_to_target, -1 }, - { "TimelessState", fx_timeless_modifier, -1 }, - { "Timestop", fx_timestop, -1}, - { "TitleModifier", fx_title_modifier, -1 }, - { "ToHitModifier", fx_to_hit_modifier, -1 }, - { "ToHitBonusModifier", fx_to_hit_bonus_modifier, -1 }, - { "ToHitVsCreature", fx_generic_effect, -1 }, - { "TrackingModifier", fx_tracking_modifier, -1 }, - { "TransparencyModifier", fx_transparency_modifier, -1 }, - { "Unknown", fx_unknown, -1}, - { "Unlock", fx_knock, -1 }, //open doors/containers - { "UnsummonCreature", fx_unsummon_creature, -1 }, - { "Variable:StoreLocalVariable", fx_local_variable, -1 }, - { "VisualAnimationEffect", fx_visual_animation_effect, -1 }, //unknown - { "VisualRangeModifier", fx_visual_range_modifier, -1 }, - { "VisualSpellHit", fx_visual_spell_hit, -1 }, - { "WildSurgeModifier", fx_wild_surge_modifier, -1 }, - { "WingBuffet", fx_wing_buffet, -1 }, - { "WisdomModifier", fx_wisdom_modifier, -1 }, - { "WizardSpellSlotsModifier", fx_bonus_wizard_spells, -1 }, - { NULL, NULL, 0 }, +static EffectDesc effectnames[] = { + { "*Crash*", fx_crash, EFFECT_NO_ACTOR, -1 }, + { "AcidResistanceModifier", fx_acid_resistance_modifier, 0, -1 }, + { "ACVsCreatureType", fx_generic_effect, 0, -1 }, //0xdb + { "ACVsDamageTypeModifier", fx_ac_vs_damage_type_modifier, 0, -1 }, + { "ACVsDamageTypeModifier2", fx_ac_vs_damage_type_modifier, 0, -1 }, // used in IWD + { "AidNonCumulative", fx_set_aid_state, 0, -1 }, + { "AIIdentifierModifier", fx_ids_modifier, 0, -1 }, + { "AlchemyModifier", fx_alchemy_modifier, 0, -1 }, + { "Alignment:Change", fx_alignment_change, 0, -1 }, + { "Alignment:Invert", fx_alignment_invert, 0, -1 }, + { "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 }, + { "ApplyEffectCurse", fx_apply_effect_curse, 0, -1 }, + { "ApplyEffectItem", fx_apply_effect_item, 0, -1 }, + { "ApplyEffectItemType", fx_apply_effect_item_type, 0, -1 }, + { "ApplyEffectRepeat", fx_apply_effect_repeat, 0, -1 }, + { "CutScene2", fx_cutscene2, EFFECT_NO_ACTOR, -1 }, + { "AttackSpeedModifier", fx_attackspeed_modifier, 0, -1 }, + { "AttacksPerRoundModifier", fx_attacks_per_round_modifier, 0, -1 }, + { "AuraCleansingModifier", fx_auracleansing_modifier, 0, -1 }, + { "SummonDisable", fx_summon_disable, 0, -1 }, //unknown + { "AvatarRemovalModifier", fx_avatar_removal_modifier, 0, -1 }, + { "BackstabModifier", fx_backstab_modifier, 0, -1 }, + { "BerserkStage1Modifier", fx_berserkstage1_modifier, 0, -1 }, + { "BerserkStage2Modifier", fx_berserkstage2_modifier, 0, -1 }, + { "BlessNonCumulative", fx_set_bless_state, 0, -1 }, + { "Bounce:School", fx_bounce_school, 0, -1 }, + { "Bounce:SchoolDec", fx_bounce_school_dec, 0, -1 }, + { "Bounce:SecondaryType", fx_bounce_secondary_type, 0, -1 }, + { "Bounce:SecondaryTypeDec", fx_bounce_secondary_type_dec, 0, -1 }, + { "Bounce:Spell", fx_bounce_spell, 0, -1 }, + { "Bounce:SpellDec", fx_bounce_spell_dec, 0, -1 }, + { "Bounce:SpellLevel", fx_bounce_spelllevel, 0, -1 }, + { "Bounce:SpellLevelDec", fx_bounce_spelllevel_dec, 0, -1 }, + { "Bounce:Opcode", fx_bounce_opcode, 0, -1 }, + { "Bounce:Projectile", fx_bounce_projectile, 0, -1 }, + { "CantUseItem", fx_generic_effect, EFFECT_NO_ACTOR, -1 }, + { "CantUseItemType", fx_generic_effect, 0, -1 }, + { "CanUseAnyItem", fx_can_use_any_item_modifier, 0, -1 }, + { "CastFromList", fx_select_spell, 0, -1 }, + { "CastingGlow", fx_casting_glow, 0, -1 }, + { "CastingGlow2", fx_casting_glow, 0, -1 }, //used in iwd + { "CastingLevelModifier", fx_castinglevel_modifier, 0, -1 }, + { "CastingSpeedModifier", fx_castingspeed_modifier, 0, -1 }, + { "CastSpellOnCondition", fx_cast_spell_on_condition, 0, -1 }, + { "ChangeBardSong", fx_change_bardsong, 0, -1 }, + { "ChangeName", fx_change_name, 0, -1 }, + { "ChangeWeather", fx_change_weather, EFFECT_NO_ACTOR, -1 }, + { "ChantBadNonCumulative", fx_set_chantbad_state, 0, -1 }, + { "ChantNonCumulative", fx_set_chant_state, 0, -1 }, + { "ChaosShieldModifier", fx_chaos_shield_modifier, 0, -1 }, + { "CharismaModifier", fx_charisma_modifier, 0, -1 }, + { "CheckForBerserkModifier", fx_checkforberserk_modifier, 0, -1 }, + { "ColdResistanceModifier", fx_cold_resistance_modifier, 0, -1 }, + { "Color:BriefRGB", fx_brief_rgb, 0, -1 }, + { "Color:GlowRGB", fx_glow_rgb, 0, -1 }, + { "Color:DarkenRGB", fx_darken_rgb, 0, -1 }, + { "Color:SetPalette", fx_set_color_gradient, 0, -1 }, + { "Color:SetRGB", fx_set_color_rgb, 0, -1 }, + { "Color:SetRGBGlobal", fx_set_color_rgb_global, 0, -1 }, //08 + { "Color:PulseRGB", fx_set_color_pulse_rgb, 0, -1 }, //9 + { "Color:PulseRGBGlobal", fx_set_color_pulse_rgb_global, 0, -1 }, //9 + { "ConstitutionModifier", fx_constitution_modifier, 0, -1 }, + { "ControlCreature", fx_set_charmed_state, 0, -1 }, //0xf1 same as charm + { "CreateContingency", fx_create_contingency, 0, -1 }, + { "CriticalHitModifier", fx_critical_hit_modifier, 0, -1 }, + { "CrushingResistanceModifier", fx_crushing_resistance_modifier, 0, -1 }, + { "Cure:Berserk", fx_cure_berserk_state, 0, -1 }, + { "Cure:Blind", fx_cure_blind_state, 0, -1 }, + { "Cure:CasterHold", fx_unpause_caster, 0, -1 }, + { "Cure:Confusion", fx_cure_confused_state, 0, -1 }, + { "Cure:Deafness", fx_cure_deaf_state, 0, -1 }, + { "Cure:Death", fx_cure_dead_state, 0, -1 }, + { "Cure:Defrost", fx_cure_frozen_state, 0, -1 }, + { "Cure:Disease", fx_cure_diseased_state, 0, -1 }, + { "Cure:Feeblemind", fx_cure_feebleminded_state, 0, -1 }, + { "Cure:Hold", fx_cure_hold_state, 0, -1 }, + { "Cure:Imprisonment", fx_freedom, 0, -1 }, + { "Cure:Infravision", fx_cure_infravision_state, 0, -1 }, + { "Cure:Intoxication", fx_cure_intoxication, 0, -1 }, //0xa4 (iwd2 has this working) + { "Cure:Invisible", fx_cure_invisible_state, 0, -1 }, //0x2f + { "Cure:Invisible2", fx_cure_invisible_state, 0, -1 }, //0x74 + //{ "Cure:ImprovedInvisible", fx_cure_improved_invisible_state, 0, -1 }, + { "Cure:LevelDrain", fx_cure_leveldrain, 0, -1 }, //restoration + { "Cure:Nondetection", fx_cure_nondetection_state, 0, -1 }, + { "Cure:Panic", fx_cure_panic_state, 0, -1 }, + { "Cure:Petrification", fx_cure_petrified_state, 0, -1 }, + { "Cure:Poison", fx_cure_poisoned_state, 0, -1 }, + { "Cure:Sanctuary", fx_cure_sanctuary_state, 0, -1 }, + { "Cure:Silence", fx_cure_silenced_state, 0, -1 }, + { "Cure:Sleep", fx_cure_sleep_state, 0, -1 }, + { "Cure:Stun", fx_cure_stun_state, 0, -1 }, + { "CurrentHPModifier", fx_current_hp_modifier, EFFECT_DICED, -1 }, + { "Damage", fx_damage, EFFECT_DICED, -1 }, + { "DamageAnimation", fx_damage_animation, 0, -1 }, + { "DamageBonusModifier", fx_damage_bonus_modifier, 0, -1 }, + { "DamageLuckModifier", fx_damageluck_modifier, 0, -1 }, + { "DamageVsCreature", fx_generic_effect, 0, -1 }, + { "Death", fx_death, 0, -1 }, + { "Death2", fx_death, 0, -1 }, //(iwd2 effect) + { "Death3", fx_death, 0, -1 }, //(iwd2 effect too, Banish) + { "DetectAlignment", fx_detect_alignment, 0, -1 }, + { "DetectIllusionsModifier", fx_detect_illusion_modifier, 0, -1 }, + { "DexterityModifier", fx_dexterity_modifier, 0, -1 }, + { "DimensionDoor", fx_dimension_door, 0, -1 }, + { "DisableButton", fx_disable_button, 0, -1 }, //sets disable button flag + { "DisableChunk", fx_disable_chunk_modifier, 0, -1 }, + { "DisableOverlay", fx_disable_overlay_modifier, 0, -1 }, + { "DisableCasting", fx_disable_spellcasting, 0, -1 }, + { "Disintegrate", fx_disintegrate, 0, -1 }, + { "DispelEffects", fx_dispel_effects, 0, -1 }, + { "DispelSchool", fx_dispel_school, 0, -1 }, + { "DispelSchoolOne", fx_dispel_school_one, 0, -1 }, + { "DispelSecondaryType", fx_dispel_secondary_type, 0, -1 }, + { "DispelSecondaryTypeOne", fx_dispel_secondary_type_one, 0, -1 }, + { "DisplayString", fx_display_string, 0, -1 }, + { "Dither", fx_dither, 0, -1 }, + { "DontJumpModifier", fx_dontjump_modifier, 0, -1 }, + { "DrainItems", fx_drain_items, 0, -1 }, + { "DrainSpells", fx_drain_spells, 0, -1 }, + { "DropWeapon", fx_drop_weapon, 0, -1 }, + { "ElectricityResistanceModifier", fx_electricity_resistance_modifier, 0, -1 }, + { "ExistanceDelayModifier", fx_existance_delay_modifier , 0, -1 }, //unknown + { "ExperienceModifier", fx_experience_modifier, 0, -1 }, + { "ExploreModifier", fx_explore_modifier, 0, -1 }, + { "FamiliarBond", fx_familiar_constitution_loss, 0, -1 }, + { "FamiliarMarker", fx_familiar_marker, 0, -1 }, + { "Farsee", fx_farsee, 0, -1 }, + { "FatigueModifier", fx_fatigue_modifier, 0, -1 }, + { "FindFamiliar", fx_find_familiar, 0, -1 }, + { "FindTraps", fx_find_traps, 0, -1 }, + { "FindTrapsModifier", fx_find_traps_modifier, 0, -1 }, + { "FireResistanceModifier", fx_fire_resistance_modifier, 0, -1 }, + { "FistDamageModifier", fx_fist_damage_modifier, 0, -1 }, + { "FistHitModifier", fx_fist_to_hit_modifier, 0, -1 }, + { "ForceSurgeModifier", fx_force_surge_modifier, 0, -1 }, + { "ForceVisible", fx_force_visible, 0, -1 }, //not invisible but improved invisible + { "FreeAction", fx_cure_slow_state, 0, -1 }, + { "GenerateWish", fx_generate_wish, 0, -1 }, + { "GoldModifier", fx_gold_modifier, 0, -1 }, + { "HideInShadowsModifier", fx_hide_in_shadows_modifier, 0, -1 }, + { "HLA", fx_generic_effect, 0, -1 }, + { "HolyNonCumulative", fx_set_holy_state, 0, -1 }, + { "Icon:Disable", fx_disable_portrait_icon, 0, -1 }, + { "Icon:Display", fx_display_portrait_icon, 0, -1 }, + { "Icon:Remove", fx_remove_portrait_icon, 0, -1 }, + { "Identify", fx_identify, 0, -1 }, + { "IgnoreDialogPause", fx_ignore_dialogpause_modifier, 0, -1 }, + { "IntelligenceModifier", fx_intelligence_modifier, 0, -1 }, + { "IntoxicationModifier", fx_intoxication_modifier, 0, -1 }, + { "InvisibleDetection", fx_see_invisible_modifier, 0, -1 }, + { "Item:CreateDays", fx_create_item_days, 0, -1 }, + { "Item:CreateInSlot", fx_create_item_in_slot, 0, -1 }, + { "Item:CreateInventory", fx_create_inventory_item, 0, -1 }, + { "Item:CreateMagic", fx_create_magic_item, 0, -1 }, + { "Item:Equip", fx_equip_item, 0, -1 }, //71 + { "Item:Remove", fx_remove_item, 0, -1 }, //70 + { "Item:RemoveInventory", fx_remove_inventory_item, 0, -1 }, + { "KillCreatureType", fx_kill_creature_type, 0, -1 }, + { "LevelModifier", fx_level_modifier, 0, -1 }, + { "LevelDrainModifier", fx_leveldrain_modifier, 0, -1 }, + { "LoreModifier", fx_lore_modifier, 0, -1 }, + { "LuckModifier", fx_luck_modifier, 0, -1 }, + { "LuckCumulative", fx_luck_cumulative, 0, -1 }, + { "LuckNonCumulative", fx_luck_non_cumulative, 0, -1 }, + { "MagicalColdResistanceModifier", fx_magical_cold_resistance_modifier, 0, -1 }, + { "MagicalFireResistanceModifier", fx_magical_fire_resistance_modifier, 0, -1 }, + { "MagicalRest", fx_magical_rest, 0, -1 }, + { "MagicDamageResistanceModifier", fx_magic_damage_resistance_modifier, 0, -1 }, + { "MagicResistanceModifier", fx_magic_resistance_modifier, 0, -1 }, + { "MassRaiseDead", fx_mass_raise_dead, EFFECT_NO_ACTOR, -1 }, + { "MaximumHPModifier", fx_maximum_hp_modifier, EFFECT_DICED, -1 }, + { "Maze", fx_maze, 0, -1 }, + { "MeleeDamageModifier", fx_melee_damage_modifier, 0, -1 }, + { "MeleeHitModifier", fx_melee_to_hit_modifier, 0, -1 }, + { "MinimumHPModifier", fx_minimum_hp_modifier, 0, -1 }, + { "MiscastMagicModifier", fx_miscast_magic_modifier, 0, -1 }, + { "MissileDamageModifier", fx_missile_damage_modifier, 0, -1 }, + { "MissileHitModifier", fx_missile_to_hit_modifier, 0, -1 }, + { "MissilesResistanceModifier", fx_missiles_resistance_modifier, 0, -1 }, + { "MirrorImage", fx_mirror_image, 0, -1 }, + { "MirrorImageModifier", fx_mirror_image_modifier, 0, -1 }, + { "ModifyGlobalVariable", fx_modify_global_variable, EFFECT_NO_ACTOR, -1 }, + { "ModifyLocalVariable", fx_modify_local_variable, 0, -1 }, + { "MonsterSummoning", fx_monster_summoning, EFFECT_NO_ACTOR, -1 }, + { "MoraleBreakModifier", fx_morale_break_modifier, 0, -1 }, + { "MoraleModifier", fx_morale_modifier, 0, -1 }, + { "MovementRateModifier", fx_movement_modifier, 0, -1 }, //fast (7e) + { "MovementRateModifier2", fx_movement_modifier, 0, -1 },//slow (b0) + { "MovementRateModifier3", fx_movement_modifier, 0, -1 },//forced (IWD - 10a) + { "MovementRateModifier4", fx_movement_modifier, 0, -1 },//slow (IWD2 - 1b9) + { "MoveToArea", fx_move_to_area, 0, -1 }, //0xba + { "NoCircleState", fx_no_circle_state, 0, -1 }, + { "NPCBump", fx_npc_bump, 0, -1 }, + { "OffscreenAIModifier", fx_offscreenai_modifier, 0, -1 }, + { "OffhandHitModifier", fx_left_to_hit_modifier, 0, -1 }, + { "OpenLocksModifier", fx_open_locks_modifier, 0, -1 }, + { "Overlay:Entangle", fx_set_entangle_state, 0, -1 }, + { "Overlay:Grease", fx_set_grease_state, 0, -1 }, + { "Overlay:MinorGlobe", fx_set_minorglobe_state, 0, -1 }, + { "Overlay:Sanctuary", fx_set_sanctuary_state, 0, -1 }, + { "Overlay:ShieldGlobe", fx_set_shieldglobe_state, 0, -1 }, + { "Overlay:Web", fx_set_web_state, 0, -1 }, + { "PauseTarget", fx_pause_target, 0, -1 }, //also known as casterhold + { "PickPocketsModifier", fx_pick_pockets_modifier, 0, -1 }, + { "PiercingResistanceModifier", fx_piercing_resistance_modifier, 0, -1 }, + { "PlayMovie", fx_play_movie, EFFECT_NO_ACTOR, -1 }, + { "PlaySound", fx_playsound, EFFECT_NO_ACTOR, -1 }, + { "PlayVisualEffect", fx_play_visual_effect, 0, -1 }, + { "PoisonResistanceModifier", fx_poison_resistance_modifier, 0, -1 }, + { "Polymorph", fx_polymorph, 0, -1 }, + { "PortraitChange", fx_portrait_change, 0, -1 }, + { "PowerWordKill", fx_power_word_kill, 0, -1 }, + { "PowerWordSleep", fx_power_word_sleep, 0, -1 }, + { "PowerWordStun", fx_power_word_stun, 0, -1 }, + { "PriestSpellSlotsModifier", fx_bonus_priest_spells, 0, -1 }, + { "Proficiency", fx_proficiency, 0, -1 }, +// { "Protection:Animation", fx_protection_from_animation, 0, -1 }, + { "Protection:Animation", fx_generic_effect, 0, -1 }, + { "Protection:Backstab", fx_no_backstab_modifier, 0, -1 }, + { "Protection:Creature", fx_generic_effect, 0, -1 }, + { "Protection:Opcode", fx_protection_opcode, 0, -1 }, + { "Protection:Opcode2", fx_protection_opcode, 0, -1 }, + { "Protection:Projectile",fx_protection_from_projectile, 0, -1 }, + { "Protection:School",fx_generic_effect, 0, -1 },//overlay? + { "Protection:SchoolDec",fx_protection_school_dec, 0, -1 },//overlay? + { "Protection:SecondaryType",fx_protection_secondary_type, 0, -1 },//overlay? + { "Protection:SecondaryTypeDec",fx_protection_secondary_type_dec, 0, -1 },//overlay? + { "Protection:Spell",fx_resist_spell, 0, -1 },//overlay? + { "Protection:SpellDec",fx_resist_spell_dec, 0, -1 },//overlay? + { "Protection:SpellLevel",fx_protection_spelllevel, 0, -1 },//overlay? + { "Protection:SpellLevelDec",fx_protection_spelllevel_dec, 0, -1 },//overlay? + { "Protection:String", fx_generic_effect, 0, -1 }, + { "Protection:Tracking", fx_protection_from_tracking, 0, -1 }, + { "Protection:Turn", fx_protection_from_turn, 0, -1 }, + { "Protection:Weapons", fx_immune_to_weapon, EFFECT_NO_ACTOR, -1 }, + { "PuppetMarker", fx_puppet_marker, 0, -1 }, + { "ProjectImage", fx_puppet_master, 0, -1 }, + { "Reveal:Area", fx_reveal_area, EFFECT_NO_ACTOR, -1 }, + { "Reveal:Creatures", fx_reveal_creatures, 0, -1 }, + { "Reveal:Magic", fx_reveal_magic, 0, -1 }, + { "Reveal:Tracks", fx_reveal_tracks, 0, -1 }, + { "RemoveCurse", fx_remove_curse, 0, -1 }, + { "RemoveImmunity", fx_remove_immunity, 0, -1 }, + { "RemoveMapNote", fx_remove_map_note, EFFECT_NO_ACTOR, -1 }, + { "RemoveProjectile", fx_remove_projectile, 0, -1 }, //removes effects from actor and area + { "RenableButton", fx_renable_button, 0, -1 }, //removes disable button flag + { "RemoveCreature", fx_remove_creature, EFFECT_NO_ACTOR, -1 }, + { "ReplaceCreature", fx_replace_creature, 0, -1 }, + { "ReputationModifier", fx_reputation_modifier, 0, -1 }, + { "RestoreSpells", fx_restore_spell_level, 0, -1 }, + { "RightHitModifier", fx_right_to_hit_modifier, 0, -1 }, + { "SaveVsBreathModifier", fx_save_vs_breath_modifier, 0, -1 }, + { "SaveVsDeathModifier", fx_save_vs_death_modifier, 0, -1 }, + { "SaveVsPolyModifier", fx_save_vs_poly_modifier, 0, -1 }, + { "SaveVsSpellsModifier", fx_save_vs_spell_modifier, 0, -1 }, + { "SaveVsWandsModifier", fx_save_vs_wands_modifier, 0, -1 }, + { "ScreenShake", fx_screenshake, EFFECT_NO_ACTOR, -1 }, + { "ScriptingState", fx_scripting_state, 0, -1 }, + { "Sequencer:Activate", fx_activate_spell_sequencer, 0, -1 }, + { "Sequencer:Create", fx_create_spell_sequencer, 0, -1 }, + { "Sequencer:Store", fx_store_spell_sequencer, 0, -1 }, + { "SetAIScript", fx_set_ai_script, 0, -1 }, + { "SetMapNote", fx_set_map_note, EFFECT_NO_ACTOR, -1 }, + { "SetMeleeEffect", fx_generic_effect, 0, -1 }, + { "SetRangedEffect", fx_generic_effect, 0, -1 }, + { "SetTrap", fx_set_area_effect, 0, -1 }, + { "SetTrapsModifier", fx_set_traps_modifier, 0, -1 }, + { "SexModifier", fx_sex_modifier, 0, -1 }, + { "SlashingResistanceModifier", fx_slashing_resistance_modifier, 0, -1 }, + { "Sparkle", fx_sparkle, 0, -1 }, + { "SpellDurationModifier", fx_spell_duration_modifier, 0, -1 }, + { "Spell:Add", fx_add_innate, 0, -1 }, + { "Spell:Cast", fx_cast_spell, 0, -1 }, + { "Spell:CastPoint", fx_cast_spell_point, 0, -1 }, + { "Spell:Learn", fx_learn_spell, 0, -1 }, + { "Spell:Remove", fx_remove_spell, 0, -1 }, + { "Spelltrap",fx_spelltrap , 0, -1 }, //overlay: spmagglo + { "State:Berserk", fx_set_berserk_state, 0, -1 }, + { "State:Blind", fx_set_blind_state, 0, -1 }, + { "State:Blur", fx_set_blur_state, 0, -1 }, + { "State:Charmed", fx_set_charmed_state, EFFECT_NO_LEVEL_CHECK, -1 }, //0x05 + { "State:Confused", fx_set_confused_state, 0, -1 }, + { "State:Deafness", fx_set_deaf_state, 0, -1 }, + { "State:DeafnessIWD2", fx_set_deaf_state_iwd2, 0, -1 }, //this is a modified version + { "State:Diseased", fx_set_diseased_state, 0, -1 }, + { "State:Feeblemind", fx_set_feebleminded_state, 0, -1 }, + { "State:Hasted", fx_set_hasted_state, 0, -1 }, + { "State:Haste2", fx_set_hasted_state, 0, -1 }, + { "State:Hold", fx_hold_creature, 0, -1 }, //175 (doesn't work in original iwd2) + { "State:Hold2", fx_hold_creature, 0, -1 },//185 (doesn't work in original iwd2) + { "State:Hold3", fx_hold_creature, 0, -1 },//109 iwd2 + { "State:HoldNoIcon", fx_hold_creature_no_icon, 0, -1 }, //109 + { "State:HoldNoIcon2", fx_hold_creature_no_icon, 0, -1 }, //0xfb (iwd/iwd2) + { "State:HoldNoIcon3", fx_hold_creature_no_icon, 0, -1 }, //0x1a8 (iwd2) + { "State:Imprisonment", fx_imprisonment, 0, -1 }, + { "State:Infravision", fx_set_infravision_state, 0, -1 }, + { "State:Invisible", fx_set_invisible_state, 0, -1 }, //both invis or improved invis + { "State:Nondetection", fx_set_nondetection_state, 0, -1 }, + { "State:Panic", fx_set_panic_state, 0, -1 }, + { "State:Petrification", fx_set_petrified_state, 0, -1 }, + { "State:Poisoned", fx_set_poisoned_state, 0, -1 }, + { "State:Regenerating", fx_set_regenerating_state, 0, -1 }, + { "State:Silenced", fx_set_silenced_state, 0, -1 }, + { "State:Helpless", fx_set_unconscious_state, 0, -1 }, + { "State:Sleep", fx_set_unconscious_state, 0, -1 }, + { "State:Slowed", fx_set_slowed_state, 0, -1 }, + { "State:Stun", fx_set_stun_state, 0, -1 }, + { "StealthModifier", fx_stealth_modifier, 0, -1 }, + { "StoneSkinModifier", fx_stoneskin_modifier, 0, -1 }, + { "StoneSkin2Modifier", fx_golem_stoneskin_modifier, 0, -1 }, + { "StrengthModifier", fx_strength_modifier, 0, -1 }, + { "StrengthBonusModifier", fx_strength_bonus_modifier, 0, -1 }, + { "SummonCreature", fx_summon_creature, EFFECT_NO_ACTOR, -1 }, + { "RandomTeleport", fx_teleport_field, 0, -1 }, + { "TeleportToTarget", fx_teleport_to_target, 0, -1 }, + { "TimelessState", fx_timeless_modifier, 0, -1 }, + { "Timestop", fx_timestop, 0, -1 }, + { "TitleModifier", fx_title_modifier, 0, -1 }, + { "ToHitModifier", fx_to_hit_modifier, 0, -1 }, + { "ToHitBonusModifier", fx_to_hit_bonus_modifier, 0, -1 }, + { "ToHitVsCreature", fx_generic_effect, 0, -1 }, + { "TrackingModifier", fx_tracking_modifier, 0, -1 }, + { "TransparencyModifier", fx_transparency_modifier, 0, -1 }, + { "Unknown", fx_unknown, EFFECT_NO_ACTOR, -1 }, + { "Unlock", fx_knock, EFFECT_NO_ACTOR, -1 }, //open doors/containers + { "UnsummonCreature", fx_unsummon_creature, 0, -1 }, + { "Variable:StoreLocalVariable", fx_local_variable, 0, -1 }, + { "VisualAnimationEffect", fx_visual_animation_effect, 0, -1 }, //unknown + { "VisualRangeModifier", fx_visual_range_modifier, 0, -1 }, + { "VisualSpellHit", fx_visual_spell_hit, 0, -1 }, + { "WildSurgeModifier", fx_wild_surge_modifier, 0, -1 }, + { "WingBuffet", fx_wing_buffet, 0, -1 }, + { "WisdomModifier", fx_wisdom_modifier, 0, -1 }, + { "WizardSpellSlotsModifier", fx_bonus_wizard_spells, 0, -1 }, + { NULL, NULL, 0, 0 }, }; static void Cleanup() @@ -771,7 +774,7 @@ static void Cleanup() void RegisterCoreOpcodes() { - core->RegisterOpcodes( sizeof( effectnames ) / sizeof( EffectRef ) - 1, effectnames ); + core->RegisterOpcodes( sizeof( effectnames ) / sizeof( EffectDesc ) - 1, effectnames ); enhanced_effects=!!core->HasFeature(GF_ENHANCED_EFFECTS); pstflags=!!core->HasFeature(GF_PST_STATE_FLAGS); default_spell_hit.SequenceFlags|=IE_VVC_BAM; @@ -852,22 +855,12 @@ inline Actor *GetNearestEnemyOf(Map *map, Actor *origin, int whoseeswho) return ac; } -inline Scriptable *GetCaster(Scriptable *Owner, Effect *fx) { - if (fx->FirstApply) { - fx->CasterID = Owner ? Owner->GetGlobalID() : 0; - return Owner; - } else { - return core->GetGame()->GetActorByGlobalID(fx->CasterID); - } - return NULL; -} - //resurrect code used in many places void Resurrect(Scriptable *Owner, Actor *target, Effect *fx, Point &p) { - Scriptable *caster = GetCaster(Owner, fx); + Scriptable *caster = GetCasterObject(); if (!caster) { - caster = Owner; // IE stores the enemyally in the effect instead + caster = Owner; } Map *area = caster->GetCurrentArea(); @@ -958,9 +951,9 @@ int fx_attacks_per_round_modifier (Scriptable* /*Owner*/, Actor* target, Effect* // 0x02 Cure:Sleep (Awaken) // this effect clears the STATE_SLEEP (1) bit, but clearing it alone wouldn't remove the // unconscious effect, which is combined with STATE_HELPLESS (0x20+1) -static EffectRef fx_set_sleep_state_ref={"State:Helpless",NULL,-1}; +static EffectRef fx_set_sleep_state_ref = { "State:Helpless", -1 }; //this reference is used by many other effects -static EffectRef fx_display_portrait_icon_ref={"Icon:Display",NULL,-1}; +static EffectRef fx_display_portrait_icon_ref = { "Icon:Display", -1 }; int fx_cure_sleep_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -1021,7 +1014,7 @@ int fx_set_berserk_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 0x04 Cure:Berserk // this effect clears the STATE_BERSERK (2) bit, but bg2 actually ignores the bit // it also removes effect 04 -static EffectRef fx_set_berserk_state_ref={"State:Berserk",NULL,-1}; +static EffectRef fx_set_berserk_state_ref = { "State:Berserk", -1 }; int fx_cure_berserk_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -1051,13 +1044,26 @@ int fx_set_charmed_state (Scriptable* Owner, Actor* target, Effect* fx) return FX_NOT_APPLIED; } - Scriptable *caster = GetCaster(Owner, fx); - if (!caster) caster = Owner; // IE stores the enemyally in the effect instead - bool enemyally = true; - if (caster->Type==ST_ACTOR) { - enemyally = ((Actor *) caster)->GetStat(IE_EA)>EA_GOODCUTOFF; //or evilcutoff? + bool playercharmed; + bool casterenemy; + if (fx->FirstApply) { + Scriptable *caster = GetCasterObject(); + if (!caster) caster = Owner; + if (caster->Type==ST_ACTOR) { + casterenemy = ((Actor *) caster)->GetStat(IE_EA)>EA_GOODCUTOFF; //or evilcutoff? + } else { + casterenemy = target->GetStat(IE_EA)>EA_GOODCUTOFF; + } + fx->DiceThrown=casterenemy; + + playercharmed = target->InParty; + fx->DiceSides = playercharmed; + } else { + casterenemy = fx->DiceThrown; + playercharmed = fx->DiceSides; } + switch (fx->Parameter2) { case 0: //charmed (target neutral after charm) if (fx->FirstApply) { @@ -1109,7 +1115,11 @@ int fx_set_charmed_state (Scriptable* Owner, Actor* target, Effect* fx) } STATE_SET( STATE_CHARMED ); - STAT_SET_PCF( IE_EA, enemyally?EA_ENEMY:EA_CHARMED ); + if (playercharmed) { + STAT_SET_PCF( IE_EA, casterenemy?EA_CHARMEDPC:EA_CHARMED ); + } else { + STAT_SET_PCF( IE_EA, casterenemy?EA_ENEMY:EA_CHARMED ); + } //don't stick if permanent return FX_PERMANENT; } @@ -1200,7 +1210,7 @@ int fx_constitution_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) } // 0x0B Cure:Poison -static EffectRef fx_poisoned_state_ref={"State:Poisoned",NULL,-1}; +static EffectRef fx_poisoned_state_ref = { "State:Poisoned", -1 }; int fx_cure_poisoned_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -1214,7 +1224,7 @@ int fx_cure_poisoned_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 0x0c Damage // this is a very important effect -int fx_damage (Scriptable* Owner, Actor* target, Effect* fx) +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 ); //save for half damage type @@ -1223,7 +1233,7 @@ int fx_damage (Scriptable* Owner, Actor* target, Effect* fx) if (modtype==3) { modtype&=~3; } - Scriptable *caster = GetCaster(Owner, fx); + Scriptable *caster = GetCasterObject(); target->Damage(fx->Parameter1, damagetype, caster, modtype); //this effect doesn't stick @@ -1341,7 +1351,7 @@ int fx_dexterity_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) return FX_PERMANENT; } -static EffectRef fx_set_slow_state_ref={"State:Slowed",NULL,-1}; +static EffectRef fx_set_slow_state_ref = { "State:Slowed", -1 }; // 0x10 State:Hasted // this function removes slowed state, or sets hasted state int fx_set_hasted_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) @@ -1586,7 +1596,7 @@ 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) +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 ); STATE_SET( STATE_POISONED ); @@ -1625,7 +1635,7 @@ int fx_set_poisoned_state (Scriptable* Owner, Actor* target, Effect* fx) return FX_APPLIED; } - Scriptable *caster = GetCaster(Owner, fx); + Scriptable *caster = GetCasterObject(); //percent target->Damage(damage, DAMAGE_POISON, caster); @@ -1633,8 +1643,8 @@ int fx_set_poisoned_state (Scriptable* Owner, Actor* target, Effect* fx) } // 0x1a RemoveCurse -static EffectRef fx_apply_effect_curse_ref={"ApplyEffectCurse",NULL,-1}; -static EffectRef fx_pst_jumble_curse_ref={"JumbleCurse",NULL,-1}; +static EffectRef fx_apply_effect_curse_ref = { "ApplyEffectCurse", -1 }; +static EffectRef fx_pst_jumble_curse_ref = { "JumbleCurse", -1 }; // gemrb extension: if the resource field is filled, it will remove curse only from the specified item int fx_remove_curse (Scriptable* /*Owner*/, Actor* target, Effect* fx) @@ -1788,7 +1798,7 @@ int fx_set_silenced_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) return FX_APPLIED; } -static EffectRef fx_animation_stance_ref = {"AnimationStateChange",NULL,-1}; +static EffectRef fx_animation_stance_ref = { "AnimationStateChange", -1 }; // 0x27 State:Helpless // this effect sets both bits, but 'awaken' only removes the sleep bit @@ -1824,7 +1834,7 @@ int fx_set_unconscious_state (Scriptable* Owner, Actor* target, Effect* fx) // 0x28 State:Slowed // this function removes hasted state, or sets slowed state -static EffectRef fx_set_haste_state_ref={"State:Hasted",NULL,-1}; +static EffectRef fx_set_haste_state_ref = { "State:Hasted", -1 }; int fx_set_slowed_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -1911,7 +1921,9 @@ 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 ); ////how strength: value is based on class + ////pst power of one also depends on this! if (fx->Parameter2==3) { + //TODO: strextra for stats>=18 fx->Parameter1 = core->Roll(1,SpellAbilityDieRoll(target,1),0); fx->Parameter2 = 0; } @@ -1970,8 +1982,8 @@ int fx_set_stun_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) } // 0x2E Cure:Stun -static EffectRef fx_set_stun_state_ref={"State:Stun",NULL,-1}; -static EffectRef fx_hold_creature_no_icon_ref={"State:HoldNoIcon",NULL,-1}; +static EffectRef fx_set_stun_state_ref = { "State:Stun", -1 }; +static EffectRef fx_hold_creature_no_icon_ref = { "State:HoldNoIcon", -1 }; int fx_cure_stun_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -1986,7 +1998,7 @@ int fx_cure_stun_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 0x2F Cure:Invisible // 0x74 Cure:Invisible2 -static EffectRef fx_set_invisible_state_ref={"State:Invisible",NULL,-1}; +static EffectRef fx_set_invisible_state_ref = { "State:Invisible", -1 }; int fx_cure_invisible_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -2003,7 +2015,7 @@ int fx_cure_invisible_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) } // 0x30 Cure:Silence -static EffectRef fx_set_silenced_state_ref={"State:Silenced",NULL,-1}; +static EffectRef fx_set_silenced_state_ref = { "State:Silenced", -1 }; int fx_cure_silenced_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -2064,7 +2076,7 @@ int fx_glow_rgb (Scriptable* /*Owner*/, Actor* target, Effect* fx) } // 0x35 AnimationIDModifier -static EffectRef fx_animation_id_modifier_ref={"AnimationIDModifier",NULL,-1}; +static EffectRef fx_animation_id_modifier_ref = { "AnimationIDModifier", -1 }; int fx_animation_id_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -2095,7 +2107,7 @@ int fx_to_hit_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) } // 0x37 KillCreatureType -static EffectRef fx_death_ref={"Death",NULL,-1}; +static EffectRef fx_death_ref = { "Death", -1 }; int fx_kill_creature_type (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -2278,7 +2290,7 @@ int fx_set_infravision_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) } // 0x40 Cure:Infravision -static EffectRef fx_set_infravision_state_ref={"State:Infravision",NULL,-1}; +static EffectRef fx_set_infravision_state_ref = { "State:Infravision", -1 }; int fx_cure_infravision_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -2341,13 +2353,6 @@ 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 (!target) { - return FX_NOT_APPLIED; - } - - if (!target->GetCurrentArea()) { - return FX_APPLIED; - } //summon creature (resource), play vvc (resource2) //creature's lastsummoner is Owner @@ -2397,7 +2402,7 @@ int fx_set_nondetection_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) } // 0x46 Cure:Nondetection -static EffectRef fx_set_nondetection_state_ref={"State:Nondetection",NULL,-1}; +static EffectRef fx_set_nondetection_state_ref = { "State:Nondetection", -1 }; int fx_cure_nondetection_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -2477,6 +2482,21 @@ 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 ); + //pst power word blind projectile support + if (fx->Parameter2==1) { + fx->Parameter2 = 0; + int stat = target->GetSafeStat(IE_HITPOINTS); + if (stat<25) { + stat = core->Roll(1,240,150); + } else if (stat<50) { + stat = core->Roll(1,120,70); + } else if (stat<100) { + stat = core->Roll(1,30,15); + } else stat = 0; + fx->Duration = core->GetGame()->GameTime+stat; + + } + //don't do this effect twice (bug exists in BG2, but fixed in IWD2) if (!STATE_GET(STATE_BLIND)) { STATE_SET( STATE_BLIND ); @@ -2489,7 +2509,7 @@ int fx_set_blind_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) } // 0x4b Cure:Blind -static EffectRef fx_set_blind_state_ref={"State:Blind",NULL,-1}; +static EffectRef fx_set_blind_state_ref = { "State:Blind", -1 }; int fx_cure_blind_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -2512,7 +2532,7 @@ int fx_set_feebleminded_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) } // 0x4d Cure:Feeblemind -static EffectRef fx_set_feebleminded_state_ref={"State:Feeblemind",NULL,-1}; +static EffectRef fx_set_feebleminded_state_ref = { "State:Feeblemind", -1 }; int fx_cure_feebleminded_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -2524,7 +2544,7 @@ int fx_cure_feebleminded_state (Scriptable* /*Owner*/, Actor* target, Effect* fx } // 0x4e State:Diseased -int fx_set_diseased_state (Scriptable* Owner, Actor* target, Effect* fx) +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 (STATE_GET(STATE_DEAD|STATE_PETRIFIED|STATE_FROZEN) ) { @@ -2582,7 +2602,7 @@ int fx_set_diseased_state (Scriptable* Owner, Actor* target, Effect* fx) break; } //percent - Scriptable *caster = GetCaster(Owner, fx); + Scriptable *caster = GetCasterObject(); if (damage) { target->Damage(damage, DAMAGE_POISON, caster); @@ -2592,7 +2612,7 @@ int fx_set_diseased_state (Scriptable* Owner, Actor* target, Effect* fx) // 0x4f Cure:Disease -static EffectRef fx_diseased_state_ref={"State:Diseased",NULL,-1}; +static EffectRef fx_diseased_state_ref = { "State:Diseased", -1 }; int fx_cure_diseased_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -2649,8 +2669,8 @@ int fx_set_deaf_state_iwd2 (Scriptable* /*Owner*/, Actor* target, Effect* fx) } // 0x51 Cure:Deafness -static EffectRef fx_deaf_state_ref={"State:Deafness",NULL,-1}; -static EffectRef fx_deaf_state_iwd2_ref={"State:DeafnessIWD2",NULL,-1}; +static EffectRef fx_deaf_state_ref = { "State:Deafness", -1 }; +static EffectRef fx_deaf_state_iwd2_ref = { "State:DeafnessIWD2", -1 }; //removes the deafness effect int fx_cure_deaf_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) @@ -2981,7 +3001,7 @@ int fx_reputation_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 0x6f Item:CreateMagic -static EffectRef fx_remove_item_ref={"Item:Remove",NULL,-1}; +static EffectRef fx_remove_item_ref = { "Item:Remove", -1 }; int fx_create_magic_item (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -3103,7 +3123,14 @@ int fx_detect_alignment (Scriptable* /*Owner*/, Actor* target, Effect* fx) 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 ); - Map *map = target->GetCurrentArea(); + Map *map = NULL; + + if (target) { + map = target->GetCurrentArea(); + } + else { + map = core->GetGame()->GetCurrentArea(); + } if (!map) { return FX_APPLIED; } @@ -3125,7 +3152,7 @@ int fx_reveal_creatures (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx) } // 0x77 MirrorImage -static EffectRef fx_mirror_image_modifier_ref={"MirrorImageModifier",NULL,-1}; +static EffectRef fx_mirror_image_modifier_ref = { "MirrorImageModifier", -1 }; int fx_mirror_image (Scriptable* Owner, Actor* target, Effect* fx) { @@ -3236,7 +3263,7 @@ int fx_visual_animation_effect (Scriptable* /*Owner*/, Actor* /*target*/, Effect } // 0x7a Item:CreateInventory -static EffectRef fx_remove_inventory_item_ref={"Item:RemoveInventory",NULL,-1}; +static EffectRef fx_remove_inventory_item_ref = { "Item:RemoveInventory", -1 }; int fx_create_inventory_item (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -3409,7 +3436,7 @@ int fx_monster_summoning (Scriptable* Owner, Actor* target, Effect* fx) //caster may be important here (Source), even if currently the EA modifiers //don't use it - Scriptable *caster = GetCaster(Owner, fx); + Scriptable *caster = GetCasterObject(); core->SummonCreature(monster, hit, caster, target, p, eamod, level, newfx); delete newfx; return FX_NOT_APPLIED; @@ -3472,7 +3499,7 @@ int fx_set_aid_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 0x82 BlessNonCumulative -static EffectRef fx_bane_ref={"Bane",NULL,-1}; +static EffectRef fx_bane_ref = { "Bane", -1 }; int fx_set_bless_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -3562,7 +3589,7 @@ int fx_set_petrified_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) } // 0x87 Polymorph -static EffectRef fx_polymorph_ref={"Polymorph",NULL,-1}; +static EffectRef fx_polymorph_ref = { "Polymorph", -1 }; void CopyPolymorphStats(Actor *source, Actor *target) { @@ -3687,11 +3714,31 @@ int fx_animation_stance (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 0x8B DisplayString // gemrb extension: rgb colour for displaystring -static EffectRef fx_protection_from_display_string_ref={"Protection:String",NULL,-1}; +// gemrb extension: resource may be an strref list (src or 2da) +static EffectRef fx_protection_from_display_string_ref = { "Protection:String", -1 }; int fx_display_string (Scriptable* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_display_string (%2d): StrRef: %d\n", fx->Opcode, fx->Parameter1 ); + if(fx->Resource[0]) { + //TODO: create a single list reader that handles src and 2da too + SrcVector *rndstr=LoadSrc(fx->Resource); + if (rndstr) { + fx->Parameter1 = rndstr->at(rand()%rndstr->size()); + FreeSrc(rndstr, fx->Resource); + DisplayStringCore(target, fx->Parameter1, DS_HEAD); + *(ieDword *) &target->overColor=fx->Parameter2; + return FX_NOT_APPLIED; + } + + //random text for other games + ieDword *rndstr2 = core->GetListFrom2DA(fx->Resource); + int cnt = rndstr2[0]; + if (cnt) { + fx->Parameter1 = rndstr2[core->Roll(1,cnt,0)]; + } + } + if (!target->fxqueue.HasEffectWithParamPair(fx_protection_from_display_string_ref, fx->Parameter1, 0) ) { displaymsg->DisplayStringName(fx->Parameter1, fx->Parameter2?fx->Parameter2:0xffffff, target, IE_STR_SOUND|IE_STR_SPEECH); } @@ -3727,6 +3774,7 @@ int fx_casting_glow (Scriptable* /*Owner*/, Actor* target, Effect* fx) sca->YPos+=fx->PosY+ypos_by_direction[target->GetOrientation()]; sca->ZPos+=heightmod; sca->SetBlend(); + sca->PlayOnce(); if (fx->Duration) { sca->SetDefaultDuration(fx->Duration-core->GetGame()->GameTime); } else { @@ -3882,7 +3930,7 @@ int fx_cast_spell (Scriptable* Owner, Actor* target, Effect* fx) if (0) printf( "fx_cast_spell (%2d): Resource:%s Mode: %d\n", fx->Opcode, fx->Resource, fx->Parameter2 ); if (fx->Parameter2) { //apply spell on target - core->ApplySpell(fx->Resource, target, Owner, fx->Power); + core->ApplySpell(fx->Resource, target, Owner, fx->Parameter1); // give feedback: Caster - spellname : target char tmp[100]; @@ -3892,10 +3940,15 @@ int fx_cast_spell (Scriptable* Owner, Actor* target, Effect* fx) displaymsg->DisplayStringName(tmp, 0xffffff, Owner); } } else { + // save the current spell ref, so the rest of its effects can be applied afterwards + ieResRef OldSpellResRef; + memcpy(OldSpellResRef, Owner->SpellResRef, sizeof(OldSpellResRef)); + Owner->SetSpellResRef(fx->Resource); //cast spell on target Owner->CastSpell(fx->Resource, target, false); //actually finish casting (if this is not good enough, use an action???) - Owner->CastSpellEnd(); + Owner->CastSpellEnd(fx->Parameter1); + Owner->SetSpellResRef(OldSpellResRef); } return FX_NOT_APPLIED; } @@ -3908,16 +3961,22 @@ int fx_learn_spell (Scriptable* /*Owner*/, Actor* target, Effect* fx) //probably we should also let this via a game flag if we want //full compatibility with bg1 //parameter2 is used in bg1 and pst to specify the spell type; bg2 and iwd2 figure it out from the resource - target->LearnSpell(fx->Resource, fx->Parameter1^LS_ADDXP); + target->LearnSpell(fx->Resource, fx->Parameter1); return FX_NOT_APPLIED; } // 0x94 Spell:CastSpellPoint -int fx_cast_spell_point (Scriptable* Owner, Actor* target, Effect* fx) +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 ); - Owner->CastSpellPoint(fx->Resource, target->Pos, false); + // save the current spell ref, so the rest of its effects can be applied afterwards + ieResRef OldSpellResRef; + memcpy(OldSpellResRef, Owner->SpellResRef, sizeof(OldSpellResRef)); + Owner->SetSpellResRef(fx->Resource); + Point p(fx->PosX, fx->PosY); + Owner->CastSpellPoint(fx->Resource, p, false); //actually finish casting (if this is not good enough, use an action???) - Owner->CastSpellPointEnd(); + Owner->CastSpellPointEnd(fx->Parameter1); + Owner->SetSpellResRef(OldSpellResRef); return FX_NOT_APPLIED; } @@ -4172,7 +4231,7 @@ int fx_mirror_image_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) } // 0xa0 Cure:Sanctuary -static EffectRef fx_sanctuary_state_ref={"Overlay:Sanctuary",NULL,-1}; +static EffectRef fx_sanctuary_state_ref = { "Overlay:Sanctuary", -1 }; int fx_cure_sanctuary_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -4183,7 +4242,7 @@ int fx_cure_sanctuary_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) } // 0xa1 Cure:Panic -static EffectRef fx_set_panic_state_ref={"State:Panic",NULL,-1}; +static EffectRef fx_set_panic_state_ref = { "State:Panic", -1 }; int fx_cure_panic_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -4194,7 +4253,7 @@ int fx_cure_panic_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) } // 0xa2 Cure:Hold -static EffectRef fx_hold_creature_ref={"State:Hold",NULL,-1}; +static EffectRef fx_hold_creature_ref = { "State:Hold", -1 }; int fx_cure_hold_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -4207,7 +4266,7 @@ int fx_cure_hold_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) } // 0xa3 FreeAction -static EffectRef fx_movement_modifier_ref={"MovementRateModifier2",NULL,-1}; +static EffectRef fx_movement_modifier_ref = { "MovementRateModifier2", -1 }; int fx_cure_slow_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -4218,7 +4277,7 @@ int fx_cure_slow_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) } // 0xa4 Cure:Intoxication -static EffectRef fx_intoxication_ref={"IntoxicationModifier",NULL,-1}; +static EffectRef fx_intoxication_ref = { "IntoxicationModifier", -1 }; int fx_cure_intoxication (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -4232,7 +4291,6 @@ int fx_cure_intoxication (Scriptable* /*Owner*/, Actor* target, Effect* fx) 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 ); - STAT_MOD( IE_CASTERHOLD ); return FX_PERMANENT; } @@ -4261,7 +4319,15 @@ int fx_missile_to_hit_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx int fx_remove_creature (Scriptable* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_remove_creature (%2d)\n", fx->Opcode); - Map *map = target->GetCurrentArea(); + + Map *map = NULL; + + if (target) { + map = target->GetCurrentArea(); + } + else { + map = core->GetGame()->GetCurrentArea(); + } Actor *actor = target; if (fx->Resource[0]) { @@ -4552,9 +4618,9 @@ int fx_castinglevel_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) #define FAMILIAR_ALIGNMENT 1 #define FAMILIAR_RESOURCE 2 -static EffectRef fx_familiar_constitution_loss_ref={"FamiliarBond",NULL,-1}; -static EffectRef fx_familiar_marker_ref={"FamiliarMarker",NULL,-1}; -static EffectRef fx_maximum_hp_modifier_ref={"MaximumHPModifier",NULL,-1}; +static EffectRef fx_familiar_constitution_loss_ref = { "FamiliarBond", -1 }; +static EffectRef fx_familiar_marker_ref = { "FamiliarMarker", -1 }; +static EffectRef fx_maximum_hp_modifier_ref = { "MaximumHPModifier", -1 }; int fx_find_familiar (Scriptable* Owner, Actor* target, Effect* fx) { @@ -4665,8 +4731,8 @@ int fx_ignore_dialogpause_modifier (Scriptable* /*Owner*/, Actor* target, Effect //0xc3 FamiliarBond //when this effect's target dies it should incur damage on protagonist -static EffectRef fx_damage_opcode_ref={"Damage",NULL,-1}; -static EffectRef fx_constitution_modifier_ref={"ConstitutionModifier",NULL,-1}; +static EffectRef fx_damage_opcode_ref = { "Damage", -1 }; +static EffectRef fx_constitution_modifier_ref = { "ConstitutionModifier", -1 }; int fx_familiar_constitution_loss (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -4895,8 +4961,8 @@ int fx_imprisonment (Scriptable* /*Owner*/, Actor* target, Effect* fx) } //0xd4 Cure:Imprisonment -static EffectRef fx_imprisonment_ref={"Imprisonment",NULL,-1}; -static EffectRef fx_maze_ref={"Maze",NULL,-1}; +static EffectRef fx_imprisonment_ref = { "Imprisonment", -1 }; +static EffectRef fx_maze_ref = { "Maze", -1 }; int fx_freedom (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -4950,7 +5016,7 @@ int fx_select_spell (Scriptable* /*Owner*/, Actor* target, Effect* fx) } // 0xd7 PlayVisualEffect -static EffectRef fx_protection_from_animation_ref={"Protection:Animation",NULL,-1}; +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 ); @@ -4971,6 +5037,7 @@ int fx_play_visual_effect (Scriptable* /*Owner*/, Actor* target, Effect* fx) vvc->active = true; return FX_APPLIED; } + if (! fx->FirstApply) return FX_NOT_APPLIED; } if (target->fxqueue.HasEffectWithResource(fx_protection_from_animation_ref,fx->Resource)) { @@ -5012,7 +5079,7 @@ int fx_play_visual_effect (Scriptable* /*Owner*/, Actor* target, Effect* fx) //d8 LevelDrainModifier -static EffectRef fx_leveldrain_ref={"LevelDrainModifier",NULL,-1}; +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) @@ -5042,7 +5109,7 @@ int fx_leveldrain_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) } //d9 PowerWordSleep -static EffectRef fx_sleep_ref={"State:Sleep",NULL,-1}; +static EffectRef fx_sleep_ref = { "State:Sleep", -1 }; int fx_power_word_sleep (Scriptable* Owner, Actor* target, Effect* fx) { @@ -5331,7 +5398,7 @@ int fx_proficiency (Scriptable* /*Owner*/, Actor* target, Effect* fx) } // 0xea CreateContingency -static EffectRef fx_contingency_ref={"CastSpellOnCondition",NULL,-1}; +static EffectRef fx_contingency_ref = { "CastSpellOnCondition", -1 }; int fx_create_contingency (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -5392,7 +5459,7 @@ int fx_wing_buffet (Scriptable* Owner, Actor* target, Effect* fx) // 0xec ProjectImage -static EffectRef fx_puppetmarker_ref={"PuppetMarker",NULL,-1}; +static EffectRef fx_puppetmarker_ref = { "PuppetMarker", -1 }; int fx_puppet_master (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -5541,7 +5608,7 @@ int fx_remove_portrait_icon (Scriptable* /*Owner*/, Actor* target, Effect* fx) // 0xf1 control creature (same as charm) // 0xF2 Cure:Confusion -static EffectRef fx_confused_state_ref={"State:Confused",NULL,-1}; +static EffectRef fx_confused_state_ref = { "State:Confused", -1 }; int fx_cure_confused_state (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -5691,7 +5758,13 @@ int fx_set_area_effect (Scriptable* Owner, Actor* target, Effect* fx) } //success displaymsg->DisplayConstantStringName(STR_SNARESUCCEED, 0xf0f0f0, target); + // save the current spell ref, so the rest of its effects can be applied afterwards + ieResRef OldSpellResRef; + memcpy(OldSpellResRef, Owner->SpellResRef, sizeof(OldSpellResRef)); + Owner->SetSpellResRef(fx->Resource); Owner->CastSpellPoint(fx->Resource, target->Pos, false); + Owner->CastSpellPointEnd(0); + Owner->SetSpellResRef(OldSpellResRef); return FX_NOT_APPLIED; } @@ -5754,7 +5827,7 @@ int fx_store_spell_sequencer(Scriptable* /*Owner*/, Actor* target, Effect* fx) } // 0x101 Sequencer:Create -static EffectRef fx_spell_sequencer_active_ref={"Sequencer:Store",NULL,-1}; +static EffectRef fx_spell_sequencer_active_ref = { "Sequencer:Store", -1 }; int fx_create_spell_sequencer(Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -5902,7 +5975,7 @@ int fx_modify_global_variable (Scriptable* /*Owner*/, Actor* /*target*/, Effect* return FX_NOT_APPLIED; } // 0x10a RemoveImmunity -EffectRef immunity_effect_ref={"Protection:Spell",NULL,-1}; +static EffectRef immunity_effect_ref = { "Protection:Spell", -1 }; int fx_remove_immunity(Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -5928,12 +6001,12 @@ int fx_explore_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) int fx_screenshake (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx) { if (0) printf( "fx_screenshake (%2d): Strength: %d\n", fx->Opcode, fx->Parameter1 ); - core->timer->SetScreenShake( fx->Parameter1, fx->Parameter1, 1); + core->timer->SetScreenShake( fx->Parameter1, fx->Parameter1, fx->Parameter1); return FX_APPLIED; } // 0x10e Cure:CasterHold -static EffectRef fx_pause_caster_modifier_ref={"PauseTarget",NULL,-1}; +static EffectRef fx_pause_caster_modifier_ref = { "PauseTarget", -1 }; int fx_unpause_caster (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -5943,9 +6016,9 @@ int fx_unpause_caster (Scriptable* /*Owner*/, Actor* target, Effect* fx) } // 0x10f SummonDisable (bg2) -int fx_avatar_removal (Scriptable* /*Owner*/, Actor* target, Effect* fx) +int fx_summon_disable (Scriptable* /*Owner*/, Actor* target, Effect* fx) { - if (0) printf( "fx_avatar_removal (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 ); + if (0) printf( "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) { @@ -5959,7 +6032,7 @@ What happens at a lower level is that the engine recreates the entire stats on s Since the repeating effects are stored in a list inside those stats, they are being recreated every ai update, if there has been an effect application. The repeating effect itself internally uses a counter to store how often it has been called. And when this counter equals the period it fires of the effect. When the list is being recreated all those counters are lost. */ -static EffectRef fx_apply_effect_repeat_ref = {"ApplyEffectRepeat", NULL, -1}; +static EffectRef fx_apply_effect_repeat_ref = { "ApplyEffectRepeat", -1 }; // 0x110 ApplyEffectRepeat int fx_apply_effect_repeat (Scriptable* Owner, Actor* target, Effect* fx) { @@ -6120,7 +6193,7 @@ int fx_to_hit_bonus_modifier (Scriptable* /*Owner*/, Actor* target, Effect* fx) } // 0x117 RenableButton -static EffectRef fx_disable_button_ref={"DisableButton",NULL,-1}; +static EffectRef fx_disable_button_ref = { "DisableButton", -1 }; int fx_renable_button (Scriptable* /*Owner*/, Actor* target, Effect* fx) { diff --git a/project/jni/application/gemrb/gemrb/plugins/GAMImporter/GAMImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/GAMImporter/GAMImporter.cpp index f757f7fe8..b04942be8 100644 --- a/project/jni/application/gemrb/gemrb/plugins/GAMImporter/GAMImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/GAMImporter/GAMImporter.cpp @@ -212,7 +212,8 @@ Game* GAMImporter::LoadGame(Game *newGame, int ver_override) //apparently BG1/IWD2 relies on this, if chapter is unset, it is //set to -1, hopefully it won't break anything - newGame->locals->SetAt("CHAPTER", (ieDword) -1); + //PST has no chapter variable by default, and would crash on one + newGame->locals->SetAt("CHAPTER", (ieDword) -1, core->HasFeature(GF_NO_NEW_VARIABLES)); // load initial values from var.var newGame->locals->LoadInitialValues("GLOBAL"); @@ -479,7 +480,7 @@ Actor* GAMImporter::GetActor(Holder aM, bool is_in_party ) } free (Buffer); - //torment has them as 0 or -1 + //torment has them as 0 or -1 if (pcInfo.Name[0]!=0 && pcInfo.Name[0]!=UNINITIALIZED_CHAR) { actor->SetName(pcInfo.Name,0); //setting both names } @@ -1141,13 +1142,13 @@ void GAMImporter::GetMazeEntry(void *memory) { maze_entry *h = (maze_entry *) memory; - str->ReadDword( &h->unknown00 ); + str->ReadDword( &h->override ); str->ReadDword( &h->valid ); str->ReadDword( &h->accessible ); - str->ReadDword( &h->traptype ); str->ReadDword( &h->trapped ); + str->ReadDword( &h->traptype ); str->ReadWord( &h->walls ); - str->ReadDword( &h->unknown16 ); + str->ReadDword( &h->visited ); } void GAMImporter::PutMazeHeader(DataStream *stream, void *memory) @@ -1172,18 +1173,18 @@ void GAMImporter::PutMazeHeader(DataStream *stream, void *memory) void GAMImporter::PutMazeEntry(DataStream *stream, void *memory) { maze_entry *h = (maze_entry *) memory; - stream->WriteDword( &h->unknown00 ); + stream->WriteDword( &h->override ); stream->WriteDword( &h->valid ); stream->WriteDword( &h->accessible ); stream->WriteDword( &h->trapped ); stream->WriteDword( &h->traptype ); stream->WriteWord( &h->walls ); - stream->WriteDword( &h->unknown16 ); + stream->WriteDword( &h->visited ); } int GAMImporter::PutMaze(DataStream *stream, Game *game) { - for(int i=0;i<64;i++) { + for(int i=0;imazedata+i*MAZE_ENTRY_SIZE); } PutMazeHeader(stream, game->mazedata+MAZE_ENTRY_COUNT*MAZE_ENTRY_SIZE); diff --git a/project/jni/application/gemrb/gemrb/plugins/GUIScript/GUIScript.cpp b/project/jni/application/gemrb/gemrb/plugins/GUIScript/GUIScript.cpp index 18ccf9ff1..d912e6ea4 100644 --- a/project/jni/application/gemrb/gemrb/plugins/GUIScript/GUIScript.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/GUIScript/GUIScript.cpp @@ -51,6 +51,10 @@ #include "GUI/MapControl.h" #include "GUI/TextEdit.h" #include "GUI/WorldMapControl.h" +#include "Scriptable/Container.h" +#include "Scriptable/Door.h" +#include "Scriptable/InfoPoint.h" +#include "System/VFS.h" #include @@ -126,7 +130,7 @@ static bool QuitOnError = false; static int CHUWidth = 0; static int CHUHeight = 0; -static EffectRef fx_learn_spell_ref={"Spell:Learn",NULL,-1}; +static EffectRef fx_learn_spell_ref = { "Spell:Learn", -1 }; // Like PyString_FromString(), but for ResRef inline PyObject* PyString_FromResRef(char* ResRef) @@ -170,6 +174,24 @@ inline PyObject* AttributeError(const char* doc_string) return NULL; } +#define GET_GAME() \ + Game *game = core->GetGame(); \ + if (!game) { \ + return RuntimeError( "No game loaded!\n" ); \ + } + +#define GET_MAP() \ + Map *map = game->GetCurrentArea(); \ + if (!map) { \ + return RuntimeError( "No current area!" ); \ + } + +#define GET_GAMECONTROL() \ + GameControl *gc = core->GetGameControl(); \ + if (!gc) { \ + return RuntimeError("Can't find GameControl!"); \ + } + inline Control *GetControl( int wi, int ci, int ct) { char errorbuffer[256]; @@ -349,6 +371,7 @@ PyDoc_STRVAR( GemRB_UnhideGUI__doc, static PyObject* GemRB_UnhideGUI(PyObject*, PyObject* /*args*/) { + //this is not the usual gc retrieval GameControl* gc = (GameControl *) GetControl( 0, 0, IE_GUI_GAMECONTROL); if (!gc) { return RuntimeError("No gamecontrol!"); @@ -366,10 +389,10 @@ PyDoc_STRVAR( GemRB_HideGUI__doc, static PyObject* GemRB_HideGUI(PyObject*, PyObject* /*args*/) { + //it is no problem if the gamecontrol couldn't be found here? GameControl* gc = (GameControl *) GetControl( 0, 0, IE_GUI_GAMECONTROL); if (!gc) { return PyInt_FromLong( 0 ); - //return RuntimeError("No gamecontrol!"); } int ret = gc->HideGUI(); @@ -1853,12 +1876,16 @@ static PyObject* GemRB_Window_Unload(PyObject * /*self*/, PyObject* args) if (arg == 0xffff) { return AttributeError( "Feature unsupported! "); } - int ret = core->DelWindow( arg ); - if (ret == -1) { - return RuntimeError( "Can't unload window!" ); - } - core->PlaySound(DS_WINDOW_CLOSE); + //Don't bug if the window wasn't loaded + if (core->GetWindow(arg) ) { + int ret = core->DelWindow( arg ); + if (ret == -1) { + return RuntimeError( "Can't unload window!" ); + } + + core->PlaySound(DS_WINDOW_CLOSE); + } Py_INCREF( Py_None ); return Py_None; } @@ -2048,7 +2075,7 @@ static PyObject* GemRB_Window_CreateTextEdit(PyObject * /*self*/, PyObject* args if (spr) edit->SetCursor( spr ); else - return RuntimeError( "BAM not found" ); + return RuntimeError( "Cursor BAM not found" ); win->AddControl( edit ); @@ -2221,7 +2248,10 @@ static PyObject* GemRB_ScrollBar_SetSprites(PyObject * /*self*/, PyObject* args) gamedata->GetFactoryResource( ResRef, IE_BAM_CLASS_ID, IE_NORMAL ); if (!af) { - return RuntimeError( "BAM not found" ); + char tmpstr[24]; + + snprintf(tmpstr,sizeof(tmpstr),"%s BAM not found", ResRef); + return RuntimeError( tmpstr ); } Sprite2D *tspr = af->GetFrame(upunpressed, (unsigned char)cycle); sb->SetImage( IE_GUI_SCROLLBAR_UP_UNPRESSED, tspr ); @@ -2274,7 +2304,10 @@ static PyObject* GemRB_Button_SetSprites(PyObject * /*self*/, PyObject* args) gamedata->GetFactoryResource( ResRef, IE_BAM_CLASS_ID, IE_NORMAL ); if (!af) { - return RuntimeError( "BAM not found" ); + char tmpstr[24]; + + snprintf(tmpstr,sizeof(tmpstr),"%s BAM not found", ResRef); + return RuntimeError( tmpstr ); } Sprite2D *tspr = af->GetFrame(unpressed, (unsigned char)cycle); btn->SetImage( IE_GUI_BUTTON_UNPRESSED, tspr ); @@ -2466,7 +2499,7 @@ static PyObject* GemRB_AddNewArea(PyObject * /*self*/, PyObject* args) AutoTable newarea(resref); if (!newarea) { - return RuntimeError( "2da not found!"); + return RuntimeError( "2da not found!\n"); } WorldMap *wmap = core->GetWorldMap(); @@ -2520,7 +2553,7 @@ static PyObject* GemRB_AddNewArea(PyObject * /*self*/, PyObject* args) entry->Y = locy; entry->LocCaptionName = label; entry->LocTooltipName = name; - memset(entry->LoadScreenResRef, 0, 8); + memset(entry->LoadScreenResRef, 0, sizeof(ieResRef)); memcpy(entry->AreaLinksIndex, indices, sizeof(entry->AreaLinksIndex) ); memcpy(entry->AreaLinksCount, links, sizeof(entry->AreaLinksCount) ); @@ -2551,7 +2584,7 @@ static PyObject* GemRB_AddNewArea(PyObject * /*self*/, PyObject* args) link->EncounterChance = encprob; for(k=0;k<5;k++) { if (enc[k][0]=='*') { - memset(link->EncounterAreaResRef[k],0,8); + memset(link->EncounterAreaResRef[k],0,sizeof(ieResRef)); } else { strnuprcpy(link->EncounterAreaResRef[k], enc[k], 8); } @@ -2611,11 +2644,11 @@ static PyObject* GemRB_CreateMovement(PyObject * /*self*/, PyObject* args) } else { everyone = CT_GO_CLOSER; } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } - game->GetCurrentArea()->MoveToNewArea(area, entrance, (unsigned int)direction, everyone, NULL); + GET_GAME(); + + GET_MAP(); + + map->MoveToNewArea(area, entrance, (unsigned int)direction, everyone, NULL); Py_INCREF( Py_None ); return Py_None; } @@ -2731,7 +2764,7 @@ static PyObject* GemRB_Window_CreateWorldMapControl(PyObject * /*self*/, PyObjec PyDoc_STRVAR( GemRB_WorldMap_SetTextColor__doc, "SetWorldMapTextColor(WindowIndex, ControlIndex, which, red, green, blue)\n\n" "Sets the label colors of a WorldMap Control. WHICH selects color affected" -"and is one of IE_GUI_WMAP_COLOR_(NORMAL|SELECTED|NOTVISITED)." ); +"and is one of IE_GUI_WMAP_COLOR_(BACKGROUND|NORMAL|SELECTED|NOTVISITED)." ); static PyObject* GemRB_WorldMap_SetTextColor(PyObject * /*self*/, PyObject* args) { @@ -2927,10 +2960,7 @@ static PyObject* GemRB_GameSetPartySize(PyObject * /*self*/, PyObject* args) return AttributeError( GemRB_GameSetPartySize__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); game->SetPartySize( Flags ); @@ -2950,10 +2980,7 @@ static PyObject* GemRB_GameSetProtagonistMode(PyObject * /*self*/, PyObject* arg return AttributeError( GemRB_GameSetProtagonistMode__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); game->SetProtagonistMode( Flags ); @@ -2966,10 +2993,8 @@ PyDoc_STRVAR( GemRB_GameGetExpansion__doc, "Gets the expansion mode." ); static PyObject* GemRB_GameGetExpansion(PyObject * /*self*/, PyObject* /*args*/) { - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + return PyInt_FromLong( game->Expansion ); } @@ -2985,10 +3010,7 @@ static PyObject* GemRB_GameSetExpansion(PyObject * /*self*/, PyObject* args) return AttributeError( GemRB_GameSetExpansion__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); if ((unsigned int) value<=game->Expansion) { Py_INCREF( Py_False ); @@ -3016,10 +3038,7 @@ static PyObject* GemRB_GameSetScreenFlags(PyObject * /*self*/, PyObject* args) return NULL; } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); game->SetControlStatus( Flags, Operation ); @@ -3039,16 +3058,10 @@ static PyObject* GemRB_GameControlSetScreenFlags(PyObject * /*self*/, PyObject* return AttributeError( GemRB_GameControlSetScreenFlags__doc ); } if (Operation < BM_SET || Operation > BM_NAND) { - printMessage( "GUIScript", - "Syntax Error: operation must be 0-4\n", LIGHT_RED ); - return NULL; + return AttributeError("Operation must be 0-4\n"); } - GameControl *gc = core->GetGameControl(); - if (!gc) { - printMessage ("GUIScript", "Flag cannot be set!\n",LIGHT_RED); - return NULL; - } + GET_GAMECONTROL(); gc->SetScreenFlags( Flags, Operation ); @@ -3070,10 +3083,7 @@ static PyObject* GemRB_GameControlSetTargetMode(PyObject * /*self*/, PyObject* a return AttributeError( GemRB_GameControlSetTargetMode__doc ); } - GameControl *gc = core->GetGameControl(); - if (!gc) { - return RuntimeError("Can't find GameControl!"); - } + GET_GAMECONTROL(); //target mode is only the low bits (which is a number) gc->SetTargetMode(Mode&GA_ACTION); @@ -3089,10 +3099,7 @@ PyDoc_STRVAR( GemRB_GameControlGetTargetMode__doc, static PyObject* GemRB_GameControlGetTargetMode(PyObject * /*self*/, PyObject* /*args*/) { - GameControl *gc = core->GetGameControl(); - if (!gc) { - return RuntimeError("Can't find GameControl!"); - } + GET_GAMECONTROL(); return PyInt_FromLong(gc->GetTargetMode()); } @@ -3577,13 +3584,11 @@ static PyObject* GemRB_VerbalConstant(PyObject * /*self*/, PyObject* args) return AttributeError( GemRB_VerbalConstant__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor *actor = game->FindPC(PartyID); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } if (str<0 || str>=VCONST_COUNT) { @@ -3734,10 +3739,8 @@ PyDoc_STRVAR( GemRB_GetMessageWindowSize__doc, static PyObject* GemRB_GetMessageWindowSize(PyObject * /*self*/, PyObject* /*args*/) { - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + return PyInt_FromLong( game->ControlStatus ); } @@ -3797,16 +3800,17 @@ static PyObject* GemRB_CheckVar(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "ss", &Variable, &Context )) { return AttributeError( GemRB_CheckVar__doc ); } - GameControl *gc = core->GetGameControl(); - if (!gc) { - return RuntimeError("Can't find GameControl!"); - } + GET_GAMECONTROL(); + Scriptable *Sender = (Scriptable *) gc->GetLastActor(); if (!Sender) { - Sender = (Scriptable *) core->GetGame()->GetCurrentArea(); + GET_GAME(); + + Sender = (Scriptable *) game->GetCurrentArea(); } + if (!Sender) { - printMessage("GUIScript","No Game!\n", LIGHT_RED); + printMessage("GUIScript","No Sender!\n", LIGHT_RED); return NULL; } long value =(long) CheckVariable(Sender, Variable, Context); @@ -3831,16 +3835,12 @@ static PyObject* GemRB_SetGlobal(PyObject * /*self*/, PyObject* args) } Scriptable *Sender = NULL; - Game *game = core->GetGame(); - if (!game) { - printMessage("GUIScript","No Game!\n", LIGHT_RED); - return NULL; - } + + GET_GAME(); + if (!strnicmp(Context, "MYAREA", 6) || !strnicmp(Context, "LOCALS", 6)) { - GameControl *gc = core->GetGameControl(); - if (!gc) { - return RuntimeError("Can't find GameControl!"); - } + GET_GAMECONTROL(); + Sender = (Scriptable *) gc->GetLastActor(); if (!Sender) { Sender = (Scriptable *) game->GetCurrentArea(); @@ -3869,10 +3869,8 @@ static PyObject* GemRB_GetGameVar(PyObject * /*self*/, PyObject* args) return AttributeError( GemRB_GetGameVar__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + if (!game->locals->Lookup( Variable, value )) { return PyInt_FromLong( ( unsigned long ) 0 ); } @@ -3922,13 +3920,11 @@ static PyObject* GemRB_SaveCharacter(PyObject * /*self*/, PyObject * args) return AttributeError( GemRB_SaveCharacter__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor *actor = game->FindPC(PartyID); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } return PyInt_FromLong(core->WriteCharacter(name, actor) ); } @@ -3949,10 +3945,7 @@ static PyObject* GemRB_SaveGame(PyObject * /*self*/, PyObject * args) CObject save(obj); - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); SaveGameIterator *sgi = core->GetSaveGameIterator(); if (!sgi) { @@ -4099,7 +4092,8 @@ static PyObject* GemRB_GetGamePreview(PyObject * /*self*/, PyObject* args) return AttributeError( GemRB_GetGamePreview__doc ); } - return CObject(core->GetGameControl()->GetPreview()); + GET_GAMECONTROL(); + return CObject(gc->GetPreview()); } PyDoc_STRVAR( GemRB_GetGamePortraitPreview__doc, @@ -4114,7 +4108,8 @@ static PyObject* GemRB_GetGamePortraitPreview(PyObject * /*self*/, PyObject* arg return AttributeError( GemRB_GetGamePreview__doc ); } - return CObject(core->GetGameControl()->GetPortraitPreview(PCSlotCount)); + GET_GAMECONTROL(); + return CObject(gc->GetPortraitPreview(PCSlotCount)); } PyDoc_STRVAR( GemRB_Roll__doc, @@ -4192,10 +4187,8 @@ PyDoc_STRVAR( GemRB_GetPartySize__doc, static PyObject* GemRB_GetPartySize(PyObject * /*self*/, PyObject * /*args*/) { - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + return PyInt_FromLong( game->GetPartySize(0) ); } @@ -4205,10 +4198,8 @@ PyDoc_STRVAR( GemRB_GetGameTime__doc, static PyObject* GemRB_GetGameTime(PyObject * /*self*/, PyObject* /*args*/) { - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + unsigned long GameTime = game->GameTime/AI_UPDATE_TIME; return PyInt_FromLong( GameTime ); } @@ -4219,10 +4210,8 @@ PyDoc_STRVAR( GemRB_GameGetReputation__doc, static PyObject* GemRB_GameGetReputation(PyObject * /*self*/, PyObject* /*args*/) { - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + int Reputation = (int) game->Reputation; return PyInt_FromLong( Reputation ); } @@ -4238,10 +4227,8 @@ static PyObject* GemRB_GameSetReputation(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "i", &Reputation )) { return AttributeError( GemRB_GameSetReputation__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + game->SetReputation( (unsigned int) Reputation ); Py_INCREF( Py_None ); @@ -4261,10 +4248,7 @@ static PyObject* GemRB_IncreaseReputation(PyObject * /*self*/, PyObject* args) return AttributeError( GemRB_IncreaseReputation__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); int Limit = core->GetReputationMod(8); if (Limit<=Donation) { @@ -4282,10 +4266,8 @@ PyDoc_STRVAR( GemRB_GameGetPartyGold__doc, static PyObject* GemRB_GameGetPartyGold(PyObject * /*self*/, PyObject* /*args*/) { - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + int Gold = game->PartyGold; return PyInt_FromLong( Gold ); } @@ -4301,10 +4283,8 @@ static PyObject* GemRB_GameSetPartyGold(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "i|i", &Gold, &flag )) { return AttributeError( GemRB_GameSetPartyGold__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + if (flag) { game->AddGold((ieDword) Gold); } else { @@ -4327,10 +4307,8 @@ static PyObject* GemRB_GameGetFormation(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "|i", &Which )) { return AttributeError( GemRB_GameGetFormation__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + if (Which<0) { Formation = game->WhichFormation; } else { @@ -4353,10 +4331,8 @@ static PyObject* GemRB_GameSetFormation(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "i|i", &Formation, &Which )) { return AttributeError( GemRB_GameSetFormation__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + if (Which<0) { game->WhichFormation = Formation; } else { @@ -4383,10 +4359,8 @@ static PyObject* GemRB_GetJournalSize(PyObject * /*self*/, PyObject * args) return AttributeError( GemRB_GetJournalSize__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + int count = 0; for (unsigned int i = 0; i < game->GetJournalCount(); i++) { GAMJournalEntry* je = game->GetJournalEntry( i ); @@ -4409,10 +4383,8 @@ static PyObject* GemRB_GetJournalEntry(PyObject * /*self*/, PyObject * args) return AttributeError( GemRB_GetJournalEntry__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + int count = 0; for (unsigned int i = 0; i < game->GetJournalCount(); i++) { GAMJournalEntry* je = game->GetJournalEntry( i ); @@ -4448,10 +4420,7 @@ static PyObject* GemRB_SetJournalEntry(PyObject * /*self*/, PyObject * args) return AttributeError( GemRB_SetJournalEntry__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); if (strref == -1) { //delete the whole journal @@ -4485,10 +4454,8 @@ static PyObject* GemRB_GameIsBeastKnown(PyObject * /*self*/, PyObject * args) return AttributeError( GemRB_GameIsBeastKnown__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + return PyInt_FromLong( game->IsBeastKnown( index )); } @@ -4500,7 +4467,7 @@ static PyObject* GemRB_GetINIPartyCount(PyObject * /*self*/, PyObject * /*args*/) { if (!core->GetPartyINI()) { - return RuntimeError( "INI resource not found!" ); + return RuntimeError( "INI resource not found!\n" ); } return PyInt_FromLong( core->GetPartyINI()->GetTagsCount() ); } @@ -4517,7 +4484,7 @@ static PyObject* GemRB_GetINIQuestsKey(PyObject * /*self*/, PyObject* args) return AttributeError( GemRB_GetINIQuestsKey__doc ); } if (!core->GetQuestsINI()) { - return RuntimeError( "INI resource not found!" ); + return RuntimeError( "INI resource not found!\n" ); } return PyString_FromString( core->GetQuestsINI()->GetKeyAsString( Tag, Key, Default ) ); @@ -4553,7 +4520,7 @@ static PyObject* GemRB_GetINIPartyKey(PyObject * /*self*/, PyObject* args) return AttributeError( GemRB_GetINIPartyKey__doc ); } if (!core->GetPartyINI()) { - return RuntimeError( "INI resource not found!" ); + return RuntimeError( "INI resource not found!\n" ); } return PyString_FromString( core->GetPartyINI()->GetKeyAsString( Tag, Key, Default ) ); @@ -4575,10 +4542,8 @@ static PyObject* GemRB_CreatePlayer(PyObject * /*self*/, PyObject* args) } //PlayerSlot is zero based Slot = ( PlayerSlot & 0x7fff ); - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + //FIXME:overwriting original slot //is dangerous if the game is already loaded //maybe the actor should be removed from the area first @@ -4590,7 +4555,7 @@ static PyObject* GemRB_CreatePlayer(PyObject * /*self*/, PyObject* args) } else { PlayerSlot = game->FindPlayer( PlayerSlot ); if (PlayerSlot >= 0) { - return RuntimeError("Slot is already filled!"); + return RuntimeError("Slot is already filled!\n"); } } if (CreResRef[0]) { @@ -4600,7 +4565,7 @@ static PyObject* GemRB_CreatePlayer(PyObject * /*self*/, PyObject* args) PlayerSlot = 0; } if (PlayerSlot < 0) { - return RuntimeError("File not found!"); + return RuntimeError("File not found!\n"); } return PyInt_FromLong( PlayerSlot ); } @@ -4616,13 +4581,11 @@ static PyObject* GemRB_GetPlayerStates(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "i", &PartyID )) { return AttributeError( GemRB_GetPlayerStates__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* MyActor = game->FindPC( PartyID ); if (!MyActor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } return PyString_FromString((const char *) MyActor->GetStateString() ); } @@ -4639,13 +4602,11 @@ static PyObject* GemRB_GetPlayerName(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "i|i", &PartyID, &Which )) { return AttributeError( GemRB_GetPlayerName__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* MyActor = game->FindPC( PartyID ); if (!MyActor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } if (Which == 2) { return PyString_FromString( MyActor->GetScriptName() ); @@ -4667,13 +4628,11 @@ static PyObject* GemRB_SetPlayerName(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "is|i", &PlayerSlot, &Name, &Which )) { return AttributeError( GemRB_SetPlayerName__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* MyActor = game->FindPC( PlayerSlot ); if (!MyActor) { - return RuntimeError( "Actor not found!" ); + return RuntimeError( "Actor not found!\n" ); } MyActor->SetName(Name, Which); MyActor->SetMCFlag(MC_EXPORTABLE,BM_OR); @@ -4693,10 +4652,7 @@ static PyObject* GemRB_CreateString(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "is", &strref, &Text )) { return AttributeError( GemRB_CreateString__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); strref = core->UpdateString(strref, Text); return PyInt_FromLong( strref ); @@ -4713,17 +4669,15 @@ static PyObject* GemRB_SetPlayerString(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "iii", &PlayerSlot, &StringSlot, &StrRef )) { return AttributeError( GemRB_SetPlayerString__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* MyActor = game->FindPC( PlayerSlot ); if (!MyActor) { - return RuntimeError( "Actor not found!" ); + return RuntimeError( "Actor not found!\n" ); } if (StringSlot>=VCONST_COUNT) { - return AttributeError( "StringSlot is out of range!" ); + return AttributeError( "StringSlot is out of range!\n" ); } MyActor->StrRefs[StringSlot]=StrRef; @@ -4744,13 +4698,11 @@ static PyObject* GemRB_SetPlayerSound(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "is", &PlayerSlot, &Sound )) { return AttributeError( GemRB_SetPlayerSound__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* MyActor = game->FindPC( PlayerSlot ); if (!MyActor) { - return RuntimeError( "Actor not found!" ); + return RuntimeError( "Actor not found!\n" ); } MyActor->SetSoundFolder(Sound); Py_INCREF( Py_None ); @@ -4770,13 +4722,11 @@ static PyObject* GemRB_GetPlayerSound(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "i|i", &PlayerSlot, &flag )) { return AttributeError( GemRB_GetPlayerSound__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* MyActor = game->FindPC( PlayerSlot ); if (!MyActor) { - return RuntimeError( "Actor not found!" ); + return RuntimeError( "Actor not found!\n" ); } MyActor->GetSoundFolder(Sound, flag); return PyString_FromString(Sound); @@ -4797,10 +4747,8 @@ static PyObject* GemRB_GetSlotType(PyObject * /*self*/, PyObject* args) } if (PartyID) { - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + actor = game->FindPC( PartyID ); } @@ -4849,10 +4797,8 @@ static PyObject* GemRB_GetPCStats(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "i", &PartyID )) { return AttributeError( GemRB_GetPCStats__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* MyActor = game->FindPC( PartyID ); if (!MyActor || !MyActor->PCStats) { Py_INCREF( Py_None ); @@ -4907,7 +4853,7 @@ static PyObject* GemRB_GetPCStats(PyObject * /*self*/, PyObject* args) Item* item = gamedata->GetItem(ps->FavouriteWeapons[largest]); if (item == NULL) { - return RuntimeError( "Item not found!" ); + return RuntimeError( "Item not found!\n" ); } PyDict_SetItemString(dict, "FavouriteWeapon", PyInt_FromLong ((signed) item->GetItemName(false))); @@ -4936,10 +4882,7 @@ static PyObject* GemRB_GameSelectPC(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "ii|i", &PartyID, &Select, &Flags )) { return AttributeError( GemRB_GameSelectPC__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); Actor* actor; if (PartyID > 0) { @@ -4969,10 +4912,8 @@ static PyObject* GemRB_GameIsPCSelected(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "i", &PlayerSlot )) { return AttributeError( GemRB_GameIsPCSelected__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* MyActor = game->FindPC( PlayerSlot ); if (!MyActor) { return PyInt_FromLong( 0 ); @@ -4994,7 +4935,9 @@ static PyObject* GemRB_GameSelectPCSingle(PyObject * /*self*/, PyObject* args) return AttributeError( GemRB_GameSelectPCSingle__doc ); } - core->GetGame()->SelectPCSingle( index ); + GET_GAME(); + + game->SelectPCSingle( index ); Py_INCREF( Py_None ); return Py_None; @@ -5011,15 +4954,11 @@ static PyObject* GemRB_GameGetSelectedPCSingle(PyObject * /*self*/, PyObject* ar if (!PyArg_ParseTuple( args, "|i", &flag )) { return AttributeError( GemRB_GameGetSelectedPCSingle__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + if (flag) { - GameControl *gc = core->GetGameControl(); - if (!gc) { - return RuntimeError("Can't find GameControl!"); - } + GET_GAMECONTROL(); + Actor *ac = gc->dialoghandler->GetSpeaker(); int ret = 0; if (ac) { @@ -5070,15 +5009,10 @@ static PyObject* GemRB_GameControlSetLastActor(PyObject * /*self*/, PyObject* ar return AttributeError( GemRB_GameControlSetLastActor__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + + GET_GAMECONTROL(); - GameControl *gc = core->GetGameControl(); - if (!gc) { - return RuntimeError("Can't find GameControl!"); - } Actor* actor = game->FindPC( PartyID ); gc->SetLastActor(actor, gc->GetLastActor() ); @@ -5097,10 +5031,8 @@ static PyObject* GemRB_ActOnPC(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "i", &PartyID )) { return AttributeError( GemRB_ActOnPC__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* MyActor = game->FindPC( PartyID ); if (MyActor) { GameControl* gc = core->GetGameControl(); @@ -5124,10 +5056,8 @@ static PyObject* GemRB_GetPlayerPortrait(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "i|i", &PlayerSlot, &Which )) { return AttributeError( GemRB_GetPlayerPortrait__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* MyActor = game->FindPC( PlayerSlot ); if (!MyActor) { return PyString_FromString( ""); @@ -5146,7 +5076,9 @@ static PyObject* GemRB_GetPlayerString(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "ii", &PlayerSlot, &Index)) { return AttributeError( GemRB_GetPlayerString__doc ); } - Actor* MyActor = core->GetGame()->FindPC( PlayerSlot ); + GET_GAME(); + + Actor* MyActor = game->FindPC( PlayerSlot ); if (!MyActor) { return RuntimeError("Cannot find actor!\n"); } @@ -5169,7 +5101,9 @@ static PyObject* GemRB_GetPlayerStat(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "ii|i", &PlayerSlot, &StatID, &BaseStat )) { return AttributeError( GemRB_GetPlayerStat__doc ); } - Actor* MyActor = core->GetGame()->FindPC( PlayerSlot ); + GET_GAME(); + + Actor* MyActor = game->FindPC( PlayerSlot ); if (!MyActor) { return RuntimeError("Cannot find actor!\n"); } @@ -5190,7 +5124,9 @@ static PyObject* GemRB_SetPlayerStat(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "iii|i", &PlayerSlot, &StatID, &StatValue, &pcf )) { return AttributeError( GemRB_SetPlayerStat__doc ); } - Actor* MyActor = core->GetGame()->FindPC( PlayerSlot ); + GET_GAME(); + + Actor* MyActor = game->FindPC( PlayerSlot ); if (!MyActor) { return RuntimeError("Cannot find actor!\n"); } @@ -5213,7 +5149,9 @@ static PyObject* GemRB_GetPlayerScript(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "i|i", &PlayerSlot, &Index )) { return AttributeError( GemRB_GetPlayerScript__doc ); } - Actor *actor = core->GetGame()->FindPC(PlayerSlot); + GET_GAME(); + + Actor *actor = game->FindPC(PlayerSlot); if (!actor) { return RuntimeError("Cannot find actor!\n"); } @@ -5237,7 +5175,9 @@ static PyObject* GemRB_SetPlayerScript(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "is|i", &PlayerSlot, &ScriptName, &Index )) { return AttributeError( GemRB_SetPlayerScript__doc ); } - Actor *actor = core->GetGame()->FindPC(PlayerSlot); + GET_GAME(); + + Actor *actor = game->FindPC(PlayerSlot); if (!actor) { return RuntimeError("Cannot find actor!\n"); } @@ -5261,14 +5201,11 @@ static PyObject* GemRB_FillPlayerInfo(PyObject * /*self*/, PyObject* args) // here comes some code to transfer icon/name to the PC sheet // // - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); Actor* MyActor = game->FindPC( PlayerSlot ); if (!MyActor) { - return RuntimeError( "Actor not found!" ); + return RuntimeError( "Actor not found!\n" ); } if (Portrait1) { MyActor->SetPortrait( Portrait1, 1); @@ -5346,8 +5283,10 @@ PyObject *SetSpellIcon(int wi, int ci, const ieResRef SpellResRef, int type, int gamedata->GetFactoryResource( IconResRef, IE_BAM_CLASS_ID, IE_NORMAL, 1 ); if (!af) { - printf("Searched for: %s\n", IconResRef); - return RuntimeError( "BAM not found" ); + char tmpstr[24]; + + snprintf(tmpstr,sizeof(tmpstr),"%s BAM not found", IconResRef); + return RuntimeError( tmpstr ); } //small difference between pst and others if (af->GetCycleSize(0)!=4) { //non-pst @@ -5581,17 +5520,15 @@ static PyObject* GemRB_GetContainer(PyObject * /*self*/, PyObject* args) Actor *actor; - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + if (PartyID) { actor = game->FindPC( PartyID ); } else { actor = core->GetFirstSelectedPC(false); } if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } Container *container = NULL; if (autoselect) { //autoselect works only with piles @@ -5627,13 +5564,11 @@ static PyObject* GemRB_GetContainerItem(PyObject * /*self*/, PyObject* args) Container *container; if (PartyID) { - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor *actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } Map *map = actor->GetCurrentArea(); container = map->TMap->GetContainer(actor->Pos, IE_CONTAINER_PILE); @@ -5682,23 +5617,21 @@ static PyObject* GemRB_ChangeContainerItem(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "iii", &PartyID, &Slot, &action)) { return AttributeError( GemRB_ChangeContainerItem__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor; Container *container; if (PartyID) { actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } Map *map = actor->GetCurrentArea(); container = map->TMap->GetContainer(actor->Pos, IE_CONTAINER_PILE); } else { actor = core->GetFirstSelectedPC(false); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } container = core->GetCurrentContainer(); } @@ -5895,13 +5828,11 @@ static PyObject* GemRB_IsValidStoreItem(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "ii|i", &PartyID, &Slot, &type)) { return AttributeError( GemRB_IsValidStoreItem__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } Store *store = core->GetCurrentStore(); @@ -6042,13 +5973,11 @@ static PyObject* GemRB_ChangeStoreItem(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "iii", &PartyID, &Slot, &action)) { return AttributeError( GemRB_ChangeStoreItem__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } Store *store = core->GetCurrentStore(); @@ -6377,10 +6306,8 @@ static PyObject* GemRB_ExecuteString(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "s|i", &String, &actornum )) { return AttributeError( GemRB_ExecuteString__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + if (actornum) { Actor *pc = game->FindPC(actornum); if (pc) { @@ -6406,7 +6333,9 @@ static PyObject* GemRB_EvaluateString(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "s", &String )) { return AttributeError( GemRB_EvaluateString__doc ); } - if (GameScript::EvaluateString( core->GetGame()->GetCurrentArea( ), String )) { + GET_GAME(); + + if (GameScript::EvaluateString( game->GetCurrentArea( ), String )) { printf( "%s returned True\n", String ); } else { printf( "%s returned False\n", String ); @@ -6445,7 +6374,9 @@ PyDoc_STRVAR( GemRB_GetCurrentArea__doc, static PyObject* GemRB_GetCurrentArea(PyObject * /*self*/, PyObject* /*args*/) { - return PyString_FromString( core->GetGame()->CurrentArea ); + GET_GAME(); + + return PyString_FromString( game->CurrentArea ); } PyDoc_STRVAR( GemRB_MoveToArea__doc, @@ -6459,10 +6390,8 @@ static PyObject* GemRB_MoveToArea(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "s", &String )) { return AttributeError( GemRB_MoveToArea__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Map* map2 = game->GetMap(String, true); if (!map2) { return RuntimeError( "Map not found!" ); @@ -6495,13 +6424,11 @@ static PyObject* GemRB_GetMemorizableSpellsCount(PyObject* /*self*/, PyObject* a if (!PyArg_ParseTuple( args, "iii|i", &PartyID, &SpellType, &Level, &Bonus )) { return AttributeError( GemRB_GetMemorizableSpellsCount__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } //this isn't in the actor's spellbook, handles Wisdom @@ -6519,13 +6446,11 @@ static PyObject* GemRB_SetMemorizableSpellsCount(PyObject* /*self*/, PyObject* a if (!PyArg_ParseTuple( args, "iiii", &PartyID, &Value, &SpellType, &Level)) { return AttributeError( GemRB_SetMemorizableSpellsCount__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } //the bonus increased value (with wisdom too) is handled by the core @@ -6546,13 +6471,11 @@ static PyObject* GemRB_GetKnownSpellsCount(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "iii", &PartyID, &SpellType, &Level )) { return AttributeError( GemRB_GetKnownSpellsCount__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } return PyInt_FromLong(actor->spellbook.GetKnownSpellsCount( SpellType, Level ) ); @@ -6569,13 +6492,11 @@ static PyObject* GemRB_GetKnownSpell(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "iiii", &PartyID, &SpellType, &Level, &Index )) { return AttributeError( GemRB_GetKnownSpell__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found!" ); + return RuntimeError( "Actor not found!\n" ); } CREKnownSpell* ks = actor->spellbook.GetKnownSpell( SpellType, Level, Index ); @@ -6605,10 +6526,8 @@ static PyObject* GemRB_GetMemorizedSpellsCount(PyObject * /*self*/, PyObject* ar if (!PyArg_ParseTuple( args, "ii|ii", &PartyID, &SpellType, &Level, &global )) { return AttributeError( GemRB_GetMemorizedSpellsCount__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor; if (global) { actor = game->GetActorByGlobalID( PartyID ); @@ -6616,7 +6535,7 @@ static PyObject* GemRB_GetMemorizedSpellsCount(PyObject * /*self*/, PyObject* ar actor = game->FindPC( PartyID ); } if (!actor) { - return RuntimeError( "Actor not found!" ); + return RuntimeError( "Actor not found!\n" ); } if (Level<0) { @@ -6637,13 +6556,11 @@ static PyObject* GemRB_GetMemorizedSpell(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "iiii", &PartyID, &SpellType, &Level, &Index )) { return AttributeError( GemRB_GetMemorizedSpell__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found!" ); + return RuntimeError( "Actor not found!\n" ); } CREMemorizedSpell* ms = actor->spellbook.GetMemorizedSpell( SpellType, Level, Index ); @@ -6711,13 +6628,11 @@ static PyObject* GemRB_LearnSpell(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "is|i", &PartyID, &Spell, &Flags )) { return AttributeError( GemRB_LearnSpell__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } int ret = actor->LearnSpell( Spell, Flags ); // returns 0 on success @@ -6739,13 +6654,11 @@ static PyObject* GemRB_DispelEffect(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "isi", &PartyID, &EffectName, &Parameter2 )) { return AttributeError( GemRB_DispelEffect__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found!" ); + return RuntimeError( "Actor not found!\n" ); } work_ref.Name=EffectName; @@ -6769,13 +6682,11 @@ static PyObject* GemRB_RemoveEffects(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "is", &PartyID, &SpellResRef )) { return AttributeError( GemRB_RemoveEffects__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found!" ); + return RuntimeError( "Actor not found!\n" ); } actor->fxqueue.RemoveAllEffects(SpellResRef); @@ -6795,13 +6706,11 @@ static PyObject* GemRB_RemoveSpell(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "iiii", &PartyID, &SpellType, &Level, &Index )) { return AttributeError( GemRB_RemoveSpell__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found!" ); + return RuntimeError( "Actor not found!\n" ); } CREKnownSpell* ks = actor->spellbook.GetKnownSpell( SpellType, Level, Index ); @@ -6824,13 +6733,11 @@ static PyObject* GemRB_RemoveItem(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "ii|i", &PartyID, &Slot, &Count )) { return AttributeError( GemRB_RemoveItem__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found!" ); + return RuntimeError( "Actor not found!\n" ); } int ok; @@ -6858,13 +6765,11 @@ static PyObject* GemRB_MemorizeSpell(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "iiii", &PartyID, &SpellType, &Level, &Index )) { return AttributeError( GemRB_MemorizeSpell__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found!" ); + return RuntimeError( "Actor not found!\n" ); } CREKnownSpell* ks = actor->spellbook.GetKnownSpell( SpellType, Level, Index ); @@ -6890,18 +6795,16 @@ static PyObject* GemRB_UnmemorizeSpell(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "iiii", &PartyID, &SpellType, &Level, &Index )) { return AttributeError( GemRB_UnmemorizeSpell__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found!" ); + return RuntimeError( "Actor not found!\n" ); } CREMemorizedSpell* ms = actor->spellbook.GetMemorizedSpell( SpellType, Level, Index ); if (! ms) { - return RuntimeError( "Spell not found!" ); + return RuntimeError( "Spell not found!\n" ); } return PyInt_FromLong( actor->spellbook.UnmemorizeSpell( ms ) ); @@ -6926,10 +6829,8 @@ static PyObject* GemRB_GetSlotItem(PyObject * /*self*/, PyObject* args) if (PartyID==0) { si = core->GetDraggedItem(); } else { - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor; if (global) { actor = game->GetActorByGlobalID( PartyID ); @@ -6937,7 +6838,7 @@ static PyObject* GemRB_GetSlotItem(PyObject * /*self*/, PyObject* args) actor = game->FindPC( PartyID ); } if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } Slot = core->QuerySlot(Slot); @@ -6971,13 +6872,11 @@ static PyObject* GemRB_ChangeItemFlag(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "iiii", &PartyID, &Slot, &Flags, &Mode)) { return AttributeError( GemRB_ChangeItemFlag__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor *actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } if (actor->inventory.ChangeItemFlag(core->QuerySlot(Slot), Flags, Mode)) { return PyInt_FromLong(1); @@ -7008,13 +6907,11 @@ static PyObject* GemRB_CanUseItemType(PyObject * /*self*/, PyObject* args) } Actor* actor = 0; if (PartyID) { - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } } @@ -7041,13 +6938,11 @@ static PyObject* GemRB_GetSlots(PyObject * /*self*/, PyObject* args) return AttributeError( GemRB_GetSlots__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } MaxCount = core->SlotTypes; @@ -7294,14 +7189,12 @@ static PyObject* GemRB_DragItem(PyObject * /*self*/, PyObject* args) return Py_None; } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); //allow -1,-1 if (!actor && ( PartyID || ResRef[0]) ) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } //dragging a portrait @@ -7384,13 +7277,11 @@ static PyObject* GemRB_DropDraggedItem(PyObject * /*self*/, PyObject* args) return Py_None; } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } int res; @@ -7583,13 +7474,11 @@ static PyObject* GemRB_CreateItem(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "is|iiii", &PartyID, &ItemResRef, &SlotID, &Charge0, &Charge1, &Charge2)) { return AttributeError( GemRB_CreateItem__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } if (SlotID==-1) { @@ -7621,6 +7510,45 @@ static PyObject* GemRB_CreateItem(PyObject * /*self*/, PyObject* args) return Py_None; } +PyDoc_STRVAR( GemRB_SetMapAnimation__doc, +"SetMapAnimation(X, Y, BAMresref[, flags, cycle, height])\n\n" +"Creates an area animation."); + +static PyObject* GemRB_SetMapAnimation(PyObject * /*self*/, PyObject* args) +{ + int x,y; + const char *ResRef; + int Cycle = 0; + int Flags = 0x19; + int Height = 0x1e; + //the animation is cloned by AddAnimation, so we can keep the original on + //the stack + AreaAnimation anim; + memset(&anim,0,sizeof(anim)); + + if (!PyArg_ParseTuple( args, "iis|iii", &x, &y, &ResRef, &Flags, &Cycle, &Height)) { + return AttributeError( GemRB_CreateItem__doc ); + } + + GET_GAME(); + + GET_MAP(); + + anim.appearance=0xffffffff; //scheduled for every hour + anim.Pos.x=(short) x; + anim.Pos.y=(short) y; + strnlwrcpy(anim.Name, ResRef, 8); + strnlwrcpy(anim.BAM, ResRef, 8); + anim.Flags=Flags; + anim.sequence=Cycle; + anim.height=Height; + if (Flags&A_ANI_ACTIVE) { + map->AddAnimation(&anim); + } + Py_INCREF( Py_None ); + return Py_None; +} + PyDoc_STRVAR( GemRB_SetMapnote__doc, "SetMapnote(X, Y, color, Text)\n\n" "Adds or removes a mapnote."); @@ -7634,14 +7562,10 @@ static PyObject* GemRB_SetMapnote(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "ii|is", &x, &y, &color, &txt)) { return AttributeError( GemRB_SetMapnote__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } - Map *map = game->GetCurrentArea(); - if (!map) { - return RuntimeError( "No current area" ); - } + GET_GAME(); + + GET_MAP(); + ieStrRef strref; Point point; point.x=x; @@ -7660,33 +7584,135 @@ static PyObject* GemRB_SetMapnote(PyObject * /*self*/, PyObject* args) return Py_None; } +PyDoc_STRVAR( GemRB_SetMapDoor__doc, +"SetMapDoor(DoorName, State)\n\n" +"Modifies a door's open state in the current area."); + +static PyObject* GemRB_SetMapDoor(PyObject * /*self*/, PyObject* args) +{ + const char *DoorName; + int State; + + if (!PyArg_ParseTuple( args, "si", &DoorName, &State) ) { + return AttributeError( GemRB_SetMapDoor__doc); + } + + GET_GAME(); + + GET_MAP(); + + Door *door = map->TMap->GetDoor(DoorName); + if (!door) { + return RuntimeError( "No such door!" ); + } + + door->SetDoorOpen(State, 0, 0); + Py_INCREF( Py_None ); + return Py_None; +} + +PyDoc_STRVAR( GemRB_SetMapExit__doc, +"SetMapExit(ExitName[, NewArea, NewEntrance])\n\n" +"Modifies the target of an exit in the current area. If no destination is given, " +"then the exit will be disabled."); + +static PyObject* GemRB_SetMapExit(PyObject * /*self*/, PyObject* args) +{ + const char *ExitName; + const char *NewArea = NULL; + const char *NewEntrance = NULL; + + if (!PyArg_ParseTuple( args, "s|ss", &ExitName, &NewArea, &NewEntrance)) { + return AttributeError( GemRB_SetMapExit__doc ); + } + + GET_GAME(); + + GET_MAP(); + + InfoPoint *ip = map->TMap->GetInfoPoint(ExitName); + if (!ip || ip->Type!=ST_TRAVEL) { + return RuntimeError( "No such exit!" ); + } + + if (!NewArea) { + //disable entrance + ip->Flags|=TRAP_DEACTIVATED; + } else { + //activate entrance + ip->Flags&=~TRAP_DEACTIVATED; + //set destination area + strnuprcpy(ip->Destination, NewArea, sizeof(ieResRef)-1 ); + //change entrance only if supplied + if (NewEntrance) { + strnuprcpy(ip->EntranceName, NewEntrance, sizeof(ieVariable)-1 ); + } + } + + Py_INCREF( Py_None ); + return Py_None; +} + +PyDoc_STRVAR( GemRB_SetMapRegion__doc, +"SetMapRegion(TrapName[, trapscript])\n\n" +"Enables or disables an infopoint in the current area."); + +static PyObject* GemRB_SetMapRegion(PyObject * /*self*/, PyObject* args) +{ + const char *Name; + const char *TrapScript = NULL; + + if (!PyArg_ParseTuple( args, "s|s", &Name, &TrapScript)) { + return AttributeError( GemRB_SetMapRegion__doc ); + } + + GET_GAME(); + + GET_MAP(); + + InfoPoint *ip = map->TMap->GetInfoPoint(Name); + if (ip) { + if (TrapScript && TrapScript[0]) { + ip->Flags&=~TRAP_DEACTIVATED; + ip->SetScript(TrapScript,0); + } else { + ip->Flags|=TRAP_DEACTIVATED; + } + } + + Py_INCREF( Py_None ); + return Py_None; +} + + PyDoc_STRVAR( GemRB_CreateCreature__doc, -"CreateCreature(PartyID, CreResRef)\n\n" -"Creates Creature in vicinity of a player character."); +"CreateCreature(PartyID, CreResRef[, posX, posY])\n\n" +"Creates Creature at a point. If the position parameters are unspecified " +"then the creature will be put near the player character given by the first parameter."); static PyObject* GemRB_CreateCreature(PyObject * /*self*/, PyObject* args) { int PartyID; const char *CreResRef; + int PosX = -1, PosY = -1; - if (!PyArg_ParseTuple( args, "is", &PartyID, &CreResRef)) { + if (!PyArg_ParseTuple( args, "is|ii", &PartyID, &CreResRef, &PosX, &PosY)) { return AttributeError( GemRB_CreateCreature__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } - Actor* actor = game->FindPC( PartyID ); - if (!actor) { - return RuntimeError( "Actor not found" ); - } - Map *map=game->GetCurrentArea(); - if (!map) { - return RuntimeError( "No current area" ); - } + GET_GAME(); - map->SpawnCreature(actor->Pos, CreResRef, 10); + GET_MAP(); + + if (PosX!=-1 && PosY!=-1) { + map->SpawnCreature(Point(PosX, PosY), CreResRef, 0); + } else { + Actor* actor = game->FindPC( PartyID ); + if (!actor) { + return RuntimeError( "Actor not found!\n" ); + } + map->SpawnCreature(actor->Pos, CreResRef, 10); + } Py_INCREF( Py_None ); return Py_None; } @@ -7706,14 +7732,10 @@ static PyObject* GemRB_RevealArea(PyObject * /*self*/, PyObject* args) } Point p(x,y); - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } - Map *map=game->GetCurrentArea(); - if (!map) { - return RuntimeError( "No current area" ); - } + GET_GAME(); + + GET_MAP(); + map->ExploreMapChunk( p, radius, Value ); Py_INCREF( Py_None ); @@ -7731,14 +7753,10 @@ static PyObject* GemRB_ExploreArea(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "|i", &Value)) { return AttributeError( GemRB_ExploreArea__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } - Map *map=game->GetCurrentArea(); - if (!map) { - return RuntimeError( "No current area" ); - } + GET_GAME(); + + GET_MAP(); + map->Explore( Value ); Py_INCREF( Py_None ); @@ -7856,14 +7874,11 @@ static PyObject* GemRB_CheckFeatCondition(PyObject * /*self*/, PyObject* args) } } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); - Actor *actor = core->GetGame()->FindPC(v[0]); + Actor *actor = game->FindPC(v[0]); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } /* see if the special function exists */ @@ -7929,13 +7944,11 @@ static PyObject* GemRB_GetAbilityBonus(PyObject * /*self*/, PyObject* args) return AttributeError( GemRB_GetAbilityBonus__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor *actor = game->FindPC(game->GetSelectedPCSingle()); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } switch (stat) { @@ -7980,13 +7993,11 @@ static PyObject* GemRB_LeaveParty(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "i|i", &PlayerSlot, &initDialog )) { return AttributeError( GemRB_LeaveParty__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor *actor = game->FindPC(PlayerSlot); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } if (initDialog) { @@ -8084,7 +8095,10 @@ static PyObject* SetActionIcon(int WindowIndex, int ControlIndex, PyObject *dict gamedata->GetFactoryResource( GUIResRef[Index], IE_BAM_CLASS_ID, IE_NORMAL ); if (!bam) { - return RuntimeError( "BAM not found" ); + char tmpstr[24]; + + snprintf(tmpstr,sizeof(tmpstr),"%s BAM not found", GUIResRef[Index]); + return RuntimeError( tmpstr ); } packtype row; @@ -8168,10 +8182,8 @@ static PyObject* GemRB_Window_SetupEquipmentIcons(PyObject * /*self*/, PyObject* return AttributeError( GemRB_Window_SetupEquipmentIcons__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor; if (global) { actor = game->GetActorByGlobalID( slot ); @@ -8179,7 +8191,7 @@ static PyObject* GemRB_Window_SetupEquipmentIcons(PyObject * /*self*/, PyObject* actor = game->FindPC( slot ); } if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } //-2 because of the left/right scroll icons @@ -8199,7 +8211,7 @@ static PyObject* GemRB_Window_SetupEquipmentIcons(PyObject * /*self*/, PyObject* gamedata->GetFactoryResource( "guibtbut", IE_BAM_CLASS_ID, IE_NORMAL ); if (!bam) { - return RuntimeError( "BAM not found" ); + return RuntimeError("guibtbut BAM not found"); } for (i=0;iGetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor; if (global) { actor = game->GetActorByGlobalID( slot ); @@ -8293,7 +8303,7 @@ static PyObject* GemRB_Window_SetupSpellIcons(PyObject * /*self*/, PyObject* arg actor = game->FindPC( slot ); } if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } //-2 because of the left/right scroll icons @@ -8324,7 +8334,7 @@ static PyObject* GemRB_Window_SetupSpellIcons(PyObject * /*self*/, PyObject* arg gamedata->GetFactoryResource( "guibtbut", IE_BAM_CLASS_ID, IE_NORMAL ); if (!bam) { - return RuntimeError( "BAM not found" ); + return RuntimeError("guibtbut BAM not found"); } // disable all spells if fx_disable_spellcasting was run with the same type @@ -8422,10 +8432,10 @@ static PyObject* GemRB_Window_SetupControls(PyObject * /*self*/, PyObject* args) return AttributeError( GemRB_Window_SetupControls__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + + GET_GAMECONTROL(); + Actor* actor = NULL; if (slot) { @@ -8441,7 +8451,7 @@ static PyObject* GemRB_Window_SetupControls(PyObject * /*self*/, PyObject* args) } if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } ActionButtonRow myrow; @@ -8587,7 +8597,7 @@ static PyObject* GemRB_Window_SetupControls(PyObject * /*self*/, PyObject* args) SetItemText(wi, ci, item->Usages[actor->PCStats->QuickWeaponHeaders[action-ACT_WEAPON1]], true); if (usedslot == slot) { btn->EnableBorder(0, true); - if (core->GetGameControl()->GetTargetMode() == TARGET_MODE_ATTACK) { + if (gc->GetTargetMode() == TARGET_MODE_ATTACK) { state = IE_GUI_BUTTON_SELECTED; } else { state = IE_GUI_BUTTON_THIRD; @@ -8677,10 +8687,8 @@ static PyObject* GemRB_ClearActions(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "i|i", &slot, &global )) { return AttributeError( GemRB_ClearActions__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!\n" ); - } + GET_GAME(); + Actor* actor; if (global) { actor = game->GetActorByGlobalID( slot ); @@ -8700,7 +8708,6 @@ static PyObject* GemRB_ClearActions(PyObject * /*self*/, PyObject* args) Py_INCREF( Py_None ); return Py_None; } - core->GetGame()->OutAttack(actor->GetGlobalID()); //stop attacking actor->ClearPath(); //stop walking actor->ClearActions(); //stop pending action involved walking actor->SetModal(MS_NONE);//stop modal actions @@ -8744,10 +8751,8 @@ static PyObject* GemRB_SetupQuickSlot(PyObject * /*self*/, PyObject* args) return AttributeError( GemRB_SetupQuickSlot__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor; if (global) { actor = game->GetActorByGlobalID( PartyID ); @@ -8755,7 +8760,7 @@ static PyObject* GemRB_SetupQuickSlot(PyObject * /*self*/, PyObject* args) actor = game->FindPC( PartyID ); } if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } slot = core->QuerySlot(slot); @@ -8781,10 +8786,8 @@ static PyObject* GemRB_SetEquippedQuickSlot(PyObject * /*self*/, PyObject* args) return AttributeError( GemRB_SetEquippedQuickSlot__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor; if (global) { actor = game->GetActorByGlobalID( PartyID ); @@ -8792,7 +8795,7 @@ static PyObject* GemRB_SetEquippedQuickSlot(PyObject * /*self*/, PyObject* args) actor = game->FindPC( PartyID ); } if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } int ret = actor->SetEquippedQuickSlot(slot, ability); @@ -8814,10 +8817,8 @@ static PyObject* GemRB_GetEquippedQuickSlot(PyObject * /*self*/, PyObject* args) return AttributeError( GemRB_GetEquippedQuickSlot__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor; if (global) { actor = game->GetActorByGlobalID( PartyID ); @@ -8825,7 +8826,7 @@ static PyObject* GemRB_GetEquippedQuickSlot(PyObject * /*self*/, PyObject* args) actor = game->FindPC( PartyID ); } if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } int ret = actor->inventory.GetEquippedSlot(); @@ -8861,13 +8862,11 @@ static PyObject* GemRB_GetEquippedAmmunition(PyObject * /*self*/, PyObject* args return AttributeError( GemRB_GetEquippedQuickSlot__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } int ret = actor->inventory.GetEquippedSlot(); @@ -8895,10 +8894,8 @@ static PyObject* GemRB_SetModalState(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "ii|is", &slot, &state, &global, &spell )) { return AttributeError( GemRB_SetModalState__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor; if (global) { actor = game->GetActorByGlobalID( slot ); @@ -8906,7 +8903,7 @@ static PyObject* GemRB_SetModalState(PyObject * /*self*/, PyObject* args) actor = game->FindPC( slot ); } if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } actor->SetModal( (ieDword) state, 0); actor->SetModalSpell(state, spell); @@ -8932,10 +8929,9 @@ static PyObject* GemRB_SpellCast(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "iii|i", &slot, &type, &spell, &global )) { return AttributeError( GemRB_SpellCast__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + + GET_GAME(); + Actor* actor; if (global) { actor = game->GetActorByGlobalID( slot ); @@ -8943,7 +8939,7 @@ static PyObject* GemRB_SpellCast(PyObject * /*self*/, PyObject* args) actor = game->FindPC( slot ); } if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } //don't cast anything, just reinit the spell list @@ -8969,7 +8965,8 @@ static PyObject* GemRB_SpellCast(PyObject * /*self*/, PyObject* args) return RuntimeError( "Wrong type of spell!"); } - GameControl *gc = core->GetGameControl(); + GET_GAMECONTROL(); + switch (spelldata.Target) { case TARGET_SELF: // FIXME: GA_NO_DEAD and such are not actually used by SetupCasting @@ -9015,15 +9012,16 @@ static PyObject* GemRB_ApplySpell(PyObject * /*self*/, PyObject* args) return AttributeError( GemRB_ApplySpell__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + + Map *map = game->GetCurrentArea(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } - Actor *caster = game->GetCurrentArea()->GetActorByGlobalID(casterID); + Actor *caster = NULL; + if (map) caster = map->GetActorByGlobalID(casterID); if (!caster) caster = game->GetActorByGlobalID(casterID); if (!caster) caster = actor; @@ -9053,10 +9051,10 @@ static PyObject* GemRB_UseItem(PyObject * /*self*/, PyObject* args) return AttributeError( GemRB_UseItem__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + + GET_GAMECONTROL(); + Actor* actor; if (global) { actor = game->GetActorByGlobalID( PartyID ); @@ -9064,7 +9062,7 @@ static PyObject* GemRB_UseItem(PyObject * /*self*/, PyObject* args) actor = game->FindPC( PartyID ); } if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } ItemExtHeader itemdata; int flags = 0; @@ -9111,19 +9109,21 @@ static PyObject* GemRB_UseItem(PyObject * /*self*/, PyObject* args) // switch (forcetarget) { case TARGET_SELF: - actor->UseItem(itemdata.slot, itemdata.headerindex, actor, flags); + gc->SetupItemUse(itemdata.slot, itemdata.headerindex, actor, GA_NO_DEAD, itemdata.TargetNumber); + gc->TryToCast(actor, actor); break; case TARGET_NONE: + gc->ResetTargetMode(); actor->UseItem(itemdata.slot, itemdata.headerindex, NULL, flags); break; case TARGET_AREA: - core->GetGameControl()->SetupItemUse(itemdata.slot, itemdata.headerindex, actor, GA_POINT, itemdata.TargetNumber); + gc->SetupItemUse(itemdata.slot, itemdata.headerindex, actor, GA_POINT, itemdata.TargetNumber); break; case TARGET_CREA: - core->GetGameControl()->SetupItemUse(itemdata.slot, itemdata.headerindex, actor, GA_NO_DEAD, itemdata.TargetNumber); + gc->SetupItemUse(itemdata.slot, itemdata.headerindex, actor, GA_NO_DEAD, itemdata.TargetNumber); break; case TARGET_DEAD: - core->GetGameControl()->SetupItemUse(itemdata.slot, itemdata.headerindex, actor, 0, itemdata.TargetNumber); + gc->SetupItemUse(itemdata.slot, itemdata.headerindex, actor, 0, itemdata.TargetNumber); break; default: printMessage("GUIScript", "Unhandled target type!", LIGHT_RED ); @@ -9219,10 +9219,8 @@ static PyObject* GemRB_RestParty(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "iii", &noareacheck, &dream, &hp)) { return AttributeError( GemRB_RestParty__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + game->RestParty(noareacheck, dream, hp); Py_INCREF( Py_None ); return Py_None; @@ -9244,13 +9242,11 @@ static PyObject* GemRB_HasSpecialItem(PyObject * /*self*/, PyObject* args) ReadSpecialItems(); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } int i = SpecialItemsCount; int slot = -1; @@ -9290,13 +9286,11 @@ static PyObject* GemRB_HasSpecialSpell(PyObject * /*self*/, PyObject* args) return AttributeError( GemRB_HasSpecialSpell__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } int i = core->GetSpecialSpellsCount(); if (i == -1) { @@ -9339,20 +9333,18 @@ static PyObject* GemRB_ApplyEffect(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "isii|ssss", &PartyID, &opcodename, ¶m1, ¶m2, &resref1, &resref2, &resref3, &source)) { return AttributeError( GemRB_ApplyEffect__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } work_ref.Name=opcodename; work_ref.opcode=-1; Effect *fx = EffectQueue::CreateEffect(work_ref, param1, param2, FX_DURATION_INSTANT_PERMANENT_AFTER_BONUSES); if (!fx) { //invalid effect name didn't resolve to opcode - return RuntimeError( "Invalid effect name!" ); + return RuntimeError( "Invalid effect name!\n" ); } if (resref1) { strnlwrcpy(fx->Resource, resref1, 8); @@ -9395,13 +9387,11 @@ static PyObject* GemRB_CountEffects(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "isii|s", &PartyID, &opcodename, ¶m1, ¶m2, &resref)) { return AttributeError( GemRB_CountEffects__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } work_ref.Name=opcodename; work_ref.opcode=-1; @@ -9423,13 +9413,11 @@ static PyObject* GemRB_ModifyEffect(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "isii", &PartyID, &opcodename, &px, &py)) { return AttributeError( GemRB_ModifyEffect__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } work_ref.Name=opcodename; work_ref.opcode=-1; @@ -9445,18 +9433,14 @@ PyDoc_STRVAR( GemRB_StealFailed__doc, static PyObject* GemRB_StealFailed(PyObject * /*self*/, PyObject* /*args*/) { - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Store *store = core->GetCurrentStore(); if (!store) { return RuntimeError( "No store loaded!" ); } - Map *map = game->GetCurrentArea(); - if (!map) { - return RuntimeError( "No area loaded!" ); - } + GET_MAP(); + Actor* owner = map->GetActorByGlobalID( store->GetOwnerID() ); if (!owner) owner = game->GetActorByGlobalID( store->GetOwnerID() ); if (!owner) { @@ -9496,10 +9480,7 @@ static PyObject* GemRB_SwapPCs(PyObject * /*self*/, PyObject* args) return AttributeError( GemRB_SwapPCs__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); game->SwapPCs(game->FindPlayer(idx1), game->FindPlayer(idx2)); //leader changed @@ -9541,13 +9522,11 @@ static PyObject* GemRB_DisplayString(PyObject * /*self*/, PyObject* args) return AttributeError( GemRB_DisplayString__doc ); } if (PartyID) { - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor *actor = game->FindPC(PartyID); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } displaymsg->DisplayStringName(strref, (unsigned int) color, actor, IE_STR_SOUND); } else { @@ -9569,13 +9548,11 @@ static PyObject* GemRB_GetCombatDetails(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "ii", &PartyID, &leftorright)) { return AttributeError( GemRB_GetCombatDetails__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } leftorright = leftorright&1; @@ -9611,13 +9588,11 @@ static PyObject* GemRB_IsDualWielding(PyObject * /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "i", &PartyID)) { return AttributeError( GemRB_IsDualWielding__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } int dualwield = actor->IsDualWielding(); @@ -9630,10 +9605,8 @@ PyDoc_STRVAR( GemRB_GetSelectedSize__doc, static PyObject* GemRB_GetSelectedSize(PyObject* /*self*/, PyObject* /*args*/) { - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + return PyInt_FromLong(game->selected.size()); } @@ -9643,10 +9616,8 @@ PyDoc_STRVAR( GemRB_GetSelectedActors__doc, static PyObject* GemRB_GetSelectedActors(PyObject* /*self*/, PyObject* /*args*/) { - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + int count = game->selected.size(); PyObject* actor_list = PyTuple_New(count); for (int i = 0; i < count; i++) { @@ -9667,13 +9638,11 @@ static PyObject* GemRB_GetSpellCastOn(PyObject* /*self*/, PyObject* args) if (!PyArg_ParseTuple( args, "i", &PartyID )) { return AttributeError( GemRB_GetSpellCastOn__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); + Actor* actor = game->FindPC( PartyID ); if (!actor) { - return RuntimeError( "Actor not found" ); + return RuntimeError( "Actor not found!\n" ); } ResolveSpellName(splname, actor->LastSpellOnMe); @@ -9727,10 +9696,7 @@ static PyObject* GemRB_SetupMaze(PyObject* /*self*/, PyObject* args) return AttributeError( GemRB_SetupMaze__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); maze_header *h = (maze_header *) (game->AllocateMazeData()+MAZE_ENTRY_COUNT*MAZE_ENTRY_SIZE); memset(h, 0, MAZE_HEADER_SIZE); @@ -9751,7 +9717,7 @@ PyDoc_STRVAR( GemRB_SetMazeEntry__doc, "SetMazeEntry(entry, type, value)\n\n" "Sets a field in a maze entry. " "The entry index shouldn't exceed the maximum possible maze size (64). " -"The type could be: ME_0, ME_WALLS, ME_TRAP or ME_16."); +"The type could be: ME_ACCESSED, ME_WALLS, ME_TRAP or ME_SPECIAL."); static PyObject* GemRB_SetMazeEntry(PyObject* /*self*/, PyObject* args) { @@ -9767,22 +9733,17 @@ static PyObject* GemRB_SetMazeEntry(PyObject* /*self*/, PyObject* args) return AttributeError( GemRB_SetMazeEntry__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); if (!game->mazedata) { return RuntimeError( "No maze set up!" ); } - maze_header *h = (maze_header *) (game->mazedata+MAZE_ENTRY_COUNT*MAZE_ENTRY_SIZE); - int dims = h->maze_sizex; maze_entry *m = (maze_entry *) (game->mazedata+entry*MAZE_ENTRY_SIZE); maze_entry *m2; switch(index) { - case ME_0: //unknown00 - m->unknown00 = value; + case ME_OVERRIDE: + m->override = value; break; default: case ME_VALID: @@ -9800,37 +9761,37 @@ static PyObject* GemRB_SetMazeEntry(PyObject* /*self*/, PyObject* args) break; case ME_WALLS: m->walls |= value; - if (value & WALL_EAST) { - if (entry%dims!=dims-1) { + if (value & WALL_SOUTH) { + if (entry%MAZE_MAX_DIM!=MAZE_MAX_DIM-1) { m2 = (maze_entry *) (game->mazedata+(entry+1)*MAZE_ENTRY_SIZE); + m2->walls|=WALL_NORTH; + } + } + + if (value & WALL_NORTH) { + if (entry%MAZE_MAX_DIM) { + m2 = (maze_entry *) (game->mazedata+(entry-1)*MAZE_ENTRY_SIZE); + m2->walls|=WALL_SOUTH; + } + } + + if (value & WALL_EAST) { + if (entry+MAZE_MAX_DIMmazedata+(entry+MAZE_MAX_DIM)*MAZE_ENTRY_SIZE); m2->walls|=WALL_WEST; } } if (value & WALL_WEST) { - if (entry%dims) { - m2 = (maze_entry *) (game->mazedata+(entry-1)*MAZE_ENTRY_SIZE); + if (entry>=MAZE_MAX_DIM) { + m2 = (maze_entry *) (game->mazedata+(entry-MAZE_MAX_DIM)*MAZE_ENTRY_SIZE); m2->walls|=WALL_EAST; } } - if (value & WALL_NORTH) { - if (entry>=dims) { - m2 = (maze_entry *) (game->mazedata+(entry-dims)*MAZE_ENTRY_SIZE); - m2->walls|=WALL_SOUTH; - } - } - - if (value & WALL_SOUTH) { - if (entry+dimsmazedata+(entry+dims)*MAZE_ENTRY_SIZE); - m2->walls|=WALL_SOUTH; - } - } - break; - case ME_16: - m->unknown16 = value; + case ME_VISITED: + m->visited = value; break; } @@ -9852,16 +9813,12 @@ static PyObject* GemRB_SetMazeData(PyObject* /*self*/, PyObject* args) return AttributeError( GemRB_SetMazeData__doc ); } - Game *game = core->GetGame(); - if (!game) { - return RuntimeError( "No game loaded!" ); - } + GET_GAME(); if (!game->mazedata) { return RuntimeError( "No maze set up!" ); } - maze_header *h = (maze_header *) (game->mazedata+MAZE_ENTRY_COUNT*MAZE_ENTRY_SIZE); switch(entry) { case MH_POS1X: @@ -9908,8 +9865,106 @@ static PyObject* GemRB_SetMazeData(PyObject* /*self*/, PyObject* args) return Py_None; } +PyDoc_STRVAR( GemRB_GetMazeHeader__doc, +"GetMazeHeader()=>dict\n\n" +"Returns the Maze header of Planescape Torment savegames." ); + +static PyObject* GemRB_GetMazeHeader(PyObject* /*self*/, PyObject* /*args*/) +{ + GET_GAME(); + + if (!game->mazedata) { + Py_INCREF(Py_None); + return Py_None; + } + + PyObject* dict = PyDict_New(); + maze_header *h = (maze_header *) (game->mazedata+MAZE_ENTRY_COUNT*MAZE_ENTRY_SIZE); + PyDict_SetItemString(dict, "MazeX", PyInt_FromLong (h->maze_sizex)); + PyDict_SetItemString(dict, "MazeY", PyInt_FromLong (h->maze_sizey)); + PyDict_SetItemString(dict, "Pos1X", PyInt_FromLong (h->pos1x)); + PyDict_SetItemString(dict, "Pos1Y", PyInt_FromLong (h->pos1y)); + PyDict_SetItemString(dict, "Pos2X", PyInt_FromLong (h->pos2x)); + PyDict_SetItemString(dict, "Pos2Y", PyInt_FromLong (h->pos2y)); + PyDict_SetItemString(dict, "Pos3X", PyInt_FromLong (h->pos3x)); + PyDict_SetItemString(dict, "Pos3Y", PyInt_FromLong (h->pos3y)); + PyDict_SetItemString(dict, "Pos4X", PyInt_FromLong (h->pos4x)); + PyDict_SetItemString(dict, "Pos4Y", PyInt_FromLong (h->pos4y)); + PyDict_SetItemString(dict, "TrapCount", PyInt_FromLong (h->trapcount)); + PyDict_SetItemString(dict, "Inited", PyInt_FromLong (h->initialized)); + return dict; +} + +PyDoc_STRVAR( GemRB_GetMazeEntry__doc, +"GetMazeEntry(entry)=>dict\n\n" +"Returns a Maze entry from Planescape Torment savegames. Entry must be 0-63." ); + +static PyObject* GemRB_GetMazeEntry(PyObject* /*self*/, PyObject* args) +{ + int entry; + + if (!PyArg_ParseTuple( args, "i", &entry )) { + return AttributeError( GemRB_GetMazeEntry__doc ); + } + + if (entry<0 || entry>=MAZE_ENTRY_COUNT) { + return AttributeError( GemRB_GetMazeEntry__doc ); + } + + GET_GAME(); + + if (!game->mazedata) { + return RuntimeError( "No maze set up!" ); + } + + PyObject* dict = PyDict_New(); + maze_entry *m = (maze_entry *) (game->mazedata+entry*MAZE_ENTRY_SIZE); + PyDict_SetItemString(dict, "Override", PyInt_FromLong (m->override)); + PyDict_SetItemString(dict, "Accessible", PyInt_FromLong (m->accessible)); + PyDict_SetItemString(dict, "Valid", PyInt_FromLong (m->valid)); + if (m->trapped) { + PyDict_SetItemString(dict, "Trapped", PyInt_FromLong (m->traptype)); + } else { + PyDict_SetItemString(dict, "Trapped", PyInt_FromLong (-1)); + } + PyDict_SetItemString(dict, "Walls", PyInt_FromLong (m->walls)); + PyDict_SetItemString(dict, "Visited", PyInt_FromLong (m->visited)); + return dict; +} + +char gametype_hint[100]; +int gametype_hint_weight; + +PyDoc_STRVAR( GemRB_AddGameTypeHint__doc, +"AddGameTypeHint(type, weight, flags=0)\n\n" +"Asserts that GameType should be TYPE, with confidence WEIGHT. " +"Original games should use WEIGHT <= 100, greater values are reserved for new games. " +"FLAGS are not used at the moment."); + +static PyObject* GemRB_AddGameTypeHint(PyObject* /*self*/, PyObject* args) +{ + char* type; + int weight; + int flags = 0; + + if (!PyArg_ParseTuple( args, "si|i", &type, &weight, &flags )) { + return AttributeError( GemRB_AddGameTypeHint__doc ); + } + + if (weight > gametype_hint_weight) { + gametype_hint_weight = weight; + strncpy(gametype_hint, type, sizeof(gametype_hint)-1); + // I assume the '\0' in the end of gametype_hint + } + + Py_INCREF(Py_None); + return Py_None; +} + + static PyMethodDef GemRBMethods[] = { METHOD(ActOnPC, METH_VARARGS), + METHOD(AddGameTypeHint, METH_VARARGS), METHOD(AddNewArea, METH_VARARGS), METHOD(ApplyEffect, METH_VARARGS), METHOD(ApplySpell, METH_VARARGS), @@ -9986,6 +10041,8 @@ static PyMethodDef GemRBMethods[] = { METHOD(GetJournalSize, METH_VARARGS), METHOD(GetKnownSpell, METH_VARARGS), METHOD(GetKnownSpellsCount, METH_VARARGS), + METHOD(GetMazeEntry, METH_VARARGS), + METHOD(GetMazeHeader, METH_NOARGS), METHOD(GetMemorizableSpellsCount, METH_VARARGS), METHOD(GetMemorizedSpell, METH_VARARGS), METHOD(GetMemorizedSpellsCount, METH_VARARGS), @@ -9999,13 +10056,12 @@ static PyMethodDef GemRBMethods[] = { METHOD(GetPlayerScript, METH_VARARGS), METHOD(GetPlayerSound, METH_VARARGS), METHOD(GetPlayerString, METH_VARARGS), + METHOD(GetRumour, METH_VARARGS), METHOD(GetSaveGames, METH_VARARGS), METHOD(GetSelectedSize, METH_NOARGS), METHOD(GetSelectedActors, METH_NOARGS), METHOD(GetString, METH_VARARGS), METHOD(GetSpellCastOn, METH_VARARGS), - METHOD(GetToken, METH_VARARGS), - METHOD(GetVar, METH_VARARGS), METHOD(GetSlotType, METH_VARARGS), METHOD(GetStore, METH_VARARGS), METHOD(GetStoreDrink, METH_VARARGS), @@ -10015,7 +10071,8 @@ static PyMethodDef GemRBMethods[] = { METHOD(GetSlotItem, METH_VARARGS), METHOD(GetSlots, METH_VARARGS), METHOD(GetSystemVariable, METH_VARARGS), - METHOD(GetRumour, METH_VARARGS), + METHOD(GetToken, METH_VARARGS), + METHOD(GetVar, METH_VARARGS), METHOD(HardEndPL, METH_NOARGS), METHOD(HasResource, METH_VARARGS), METHOD(HasSpecialItem, METH_VARARGS), @@ -10058,7 +10115,11 @@ static PyMethodDef GemRBMethods[] = { METHOD(SetGlobal, METH_VARARGS), METHOD(SetInfoTextColor, METH_VARARGS), METHOD(SetJournalEntry, METH_VARARGS), + METHOD(SetMapAnimation, METH_VARARGS), + METHOD(SetMapDoor, METH_VARARGS), + METHOD(SetMapExit, METH_VARARGS), METHOD(SetMapnote, METH_VARARGS), + METHOD(SetMapRegion, METH_VARARGS), METHOD(SetMasterScript, METH_VARARGS), METHOD(SetMazeEntry, METH_VARARGS), METHOD(SetMazeData, METH_VARARGS), @@ -10236,6 +10297,26 @@ GUIScript::~GUIScript(void) GUIAction[0]=UNINIT_IEDWORD; } +/** + * Quote path for use in python strings. + * On windows also convert backslashes to forward slashes. + */ +char* QuotePath(char* tgt, const char* src) +{ + char *p = tgt; + char c; + + do { + c = *src++; +#ifdef WIN32 + if (c == '\\') c = '/'; +#endif + if (c == '"' || c == '\\') *p++ = '\\'; + } while (0 != (*p++ = c)); + return tgt; +} + + PyDoc_STRVAR( GemRB__doc, "Module exposing GemRB data and engine internals\n\n" "This module exposes to python GUIScripts GemRB engine data and internals." @@ -10278,9 +10359,35 @@ bool GUIScript::Init(void) char path[_MAX_PATH]; char path2[_MAX_PATH]; + char quoted[_MAX_PATH]; PathJoin(path, core->GUIScriptsPath, "GUIScripts", NULL); + // 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 ); + return false; + } + + sprintf( string, "import GemRB\n"); + if (PyRun_SimpleString( "import GemRB" ) == -1) { + printMessage( "GUIScript", string, RED ); + 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 ); + return false; + } + + // Detect GameType if it was set to auto + if (stricmp( core->GameType, "auto" ) == 0) { + Autodetect(); + } + // use the iwd guiscripts for how, but leave its override if (stricmp( core->GameType, "how" ) == 0) { PathJoin(path2, path, "iwd", NULL); @@ -10288,38 +10395,13 @@ bool GUIScript::Init(void) PathJoin(path2, path, core->GameType, NULL); } -#ifdef WIN32 - char *p; - - for (p = path; *p != 0; p++) - { - if (*p == '\\') - *p = '/'; - } - - for (p = path2; *p != 0; p++) - { - if (*p == '\\') - *p = '/'; - } -#endif - - sprintf( string, "sys.path.append(\"%s\")", path2 ); + // GameType-specific import path must have a higher priority than + // 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 ); return false; } - sprintf( string, "sys.path.append(\"%s\")", path ); - if (PyRun_SimpleString( string ) == -1) { - printMessage( "GUIScript", string, RED ); - return false; - } - sprintf( string, "import GemRB\n"); - if (PyRun_SimpleString( "import GemRB" ) == -1) { - printMessage( "GUIScript", string, RED ); - return false; - } - sprintf( string, "GemRB.GameType = \"%s\"", core->GameType); if (PyRun_SimpleString( string ) == -1) { printMessage( "GUIScript", string, RED ); @@ -10370,6 +10452,47 @@ bool GUIScript::Init(void) return true; } +bool GUIScript::Autodetect(void) +{ + printMessage( "GUIScript", "Detecting GameType: ", WHITE); + + char path[_MAX_PATH]; + PathJoin( path, core->GUIScriptsPath, "GUIScripts", NULL ); + DirectoryIterator iter( path ); + if (!iter) + return false; + + gametype_hint[0] = '\0'; + gametype_hint_weight = 0; + + do { + const char *dirent = iter.GetName(); + char module[_MAX_PATH]; + + //printf("DE: %s\n", dirent); + if (iter.IsDirectory() && dirent[0] != '.') { + // NOTE: these methods subtly differ in sys.path content, need for __init__.py files ... + // Method1: + PathJoin(module, core->GUIScriptsPath, "GUIScripts", dirent, "Autodetect.py", NULL); + ExecFile(module); + // Method2: + //strcpy( module, dirent ); + //strcat( module, ".Autodetect"); + //LoadScript(module); + } + } while (++iter); + + if (gametype_hint[0]) { + printStatus(gametype_hint, GREEN); + strcpy(core->GameType, gametype_hint); + return true; + } + else { + printStatus("ERROR", LIGHT_RED); + return false; + } +} + bool GUIScript::LoadScript(const char* filename) { if (!Py_IsInitialized()) { diff --git a/project/jni/application/gemrb/gemrb/plugins/GUIScript/GUIScript.h b/project/jni/application/gemrb/gemrb/plugins/GUIScript/GUIScript.h index 1423f09dc..05d8bfdfa 100644 --- a/project/jni/application/gemrb/gemrb/plugins/GUIScript/GUIScript.h +++ b/project/jni/application/gemrb/gemrb/plugins/GUIScript/GUIScript.h @@ -47,6 +47,8 @@ public: ~GUIScript(void); /** Initialization Routine */ bool Init(void); + /** Autodetect GameType */ + bool Autodetect(void); /** Load Script */ bool LoadScript(const char* filename); /** Run Function */ diff --git a/project/jni/application/gemrb/gemrb/plugins/IWDOpcodes/IWDOpcodes.cpp b/project/jni/application/gemrb/gemrb/plugins/IWDOpcodes/IWDOpcodes.cpp index 5efe18cf7..e55f6364a 100644 --- a/project/jni/application/gemrb/gemrb/plugins/IWDOpcodes/IWDOpcodes.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/IWDOpcodes/IWDOpcodes.cpp @@ -222,126 +222,126 @@ static int fx_hamstring (Scriptable* Owner, Actor* target, Effect* fx); //456 static int fx_rapid_shot (Scriptable* Owner, Actor* target, Effect* fx); //457 //No need to make these ordered, they will be ordered by EffectQueue -static EffectRef effectnames[] = { - { "ACVsDamageTypeModifierIWD2", fx_ac_vs_damage_type_modifier_iwd2, -1}, //0 - { "DamageBonusModifier", fx_damage_bonus_modifier, -1 }, //49 - { "DrawUponHolyMight", fx_draw_upon_holy_might, -1},//84 (iwd2) - { "RetreatFrom", fx_turn_undead, -1 },//6e - { "IronSkins", fx_ironskins, -1}, //da (iwd2) - { "Color:FadeRGB", fx_fade_rgb, -1}, //e8 - { "IWDVisualSpellHit", fx_iwd_visual_spell_hit, -1}, //e9 - { "ColdDamage", fx_cold_damage, -1}, //ea - { "ChillTouch", fx_chill_touch, -1}, //ec (how) - { "ChillTouchPanic", fx_chill_touch_panic, -1}, //ec (iwd2) - { "CrushingDamage", fx_crushing_damage, -1}, //ed - { "SaveBonus", fx_save_bonus, -1}, //ee - { "SlowPoison", fx_slow_poison, -1}, //ef - { "IWDMonsterSummoning", fx_iwd_monster_summoning, -1}, //f0 - { "VampiricTouch", fx_vampiric_touch, -1}, //f1 - { "AnimateDead", fx_animate_dead, -1}, //f3 - { "Prayer2", fx_prayer, -1}, //f4 - { "Curse2", fx_curse, -1}, //f5 - { "SummonMonster2", fx_summon_monster2, -1}, //f6 - { "BurningBlood", fx_burning_blood, -1}, //f7 - { "BurningBlood2", fx_burning_blood2, -1}, //f7 - { "SummonShadowMonster", fx_summon_shadow_monster, -1}, //f8 - { "Recitation", fx_recitation, -1}, //f9 - { "RecitationBad", fx_recitation_bad, -1},//fa - { "LichTouch", fx_lich_touch, -1},//fb - { "BlindingOrb", fx_blinding_orb, -1}, //fc - { "RemoveEffects", fx_remove_effects, -1}, //fe - { "SalamanderAura", fx_salamander_aura, -1}, //ff - { "UmberHulkGaze", fx_umberhulk_gaze, -1}, //100 - { "ZombieLordAura", fx_zombielord_aura, -1},//101, duff in iwd2 - { "SummonCreature2", fx_summon_creature2, -1}, //103 - { "AvatarRemoval", fx_avatar_removal, -1}, //104 - { "SummonPomab", fx_summon_pomab, -1}, //106 - { "ControlUndead", fx_control_undead, -1}, //107 - { "StaticCharge", fx_static_charge, -1}, //108 - { "CloakOfFear", fx_cloak_of_fear, -1}, //109 how/iwd2 - { "EyeOfTheMind", fx_eye_of_the_mind, -1}, //10c - { "EyeOfTheSword", fx_eye_of_the_sword, -1}, //10d - { "EyeOfTheMage", fx_eye_of_the_mage, -1}, //10e - { "EyeOfVenom", fx_eye_of_venom, -1}, //10f - { "EyeOfTheSpirit", fx_eye_of_the_spirit, -1}, //110 - { "EyeOfFortitude", fx_eye_of_fortitude, -1}, //111 - { "EyeOfStone", fx_eye_of_stone, -1}, //112 - { "RemoveSevenEyes", fx_remove_seven_eyes, -1}, //113 - { "RemoveEffect", fx_remove_effect, -1}, //114 - { "SoulEater", fx_soul_eater, -1}, //115 - { "ShroudOfFlame", fx_shroud_of_flame, -1},//116 - { "ShroudOfFlame2", fx_shroud_of_flame2, -1},//116 - { "AnimalRage", fx_animal_rage, -1}, //117 - berserk? - { "TurnUndead", fx_turn_undead, -1}, //118 how - { "TurnUndead2", fx_turn_undead2, -1}, //118 iwd2 - { "VitriolicSphere", fx_vitriolic_sphere, -1}, //119 - { "SuppressHP", fx_suppress_hp, -1}, //11a -- some stat??? - { "FloatText", fx_floattext, -1}, //11b - { "MaceOfDisruption", fx_mace_of_disruption, -1}, //11c - { "State:Set", fx_set_state, -1}, //120 - { "CutScene", fx_cutscene, -1}, //121 - { "Protection:Spell2", fx_resist_spell, -1}, //ce - { "Protection:Spell3", fx_resist_spell_and_message, -1}, //122 - { "RodOfSmithing", fx_rod_of_smithing, -1}, //123 - { "BeholderDispelMagic", fx_beholder_dispel_magic, -1},//125 - { "HarpyWail", fx_harpy_wail, -1}, //126 - { "JackalWereGaze", fx_jackalwere_gaze, -1}, //127 - { "UseMagicDeviceModifier", fx_use_magic_device_modifier, -1}, //12a +static EffectDesc effectnames[] = { + { "ACVsDamageTypeModifierIWD2", fx_ac_vs_damage_type_modifier_iwd2, 0, -1 }, //0 + { "DamageBonusModifier", fx_damage_bonus_modifier, 0, -1 }, //49 + { "DrawUponHolyMight", fx_draw_upon_holy_might, 0, -1 },//84 (iwd2) + { "RetreatFrom", fx_turn_undead, 0, -1 },//6e + { "IronSkins", fx_ironskins, 0, -1 }, //da (iwd2) + { "Color:FadeRGB", fx_fade_rgb, 0, -1 }, //e8 + { "IWDVisualSpellHit", fx_iwd_visual_spell_hit, 0, -1 }, //e9 + { "ColdDamage", fx_cold_damage, EFFECT_DICED, -1 }, //ea + { "ChillTouch", fx_chill_touch, 0, -1 }, //ec (how) + { "ChillTouchPanic", fx_chill_touch_panic, 0, -1 }, //ec (iwd2) + { "CrushingDamage", fx_crushing_damage, EFFECT_DICED, -1 }, //ed + { "SaveBonus", fx_save_bonus, 0, -1 }, //ee + { "SlowPoison", fx_slow_poison, 0, -1 }, //ef + { "IWDMonsterSummoning", fx_iwd_monster_summoning, EFFECT_NO_ACTOR, -1 }, //f0 + { "VampiricTouch", fx_vampiric_touch, EFFECT_DICED, -1 }, //f1 + { "AnimateDead", fx_animate_dead, 0, -1 }, //f3 + { "Prayer2", fx_prayer, 0, -1 }, //f4 + { "Curse2", fx_curse, 0, -1 }, //f5 + { "SummonMonster2", fx_summon_monster2, EFFECT_NO_ACTOR, -1 }, //f6 + { "BurningBlood", fx_burning_blood, EFFECT_DICED, -1 }, //f7 + { "BurningBlood2", fx_burning_blood2, EFFECT_NO_LEVEL_CHECK, -1 }, //f7 + { "SummonShadowMonster", fx_summon_shadow_monster, EFFECT_NO_ACTOR, -1 }, //f8 + { "Recitation", fx_recitation, 0, -1 }, //f9 + { "RecitationBad", fx_recitation_bad, 0, -1 },//fa + { "LichTouch", fx_lich_touch, EFFECT_NO_LEVEL_CHECK, -1 },//fb + { "BlindingOrb", fx_blinding_orb, 0, -1 }, //fc + { "RemoveEffects", fx_remove_effects, 0, -1 }, //fe + { "SalamanderAura", fx_salamander_aura, 0, -1 }, //ff + { "UmberHulkGaze", fx_umberhulk_gaze, 0, -1 }, //100 + { "ZombieLordAura", fx_zombielord_aura, 0, -1 },//101, duff in iwd2 + { "SummonCreature2", fx_summon_creature2, 0, -1 }, //103 + { "AvatarRemoval", fx_avatar_removal, 0, -1 }, //104 + { "SummonPomab", fx_summon_pomab, 0, -1 }, //106 + { "ControlUndead", fx_control_undead, 0, -1 }, //107 + { "StaticCharge", fx_static_charge, EFFECT_NO_LEVEL_CHECK, -1 }, //108 + { "CloakOfFear", fx_cloak_of_fear, 0, -1 }, //109 how/iwd2 + { "EyeOfTheMind", fx_eye_of_the_mind, 0, -1 }, //10c + { "EyeOfTheSword", fx_eye_of_the_sword, 0, -1 }, //10d + { "EyeOfTheMage", fx_eye_of_the_mage, 0, -1 }, //10e + { "EyeOfVenom", fx_eye_of_venom, 0, -1 }, //10f + { "EyeOfTheSpirit", fx_eye_of_the_spirit, 0, -1 }, //110 + { "EyeOfFortitude", fx_eye_of_fortitude, 0, -1 }, //111 + { "EyeOfStone", fx_eye_of_stone, 0, -1 }, //112 + { "RemoveSevenEyes", fx_remove_seven_eyes, 0, -1 }, //113 + { "RemoveEffect", fx_remove_effect, 0, -1 }, //114 + { "SoulEater", fx_soul_eater, EFFECT_NO_LEVEL_CHECK, -1 }, //115 + { "ShroudOfFlame", fx_shroud_of_flame, 0, -1 },//116 + { "ShroudOfFlame2", fx_shroud_of_flame2, 0, -1 },//116 + { "AnimalRage", fx_animal_rage, 0, -1 }, //117 - berserk? + { "TurnUndead", fx_turn_undead, 0, -1 }, //118 how + { "TurnUndead2", fx_turn_undead2, 0, -1 }, //118 iwd2 + { "VitriolicSphere", fx_vitriolic_sphere, EFFECT_DICED, -1 }, //119 + { "SuppressHP", fx_suppress_hp, 0, -1 }, //11a -- some stat??? + { "FloatText", fx_floattext, 0, -1 }, //11b + { "MaceOfDisruption", fx_mace_of_disruption, 0, -1 }, //11c + { "State:Set", fx_set_state, 0, -1 }, //120 + { "CutScene", fx_cutscene, EFFECT_NO_ACTOR, -1 }, //121 + { "Protection:Spell2", fx_resist_spell, 0, -1 }, //ce + { "Protection:Spell3", fx_resist_spell_and_message, 0, -1 }, //122 + { "RodOfSmithing", fx_rod_of_smithing, 0, -1 }, //123 + { "BeholderDispelMagic", fx_beholder_dispel_magic, 0, -1 },//125 + { "HarpyWail", fx_harpy_wail, 0, -1 }, //126 + { "JackalWereGaze", fx_jackalwere_gaze, 0, -1 }, //127 + { "UseMagicDeviceModifier", fx_use_magic_device_modifier, 0, -1 }, //12a //unhardcoded hacks for IWD - { "AlterAnimation", fx_alter_animation, -1}, //399 + { "AlterAnimation", fx_alter_animation, EFFECT_NO_ACTOR, -1 }, //399 //iwd2 effects - { "Hopelessness", fx_hopelessness, -1}, //400 - { "ProtectionFromEvil", fx_protection_from_evil, -1}, //401 - { "AddEffectsList", fx_add_effects_list, -1}, //402 - { "ArmorOfFaith", fx_armor_of_faith, -1}, //403 - { "Nausea", fx_nausea, -1}, //404 - { "Enfeeblement", fx_enfeeblement, -1}, //405 - { "FireShield", fx_fireshield, -1}, //406 - { "DeathWard", fx_death_ward, -1}, //407 - { "HolyPower", fx_holy_power, -1}, //408 - { "RighteousWrath", fx_righteous_wrath, -1}, //409 - { "SummonAlly", fx_summon_ally, -1}, //410 - { "SummonEnemy", fx_summon_enemy, -1}, //411 - { "Control2", fx_control, -1}, //412 - { "VisualEffectIWD2", fx_visual_effect_iwd2, -1}, //413 - { "ResilientSphere", fx_resilient_sphere, -1}, //414 - { "BarkSkin", fx_barkskin, -1}, //415 - { "BleedingWounds", fx_bleeding_wounds, -1},//416 - { "AreaEffect", fx_area_effect, -1}, //417 - { "FreeAction2", fx_free_action_iwd2, -1}, //418 - { "Unconsciousness", fx_unconsciousness, -1}, //419 - { "EntropyShield", fx_entropy_shield, -1}, //421 - { "StormShell", fx_storm_shell, -1}, //422 - { "ProtectionFromElements", fx_protection_from_elements, -1}, //423 - { "ControlUndead2", fx_control_undead, -1}, //425 - { "Aegis", fx_aegis, -1}, //426 - { "ExecutionerEyes", fx_executioner_eyes, -1}, //427 - { "ProjectileUseEffectList", fx_projectile_use_effect_list, -1}, //430 - { "EnergyDrain", fx_energy_drain, -1}, //431 - { "TortoiseShell", fx_tortoise_shell, -1}, //432 - { "Blink", fx_blink, -1},//433 - { "PersistentUseEffectList", fx_persistent_use_effect_list, -1}, //434 - { "DayBlindness", fx_day_blindness, -1}, //435 - { "DamageReduction", fx_damage_reduction, -1}, //436 - { "Disguise", fx_disguise, -1}, //437 - { "HeroicInspiration", fx_heroic_inspiration, -1},//438 - //{ "PreventAISlowDown", fx_prevent_ai_slowdown, -1}, //439 same as bg2 - { "BarbarianRage", fx_barbarian_rage, -1}, //440 - { "MissileDamageReduction", fx_missile_damage_reduction, -1}, //443 - { "TensersTransformation", fx_tenser_transformation, -1}, //444 - { "SmiteEvil", fx_smite_evil, -1}, //446 - { "Restoration", fx_restoration, -1}, //447 - { "AlicornLance", fx_alicorn_lance, -1}, //448 - { "CallLightning", fx_call_lightning, -1}, //449 - { "GlobeInvulnerability", fx_globe_invulnerability, -1}, //450 - { "LowerResistance", fx_lower_resistance, -1}, //451 - { "Bane", fx_bane, -1}, //452 - { "PowerAttack", fx_power_attack, -1}, //453 - { "Expertise", fx_expertise, -1}, //454 - { "ArterialStrike", fx_arterial_strike, -1}, //455 - { "HamString", fx_hamstring, -1}, //456 - { "RapidShot", fx_rapid_shot, -1}, //457 - { NULL, NULL, 0 }, + { "Hopelessness", fx_hopelessness, 0, -1 }, //400 + { "ProtectionFromEvil", fx_protection_from_evil, 0, -1 }, //401 + { "AddEffectsList", fx_add_effects_list, 0, -1 }, //402 + { "ArmorOfFaith", fx_armor_of_faith, 0, -1 }, //403 + { "Nausea", fx_nausea, 0, -1 }, //404 + { "Enfeeblement", fx_enfeeblement, 0, -1 }, //405 + { "FireShield", fx_fireshield, 0, -1 }, //406 + { "DeathWard", fx_death_ward, 0, -1 }, //407 + { "HolyPower", fx_holy_power, 0, -1 }, //408 + { "RighteousWrath", fx_righteous_wrath, 0, -1 }, //409 + { "SummonAlly", fx_summon_ally, EFFECT_NO_ACTOR, -1 }, //410 + { "SummonEnemy", fx_summon_enemy, EFFECT_NO_ACTOR, -1 }, //411 + { "Control2", fx_control, 0, -1 }, //412 + { "VisualEffectIWD2", fx_visual_effect_iwd2, 0, -1 }, //413 + { "ResilientSphere", fx_resilient_sphere, 0, -1 }, //414 + { "BarkSkin", fx_barkskin, 0, -1 }, //415 + { "BleedingWounds", fx_bleeding_wounds, 0, -1 },//416 + { "AreaEffect", fx_area_effect, EFFECT_NO_ACTOR, -1 }, //417 + { "FreeAction2", fx_free_action_iwd2, 0, -1 }, //418 + { "Unconsciousness", fx_unconsciousness, 0, -1 }, //419 + { "EntropyShield", fx_entropy_shield, 0, -1 }, //421 + { "StormShell", fx_storm_shell, 0, -1 }, //422 + { "ProtectionFromElements", fx_protection_from_elements, 0, -1 }, //423 + { "ControlUndead2", fx_control_undead, 0, -1 }, //425 + { "Aegis", fx_aegis, 0, -1 }, //426 + { "ExecutionerEyes", fx_executioner_eyes, 0, -1 }, //427 + { "ProjectileUseEffectList", fx_projectile_use_effect_list, 0, -1 }, //430 + { "EnergyDrain", fx_energy_drain, 0, -1 }, //431 + { "TortoiseShell", fx_tortoise_shell, 0, -1 }, //432 + { "Blink", fx_blink, 0, -1 },//433 + { "PersistentUseEffectList", fx_persistent_use_effect_list, 0, -1 }, //434 + { "DayBlindness", fx_day_blindness, 0, -1 }, //435 + { "DamageReduction", fx_damage_reduction, 0, -1 }, //436 + { "Disguise", fx_disguise, 0, -1 }, //437 + { "HeroicInspiration", fx_heroic_inspiration, 0, -1 },//438 + //{ "PreventAISlowDown", fx_prevent_ai_slowdown, 0, -1 }, //439 same as bg2 + { "BarbarianRage", fx_barbarian_rage, 0, -1 }, //440 + { "MissileDamageReduction", fx_missile_damage_reduction, 0, -1 }, //443 + { "TensersTransformation", fx_tenser_transformation, 0, -1 }, //444 + { "SmiteEvil", fx_smite_evil, 0, -1 }, //446 + { "Restoration", fx_restoration, 0, -1 }, //447 + { "AlicornLance", fx_alicorn_lance, 0, -1 }, //448 + { "CallLightning", fx_call_lightning, 0, -1 }, //449 + { "GlobeInvulnerability", fx_globe_invulnerability, 0, -1 }, //450 + { "LowerResistance", fx_lower_resistance, 0, -1 }, //451 + { "Bane", fx_bane, 0, -1 }, //452 + { "PowerAttack", fx_power_attack, 0, -1 }, //453 + { "Expertise", fx_expertise, 0, -1 }, //454 + { "ArterialStrike", fx_arterial_strike, 0, -1 }, //455 + { "HamString", fx_hamstring, 0, -1 }, //456 + { "RapidShot", fx_rapid_shot, 0, -1 }, //457 + { NULL, NULL, 0, 0 }, }; struct IWDIDSEntry { @@ -368,7 +368,7 @@ static void Cleanup() void RegisterIWDOpcodes() { - core->RegisterOpcodes( sizeof( effectnames ) / sizeof( EffectRef ) - 1, effectnames ); + core->RegisterOpcodes( sizeof( effectnames ) / sizeof( EffectDesc ) - 1, effectnames ); enhanced_effects=!!core->HasFeature(GF_ENHANCED_EFFECTS); //create enemy trigger object for enemy in line of sight check if (!Enemy) { @@ -505,7 +505,7 @@ static int check_iwd_targeting(Scriptable* Owner, Actor* target, ieDword value, //iwd got a hardcoded 'fireshield' system //this effect applies damage on ALL nearby actors, except the center -static EffectRef fx_damage_opcode_ref={"Damage",NULL,-1}; +static EffectRef fx_damage_opcode_ref = { "Damage", -1 }; static void ApplyDamageNearby(Scriptable* Owner, Actor* target, Effect *fx, ieDword damagetype) { @@ -700,7 +700,7 @@ int fx_iwd_visual_spell_hit (Scriptable* Owner, Actor* target, Effect* fx) } Point pos(fx->PosX,fx->PosY); Projectile *pro = core->GetProjectileServer()->GetProjectileByIndex(0x1001+fx->Parameter2); - pro->SetCaster(Owner->GetGlobalID()); + pro->SetCaster(fx->CasterID, fx->CasterLevel); if (target) { //i believe the spell hit projectiles don't follow anyone map->AddProjectile( pro, pos, target->GetGlobalID(), true); @@ -779,8 +779,8 @@ int fx_save_bonus (Scriptable* /*Owner*/, Actor* target, Effect* fx) //0xef SlowPoison //gemrb extension: can slow bleeding wounds (like bandage) -static EffectRef fx_poison_ref={"Poison",NULL,-1}; -static EffectRef fx_wound_ref={"BleedingWounds",NULL,-1}; +static EffectRef fx_poison_ref = { "Poison", -1 }; +static EffectRef fx_wound_ref = { "BleedingWounds", -1 }; int fx_slow_poison (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -829,13 +829,6 @@ 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 (!target) { - return FX_NOT_APPLIED; - } - - if (!target->GetCurrentArea()) { - return FX_APPLIED; - } //check the summoning limit? ieResRef monster; @@ -967,14 +960,6 @@ 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 ); - //check the summoning limit? - if (!target) { - return FX_NOT_APPLIED; - } - - if (!target->GetCurrentArea()) { - return FX_APPLIED; - } ieResRef monster; ieResRef hit; @@ -1055,14 +1040,6 @@ 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 ); - //check the summoning limit? - if (!target) { - return FX_NOT_APPLIED; - } - - if (!target->GetCurrentArea()) { - return FX_APPLIED; - } ieResRef monster; ieResRef hit; @@ -1125,7 +1102,7 @@ int fx_recitation_bad (Scriptable* /*Owner*/, Actor* target, Effect* fx) } //0xfb LichTouch (how) //0xfb State:Hold4 (iwd2) -static EffectRef fx_hold_creature_ref={"State:Hold",NULL,-1}; +static EffectRef fx_hold_creature_ref = { "State:Hold", -1 }; int fx_lich_touch (Scriptable* Owner, Actor* target, Effect* fx) { @@ -1146,7 +1123,7 @@ int fx_lich_touch (Scriptable* Owner, Actor* target, Effect* fx) } //0xfc BlindingOrb (how) -static EffectRef fx_state_blind_ref={"State:Blind",NULL,-1}; +static EffectRef fx_state_blind_ref = { "State:Blind", -1 }; int fx_blinding_orb (Scriptable* Owner, Actor* target, Effect* fx) { @@ -1223,8 +1200,8 @@ int fx_salamander_aura (Scriptable* Owner, Actor* target, Effect* fx) //0x100 UmberHulkGaze (causes confusion) //it is a specially hacked effect to ignore certain races //from the confusion effect -static EffectRef fx_confusion_ref={"State:Confused",NULL,-1}; -static EffectRef fx_immunity_resource_ref={"Protection:Spell",NULL,-1}; +static EffectRef fx_confusion_ref = { "State:Confused", -1 }; +static EffectRef fx_immunity_resource_ref = { "Protection:Spell", -1 }; int fx_umberhulk_gaze (Scriptable* Owner, Actor* target, Effect* fx) { @@ -1284,7 +1261,7 @@ int fx_umberhulk_gaze (Scriptable* Owner, Actor* target, Effect* fx) } //0x101 ZombieLordAura (causes Panic) unused in all games -static EffectRef fx_fear_ref={"State:Panic",NULL,-1}; +static EffectRef fx_fear_ref = { "State:Panic", -1 }; int fx_zombielord_aura (Scriptable* Owner, Actor* target, Effect* fx) { @@ -1506,7 +1483,7 @@ int fx_static_charge(Scriptable* Owner, Actor* target, Effect* fx) //0x109 CloakOfFear (HoW/IWD2) //if the resource is not specified, it will work like in HoW -static EffectRef fx_umberhulk_gaze_ref={"UmberHulkGaze",NULL,-1}; +static EffectRef fx_umberhulk_gaze_ref = { "UmberHulkGaze", -1 }; int fx_cloak_of_fear(Scriptable* Owner, Actor* target, Effect* fx) { @@ -1533,7 +1510,7 @@ int fx_cloak_of_fear(Scriptable* Owner, Actor* target, Effect* fx) } //how style (probably better would be to provide effcof.spl) - Effect *newfx = EffectQueue::CreateEffect(fx_umberhulk_gaze_ref, 0, + Effect *newfx = EffectQueue::CreateEffect(fx_umberhulk_gaze_ref, 0, 8, FX_DURATION_INSTANT_PERMANENT); newfx->Power = fx->Power; @@ -1675,9 +1652,9 @@ int fx_remove_effect (Scriptable* /*Owner*/, Actor* target, Effect* fx) return FX_NOT_APPLIED; } -static EffectRef fx_str_ref={"StrengthModifier",NULL,-1}; -static EffectRef fx_con_ref={"ConstitutionModifier",NULL,-1}; -static EffectRef fx_dex_ref={"DexterityModifier",NULL,-1}; +static EffectRef fx_str_ref = { "StrengthModifier", -1 }; +static EffectRef fx_con_ref = { "ConstitutionModifier", -1 }; +static EffectRef fx_dex_ref = { "DexterityModifier", -1 }; //0x115 SoulEater int fx_soul_eater (Scriptable* Owner, Actor* target, Effect* fx) @@ -1987,8 +1964,8 @@ int fx_floattext (Scriptable* /*Owner*/, Actor* target, Effect* fx) //0x11c MaceOfDisruption //death with chance based on race and level -static EffectRef fx_death_ref={"Death",NULL,-1}; -static EffectRef fx_iwd_visual_spell_hit_ref={"IWDVisualSpellHit",NULL,-1}; +static EffectRef fx_death_ref = { "Death", -1 }; +static EffectRef fx_iwd_visual_spell_hit_ref = { "IWDVisualSpellHit", -1 }; int fx_mace_of_disruption (Scriptable* Owner, Actor* target, Effect* fx) { @@ -2092,7 +2069,7 @@ int fx_resist_spell (Scriptable* Owner, Actor* target, Effect *fx) return FX_ABORT; } -static EffectRef fx_resist_spell_ref={"Protection:Spell2",NULL,-1}; +static EffectRef fx_resist_spell_ref = { "Protection:Spell2", -1 }; //0x122 Protection:Spell3 ??? IWD ids targeting // this is a variant of resist spell, used in iwd2 @@ -2298,7 +2275,7 @@ int fx_alter_animation (Scriptable* Owner, Actor* /*target*/, Effect* fx) if (!strnicmp (an->Name, fx->Resource, 8) ) { //play spell hit animation Projectile *pro=core->GetProjectileServer()->GetProjectileByIndex(fx->Parameter2); - pro->SetCaster(Owner->GetGlobalID()); + pro->SetCaster(fx->CasterID, fx->CasterLevel); map->AddProjectile(pro, an->Pos, an->Pos); //alter animation, we need only this for the original, but in the //spirit of unhardcoding, i provided the standard modifier codeset @@ -2397,7 +2374,7 @@ static int fx_armor_of_faith (Scriptable* /*Owner*/, Actor* target, Effect* fx) } //404 Nausea -static EffectRef fx_unconscious_state_ref={"State:Helpless",NULL,-1}; +static EffectRef fx_unconscious_state_ref = { "State:Helpless", -1 }; int fx_nausea (Scriptable* Owner, Actor* target, Effect* fx) { @@ -2493,13 +2470,6 @@ int fx_righteous_wrath (Scriptable* /*Owner*/, Actor* target, Effect* fx) //410 SummonAllyIWD2 int fx_summon_ally (Scriptable* Owner, Actor* target, Effect* fx) { - if (!target) { - return FX_NOT_APPLIED; - } - - if (!target->GetCurrentArea()) { - return FX_APPLIED; - } Point p(fx->PosX, fx->PosY); Effect *newfx = EffectQueue::CreateUnsummonEffect(fx); core->SummonCreature(fx->Resource, fx->Resource2, Owner, target, p, EAM_ALLY, 0, newfx); @@ -2510,13 +2480,6 @@ int fx_summon_ally (Scriptable* Owner, Actor* target, Effect* fx) //411 SummonEnemyIWD2 int fx_summon_enemy (Scriptable* Owner, Actor* target, Effect* fx) { - if (!target) { - return FX_NOT_APPLIED; - } - - if (!target->GetCurrentArea()) { - return FX_APPLIED; - } Point p(fx->PosX, fx->PosY); Effect *newfx = EffectQueue::CreateUnsummonEffect(fx); core->SummonCreature(fx->Resource, fx->Resource2, Owner, target, p, EAM_ENEMY, 0, newfx); @@ -2526,7 +2489,7 @@ int fx_summon_enemy (Scriptable* Owner, Actor* target, Effect* fx) //412 Control2 -static EffectRef fx_protection_from_evil_ref={"ProtectionFromEvil",NULL,-1}; +static EffectRef fx_protection_from_evil_ref = { "ProtectionFromEvil", -1 }; int fx_control (Scriptable* Owner, Actor* target, Effect* fx) { @@ -2676,13 +2639,35 @@ seconds: int fx_area_effect (Scriptable* Owner, Actor* target, Effect* fx) { - if (0) printf( "fx_area_effect (%2d) Type: %d\n", fx->Opcode, fx->Parameter2); + if (0) printf( "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) - if (STATE_GET(STATE_DEAD) ) { - return FX_NOT_APPLIED; + Game *game = core->GetGame(); + Map *map = NULL; + + if (target) { + if (STATE_GET(STATE_DEAD) ) { + return FX_NOT_APPLIED; + } + map = target->GetCurrentArea(); + } else { + map = game->GetCurrentArea(); } + if (fx->FirstApply) { + if (!fx->Parameter3) { + fx->Parameter3=AI_UPDATE_TIME; + } else { + fx->Parameter3*=AI_UPDATE_TIME; + } + fx->Parameter4 = 0; + } + + if (fx->Parameter4>=game->GameTime) { + return FX_APPLIED; + } + + fx->Parameter4 = game->GameTime+fx->Parameter3; Point pos(fx->PosX, fx->PosY); Spell *spell = gamedata->GetSpell(fx->Resource); @@ -2690,10 +2675,10 @@ int fx_area_effect (Scriptable* Owner, Actor* target, Effect* fx) return FX_NOT_APPLIED; } - EffectQueue *fxqueue = spell->GetEffectBlock(Owner, pos, 0); + EffectQueue *fxqueue = spell->GetEffectBlock(Owner, pos, 0, fx->CasterLevel); fxqueue->SetOwner(Owner); //bit 2 original target is excluded or not excluded - fxqueue->AffectAllInRange(target->GetCurrentArea(), pos, 0, 0,fx->Parameter1, fx->Parameter2&AE_TARGETEXCL?target:NULL); + fxqueue->AffectAllInRange(map, pos, 0, 0,fx->Parameter1, fx->Parameter2&AE_TARGETEXCL?target:NULL); delete fxqueue; //bit 1 repeat or only once @@ -2896,9 +2881,9 @@ int fx_projectile_use_effect_list (Scriptable* Owner, Actor* target, Effect* fx) if (pro) { Point p(fx->PosX, fx->PosY); - pro->SetEffects(spl->GetEffectBlock(Owner, p, 0, fx->Parameter2)); + pro->SetEffects(spl->GetEffectBlock(Owner, p, 0, fx->CasterLevel, fx->Parameter2)); Point origin(fx->PosX, fx->PosY); - pro->SetCaster(Owner->GetGlobalID()); + pro->SetCaster(fx->CasterID, fx->CasterLevel); if (target) { map->AddProjectile( pro, origin, target->GetGlobalID(), false); } else { @@ -3006,7 +2991,7 @@ int fx_day_blindness (Scriptable* Owner, Actor* target, Effect* fx) else if (check_iwd_targeting(Owner, target, 0, 84)) penalty = 2; //duergar else penalty = 0; - STAT_ADD(IE_SAVEFORTITUDE, penalty); + STAT_ADD(IE_SAVEFORTITUDE, penalty); STAT_ADD(IE_SAVEREFLEX, penalty); STAT_ADD(IE_SAVEWILL, penalty); //for compatibility reasons @@ -3021,7 +3006,7 @@ int fx_day_blindness (Scriptable* Owner, Actor* target, Effect* fx) int fx_damage_reduction (Scriptable* /*Owner*/, Actor* target, Effect* fx) { if (0) printf( "fx_damage_reduction (%2d) Amount: %d\n", fx->Opcode, fx->Parameter2); - STAT_SET(IE_RESISTSLASHING, fx->Parameter2*5); + STAT_SET(IE_RESISTSLASHING, fx->Parameter2*5); STAT_SET(IE_RESISTCRUSHING, fx->Parameter2*5); STAT_SET(IE_RESISTPIERCING, fx->Parameter2*5); return FX_APPLIED; @@ -3110,10 +3095,10 @@ int fx_smite_evil (Scriptable* /*Owner*/, Actor* target, Effect* fx) //447 Restoration -static EffectRef fx_disease_ref={"Disease",NULL,-1}; -static EffectRef fx_int_ref={"IntelligenceModifier",NULL,-1}; -static EffectRef fx_wis_ref={"WisdomModifier",NULL,-1}; -static EffectRef fx_cha_ref={"CharismaModifier",NULL,-1}; +static EffectRef fx_disease_ref = { "Disease", -1 }; +static EffectRef fx_int_ref = { "IntelligenceModifier", -1 }; +static EffectRef fx_wis_ref = { "WisdomModifier", -1 }; +static EffectRef fx_cha_ref = { "CharismaModifier", -1 }; int fx_restoration (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -3278,7 +3263,7 @@ int fx_lower_resistance (Scriptable* /*Owner*/, Actor* target, Effect* fx) } //452 Bane -static EffectRef fx_bless_ref={"Bless",NULL,-1}; +static EffectRef fx_bless_ref = { "Bless", -1 }; int fx_bane (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -3298,7 +3283,7 @@ int fx_bane (Scriptable* /*Owner*/, Actor* target, Effect* fx) } //453 PowerAttack -static EffectRef fx_expertise_ref={"Expertise",NULL,-1}; +static EffectRef fx_expertise_ref = { "Expertise", -1 }; int fx_power_attack (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -3325,7 +3310,7 @@ int fx_power_attack (Scriptable* /*Owner*/, Actor* target, Effect* fx) } //454 Expertise -static EffectRef fx_powerattack_ref={"PowerAttack",NULL,-1}; +static EffectRef fx_powerattack_ref = { "PowerAttack", -1 }; int fx_expertise (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -3354,7 +3339,7 @@ int fx_expertise (Scriptable* /*Owner*/, Actor* target, Effect* fx) } //455 ArterialStrike -static EffectRef fx_hamstring_ref={"HamString",NULL,-1}; +static EffectRef fx_hamstring_ref = { "HamString", -1 }; int fx_arterial_strike (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -3372,7 +3357,7 @@ int fx_arterial_strike (Scriptable* /*Owner*/, Actor* target, Effect* fx) } //456 HamString -static EffectRef fx_arterialstrike_ref={"ArterialStrike",NULL,-1}; +static EffectRef fx_arterialstrike_ref = { "ArterialStrike", -1 }; int fx_hamstring (Scriptable* /*Owner*/, Actor* target, Effect* fx) { diff --git a/project/jni/application/gemrb/gemrb/plugins/KEYImporter/KEYImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/KEYImporter/KEYImporter.cpp index ea8afb2b2..a444a492f 100644 --- a/project/jni/application/gemrb/gemrb/plugins/KEYImporter/KEYImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/KEYImporter/KEYImporter.cpp @@ -30,10 +30,12 @@ KEYImporter::KEYImporter(void) { + description = NULL; } KEYImporter::~KEYImporter(void) { + free(description); for (unsigned int i = 0; i < biffiles.size(); i++) { free( biffiles[i].name ); } @@ -123,7 +125,8 @@ static void FindBIF(BIFEntry *entry) bool KEYImporter::Open(const char *resfile, const char *desc) { - description = desc; + free(description); + description = strdup(desc); if (!core->IsAvailable( IE_BIF_CLASS_ID )) { printf( "[ERROR]\nAn Archive Plug-in is not Available\n" ); return false; diff --git a/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/MVEPlayer.cpp b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/MVEPlayer.cpp index b19cebb6a..6ff83ca0f 100644 --- a/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/MVEPlayer.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/MVEPlayer.cpp @@ -172,8 +172,8 @@ void MVEPlay::freeAudioStream(int stream) } void MVEPlay::queueBuffer(int stream, unsigned short bits, - int channels, short* memory, - int size, int samplerate) + int channels, short* memory, + int size, int samplerate) { if (stream > -1) core->GetAudioDrv()->QueueBuffer(stream, bits, channels, memory, size, samplerate) ; diff --git a/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/MVEPlayer.h b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/MVEPlayer.h index 86466f4cb..1a564386d 100644 --- a/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/MVEPlayer.h +++ b/project/jni/application/gemrb/gemrb/plugins/MVEPlayer/MVEPlayer.h @@ -44,8 +44,8 @@ private: int setAudioStream(); void freeAudioStream(int stream); void queueBuffer(int stream, unsigned short bits, - int channels, short* memory, - int size, int samplerate); + int channels, short* memory, + int size, int samplerate); public: MVEPlay(void); ~MVEPlay(void); diff --git a/project/jni/application/gemrb/gemrb/plugins/NullSound/NullSound.h b/project/jni/application/gemrb/gemrb/plugins/NullSound/NullSound.h index 9153306de..2261c5693 100644 --- a/project/jni/application/gemrb/gemrb/plugins/NullSound/NullSound.h +++ b/project/jni/application/gemrb/gemrb/plugins/NullSound/NullSound.h @@ -46,7 +46,7 @@ public: bool ReleaseStream(int stream, bool hardstop); void SetAmbientStreamVolume(int stream, int gain); void QueueBuffer(int stream, unsigned short bits, int channels, - short* memory, int size, int samplerate); + short* memory, int size, int samplerate); private: int XPos, YPos; diff --git a/project/jni/application/gemrb/gemrb/plugins/OGGReader/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/OGGReader/CMakeLists.txt index fff2bfbca..244603a53 100644 --- a/project/jni/application/gemrb/gemrb/plugins/OGGReader/CMakeLists.txt +++ b/project/jni/application/gemrb/gemrb/plugins/OGGReader/CMakeLists.txt @@ -1,11 +1,11 @@ IF (VORBIS_LIBRARY) - FILE( GLOB OGGReader_files *.cpp ) + FILE( GLOB OGGReader_files *.cpp ) - # include the second parent of vorbisfile.h - get_filename_component(OGG_INCLUDE ${VORBIS_FILE} PATH) - include_directories(${OGG_INCLUDE}) + # include the second parent of vorbisfile.h + get_filename_component(OGG_INCLUDE ${VORBIS_FILE} PATH) + include_directories(${OGG_INCLUDE}) - ADD_GEMRB_PLUGIN (OGGReader ${OGGReader_files}) + ADD_GEMRB_PLUGIN (OGGReader ${OGGReader_files}) - TARGET_LINK_LIBRARIES(OGGReader ${VORBIS_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) + TARGET_LINK_LIBRARIES(OGGReader ${VORBIS_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) ENDIF (VORBIS_LIBRARY) diff --git a/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/OpenALAudio.cpp b/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/OpenALAudio.cpp index 9a4440ebb..4634342e9 100644 --- a/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/OpenALAudio.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/OpenALAudio.cpp @@ -29,7 +29,7 @@ bool checkALError(const char* msg, const char* status) { int error = alGetError(); if (error != AL_NO_ERROR) { printMessage("OpenAL", msg, WHITE ); - printf (": %d ", error); + printf (": 0x%x ", error); printStatus(status, YELLOW); return true; } @@ -40,7 +40,7 @@ void showALCError(const char* msg, const char* status, ALCdevice *device) { int error = alcGetError(device); printMessage("OpenAL", msg, WHITE ); if (error != AL_NO_ERROR) { - printf (": %d ", error); + printf (": 0x%x ", error); } printStatus(status, YELLOW); } @@ -134,7 +134,7 @@ OpenALAudioDriver::OpenALAudioDriver(void) { alutContext = NULL; MusicPlaying = false; - music_memory = (unsigned char*) malloc(ACM_BUFFERSIZE); + music_memory = (short*) malloc(ACM_BUFFERSIZE); MusicSource = 0; memset(MusicBuffer, 0, MUSICBUFFERS*sizeof(ALuint)); musicMutex = SDL_CreateMutex(); @@ -278,9 +278,9 @@ ALuint OpenALAudioDriver::loadSound(const char *ResRef, unsigned int &time_lengt int samplerate = acm->get_samplerate(); //multiply always by 2 because it is in 16 bits int rawsize = cnt * 2; - unsigned char * memory = (unsigned char*) malloc(rawsize); + short* memory = (short*) malloc(rawsize); //multiply always with 2 because it is in 16 bits - int cnt1 = acm->read_samples( ( short* ) memory, cnt ) * 2; + 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 @@ -508,6 +508,7 @@ bool OpenALAudioDriver::Stop() bool OpenALAudioDriver::Pause() { + ambim->deactivate(); SDL_mutexP( musicMutex ); if (!alIsSource( MusicSource )) { SDL_mutexV( musicMutex ); @@ -517,7 +518,6 @@ 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,6 +529,7 @@ 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 ); @@ -538,7 +539,6 @@ bool OpenALAudioDriver::Resume() checkALError("Unable to resume music source", "WARNING"); MusicPlaying = true; SDL_mutexV( musicMutex ); - ((AmbientMgrAL*) ambim)->activate(); return true; } @@ -801,7 +801,7 @@ int OpenALAudioDriver::MusicManager(void* arg) { printMessage("OPENAL", "Music in INITIAL State. AutoStarting\n", WHITE ); for (int i = 0; i < MUSICBUFFERS; i++) { - driver->MusicReader->read_samples( ( short* ) driver->music_memory, ACM_BUFFERSIZE >> 1 ); + 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() ); @@ -841,7 +841,7 @@ int OpenALAudioDriver::MusicManager(void* arg) } if (bFinished == AL_FALSE) { int size = ACM_BUFFERSIZE; - int cnt = driver->MusicReader->read_samples( ( short* ) driver->music_memory, ACM_BUFFERSIZE >> 1 ); + int cnt = driver->MusicReader->read_samples( driver->music_memory, ACM_BUFFERSIZE >> 1 ); size -= ( cnt * 2 ); if (size != 0) bFinished = AL_TRUE; @@ -850,11 +850,11 @@ int OpenALAudioDriver::MusicManager(void* arg) core->GetMusicMgr()->PlayNext(); if (driver->MusicPlaying) { printMessage( "OpenAL", "Queuing New Music\n", WHITE ); - driver->MusicReader->read_samples( ( short* ) ( driver->music_memory + ( cnt*2 ) ), size >> 1 ); + 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 * 2 ), 0, size ); + memset( driver->music_memory + cnt, 0, size ); driver->MusicPlaying = false; break; } diff --git a/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/OpenALAudio.h b/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/OpenALAudio.h index a94221698..085bd0de2 100644 --- a/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/OpenALAudio.h +++ b/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/OpenALAudio.h @@ -75,74 +75,74 @@ public: }; struct AudioStream { - AudioStream() : Buffer(0), Source(0), Duration(0), free(true), ambient(false), locked(false), delete_buffers(false) { } + AudioStream() : Buffer(0), Source(0), Duration(0), free(true), ambient(false), locked(false), delete_buffers(false) { } - ALuint Buffer; - ALuint Source; - int Duration; - bool free; - bool ambient; - bool locked; - bool delete_buffers; + ALuint Buffer; + ALuint Source; + int Duration; + bool free; + bool ambient; + bool locked; + bool delete_buffers; - void ClearIfStopped(); - void ClearProcessedBuffers(); - void ForceClear(); + void ClearIfStopped(); + void ClearProcessedBuffers(); + void ForceClear(); - Holder handle; + Holder handle; }; struct CacheEntry { - ALuint Buffer; - unsigned int Length; + ALuint Buffer; + unsigned int Length; }; class OpenALAudioDriver : public Audio { public: - OpenALAudioDriver(void); - ~OpenALAudioDriver(void); - bool Init(void); - Holder Play(const char* ResRef, int XPos, int YPos, - unsigned int flags = 0, unsigned int *length = 0); - bool IsSpeaking(); - void UpdateVolume(unsigned int flags); - bool CanPlay(); - void ResetMusics(); - bool Play(); - bool Stop(); + OpenALAudioDriver(void); + ~OpenALAudioDriver(void); + bool Init(void); + Holder Play(const char* ResRef, int XPos, int YPos, + unsigned int flags = 0, unsigned int *length = 0); + bool IsSpeaking(); + void UpdateVolume(unsigned int flags); + bool CanPlay(); + void ResetMusics(); + bool Play(); + bool Stop(); bool Pause(); bool Resume(); - int CreateStream(Holder); - void UpdateListenerPos(int XPos, int YPos ); - void GetListenerPos( int &XPos, int &YPos ); - bool ReleaseStream(int stream, bool HardStop); - int SetupNewStream( ieWord x, ieWord y, ieWord z, - ieWord gain, bool point, bool Ambient ); - int QueueAmbient(int stream, const char* sound); - void SetAmbientStreamVolume(int stream, int volume); - void QueueBuffer(int stream, unsigned short bits, - int channels, short* memory, - int size, int samplerate) ; + int CreateStream(Holder); + void UpdateListenerPos(int XPos, int YPos ); + void GetListenerPos( int &XPos, int &YPos ); + bool ReleaseStream(int stream, bool HardStop); + int SetupNewStream( ieWord x, ieWord y, ieWord z, + ieWord gain, bool point, bool Ambient ); + int QueueAmbient(int stream, const char* sound); + void SetAmbientStreamVolume(int stream, int volume); + void QueueBuffer(int stream, unsigned short bits, + int channels, short* memory, + int size, int samplerate) ; private: - ALCcontext *alutContext; - ALuint MusicSource; - bool MusicPlaying; - SDL_mutex* musicMutex; - ALuint MusicBuffer[MUSICBUFFERS]; - Holder MusicReader; - LRUCache buffercache; - AudioStream speech; - AudioStream streams[MAX_STREAMS]; - ALuint loadSound(const char* ResRef, unsigned int &time_length); - int num_streams; - int CountAvailableSources(int limit); - bool evictBuffer(); - void clearBufferCache(bool force); - ALenum GetFormatEnum(int channels, int bits); - static int MusicManager(void* args); - bool stayAlive; - unsigned char* music_memory; - SDL_Thread* musicThread; + ALCcontext *alutContext; + ALuint MusicSource; + bool MusicPlaying; + SDL_mutex* musicMutex; + ALuint MusicBuffer[MUSICBUFFERS]; + Holder MusicReader; + LRUCache buffercache; + AudioStream speech; + AudioStream streams[MAX_STREAMS]; + ALuint loadSound(const char* ResRef, unsigned int &time_length); + int num_streams; + int CountAvailableSources(int limit); + bool evictBuffer(); + void clearBufferCache(bool force); + ALenum GetFormatEnum(int channels, int bits); + static int MusicManager(void* args); + bool stayAlive; + short* music_memory; + SDL_Thread* musicThread; }; #endif // OPENALAUDIO_H_INCLUDED diff --git a/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/StackLock.cpp b/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/StackLock.cpp index 804e4769f..b1db38f1b 100644 --- a/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/StackLock.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/OpenALAudio/StackLock.cpp @@ -25,31 +25,31 @@ // adapted from ScummVM's mutex.cpp StackLock::StackLock(SDL_mutex* mutex, const char *mutexName) - : _mutex(mutex), _mutexName(mutexName) { - lock(); + : _mutex(mutex), _mutexName(mutexName) { + lock(); } StackLock::~StackLock() { - unlock(); + unlock(); } void StackLock::lock() { #if 0 - if (_mutexName != NULL) { - fprintf(stderr, "Locking mutex %s\n", _mutexName); + if (_mutexName != NULL) { + fprintf(stderr, "Locking mutex %s\n", _mutexName); } #endif - SDL_mutexP(_mutex); + SDL_mutexP(_mutex); } void StackLock::unlock() { #if 0 - if (_mutexName != NULL) { - fprintf(stderr, "Unlocking mutex %s\n", _mutexName); + if (_mutexName != NULL) { + fprintf(stderr, "Unlocking mutex %s\n", _mutexName); } #endif - SDL_mutexV(_mutex); + SDL_mutexV(_mutex); } diff --git a/project/jni/application/gemrb/gemrb/plugins/PROImporter/PROImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/PROImporter/PROImporter.cpp index 40ccbc017..013cc75e0 100644 --- a/project/jni/application/gemrb/gemrb/plugins/PROImporter/PROImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/PROImporter/PROImporter.cpp @@ -73,14 +73,20 @@ Projectile* PROImporter::GetProjectile(Projectile *s) str->ReadDword( &s->SFlags ); //spark, ignore center, looping sound etc str->ReadResRef( s->SoundRes1 ); str->ReadResRef( s->SoundRes2 ); - str->ReadResRef( s->SoundRes3 ); + str->ReadResRef( s->TravelVVC ); //no original game data uses this feature str->ReadDword( &s->SparkColor );//enabled by PSF_SPARK str->ReadDword( &s->ExtFlags ) ; //gemrb extension flags str->ReadDword( &s->StrRef ); //gemrb extension strref str->ReadDword( &s->RGB ); //gemrb extension rgb pulse str->ReadWord( &s->ColorSpeed ); //gemrb extension rgb speed str->ReadWord( &s->Shake ); //gemrb extension screen shake - str->Seek(196, GEM_CURRENT_POS); //skipping unused (unknown) bytes + str->ReadWord( &s->IDSValue); //gemrb extension IDS targeting + str->ReadWord( &s->IDSType); //gemrb extension IDS targeting + str->ReadWord( &s->IDSValue2); //gemrb extension IDS targeting + str->ReadWord( &s->IDSType2); //gemrb extension IDS targeting + str->ReadResRef( s->FailSpell); //gemrb extension fail effect + str->ReadResRef( s->SuccSpell); //gemrb extension implicit effect + str->Seek(172, GEM_CURRENT_POS); //skipping unused (unknown) bytes //we should stand at offset 0x100 now str->ReadDword( &s->TFlags ); //other projectile flags str->ReadResRef( s->BAMRes1 ); @@ -150,8 +156,20 @@ void PROImporter::GetAreaExtension(ProjectileExtension *e) str->ReadResRef( e->Secondary ); str->ReadResRef( e->AreaSound ); str->ReadDword( &e->APFlags ); + str->ReadWord( &e->DiceCount ); + str->ReadWord( &e->DiceSize ); + str->ReadWord( &e->TileX ); + str->ReadWord( &e->TileY ); + + if (!e->TileX) { + e->TileX=64; + } + if (!e->TileY) { + e->TileY=64; + } + //we skip the rest - str->Seek(188, GEM_CURRENT_POS); + str->Seek(180, GEM_CURRENT_POS); } #include "plugindef.h" diff --git a/project/jni/application/gemrb/gemrb/plugins/PSTOpcodes/PSTOpcodes.cpp b/project/jni/application/gemrb/gemrb/plugins/PSTOpcodes/PSTOpcodes.cpp index b828a7184..477894e55 100644 --- a/project/jni/application/gemrb/gemrb/plugins/PSTOpcodes/PSTOpcodes.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/PSTOpcodes/PSTOpcodes.cpp @@ -34,11 +34,14 @@ int fx_set_status (Scriptable* Owner, Actor* target, Effect* fx);//ba int fx_play_bam_blended (Scriptable* Owner, Actor* target, Effect* fx);//bb int fx_play_bam_not_blended (Scriptable* Owner, Actor* target, Effect* fx);//bc int fx_transfer_hp (Scriptable* Owner, Actor* target, Effect* fx);//c0 -//int fx_shake_screen (Scriptable* Owner, Actor* target, Effect* fx);//c1 already implemented +//int fx_shake_screen (Scriptable* Owner, Actor* target, Effect* fx);//c1 already implemented in fxopcodes int fx_flash_screen (Scriptable* Owner, Actor* target, Effect* fx);//c2 int fx_tint_screen (Scriptable* Owner, Actor* target, Effect* fx);//c3 int fx_special_effect (Scriptable* Owner, Actor* target, Effect* fx);//c4 -//unknown 0xc5-c8 +int fx_multiple_vvc (Scriptable* Owner, Actor* target, Effect* fx);//c5 //gemrb specific +//int fx_modify_global ((Scriptable* Owner, Actor* target, Effect* fx);//c6 already implemented in fxopcodes +int fx_change_background (Scriptable* Owner, Actor* target, Effect* fx);//c7 //gemrb specific +//unknown 0xc7-c8 int fx_overlay (Scriptable* Owner, Actor* target, Effect* fx);//c9 //unknown 0xca int fx_bless (Scriptable* Owner, Actor* target, Effect* fx);//82 (this is a modified effect) @@ -51,38 +54,41 @@ int fx_iron_fist (Scriptable* Owner, Actor* target, Effect* fx);//d0 int fx_hostile_image(Scriptable* Owner, Actor* target, Effect* fx);//d1 int fx_detect_evil (Scriptable* Owner, Actor* target, Effect* fx);//d2 int fx_jumble_curse (Scriptable* Owner, Actor* target, Effect* fx);//d3 -//int fx_unknown (Scriptable* Owner, Actor* target, Effect* fx);//d4 +int fx_speak_with_dead (Scriptable* Owner, Actor* target, Effect* fx);//d4 -// FIXME: Make this an ordered list, so we could use bsearch! -static EffectRef effectnames[] = { - { "RetreatFrom", fx_retreat_from, -1 },//6e - { "Bless", fx_bless, -1},//82 - { "Curse", fx_curse, -1},//cb - { "DetectEvil", fx_detect_evil, -1}, //d2 - { "Embalm", fx_embalm, -1}, //0xce - { "FlashScreen", fx_flash_screen, -1}, //c2 - { "HostileImage", fx_hostile_image, -1},//d1 - { "IronFist", fx_iron_fist, -1}, //d0 - { "JumbleCurse", fx_jumble_curse, -1}, //d3 - { "MoveView", fx_move_view, -1},//cd - { "Overlay", fx_overlay, -1}, //c9 - { "PlayBAM1", fx_play_bam_blended, -1}, //bb - { "PlayBAM2", fx_play_bam_not_blended, -1},//bc - { "PlayBAM3", fx_play_bam_not_blended, -1}, //bd - { "PlayBAM4", fx_play_bam_not_blended, -1}, //be - { "PlayBAM5", fx_play_bam_not_blended, -1}, //bf - { "Prayer", fx_prayer, -1},//cc - { "SetStatus", fx_set_status, -1}, //ba - { "SpecialEffect", fx_special_effect, -1},//c4 - { "StopAllAction", fx_stop_all_action, -1}, //cf - { "TintScreen", fx_tint_screen, -1}, //c3 - { "TransferHP", fx_transfer_hp, -1}, //c0 - { NULL, NULL, 0 }, +//the engine sorts these, feel free to use any order +static EffectDesc effectnames[] = { + { "Bless", fx_bless, 0, -1 },//82 + { "ChangeBackground", fx_change_background, EFFECT_NO_ACTOR, -1 }, //c6 + { "Curse", fx_curse, 0, -1 },//cb + { "DetectEvil", fx_detect_evil, 0, -1 }, //d2 + { "Embalm", fx_embalm, 0, -1 }, //0xce + { "FlashScreen", fx_flash_screen, EFFECT_NO_ACTOR, -1 }, //c2 + { "HostileImage", fx_hostile_image, 0, -1 },//d1 + { "IronFist", fx_iron_fist, 0, -1 }, //d0 + { "JumbleCurse", fx_jumble_curse, 0, -1 }, //d3 + { "MoveView", fx_move_view, EFFECT_NO_ACTOR, -1 },//cd + { "MultipleVVC", fx_multiple_vvc, EFFECT_NO_ACTOR, -1 }, //c5 + { "Overlay", fx_overlay, 0, -1 }, //c9 + { "PlayBAM1", fx_play_bam_blended, 0, -1 }, //bb + { "PlayBAM2", fx_play_bam_not_blended, 0, -1 },//bc + { "PlayBAM3", fx_play_bam_not_blended, 0, -1 }, //bd + { "PlayBAM4", fx_play_bam_not_blended, 0, -1 }, //be + { "PlayBAM5", fx_play_bam_not_blended, 0, -1 }, //bf + { "Prayer", fx_prayer, 0, -1 },//cc + { "RetreatFrom", fx_retreat_from, 0, -1 },//6e + { "SetStatus", fx_set_status, 0, -1 }, //ba + { "SpeakWithDead", fx_speak_with_dead, 0, -1 }, //d4 + { "SpecialEffect", fx_special_effect, 0, -1 },//c4 + { "StopAllAction", fx_stop_all_action, EFFECT_NO_ACTOR, -1 }, //cf + { "TintScreen", fx_tint_screen, EFFECT_NO_ACTOR, -1 }, //c3 + { "TransferHP", fx_transfer_hp, EFFECT_DICED, -1 }, //c0 + { NULL, NULL, 0, 0 }, }; void RegisterTormentOpcodes() { - core->RegisterOpcodes( sizeof( effectnames ) / sizeof( EffectRef ) - 1, effectnames ); + core->RegisterOpcodes( sizeof( effectnames ) / sizeof( EffectDesc ) - 1, effectnames ); } //retreat_from (works only in PST) - forces target to run away/walk away from Owner @@ -144,6 +150,15 @@ 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 (!Owner) + Owner = target; + if (!Owner) + return FX_NOT_APPLIED; + //delay effect + Map *area = Owner->GetCurrentArea(); + if (!area) + return FX_APPLIED; + //play once set to true //check tearring.itm (0xbb effect) ScriptedAnimation *sca = gamedata->GetScriptedAnimation(fx->Resource, true); @@ -169,20 +184,25 @@ int fx_play_bam_blended (Scriptable* Owner, Actor* target, Effect* fx) } else { playonce=false; } - if (fx->Parameter2&1) { - //four cycles, duration is in millisecond - sca->SetDefaultDuration(sca->GetSequenceDuration(4000)); - } else { - if (playonce) { + if (playonce) { sca->PlayOnce(); + } else { + if (fx->Parameter2&1) { + //four cycles, duration is in millisecond + sca->SetDefaultDuration(sca->GetSequenceDuration(AI_UPDATE_TIME)); } else { sca->SetDefaultDuration(fx->Duration-core->GetGame()->Ticks); } } + //convert it to an area VVC + if (!target) { + fx->Parameter2|=2; + } + if (fx->Parameter2&2) { sca->XPos+=fx->PosX; sca->YPos+=fx->PosY; - Owner->GetCurrentArea()->AddVVCell(sca); + area->AddVVCell(sca); } else { ScriptedAnimation *twin = sca->DetachTwin(); if (twin) { @@ -207,6 +227,15 @@ int fx_play_bam_not_blended (Scriptable* Owner, Actor* target, Effect* fx) bool doublehint; if (0) printf( "fx_play_bam_not_blended (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 ); + if (!Owner) + Owner = target; + if (!Owner) + return FX_NOT_APPLIED; + + Map *area = Owner->GetCurrentArea(); + if (!area) + return FX_APPLIED; + //play once set to true //check tearring.itm (0xbb effect) if ((fx->Parameter2&0x30000)==0x30000) { @@ -243,23 +272,27 @@ int fx_play_bam_not_blended (Scriptable* Owner, Actor* target, Effect* fx) sca->AlterPalette(rgb); } } - if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) { - playonce=true; - } else { + if (fx->TimingMode==FX_DURATION_INSTANT_LIMITED) { playonce=false; + } else { + playonce=true; } switch (fx->Parameter2&0x30000) { case 0x20000://foreground sca->ZPos+=9999; + sca->YPos+=9999; break; case 0x30000: //both sca->ZPos+=9999; + sca->YPos+=9999; if (sca->twin) { sca->twin->ZPos-=9999; + sca->twin->YPos-=9999; } break; default: //background sca->ZPos-=9999; + sca->YPos-=9999; break; } if (playonce) { @@ -268,7 +301,8 @@ int fx_play_bam_not_blended (Scriptable* Owner, Actor* target, Effect* fx) sca->SetDefaultDuration(fx->Duration-core->GetGame()->Ticks); } ScriptedAnimation *twin = sca->DetachTwin(); - if (fx->Parameter2&4096) { + + if (target && (fx->Parameter2&4096)) { if (twin) { target->AddVVCell(twin); } @@ -288,9 +322,9 @@ int fx_play_bam_not_blended (Scriptable* Owner, Actor* target, Effect* fx) if (twin) { twin->XPos+=fx->PosX-x; twin->YPos+=fx->PosY+twin->ZPos-y; - Owner->GetCurrentArea()->AddVVCell(twin); + area->AddVVCell(twin); } - Owner->GetCurrentArea()->AddVVCell(sca); + area->AddVVCell(sca); } return FX_NOT_APPLIED; } @@ -303,7 +337,7 @@ int fx_transfer_hp (Scriptable* Owner, Actor* target, Effect* fx) return FX_NOT_APPLIED; } - Actor *owner = (Actor *) Owner; + Actor *owner = GetCasterObject(); if (owner==target) { return FX_NOT_APPLIED; @@ -313,6 +347,12 @@ int fx_transfer_hp (Scriptable* Owner, Actor* target, Effect* fx) Actor *donor; int a,b; + //handle variable level hp drain (for blood bridge) + if (fx->IsVariable) { + fx->Parameter1+=fx->CasterLevel; + fx->IsVariable=0; + } + switch(fx->Parameter2) { case 3: case 0: receiver = target; donor = owner; break; @@ -327,8 +367,14 @@ int fx_transfer_hp (Scriptable* Owner, Actor* target, Effect* fx) default: return FX_NOT_APPLIED; } - int damage = donor->Damage(fx->Parameter1, fx->Parameter2, owner); - receiver->SetBase( IE_HITPOINTS, BASE_GET( IE_HITPOINTS ) + ( damage ) ); + int damage = receiver->GetStat(IE_MAXHITPOINTS)-receiver->GetStat(IE_HITPOINTS); + if (damage>(signed) fx->Parameter1) { + damage=(signed) fx->Parameter1; + } + if (damage) { + damage = donor->Damage(damage, fx->Parameter2, owner); + receiver->NewBase( IE_HITPOINTS, damage, MOD_ADDITIVE ); + } return FX_NOT_APPLIED; } @@ -338,9 +384,9 @@ int fx_transfer_hp (Scriptable* Owner, Actor* target, Effect* fx) int fx_flash_screen (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx) { if (0) printf( "fx_flash_screen (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 ); - core->GetVideoDriver()->SetFadeColor(((char *) &fx->Parameter1)[0],((char *) &fx->Parameter1)[1],((char *) &fx->Parameter1)[2]); - core->timer->SetFadeFromColor(1); - core->timer->SetFadeToColor(1); + 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); return FX_NOT_APPLIED; } @@ -361,13 +407,82 @@ int fx_tint_screen (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx) } //0xc4 fx_special_effect -int fx_special_effect (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 ); + //param2 determines the effect's behaviour + //0 - adder's kiss projectile (0xcd) + // adds play bam and damage opcodes to the projectile + //1 - ball lightning projectile (0xe0) + // adds a play bam opcode to the projectile + //2 - raise dead projectile - the projectile itself has the effect (why is it so complicated) + //TODO: create the spells + switch(fx->Parameter2) { + case 0: + strnuprcpy(fx->Resource,"adder",8); + break; + case 1: + strnuprcpy(fx->Resource,"ball",8); + break; + case 2: + strnuprcpy(fx->Resource,"rdead",8); + break; + } + Owner->CastSpell(fx->Resource, target, false); + Owner->CastSpellEnd(fx->CasterLevel); return FX_NOT_APPLIED; } -//0xc5-c8 fx_unknown +//0xc5 fx_multiple_vvc +//this is a gemrb specific opcode to support the rune of torment projectile +//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 ); + + Map *area = Owner->GetCurrentArea(); + if (!area) + return FX_NOT_APPLIED; + + AutoTable tab(fx->Resource); + if (!tab) + return FX_NOT_APPLIED; + + int rows = tab->GetRowCount(); + while(rows--) { + Point offset; + int delay, duration; + + offset.x=atoi(tab->QueryField(rows,0)); + offset.y=atoi(tab->QueryField(rows,1)); + delay = atoi(tab->QueryField(rows,3)); + duration = atoi(tab->QueryField(rows,4)); + ScriptedAnimation *sca = gamedata->GetScriptedAnimation(tab->QueryField(rows,2), true); + if (!sca) continue; + sca->SetBlend(); + sca->SetDelay(AI_UPDATE_TIME*delay); + sca->SetDefaultDuration(AI_UPDATE_TIME*duration); + sca->XPos+=fx->PosX+offset.x; + sca->YPos+=fx->PosY+offset.y; + area->AddVVCell(sca); + } + return FX_NOT_APPLIED; +} + +//0xc6 ChangeBackground +//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 ); + Map *map = core->GetGame()->GetCurrentArea(); + if (map) { + map->SetBackground(fx->Resource, fx->Duration); + } + return FX_NOT_APPLIED; +} + +//0xc7-c8 fx_unknown //0xc9 fx_overlay int fx_overlay (Scriptable* /*Owner*/, Actor* target, Effect* fx) { @@ -379,7 +494,7 @@ int fx_overlay (Scriptable* /*Owner*/, Actor* target, Effect* fx) //0xca fx_unknown //0x82 fx_bless -//static EffectRef fx_glow_ref ={"Color:PulseRGBGlobal",NULL,-1}; +//static EffectRef fx_glow_ref = { "Color:PulseRGBGlobal", -1 }; //pst bless effect spawns a color glow automatically //but i would rather use the IWD2 method int fx_bless (Scriptable* /*Owner*/, Actor* target, Effect* fx) @@ -425,8 +540,8 @@ int fx_curse (Scriptable* /*Owner*/, Actor* target, Effect* fx) } //0xcc fx_prayer -static EffectRef fx_curse_ref={"Curse",NULL,-1}; -static EffectRef fx_bless_ref={"Bless",NULL,-1}; +static EffectRef fx_curse_ref = { "Curse", -1 }; +static EffectRef fx_bless_ref = { "Bless", -1 }; int fx_prayer (Scriptable* Owner, Actor* target, Effect* fx) { @@ -531,7 +646,7 @@ int fx_hostile_image (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx) } //0xd2 fx_detect_evil -static EffectRef fx_single_color_pulse_ref={"Color:BriefRGB",NULL,-1}; +static EffectRef fx_single_color_pulse_ref = { "Color:BriefRGB", -1 }; int fx_detect_evil (Scriptable* Owner, Actor* target, Effect* fx) { @@ -589,6 +704,20 @@ int fx_jumble_curse (Scriptable* /*Owner*/, Actor* target, Effect* fx) return FX_APPLIED; } +//0xd4 fx_speak_with_dead +//This opcode is directly employed by the speak with dead projectile in the original engine +//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 (!STATE_GET( STATE_DEAD) ) { + return FX_NOT_APPLIED; + } + + //TODO: reverse engineer the original opcode + return FX_NOT_APPLIED; +} + #include "plugindef.h" GEMRB_PLUGIN(0x115A670, "Effect opcodes for the torment branch of the games") diff --git a/project/jni/application/gemrb/gemrb/plugins/SDLAudio/CMakeLists.txt b/project/jni/application/gemrb/gemrb/plugins/SDLAudio/CMakeLists.txt index ae7e2b16c..933a45230 100644 --- a/project/jni/application/gemrb/gemrb/plugins/SDLAudio/CMakeLists.txt +++ b/project/jni/application/gemrb/gemrb/plugins/SDLAudio/CMakeLists.txt @@ -1,6 +1,6 @@ IF (SDLMIXER_LIBRARY) - INCLUDE_DIRECTORIES( ${SDL_INCLUDE_DIR} ) + INCLUDE_DIRECTORIES( ${SDL_INCLUDE_DIR} ${SDLMIXER_INCLUDE_DIR}) - ADD_GEMRB_PLUGIN (SDLAudio SDLAudio.cpp ) - TARGET_LINK_LIBRARIES( SDLAudio ${SDL_LIBRARY} ${SDLMIXER_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ) + ADD_GEMRB_PLUGIN (SDLAudio SDLAudio.cpp ) + TARGET_LINK_LIBRARIES( SDLAudio ${SDL_LIBRARY} ${SDLMIXER_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ) ENDIF (SDLMIXER_LIBRARY) diff --git a/project/jni/application/gemrb/gemrb/plugins/SDLAudio/SDLAudio.h b/project/jni/application/gemrb/gemrb/plugins/SDLAudio/SDLAudio.h index b31f45ec7..4bdbbaf56 100644 --- a/project/jni/application/gemrb/gemrb/plugins/SDLAudio/SDLAudio.h +++ b/project/jni/application/gemrb/gemrb/plugins/SDLAudio/SDLAudio.h @@ -53,7 +53,7 @@ public: bool ReleaseStream(int stream, bool hardstop); void SetAmbientStreamVolume(int stream, int gain); void QueueBuffer(int stream, unsigned short bits, int channels, - short* memory, int size, int samplerate); + short* memory, int size, int samplerate); private: void FreeBuffers(); diff --git a/project/jni/application/gemrb/gemrb/plugins/SDLVideo/SDLVideo.cpp b/project/jni/application/gemrb/gemrb/plugins/SDLVideo/SDLVideo.cpp index 87aa891f0..be87bcfc3 100644 --- a/project/jni/application/gemrb/gemrb/plugins/SDLVideo/SDLVideo.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/SDLVideo/SDLVideo.cpp @@ -1738,16 +1738,16 @@ void SDLVideoDriver::GetPixel(short x, short y, Color& c) void SDLVideoDriver::GetPixel(void *vptr, unsigned short x, unsigned short y, Color &c) { - SDL_Surface *surf = (SDL_Surface*)(vptr); + SDL_Surface *surf = (SDL_Surface*)(vptr); - SDL_LockSurface( surf ); - unsigned char * pixels = ( ( unsigned char * ) surf->pixels ) + - ( ( y * surf->w + x) * surf->format->BytesPerPixel ); - long val = 0; - ReadPixel(val, pixels, surf->format->BytesPerPixel); - SDL_UnlockSurface( surf ); + SDL_LockSurface( surf ); + unsigned char * pixels = ( ( unsigned char * ) surf->pixels ) + + ( ( y * surf->w + x) * surf->format->BytesPerPixel ); + long val = 0; + ReadPixel(val, pixels, surf->format->BytesPerPixel); + SDL_UnlockSurface( surf ); - SDL_GetRGBA( val, surf->format, (Uint8 *) &c.r, (Uint8 *) &c.g, (Uint8 *) &c.b, (Uint8 *) &c.a ); + SDL_GetRGBA( val, surf->format, (Uint8 *) &c.r, (Uint8 *) &c.g, (Uint8 *) &c.b, (Uint8 *) &c.a ); } long SDLVideoDriver::GetPixel(void *vptr, unsigned short x, unsigned short y) diff --git a/project/jni/application/gemrb/gemrb/plugins/SDLVideo/TileRenderer.inl b/project/jni/application/gemrb/gemrb/plugins/SDLVideo/TileRenderer.inl index 81110f6c3..21825e091 100644 --- a/project/jni/application/gemrb/gemrb/plugins/SDLVideo/TileRenderer.inl +++ b/project/jni/application/gemrb/gemrb/plugins/SDLVideo/TileRenderer.inl @@ -47,8 +47,8 @@ struct TRBlender_HalfTrans { TRBlender_HalfTrans(const SDL_PixelFormat* format) { mask = (0x7F >> format->Rloss) << format->Rshift - | (0x7F >> format->Gloss) << format->Gshift - | (0x7F >> format->Bloss) << format->Bshift; + | (0x7F >> format->Gloss) << format->Gshift + | (0x7F >> format->Bloss) << format->Bshift; } Uint32 operator()(Uint32 p, Uint32 v) const { @@ -63,12 +63,12 @@ struct TRBlender_HalfTrans { //because it cannot select between the 16 and 32 bit variants template static void BlitTile_internal(SDL_Surface* target, - int tx, int ty, - int rx, int ry, - int w, int h, - const Uint8* data, const SDL_Color* pal, - const Uint8* mask, Uint8 mask_key, - Tinter& tint, Blender& blend, PixelType /*dummy*/=0) + int tx, int ty, + int rx, int ry, + int w, int h, + const Uint8* data, const SDL_Color* pal, + const Uint8* mask, Uint8 mask_key, + Tinter& tint, Blender& blend, PixelType /*dummy*/=0) { PixelType* buf_line = (PixelType*)(target->pixels) + (ty+ry)*(target->pitch / sizeof(PixelType)); const Uint8* data_line = data + ry*64; diff --git a/project/jni/application/gemrb/gemrb/plugins/SPLImporter/SPLImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/SPLImporter/SPLImporter.cpp index db8c17e8a..c8c9bfe01 100644 --- a/project/jni/application/gemrb/gemrb/plugins/SPLImporter/SPLImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/SPLImporter/SPLImporter.cpp @@ -166,6 +166,16 @@ Spell* SPLImporter::GetSpell(Spell *s, bool /*silent*/) //the low byte is unused, so we can keep the iwd2 bits there s->Flags|=(s->Flags>>8)&0xc0; s->Flags&=~0xc000; + } else { + //in case of old format, use some unused fields for gemrb's simplified duration + //to simulate IWD2's useful feature (this is needed for some pst projectiles) + if (s->Flags&SF_SIMPLIFIED_DURATION) { + s->TimePerLevel = s->unknown2; + s->TimeConstant = s->unknown3; + } else { + s->TimePerLevel = 0; + s->TimeConstant = 0; + } } s->ext_headers = core->GetSPLExt(s->ExtHeaderCount); @@ -195,6 +205,13 @@ void SPLImporter::GetExtHeader(Spell *s, SPLExtHeader* eh) str->Read( &eh->unknown2, 1 ); str->ReadResRef( eh->MemorisedIcon ); str->Read( &eh->Target, 1 ); + + //this hack is to let gemrb target dead actors by some spells + if (eh->Target == 1) { + if (core->GetSpecialSpell(s->Name)&SPEC_DEAD) { + eh->Target = 3; + } + } str->Read( &tmpByte,1 ); if (!tmpByte) { tmpByte = 1; diff --git a/project/jni/application/gemrb/gemrb/plugins/STOImporter/STOImporter.cpp b/project/jni/application/gemrb/gemrb/plugins/STOImporter/STOImporter.cpp index b6f086b06..14dabd0b5 100644 --- a/project/jni/application/gemrb/gemrb/plugins/STOImporter/STOImporter.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/STOImporter/STOImporter.cpp @@ -158,10 +158,7 @@ Store* STOImporter::GetStore(Store *s) void STOImporter::GetItem(STOItem *it) { - CREItem *itm = core->ReadItem(str); - memcpy(it, itm, sizeof(CREItem) ); - //core allocates CREItem!!! - delete itm; + core->ReadItem(str, (CREItem *) it); str->ReadDword( &it->AmountInStock ); //if there was no item on stock, how this could be 0 diff --git a/project/jni/application/gemrb/gemrb/plugins/TLKImporter/TLKImporter.h b/project/jni/application/gemrb/gemrb/plugins/TLKImporter/TLKImporter.h index bb3cf4353..c2a03e01b 100644 --- a/project/jni/application/gemrb/gemrb/plugins/TLKImporter/TLKImporter.h +++ b/project/jni/application/gemrb/gemrb/plugins/TLKImporter/TLKImporter.h @@ -60,7 +60,7 @@ private: if dest is not NULL it also returns the decoded value */ int BuiltinToken(char* Token, char* dest); int RaceStrRef(int slot); - int GenderStrRef(int slot, int malestrref, int femalestrref); + int GenderStrRef(int slot, int malestrref, int femalestrref); char *Gabber(); char *CharName(int slot); }; diff --git a/project/jni/application/gemrb/gemrb/plugins/WAVReader/WAVReader.cpp b/project/jni/application/gemrb/gemrb/plugins/WAVReader/WAVReader.cpp index 577442367..90c701014 100644 --- a/project/jni/application/gemrb/gemrb/plugins/WAVReader/WAVReader.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/WAVReader/WAVReader.cpp @@ -128,8 +128,8 @@ bool WavPCMReader::Open(DataStream* stream) str->ReadDword(&r_hdr.length); //don't swap this str->Read( &wave, 4 ); - if (r_hdr.fourcc != *( unsigned int * ) RIFF_4cc || - wave != *( unsigned int * ) WAVE_4cc) { + if (memcmp(&r_hdr.fourcc, RIFF_4cc, 4) != 0 || + memcmp(&wave, WAVE_4cc, 4) != 0) { return false; } @@ -137,7 +137,7 @@ bool WavPCMReader::Open(DataStream* stream) //don't swap this str->Read(&fmt_hdr.fourcc,4); str->ReadDword(&fmt_hdr.length); - if (fmt_hdr.fourcc != *( unsigned int * ) fmt_4cc || + if (memcmp(&fmt_hdr.fourcc, fmt_4cc, 4) != 0 || fmt_hdr.length > sizeof( cWAVEFORMATEX )) { return false; } @@ -166,13 +166,13 @@ bool WavPCMReader::Open(DataStream* stream) str->Read(&data_hdr.fourcc,4); str->ReadDword(&data_hdr.length); - if (data_hdr.fourcc == *( unsigned int * ) fact_4cc) { + if (memcmp(&data_hdr.fourcc, fact_4cc, 4) == 0) { str->Seek( data_hdr.length, GEM_CURRENT_POS ); //str->Read( &data_hdr, sizeof( data_hdr ) ); str->ReadDword(&data_hdr.fourcc); str->ReadDword(&data_hdr.length); } - if (data_hdr.fourcc != *( unsigned int * ) data_4cc) { + if (memcmp(&data_hdr.fourcc, data_4cc, 4) != 0) { return false; } diff --git a/project/jni/application/gemrb/gemrb/plugins/ZLibManager/ZLibManager.cpp b/project/jni/application/gemrb/gemrb/plugins/ZLibManager/ZLibManager.cpp index 9d23296e0..858ae716c 100644 --- a/project/jni/application/gemrb/gemrb/plugins/ZLibManager/ZLibManager.cpp +++ b/project/jni/application/gemrb/gemrb/plugins/ZLibManager/ZLibManager.cpp @@ -35,8 +35,8 @@ ZLibManager::~ZLibManager(void) } -#define INPUTSIZE 4096 -#define OUTPUTSIZE 4096 +#define INPUTSIZE 8192 +#define OUTPUTSIZE 8192 // ZLib Decompression Routine int ZLibManager::Decompress(FILE* dest, DataStream* source, unsigned int size_guess) const diff --git a/project/jni/application/gemrb/gemrb/templates/cpp_template b/project/jni/application/gemrb/gemrb/templates/cpp_template new file mode 100644 index 000000000..6afef5d4e --- /dev/null +++ b/project/jni/application/gemrb/gemrb/templates/cpp_template @@ -0,0 +1,16 @@ +/*************************************************************************** + |FILENAME| - description + ------------------- + begin : |DATE| + copyright : (C) |YEAR| by |AUTHOR| + email : |EMAIL| + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ diff --git a/project/jni/application/gemrb/gemrb/templates/header_template b/project/jni/application/gemrb/gemrb/templates/header_template new file mode 100644 index 000000000..6afef5d4e --- /dev/null +++ b/project/jni/application/gemrb/gemrb/templates/header_template @@ -0,0 +1,16 @@ +/*************************************************************************** + |FILENAME| - description + ------------------- + begin : |DATE| + copyright : (C) |YEAR| by |AUTHOR| + email : |EMAIL| + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/